2.3. Data Types and Operators

TQL provides both scalar and composite data types along with operators to manipulate them. A scalar data type represents a single item, while a composite data type represents multiple items. Each column of the schema of a frame must be one of the scalar or composite data types described below.

2.3.1. Scalar Data Types

A scalar data type can be stored as a frame property and returned from a query. They can be constructed as literals and passed as query parameters. The following scalar data types are supported in xGT.

2.3.1.1. BOOLEAN

The BOOLEAN type supports the storage of two values: true or false.

2.3.1.2. INT

The INT type holds signed integer values in the range of -263 to 263 - 1. Using values outside this range causes an error.

2.3.1.3. UINT

The UINT type hold unsigned integer values in the range of 0 to 264 - 1. Using values outside this range causes an error.

2.3.1.4. FLOAT

The FLOAT type holds single-precision (32-bit) floating-point values. Values with precision greater than 32 bits are valid input but will be truncated.

2.3.1.5. DATE

The DATE type holds a date composed of a year, month, and day. Dates must be in the range -9999-01-01 to 9999-12-31 and have a precision of days.

2.3.1.6. TIME

The TIME type holds a time composed of hours, minutes, seconds, and microseconds. Times must be in the range 00:00:00.000000 to 23:59:59.999999 and have a precision of microseconds. Times do not store time zones.

2.3.1.7. DATETIME

The DATETIME type holds a date composed of year, month, day, hours, minutes, seconds, and microseconds. Datetimes must be in the range -9999-01-01 00:00:00.000000 to 9999-12-31 23:59:59.999999 and have a precision of microseconds.

2.3.1.8. DURATION

The DURATION type holds a span of time composed of weeks, days, hours, minutes, seconds, and microseconds. The duration’s range is large enough to hold the difference between the extreme ranges of a datetime and have a precision of microseconds.

2.3.1.9. IPADDRESS

The IPADDRESS type holds either an IPv4 address or an IPv6 address. If the IP address is expressible as an IPv4 it will be returned as an IPv4.

2.3.1.10. TEXT

The TEXT type holds a string of UTF-8 encoded Unicode characters.

2.3.1.11. CARTESIANPOINT

The CARTESIANPOINT type holds a 2 or 3 coordinate point in the Cartesian system. The only valid comparisons for point types are equality and inequality. Currently, this type is not supported in the client and can only be created via the point constructor.

2.3.1.12. WGS84POINT

The WGS84POINT type holds a 2 or 3 coordinate point in the WGS-84 system. The only valid comparisons for point types are equality and inequality. Currently, this type is not supported in the client can only be created via the point constructor.

2.3.2. Composite Data Types

A composite data type can be constructed as a literal. The only composite data type supported by TQL is a list. Lists can be stored as a frame property, returned from a query, or passed as a query parameter.

2.3.2.1. LIST

xGT supports homogeneous nested lists with the LIST type.

A literal list is created using brackets: [1, 2, 4, 1]. They can contain vertex and edge properties, constants, or any other valid TQL expression: Brackets can be nested to form nested lists: [[1, 2, 4, 1], [5, 6, 7]].

MATCH (v:VertexFrame)-[]->(v2)
WITH [v.property1, v2.property1 + 10] AS list

An empty literal list is allowed: []. Lists of any type can also include null as a value. For example, the following are all valid literal lists:

[1, 2, NULL, 4]
[NULL, "a"]

Numeric lists can be created with the range function, which takes three arguments: the start, end, and an optional step.

WITH range(0, 10) AS list0, range(2, 14, 3) AS list1

The collect aggregator can be used to create a list from data. In the example below, it is used to create a list of property values found over all matches of a pattern:

MATCH (v:VertexFrame)
WITH collect(v.property) AS list0
MATCH (w)-[e:EdgeFrame]->()
WHERE e.value IN list0

All elements in a list must be the same data type. The one exception is numeric types. FLOAT and INT can be mixed in a list. For example, the following lists are valid:

[date("2018-02-20"), date("2018-02-21"), date("2007-05-20")]
[ipaddress("172.16.254.1"), ipaddress("216.58.216.164")]
["a", "zebra"]
[1, 0.45, 7, 9.382]

The following example mixes incompatible types and is invalid:

[date("2018-02-20"), 12, "a"]

Vertex and edge variables are not allowed as list elements. For example, the lists in the following query are invalid:

MATCH (v:VertexFrame)-[e]->(v2)
WITH [v] AS list, [e] AS list2

Nested lists must be the same type at a given level across all lists. A list is considered a type, so lists cannot be mixed with other types either. The exception is that a empty or null list can be mixed with other lists. The following are valid:

