Operators, Functions, and Expressions

An expression is a combination of fixed values, variables, operators, function calls, and groupings which specify a computation, resulting in a data value. This section of the specification describes the literals (fixed values), operators, and functions available in the GSQL query language. It covers the subset of the EBNF definitions shown below. However, more so than in other sections of the specification, syntax alone is not an adequate description. The semantics (functionality) of the particular operators and functions are an essential complement to the syntax.

EBNF for Operations, Functions, and Expressions
constant := numeric | stringLiteral | TRUE | FALSE | GSQL_UINT_MAX
| GSQL_INT_MAX | GSQL_INT_MIN | TO_DATETIME "(" stringLiteral ")"
mathOperator := "*" | "/" | "%" | "+" | "-" | "<<" | ">>" | "&" | "|"
condition := expr
| expr comparisonOperator expr
| expr [ NOT ] IN setBagExpr
| expr IS [ NOT ] NULL
| expr BETWEEN expr AND expr
| "(" condition ")"
| NOT condition
| condition (AND | OR) condition
| (TRUE | FALSE)
comparisonOperator := "<" | "<=" | ">" | ">=" | "==" | "!="
expr := name
| "@@"accumName
| name "." "type"
| name "." name
| name "." "@"accumName ["\'"]
| name "." name "." name "(" [argList] ")"
| name "." name "(" [argList] ")" [ ".".FILTER "(" condition ")" ]
| name ["<" type ["," type]* ">"] "(" [argList] ")"
| name "." "@"accumName ("." name "(" [argList] ")")+ ["." name]
| "@@"accumName ("." name "(" [argList] ")")+ ["." name]
| COALESCE "(" [argList] ")"
| ( COUNT | ISEMPTY | MAX | MIN | AVG | SUM ) "(" setBagExpr ")"
| expr mathOperator expr
| "-" expr
| "(" expr ")"
| "(" argList "->" argList ")" // key value pair for MapAccum
| "[" argList "]" // a list
| constant
| setBagExpr
| name "(" argList ")" // function call or a tuple object
setBagExpr := name
| "@@"accumName
| name "." name
| name "." "@"accumName
| name "." "@"accumName ("." name "(" [argList] ")")+
| name "." name "(" [argList] ")" [ ".".FILTER "(" condition ")" ]
| "@@"accumName ("." name "(" [argList] ")")+
| setBagExpr (UNION | INTERSECT | MINUS) setBagExpr
| "(" argList ")"
| "(" setBagExpr ")"
argList := expr ["," expr]*

Constants

constant := numeric | stringLiteral | TRUE | FALSE | GSQL_UINT_MAX
| GSQL_INT_MAX | GSQL_INT_MIN | TO_DATETIME "(" stringLiteral ")"

Each primitive data type supports constant values:

Data Type

Constant

Examples

Numeric types (INT, UINT, FLOAT, DOUBLE)

numeric

123 -5 45.67 2.0e-0.5

UINT

GSQL_UINT_MAX

INT

GSQL_INT_MAX GSQL_INT_MIN

boolean

TRUE FALSE

string

stringLiteral

"atoz@com" "0.25"

GSL_UINT_MAX = 2 ^ 64 - 1 = 18446744073709551615

GSQL_INT_MAX = 2 ^ 63 - 1 = 9223372036854775807

GSQL_INT_MIN = -2 ^ 63 = -9223372036854775808

Operators

An operator is a keyword token which performs a specific computational function to return a resulting value, using the adjacent expressions (its operands) as input values. An operator is similar to a function in that both compute a result from inputs, but syntactically they are different. The most familiar operators are the mathematical operators for addition + and subtraction - .

Tip: The operators listed in this section are designed to behave like the operators in MySQL.

Mathematical Operators and Expressions

We support the following standard mathematical operators and meanings. The latter four ("<<" | ">>" | "&" | "|") are for bitwise operations. See the section below: "Bit Operators".

mathOperator := "*" | "/" | "%" | "+" | "-" | "<<" | ">>" | "&" | "|"

Operator precedences are shown in the following list, from highest precedence to the lowest. Operators that are shown together on a line have the same precedence:

Operator Precedence, highest to lowest
*, /, %
-, +
<<, >>
&
|
==, >=, >, <=, <, !=
Example 1. Math Operators + - * /
CREATE QUERY mathOperators() FOR GRAPH minimalNet api("v2")
{
int x,y;
int z1,z2,z3,z4,z5;
float f1,f2,f3,f4;
x = 7;
y = 3;
z1 = x * y; # z = 21
z2 = x - y; # z = 4
z3 = x + y; # z = 10
z4 = x / y; # z = 2
z5 = x / 4.0; # z = 1
f1 = x / y; # v = 2
f2 = x / 4.0; # v = 1.75
f3 = x % 3; # v = 1
f4 = x % y; # z = 1
PRINT x,y;
PRINT z1 AS xTIMESy, z2 AS xMINUSy, z3 AS xPLUSy, z4 AS xDIVy, z5 AS xDIV4f;
PRINT f1 AS xDIVy, f2 AS xDIV4f, f3 AS xMOD3, f4 AS xMODy;
}
mathOperators.json Results
GSQL > RUN QUERY mathOperators()
{
"error": false,
"message": "",
"version": {
"edition": "developer",
"schema": 0,
"api": "v2"
},
"results": [
{
"x": 7,
"y": 3
},
{
"xTIMESy": 21,
"xPLUSy": 10,
"xMINUSy": 4,
"xDIVy": 2,
"xDIV4f": 1
},
{
"xMODy": 1,
"xMOD3": 1,
"xDIVy": 2,
"xDIV4f": 1.75
}
]
}

Boolean Operators

We support the standard Boolean operators and standard order of precedence: AND, OR, NOT

Bit Operators

