4.3. Data Types and Operators in xGT¶
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.
4.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. Each column of the schema of a frame must be one of these data types.
4.3.1.1. BOOLEAN¶
The BOOLEAN
type supports the storage of two values: true or false.
Use the case-insensitive keywords TRUE
or FALSE
or the integer values 1 or 0 to assign a BOOLEAN
.
4.3.1.2. INTEGER¶
The INTEGER
type holds signed numeric values.
It stores any value between the range of -263 and 263 - 1.
Attempting to assign values outside this range causes an error.
4.3.1.3. FLOAT¶
The FLOAT
type holds single-precision (32-bit) floating-point values.
Inputs with precision greater than 32 bits are valid input but will be truncated.
The case-insensitive string NaN
is also an acceptable value.
Any other non-decimal characters will result in an error.
4.3.1.4. DATE¶
The DATE
type holds a date composed of a day, month, and year.
The expected format for a DATE
is YYYY-MM-DD
where leading zeros must be given.
For example, a valid DATE
would be 2018-02-20
.
Assigning a DATE
property with a valid DATETIME
as described in the DATETIME
section will result in the DATETIME
being downcast and ignoring the time fields.
Attempting to assign any other type will result in an error.
4.3.1.5. TIME¶
The TIME
type holds a time composed of hours, minutes, seconds, and (optionally) a decimal fraction of a second.
The expected format for a TIME
is HH:MM:SS
where leading zeros must be given.
For example, a valid TIME
would be 06:10:50
.
Optionally, a decimal fraction of a second can be included where the expected format is HH:MM:SS.S
.
Values with 1 to 19 decimal digits can be read in, but only a maximum of 6 decimal digits is stored.
If the input decimal fraction has between 7 and 19 digits, the number stored is rounded to 6 digits.
For example, a valid TIME
with a decimal fraction would be 06:10:50.0206
.
Attempting to assign any other type will result in an error.
In addition, a time zone can be indicated, though this will be converted to a Coordinated Universal Time (UTC) and the time zone will not be retained.
Time zones are expressed either with a Z
to indicated UTC or with an offset in containing an hour part and an optional minute part.
The hour part must be between 14 and -14, and the minute part must be in 15 minute increments.
The following formats are valid with or without a decimal fraction: HH:MM:SSZ
, HH:MM:SS+HH:MM
, HH:MM:SS-HH:MM
, HH:MM:SS+HH
, and HH:MM:SS-HH
.
For example, 06:10:50.0206+01:15
and 06:10:50-01:00
are valid times whereas 06:10:50+16
and 06:10:50+01:17
are not valid.
4.3.1.6. DATETIME¶
The DATETIME
type holds a valid date and time separated by either a T
or a space, where the date and time must be formatted as described above.
It is composed of a day, month, year, hours, minutes, seconds, and optionally microseconds.
The expected format for a DATETIME
is YYYY-MM-DDTHH:MM:SS
, YYYY-MM-DD HH:MM:SS
, YYYY-MM-DDTHH:MM:SS.S
, YYYY-MM-DD HH:MM:SS.S
, YYYY-MM-DDTHH:MM:SSZ
(UTC), YYYY-MM-DDTHH:MM:SS+HH:MM
, YYYY-MM-DDTHH:MM:SS+HH
, YYYY-MM-DDTHH:MM:SS-HH:MM
, or YYYY-MM-DDTHH:MM:SS-HH
.
For example, a valid DATETIME
would be 2018-12-20T06:10:50
, 2018-12-20 06:10:50.02006
, or 2018-12-20T06:10:50.02006+01:15
.
Assigning a DATE
to a DATETIME
will result in the DATE
being “promoted” to a DATETIME
with zeros for the time fields.
Attempting to assign any other type will result in an error.
4.3.1.7. IPADDRESS¶
The IPADDRESS
type holds an IPv4 address.
The expected format of an IPADDRESS
is XXX.XXX.XXX.XXX
where each dot-separated value is between 0 and 255.
For example, a valid IPADDRESS
would be 172.16.254.1
.
Assigning any other type (including IPv6 addresses) will result in an error.
For situations where there are both IPv4 and IPv6 addresses in a single data source, it is recommended that the schema provide a TEXT
type for that data.
4.3.1.8. TEXT¶
The TEXT
type holds a string of UTF-8 encoded Unicode characters.
4.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. Lists are currently not supported for Pandas frames.
4.3.2.1. Lists¶
xGT supports homogeneous nested lists.
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 INTEGER
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]]
4.3.3. Supported Operators¶
TQL provides boolean, comparison, arithmetic, string, and list operators. “Numeric” below refers to INTEGER and FLOAT data types. “Any” refers to any of the data types described above.
4.3.3.1. Boolean Operators¶
xGT supports the following boolean operators:
Operator |
Operand 1 |
Operand 2 |
Result |
Description |
---|---|---|---|---|
NOT |
BOOLEAN |
N/A |
BOOLEAN |
Boolean negation operator. |
AND |
BOOLEAN |
BOOLEAN |
BOOLEAN |
Boolean conjunction operator. |
OR |
BOOLEAN |
BOOLEAN |
BOOLEAN |
Boolean disjunction operator. |
4.3.3.2. Comparison Operators¶
xGT supports the following comparison operators:
Operator |
Operand 1 |
Operand 2 |
Result |
Description |
---|---|---|---|---|
IS NULL / IS NOT NULL |
Any |
N/A |
BOOLEAN |
Null check. |
= |
Any |
Any |
BOOLEAN |
Equality comparison. |
<> |
Any |
Any |
BOOLEAN |
Inequality comparison. |
<, <= |
Any |
Any |
BOOLEAN |
Less-than, less-than equal comparison. |
>, >= |
Any |
Any |
BOOLEAN |
Greater-than, greater-than equal comparison. |
For the comparison operators that have two parameters, the parameters must be of the same type or both be numeric types.
When the parameters are of different numeric types, type promotion occurs automatically.
All comparisons on lists perform lexicographical comparisons 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.
4.3.3.3. Arithmetic Operators¶
The following arithmetic operators are supported with type promotion from integer to floating-point occurring automatically.
Operator |
Operand 1 |
Operand 2 |
Result |
Description |
---|---|---|---|---|
+ |
Numeric |
Numeric |
Numeric |
Addition operator. |
- |
Numeric |
Numeric |
Numeric |
Subtraction operator. |
* |
Numeric |
Numeric |
Numeric |
Multiplication operator. |
/ |
Numeric |
Numeric |
Numeric |
Division operator. |
% |
Integer |
Integer |
Integer |
Modulus (remainder) operator. |
4.3.3.4. String Operators¶
The following string operators are supported.
Operator |
Operand 1 |
Operand 2 |
Result |
Description |
---|---|---|---|---|
STARTS WITH |
String |
String |
Boolean |
True if the right-hand is a prefix of the left-hand side. |
ENDS WITH |
String |
String |
Boolean |
True if the right-hand is a suffix of the left-hand side. |
CONTAINS |
String |
String |
Boolean |
True if the right-hand is a substring of the left-hand side. |
+ |
String |
String |
String |
String concatenation. |
4.3.3.5. List Operators¶
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]