Data Types in CTL2

For basic information about data types used in metadata see Data Types in Metadata

In any program, you can use some variables. Data types in CTL are the following:

boolean long
byte number (double)
cbyte string
date list
decimal map
integer record

boolean

The boolean data type contains values of logical expressions.

The default value is false.

It can be either true or false.

Its declaration looks like this: boolean identifier;

Example 64.4. Declaration of boolean variable

boolean b;        // declaration
boolean b = true; // declaration with assignment

byte

This data type is an array of bytes of a length that can be up to Integer.MAX_VALUE as a maximum. It behaves similarly to the list data type (see below).

The default value is null.

Its declaration looks like this: byte identifier;

Example 64.5. Declaration of byte variable

byte b;
// declaration of variable with assignment
byte b = hex2byte("414243");

cbyte

This data type is a compressed array of bytes of a length that can be up to Integer.MAX_VALUE as a maximum. It behaves similarly to the list data type (see below).

The default value is null.

Its declaration looks like this: cbyte identifier;

Example 64.6. Declaration of cbyte variable

cbyte c1;
cbyte c2 = hex2byte("61"); // declaration with assignment

date

The date data type contains date and time.

The default value is 1970-01-01 00:00:00 GMT.

Its declaration look like this: date identifier;

Example 64.7. Declaration of date variable

// declaration of variable
date d;
// declaration of variable with assignment from function
date d = str2date("1600-01-31", "yyyy-MM-dd");

[Note]Note

If you work with date, you should be aware of time zone of the data.

decimal

The decimal data type serves to store decimal numbers.

Calculations with the decimal data type are performed in fixed point arithmetic. It makes decimal data type suitable for calculations with money.

The default value is 0.

Its declaration looks like this: decimal identifier;

By default, any decimal may have up to 32 significant digits. If you want to have different Length or Scale, you need to set these properties of decimal field in metadata.

Example 64.8. Usage of decimal data type in CTL2

If you assign 100.0 / 3 to a decimal variable, its value might for example be 33.333333333333335701809119200333. As 100.0 is double and 3 is integer, the both operands were firstly converted to double, then the value has been calculated and finally the result value has been converted to decimal. Assigning it to a decimal field (with default Length and Scale, which are 12 and 2, respectively), it will be converted to 33.33D.


You can cast any float number to the decimal data type by appending the d letter to its end.

Any numeric data type (integer, long, number/double) can be converted to the decimal.

Example 64.9. Declaration of decimal variable

decimal d;
decimal d2 = 4.56D; // declaration of variable with assignment

integer

The integer data type can contain integral values.

CTL2 integer can store values from -2147483648 to 2147483647.

The integer data type can overflow (i.e., adding 1 to the maximum value returns -2147483648; similarly, subtracting 1 from the minimum value returns 2147483647) which may lead to errors and/or incorrect results.

The default value is 0.

Its declaration looks like this: integer identifier;

[Important]Important

The value -2147483648 can be stored in CTL2 variable but cannot be stored in integer field of record metadata (value of the field would be null). If the value -2147483648 is expected to arise, consider usage of data type with wider range of values in metadata; e.g., long.

If you append an L letter to the end of any integer number, you can cast it to the long data type.

Integer can be converted to the long, double or decimal using automatic conversions.

Example 64.10. Declaration of integer variable

integer i1;
integer i2 = 1241;

long

long is an integral data type allowing to store greater values than the integer data type.

CTL2 long can store values from -9223372036854775808 to 9223372036854775807.

The long data type can overflow (i.e., adding 1 to the maximum value returns -92233720368547758088; similarly, subtracting 1 from the minimum value returns 9223372036854775807) which may lead to errors and/or incorrect results.

The default value is 0.

Its declaration looks like this: long identifier;

[Important]Important

The value -9223372036854775808 can be stored in CTL2 variable but the value is used in long field in record metadata for null value. If the value -9223372036854775808 is expected to arise, consider usage of data type with wider range of values in metadata; e.g., decimal.

Any integer number can be cast to long data type by appending an l letter to its end.

Long data type can be converted to the number/double or decimal without explicit casting.

Example 64.11. Declaration of long variable

long myLong;
long myLong2 = 2141L;

number (double)

The number data type is used for floating point number.

The default value is 0.0.

Its declaration looks like this: number identifier;

If you need a data type for money amount, you are strongly advised to use decimal instead of number (double).

The integer and long data types can be converted to double using automatic conversions. If long is being converted to number (double), lost of precision may occur.

Number(double) can be converted to decimal without explicit casting.

Example 64.12. Declaration of number (double) variable

double d;
double d2 = 1.5e2;

string

This data type serves to store sequences of characters.

The default value is empty string.

The declaration looks like this: string identifier;

Example 64.13. Declaration of string variable

string s;
string s2 = "Hello world!";

list

Each list is a container of one of the following data types: boolean, byte, date, decimal, integer, long, number, string, record.

The list data type is indexed by integers starting from 0.

Its declaration can look like this: string[] identifier;

List cannot be created as a list of lists or maps.

The default list is an empty list.

Example 64.14. List

integer[] myIntegerList;
myIntegerList[5] = 123;

// Customer is metadata record name
Customer JohnSmith;
Customer PeterBrown;
Customer[] CompanyCustomers;
CompanyCustomers[0] = JohnSmith;
CompanyCustomers[1] = PeterBrown;


Assignments:
  • myStringList[3] = "abc";

    It means that the specified string is put to the fourth position in the string list. The other values are filled with null as follows:

    myStringList is [null,null,null,"abc"]

  • myList1 = myList2;

    It means that both lists reference the same elements.

  • myList1 = myList1 + myList2;

    It adds all elements of myList2 to the end of myList1.

    Both lists must be based on the same primitive data type.

  • myList1 = null;

    It destroys the myList1.

Be careful when performing list operations (such as append). See Warning.

map

This data type is a container of pairs of a key and a value.

Its declaration looks like this: map[<type of key>, <type of value>] identifier;

Both the Key and the Value can be of the following primitive data types: boolean, date, decimal, integer, long, number, string. Value can also be of the record, byte and cbyte type.

Map cannot be created as a map of lists or other maps.

The default map is an empty map.

Example 64.15. Map

map[string, boolean] map1;
map1["abc"]=true;

// Customer is a name of record
Customer JohnSmith;
Customer PeterBrown;
map[integer, Customer] CompanyCustomersMap;
CompanyCustomersMap[JohnSmith.ID] = JohnSmith;
CompanyCustomersMap[PeterBrown.ID] = PeterBrown

The assignments are similar to those valid for a list.

record

Record is a container that can contain different primitive data types.

The structure of record is based on metadata. Any metadata item represents a data type.

Declaration of a record looks like this: <metadata name> identifier;

Metadata names must be unique in a graph. Different metadata must have different names.

For more detailed information about possible expressions and records usage see Accessing Data Records and Fields.

Record does not have a default value.

It can be indexed by both integer numbers and strings (field names). If indexed by numbers, fields are indexed starting from 0.

[Warning]Warning

Be careful when a record is pushed|appended|inserted (push(), append(), insert() functions) to a list of records within the transform() or another function. If the record is declared as a global variable, the last item in the list will always reference the same record. To avoid that, declare your record as a local variable (within transform()). Calling transform(), a new reference will be created and a correct value will be put to the list.