Bit operators (<<, >>, &, and |) operate on integers and return an integer.

Bit Operators
CREATE QUERY bitOperationTest() FOR GRAPH minimalNet{
PRINT 80 >> 2; # 20
PRINT 80 << 2; # 320
PRINT 2 + 80 >> 4; # 5
PRINT 2 | 3 ; # 3
PRINT 2 & 3 ; # 2
PRINT 2 | 3 + 2; # 7
PRINT 2 & 3 - 2; # 0
}

String Operators

Operator + can be used for concatenating strings.

Tuple Fields

The fields of the tuple can be accessed using the dot operator.

Comparison Operators and Conditions

A condition is an expression which evaluates to a boolean value of either true or false. One type of condition uses the familiar comparison operators. A comparison operator compares two numeric or string values.

comparisonOperator := "<" | "<=" | ">" | ">=" | "==" | "!="
condition := expr
| expr comparisonOperator expr
| expr [ NOT ] IN setBagExpr
| expr IS [ NOT ] NULL
| expr BETWEEN expr AND expr
| "(" condition ")"
| NOT condition
| condition (AND | OR) condition
| (TRUE | FALSE)
| expr NOT? LIKE expr (ESCAPE ESCAPE_CHAR)?

Strings are compared based on standard lexicographical ordering: (space) < (digit) < (uppercase_letter) < (lowercase_letter).

The comparison operators treat the STRING COMPRESS type as though it is STRING type.

BETWEEN expr AND expr

The expression expr1 BETWEEN expr2 AND expr3 is true if the value expr1 is in the range from expr2 to expr3, including the endpoint values. Each expression must be numeric.

" expr1 BETWEEN expr2 AND expr3 " is equivalent to " expr1 <= expr3 AND expr1 >= expr2".

BETWEEN AND example
CREATE QUERY mathOperatorBetween() FOR GRAPH minimalNet
{
int x;
bool b;
x = 1;
b = (x BETWEEN 0 AND 100); PRINT b; # True
b = (x BETWEEN 1 AND 2); PRINT b; # True
b = (x BETWEEN 0 AND 1); PRINT b; # True
}

IS NULL, IS NOT NULL

IS NULL and IS NOT NULL can be used for checking whether an optional parameter is given any value.

IS NULL example
CREATE QUERY parameterIsNULL (INT p) FOR GRAPH minimalNet {
IF p IS NULL THEN
PRINT "p is null";
ELSE
PRINT "p is not null";
END;
}
parameterIsNULL.json Results
GSQL > RUN QUERY parameterIsNULL(_)
{
"error": false,
"message": "",
"version": {
"edition": "developer",
"schema": 0,
"api": "v2"
},
"results": [{"p is null": "p is null"}]
}
GSQL > RUN QUERY parameterIsNULL(3)
{
"error": false,
"message": "",
"version": {
"edition": "developer",
"schema": 0,
"api": "v2"
},
"results": [{"p is not null": "p is not null"}]
}

Every attribute value stored in GSQL is a valid value, so IS NULL and IS NOT NULL is only effective for query parameters.

LIKE

The LIKE operator is used for string pattern matching. The expression

string1 LIKE string_pattern

evaluates to boolean true if string1 matches the pattern in string_pattern ; otherwise it is false. Both operands must be strings. LIKE may be used only in WHERE clauses. Additionally, string_patternsupports the following wildcard and other symbols, in order to express a pattern:

character or syntax

meaning

%

matches zero or more characters.

Example : %abc% matches any string which contains the sequence "abc".

_ (underscore)

matches any single character. Example : _abc_ematches any 6-character string where the 2nd to 4th characters are "abc" and the last character is "e".

[charlist]

match any character in charlist. charlist is a concatenated character set, with no separators. Example : [Tiger]matches either T, i, g, e, or r.

[^charlist]

matches any character NOT in charlist. Example : [^qxz]matches any character other than q, x, or z.

[!charlist]

matches any character NOT in charlist.

special syntax within charlist

α-β

matches a character in the range from α to β. A charlist can have multiple ranges. Example : [a-mA-M0-3]matches a letter from a to m, upper or lower case, or a digit from 0 to 3.

special syntax within charlist

\\

matches the character \

special syntax within charlist

\\]

matches the character ] No special treatment is needed for [ inside a charlist. Example : %[\\]!]matches any string which ends with either ] or !

Mathematical Functions

There are a number of built-in functions which act on either an accumulator, a base type, or vertex variable. The accumulator function calls are discussed in detail in the "Accumulators" section.

Below is a list of built-in functions which act on either INT, FLOAT, or DOUBLE value(s).

function name and parameters(NUM means INT, FLOAT, or DOUBLE)

description

return type

abs (NUM num )

Returns the absolute value of num

Same as parameter type

sqrt ( NUM num )

Returns the square root of num

FLOAT

pow ( NUM base , NUM exp )

Returns base exp

If base and exp are both INT → INT; Otherwise → FLOAT

acos ( NUM num )

arc cosine

FLOAT

asin ( NUM num )

arc sine

FLOAT

atan ( NUM num )

arc tangent

FLOAT

atan2 (NUM y , NUM x )

arc tangent of y / x

FLOAT

ceil ( NUM num )

rounds upward

INT

cos ( NUM num )

cosine

FLOAT

cosh ( NUM num )

hyperbolic cosine

FLOAT

exp ( NUM num )

base-e exponential

FLOAT

floor ( NUM num )

rounds downward

INT

fmod (NUM numer , NUM denom )

floating-point remainder of numer / denom

FLOAT

ldexp (NUM x , NUM exp )

x * 2 exp

FLOAT

log ( NUM num )

natural logarithm

FLOAT

log10 ( NUM num )

common (base-10) logarithm

FLOAT

sin ( NUM num )

sine

FLOAT

sinh ( NUM num )