[[1, 2, 3], [4, 5, 6]]
[["x"], ["a", "b"]]
[[1, 2, 3], []]
[[1, 2, 3], [null]]
[[1, 4], null]
[[[1, 4]], null]

The following are invalid because the sublists are of different types:

[[9, 12, 8], ["a", "b"]]
[[9, 12, 8], [[9, 12, 8]]]

The following is invalid because it mixes other types with the list type:

[9, 12, 8, [9, 12, 8]]

2.3.3. Operators

TQL provides boolean, comparison, arithmetic, string, and list operators. “Numeric” below refers to INT and FLOAT data types. “Any” refers to any of the data types described above.

2.3.3.1. Boolean Operators

xGT supports the following boolean operators.

Boolean Operators

Operator

Description

NOT

Boolean negation operator.

AND

Boolean conjunction operator.

OR

Boolean disjunction operator.

XOR

Boolean exclusive disjunction operator.

All the operators return a boolean expression. The operands to all the operators must be boolean expressions.

2.3.3.2. Comparison Operators

xGT supports the following comparison operators.

Comparison Operators

Operator

Description

=

Equality comparison.

<>

Inequality comparison.

<<=

Less-than, less-than equal comparison.

>>=

Greater-than, greater-than equal comparison.

IS NULL / IS NOT NULL

Null check.

All the operators return a boolean expression. For the comparison operators that have two operands, the expressions must be of the same type or both be numeric types. Mixed integer and floating-point are allowed. All comparisons on lists are lexicographical, meaning the list elements are compared in order pairwise. If one list is longer than the other, its remaining elements are considered greater than the missing elements. For example, [1] < [1,2] evaluates to true.

2.3.3.3. Arithmetic Operators

The following arithmetic operators are valid only on numerical expressions. Mixed integer and floating-point are allowed.

Arithmetic Operators

Operator

Description

+

Addition operator.

-

Subtraction operator.

*

Multiplication operator.

/

Division operator.

%

Modulus (remainder) operator.

^

Exponentiation operator.

-

Unary minus operator.

2.3.3.4. Temporal Operators

The following arithmetic operators are supported for temporal types.

Temporal Operators

Operator

Types

Description

+

duration + duration = duration

duration + date = date
date + duration = date

The duration’s precision below a day is truncated.

duration + time = time
time + duration = time

Overflows wrap around (i.e. time(23:00:00) + duration({ day = 1, hour = 2 }) = time(01:00:00).

duration + datetime = datetime
datetime + duration = datetime

-

date - date = duration
time - time = duration
datetime - datetime = duration
datetime - date = duration
duration - duration = duration

date - datetime = duration

The time portion of the datetime is truncated.

date - duration = date

The duration’s precision below a day is truncated.

time - duration = time

Overflows wrap around (i.e. (time(1:00:00) - duration({ day = 1, hour = 2 }) = time(23:00:00).

datetime - duration = datetime

*

integer * duration = duration
duration * integer = duration
float * duration = duration
duration * float = duration
duration * duration = duration

/

duration / integer = duration
duration / float = duration
duration / duration = float

%

duration % duration = duration

-

-duration = duration

Unary minus.

2.3.3.5. String Operators

The following string operators are supported.

String Operators

Operator

Description

STARTS WITH

True if the first string is a prefix of the second.

ENDS WITH

True if the first string is a suffix of the second.

CONTAINS

True if the second string is a substring of the first.

+

Concatenates two strings.

2.3.3.6. List Operators

The following list operators are supported.

List Operators

Operator

Description

element IN list

True if element is found in the list.

+

Concatenates two lists into a single list.

[position]

Subscript. Returns the element at the given position in a list.

[start..stop]

Slice subscript. Returns a sublist that includes the element at start but excludes the element at stop.

The IN operator is used to test for membership in a list. The test expression must be of a compatible type with the elements in the list. Some examples:

a.name IN ["John", "Mary"]
b.id IN [1, 2, 3]
c.startdate IN [date("2000-01-01"), date("2002-01-01")]

The IN operator also supports nested lists:

parents IN [["John", "Mary"], ["Jacob", "Mary"]]

List concatenation is supported via the + operator. The two lists to be concatenated must have the same type.

RETURN [1, 2, 3] + [-1, 0, 1]

The subscript operator is supported to access individual elements in a list. The following example would return the integer 2.

RETURN [1, 2, 3][1]

The slicing operator is supported to retrieve sublists from an original list. The following example would return the list with elements [2, 3].

RETURN [1, 2, 3][1..2]