Queries
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.
CREATE QUERY
createQuery := CREATE [OR REPLACE] [DISTRIBUTED] QUERY queryName
"(" [parameterList] ")"
[FOR GRAPH graphName]
[RETURNS "(" baseType | accumType ")"]
[API "(" stringLiteral ")"]
[SYNTAX syntaxName]
"{" queryBody "}"
interpretQuery := INTERPRET QUERY "(" ")"
[FOR GRAPH graphName]
[SYNTAX syntaxName]
"{" queryBody "}"
parameterValueList := parameterValue ["," parameterValue]*
parameterValue := parameterConstant
| "[" parameterValue ["," parameterValue]* "]" // BAG or SET
| "(" stringLiteral "," stringLiteral ")" // generic VERTEX value
parameterConstant := numeric | stringLiteral | TRUE | FALSE
parameterList := parameterType paramName ["=" constant]
["," parameterType paramName ["=" constant]]*
syntaxName := name
queryBody := [typedefs] [declStmts] [declExceptStmts] queryBodyStmts
typedefs := (typedef ";")+
declStmts := (declStmt ";")+
declStmt := baseDeclStmt | accumDeclStmt | fileDeclStmt
declExceptStmts := (declExceptStmt ";")+
queryBodyStmts := (queryBodyStmt ";")+
installQuery := INSTALL QUERY [installOptions] ( "*" | ALL |queryName ["," queryName]* )
runQuery := RUN QUERY [runOptions] queryName "(" parameterValueList ")"
showQuery := SHOW QUERY queryName
dropQuery := DROP QUERY ( "*" | ALL | queryName ["," queryName]* )
A query can be run in one of three ways:
-
Define and run an unnamed query immediately:
-
INTERPRET QUERY
: execute the query’s statementsAlternately, 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.
-
-
Define a named query and then run it.
-
CREATE QUERY
: define the functionality of the query -
INTERPRET QUERY
: execute the query with input values
-
-
Define a named query, compile it to optimize performance, and then run it.
-
CREATE QUERY
: define the functionality of the query -
INSTALL QUERY
: compile the query -
RUN QUERY
: execute the query with input values
-
There are some limitations to Interpreted Mode. See the section on Interpret a created query and the appendix section Interpreted GSQL Limitations.
CREATE QUERY
createQuery := CREATE [OR REPLACE] [DISTRIBUTED] QUERY queryName
"(" [parameterList] ")"
[FOR GRAPH graphName]
[RETURNS "(" baseType | accumType ")"]
[API ( v2 )]
[SYNTAX syntaxName]
"{" queryBody "}"
queryBody := [typedefs] [declExceptStmts] queryBodyStmts
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.
Parameters
OR REPLACE
-
If the optional keywords
OR REPLACE
are included, then this query definition, if error-free, replaces a previous definition with the same query name. If the original query was installed, you’ll need to reinstall the new query.However, if there are any errors in this query definition, then the previous query definition is maintained. If the
OR REPLACE
option is not used, GSQL rejects aCREATE QUERY
command that uses an existing name.Only the query owner is allowed to run
CREATE OR REPLACE
on a query. However, if you have theWRITE_QUERY
RBAC privilege on the corresponding graph, you can executeDROP QUERY
to drop the query and create a new one with the same name.The difference between
CREATE OR REPLACE
and dropping and recreating a query are the following:-
Only the query owner is allowed to run
CREATE OR REPLACE
on a query directly, while anyone with theWRITE_QUERY
privilege on the corresponding graph and drop and recreate the query. -
The ACLs on the original query are dropped when you drop the query.
CREATE OR REPLACE
keeps the original ACLs intact.
-
DISTRIBUTED
-
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. queryName
-
Name of the query.
parameterList
-
A list of parameters for the query. The parameter list for a query follows the following form:
parameterType paramName ["=" constant] ["," parameterType paramName ["=" constant]]*
For a list of allowed data types for query parameters, see Query parameter types.
FOR GRAPH graphName
-
Specifies the graph that the query is created on. This clause is optional if you have already specified a working graph either when entering GSQL or through the
USE GRAPH
command. RETURNS
clause-
The optional
RETURNS
clause makes the query a subquery and specifies the data type to be returned in theRETURN
statement of the subquery. For more information, see Subqueries. API v2
-
Specifies the JSON output format. The only option is v2.
SYNTAX syntaxName
-
Specifies the GSQL syntax version to be used by the query. See the Query Language Syntax Versions for an outline of the differences. See Pattern Matching tutorial for details on v2.
queryBody
-
The query body contains a sequence of data retrieval-and-computation statements.
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 anIF
statement as well as looping constructs such asWHILE
andFOREACH
. 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 "subqueries".
Additionally, GSQL supports openCypher syntax in the query body. See pages openCypher in GSQL, Writing and Running openCypher in GSQL Shell, and openCypher Pattern Support in GSQL to learn more about openCypher and for examples.
Examples
CREATE QUERY
statementCREATE QUERY create_query_ex (STRING uid) FOR GRAPH Social_Net RETURNS (int) SYNTAX v2 {
// declaration statements
users = {Person.*};
// body statements
posts = SELECT p
FROM users:u-(Posted>)-:p
WHERE u.id == uid;
PRINT posts;
RETURN posts.size();
}
Default query 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
-
DATETIME
To specify the default value for a parameter, use the assignment operator (=
) after the parameter name and specify the default value:
CREATE QUERY
command with a default parameter valueCREATE QUERY create_query_ex (STRING uid = "Tom") FOR GRAPH Social_Net RETURNS (int) SYNTAX v2 {
// declaration statements
users = {Person.*};
// body statements
posts = SELECT p
FROM users:u-(Posted>)-:p
WHERE u.id == uid;
PRINT posts;
RETURN posts.size();
}
To specify the default value of a DATETIME
type parameter, use the to_datetime()
function.
You cannot use other functions that return a DATETIME
value to specify the default value.
For example, the following query definition sets the default value of d1
to 2023-01-01 00:00:00
.
CREATE QUERY print_default(DATETIME d1 = to_datetime("2023-01-01 00:00:00")) {
PRINT d1;
}
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. The graph name can be specified either when entering GSQL:GSQL -g graphName [<gsql_command>]
or once inside the GSQL shell, by using theUSE GRAPH graphName
command. -
Vertex type and edge type in
SELECT
statements. Typically, theFROM
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
andsetAttr
functions, which take attribute name and data type as string parameters, can be used to parameterize attribute access. -
INSERT
statements: If you are usingINSERT
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.
The following example demonstrates Dynamic GSQL Query techniques using the PageRank algorithm from our Graph Data Science library. The query is written with schema information embedded statically in it:
-
graph name = social
-
vertex type = Page
-
edge type = Link
-
vertex attribute = Score
CREATE QUERY page_rank (FLOAT max_change=0.00, INT max_iter=25,
FLOAT damping=0.85) // parameters
FOR GRAPH Gsql_Demo
{
MaxAccum<float> @@max_diff = 9999;
SumAccum<float> @rcvd_score = 0;
SumAccum<float> @score = 1;
Start = {Page.*};
WHILE @@maxDiff > max_change LIMIT max_iter DO
@@maxDiff = 0;
V = SELECT s
FROM Start:s -(Linkto:e)- Page:t // hardcoded types
ACCUM t.@rcvd_score += s.@score/(s.outdegree("Linkto")) // Param
POST-ACCUM s.@score = (1.0-damping) + damping * s.@rcvd_score, s.@rcvd_score = 0, @@max_diff += abs(s.@score - s.@score');
END;
V = SELECT s FROM Start:s
POST-ACCUM s.Score = s.@score; // hardcoded attribute
}
CREATE QUERY pagerank_dyn (FLOAT max_change=0.00, INT max_iter=25,
FLOAT damping=0.85, STRING v_type, STRING e_type, STRING attr)
{
MaxAccum<FLOAT> @@max_diff = 9999;
SumAccum<FLOAT> @rcvd_score = 0;
SumAccum<FLOAT> @score = 1;
Start = {v_type};
WHILE @@max_diff > max_change LIMIT max_iter DO
@@max_diff = 0;
V = SELECT s
FROM Start:s -(e_type:e)- v_type:t // Parameterized
ACCUM t.@rcvd_score += s.@score/(s.outdegree(e_type)) //param
POST-ACCUM s.@score = (1.0-damping) + damping * s.@rcvd_score,
s.@rcvd_score = 0,
@@max_diff += abs(s.@score - s.@score');
END;
V = SELECT s FROM Start:s
POST-ACCUM s.setAttr(attr, s.@score); // Parameterized
}
RUN QUERY pagerank_dyn(_,_,_,"Page", "Link", "Score")
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.
queryBodyStmts := (queryBodyStmt ";")+
queryBodyStmt := assignStmt // Assignment
| vSetVarDeclStmt // Declaration
| gAccumAssignStmt // Assignment
| gAccumAccumStmt // Assignment
| lAccumAccumStmt // Assignment
| funcCallStmt // Function Call
| selectStmt // Select
| queryBodyCaseStmt // Control Flow
| queryBodyIfStmt // Control Flow
| queryBodyWhileStmt // Control Flow
| queryBodyForEachStmt // Control Flow
| BREAK // Control Flow
| CONTINUE // Control Flow
| updateStmt // Data Modification
| insertStmt // Data Modification
| queryBodyDeleteStmt // Data Modification
| printStmt // Output
| printlnStmt // Output
| logStmt // Output
| returnStmt // Output
| raiseStmt // Exception
| tryStmt // Exception
DMLSubStmtList := DMLSubStmt ["," DMLSubStmt]*
DMLSubStmt := assignStmt // Assignment
| funcCallStmt // Function Call
| gAccumAccumStmt // Assignment
| lAccumAccumStmt // Assignment
| attrAccumStmt // Assignment
| vAccumFuncCall // Function Call
| localVarDeclStmt // Declaration
| DMLSubCaseStmt // Control Flow
| DMLSubIfStmt // Control Flow
| DMLSubWhileStmt // Control Flow
| DMLSubForEachStmt // Control Flow
| BREAK // Control Flow
| CONTINUE // Control Flow
| insertStmt // Data Modification
| DMLSubDeleteStmt // Data Modification
| printlnStmt // Output
| logStmt // Output
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.
CREATE QUERY stmt_types (parameterList) FOR GRAPH g [
other queryBodyStmt1;
ControlFlow queryBodyStmt2 // ControlFlow inside top level.
other queryBodyStmt2.1; // subStmts in ControlFlow are queryBody unless inside DML.
ControlFlow queryBodyStmt2.2 // ControlFlow inside ControlFlow inside top level
other queryBodyStmt2.2.1;
other queryBodyStmt2.2.2;
END;
DML queryBodyStmt2.3 // DML inside ControlFlow inside top-level
other DMLSubStmt2.3.1, // switch to DMLSubStmt
other DMLSubStmt2.3.2
;
END;
DML queryBodyStmt3 // DML inside top level.
other DMLSubStmt3.1, // All subStmts in DML must be DMLSubStmt type
ControlFlow DMLSubStmt3.2 // ControlFlow inside DML inside top level
other DMLSubStmt3.2.1,
other DMLSubStmt3.2.2
,
DML DMLsubStmt3.3
other DMLSubStmt3.3.1,
other DMLSubStmt3.3.2
;
other queryBodyStmt4;
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" |
Draft queries
GSQL internally has two statuses for queries, DRAFT
and VALID
.
If your query passes the semantic checks upon running the CREATE QUERY
command, it is saved automatically in VALID
status.
If not, along with the error statement, a message appears to indicate the draft status.
In this example, the first query gets saved upon running CREATE QUERY
, while the second one remains a draft.
GSQL > CREATE QUERY valid_query(){ print 1; }
Successfully created queries: [valid_query].
GSQL > BEGIN
GSQL > CREATE QUERY draft_query(){
GSQL > PRINT;
GSQL > PRINT "I am a draft"
GSQL > }
GSQL > END
line 2:7 mismatched input ';' expecting {ABORT, AND, ANY, AVG, BY, COALESCE, COMMIT, COUNT, DATETIME_ADD, DATETIME_SUB, DISTINCT, FALSE, FILE, GROUP, INSERT, ISEMPTY, LASTHOP, LIST, LOG, MAP, MATCH, MAX, MIN, NOT, NOW, OR, PATH, PER, RANGE, REPLACE, SELECT_VERTEX, SET, SRC, SUM, TGT, TO_DATETIME, TRIM, TRUE, UPDATE, GSQL_INT_MAX, GSQL_INT_MIN, GSQL_UINT_MAX, '__ENGINE__E_ATTR', '__ENGINE__SRC_ATTR', '__ENGINE__TGT_ATTR', '__ENGINE__V_ATTR', '__ENGINE__SRC_VAL', '__ENGINE__TGT_VAL', '__ENGINE__V_VAL', '__ENGINE__MESSAGE', '__ENGINE__CONTEXT', '__ENGINE__REQUEST', '__ENGINE__SERVICEAPI', '(', '[', '-', '.', '_', CONST_INT, CONST_STR, NAME, GACCNAME}
line 4:0 mismatched input '}' expecting {TO_CSV, WHERE, ',', ';'}
Parsing encountered 2 syntax error(s)
Saved as draft query with type/semantic error: [draft_query].
Because the query status is determined and saved internally, there are no commands for users to choose to save valid queries as DRAFT
status.
Queries are not saved as drafts in the following situations:
-
The user does not have the correct permissions to create a query.
-
An existing valid query has the same name, and there is no
REPLACE
command used while creating the new query. -
An existing valid query is called by another query.
-
The new query will change its signature (parameters or return type).
-
-
A circular call is detected, where
queryA
callsqueryB and `queryB
callsqueryA
.-
However, a recursive call (A calls A) is allowed.
-
If a query is saved as a draft before it reaches valid status, any queries that call it are also set to draft status.
INTERPRET QUERY
INTERPRET QUERY
runs a query by translating it line-by-line.
This is in contrast to the 2-step flow to install a query first and then run the query.
INTERPRET QUERY
runs a query immediately but may take longer to finish than running an installed query.
INTERPRET QUERY
also has limitations and does not support all GSQL query language features.
There are two GSQL syntax options for Interpreted GSQL:
Interpret an anonymous query
interpretQuery := INTERPRET QUERY "(" ")"
[FOR GRAPH graph_name]
[SYNTAX syntax_name]
"{" queryBody "}"
This syntax is similar in concept to SQL queries. Queries are not named, do not accept parameters, and are not saved after being run.
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.
INTERPRET QUERY () FOR GRAPH Social_Net {
// declaration statements
STRING uid = "Jane.Doe";
users = {Person.*};
// body statements
posts = SELECT p
FROM users:u-(Posted>)-:p
WHERE u.id == uid;
PRINT posts, posts.size();
}
Interpret a created query
runQuery := (RUN | INTERPRET) QUERY [runOptions] queryName "(" parameterValueList ")"
This syntax is like RUN
query, except
-
The keyword
RUN
is replaced withINTERPRET
. -
Some options may not be supported.
INTERPRET QUERY createQueryEx ("Jane.Doe")
INSTALL QUERY
installQuery := INSTALL QUERY [installOptions] ( "*" | ALL | queryName ["," queryMame]* )
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 |
Options
The following options are available:
Option | Effect |
---|---|
|
Re-installs 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. |
|
Enables a new internal framework for compiling non-distributed queries. Equivalent to the The loop variable in a |
|
Installs and optimizes the query using cost-based optimization.
The optimizer uses various statistics to generate an efficient traversal plan when compiling a query.
You can benefit from this option if your query uses a This option can be used together with other options, but it must come after the other options.
For example, you cannot run This is a Preview feature and should not be used in production. |
Optimize installed queries
INSTALL QUERY -OPTIMIZE
This feature is deprecated and support for it will be dropped in a future version. |
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
runQuery := (RUN | INTERPRET) QUERY [runOptions] queryName
"(" parameterValueList | parameterValueJSON ")"
runOptions := ( "-av" | "-d" )*
parameterValueList := parameterValue ["," parameterValue]*
parmeterValueJSON ::= '{"'parameterName'":' parameterValue(', "'parameterName'":' parameterValue)* '}'
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:
CREATE QUERY greet_person(INT age = 3, STRING name = "John",
DATETIME birthday = to_datetime("2019-02-19 19:19:19"))
{
PRINT age, name, birthday;
}
To run the query with default values for the parameter name,
use _
in the place of the second parameter value:
GSQL > RUN QUERY greet_person (21, _, "2020-02-02 20:02:20")
{
"error": false,
"message": "",
"version": {
"schema": 0,
"edition": "enterprise",
"api": "v2"
},
"results": [{
"birthday": "2020-02-02 20:02:20",
"name": "John",
"age": 21
}]
}
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.
GSQL > RUN QUERY greet_person(21)
{
"error": false,
"message": "",
"version": {
"schema": 0,
"edition": "enterprise",
"api": "v2"
},
"results": [{
"birthday": "2019-02-19 19:19:19",
"name": "John",
"age": 21
}]
}
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:
CREATE QUERY greet_person(INT age = 3, STRING name = "John",
DATETIME birthday = to_datetime("2019-02-19 19:19:19"))
{
PRINT age, name, birthday;
}
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:
RUN QUERY greet_person( {"name": "Emma", "age": 21} )
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 Query Parameter Types.
If a vertex type has a composite key, use a comma to separate the different attributes to denote their ID. For example, if you have the following vertex definition:
A vertex ID would be |
Parameter list
Parameter type | Syntax | Example |
---|---|---|
|
Use a string formatted as |
|
Set or bag of primitives |
Use square brackets to enclose the collection of values. |
A set of integers: |
Typed vertex parameter: |
If the vertex type is specified in the query
definition, then the vertex argument is |
The vertex type
is |
Generic vertex parameter: |
If the type is not defined in the
query definition, then the argument must be a tuple of strings with both the id and type: |
A vertex with ID |
Set or bag of typed vertex parameters |
Same as a set or bag of primitives, where the primitive type is the vertex ID. |
|
Set or bag of generic |
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) tuples. Mixed types are permitted. |
|
Queries that could take any vertex type as input should be written using generic VERTEX
parameters.
Users who call these queries will provide ("id", "type")
tuple arguments for these parameters.
Parameter JSON object
Parameter type | Syntax | Example |
---|---|---|
|
Use a string formatted as |
|
Set or bag of primitives |
Use a JSON array containing the primitive values |
|
|
Since the type is already specified in the query, you only need to use a JSON object containing the field
|
|
|
Use a JSON object containing a field |
|
Set or bag of |
Use a JSON array containing a list of
JSON |
|
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.
GSQL > RUN QUERY -av test()
## In a curl URL call. Note the use of both single and double underscores.
curl -X GET 'http://localhost:9000/query/graphname/queryname?__GQUERY__USING_ALL_ACTIVE_MODE=true'
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.
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 the GSQL-TIMEOUT
header.
To run a query in Detached Mode from the command line, use the-async
option for theRUN QUERY
command:
GSQL > RUN QUERY -async <queryName>
You will receive a JSON response immediately containing a query ID (request_id
):
{
"error": false,
"message": "The query is successfully submitted. Please check query status using the request id.",
"request_id": "<RequestID>"
}
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:
$ curl -s -H "GSQL-ASYNC:true" GET "http://localhost:9000/query/<graphName>/<queryName>?parameter1=<parameter1>
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 |
---|---|
|
String specifying the output API version. Values are specified as follows:``v1'': Output API used in TigerGraph platform v0.8 through v1.0.
|
|
String indicating the edition of the product. |
|
Integer representing which version of the user’s graph schema
is currently in use. When a |
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:
{
"version": {"edition": "developer","api": "v2","schema": "1"},
"error": false,
"message": "",
"results": [
{results_of_PRINT_statement_1},
...,
{results_of_PRINT_statement_N}
]
}
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
curl -X GET "http://localhost:9000/eco"
and generates the following output:
{
"version": {"edition":"developer","api":"v2","schema":0},
"error": true,
"message": "Endpoint is not found from url = /eco, please use GET /endpoints to list all valid endpoints.",
"code": "REST-1000"
}
Changing the default output API
The following GSQL statement can be used to set the JSON output API configuration.
SET json_api = <version_string>
The only supported JSON API is "v2". |
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.
SHOW QUERY
showQuery := SHOW QUERY queryName
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 items on the graph and their statuses, including queries.
In this example, the output of the ls
command has been truncated to show only the query statuses.
ls <--- show all queries
Queries:
- draft1() (draft)
- valid1() (installed v2)
...
SHOW QUERY * <--- the flags are same as above
CREATE QUERY valid1(){ <-- no status is shown for a valid query that has not been installed
PRINT 1;
}
# draft <-- a query that is set to DRAFT status because it calls a query with DRAFT status
CREATE QUERY draft_callDraft2(){
draft2();
PRINT "I am a draft too";
}
# installed v2 <-- query is valid and has been installed successfully
CREATE QUERY valid2(){
PRINT 1;
}
# deprecated <-- the query is deprecated if it is incompatible with the schema after a schema change
CREATE QUERY valid3(){
v = SELECT src
FROM unexistentType:src;
}
# blocked <-- the query is blocked by the file output policy
CREATE QUERY blockedQuery(){
FILE f("/root");
}
# disabled <-- the query is disabled if it calls a deleted sub-query.
CREATE QUERY disabledQuery(){
deletedQuery();
}
# pendingInstall <-- the query is installing
CREATE QUERY valid3(){
PRINT 1;
}
# failedCompilation <-- query installation failed
CREATE QUERY valid3(){
PRINT 1;
}
DROP QUERY
dropQuery := DROP QUERY ( "*" | ALL | queryName ["," queryName]* )
To drop a query, run DROP QUERY query_name
.
The query will be uninstalled (if it has been installed) and removed from the dictionary.
If a subquery is dropped, the main query is marked as disabled.
In this example, using a graph g
, a test query A
is created, followed by a test query B
that calls A()
.
After A
is dropped, B
is disabled.
GSQL > create query A(){print 1;}
Successfully created queries: [A].
GSQL > create query B(){ A();}
Successfully created queries: [B].
GSQL > install query *
Start installing queries, about 1 minute ...
<....>
Query installation finished.
GSQL > drop query A
Successfully dropped queries on the graph 'g': [A].
GSQL > ls
---- Graph g
Vertex Types:
Edge Types:
Graphs:
- Graph g()
Jobs:
Queries:
- B() (disabled)
Both valid and draft queries can be dropped.
To drop all queries, either of the following commands can be used:
-
DROP QUERY ALL
-
DROP QUERY *
The scope of the command depends on the user’s current scope.
If the user has set a working graph, then DROP ALL
removes all the queries for that graph.
If a user has set their scope to be global, then DROP ALL
removes all queries across all graph spaces.