KB-1617 Casting of CDT in process reports returns inconsistent, unexpected data due to Appian BULK type values

Symptoms

Casting a custom data type (CDT) to a new type returns inconsistent, unexpected data in process reports.

For example, imagine that an application has a process variable named pv!example, and this process variable populates the data for a CDT. Then, this CDT is cast to another CDT named CDT_Casted_Type that changes some of the data types in the original CDT. A process report is then constructed with the following column definition expressions:

  • Column 1 =pv!example
  • Column 2 =cast('type!{urn:com:appian:types}CDT_Casted_Type', pv!example)

These columns should display nearly the same data, as the cast should only alter the data type. However, some of the rows in this report show that the column definition expression for Column 2 is returning completely different data values.

Cause

Appian has scalar and list versions for all types. For example:

  • INTEGER would be 1
  • LIST_OF_INTEGER would be 101

The process analytics engines use BULK versions of these types, which are evaluated by taking the negative value of the original type value. For example:

  • BULK_INTEGER would be -1
  • BULK_LIST_OF_INTEGER would be -101

These BULK types allow the process analytics engines to perform a single evaluation of the column definition expression, rather than evaluate the column once per row, making the operation more efficient. In the case described above, the process variable pv!example is evaluated as the BULK version of its CDT type. However, the cast is converting to the regular, non-BULK type. In the process report, the column definition expressions are only evaluated once, and the result of evaluating a non-BULK list is repeated, unexpected data.

This issue has been reported to the Appian Product Team. The reference number for this issue is AN-108982.

Workaround

Ensure that the cast is of BULK type. This can be done by getting the type value of the CDT and negating it. For the example above, this requires making the following changes to the column definition expression:

  • cast('type!{urn:com:appian:types}CDT_Casted_Type', pv!example) becomes:
  • cast(-fn!tointeger('type!{urn:com:appian:types}CDT_Casted_Type'), pv!example)

Note: It is recommended to make an expression rule, for example getBulkTypeFromType, that passes in the normal type ('type{urn:com:appian:types}CDT_Casted_Type') and returns -fn!tointeger(ri!type). This way, if the conversion must be done for other process reports, there is only a single source of truth for this code.

Affected Versions

This article applies to all versions of Appian.

Last Reviewed: July 2018

Related
Recommended