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 %%