CREATE/INTERPRET/INSTALL/RUN QUERY
Query Privileges
Users with the querywriter role or greater (designer, admin, globaldesigner, and superuser) can create, install, and drop queries.
Any user with the queryreader role or greater for a given graph can run the queries for that graph.
To implement fine-grained control over which queries can be executed by which sets of users:
  1. 1.
    Group your queries into your desired privilege groups.
  2. 2.
    Define a graph for each privilege group. These graphs can all have the same domain if you wish.
  3. 3.
    Create your queries, assigning each to its appropriate privilege group.
EBNF for CREATE QUERY
1
createQuery := CREATE [OR REPLACE] [DISTRIBUTED] QUERY queryName
2
"(" [parameterList] ")"
3
[FOR GRAPH graphName]
4
[RETURNS "(" baseType | accumType ")"]
5
[API "(" stringLiteral ")"]
6
[SYNTAX syntaxName]
7
"{" queryBody "}"
8
9
interpretQuery := INTERPRET QUERY "(" ")"
10
[FOR GRAPH graphName]
11
[SYNTAX syntaxName]
12
"{" queryBody "}"
13
14
parameterValueList := parameterValue ["," parameterValue]*
15
parameterValue := parameterConstant
16
| "[" parameterValue ["," parameterValue]* "]" // BAG or SET
17
| "(" stringLiteral "," stringLiteral ")" // generic VERTEX value
18
parameterConstant := numeric | stringLiteral | TRUE | FALSE
19
parameterList := parameterType paramName ["=" constant]
20
["," parameterType paramName ["=" constant]]*
21
22
syntaxName := name
23
24
queryBody := [typedefs] [declStmts] [declExceptStmts] queryBodyStmts
25
typedefs := (typedef ";")+
26
declStmts := (declStmt ";")+
27
declStmt := baseDeclStmt | accumDeclStmt | fileDeclStmt
28
declExceptStmts := (declExceptStmt ";")+
29
queryBodyStmts := (queryBodyStmt ";")+
30
31
installQuery := INSTALL QUERY [installOptions] ( "*" | ALL |queryName ["," queryName]* )
32
runQuery := RUN QUERY [runOptions] queryName "(" parameterValueList ")"
33
34
showQuery := SHOW QUERY queryName
35
dropQuery := DROP QUERY ( "*" | ALL | queryName ["," queryName]* )
Copied!
A GSQL query is a sequence of data retrieval-and-computation statements executed as a single operation. Users can write queries to explore a data graph however they like, to read and make computations on the graph data along the way, to update the graph, and to deliver resulting data. A query is analogous to a user-defined procedure or function: it can have one or more input parameters, and it can produce output in two ways: by returning a value or by printing. A query can be run in one of three ways:
  1. 1.
    Define and run an unnamed query immediately:
    1. 1.
      INTERPRET QUERY: execute the query's statements
    Alternately, there is also a built-in REST++ endpoint to interpret a query string: POST /gsqlserver/interpreted_query See the RESTPP API User Guide for details.
  2. 2.
    Define a named query and then run it.
    1. 1.
      CREATE QUERY: define the functionality of the query
    2. 2.
      INTERPRET QUERY: execute the query with input values
  3. 3.
    Define a named query, compile it to optimize performance, and then run it.
    1. 1.
      CREATE QUERY: define the functionality of the query
    2. 2.
      INSTALL QUERY: compile the query
    3. 3.
      RUN QUERY: execute the query with input values
There are some limitations to Interpreted Mode. See the section on INTERPRET QUERY and the appendix section Interpreted GSQL Limitations.

CREATE QUERY