hyperbolic sine

FLOAT

tan ( NUM num )

tangent

FLOAT

tanh ( NUM num )

hyperbolic tangent

FLOAT

to_string (NUM num )

Converts num to a STRING value

STRING

float_to_int (FLOAT num )

Converts num to a INT value by truncating the floating part

INT

str_to_int (STRING str )

Converts str to a INT value. If str is a floating number, the floating part is truncated; If str is not a numerical value, returns 0.

INT

Type Conversion Functions

function name and parameters

description

return type

to_string (NUM num)

Converts num to a STRING

STRING

float_to_int (FLOAT num)

Converts num to a INT value by truncating the floating point

INT

str_to_int (STRING str)

Concerts str to a INT value. If str is a floating number, the floating part is truncated. If str is not a numerical value, returns 0.

INT

String Functions

The following built-in functions are provided for text processing. Note that these functions do not modify the input parameter. They each return a new string.

function name and parameters

description

return type

lower(STRING str )

Converts str to all lowercase letters

STRING

upper(STRING str )

Converts str to all uppercase letters

STRING

trim( [ [ LEADING | TRAILING | BOTH ] [STRING removal_char ] FROM ] STRING str )

Trims* characters from the leading and/or trailing ends of str

STRING

  • In the syntax for trim(), the words in bold ( LEADING, TRAILING, BOTH, and FROM ) are keywords which should appear exactly as shown.

  • STRING is just an indicator of the datatype; it is not an explicit keyword.

  • The trim() function have the following options:

    • By using one of the keywords LEADING, TRAILING, or BOTH, the user can specify that characters are to be removed from the left end, right end, or both ends of the string, respectively. If none of these keywords is used, the function will removed from both ends.

    • removal_char is a single character. The function will remove consecutive instances of removal_char , until it encounters a different character. If removal_char is not specified, then trim() removes whitespace (spaces, tabs, and newlines).

CREATE QUERY stringFuncEx() FOR GRAPH minimalNet {
#Example strings
string a = " Abc ";
string b = "aa ABC aaa";
string c = " a A ";
PRINT lower(a); # prints " abc "
PRINT upper(b); # prints "AA ABCC AAA"
PRINT trim(a); # prints "Abc"
PRINT trim(BOTH a); # prints "Abc"
PRINT trim(LEADING c); # prints "a A "
PRINT trim(TRAILING "a" FROM b); # prints "aa ABC "
#You can combine functions for more convenient calling:
PRINT trim(BOTH trim(BOTH " " FROM c) FROM b);
# prints "BC"
}

Notes about the trim() function:

Datetime Functions

The following functions convert from/to DATETIME to/from other types.

function name and parameters

description

return type

to_datetime (STRING str )

Converts str to a DATETIME value

DATETIME

epoch_to_datetime (INT int_value )

Converts int_value to a DATETIME value by epoch time conversion

DATETIME

datetime_to_epoch (DATETIME date )

Converts date to epoch time.

INT

The following function converts a DATETIME value into a string format specified by the user:

function name and parameters

description

return type

datetime_format( DATETIME date[, STRING str ] )

Prints date as the str indicates. The following specifiers may be used as the format of str . The “%” character is required before the format specifier characters. If str is not given, "%Y-%m-%d %H:%M:%S" is used. Specifier:

  • %Y: Year, numeric, four digits

  • %S: Seconds (0..59)

  • %m: Month, numeric (1..12)

  • %M: Minutes, numeric (0..59)

  • %H: Hour, numeric (0..23)

  • %d: Day of the month, numeric (1..31)

STRING

datetime_format example
# Show all posts's post time
CREATE QUERY allPostTime() FOR GRAPH socialNet api("v2") {
start = {post.*};
#PRINT datetime_format(start.postTime, "a message was posted at %H:%M:%S on %Y/%m/%d");
PRINT start[datetime_format(start.postTime, "a message was posted at %H:%M:%S on %Y/%m/%d") as postTimeMsg]; // api v2
}

The followings are other functions related to DATETIME :

function name and parameters

description

return type

now()

Returns the current time in DATETIME type.

DATETIME

year( DATETIME date )

Extracts the year of date .

INT

month( DATETIME date )

Extracts the month of date.

INT

day( DATETIME date )

Extracts the day of month of date .

INT

hour( DATETIME date )

Extracts the hour of date .

INT

minute( DATETIME date )

Extracts the minute of date .

INT

second( DATETIME date )

Extracts the second of date .

INT

datetime_add( DATETIME date, INTERVAL int_value time_unit)

INTERVAL is a keyword; time_unit is one of the keywords YEAR, MONTH, DAY, HOUR, MINUTE, or SECOND. The function returns the DATETIME value which is int_value units later than date. For example, datetime_add( now(), INTERVAL 1 MONTH ) returns a DATETIME value which is 1 month from now.

DATETIME

datetime_sub( DATETIME date, INTERVAL int_value time_unit )

Same as datetime_add, except that the returned value is int_value units earlier than date .

DATETIME

datetime_diff( DATETIMEdate1 , DATETIME date2)

Returns the difference in seconds of these two DATETIME values: ( date1 - date2 ) .

INT

JSONOBJECT and JSONARRAY Functions

JSONOBJECT and JSONARRAY are base types, meaning they can be used as a parameter type, an element type for most accumulators, or a return type. This enables the input and output of complex, customized data structures. For input and output, a string representation of the JSON is used. Hence, the GSQL query language offers several functions to convert a formatted string into JSON and then to search and access the components of a JSON structure.

Data Conversion Functions

The following parsing functions convert a string into a JSONOBJECT or a JSONARRAY:

function name

description

return type

parse_json_object(STRING str )

Converts str into a JSON object

JSONOBJECT

parse_json_array( STRING str )

Converts str into a JSON array

JSONARRAY

