github.com/vescale/zgraph@v0.0.0-20230410094002-959c02d50f95/parser/parser.y (about)

     1  %{
     2  // Copyright 2013 The ql Authors. All rights reserved.
     3  // Use of this source code is governed by a BSD-style
     4  // license that can be found in the LICENSES/QL-LICENSE file.
     5  
     6  // Copyright 2022 zGraph Authors. All rights reserved.
     7  //
     8  // Licensed under the Apache License, Version 2.0 (the "License");
     9  // you may not use this file except in compliance with the License.
    10  // You may obtain a copy of the License at
    11  //
    12  //     http://www.apache.org/licenses/LICENSE-2.0
    13  //
    14  // Unless required by applicable law or agreed to in writing, software
    15  // distributed under the License is distributed on an "AS IS" BASIS,
    16  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    17  // See the License for the specific language governing permissions and
    18  // limitations under the License.
    19  
    20  // Initial yacc source generated by ebnf2y[1]
    21  // at 2013-10-04 23:10:47.861401015 +0200 CEST
    22  //
    23  //  $ ebnf2y -o ql.y -oe ql.ebnf -start StatementList -pkg ql -p _
    24  //
    25  //   [1]: http://github.com/cznic/ebnf2y
    26  
    27  // The parser implements the PGQL specification
    28  //
    29  // - https://pgql-lang.org/spec/1.5/
    30  //
    31  
    32  package parser
    33  
    34  import (
    35  	"math"
    36  
    37  	"github.com/vescale/zgraph/datum"
    38  	"github.com/vescale/zgraph/parser/ast"
    39  	"github.com/vescale/zgraph/parser/model"
    40  	"github.com/vescale/zgraph/parser/opcode"
    41  )
    42  
    43  %}
    44  
    45  %union {
    46  	offset int // offset
    47  	item interface{}
    48  	ident string
    49  	expr ast.ExprNode
    50  	statement ast.StmtNode
    51  }
    52  
    53  %token	<ident>
    54  
    55  	/*yy:token "%c"     */
    56  	identifier "identifier"
    57  
    58  	/*yy:token "\"%c\"" */
    59  	stringLit          "string literal"
    60  	singleAtIdentifier "identifier with single leading at"
    61  	doubleAtIdentifier "identifier with double leading at"
    62  	invalid            "a special token never used by parser, used by lexer to indicate error"
    63  	andand             "&&"
    64  	pipes              "||"
    65  
    66  	/* Reserved keywords */
    67  	as                    "AS"
    68  	asc                   "ASC"
    69  	by                    "BY"
    70  	create                "CREATE"
    71  	defaultKwd            "DEFAULT"
    72  	deleteKwd             "DELETE"
    73  	desc                  "DESC"
    74  	doubleType            "DOUBLE"
    75  	drop                  "DROP"
    76  	edge                  "EDGE"
    77  	exists                "EXISTS"
    78  	falseKwd              "FALSE"
    79  	floatType             "FLOAT"
    80  	from                  "FROM"
    81  	group                 "GROUP"
    82  	having                "HAVING"
    83  	ifKwd                 "IF"
    84  	index                 "INDEX"
    85  	insert                "INSERT"
    86  	integerType           "INTEGER"
    87  	into                  "INTO"
    88  	is                    "IS"
    89  	limit                 "LIMIT"
    90  	match                 "MATCH"
    91  	not                   "NOT"
    92  	null                  "NULL"
    93  	on                    "ON"
    94  	order                 "ORDER"
    95  	selectKwd             "SELECT"
    96  	set                   "SET"
    97  	show                  "SHOW"
    98  	trueKwd               "TRUE"
    99  	unique                "UNIQUE"
   100  	update                "UPDATE"
   101  	use                   "USE"
   102  	vertex                "VERTEX"
   103  	where                 "WHERE"
   104  	xor                   "XOR"
   105  	or                    "OR"
   106  	and                   "AND"
   107  	between               "BETWEEN"
   108  	labels                "LABELS"
   109  	properties            "PROPERTIES"
   110  	caseKwd               "CASE"
   111  	then                  "THEN"
   112  	when                  "WHEN"
   113  	elseKwd               "ELSE"
   114  	in                    "IN"
   115  	distinct              "DISTINCT"
   116  
   117  	/* Unreserved keywords. Notice: make sure these tokens are contained in UnReservedKeyword. */
   118  	begin                 "BEGIN"
   119  	end                   "END"
   120  	comment               "COMMENT"
   121  	commit                "COMMIT"
   122  	booleanType           "BOOLEAN"
   123  	decimalType           "DECIMAL"
   124  	explain               "EXPLAIN"
   125  	yearType              "YEAR"
   126  	dateType              "DATE"
   127  	day                   "DAY"
   128  	timestampType         "TIMESTAMP"
   129  	timeType              "TIME"
   130  	rollback              "ROLLBACK"
   131  	offset                "OFFSET"
   132  	graph                 "GRAPH"
   133  	graphs                "GRAPHS"
   134  	all                   "ALL"
   135  	any                   "ANY"
   136  	shortest              "SHORTEST"
   137  	cheapest              "CHEAPEST"
   138  	top                   "TOP"
   139  	cost                  "COST"
   140  	path                  "PATH"
   141  	interval              "INTERVAL"
   142  	hour                  "HOUR"
   143  	minute                "MINUTE"
   144  	month                 "MONTH"
   145  	second                "SECOND"
   146  	substring             "SUBSTRING"
   147  	forkKwd               "FOR"
   148  	arrayAgg              "ARRAY_AGG"
   149  	avg                   "AVG"
   150  	count                 "COUNT"
   151  	listagg               "LISTAGG"
   152  	max                   "MAX"
   153  	min                   "MIN"
   154  	sum                   "SUM"
   155  	extract               "EXTRACT"
   156  	timezoneHour          "TIMEZONE_HOUR"
   157  	timezoneMinute       "TIMEZONE_MINUTE"
   158  	cast                  "CAST"
   159  	stringKwd             "STRING"
   160  	with                  "WITH"
   161  	zone                  "ZONE"
   162  	prefix                "PREFIX"
   163  
   164  	/* Functions */
   165  	lower                 "LOWER"
   166  	uppper                "UPPER"
   167  	inDegree              "IN_DEGREE"
   168  	javaRegexpLike        "JAVA_REGEXP_LIKE"
   169  	label                 "LABEL"
   170  	matchNumber           "MATCH_NUMBER"
   171  	outDegree             "OUT_DEGREE"
   172  	abs                   "ABS"
   173  	ceil                  "CEIL"
   174  	ceiling               "CEILING"
   175  	elementNumber         "ELEMENT_NUMBER"
   176  	floor                 "FLOOR"
   177  	hasLabel              "HAS_LABEL"
   178  	id                    "ID"
   179  	allDifferent          "ALL_DIFFERENT"
   180  
   181  %token	<item>
   182  
   183  	/*yy:token "1.%d"   */
   184  	floatLit "floating-point literal"
   185  
   186  	/*yy:token "1.%d"   */
   187  	decLit "decimal literal"
   188  
   189  	/*yy:token "%d"     */
   190  	intLit "integer literal"
   191  
   192  	/*yy:token "%x"     */
   193  	hexLit "hexadecimal literal"
   194  
   195  	/*yy:token "%b"     */
   196  	bitLit       "bit literal"
   197  
   198  	andnot       "&^"
   199  	assignmentEq ":="
   200  	eq           "="
   201  	ge           ">="
   202  	le           "<="
   203  	neq          "!="
   204  	neqSynonym   "<>"
   205  	nulleq       "<=>"
   206  	paramMarker  "?"
   207  	allProp      ".*"
   208  
   209  	leftArrow           "<-"
   210  	rightArrow          "->"
   211  	edgeOutgoingLeft    "-["
   212  	edgeOutgoingRight   "]->"
   213  	edgeIncomingLeft    "<-["
   214  	edgeIncomingRight   "]-"
   215  	reachOutgoingLeft   "-/"
   216  	reachOutgoingRight  "/->"
   217  	reachIncomingLeft   "<-/"
   218  	reachIncomingRight  "/-"
   219  
   220  %type	<expr>
   221  	Aggregation
   222  	ArithmeticExpression
   223  	BindVariable
   224  	BracketedValueExpression
   225  	CaseExpression
   226  	CastSpecification
   227  	CharacterSubstring
   228  	ElseClauseOpt
   229  	ExistsPredicate
   230  	ExtractFunction
   231  	FunctionInvocation
   232  	ForStringLengthOpt
   233  	InPredicate
   234  	IsNotNullPredicate
   235  	IsNullPredicate
   236  	LengthNum
   237  	LimitOption
   238  	Literal
   239  	ListaggSeparatorOpt
   240  	LogicalExpression
   241  	NotInPredicate
   242  	PropertyAccess
   243  	RelationalExpression
   244  	ScalarSubquery
   245  	SimpleCase
   246  	SearchedCase
   247  	StartPosition
   248  	StringConcat
   249  	StringLiteral
   250  	Subquery
   251  	ValueExpression
   252  	VariableReference
   253  	NumericLiteral
   254  	BooleanLiteral
   255  	DateLiteral
   256  	TimeLiteral
   257  	TimestampLiteral
   258  	IntervalLiteral
   259  
   260  
   261  %type	<statement>
   262  	BeginStmt
   263  	CommitStmt
   264  	CreateGraphStmt
   265  	CreateLabelStmt
   266  	CreateIndexStmt
   267  	DeleteStmt
   268  	DropGraphStmt
   269  	DropLabelStmt
   270  	DropIndexStmt
   271  	EmptyStmt
   272  	ExplainStmt
   273  	InsertStmt
   274  	RollbackStmt
   275  	SelectStmt
   276  	Statement
   277  	UpdateStmt
   278  	UseStmt
   279  	ShowStmt
   280  
   281  %type	<ident>
   282  	Identifier
   283  	FunctionName
   284  	UnReservedKeyword
   285  
   286  %type   <item>
   287  	AllPropertiesPrefixOpt
   288  	ArgumentList
   289  	ByItem
   290  	ByList
   291  	CostClause
   292  	CostClauseOpt
   293  	DataType
   294  	DateTimeField
   295  	DistinctOpt
   296  	EdgePattern
   297  	ExpAsVar
   298  	ExtractField
   299  	SelectEelement
   300  	FieldAsName
   301  	FieldAsNameOpt
   302  	FromClause
   303  	FromClauseOpt
   304  	GraphElementInsertion
   305  	GraphElementInsertionList
   306  	GraphElementUpdate
   307  	GraphElementUpdateList
   308  	GraphName
   309  	GraphOnClause
   310  	GraphOnClauseOpt
   311  	GraphPattern
   312  	GroupByClauseOpt
   313  	HavingClauseOpt
   314  	InValueList
   315  	IntoClause
   316  	IntoClauseOpt
   317  	IfExists
   318  	IfNotExists
   319  	IndexKeyTypeOpt
   320  	IndexName
   321  	LabelName
   322  	LabelNameList
   323  	LabelNameListWithComma
   324  	LabelPredicate
   325  	LabelPredicateOpt
   326  	LabelsAndProperties
   327  	LabelSpecification
   328  	LabelSpecificationOpt
   329  	LimitClauseOpt
   330  	MatchClause
   331  	MatchClauseList
   332  	Order
   333  	OrderByClauseOpt
   334  	PathPattern
   335  	PathPatternList
   336  	PathPatternMacro
   337  	PathPatternMacroList
   338  	PathPatternMacroOpt
   339  	PatternQuantifier
   340  	PatternQuantifierOpt
   341  	PropertyAssignment
   342  	PropertyAssignmentList
   343  	PropertiesSpecification
   344  	PropertiesSpecificationOpt
   345  	PropertyName
   346  	PropertyNameList
   347  	QuantifiedPathExpr
   348  	ReachabilityPathExpr
   349  	SelectClause
   350  	SelectElementList
   351  	SimplePathPattern
   352  	StatementList
   353  	ValueExpressionList
   354  	VariableLengthPathPattern
   355  	VariableName
   356  	VariableNameOpt
   357  	VariableNameList
   358  	VariableSpec
   359  	VertexPattern
   360  	VertexPatternOpt
   361  	WhenClause
   362  	WhenClauseList
   363  	WhereClauseOpt
   364  
   365  %precedence empty
   366  %precedence insert
   367  
   368  %right '('
   369  %left ')'
   370  %precedence lowerThanOn
   371  %precedence on
   372  %right assignmentEq
   373  %left pipes or pipesAsOr
   374  %left xor
   375  %left andand and
   376  %left between
   377  %left eq ge le neq neqSynonym '>' '<' is in
   378  %left '|'
   379  %left '&'
   380  %left '-' '+'
   381  %left '*' '/' '%' div mod
   382  %left '^'
   383  %left '~' neg
   384  %right not
   385  %precedence ','
   386  
   387  %start	Entry
   388  
   389  %%
   390  
   391  Entry:
   392  	StatementList
   393  
   394  StatementList:
   395  	Statement
   396  	{
   397  		if $1 != nil {
   398  			parser.result = append(parser.result, $1)
   399  		}
   400  	}
   401  |	StatementList ';' Statement
   402  	{
   403  		if $3 != nil {
   404  			parser.result = append(parser.result, $3)
   405  		}
   406  	}
   407  
   408  Statement:
   409  	EmptyStmt
   410  |	BeginStmt
   411  |	CommitStmt
   412  |	CreateGraphStmt
   413  |	CreateLabelStmt
   414  |	CreateIndexStmt
   415  |	DeleteStmt
   416  |	DropGraphStmt
   417  |	DropLabelStmt
   418  |	DropIndexStmt
   419  |	ExplainStmt
   420  |	InsertStmt
   421  |	RollbackStmt
   422  |	SelectStmt
   423  |	UpdateStmt
   424  |	UseStmt
   425  |	ShowStmt
   426  
   427  EmptyStmt:
   428  	/* EMPTY */
   429  	{
   430  		$$ = nil
   431  	}
   432  
   433  BeginStmt:
   434  	"BEGIN"
   435  	{
   436  		$$ = &ast.BeginStmt{}
   437  	}
   438  
   439  CommitStmt:
   440  	"COMMIT"
   441  	{
   442  		$$ = &ast.CommitStmt{}
   443  	}
   444  
   445  CreateGraphStmt:
   446  	"CREATE" "GRAPH" IfNotExists GraphName
   447  	{
   448  		$$ = &ast.CreateGraphStmt{
   449  			IfNotExists: $3.(bool),
   450  			Graph:       $4.(model.CIStr),
   451  		}
   452  	}
   453  
   454  CreateLabelStmt:
   455  	"CREATE" "LABEL" IfNotExists LabelName
   456  	{
   457  		cl := &ast.CreateLabelStmt{
   458  			IfNotExists: $3.(bool),
   459  			Label:       $4.(model.CIStr),
   460  		}
   461  		$$ = cl
   462  	}
   463  
   464  CreateIndexStmt:
   465  	"CREATE" IndexKeyTypeOpt "INDEX" IfNotExists IndexName '(' PropertyNameList ')'
   466  	{
   467  		$$ = &ast.CreateIndexStmt{
   468  			KeyType:     $2.(ast.IndexKeyType),
   469  			IfNotExists: $4.(bool),
   470  			IndexName:   $5.(model.CIStr),
   471  			Properties:  $7.([]model.CIStr),
   472  		}
   473  	}
   474  
   475  IndexKeyTypeOpt:
   476  	{
   477  		$$ = ast.IndexKeyTypeNone
   478  	}
   479  |	"UNIQUE"
   480  	{
   481  		$$ = ast.IndexKeyTypeUnique
   482  	}
   483  
   484  /******************************************************************************
   485  
   486   DELETE Statement Specification
   487   Reference: https://pgql-lang.org/spec/1.5/#delete
   488  
   489   ******************************************************************************/
   490  DeleteStmt:
   491  	PathPatternMacroOpt "DELETE" VariableNameList FromClause WhereClauseOpt GroupByClauseOpt HavingClauseOpt OrderByClauseOpt LimitClauseOpt
   492  	{
   493  		ds := &ast.DeleteStmt{
   494  			VariableNames: $3.([]model.CIStr),
   495  			From:          $4.(*ast.MatchClauseList),
   496  		}
   497  		if $1 != nil {
   498  			ds.PathPatternMacros = $1.([]*ast.PathPatternMacro)
   499  		}
   500  		if $5 != nil {
   501  			ds.Where = $5.(ast.ExprNode)
   502  		}
   503  		if $6 != nil {
   504  			ds.GroupBy = $6.(*ast.GroupByClause)
   505  		}
   506  		if $7 != nil {
   507  			ds.Having = $7.(*ast.HavingClause)
   508  		}
   509  		if $8 != nil {
   510  			ds.OrderBy = $8.(*ast.OrderByClause)
   511  		}
   512  		if $9 != nil {
   513  			ds.Limit = $9.(*ast.LimitClause)
   514  		}
   515  		$$ = ds
   516  	}
   517  
   518  DropGraphStmt:
   519  	"DROP" "GRAPH" IfExists GraphName
   520  	{
   521  		$$ = &ast.DropGraphStmt{
   522  			IfExists: $3.(bool),
   523  			Graph:    $4.(model.CIStr),
   524  		}
   525  	}
   526  
   527  DropLabelStmt:
   528  	"DROP" "LABEL" IfExists LabelName
   529  	{
   530  		$$ = &ast.DropLabelStmt{
   531  			IfExists: $3.(bool),
   532  			Label:    $4.(model.CIStr),
   533  		}
   534  	}
   535  
   536  DropIndexStmt:
   537  	"DROP" "INDEX" IfExists Identifier
   538  	{
   539  		$$ = &ast.DropIndexStmt{
   540  			IfExists:  $3.(bool),
   541  			IndexName: model.NewCIStr($4),
   542  		}
   543  	}
   544  
   545  ExplainStmt:
   546  	"EXPLAIN" SelectStmt
   547  	{
   548  		$$ = &ast.ExplainStmt{
   549  			Select: $2.(*ast.SelectStmt),
   550  		}
   551  	}
   552  
   553  /******************************************************************************
   554  
   555   INSERT Statement Specification
   556   Reference: https://pgql-lang.org/spec/1.5/#insert
   557  
   558   ******************************************************************************/
   559  InsertStmt:
   560  	PathPatternMacroOpt "INSERT" IntoClauseOpt GraphElementInsertionList FromClauseOpt WhereClauseOpt GroupByClauseOpt HavingClauseOpt OrderByClauseOpt LimitClauseOpt
   561  	{
   562  		is := &ast.InsertStmt{
   563  			Insertions: $4.([]*ast.GraphElementInsertion),
   564  		}
   565  		if $1 != nil {
   566  			is.PathPatternMacros = $1.([]*ast.PathPatternMacro)
   567  		}
   568  		if $3 != nil {
   569  			is.IntoGraphName = $3.(model.CIStr)
   570  		}
   571  		if $5 != nil {
   572  			is.From = $5.(*ast.MatchClauseList)
   573  		}
   574  		if $6 != nil {
   575  			is.Where = $6.(ast.ExprNode)
   576  		}
   577  		if $7 != nil {
   578  			is.GroupBy = $7.(*ast.GroupByClause)
   579  		}
   580  		if $8 != nil {
   581  			is.Having = $8.(*ast.HavingClause)
   582  		}
   583  		if $9 != nil {
   584  			is.OrderBy = $9.(*ast.OrderByClause)
   585  		}
   586  		if $10 != nil {
   587  			is.Limit = $10.(*ast.LimitClause)
   588  		}
   589  		$$ = is
   590  	}
   591  
   592  IntoClauseOpt:
   593  	{
   594  		$$ = nil
   595  	}
   596  |	IntoClause
   597  
   598  IntoClause:
   599  	"INTO" GraphName
   600  	{
   601  		$$ = $2
   602  	}
   603  
   604  GraphElementInsertionList:
   605  	GraphElementInsertion
   606  	{
   607  		$$ = []*ast.GraphElementInsertion{$1.(*ast.GraphElementInsertion)}
   608  	}
   609  |	GraphElementInsertionList ',' GraphElementInsertion
   610  	{
   611  		$$ = append($1.([]*ast.GraphElementInsertion), $3.(*ast.GraphElementInsertion))
   612  	}
   613  
   614  GraphElementInsertion:
   615  	"VERTEX" VariableNameOpt LabelsAndProperties
   616  	{
   617  		insertion := &ast.GraphElementInsertion{
   618  			InsertionType:       ast.InsertionTypeVertex,
   619  			LabelsAndProperties: $3.(*ast.LabelsAndProperties),
   620  		}
   621  		if $2 != nil {
   622  			insertion.VariableName = $2.(model.CIStr)
   623  		}
   624  		$$ = insertion
   625  	}
   626  |	"EDGE" VariableNameOpt "BETWEEN" VariableName "AND" VariableName LabelsAndProperties
   627  	{
   628  		insertion := &ast.GraphElementInsertion{
   629  			InsertionType:       ast.InsertionTypeEdge,
   630  			From:                $4.(model.CIStr),
   631  			To:                  $6.(model.CIStr),
   632  			LabelsAndProperties: $7.(*ast.LabelsAndProperties),
   633  		}
   634  		if $2 != nil {
   635  			insertion.VariableName = $2.(model.CIStr)
   636  		}
   637  		$$ = insertion
   638  	}
   639  
   640  LabelsAndProperties:
   641  	LabelSpecificationOpt PropertiesSpecificationOpt
   642  	{
   643  		lps := &ast.LabelsAndProperties{}
   644  		if $1 != nil {
   645  			lps.Labels = $1.([]model.CIStr)
   646  		}
   647  		if $2 != nil {
   648  			lps.Assignments = $2.([]*ast.PropertyAssignment)
   649  		}
   650  		$$ = lps
   651  	}
   652  
   653  LabelSpecificationOpt:
   654  	{
   655  		$$ = nil
   656  	}
   657  |	LabelSpecification
   658  
   659  LabelSpecification:
   660  	"LABELS" '(' LabelNameListWithComma ')'
   661  	{
   662  		$$ = $3
   663  	}
   664  
   665  PropertiesSpecificationOpt:
   666  	{
   667  		$$ = nil
   668  	}
   669  |	PropertiesSpecification
   670  
   671  PropertiesSpecification:
   672  	"PROPERTIES" '(' PropertyAssignmentList ')'
   673  	{
   674  		$$ = $3
   675  	}
   676  
   677  PropertyAssignmentList:
   678  	PropertyAssignment
   679  	{
   680  		$$ = []*ast.PropertyAssignment{$1.(*ast.PropertyAssignment)}
   681  	}
   682  |	PropertyAssignmentList ',' PropertyAssignment
   683  	{
   684  		$$ = append($1.([]*ast.PropertyAssignment), $3.(*ast.PropertyAssignment))
   685  	}
   686  
   687  PropertyAssignment:
   688  	PropertyAccess eq ValueExpression
   689  	{
   690  		$$ = &ast.PropertyAssignment{
   691  			PropertyAccess:  $1.(*ast.PropertyAccess),
   692  			ValueExpression: $3.(ast.ExprNode),
   693  		}
   694  	}
   695  
   696  PropertyAccess:
   697  	VariableName '.' PropertyName
   698  	{
   699  		$$ = &ast.PropertyAccess{
   700  			VariableName: $1.(model.CIStr),
   701  			PropertyName: $3.(model.CIStr),
   702  		}
   703  	}
   704  
   705  ValueExpression:
   706  	VariableReference
   707  |	PropertyAccess
   708  |	Literal
   709  |	BindVariable
   710  |	ArithmeticExpression
   711  |	RelationalExpression
   712  |	LogicalExpression
   713  |	StringConcat
   714  |	BracketedValueExpression
   715  |	FunctionInvocation
   716  |	CharacterSubstring
   717  |	Aggregation
   718  |	ExtractFunction
   719  |	IsNullPredicate
   720  |	IsNotNullPredicate
   721  |	CastSpecification
   722  |	CaseExpression
   723  |	InPredicate
   724  |	NotInPredicate
   725  |	ExistsPredicate
   726  |	ScalarSubquery
   727  
   728  VariableReference:
   729  	VariableName
   730  	{
   731  		$$ = &ast.VariableReference{
   732  			VariableName: $1.(model.CIStr),
   733  		}
   734  	}
   735  
   736  Literal:
   737  	StringLiteral
   738  |	NumericLiteral
   739  |	BooleanLiteral
   740  |	DateLiteral
   741  |	TimeLiteral
   742  |	TimestampLiteral
   743  |	IntervalLiteral
   744  
   745  StringLiteral:
   746  	stringLit
   747  	{
   748  		$$ = ast.NewValueExpr($1)
   749  	}
   750  |	hexLit
   751  	{
   752  		$$ = ast.NewValueExpr($1)
   753  	}
   754  |	bitLit
   755  	{
   756  		$$ = ast.NewValueExpr($1)
   757  	}
   758  
   759  NumericLiteral:
   760  	intLit
   761  	{
   762  		$$ = ast.NewValueExpr($1)
   763  	}
   764  |	decLit
   765  	{
   766  		$$ = ast.NewValueExpr($1)
   767  	}
   768  |	floatLit
   769  	{
   770  		$$ = ast.NewValueExpr($1)
   771  	}
   772  
   773  BooleanLiteral:
   774  	"FALSE"
   775  	{
   776  		$$ = ast.NewValueExpr(false)
   777  	}
   778  |	"TRUE"
   779  	{
   780  		$$ = ast.NewValueExpr(true)
   781  	}
   782  
   783  DateLiteral:
   784  	"DATE" stringLit
   785  	{
   786  		d, err := datum.ParseDate($2)
   787  		if err != nil {
   788  			yylex.AppendError(err)
   789  			return 1
   790  		}
   791  		$$ = ast.NewValueExpr(d)
   792  	}
   793  
   794  TimeLiteral:
   795  	"TIME" stringLit
   796  	{
   797  		t, ttz, err := datum.ParseTimeOrTimeTZ($2)
   798  		if err != nil {
   799  			yylex.AppendError(err)
   800  			return 1
   801  		}
   802  		if t != nil {
   803  			$$ = ast.NewValueExpr(t)
   804  		} else {
   805  			$$ = ast.NewValueExpr(ttz)
   806  		}
   807  	}
   808  
   809  TimestampLiteral:
   810  	"TIMESTAMP" stringLit
   811  	{
   812  		t, ttz, err := datum.ParseTimestampOrTimestampTZ($2)
   813  		if err != nil {
   814  			yylex.AppendError(err)
   815  			return 1
   816  		}
   817  		if t != nil {
   818  			$$ = ast.NewValueExpr(t)
   819  		} else {
   820  			$$ = ast.NewValueExpr(ttz)
   821  		}
   822  	}
   823  
   824  IntervalLiteral:
   825  	"INTERVAL" intLit DateTimeField
   826  	{
   827  		$$ = ast.NewValueExpr(datum.NewInterval($2.(int64), $3.(datum.IntervalUnit)))
   828  	}
   829  
   830  DateTimeField:
   831  	"YEAR"
   832  	{
   833  		$$ = datum.IntervalUnitYear
   834  	}
   835  |	"MONTH"
   836  	{
   837  		$$ = datum.IntervalUnitMonth
   838  	}
   839  |	"DAY"
   840  	{
   841  		$$ = datum.IntervalUnitDay
   842  	}
   843  |	"HOUR"
   844  	{
   845  		$$ = datum.IntervalUnitHour
   846  	}
   847  |	"MINUTE"
   848  	{
   849  		$$ = datum.IntervalUnitMinute
   850  	}
   851  |	"SECOND"
   852  	{
   853  		$$ = datum.IntervalUnitSecond
   854  	}
   855  
   856  BindVariable:
   857  	'?'
   858  	{
   859  		$$ = &ast.BindVariable{}
   860  	}
   861  
   862  ArithmeticExpression:
   863  	'-' ValueExpression %prec neg
   864  	{
   865  		$$ = &ast.UnaryExpr{ Op: opcode.Minus, V:  $2}
   866  	}
   867  |	ValueExpression '*' ValueExpression %prec '*'
   868  	{
   869  		$$ = &ast.BinaryExpr{Op: opcode.Mul, L: $1, R: $3}
   870  	}
   871  |	ValueExpression '/' ValueExpression %prec '/'
   872  	{
   873  		$$ = &ast.BinaryExpr{Op: opcode.Div, L: $1, R: $3}
   874  	}
   875  |	ValueExpression '%' ValueExpression %prec '%'
   876  	{
   877  		$$ = &ast.BinaryExpr{Op: opcode.Mod, L: $1, R: $3}
   878  	}
   879  |	ValueExpression '+' ValueExpression %prec '+'
   880  	{
   881  		$$ = &ast.BinaryExpr{Op: opcode.Plus, L: $1, R: $3}
   882  	}
   883  |	ValueExpression '-' ValueExpression %prec '-'
   884  	{
   885  		$$ = &ast.BinaryExpr{Op: opcode.Minus, L: $1, R: $3}
   886  	}
   887  
   888  RelationalExpression:
   889  	ValueExpression eq ValueExpression
   890  	{
   891  		$$ = &ast.BinaryExpr{Op: opcode.EQ, L: $1, R: $3}
   892  	}
   893  |	ValueExpression neqSynonym ValueExpression
   894  	{
   895  		$$ = &ast.BinaryExpr{Op: opcode.NE, L: $1, R: $3}
   896  	}
   897  |	ValueExpression '>' ValueExpression
   898  	{
   899  		$$ = &ast.BinaryExpr{Op: opcode.GT, L: $1, R: $3}
   900  	}
   901  |	ValueExpression '<' ValueExpression
   902  	{
   903  		$$ = &ast.BinaryExpr{Op: opcode.LT, L: $1, R: $3}
   904  	}
   905  |	ValueExpression ge ValueExpression
   906  	{
   907  		$$ = &ast.BinaryExpr{Op: opcode.GE, L: $1, R: $3}
   908  	}
   909  |	ValueExpression le ValueExpression
   910  	{
   911  		$$ = &ast.BinaryExpr{Op: opcode.LE, L: $1, R: $3}
   912  	}
   913  
   914  LogicalExpression:
   915  	ValueExpression "OR" ValueExpression %prec pipes
   916  	{
   917  		$$ = &ast.BinaryExpr{Op: opcode.LogicOr, L: $1, R: $3}
   918  	}
   919  |	ValueExpression "XOR" ValueExpression %prec xor
   920  	{
   921  		$$ = &ast.BinaryExpr{Op: opcode.LogicXor, L: $1, R: $3}
   922  	}
   923  |	ValueExpression "AND" ValueExpression %prec andand
   924  	{
   925  		$$ = &ast.BinaryExpr{Op: opcode.LogicAnd, L: $1, R: $3}
   926  	}
   927  |	"NOT" ValueExpression %prec not
   928  	{
   929  		v, ok := $2.(*ast.ExistsSubqueryExpr)
   930  		if ok {
   931  			v.Not = true
   932  			$$ = $2
   933  		} else {
   934  			$$ = &ast.UnaryExpr{ Op: opcode.Not, V:  $2}
   935  		}
   936  	}
   937  
   938  StringConcat:
   939  	ValueExpression pipes ValueExpression
   940  	{
   941  		$$ = &ast.BinaryExpr{Op: opcode.Concat, L: $1, R: $3}
   942  	}
   943  
   944  BracketedValueExpression:
   945  	'(' ValueExpression ')'
   946  	{
   947  		$$ = &ast.ParenthesesExpr{Expr: $2}
   948  	}
   949  
   950  /******************************************************************************
   951  
   952   Reference
   953   - https://pgql-lang.org/spec/1.5/#user-defined-functions
   954  
   955   zGraph doesn't plan to support UDF and remove the PackageSpecificationOpt
   956  
   957   FunctionInvocation  ::= PackageSpecification? FunctionName '(' ArgumentList? ')'
   958   PackageSpecification::= PackageName '.'
   959   PackageName         ::= Identifier
   960  
   961   FunctionInvocation:
   962   	PackageSpecificationOpt FunctionName '(' ArgumentList ')'
   963   	{}
   964  
   965   PackageSpecificationOpt:
   966   	{}
   967   |	PackageName '.'
   968   	{}
   969  
   970   PackageName:
   971   	Identifier
   972  
   973   ******************************************************************************/
   974  FunctionInvocation:
   975  	FunctionName '(' ArgumentList ')'
   976  	{
   977  		$$ = &ast.FuncCallExpr{
   978  			FnName: model.NewCIStr($1),
   979  			Args:   $3.([]ast.ExprNode),
   980  		}
   981  	}
   982  
   983  FunctionName:
   984  	"LOWER"
   985  |	"UPPER"
   986  |	"JAVA_REGEXP_LIKE"
   987  |	"ABS"
   988  |	"CEIL"
   989  |	"CEILING"
   990  |	"FLOOR"
   991  |	"ID"
   992  |	"LABEL"
   993  |	"LABELS"
   994  |	"HAS_LABEL"
   995  |	"MATCH_NUMBER"
   996  |	"ELEMENT_NUMBER"
   997  |	"IN_DEGREE"
   998  |	"OUT_DEGREE"
   999  |	"ALL_DIFFERENT"
  1000  
  1001  ArgumentList:
  1002  	ValueExpression
  1003  	{
  1004  		$$ = []ast.ExprNode{$1}
  1005  	}
  1006  |	ArgumentList ',' ValueExpression
  1007  	{
  1008  		$$ = append($1.([]ast.ExprNode), $3)
  1009  	}
  1010  
  1011  CharacterSubstring:
  1012  	"SUBSTRING" '(' ValueExpression "FROM" StartPosition ForStringLengthOpt ')'
  1013  	{
  1014  		$$ = &ast.SubstrFuncExpr{
  1015  			Expr:  $3,
  1016  			Start: $5,
  1017  			For:   $6,
  1018  		}
  1019  	}
  1020  
  1021  StartPosition:
  1022  	ValueExpression
  1023  
  1024  ForStringLengthOpt:
  1025  	{
  1026  		$$ = nil
  1027  	}
  1028  |	"FOR" ValueExpression
  1029  	{
  1030  		$$ = $2
  1031  	}
  1032  
  1033  Aggregation:
  1034  	"COUNT" '(' '*' ')'
  1035  	{
  1036  		$$ = &ast.AggregateFuncExpr{
  1037  			F:    $1,
  1038  			Args: []ast.ExprNode{
  1039  				ast.NewValueExpr(1),
  1040  			},
  1041  		}
  1042  	}
  1043  |	"COUNT" '(' DistinctOpt ValueExpression ')'
  1044  	{
  1045  		$$ = &ast.AggregateFuncExpr{
  1046  			F:        $1,
  1047  			Args:     []ast.ExprNode{$4},
  1048  			Distinct: $3.(bool),
  1049  		}
  1050  	}
  1051  |	"MIN" '(' DistinctOpt ValueExpression ')'
  1052  	{
  1053  		$$ = &ast.AggregateFuncExpr{
  1054  			F:        $1,
  1055  			Args:     []ast.ExprNode{$4},
  1056  			Distinct: $3.(bool),
  1057  		}
  1058  	}
  1059  |	"MAX" '(' DistinctOpt ValueExpression ')'
  1060  	{
  1061  		$$ = &ast.AggregateFuncExpr{
  1062  			F:        $1,
  1063  			Args:     []ast.ExprNode{$4},
  1064  			Distinct: $3.(bool),
  1065  		}
  1066  	}
  1067  |	"AVG" '(' DistinctOpt ValueExpression ')'
  1068  	{
  1069  		$$ = &ast.AggregateFuncExpr{
  1070  			F:        $1,
  1071  			Args:     []ast.ExprNode{$4},
  1072  			Distinct: $3.(bool),
  1073  		}
  1074  	}
  1075  |	"SUM" '(' DistinctOpt ValueExpression ')'
  1076  	{
  1077  		$$ = &ast.AggregateFuncExpr{
  1078  			F:        $1,
  1079  			Args:     []ast.ExprNode{$4},
  1080  			Distinct: $3.(bool),
  1081  		}
  1082  	}
  1083  |	"ARRAY_AGG" '(' DistinctOpt ValueExpression ')'
  1084  	{
  1085  		$$ = &ast.AggregateFuncExpr{
  1086  			F:        $1,
  1087  			Args:     []ast.ExprNode{$4},
  1088  			Distinct: $3.(bool),
  1089  		}
  1090  	}
  1091  |	"LISTAGG" '(' DistinctOpt ValueExpression ListaggSeparatorOpt')'
  1092  	{
  1093  		expr := &ast.AggregateFuncExpr{
  1094  			F:        $1,
  1095  			Args:     []ast.ExprNode{$4},
  1096  			Distinct: $3.(bool),
  1097  		}
  1098  		if $5 != nil {
  1099  			expr.Args = append(expr.Args, $5)
  1100  		}
  1101  		$$ = expr
  1102  	}
  1103  
  1104  DistinctOpt:
  1105  	{
  1106  		$$ = false
  1107  	}
  1108  |	"DISTINCT"
  1109  	{
  1110  		$$ = true
  1111  	}
  1112  
  1113  ListaggSeparatorOpt:
  1114  	{
  1115  		$$ = nil
  1116  	}
  1117  |	',' StringLiteral
  1118  	{
  1119  		$$ = $2
  1120  	}
  1121  
  1122  ExtractFunction:
  1123  	"EXTRACT" '(' ExtractField "FROM" ValueExpression ')'
  1124  	{
  1125  		$$ = &ast.ExtractFuncExpr{
  1126  			ExtractField: $3.(ast.ExtractField),
  1127  			Expr:         $5,
  1128  		}
  1129  	}
  1130  
  1131  ExtractField:
  1132  	"YEAR"
  1133  	{
  1134  		$$ = ast.ExtractFieldYear
  1135  	}
  1136  |	"MONTH"
  1137  	{
  1138  		$$ = ast.ExtractFieldMonth
  1139  	}
  1140  |	"DAY"
  1141  	{
  1142  		$$ = ast.ExtractFieldDay
  1143  	}
  1144  |	"HOUR"
  1145  	{
  1146  		$$ = ast.ExtractFieldHour
  1147  	}
  1148  |	"MINUTE"
  1149  	{
  1150  		$$ = ast.ExtractFieldMinute
  1151  	}
  1152  |	"SECOND"
  1153  	{
  1154  		$$ = ast.ExtractFieldSecond
  1155  	}
  1156  |	"TIMEZONE_HOUR"
  1157  	{
  1158  		$$ = ast.ExtractFieldTimezoneHour
  1159  	}
  1160  |	"TIMEZONE_MINUTE"
  1161  	{
  1162  		$$ = ast.ExtractFieldTimezoneMinute
  1163  	}
  1164  
  1165  IsNullPredicate:
  1166  	ValueExpression "IS" "NULL"
  1167  	{
  1168  		$$ = &ast.IsNullExpr{
  1169  			Expr: $1,
  1170  		}
  1171  	}
  1172  
  1173  IsNotNullPredicate:
  1174  	ValueExpression "IS" "NOT" "NULL"
  1175  	{
  1176  		$$ = &ast.IsNullExpr{
  1177  			Expr: $1,
  1178  			Not:  true,
  1179  		}
  1180  	}
  1181  
  1182  CastSpecification:
  1183  	"CAST" '(' ValueExpression "AS" DataType ')'
  1184  	{
  1185  		$$ = &ast.CastFuncExpr{
  1186  			Expr:     $3,
  1187  			DataType: $5.(ast.DataType),
  1188  		}
  1189  	}
  1190  
  1191  DataType:
  1192  	"STRING"
  1193  	{
  1194  		$$ = ast.DataTypeString
  1195  	}
  1196  |	"BOOLEAN"
  1197  	{
  1198  		$$ = ast.DataTypeBoolean
  1199  	}
  1200  |	"INTEGER"
  1201  	{
  1202  		$$ = ast.DataTypeInteger
  1203  	}
  1204  |	"FLOAT"
  1205  	{
  1206  		$$ = ast.DataTypeFloat
  1207  	}
  1208  |	"DOUBLE"
  1209  	{
  1210  		$$ = ast.DataTypeDouble
  1211  	}
  1212  |	"DECIMAL"
  1213  	{
  1214  		$$ = ast.DataTypeDecimal
  1215  	}
  1216  |	"DATE"
  1217  	{
  1218  		$$ = ast.DataTypeDate
  1219  	}
  1220  |	"TIME"
  1221  	{
  1222  		$$ = ast.DataTypeTime
  1223  	}
  1224  |	"TIME" "WITH" "TIME" "ZONE"
  1225  	{
  1226  		$$ = ast.DataTypeTimeWithTimeZone
  1227  	}
  1228  |	"TIMESTAMP"
  1229  	{
  1230  		$$ = ast.DataTypeTimestamp
  1231  	}
  1232  |	"TIMESTAMP" "WITH" "TIME" "ZONE"
  1233  	{
  1234  		$$ = ast.DataTypeTimestampWithTimeZone
  1235  	}
  1236  
  1237  CaseExpression:
  1238  	SimpleCase
  1239  |	SearchedCase
  1240  
  1241  SimpleCase:
  1242  	"CASE" ValueExpression WhenClauseList ElseClauseOpt "END"
  1243  	{
  1244  		$$ = &ast.CaseExpr{
  1245  			Value:       $2,
  1246  			WhenClauses: $3.([]*ast.WhenClause),
  1247  			ElseClause:  $4,
  1248  		}
  1249  	}
  1250  
  1251  SearchedCase:
  1252  	"CASE" WhenClauseList ElseClauseOpt "END"
  1253  	{
  1254  		$$ = &ast.CaseExpr{
  1255  			WhenClauses: $2.([]*ast.WhenClause),
  1256  			ElseClause:  $3,
  1257  		}
  1258  	}
  1259  
  1260  WhenClauseList:
  1261  	WhenClause
  1262  	{
  1263  		$$ = []*ast.WhenClause{$1.(*ast.WhenClause)}
  1264  	}
  1265  |	WhenClauseList WhenClause
  1266  	{
  1267  		$$ = append($1.([]*ast.WhenClause), $2.(*ast.WhenClause))
  1268  	}
  1269  
  1270  WhenClause:
  1271  	"WHEN" ValueExpression "THEN" ValueExpression
  1272  	{
  1273  		$$ = &ast.WhenClause{
  1274  			Expr:   $2,
  1275  			Result: $4,
  1276  		}
  1277  	}
  1278  
  1279  ElseClauseOpt:
  1280  	{
  1281  		$$ = nil
  1282  	}
  1283  |	"ELSE" ValueExpression
  1284  	{
  1285  		$$ = $2
  1286  	}
  1287  
  1288  InPredicate:
  1289  	ValueExpression "IN" InValueList
  1290  	{
  1291  		$$ = &ast.PatternInExpr{
  1292  			Expr: $1,
  1293  			List: $3.([]ast.ExprNode),
  1294  		}
  1295  	}
  1296  
  1297  NotInPredicate:
  1298  	ValueExpression "NOT" "IN" InValueList
  1299  	{
  1300  		$$ = &ast.PatternInExpr{
  1301  			Expr: $1,
  1302  			List: $4.([]ast.ExprNode),
  1303  			Not:  true,
  1304  		}
  1305  	}
  1306  
  1307  InValueList:
  1308  	'(' ValueExpressionList ')'
  1309  	{
  1310  		$$ = $2
  1311  	}
  1312  
  1313  ValueExpressionList:
  1314  	ValueExpression
  1315  	{
  1316  		$$ = []ast.ExprNode{$1}
  1317  	}
  1318  |	ValueExpressionList ',' ValueExpression
  1319  	{
  1320  		$$ = append($1.([]ast.ExprNode), $3)
  1321  	}
  1322  
  1323  ExistsPredicate:
  1324  	"EXISTS" Subquery
  1325  	{
  1326  		$$ = &ast.ExistsSubqueryExpr{
  1327  			Sel: $2,
  1328  		}
  1329  	}
  1330  
  1331  Subquery:
  1332  	'(' SelectStmt ')'
  1333  	{
  1334  		$$ = &ast.SubqueryExpr{
  1335  			Query: $2.(*ast.SelectStmt),
  1336  		}
  1337  	}
  1338  
  1339  ScalarSubquery:
  1340  	Subquery
  1341  
  1342  /******************************************************************************
  1343  
  1344   ROLLBACK Statement
  1345  
  1346   *****************************************************************************/
  1347  RollbackStmt:
  1348  	"ROLLBACK"
  1349  	{}
  1350  
  1351  /*************************************Select Statement***************************************/
  1352  SelectStmt:
  1353  	PathPatternMacroOpt SelectClause FromClause WhereClauseOpt GroupByClauseOpt HavingClauseOpt OrderByClauseOpt LimitClauseOpt
  1354  	{
  1355  		ss := &ast.SelectStmt{
  1356  			Select: $2.(*ast.SelectClause),
  1357  			From:   $3.(*ast.MatchClauseList),
  1358  		}
  1359  		if $1 != nil {
  1360  			ss.PathPatternMacros = $1.([]*ast.PathPatternMacro)
  1361  		}
  1362  		if $4 != nil {
  1363  			ss.Where = $4.(ast.ExprNode)
  1364  		}
  1365  		if $5 != nil {
  1366  			ss.GroupBy = $5.(*ast.GroupByClause)
  1367  		}
  1368  		if $6 != nil {
  1369  			ss.Having = $6.(*ast.HavingClause)
  1370  		}
  1371  		if $7 != nil {
  1372  			ss.OrderBy = $7.(*ast.OrderByClause)
  1373  		}
  1374  		if $8 != nil {
  1375  			ss.Limit = $8.(*ast.LimitClause)
  1376  		}
  1377  		$$ = ss
  1378  	}
  1379  
  1380  SelectClause:
  1381  	"SELECT" DistinctOpt SelectElementList
  1382  	{
  1383  		$$ = &ast.SelectClause{
  1384  			Distinct: $2.(bool),
  1385  			Elements: $3.([]*ast.SelectElement),
  1386  		}
  1387  	}
  1388  |	"SELECT" '*' %prec '*'
  1389  	{
  1390  		$$ = &ast.SelectClause{
  1391  			Star: true,
  1392  		}
  1393  	}
  1394  
  1395  SelectElementList:
  1396  	SelectEelement
  1397  	{
  1398  		$$ = []*ast.SelectElement{$1.(*ast.SelectElement)}
  1399  	}
  1400  |	SelectElementList ',' SelectEelement
  1401  	{
  1402  		$$ = append($1.([]*ast.SelectElement), $3.(*ast.SelectElement))
  1403  	}
  1404  
  1405  SelectEelement:
  1406  	ExpAsVar
  1407  	{
  1408  		$$ = &ast.SelectElement{
  1409  			ExpAsVar: $1.(*ast.ExpAsVar),
  1410  		}
  1411  	}
  1412  |	Identifier allProp AllPropertiesPrefixOpt %prec '*'
  1413  	{
  1414  		$$ = &ast.SelectElement{
  1415  			Identifier: $1,
  1416  			Prefix:     $3.(string),
  1417  		}
  1418  	}
  1419  
  1420  ExpAsVar:
  1421  	ValueExpression FieldAsNameOpt
  1422  	{
  1423  		ev := &ast.ExpAsVar{
  1424  			Expr: $1.(ast.ExprNode),
  1425  		}
  1426  		if $2 != nil {
  1427  			ev.AsName = $2.(model.CIStr)
  1428  		}
  1429  		$$ = ev
  1430  	}
  1431  
  1432  AllPropertiesPrefixOpt:
  1433  	%prec empty
  1434  	{
  1435  		$$ = ""
  1436  	}
  1437  |	"PREFIX" StringLiteral
  1438  	{
  1439  		$$ = $1
  1440  	}
  1441  
  1442  FieldAsNameOpt:
  1443  	/* EMPTY */
  1444  	{
  1445  		$$ = nil
  1446  	}
  1447  |	FieldAsName
  1448  	{
  1449  		$$ = $1.(model.CIStr)
  1450  	}
  1451  
  1452  FieldAsName:
  1453  	"AS" Identifier
  1454  	{
  1455  		$$ = model.NewCIStr($2)
  1456  	}
  1457  |	"AS" stringLit
  1458  	{
  1459  		$$ = model.NewCIStr($2)
  1460  	}
  1461  
  1462  FromClause:
  1463  	"FROM" MatchClauseList
  1464  	{
  1465  		$$ = $2.(*ast.MatchClauseList)
  1466  	}
  1467  
  1468  FromClauseOpt:
  1469  	/* EMPTY */
  1470  	{
  1471  		$$ = nil
  1472  	}
  1473  |	FromClause
  1474  	{
  1475  		$$ = $1.(*ast.MatchClauseList)
  1476  	}
  1477  
  1478  MatchClauseList:
  1479  	MatchClause
  1480  	{
  1481  		$$ = &ast.MatchClauseList{
  1482  			Matches: []*ast.MatchClause{$1.(*ast.MatchClause)},
  1483  		}
  1484  	}
  1485  |	MatchClauseList ',' MatchClause
  1486  	{
  1487  		ml := $1.(*ast.MatchClauseList)
  1488  		ml.Matches = append(ml.Matches, $3.(*ast.MatchClause))
  1489  		$$ = ml
  1490  	}
  1491  
  1492  MatchClause:
  1493  	"MATCH" GraphPattern GraphOnClauseOpt RowsPerMatchOpt
  1494  	{
  1495  		mc := &ast.MatchClause{
  1496  			Paths: $2.([]*ast.PathPattern),
  1497  		}
  1498  		if $3 != nil {
  1499  			mc.Graph = $3.(model.CIStr)
  1500  		}
  1501  		$$ = mc
  1502  	}
  1503  
  1504  GraphOnClause:
  1505  	"ON" GraphName
  1506  	{
  1507  		$$ = $2.(model.CIStr)
  1508  	}
  1509  
  1510  GraphOnClauseOpt:
  1511  	%prec lowerThanOn
  1512  	{
  1513  		$$ = nil
  1514  	}
  1515  |	GraphOnClause
  1516  
  1517  RowsPerMatchOpt:
  1518  	{}
  1519  
  1520  GraphPattern:
  1521  	PathPattern
  1522  	{
  1523  		$$ = []*ast.PathPattern{$1.(*ast.PathPattern)}
  1524  	}
  1525  |	'(' PathPatternList ')'
  1526  	{
  1527  		$$ = $2.([]*ast.PathPattern)
  1528  	}
  1529  
  1530  PathPatternList:
  1531  	PathPattern
  1532  	{
  1533  		$$ = []*ast.PathPattern{$1.(*ast.PathPattern)}
  1534  	}
  1535  |	PathPatternList ',' PathPattern
  1536  	{
  1537  		$$ = append($1.([]*ast.PathPattern), $3.(*ast.PathPattern))
  1538  	}
  1539  
  1540  PathPattern:
  1541  	SimplePathPattern
  1542  	{
  1543  		pp := $1.(*ast.PathPattern)
  1544  		pp.Tp = ast.PathPatternSimple
  1545  		$$ = pp
  1546  	}
  1547  |	"ANY" VariableLengthPathPattern
  1548  	{
  1549  		pp := $2.(*ast.PathPattern)
  1550  		pp.Tp = ast.PathPatternAny
  1551  		$$ = pp
  1552  	}
  1553  |	"ANY" "SHORTEST" VariableLengthPathPattern
  1554  	{
  1555  		pp := $3.(*ast.PathPattern)
  1556  		pp.Tp = ast.PathPatternAnyShortest
  1557  		$$ = pp
  1558  	}
  1559  |	"ALL" "SHORTEST" VariableLengthPathPattern
  1560  	{
  1561  		pp := $3.(*ast.PathPattern)
  1562  		pp.Tp = ast.PathPatternAllShortest
  1563  		$$ = pp
  1564  	}
  1565  |	"TOP" intLit "SHORTEST" VariableLengthPathPattern
  1566  	{
  1567  		pp := $4.(*ast.PathPattern)
  1568  		pp.Tp = ast.PathPatternTopKShortest
  1569  		pp.TopK = $2.(int64)
  1570  		$$ = pp
  1571  	}
  1572  |	"ANY" "CHEAPEST" VariableLengthPathPattern
  1573  	{
  1574  		pp := $3.(*ast.PathPattern)
  1575  		pp.Tp = ast.PathPatternAnyCheapest
  1576  		$$ = pp
  1577  	}
  1578  |	"ALL" "CHEAPEST" VariableLengthPathPattern
  1579  	{
  1580  		pp := $3.(*ast.PathPattern)
  1581  		pp.Tp = ast.PathPatternAllCheapest
  1582  		$$ = pp
  1583  	}
  1584  |	"TOP" intLit "CHEAPEST" VariableLengthPathPattern
  1585  	{
  1586  		pp := $4.(*ast.PathPattern)
  1587  		pp.Tp = ast.PathPatternTopKCheapest
  1588  		pp.TopK = $2.(int64)
  1589  		$$ = pp
  1590  	}
  1591  |	"ALL" VariableLengthPathPattern
  1592  	{
  1593  		pp := $2.(*ast.PathPattern)
  1594  		pp.Tp = ast.PathPatternAll
  1595  		$$ = pp
  1596  	}
  1597  
  1598  SimplePathPattern:
  1599  	VertexPattern
  1600  	{
  1601  		$$ = &ast.PathPattern{Vertices: []*ast.VertexPattern{$1.(*ast.VertexPattern)}}
  1602  	}
  1603  |	SimplePathPattern ReachabilityPathExpr VertexPattern
  1604  	{
  1605  		pp := $1.(*ast.PathPattern)
  1606  		pp.Vertices = append(pp.Vertices, $3.(*ast.VertexPattern))
  1607  		pp.Connections = append(pp.Connections, $2.(*ast.ReachabilityPathExpr))
  1608  		$$ = pp
  1609  	}
  1610  |	SimplePathPattern EdgePattern VertexPattern
  1611  	{
  1612  		pp := $1.(*ast.PathPattern)
  1613  		pp.Vertices = append(pp.Vertices, $3.(*ast.VertexPattern))
  1614  		pp.Connections = append(pp.Connections, $2.(*ast.EdgePattern))
  1615  		$$ = pp
  1616  	}
  1617  
  1618  VariableLengthPathPattern:
  1619  	VertexPattern QuantifiedPathExpr VertexPattern
  1620  	{
  1621  		$$ = &ast.PathPattern{
  1622  			Vertices:    []*ast.VertexPattern{$1.(*ast.VertexPattern), $3.(*ast.VertexPattern)},
  1623  			Connections: []ast.VertexPairConnection{$2.(*ast.QuantifiedPathExpr)},
  1624  		}
  1625  	}
  1626  
  1627  ReachabilityPathExpr:
  1628  	"-/" LabelPredicate PatternQuantifierOpt "/->"
  1629  	{
  1630  		$$ = &ast.ReachabilityPathExpr{
  1631  			Labels:     $2.([]model.CIStr),
  1632  			Direction:  ast.EdgeDirectionOutgoing,
  1633  			Quantifier: $3.(*ast.PatternQuantifier),
  1634  		}
  1635  	}
  1636  |	"<-/" LabelPredicate PatternQuantifierOpt "/-"
  1637  	{
  1638  		$$ = &ast.ReachabilityPathExpr{
  1639  			Labels:     $2.([]model.CIStr),
  1640  			Direction:  ast.EdgeDirectionIncoming,
  1641  			Quantifier: $3.(*ast.PatternQuantifier),
  1642  		}
  1643  	}
  1644  |	"-/" LabelPredicate PatternQuantifierOpt "/-"
  1645  	{
  1646  		$$ = &ast.ReachabilityPathExpr{
  1647  			Labels:     $2.([]model.CIStr),
  1648  			Direction:  ast.EdgeDirectionAnyDirected,
  1649  			Quantifier: $3.(*ast.PatternQuantifier),
  1650  		}
  1651  	}
  1652  
  1653  VertexPattern:
  1654  	'(' VariableSpec ')'
  1655  	{
  1656  		$$ = &ast.VertexPattern{Variable: $2.(*ast.VariableSpec)}
  1657  	}
  1658  
  1659  VertexPatternOpt:
  1660  	{
  1661  		$$ = (*ast.VertexPattern)(nil)
  1662  	}
  1663  |	VertexPattern
  1664  
  1665  EdgePattern:
  1666  	"-[" VariableSpec "]->"
  1667  	{
  1668  		$$ = &ast.EdgePattern{
  1669  			Variable:  $2.(*ast.VariableSpec),
  1670  			Direction: ast.EdgeDirectionOutgoing,
  1671  		}
  1672  	}
  1673  |	"->"
  1674  	{
  1675  		$$ = &ast.EdgePattern{Direction: ast.EdgeDirectionOutgoing}
  1676  	}
  1677  |	"<-[" VariableSpec "]-"
  1678  	{
  1679  		$$ = &ast.EdgePattern{
  1680  			Variable:  $2.(*ast.VariableSpec),
  1681  			Direction: ast.EdgeDirectionIncoming,
  1682  		}
  1683  	}
  1684  |	"<-"
  1685  	{
  1686  		$$ = &ast.EdgePattern{Direction: ast.EdgeDirectionIncoming}
  1687  	}
  1688  |	"-[" VariableSpec "]-"
  1689  	{
  1690  		$$ = &ast.EdgePattern{
  1691  			Variable:  $2.(*ast.VariableSpec),
  1692  			Direction: ast.EdgeDirectionAnyDirected,
  1693  		}
  1694  	}
  1695  |	'-'
  1696  	{
  1697  		$$ = &ast.EdgePattern{Direction: ast.EdgeDirectionAnyDirected}
  1698  	}
  1699  
  1700  VariableSpec:
  1701  	VariableNameOpt LabelPredicateOpt
  1702  	{
  1703  		v := &ast.VariableSpec{
  1704  			Name:   $1.(model.CIStr),
  1705  			Labels: $2.([]model.CIStr),
  1706  		}
  1707  		if v.Name.L == "" {
  1708  			v.Anonymous = true
  1709  		}
  1710  		$$ = v
  1711  	}
  1712  
  1713  VariableName:
  1714  	Identifier
  1715  	{
  1716  		$$ = model.NewCIStr($1)
  1717  	}
  1718  
  1719  VariableNameOpt:
  1720  	{
  1721  		$$ = model.CIStr{}
  1722  	}
  1723  |	VariableName
  1724  
  1725  VariableNameList:
  1726  	VariableName
  1727  	{
  1728  		$$ = []model.CIStr{$1.(model.CIStr)}
  1729  	}
  1730  |	VariableNameList ',' VariableName
  1731  	{
  1732  		$$ = append($1.([]model.CIStr), $3.(model.CIStr))
  1733  	}
  1734  
  1735  LabelPredicate:
  1736  	ColonOrIsKeyword LabelNameList
  1737  	{
  1738  		$$ = $2.([]model.CIStr)
  1739  	}
  1740  
  1741  LabelPredicateOpt:
  1742  	{
  1743  		$$ = []model.CIStr(nil)
  1744  	}
  1745  |	LabelPredicate
  1746  
  1747  ColonOrIsKeyword:
  1748  	':'
  1749  |	"IS"
  1750  
  1751  LabelNameListWithComma:
  1752  	LabelName
  1753  	{
  1754  		$$ = []model.CIStr{$1.(model.CIStr)}
  1755  	}
  1756  |	LabelNameListWithComma ',' LabelName
  1757  	{
  1758  		$$ = append($1.([]model.CIStr), $3.(model.CIStr))
  1759  	}
  1760  
  1761  LabelNameList:
  1762  	LabelName
  1763  	{
  1764  		$$ = []model.CIStr{$1.(model.CIStr)}
  1765  	}
  1766  |	LabelNameList '|' LabelName
  1767  	{
  1768  		$$ = append($1.([]model.CIStr), $3.(model.CIStr))
  1769  	}
  1770  
  1771  QuantifiedPathExpr:
  1772  	EdgePattern PatternQuantifierOpt
  1773  	{
  1774  		$$ = &ast.QuantifiedPathExpr{
  1775  			Edge:       $1.(*ast.EdgePattern),
  1776  			Quantifier: $2.(*ast.PatternQuantifier),
  1777  		}
  1778  	}
  1779  |	'(' VertexPatternOpt EdgePattern VertexPatternOpt WhereClauseOpt CostClauseOpt ')' PatternQuantifierOpt
  1780  	{
  1781  		q := &ast.QuantifiedPathExpr{
  1782  			Edge:        $3.(*ast.EdgePattern),
  1783  			Quantifier:  $8.(*ast.PatternQuantifier),
  1784  			Source:      $2.(*ast.VertexPattern),
  1785  			Destination: $4.(*ast.VertexPattern),
  1786  		}
  1787  		if $5 != nil {
  1788  			q.Where = $5.(ast.ExprNode)
  1789  		}
  1790  		if $6 != nil {
  1791  			q.Cost = $6.(ast.ExprNode)
  1792  		}
  1793  		$$ = q
  1794  	}
  1795  
  1796  CostClause:
  1797  	"COST" ValueExpression
  1798  	{
  1799  		$$ = $2.(ast.ExprNode)
  1800  	}
  1801  
  1802  CostClauseOpt:
  1803  	{
  1804  		$$ = nil
  1805  	}
  1806  |	CostClause
  1807  
  1808  PatternQuantifier:
  1809  	'*'
  1810  	{
  1811  		$$ = &ast.PatternQuantifier{Tp: ast.PatternQuantifierZeroOrMore, M: math.MaxInt64}
  1812  	}
  1813  |	'+'
  1814  	{
  1815  		$$ = &ast.PatternQuantifier{Tp: ast.PatternQuantifierOneOrMore, N: 1, M: math.MaxInt64}
  1816  	}
  1817  // '?' is declared as paramMarker before.
  1818  |	paramMarker
  1819  	{
  1820  		$$ = &ast.PatternQuantifier{Tp: ast.PatternQuantifierOptional, N: 0, M: 1}
  1821  	}
  1822  |	'{' intLit '}'
  1823  	{
  1824  		$$ = &ast.PatternQuantifier{Tp: ast.PatternQuantifierExactlyN, N: $2.(int64), M: $2.(int64)}
  1825  	}
  1826  |	'{' intLit ',' '}'
  1827  	{
  1828  		$$ = &ast.PatternQuantifier{Tp: ast.PatternQuantifierNOrMore, N: $2.(int64), M: math.MaxInt64}
  1829  	}
  1830  |	'{' intLit ',' intLit '}'
  1831  	{
  1832  		$$ = &ast.PatternQuantifier{Tp: ast.PatternQuantifierBetweenNAndM, N: $2.(int64), M: $4.(int64)}
  1833  	}
  1834  |	'{' ',' intLit '}'
  1835  	{
  1836  		$$ = &ast.PatternQuantifier{Tp: ast.PatternQuantifierBetweenZeroAndM, N: 0, M: $3.(int64)}
  1837  	}
  1838  
  1839  PatternQuantifierOpt:
  1840  	{
  1841  		$$ = (*ast.PatternQuantifier)(nil)
  1842  	}
  1843  |	PatternQuantifier
  1844  
  1845  PathPatternMacroOpt:
  1846  	{
  1847  		$$ = nil
  1848  	}
  1849  |	PathPatternMacroList
  1850  
  1851  PathPatternMacroList:
  1852  	PathPatternMacro
  1853  	{
  1854  		$$ = []*ast.PathPatternMacro{$1.(*ast.PathPatternMacro)}
  1855  	}
  1856  |	PathPatternMacroList PathPatternMacro
  1857  	{
  1858  		$$ = append($1.([]*ast.PathPatternMacro), $2.(*ast.PathPatternMacro))
  1859  	}
  1860  
  1861  PathPatternMacro:
  1862  	"PATH" Identifier "AS" PathPattern WhereClauseOpt
  1863  	{
  1864  		p := &ast.PathPatternMacro{
  1865  			Name: model.NewCIStr($2),
  1866  			Path: $4.(*ast.PathPattern),
  1867  		}
  1868  		if $5 != nil {
  1869  			p.Where = $5.(ast.ExprNode)
  1870  		}
  1871  		$$ = p
  1872  	}
  1873  
  1874  WhereClauseOpt:
  1875   	{
  1876   		$$ = nil
  1877   	}
  1878  |	"WHERE" ValueExpression
  1879  	{
  1880  		$$ = $2
  1881  	}
  1882  
  1883  GroupByClauseOpt:
  1884   	{
  1885   		$$ = nil
  1886   	}
  1887  |	"GROUP" "BY" ByList
  1888  	{
  1889  		$$ = &ast.GroupByClause{Items: $3.([]*ast.ByItem)}
  1890  	}
  1891  
  1892  ByList:
  1893  	ByItem
  1894  	{
  1895  		$$ = []*ast.ByItem{$1.(*ast.ByItem)}
  1896  	}
  1897  |	ByList ',' ByItem
  1898  	{
  1899  		$$ = append($1.([]*ast.ByItem), $3.(*ast.ByItem))
  1900  	}
  1901  
  1902  ByItem:
  1903  	ExpAsVar
  1904  	{
  1905  		$$ = &ast.ByItem{
  1906  			Expr: $1.(*ast.ExpAsVar),
  1907  			NullOrder: true,
  1908  		}
  1909  	}
  1910  |	ExpAsVar Order
  1911  	{
  1912  		$$ = &ast.ByItem{
  1913  			Expr: $1.(*ast.ExpAsVar),
  1914  			Desc: $2.(bool),
  1915  		}
  1916  	}
  1917  
  1918  Order:
  1919  	"ASC"
  1920  	{
  1921  		$$ = false
  1922  	}
  1923  |	"DESC"
  1924  	{
  1925  		$$ = true
  1926  	}
  1927  
  1928  HavingClauseOpt:
  1929  	{
  1930  		$$ = nil
  1931  	}
  1932  |	"HAVING" ValueExpression
  1933  	{
  1934  		$$ = &ast.HavingClause{
  1935  			Expr: $2,
  1936  		}
  1937  	}
  1938  
  1939  OrderByClauseOpt:
  1940   	{
  1941   		$$ = nil
  1942   	}
  1943  |	"ORDER" "BY" ByList
  1944  	{
  1945  		$$ = &ast.OrderByClause{
  1946  			Items: $3.([]*ast.ByItem),
  1947  		}
  1948  	}
  1949  
  1950  LimitClauseOpt:
  1951   	{
  1952   		$$ = nil
  1953   	}
  1954  |	"LIMIT" LimitOption
  1955  	{
  1956  		$$ = &ast.LimitClause{
  1957  			Count: $2,
  1958  		}
  1959  	}
  1960  |	"LIMIT" LimitOption ',' LimitOption
  1961  	{
  1962  		$$ = &ast.LimitClause{
  1963  			Count:  $4.(ast.ExprNode),
  1964  			Offset: $2.(ast.ExprNode),
  1965  		}
  1966  	}
  1967  |	"LIMIT" LimitOption "OFFSET" LimitOption
  1968  	{
  1969  		$$ = &ast.LimitClause{
  1970  			Count:  $2.(ast.ExprNode),
  1971  			Offset: $4.(ast.ExprNode),
  1972  		}
  1973  	}
  1974  
  1975  LimitOption:
  1976  	LengthNum
  1977  |	paramMarker
  1978  	{
  1979  		$$ = &ast.BindVariable{}
  1980  	}
  1981  
  1982  LengthNum:
  1983  	intLit
  1984  	{
  1985  		$$ = ast.NewValueExpr($1)
  1986  	}
  1987  
  1988  /******************************************************************************
  1989  
  1990   UPDATE Statement Specification
  1991   Reference: https://pgql-lang.org/spec/1.5/#update
  1992  
  1993   ******************************************************************************/
  1994  UpdateStmt:
  1995  	PathPatternMacroOpt "UPDATE" GraphElementUpdateList FromClause WhereClauseOpt GroupByClauseOpt HavingClauseOpt OrderByClauseOpt LimitClauseOpt
  1996  	{
  1997  		us := &ast.UpdateStmt{
  1998  			Updates:  $3.([]*ast.GraphElementUpdate),
  1999  			From:     $4.(*ast.MatchClauseList),
  2000  		}
  2001  		if $1 != nil {
  2002  			us.PathPatternMacros = $1.([]*ast.PathPatternMacro)
  2003  		}
  2004  		if $5 != nil {
  2005  			us.Where = $5.(ast.ExprNode)
  2006  		}
  2007  		if $6 != nil {
  2008  			us.GroupBy = $6.(*ast.GroupByClause)
  2009  		}
  2010  		if $7 != nil {
  2011  			us.Having = $7.(*ast.HavingClause)
  2012  		}
  2013  		if $8 != nil {
  2014  			us.OrderBy = $8.(*ast.OrderByClause)
  2015  		}
  2016  		if $9 != nil {
  2017  			us.Limit = $9.(*ast.LimitClause)
  2018  		}
  2019  		$$ = us
  2020  	}
  2021  
  2022  GraphElementUpdateList:
  2023  	GraphElementUpdate
  2024  	{
  2025  		$$ = []*ast.GraphElementUpdate{$1.(*ast.GraphElementUpdate)}
  2026  	}
  2027  |	GraphElementUpdateList ',' GraphElementUpdate
  2028  	{
  2029  		$$ = append($1.([]*ast.GraphElementUpdate), $3.(*ast.GraphElementUpdate))
  2030  	}
  2031  
  2032  GraphElementUpdate:
  2033  	VariableName "SET" '(' PropertyAssignmentList ')'
  2034  	{
  2035  		$$ = &ast.GraphElementUpdate{
  2036  			VariableName: $1.(model.CIStr),
  2037  			Assignments:  $4.([]*ast.PropertyAssignment),
  2038  		}
  2039  	}
  2040  
  2041  UseStmt:
  2042  	"USE" GraphName
  2043  	{
  2044  		$$ = &ast.UseStmt{
  2045  			GraphName: $2.(model.CIStr),
  2046  		}
  2047  	}
  2048  
  2049  ShowStmt:
  2050  	"SHOW" "GRAPHS"
  2051  	{
  2052  		$$ = &ast.ShowStmt{
  2053  			Tp: ast.ShowTargetGraphs,
  2054  		}
  2055  	}
  2056  |	"SHOW" "LABELS"
  2057  	{
  2058  		$$ = &ast.ShowStmt{
  2059  			Tp: ast.ShowTargetLabels,
  2060  		}
  2061  	}
  2062  |	"SHOW" "LABELS" "IN" GraphName
  2063  	{
  2064  		$$ = &ast.ShowStmt{
  2065  			Tp: ast.ShowTargetLabels,
  2066  			GraphName: $4.(model.CIStr),
  2067  		}
  2068  	}
  2069  
  2070  IfExists:
  2071  	{
  2072  		$$ = false
  2073  	}
  2074  |	"IF" "EXISTS"
  2075  	{
  2076  		$$ = true
  2077  	}
  2078  
  2079  IfNotExists:
  2080  	{
  2081  		$$ = false
  2082  	}
  2083  |	"IF" "NOT" "EXISTS"
  2084  	{
  2085  		$$ = true
  2086  	}
  2087  
  2088  GraphName:
  2089  	Identifier
  2090  	{
  2091  		$$ = model.NewCIStr($1)
  2092  	}
  2093  
  2094  PropertyName:
  2095  	Identifier
  2096  	{
  2097  		$$ = model.NewCIStr($1)
  2098  	}
  2099  
  2100  IndexName:
  2101  	Identifier
  2102  	{
  2103  		$$ = model.NewCIStr($1)
  2104  	}
  2105  
  2106  LabelName:
  2107  	Identifier
  2108  	{
  2109  		$$ = model.NewCIStr($1)
  2110  	}
  2111  
  2112  Identifier:
  2113  	identifier
  2114  |	UnReservedKeyword
  2115  
  2116  UnReservedKeyword:
  2117  	"BEGIN"
  2118  |	"END"
  2119  |	"COMMIT"
  2120  |	"BOOLEAN"
  2121  |	"EXPLAIN"
  2122  |	"YEAR"
  2123  |	"DATE"
  2124  |	"DAY"
  2125  |	"TIMESTAMP"
  2126  |	"TIME"
  2127  |	"ROLLBACK"
  2128  |	"OFFSET"
  2129  |	"GRAPH"
  2130  |	"ALL"
  2131  |	"ANY"
  2132  |	"SHORTEST"
  2133  |	"CHEAPEST"
  2134  |	"TOP"
  2135  |	"COST"
  2136  |	"PATH"
  2137  |	"INTERVAL"
  2138  |	"HOUR"
  2139  |	"MINUTE"
  2140  |	"MONTH"
  2141  |	"SECOND"
  2142  |	"SUBSTRING"
  2143  |	"FOR"
  2144  |	"ARRAY_AGG"
  2145  |	"AVG"
  2146  |	"COUNT"
  2147  |	"LISTAGG"
  2148  |	"MAX"
  2149  |	"MIN"
  2150  |	"SUM"
  2151  |	"EXTRACT"
  2152  |	"TIMEZONE_HOUR"
  2153  |	"TIMEZONE_MINUTE"
  2154  |	"CAST"
  2155  |	"STRING"
  2156  |	"WITH"
  2157  |	"ZONE"
  2158  |	"PREFIX"
  2159  
  2160  PropertyNameList:
  2161  	PropertyName
  2162  	{
  2163  		$$ = []model.CIStr{$1.(model.CIStr)}
  2164  	}
  2165  |	PropertyNameList ',' PropertyName
  2166  	{
  2167  		$$ = append($1.([]model.CIStr), $3.(model.CIStr))
  2168  	}
  2169  
  2170  %%