1
createQuery := CREATE [OR REPLACE] [DISTRIBUTED] QUERY queryName
2
"(" [parameterList] ")"
3
[FOR GRAPH graphName]
4
[RETURNS "(" baseType | accumType ")"]
5
[API "(" stringLiteral ")"]
6
[SYNTAX syntaxName]
7
"{" queryBody "}"
8
9
queryBody := [typedefs] [declStmts] [declExceptStmts] queryBodyStmts
Copied!
CREATE QUERY defines the functionality of a query on a given graph schema.
A query has a name, a parameter list, the name of the graph being queried, an optional RETURNS type (see Section "RETURN Statement" for more details), optional specifiers for the output API and the language syntax version, and a body. The body consists of an optional sequence of typedefs, followed by an optional sequence of declarations, then followed by one or more statements. The body defines the behavior of the query.
Dynamic Query Support
As of TigerGraph 3.0+, FOR GRAPH graphName is optional, as long as the graph has been specified already, either when entering gsql: GSQL -g graphName [<gsql_command>] or once inside the GSQL shell, by using the USE GRAPH graphName command. This is one aspect of Dynamic Querying.
If the optional keywords OR REPLACE are included, then this query definition, if error-free, will replace a previous definition with the same query name. The new query will not be installed. That is, CREATE OR REPLACE QUERY name acts like DROP QUERY name CREATE QUERY name However, if there are any errors in this query definition, then the previous query definition will be maintained. If the OR REPLACE option is not used, then GSQL will reject a CREATE QUERY command that uses an existing name.
The DISTRIBUTED option applies only to installations where the graph has been distributed across a cluster. If specified, the query will run with a different execution model which may give better performance for queries that traverse a large portion of the cluster. For details, see Distributed Query Mode.
Typedefs allow the definition of custom types for use within the body. The declarations support the definition of accumulators (see Chapter "Accumulators" for more details) and global/local variables. All accumulators and global variables must be declared before any statements. There are various types of statements that can be used within the body. Typically, the core statement(s) in the body of a query is one or more SELECT, UPDATE, INSERT, DELETE statements. The language supports conditional statements such as an IF statement as well as looping constructs such as WHILE and FOREACH. It also supports calling functions, assigning variables, printing, and modifying the graph data.
The query body may include calls to other queries. That is, the other queries are treated as subquery functions. See the subsection on "Queries as Functions".
Example of a CREATE QUERY statement
1
CREATE QUERY createQueryEx (STRING uid) FOR GRAPH socialNet RETURNS (int)
2
SYNTAX v2 {
3
# declaration statements
4
users = {person.*};
5
# body statements
6
posts = SELECT p
7
FROM users:u-(posted)->:p
8
WHERE u.id == uid;
9
PRINT posts;
10
RETURN posts.size();
11
}
Copied!

Query parameter and return types

This table lists the supported data types for input parameters and return values.
Type
Supported Data Types
Parameter Types
  • Any base type (except EDGE or JSONOBJECT): INT, UINT, FLOAT, DOUBLE, STRING, BOOL, STRING, DATETIME, VERTEX, JSONARRAY
  • SET<baseType>, BAG<baseType>
    • Edge and JSONOBJECT
Return Types
  • any baseType (including EDGE): INT, UINT, FLOAT, DOUBLE, STRING, BOOL, STRING, VERTEX, EDGE, JSONOBJECT, JSONARRAY
  • any accumulator type, except GroupByAccum
API (JSON output format)
Currently, the only option is "v2" (default)
SYNTAX
v1 (default) or v2 (pattern matching). See the SELECT Statement section for an outline of the differences. See Pattern Matching for details on v2.

Default parameter values

You can specify default values for parameters of primitive types when creating a query. Primitive types include:
  • INT
  • UINT
  • FLOAT
  • DOUBLE
  • STRING
  • BOOL
  • STRING
  • DATETIME
To specify the default value for a parameter, use the assignment operator (=) after the parameter name and specify the default value:
Example of a CREATE QUERY command with a default parameter value
1
CREATE QUERY createQueryEx (STRING uid = "Tom") FOR GRAPH socialNet RETURNS (int)
2
SYNTAX v2 {
3
# declaration statements
4
users = {person.*};
5
# body statements
6
posts = SELECT p
7
FROM users:u-(posted)->:p
8
WHERE u.id == uid;
9
PRINT posts;
10
RETURN posts.size();
11
}
Copied!

Dynamic querying

TigerGraph 3.0+ supports Dynamic Querying. This means the query can be written and installed as a saved procedure without referencing a particular graph. Schema details -- the name of the graph, vertex types, edge types, and attributes -- can all be parameterized and only need to be specified at run time.
Here are the ingredients for a dynamic query:
  • Graph name: When creating a query, FOR GRAPH graphName is optional, as long as the graph has been specified already, either when entering gsql: GSQL -g graphName [<gsql_command>] or once inside the GSQL shell, by using the USE GRAPH graphName command.
  • Vertex type and edge type in SELECT statements. Typically, the FROM clause mentions the name of specific vertex types and edge types. String or string set parameters can be used for edge and target types instead.
  • Attribute names. The getAttr and setAttr functions, which take attribute name and data type as string parameters, can be used to parameterize attribute access.
  • INSERT statements: If you are using INSERT to add data to your graph, you need to specify what type of vertex or edge you want to add. This can also be parameterized.
Here is a simple example to demonstrate how to apply Dynamic GSQL Query techniques. Here is the PageRank algorithm from our GSQL Graph Algorithm library. Here is it written with schema information embedded statically in the query:
  • graph name = social
  • vertex type = Page
  • edge type = Link
  • vertex attribute = Score