Both functions generate a run-time error if the input string cannot be converted into a JSON object or a JSON array. To be properly formatted, besides having the proper nesting and matching of curly braces { } and brackets [ ], each value field must be one of the following: a string (in double quotes "), a number, a boolean ( true or false ), or a JSONOBJECT or JSONARRAY. Each key of a key:value pair must be a string in double quotes.

See examples below.

parse_json_object and parse_json_array example
CREATE QUERY jsonEx (STRING strA, STRING strB) FOR GRAPH minimalNet {
JSONARRAY jsonA;
JSONOBJECT jsonO;
jsonA = parse_json_array( strA );
jsonO = parse_json_object( strB );
PRINT jsonA, jsonO;
}
jsonEx.json Result
GSQL > RUN QUERY jsonEx("[123]","{\"abc\":123}")
or curl -X GET 'http://localhost:9000/query/jsonEx?strA=\[123\]&strB=\{"abc":123\}'
{
"error": false,
"message": "",
"version": {
"edition": "developer",
"schema": 0,
"api": "v2"
},
"results": [{
"jsonA": [123],
"jsonO": {"abc": 123}
}]
}
GSQL > RUN QUERY jsonEx("{123}","{\"123\":\"123\"}")
Runtime Error: {123} cannot be parsed as a json array.

Data Access Methods

JSONOBJECT and JSONARRAY are object classes, each class supporting a set of data access methods, using dot notation:

jsonVariable.functionName(parameter_list)

The following methods (class functions) can act on a JSONOBJECT variable:

method name

description

return type

containsKey(STRING keyStr )

Returns a boolean value indicating whether the JSON object contains the key keyStr .

BOOL

getInt(STRING keyStr )

Returns the numeric value associated with key keyStr as an INT.

INT

getDouble (STRING keyS tr )

Returns the numeric value associated with key keyStr as a DOUBLE.

DOUBLE

getString (STRING keyS tr )

Returns the string value associated with key keyStr .

STRING

getBool (STRING keyS tr )

Returns the bool value associated with key keyStr .

BOOL

getJsonObject (STRING keyS tr )

Returns the JSONOBJECT associated with key keyStr .

JSONOBJECT

getJsonArray (STRING keySt r )

Returns the JSONARRAY associated with key keyStr .

JSONARRAY

The above getType(STRING keyStr ) function generates a run-time error if

  1. The key keyStr doesn't exist, or

  2. The function's return type is different than the stored value type. See the next note about numeric data.

  3. Pure JSON stores "numbers" without distinguishing between INT and DOUBLE, but for TigerGraph, if the input value is all digits, it will be stored as INT. Other numeric values are stored as DOUBLE. The getDouble function can read an INT and return its equivalent DOUBLE value, but it is an error to call getINT for a DOUBLE value.

The following methods can act on a JSONARRAY variable:

method name

description

return type

size()

Returns the size of this array.

INT

getInt( INT idx )

Returns the numeric value at position idx as an INT.

INT

getDouble( INT idx )

Returns the numeric value at position idx as a DOUBLE.

DOUBLE

getString( INT idx )

Returns the string value at position idx .

STRING

getBool( INT idx )

Returns the bool value at position idx .

BOOL

getJsonObject( INT idx )

Returns the JSONOBJECT value at position idx .

JSONOBJECT

getJsonArray( INT idx )

Returns the JSONARRAY value at position idx .

JSONARRAY

Similar to the methods of JSONOBJECT, the above getType(INT idx ) function generates a run-time error if

  1. idx is out of bounds, or

  2. The function's return type is different than the stored value type. See the next note about numeric data.

  3. Pure JSON stores "numbers" without distinguishing between INT and DOUBLE, but for TigerGraph, if the input value is all digits, it will be stored as INT. Other numeric values are stored as DOUBLE. The getDouble function can read an INT and return its equivalent DOUBLE value, but it is an error to call getINT for a DOUBLE value.

Below is an example of using these functions and methods :

JSONOBJECT and JSONARRAY function example
CREATE QUERY jsonEx2 () FOR GRAPH minimalNet {
JSONOBJECT jsonO, jsonO2;
JSONARRAY jsonA, jsonA2;
STRING str, str2;
str = "{\"int\":1, \"double\":3.0, \"string\":\"xyz\", \"bool\":true, \"obj\":{\"obj\":{\"bool\":false}}, \"arr\":[\"xyz\",123,true] }";
str2 = "[\"xyz\", 123, false, 5.0]";
jsonO = parse_json_object( str ) ;
jsonA = parse_json_array( str2 ) ;
jsonO2 = jsonO.getJsonObject("obj");
jsonA2 = jsonO.getJsonArray("arr");
PRINT jsonO;
PRINT jsonO.getBool("bool"), jsonO.getJsonObject("obj"), jsonO.getJsonArray("arr"), jsonO2.getJsonObject("obj"), jsonA2.getString(0) , jsonA.getDouble(3), jsonA.getDouble(1);
}
jsonEx2.json Result
GSQL > RUN QUERY jsonEx2()
{
"error": false,
"message": "",
"version": {
"edition": "developer",
"schema": 0,
"api": "v2"
},
"results": [ {"jsonO": { "arr": [ "xyz", 123, true ],
"bool": true,
"string": "xyz",
"double": 3,
"obj": {"obj": {"bool": false}},
"int": 1
}},
{
"jsonO.getBool(bool)": true,
"jsonA.getDouble(3)": 5,
"jsonA.getDouble(1)": 123,
"jsonO.getJsonObject(obj)": {"obj": {"bool": false}},
"jsonO2.getJsonObject(obj)": {"bool": false},
"jsonO.getJsonArray(arr)": [ "xyz", 123, true ],
"jsonA2.getString(0)": "xyz"
}
]
}

Vertex, Edge, and Accumulator Functions and Attributes

Accessing attributes

Attributes on vertices or edges are defined in the graph schema. Additionally, each vertex and edge has a built-in STRING attribute called type which represents the user-defined type of that edge or vertex. These attributes, including type, can be accessed for a particular edge or vertex with the dot operator:

Accessing attributes with a known name.
name "." "type" // read only. Returns vertexType or edgeType of name
name "." attrName // read/write. Accesses attribute called attrName

DYNAMIC Query Support

The name of the attribute can be parameterized using the getAttr and setAttr vertex functions, described later in this section. This allows you to write dynamic query procedures where the attribute names are specified when you run the query.

For example, the following code snippet shows two different SELECT statements which produce equivalent results. The first uses the dot operator on the vertex variable v to access the "subject" attribute, which is defined in the graph schema. The FROM clause in the first SELECT statement necessitates that any target vertices will be of type "post" (also defined in the graph schema). The second SELECT schema checks that the vertex variable v's type is a "post" vertex by using the dot operator to access the built-in type attribute.

Accessing vertex variable attributes
CREATE QUERY coffeeRelatedPosts() FOR GRAPH socialNet
{
allVertices = {ANY};
results = SELECT v FROM allVertices:s -(:e)-> post:v WHERE v.subject == "coffee";
PRINT results;
results = SELECT v FROM allVertices:s -(:e)-> :v WHERE v.type == "post" AND v.subject == "coffee";
PRINT results;
}
Results for Query coffeeRelatedPosts
GSQL > RUN QUERY coffeeRelatedPosts()
{
"error": false,
"message": "",
"version": {
"edition": "developer",
"schema": 0,
"api": "v2"
},
"results": [
{"results": [{
"v_id": "4",
"attributes": {
"postTime": "2011-02-07 05:02:51",
"subject": "coffee"
},
"v_type": "post"
}]},
{"results": [{
"v_id": "4",
"attributes": {
"postTime": "2011-02-07 05:02:51",
"subject": "coffee"
},
"v_type": "post"
}]}
]
}

Vertex Functions

Below is a list of built-in functions that can be accessed by vertex aliases, using the dot operator:

Syntax for vertex functions
vertex_alias.function_name(parameter)[.FILTER(condition)]

Currently, these functions are only available for vertex aliases (defined in the FROM clause); vertex variables do not have these functions.

Note that in order to calculate outdegree by edge type, the graph schema must be defined such that vertices keep track of their edge types using WITH STATS="OUTDEGREE_BY_EDGETYPE" (however, "OUTDEGREE_BY_EDGETYPE" is now the default STATS option).

function name

description

return type

outdegree ([STRING edgeType ])

Returns the recent number* [see footnote] of outgoing or undirected edges connected to the vertex. If the optional argument edgeType is given, then count only edges of the given edgeType.

INT

neighbors ([ STRING edgeType ])

Returns the set of ids for the vertices which are out-neighbors or undirected neighbors of the vertex. If the optional argument edgeType is given, then include only those neighbors reachable by edges of the given edgeType.

BagAccum<VERTEX>

neighborAttribute ( STRING edgeType, STRING targetVertexType, STRING attrName)

From the given vertex, traverses the given edgeType to the given targetVertexType , and returns the set of values for the vertex attribute called attrName. edgeType can only be string literal.

BagAccum<attrType>

edgeAttribute ( STRING edgeType, STRING attrName)

From the given vertex, traverses the given edgeType, and returns the set of values for the edge attributed called attrName. edgeType can only be string literal.

BagAccum<attrType>

getAttr (STRING attrName,

STRING attrType)

Returns the value of the attribute called attrName of type attrType. attrType can "INT", "UINT", "FLOAT", "DOUBLE", "BOOL", "STRING", or "DATETIME".

attrType

setAttr (STRING attrName, attrType newValue)

Sets the value of the attribute called attrName to newValue.

n/a

Note on outdegree(): This function reads a metadata value stored with each vertex, to avoid traversing the graph and thus have a fast response. The snapshot transaction semantics means that outdegree() may sometimes read an old value if there are concurrent write transactions. To guarantee an accurate count, traverse the neighboring edges and count them with a SumAccum, or use a function like neighbors() and then use size() on the set.

Vertex function examples
CREATE QUERY vertexFunctionExample(vertex<person> m1) FOR GRAPH socialNet {
SetAccum<Vertex> @neighborSet;
SetAccum<Vertex> @neighborSet2;
SetAccum<DATETIME> @attr1;
BagAccum<DATETIME> @attr2;
int deg1, deg2, deg3, deg4;
S = {m1};
S2 = SELECT S
FROM S - (posted:e) -> post:t
ACCUM deg1 = S.outdegree(),
deg2 = S.outdegree("posted"),
deg3 = S.outdegree(e.type), # same as deg2
STRING str = "posted",
deg4 = S.outdegree(str); # same as deg2
PRINT deg1, deg2, deg3, deg4;
S3 = SELECT S
FROM S:s
POST-ACCUM s.@neighborSet += s.neighbors(),
s.@neighborSet2 += s.neighbors("posted"),
s.@attr1 += s.neighborAttribute("posted", "post", "postTime"),
s.@attr2 += s.edgeAttribute("liked", "actionTime");
PRINT S3;
}
vertexFunctionExample Result
GSQL > RUN QUERY vertexFunctionExample("person5")
{
"error": false,
"message": "",
"version": {
"edition": "developer",
"schema": 0,
"api": "v2"
},
"results": [
{
"deg4": 2,
"deg2": 2,
"deg3": 2,
"deg1": 5
},
{"S3": [{
"v_id": "person5",
"attributes": {
"@attr2": [1263330725],
"@attr1": [
1297054971,
1296694941
],
"gender": "Female",
"@neighborSet": [
"6",
"11",
"4",
"person7",
"person4"
],
"id": "person5",
"@neighborSet2": [
"4",
"11"
]
},
"v_type": "person"
}]}
]
}

FILTER

The optional .FILTER(condition) clause offers an additional filter for selecting which elements are added to the output set of the neighbor, neighborAttribute and edgeAttribute functions. The condition is evaluated for each element . If the condition is true, the element is added to the output set; if false, it is not. An example is shown below:

Example: vertex functions with optional filter
CREATE QUERY filterEx (SET<STRING> pIds, INT yr) FOR GRAPH workNet api("v2") {
SetAccum<vertex<company>> @recentEmplr, @allEmplr;
BagAccum<string> @diffCountry, @allCountry;
Start = {person.*};
L0 = SELECT v
FROM Start:v
WHERE v.id IN pIds
ACCUM
# filter using edge attribute
v.@recentEmplr += v.neighbors("worksFor").filter(worksFor.startYear >= yr),
v.@allEmplr += v.neighbors("worksFor").filter(true),
# vertex alias attribute and neighbor type attribute
v.@diffCountry += v.neighborAttribute("worksFor", "company", "id")
.filter(v.locationId != company.country),
v.@allCountry += v.neighborAttribute("worksFor", "company", "id")
;
PRINT yr, L0[L0.@recentEmplr, L0.@allEmplr, L0.@diffCountry, L0.@allCountry]; // api v2
}
Results in filterEx.json
GSQL > RUN QUERY filterEx(["person1","person2"],2016)
{
"error": false,
"message": "",
"version": {
"edition": "developer",
"schema": 0,
"api": "v2"
},
"results": [{
"L0": [
{
"v_id": "person1",
"attributes": {
"L0.@diffCountry": ["company2"],
"L0.@recentEmplr": ["company1"],
"L0.@allCountry": [ "company1", "company2" ],
"L0.@allEmplr": [ "company2", "company1" ]
},
"v_type": "person"
},
{
"v_id": "person2",
"attributes": {
"L0.@diffCountry": ["company1"],
"L0.@recentEmplr": [],
"L0.@allCountry": [ "company1", "company2" ],
"L0.@allEmplr": [ "company2", "company1" ]
},
"v_type": "person"
}
],
"yr": 2016
}]
}

Edge Functions

Below are the built-in functions that can be accessed by edge aliases, using the dot operator. Edge functions follow the same general rules as vertex functions (see above).

function name

description

return type

isDirected()

Returns a boolean value indicating whether this edge is directed or undirected.

BOOL

getAttr (STRING attrName,

STRING attrType)

Returns the value of the attribute called attrName of type attrType. attrType can "INT", "UINT", "FLOAT", "DOUBLE", "BOOL", "STRING", or "DATETIME".

attrType

setAttr (STRING attrName, attrType newValue)

Sets the value of the attribute called attrName to newValue.

n/a

Accumulator Functions

This section describes functions which all to all or most accumulators. Other accumulator functions for each accumulator type are illustrated at the "Accumulator Type" section.

Previous value of accumulator

The tick operator ( ' ) can be used to read the value of an accumulator as it was at the start an ACCUM clause, before any changes that took place within the ACCUM clause. It can only be used in the POST-ACCUM clause. A typical use is to compare the value of the accumulator before and after the ACCUM clause. The PageRank algorithm provides a good example:

v = SELECT s
FROM start:s - (e_type:e) -> :t
ACCUM t.@received_score += s.@score/(s.outdegree(e_type))
POST-ACCUM s.@score = (1.0 - damping) + damping * s.@received_score,
s.@received_score = 0,
@@max_diff += abs(s.@score - s.@score');

In the last line, we compute @@max_diff as the absolute value of the difference between the post-ACCUM score (s.@score) and the pre-ACCUM score (s.@score').

Set/Bag Expression and Operators

SELECT blocks take an input vertex set and perform various selection and filtering operations to produce an output set. Therefore, set/bag expressions and their operators are a useful and powerful part of the GSQL query language. A set/bag expression can use either SetAccum or BagAccum.

BNF
setBagExpr := ["@@"] name
| name "." ["@"] name
| name "." "@" name ("." name "(" [argList] ")")+
| name "." name "(" [argList] ")" [ ".".FILTER "(" condition ")" ]
| "@@" name ("." name "(" [argList] ")")+
| setBagExpr (UNION | INTERSECT | MINUS) setBagExpr
| "(" argList ")"
| "(" setBagExpr ")"

Set/Bag Expression Operators - UNION, INTERSECT, MINUS

The operators are straightforward, when two operands are both sets, the result expression is a set. When at least one operant is a bag, the result expression is a bag. If one operant is a bag and the other is a set, the operator treats the set operant as a bag containing one of each value.

Set/Bag Operator Examples
# Demonstrate Set & Bag operators
CREATE QUERY setOperatorsEx() FOR GRAPH minimalNet {
SetAccum<INT> @@setA, @@setB, @@AunionB, @@AintsctB, @@AminusB;
BagAccum<INT> @@bagD, @@bagE, @@DunionE, @@DintsctE, @@DminusE;
BagAccum<INT> @@DminusA, @@DunionA, @@AunionBbag;
BOOL x;
@@setA = (1,2,3,4); PRINT @@setA;
@@setB = (2,4,6,8); PRINT @@setB;
@@AunionB = @@setA UNION @@setB ; PRINT @@AunionB; // (1, 2, 3, 4, 6, 8)
@@AintsctB = @@setA INTERSECT @@setB; PRINT @@AintsctB; // (2, 4)
@@AminusB = @@setA MINUS @@setB ; PRINT @@AminusB; // C = (1, 3)
@@bagD = (1,2,2,3); PRINT @@bagD;
@@bagE = (2,3,5,7); PRINT @@bagE;
@@DunionE = @@bagD UNION @@bagE; PRINT @@DunionE; // (1, 2, 2, 2, 3, 3, 5, 7)
@@DintsctE = @@bagD INTERSECT @@bagE; PRINT @@DintsctE; // (2, 3)
@@DminusE = @@bagD MINUS @@bagE; PRINT @@DminusE; // (1, 2)
@@DminusA = @@bagD MINUS @@setA; PRINT @@DminusA; // (2)
@@DunionA = @@bagD UNION @@setA; PRINT @@DunionA; // (1, 1, 2, 2, 2, 3, 3, 4)
// because bag UNION set is a bag
@@AunionBbag = @@setA UNION @@setB; PRINT @@AunionBbag; // (1, 2, 3, 4, 6, 8)
// because set UNION set is a set
}
setOperatorsEx Query Results
GSQL > RUN QUERY setOperatorsEx()
{
"error": false,
"message": "",
"version": {
"edition": "developer",
"schema": 0,
"api": "v2"
},
"results": [ {"@@setA": [ 4, 3, 2, 1 ]},
{"@@setB": [ 8, 6, 4, 2 ]},
{"@@AunionB": [ 4, 3, 2, 1, 8, 6 ]},
{"@@AintsctB": [ 4, 2 ]},
{"@@AminusB": [ 3, 1 ]},
{"@@bagD": [ 1, 2, 2, 3 ]},
{"@@bagE": [ 2, 7, 3, 5 ]},
{"@@DunionE": [ 1, 2, 2, 2, 3, 3, 7, 5 ]},
{"@@DintsctE": [ 2, 3 ]},
{"@@DminusE": [ 1, 2 ]},
{"@@DminusA": [2]},
{"@@DunionA": [ 1, 1, 2, 2, 2, 3, 3, 4 ]},
{"@@AunionBbag": [ 6, 8, 1, 2, 3, 4 ]}
]
}

The result of these operators is another set or bag, so these operations can be nested and chained to form more complex expressions, such as

(setBagExpr_A INTERSECT (setBagExpr_B UNION setBagExpr_C) ) MINUS setBagExpr_D

Set/Bag Expression Membership Operators

For example , suppose setBagExpr_A is ("a", "b", "c")

"a" IN setBagExpr_A => true
"d" IN setBagExpr_A => false
"a" NOT IN setBagExpr_A => false
"d" NOT IN setBagExpr_A => true

The IN and NOT IN operators support all base types on the left-hand side, and any set/bag expression on the right-hand side. The base type must be the same as the accumulator's element type. IN and NOT IN return a BOOL value.

The following example uses NOT IN to exclude neighbors that are on a blocked list.

Set Membership example
CREATE QUERY friendsNotInblockedlist (VERTEX<person> seed, SET<VERTEX<person>> blockedList) FOR GRAPH socialNet `{
Start = {seed};
Result = SELECT v
FROM Start:s-(friend:e)-person:v
WHERE v NOT IN blockedList;
PRINT Result;
}
Results for Query friendsNotInblockedlist
GSQL > RUN QUERY friendsNotInblockedlist("person1", ["person2"])
{
"error": false,
"message": "",
"version": {
"edition": "developer",
"schema": 0,
"api": "v2"
},
"results": [{"Result": [{
"v_id": "person8",
"attributes": {
"gender": "Male",
"id": "person8"
},
"v_type": "person"
}]}]
}

Aggregation Functions - COUNT, SUM, MIN, MAX, AVG

The aggregation functions take a set/bag expression as its input parameter and return one value or element.

  • count() : Returns the size (INT) of the set.

  • sum() : Returns the sum of all elements. This is only applicable to a set/bag expression with numeric type.

  • min() : Returns the member with minimum value. This is only applicable to a set/bag expression with numeric type.

  • max() : Returns the member with maximum value. This is only applicable to a set/bag expression with numeric type.

  • avg() : Returns the average of all elements. This is only applicable to a set/bag expression with numeric type. The average is INT if the element type of the set/bag expression is INT.

Aggregation function example
CREATE QUERY aggregateFuncEx(BAG<INT> x) FOR GRAPH minimalNet {
BagAccum<INT> @@t;
@@t += -5; @@t += 2; @@t+= -1;
PRINT max(@@t), min(@@t), avg(@@t), count(@@t), sum(@@t);
PRINT max(x), min(x), avg(x), count(x), sum(x);
}
aggregateFuncEx.json Result
GSQL > RUN QUERY aggregateFuncEx([1,2,5])
{
"error": false,
"message": "",
"version": {
"edition": "developer",
"schema": 0,
"api": "v2"
},
"results": [
{
"sum(@@t)": -4,
"count(@@t)": 3,
"max(@@t)": 2,
"avg(@@t)": -1,
"min(@@t)": -5
},
{
"avg(x)": 2,
"count(x)": 3,
"max(x)": 5,
"min(x)": 1,
"sum(x)": 8
}
]
}

Miscellaneous Functions

SelectVertex()

SelectVertex() reads a data file which lists particular vertices of the graph and returns the corresponding vertex set. This function can only be used in a vertex set variable declaration statement as a seed set. The data file must be organized as a table with one or more columns. One column must be for vertex id. Optionally, another column is for vertex type. SelectVertex() has five parameters explained in the below table: filePath, vertexIdColumn, vertexTypeColumn, separator, and header. The rules for column separators and column headings are the same as for the GSQL Loader.

parameter name

type

description

filePath

string

The absolute file path of the input file to be read. A relative path is not supported.

vertexIdColumn

$ num , or $ "column_name" if header is true.

The vertex id column position.

vertexTypeColumn

$ num , $ "column_name" if header is true, or a vertex type

The vertex type column position or a specific vertex type.

separator

single-character string

The column separator character.

header

bool

Whether this file has a header.

One vertex set variable declaration statement can have multiple SelectVertex() function calls. However, if a declaration statement has multiple SelectVertex() calls referring to the same file, they must use the same separator and header parameters. If any row of the file contains an invalid vertex type, a run time error occurs; if any row of the file contains an nonexistent vertex id, a warning message is shown with the count of nonexistent ids.

Below is a query example using SelectVertex calls, reading from the data file selectVertexInput.csv.

selectVertexInput.csv
c1,c2,c3
person1,person,3
person5,person,4
person6,person,5
selectVertex example
CREATE QUERY selectVertexEx(STRING filename) FOR GRAPH socialNet {
S = {SelectVertex(filename, $"c1", $1, ",", true),
SelectVertex(filename, $2, post, ",", true)
};
PRINT S;
}
Result
GSQL > RUN QUERY selectVertexEx("/file_directory/selectVertexInput.csv")
{
"error": false,
"message": "",
"version": {
"edition": "developer",
"schema": 0,
"api": "v2"
},
"results": [{"S": [
{
"v_id": "4",
"attributes": {
"postTime": "2011-02-07 05:02:51",
"subject": "coffee"
},
"v_type": "post"
},
{
"v_id": "person1",
"attributes": {
"gender": "Male",
"id": "person1"
},
"v_type": "person"
},
{
"v_id": "person5",
"attributes": {
"gender": "Female",
"id": "person5"
},
"v_type": "person"
},
{
"v_id": "3",
"attributes": {
"postTime": "2011-02-05 01:02:44",
"subject": "cats"
},
"v_type": "post"
},
{
"v_id": "5",
"attributes": {
"postTime": "2011-02-06 01:02:02",
"subject": "tigergraph"
},
"v_type": "post"
},
{
"v_id": "person6",
"attributes": {
"gender": "Male",
"id": "person6"
},
"v_type": "person"
}
]}]
}

to_vertex() and to_vertex_set()

to_vertex() and to_vertex_set() convert a string or a string set into a vertex or a vertex set, respectively, of a given vertex type. These two functions are useful when the vertex id(s) are obtained and only known at run-time.

Running these functions requires real-time conversion of an external id to a GSQL internal id, which is a relatively slow process. Therefore,

  1. If the user can always know the id before running the query, define the query with VERTEX or SET<VERTEX> parameters instead of STRING or SET<STRING> parameters, and avoid calling to_vertex() or to_vertex_set().

  2. Calling to_vertex_set() one time is much faster than c alling to_vertex() multiple times . Use to_vertex_set() instead of to_vertex() as much as possible.

The first parameter of to_vertex() is the vertex id string. The first parameter of to_vertex_set() is a string set representing vertex ids. The second parameter of both functions is the vertex type string.

Function signatures for to_vertex() and to_vertex_set()
VERTEX to_vertex(STRING id, STRING vertex_type)
SET<VERTEX> to_vertex_set(SET<STRING>, STRING vertex_type)
SET<VERTEX> to_vertex_set(BAG<STRING>, STRING vertex_type)

to_vertex_set can accept a bag of vertices as input, but the function will reduce the bag to a set by eliminating duplicate items.

If the vertex id or the vertex type doesn't exist, to_vertex() will have a run-time error, as shown below. However, to_vertex_set() will have a run-time error only if the vertex type doesn't exist. If one or more vertex ids are nonexistent, to_vertex_set() will display a warning message but will still run, converting all valid ids and skipping nonexistent vertex ids. If the user wants an error instead of a warning if a nonexistent id is given when converting a string set to a vertex set, the user can use to_vertex() inside a FOREACH loop, instead of to_vertex_set(). See the example below .

to_vertex() and to_vertex_set() example
CREATE QUERY to_vertex_setTest (SET<STRING> uids, STRING uid, STRING vtype) FOR GRAPH workNet {
SetAccum<VERTEX> @@v2, @@v3;
SetAccum<STRING> @@strSet;
VERTEX v;
v = to_vertex (uid, vtype); # to_vertex assigned to a vertex variable
PRINT v; # vertex variable -> only vertex id is printed
@@v2 += to_vertex (uid, vtype); # to_vertex accumulated to a SetAccum<VERTEX>
PRINT @@v2; # SetAccum of vertex -> only vertex ids are printed
S2 = to_vertex_set (uids, vtype); # to_vertex_set assigned to a vertex set variable
PRINT S2; # vertex set variable-> full details printed
@@strSet = uids; # Show SET<STRING> & SetAccumm<STRING> are the same
S3 = to_vertex_set(@@strSet, vtype); # Input to to_vertex_set is SetAccum<STRING>
SDIFF = S2 MINUS S3; # Now S2 = S3, so SDIFF2 is empty
PRINT SDIFF.size();
#FOREACH vid in uids DO # In this case non-existing ids in uids causes run-time error
# @@v3 += to_vertex( vid, vtype );
#END;
#L3 = @@v3;
#PRINT L3;
}
to_vertex_set.json Results
GSQL > RUN QUERY to_vertex_setTest(["person1","personx","person2"], "person3", "person")
{
"error": false,
"message": "Runtime Warning: 1 ids are invalid person vertex ids.",
"version": {
"edition": "developer",
"schema": 0,
"api": "v2"
},
"results": [
{"v": "person3"},
{"@@v2": ["person3"]},
{"S2": [
{
"v_id": "person1",
"attributes": {
"interestList": [ "management", "financial" ],
"skillSet": [ 3, 2, 1 ],
"skillList": [ 1, 2, 3 ],
"locationId": "us",
"interestSet": ["financial", "management" ],
"id": "person1"
},
"v_type": "person"
},
{
"v_id": "person2",
"attributes": {
"interestList": ["engineering"],
"skillSet": [ 6, 5, 3, 2 ],
"skillList":