附录B:查询语言的完整正式语法
版本2.1
下面描述了GSQL语言的语法正式规则。它由一系列遵循EBNF范式的表达式组成。
定义语法所使用的表示法
我们用EBNF范式规则来定义本语言的语法。它的规则包含了终端符号和非终端符号。 终端符号(terminal symbol)是表示文字输出的最基本符号。 所有被单引号或双引号引用的字符(例如,“+”,“=”,“)”,“10”等)都是终端符号。 非终端符号(non-terminal symbol)是终端符号和非终端符号的组合。规则规定公式的左边始终是非终端符号; 因此规定实质上是在定义非终端符号。 例如在下面的例子中,assignmentStmt(即赋值语句的缩写)被写成一个名称,加一个等号,一个表达式,一个运算符,再加一个表示终止的分号的形式。 AssignmentStmt,name和expr都是非终端符号。 此外,所有关键词(KEYWORD)必须全部大写的,并且它们都是终端符号。 “:=”是EBNF的一部分,意思它的右侧内容是左侧内容的展开。
assignmentStmt := name "=" expr op expr ";"
竖线“|”在EBNF范式中表示选项,即在竖线的两侧二选一。如果有一系列的竖线,则表示在竖线分割的选项中多选一。
op := "+" | "-" | "*" | "/"
方括号代表可选部分或者一组符号。而圆括号将一组符号聚集在一起。下面的例子演示了一个常数,它可以是一位数,两位数或者三位数,而在数字之前可以选择添加加减号。
constant := ["+" | "-"] (digit | (digit digit) | (digit digit digit))
星号( *)和加号( +)是EBNF范式中位于结尾表示重复出现次数。 星号表示零次或多次出现,而加号表示一次或多次出现。 下例中的intConstant中,开头可以有可选的加号或减号,而后跟一位或多位数字。 而floatConstant的开头也为可选的加号或减号,后跟零位或多位数字,再后跟一位或多位小数。 星号和加号也可以应用于列表定义中的符号组。 比如下例中,非终端符号的list被定义为逗号分隔的表达式列表,并用圆括号括起来。 该列表至少有一个表达式,后面可以跟着零个或多个表达式,并用逗号分隔。
intConstant := ["+" | "-"] digit+
floatConstant := ["+" | "-"] digit* "." digit+
list := "(" expr ["," expr]* ")"
大括号{}用于标识一个可选的符号组,它们可以重复出现零次或多次。 因此,大括号的使用等效于方括号或圆括号后跟星号的情况,以表示该符号组零次或多次重复出现。 以下所有表达式都是等效的:
list1 := expr ["," expr]*
list2 += expr ("," expr)*
list3 := expr {"," expr}
为简洁起见,我们有时在范式中不在逗号上添加引号:
list4 := expr {, expr}
GSQL 图形查询语言的EBNF范式
#########################################################
## EBNF for GSQL Query Language
createQuery := CREATE [DISTRIBUTED][OR REPLACE] QUERY name "(" [parameterList] ")" FOR GRAPH name
[RETURNS "(" baseType | accumType ")"]
[API "(" stringLiteral ")"]
"{" [typedefs] [declStmts] [declExceptStmts] queryBodyStmts "}"
parameterValueList := parameterValue [, parameterValue]*
parameterValue := parameterConstant
| "[" parameterValue [, parameterValue]* "]" // BAG or SET
| "(" stringLiteral, stringLiteral ")" // a generic VERTEX value
parameterConstant := numeric | stringLiteral | TRUE | FALSE
parameterList := parameterType name ["=" constant] ["," parameterType name ["=" constant]]*
typedefs := (typedef ";")+
declStmts := (declStmt ";")+
declStmt := baseDeclStat | accumDeclStmt | fileDeclStmt
declExceptStmts := (declExceptStmt ";")+
queryBodyStmts := (queryBodyStmt ";")+
queryBodyStmt := assignStmt // Assignment
| vSetVarDeclStmt // Declaration
| gAccumAssignStmt // Assignment
| gAccumAccumStmt // 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
installQuery := INSTALL QUERY [installOptions] ( "*" | ALL |name [, name]* )
runQuery := RUN QUERY [runOptions] name "(" parameterValueList ")"
showQuery := SHOW QUERY name
dropQuery := DROP QUERY ( "*" | ALL | name [, name]* )
#########################################################
## Types and names
lowercase := [a-z]
uppercase := [A-Z]
letter := lowercase | uppercase
digit := [0-9]
integer := ["-"]digit+
real := ["-"]("." digit+) | ["-"](digit+ "." digit*)
numeric := integer | real
stringLiteral := '"' [~["] | '\\' ('"' | '\\')]* '"'
name := (letter | "_") [letter | digit | "_"]* // Can be a single "_" or start with "_"
type := baseType | name | accumType | STRING COMPRESS
baseType := INT
| UINT
| FLOAT
| DOUBLE
| STRING
| BOOL
| VERTEX ["<" name ">"]
| EDGE
| JSONOBJECT
| JSONARRAY
| DATETIME
filePath := name | stringLiteral
typedef := TYPEDEF TUPLE "<" tupleType ">" name
tupleType := (baseType name) | (name baseType) ["," (baseType name) | (name baseType)]*
parameterType := baseType
| [ SET | BAG ] "<" baseType ">"
| FILE
#########################################################
## Accumulators
accumDeclStmt := accumType "@"name ["=" constant][, "@"name ["=" constant]]*
| "@"name ["=" constant][, "@"name ["=" constant]]* accumType
| [STATIC] accumType "@@"name ["=" constant][, "@@"name ["=" constant]]*
| [STATIC] "@@"name ["=" constant][, "@@"name ["=" constant]]* accumType
accumType := "SumAccum" "<" ( INT | FLOAT | DOUBLE | STRING | STRING COMPRESS) ">"
| "MaxAccum" "<" ( INT | FLOAT | DOUBLE ) ">"
| "MinAccum" "<" ( INT | FLOAT | DOUBLE ) ">"
| "AvgAccum"
| "OrAccum"
| "AndAccum"
| "BitwiseOrAccum"
| "BitwiseAndAccum"
| "ListAccum" "<" type ">"
| "SetAccum" "<" elementType ">"
| "BagAccum" "<" elementType ">"
| "MapAccum" "<" elementType "," type ">"
| "HeapAccum" "<" name ">" "(" (integer | name) "," name [ASC | DESC] ["," name [ASC | DESC]]* ")"
| "GroupByAccum" "<" elementType name ["," elementType name]* , accumType name ["," accumType name]* ">"
| "ArrayAccum" "<" name ">"
elementType := baseType | name | STRING COMPRESS
gAccumAccumStmt := "@@"name "+=" expr
###############################################################################
## Operators, 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
| name "." "type"
| name "." ["@"]name
| name "." "@"name ["\'"]
| name "." name "." name "(" [argList] ")"
| name "." name "(" [argList] ")" [ ".".FILTER "(" condition ")" ]
| name ["<" type ["," type"]* ">"] "(" [argList] ")"
| name "." "@"name ("." name "(" [argList] ")")+ ["." name]
| "@@"name ("." 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
| name "." ["@"]name
| name "." "@"name ("." name "(" [argList] ")")+
| name "." name "(" [argList] ")" [ ".".FILTER "(" condition ")" ]
| "@@"name ("." name "(" [argList] ")")+
| setBagExpr (UNION | INTERSECT | MINUS) setBagExpr
| "(" argList ")"
| "(" setBagExpr ")"
#########################################################
## Declarations and Assignments ##
## Declarations ##
baseDeclStmt := baseType name ["=" constant][, name ["=" constant]]*
fileDeclStmt := FILE fileVar "(" filePath ")"
fileVar := name
localVarDeclStmt := baseType name "=" expr
vSetVarDeclStmt := name ["(" vertexEdgeType ")"] "=" (seedSet | simpleSet | selectBlock)
simpleSet := name | "(" simpleSet ")" | simpleSet (UNION | INTERSECT | MINUS) simpleSet
seedSet := "{" [seed ["," seed ]*] "}"
seed := '_'
| ANY
| ["@@"]name
| name ".*"
| "SelectVertex" selectVertParams
selectVertParams := "(" filePath "," columnId "," (columnId | name) ","
stringLiteral "," (TRUE | FALSE) ")" [".".FILTER "(" condition ")"]
columnId := "$" (integer | stringLiteral)
## Assignment Statements ##
assignStmt := name "=" expr
| name "." name "=" expr
| name "." "@"name ("+="| "=") expr
gAccumAssignStmt := "@@"name ("+=" | "=") expr
loadAccumStmt := "@@"name "=" "{" "LOADACCUM" loadAccumParams ["," "LOADACCUM" loadAccumParams]* "}"
loadAccumParams := "(" filePath "," columnId "," [columnId ","]*
stringLiteral "," (TRUE | FALSE) ")" [".".FILTER "(" condition ")"]
## Function Call Statement ##
funcCallStmt := name ["<" type ["," type"]* ">"] "(" [argList] ")"
| "@@"name ("." name "(" [argList] ")")+
argList := expr ["," expr]*
#########################################################
## Select Statement
selectStmt := name "=" selectBlock
selectBlock := SELECT name FROM ( edgeSet | vertexSet )
[sampleClause]
[whereClause]
[accumClause]
[postAccumClause]
[havingClause]
[orderClause]
[limitClause]
vertexSet := name [":" name]
edgeSet := name [":" name]
"-" "(" [vertexEdgeType] [":" name] ")" "->"
[vertexEdgeType] [":" name]
vertexEdgeType := "_" | ANY | name | ( "(" name ["|" name]* ")" )
sampleClause := SAMPLE ( expr | expr "%" ) EDGE WHEN condition
| SAMPLE expr TARGET WHEN condition
| SAMPLE expr "%" TARGET PINNED WHEN condition
whereClause := WHERE condition
accumClause := ACCUM DMLSubStmtList
postAccumClause := POST-ACCUM DMLSubStmtList
DMLSubStmtList := DMLSubStmt ["," DMLSubStmt]*
DMLSubStmt := assignStmt // Assignment
| funcCallStmt // Function Call
| gAccumAccumStmt // 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
vAccumFuncCall := name "." "@"name ("." name "(" [argList] ")")+
havingClause := HAVING condition
orderClause := ORDER BY expr [ASC | DESC] ["," expr [ASC | DESC]]*
limitClause := LIMIT ( expr | expr "," expr | expr OFFSET expr )
#########################################################
## Control Flow Statements ##
queryBodyIfStmt := IF condition THEN queryBodyStmts [ELSE IF condition THEN queryBodyStmts ]* [ELSE queryBodyStmts ] END
DMLSubIfStmt := IF condition THEN DMLSubStmtList [ELSE IF condition THEN DMLSubStmtList ]* [ELSE DMLSubStmtList ] END
queryBodyCaseStmt := CASE (WHEN condition THEN queryBodyStmts)+ [ELSE queryBodyStmts] END
| CASE expr (WHEN constant THEN queryBodyStmts)+ [ELSE queryBodyStmts] END
DMLSubCaseStmt := CASE (WHEN condition THEN DMLSubStmtList)+ [ELSE DMLSubStmtList] END
| CASE expr (WHEN constant THEN DMLSubStmtList)+ [ELSE DMLSubStmtList] END
queryBodyWhileStmt := WHILE condition [LIMIT (name | integer)] DO queryBodyStmts END
DMLSubWhileStmt := WHILE condition [LIMIT (name | integer)] DO DMLSubStmtList END
queryBodyForEachStmt := FOREACH forEachControl DO queryBodyStmts END
DMLSubForEachStmt := FOREACH forEachControl DO DMLSubStmtList END
forEachControl := ( name | "(" name (, name)+ ")") (IN | ":") setBagExpr
| name IN RANGE "[" expr , expr"]" [".STEP(" expr ")"]
#########################################################
## Other Data Modifications Statements ##
queryBodyDeleteStmt := DELETE name FROM ( edgeSet | vertexSet ) [whereClause]
DMLSubDeleteStmt := DELETE "(" name ")"
updateStmt := UPDATE name FROM ( edgeSet | vertexSet ) SET DMLSubStmtList [whereClause]
insertStmt := INSERT INTO name ["(" ( PRIMARY_ID | FROM "," TO ) ["," name]* ")"]
VALUES "(" ( "_" | expr ) [name] ["," ( "_" | expr ) [name] ["," ("_" | expr)]*] ")"
#########################################################
## Output Statements ##
printStmt := PRINT printExpr {, printExpr} [WHERE condition] [TO_CSV (filePath | fileVar)]
printExpr := (expr | vExprSet) [ AS name]
vExprSet := expr "[" vSetProj {, vSetProj} "]"
vSetProj := expr [ AS name]
printlnStmt := fileVar".println" "(" expr {, expr} ")"
logStmt := LOG "(" condition "," argList ")"
returnStmt := RETURN expr
#########################################################
## Exception Statements ##
declExceptStmt := EXCEPTION exceptVarName "(" errorInt ")"
exceptVarName := name
errorInt := integer
raiseStmt := RAISE exceptVarName [errorMsg]
errorMsg := "(" expr ")"
tryStmt := TRY queryBodyStmts EXCEPTION caseExceptBlock+ [elseExceptBlock] END ";"
caseExceptBlock := WHEN exceptVarName THEN queryBodyStmts
elseExceptBlock := ELSE queryBodyStmts
Last updated