1
CREATE QUERY pageRank (FLOAT maxChange=0.00, INT maxIter=25,
2
FLOAT damping=0.85) //parameters
3
FOR GRAPH gsql_demo
4
{
5
MaxAccum<float> @@maxDiff = 9999;
6
SumAccum<float> @rcvd_score = 0;
7
SumAccum<float> @score = 1;
8
9
Start = {Page.*};
10
WHILE @@maxDiff > maxChange LIMIT maxIter DO
11
@@maxDiff = 0;
12
V = SELECT s
13
FROM Start:s -(Linkto:e)- Page:t //hardcoded types
14
ACCUM t.@rcvd_score += s.@score/(s.outdegree("Linkto")) //Param
15
POST-ACCUM s.@score = (1.0-damping) + damping * s.@rcvd_score,
16
s.@rcvd_score = 0,
17
@@maxDiff += abs(s.@score - s.@score');
18
END;
19
20
V = SELECT s FROM Start:s
21
POST-ACCUM s.Score = s.@score; //hardcoded attribute
22
}
23
RUN QUERY pageRank(_,_,_)
Copied!
Here is the same algorithm written in Dynamic Querying style:
1
CREATE QUERY pageRankDyn (FLOAT maxChange=0.00, INT maxIter=25,
2
FLOAT damping=0.85,
3
STRING vType, STRING eType, STRING attr) //parameterized schema
4
//no graph name
5
{
6
MaxAccum<float> @@maxDiff = 9999;
7
SumAccum<float> @rcvd_score = 0;
8
SumAccum<float> @score = 1;
9
10
Start = {vType};
11
WHILE @@maxDiff > maxChange LIMIT maxIter DO
12
@@maxDiff = 0;
13
V = SELECT s
14
FROM Start:s -(eType:e)- vType:t //parameterized
15
ACCUM t.@rcvd_score += s.@score/(s.outdegree(eType)) //param
16
POST-ACCUM s.@score = (1.0-damping) + damping * s.@rcvd_score,
17
s.@rcvd_score = 0,
18
@@maxDiff += abs(s.@score - s.@score');
19
END;
20
21
V = SELECT s FROM Start:s
22
POST-ACCUM s.setAttr(attr, s.@score); //parameterized
23
}
24
RUN QUERY pageRankDyn(_,_,_,"Page", "Link", "Score")
Copied!

Statement types

A statement is a standalone instruction that expresses an action to be carried out. The most common statements are data manipulation language (DML) statements. DML statements include the SELECT, UPDATE, INSERT INTO, DELETE FROM, and DELETE statements.
A GSQL query has two levels of statements. The upper-level statement type is called query-body-level statement, or query-body statement for short. This statement type is part of either the top-level block or a query-body control flow block. For example, each of the statements at the top level directly under CREATE QUERY is a query-body statement. If one of the statements is a CASE statement with several THEN blocks, each of the statements in the THEN blocks is also a query-body statement. Each query-body statement ends with a semicolon.
The lower-level statement type is called DML-sub-level statement or DML-sub statement for short. This statement type is used inside certain query-body DML statements, to define particular data manipulation actions. DML-sub-statements are comma-separated. There is no comma or semicolon after the last DML-sub-statement in a block. For example, one of the top-level statements is a SELECT statement, each of the statements in its ACCUM clause is a DML-sub-statement. If one of those DML-sub-statements is a CASE statement, each of the statement in the THEN blocks is a DML-sub-statement.
There is some overlap in the types. For example, an assignment statement can be used either at the query-body level or the DML-sub-level.
1
queryBodyStmts := (queryBodyStmt ";")+
2
3
queryBodyStmt := assignStmt // Assignment
4
| vSetVarDeclStmt // Declaration
5
| gAccumAssignStmt // Assignment
6
| gAccumAccumStmt // Assignment
7
| lAccumAccumStmt // Assignment
8
| funcCallStmt // Function Call
9
| selectStmt // Select
10
| queryBodyCaseStmt // Control Flow
11
| queryBodyIfStmt // Control Flow
12
| queryBodyWhileStmt // Control Flow
13
| queryBodyForEachStmt // Control Flow
14
| BREAK // Control Flow
15
| CONTINUE // Control Flow
16
| updateStmt // Data Modification
17
| insertStmt // Data Modification
18
| queryBodyDeleteStmt // Data Modification
19
| printStmt // Output
20
| printlnStmt // Output
21
| logStmt // Output
22
| returnStmt // Output
23
| raiseStmt // Exception
24
| tryStmt // Exception
25
26
DMLSubStmtList := DMLSubStmt ["," DMLSubStmt]*
27
28
DMLSubStmt := assignStmt // Assignment
29
| funcCallStmt // Function Call
30
| gAccumAccumStmt // Assignment
31
| lAccumAccumStmt // Assignment
32
| attrAccumStmt // Assignment
33
| vAccumFuncCall // Function Call
34
| localVarDeclStmt // Declaration
35
| DMLSubCaseStmt // Control Flow
36
| DMLSubIfStmt // Control Flow
37
| DMLSubWhileStmt // Control Flow
38
| DMLSubForEachStmt // Control Flow
39
| BREAK // Control Flow
40
| CONTINUE // Control Flow
41
| insertStmt // Data Modification
42
| DMLSubDeleteStmt // Data Modification
43
| printlnStmt // Output
44
| logStmt // Output
Copied!
Guidelines for understanding statement type hierarchy:
  • Top-level statements are Query-Body type (each statement ending with a semicolon).
  • The statements within a DML statement are DML-sub statements (comma-separated list).
  • The blocks within a Control Flow statement have the same type as the entire Control Flow statement itself.
Schematic illustration of relationship between queryBodyStmt and DMLSubStmt
1
# Each statement's operation type is either ControlFlow, DML, or other.
2
# Each statement's syntax type is either queryBodyStmt or DMLSubStmt.
3
4
CREATE QUERY stmtTypes (parameterList) FOR GRAPH g [
5
other queryBodyStmt1;
6
ControlFlow queryBodyStmt2 # ControlFlow inside top level.
7
other queryBodyStmt2.1; # subStmts in ControlFlow are queryBody unless inside DML.
8
ControlFlow queryBodyStmt2.2 # ControlFlow inside ControlFlow inside top level
9
other queryBodyStmt2.2.1;
10
other queryBodyStmt2.2.2;
11
END;
12
DML queryBodyStmt2.3 # DML inside ControlFlow inside top-level
13
other DMLSubStmt2.3.1, # switch to DMLSubStmt
14
other DMLSubStmt2.3.2
15
;
16
END;
17
DML queryBodyStmt3 # DML inside top level.
18
other DMLSubStmt3.1, # All subStmts in DML must be DMLSubStmt type
19
ControlFlow DMLSubStmt3.2 # ControlFlow inside DML inside top level
20
other DMLSubStmt3.2.1,
21
other DMLSubStmt3.2.2
22
,
23
DML DMLsubStmt3.3
24
other DMLSubStmt3.3.1,
25
other DMLSubStmt3.3.2
26
;
27
other queryBodyStmt4;
Copied!
Here is a descriptive list of query-body statements:
EBNF term
Common Name
Description
assignStmt
Assignment Statement
See "Declaration and Assignment Statements"
vSetVarDeclStmt
Vertex Set Variable Declaration Statement
See "Declaration and Assignment Statements"
gAccumAssignStmt
Global Accumulator Assignment Statement
See "Declaration and Assignment Statements"
gAccumAccumStmt
Global Accumulator Accumulation Statement
See "Declaration and Assignment Statements"
lAccumAccumStmt
Local Accumulator Accumulation Statement
See "Declaration and Assignment Statements"
funcCallStmt
Functional Call or Query Call Statement
See "Declaration and Assignment Statements"
selectStmt
SELECT Statement
See "SELECT Statement"
queryBodyCaseStmt
query-body CASE statement
See "Control Flow Statements"
queryBodyIfStmt
query-body IF statement
See "Control Flow Statements"
queryBodyWhileStmt
query-body WHILE statement
See "Control Flow Statements"
queryBodyForEachStmt
query-body FOREACH statement
See "Control Flow Statements"
updateStmt
UPDATE Statement
See "Data Modification Statements"
insertStmt
INSERT INTO statement
See "Data Modification Statements"
queryBodyDeleteStmt
Query-body DELETE Statement
See "Data Modification Statements"
printStmt
PRINT Statement
See "Output Statements"
logStmt
LOG Statement
See Output Statements"
returnStmt
RETURN Statement
See "Output Statements"
raiseStmt
PRINT Statement
See "Exception Statements"
tryStmt
TRY Statement
See "Exception Statements"
Here is a descriptive list of DML-sub-statements:
EBNF term
Common Name
Description
assignStmt
Assignment Statement
See "Declaration and Assignment Statements"
funcCallStmt
Functional Call Statement
See "Declaration and Assignment Statements"
gAccumAccumStmt
Global Accumulator Accumulation Statement
See "Declaration and Assignment Statements"
lAccumAccumStmt
Local Accumulator Accumulation Statement
See "Declaration and Assignment Statements"
attrAccumStmt
Attribute Accumulation Statement
See "Declaration and Assignment Statements"
vAccumFuncCall
Vertex-attached Accumulator Function Call Statement
See "Declaration and Assignment Statements"
localVarDeclStmt
Local Variable Declaration Statement
See "SELECT Statement"
insertStmt
INSERT INTO Statement
See "Control Flow Statements"
DMLSubDeleteStmt
DML-sub DELETE Statement
See "Data Modification Statements"
DMLSubcaseStmt
DML-sub CASE statement
See "Data Modification Statements"
DMLSubIfStmt
DML-sub IF statement
See "Data Modification Statements"
DMLSubForEachStmt
DML-sub FOREACH statement
See "Data Modification Statements"
DMLSubWhileStmt
DML-sub WHILE statement
See "Data Modification Statements"
logStmt
LOG Statement
See "Output Statements"

INTERPRET QUERY

INTERPRET QUERY runs a query by translating it line-by-line. This is in contrast to the 2-step flow: (1) INSTALL to pre-translate and optimize a query, then (2) RUN to execute the installed query. The basic trade-off between INTERPRET QUERY and INSTALL/RUN QUERY is as follows:
  • INTERPRET:
    • Starts running immediately but may take longer to finish than running an installed query.
    • Suitable for ad hoc exploration of a graph or when developing and debugging an application, and rapid experimentation is desired.
    • Supports most but not all of the features of the full GSQL query language. See the Appendix section Interpreted GSQL Limitations.
  • INSTALL/RUN:
    • Takes up to a minute to INSTALL.
    • Runs faster than INTERPRET, from only a few percent faster to twice as fast.
    • Should always be used for production environments with fixed queries.
There are two GSQL syntax options for Interpreted GSQL: Immediate mode and Saved-query mode. In addition there is also a predefined RESTful endpoint for running interpreted GSQL: POST /gsqlserver/interpreted_query. The query body is sent as the payload of the request. The syntax is like the Immediate query option, except that it is possible to provide parameters, using the query string of the endpoint's request URL. The example below shows a parameterized query using the POST /gsqlserver/interpreted_query endpoint. For more details, see the RESTPP API User Guide.
Interpreted GSQL REST Endpoint with Immediate Query
1
curl --user tigergraph:tigergraph -X POST 'localhost:14240/gsqlserver/interpreted_query?a=10' -d '
2
INTERPRET QUERY (int a) FOR GRAPH gsql_demo {
3
PRINT a;
4
}
5
'
Copied!

Immediate mode: define and interpret

interpret-anonymous-query syntax
1
interpretQuery := INTERPRET QUERY "(" ")"
2
[FOR GRAPH graphName]
3
[SYNTAX syntaxName]
4
"{" queryBody "}"
Copied!
This syntax is similar in concept to SQL queries. Queries are not named, do not accept parameters, and are not saved after being run. Syntax differences from compiled GSQL:
  • The keyword CREATE is replaced with INTERPRET.
  • The query is executed immediately by the INTERPRET statement. The INSTALL and RUN statements are not used.
  • Parameters are not accepted.
Compare the example below to the example in the Create Query section:
  • No query name, no parameters, no RETURN statement.
  • Because no parameter is allowed, the parameter uid is set within the query.
Example of Immediate Mode for INTERPRET QUERY
1
INTERPRET QUERY () FOR GRAPH socialNet {
2
# declaration statements
3
STRING uid = "Jane.Doe";
4
users = {person.*};
5
# body statements
6
posts = SELECT p
7
FROM users:u-(posted)->:p
8
WHERE u.id == uid;
9
PRINT posts, posts.size();
10
}
Copied!

Interpret a created query

interpret-saved-query syntax
1
runQuery := (RUN | INTERPRET) QUERY [runOptions] queryName "(" parameterValueList ")"
Copied!
This syntax is like RUN query, except
  1. 1.
    The keyword RUN is replaced with INTERPRET.
  2. 2.
    Some options may not be supported.
Example of Interpret-Only Mode for INTERPRET QUERY
1
INTERPRET QUERY createQueryEx ("Jane.Doe")
Copied!

INSTALL QUERY

1
installQuery := INSTALL QUERY [installOptions] ( "*" | ALL | queryName ["," queryMame]* )
Copied!
INSTALL QUERY installs a query or multiple queries on a graph. Installing a query compiles the procedures described by the query as well as generates a REST endpoint for running the query.
Installing a query allows the query to be run through the RUN QUERY command as well as through its REST endpoint, both offering stronger performance as compared to running the query through the INTERPRET QUERY command. The INSTALL QUERY command will install the queries specified, with query names separated by a comma.
If a query calls a subquery, the query can only be installed after one of the following conditions is met:
  • The subquery has already been installed
  • The subquery is being installed in the same INSTALL QUERY command as the query itself
If a subquery that was previously installed is dropped from the graph, all installed queries that call the subquery will be disabled. To re-enable a disabled query, all its subqueries need to be installed with the same parameters and return type.
When a single INSTALL QUERY command installs multiple queries, each query is installed independently. If one query fails to be installed, it will not affect the installation of other queries.
To install a query, the user needs to have the WRITE_QUERY privilege on the graph where the query is to be installed or on the global scope.
Users can also install all uninstalled queries on a graph with INSTALL QUERY, using either of the following commands:
  • INSTALL QUERY *
  • INSTALL QUERY ALL
Installing takes several seconds for each query. The current version does not support concurrent installation and running of queries. Other concurrent graph operations will be delayed until the installation finishes.
Concurrent INSTALL QUERY commands are allowed as long as only one INSTALL QUERY command is running on a single graph. Concurrent INSTALL QUERY commands are not allowed on a single graph.

Options for INSTALL QUERY

The following options are available:
Option
Effect
-FORCE
Reinstall the query even if the system indicates the query is already installed.
This is useful for overwriting an installation that is corrupted or otherwise outdated, without having to drop and then recreate the query. If this option is not used, the GSQL shell will refuse to re-install a query that is already installed.
-DISTRIBUTED
If you have a distributed database deployment, installing the query in Distributed Query Mode can increase performance for single queries - using a single worker from each available machine to yield results. Certain cases may benefit more from this option than others -- more detailed information is available on the next page: Distributed Query Mode.

Optimize installed queries

INSTALL QUERY -OPTIMIZE
Users can run INSTALL QUERY -OPTIMIZE to optimize all installed queries. The names of the individual queries are not needed. This operation optimizes all previously installed queries, reducing their run times by about 20%. Optimize a query if query run time is more important to you than query installation time.

RUN QUERY

The RUN QUERY command runs an installed query. To run a query with the RUN QUERY command, specify the query name, followed by the query parameters enclosed in parentheses. Running a query executes all statements in the query body and produces output as specified by the output statements in the query.
You can also run an installed query through REST requests - see Run an installed query.

Syntax

RUN QUERY syntax
1
runQuery := (RUN | INTERPRET) QUERY [runOptions] queryName
2
"(" parameterValueList | parameterValueJSON ")"
3
4
runOptions := ( "-av" | "-d" )*
5
parameterValueList := parameterValue ["," parameterValue]*
6
parmeterValueJSON ::= '{"'parameterName'":' parameterValue(', "'parameterName'":' parameterValue)* '}'
Copied!

Query parameters

There are two ways of passing parameters to a query in a RUN QUERY command:

Parameter list

To pass parameters to a query with a list, the parameters must be put in the same order as they were in the query definition. Each value passed in will correspond to the parameter at the same index when the query was created.
To use the default value for a parameter, use the _ character for the value of the parameter. You can also omit parameters to use their default value. However, if you omit one parameter, you also have to omit all parameters that come after that parameter.
For example, if we have the following query definition:
1
CREATE QUERY greetPerson(INT age = 3, STRING name = "John",
2
DATETIME birthday = to_datetime("2019-02-19 19:19:19"))
3
{
4
PRINT age, name, birthday;
5
}
Copied!
To run the query with default values for the parameter name, use _ in the place of the second parameter value:
1
GSQL > RUN QUERY greetPerson (21, _, "2020-02-02 20:02:20")
2
# Below is the query output
3
{
4
"error": false,
5
"message": "",
6
"version": {
7
"schema": 0,
8
"edition": "enterprise",
9
"api": "v2"
10
},
11
"results": [{
12
"birthday": "2020-02-02 20:02:20",
13
"name": "John",
14
"age": 21
15
}]
16
}
Copied!
To use the default values for both the second and the third parameters, you can omit both parameters and only provide a value for the first parameter.
1
GSQL > RUN QUERY greetPerson(21)
2
# Below is the query output
3
{
4
"error": false,
5
"message": "",
6
"version": {
7
"schema": 0,
8
"edition": "enterprise",
9
"api": "v2"
10
},
11
"results": [{
12
"birthday": "2019-02-19 19:19:19",
13
"name": "John",
14
"age": 21
15
}]
16
}
Copied!

Parameter JSON object

To pass query parameters by name with a JSON object, map the parameter names to their values in a JSON object enclosed in parentheses. Parameters that are not named in the JSON object will keep their default values for the execution of the query.
For example, if we have the following query:
1
CREATE QUERY greetPerson(INT age = 3, STRING name = "John",
2
DATETIME birthday = to_datetime("2019-02-19 19:19:19"))
3
{
4
PRINT age, name, birthday;
5
}
Copied!
Supplying the parameters with a JSON object will look like the following. The parameter birthday is not named in the parameter JSON object and therefore takes the default value:
1
RUN QUERY greetPerson( {"name": "Emma", "age": 21} )
Copied!

Complex type parameter passing

This subsection describes how to format the complex type parameter values when executing a query by RUN QUERY. More details about all parameter types are described in Section "Query Parameter Types".

Parameter list

Parameter type
Syntax
Example
DATETIME
Use a string formatted as "YYYY-MM-DD HH-MM-SS"
"2019-02-19 19:19:19"
Set or bag of primitives
Use square brackets to enclose the collection of values.
A set of integers: [1,5,10]
VERTEX<type>
If the vertex type is specified in the query definition, then the vertex argument is vertex_id
The vertex type is person and the desired ID is person2. "person2"
VERTEX
(type not pre-specified)
If the type is not defined in the query definition, then the argument must provide both the id and type in parentheses:(vertex_id, vertex_type)
A vertex with ID "person1" and type="person: ("person1","person")
Set or bag of VERTEX<type>
Same as a SET or BAG of primitives, where the primitive type is vertex_id.
[ "person3", "person4" ]
Set or bag of VERTEX
(type not pre-specified)
Same as a SET or BAG of vertices, with vertex type not pre-specified. Square brackets enclose a comma-separated list of vertex (id, type) pairs. Mixed types are permitted.
[ ("person1","person"),("11","post") ]

Parameter JSON object

Parameter type
Syntax
Example
DATETIME
Use a string formatted as "YYYY-MM-DD HH-MM-SS"
"2019-02-19 19:19:19"
Set or bag of primitives
Use a JSON array containing the primitive values
["a", "list", "of", "args"]
VERTEX<type>
Use a JSON object containing a field "id" for the vertex ID and a field "type" for the type of the vertex
{"id": "person1",
"type": "person"}
VERTEX (type not specified)
Use a JSON object containing a field "id" for the vertex ID
{"id": "person1"}
Set or bag of VERTEX<type>
Use a JSON array containing a list of JSON VERTEX<type> object
[{"id": "person1"}, {"id": "person2"}]
Set or bag of vertices of unspecified types
Use a JSON array containing a list of JSON VERTEX
[{"id": "person1",
"type": "person"},{"id": "person2",
"type": "person"}]

Options

All-vertex mode -av option

Some queries run with all or almost all vertices in a SELECT statement s, e.g. PageRank algorithm. In this case, the graph processing engine can run much more efficiently in all-vertex mode. In the all-vertex mode, all vertices are always selected, and the following actions become ineffective:
  • Filtering with selected vertices or vertex types. The source vertex set must be all vertices.
  • Filtering with the WHERE clause.
  • Filtering with the HAVING clause.
  • Assigning designated vertex or designated type of vertexes. E.g. X = { vertex_type .*}
To run the query in all-vertex mode, use the -av option in shell mode or include __GQUERY__USING_ALL_ACTIVE_MODE=true in the query string of an HTTP request.
1
GSQL > RUN QUERY -av test()
2
3
## In a curl URL call. Note the use of both single and double underscores.
4
curl -X GET 'http://localhost:9000/query/graphname/queryname?__GQUERY__USING_ALL_ACTIVE_MODE=true'
Copied!

Detached mode -async option

Typically, the GSQL RUN QUERY command runs in the foreground and does not produce output until the query completes, which is inconvenient in the case of long-running queries. Starting with TigerGraph 3.1, you can run queries in Detached Mode to enable background execution of long-running queries.
Queries executed in Detached mode are still subject to the system timeout limit. The default timeout limit is 16 seconds and can be set using theGSQL-TIMEOUT header.
To run a query in Detached Mode from the command line, use the-asyncoption for theRUN QUERYcommand:
1
GSQL > RUN QUERY -async <queryName>
Copied!
You will receive a JSON response immediately containing a query ID (request_id):
1
{
2
"error": false,
3
"message": "The query is successfully submitted. Please check query status using the request id.",
4
"request_id": "<RequestID>"
5
}
6
Copied!
To run queries in Detached Mode via RESTPP endpoint call, use the GSQL-ASYNC header and set its value to true. If the query takes parameters, put them in the query string:
1
$ curl -s -H "GSQL-ASYNC:true" GET "http://localhost:9000/query/<graphName>/<queryName>?parameter1=<parameter1>
Copied!
To check the status and results of the queries executed in Detached Mode, use the /query_status and the /query_result RESTPP endpoints.

GSQL Query output format

The standard output of GSQL queries is in industry-standard JSON format. A JSON object is an unordered set of key-value pairs, enclosed in curly braces. Among the acceptable data types for a JSON value are array and object. A JSON array is an ordered list of values, enclosed in square brackets. Since values can be objects or arrays, JSON supports hierarchical, nested structures. Strings are enclosed in double quotation marks. We also use the term field to refer to a key (or a key-value pair) of a given object.
At the top level of the JSON structure are four required fields ("version", "error", "message", and "results") and one dependent field ("code"). If a query is successful, the value of "error" will be "false", the "message" value will be empty, and the "results" value will be the intended output of the query. If an error or exception occurred during query execution, the "error" value will be "true", the "message" value will be a string message describing the error condition, and the "results" field will be empty. Also, the "code" field will contain an error code.
Beginning with version 2 (v2) of the output specification, an additional top-level field is required: "version". The "version" value is an object with the following fields:
Field
Description
api
String specifying the output API version. Values are specified as follows:
  • "v1": Output API used in TigerGraph platform v0.8 through v1.0. NOTE: "v1" support is no longer available as of TigerGraph v3.0.
  • "v2" (default): Output API introduced in TigerGraph platform v1.1 This is the latest API.
edition
String indicating the edition of the product.
schema
Integer representing which version of the user's graph schema is currently in use. When a CREATE GRAPH statement is executed, the version is initialized to 0. Each time a SCHEMA_CHANGE JOB is run, the schema value is incremented by 1 (e.g., 1, 2, etc.).
Other top-level objects, such as "code" may appear in certain circumstances. Note that the top-level objects are enclosed in curly braces, meaning that they form an unordered set. They may appear in any order.
Below is an example of the output of a successful query:
Top Level JSON of a Valid Query - Example
1
{
2
"version": {"edition": "developer","api": "v2","schema": "1"},
3
"error": false,
4
"message": "",
5
"results": [
6
{results_of_PRINT_statement_1},
7
...,
8
{results_of_PRINT_statement_N}
9
]
10
}
Copied!
The value of the "results" key-value pair is a sequential list of the data objects specified by the PRINT statements of the query. The list order follows the order of PRINT execution. The detailed format of the PRINT statement results is described in Output Statements and FILE Objects.
The following REST response misspells the name of the endpoint
GET echo/ Request and Response
1
curl -X GET "http://localhost:9000/eco"
Copied!
and generates the following output:
1
{
2
"version": {"edition":"developer","api":"v2","schema":0},
3
"error": true,
4
"message": "Endpoint is not found from url = /eco, please use GET /endpoints to list all valid endpoints.",
5
"code": "REST-1000"
6
}
Copied!

Changing the default output API

The following GSQL statement can be used to set the JSON output API configuration.
1
SET json_api = <version_string>
Copied!
This statement sets a persistent system parameter. Each version of the TigerGraph platform is pre-configured to what was the latest output API that at the time of release. For example, platform version 1.1 is configured so that each query will produce v2 output by default.
As of TigerGraph v3.0, the only supported JSON API is "v2".

SHOW QUERY

1
showQuery := SHOW QUERY queryName
Copied!
To show the GSQL text of a query, run SHOW QUERY query_name . The query_name argument can use * or ? wildcards from Linux globbing, or it can be a regular expression when preceded by -r. See SHOW: View Parts of the Catalog
Additionally, the ls GSQL command lists all created queries and identifies which queries have been installed.

DROP QUERY

1
dropQuery := DROP QUERY ( "*" | ALL | queryName ["," queryName]* )
Copied!
To drop a query, run DROP QUERY query_name . The query will be uninstalled (if it has been installed) and removed from the dictionary. The GSQL language will refuse to drop an installed query if another query is installed which calls query Q. That is, all calling queries must be dropped before or at the same time that their called subqueries are dropped.
To drop all queries, either of the following commands can be used: DROP QUERY ALL DROP QUERY *
The scope of ALL depends on the user's current scope. If the user has set a working graph, then DROP ALL removes all the jobs for that graph. If a superuser has set their scope to be global, then DROP ALL removes all jobs across all graph spaces.