You are currently reviewing an older revision of this page.

DRAFT KB-XXXX Casting of CDT returns inconsistent, unexpected data


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

For example, imagine that an application a process variables 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 these column definition expressions are returning completely different data values.


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

  • INTEGER would be 1
  • LIST_OF_INTEGER would be 101

In process analytics, Appian also has the concept of 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 Appian to perform a single evaluation of the column definition expression, rather than evaluate the column once per row. In the case described above, the process variable pv!example exists as the BULK version of its CDT type. However, the cast is enforcing that it must be converted to the regular, non-BULK type. In the process report, the column definition expressions are only evaluate once, and the result of a single evaluation of a non-BULK list is a pointer to the head of that list. This results in repeated, unexpected data values.


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:
  • (-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