github.com/bingoohuang/gg@v0.0.0-20240325092523-45da7dee9335/pkg/sqlparse/sqlparser/sql.y (about) 1 /* 2 Copyright 2017 Google Inc. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 %{ 18 package sqlparser 19 20 func setParseTree(yylex interface{}, stmt Statement) { 21 yylex.(*Tokenizer).ParseTree = stmt 22 } 23 24 func setAllowComments(yylex interface{}, allow bool) { 25 yylex.(*Tokenizer).AllowComments = allow 26 } 27 28 func incNesting(yylex interface{}) bool { 29 yylex.(*Tokenizer).nesting++ 30 if yylex.(*Tokenizer).nesting == 200 { 31 return true 32 } 33 return false 34 } 35 36 func decNesting(yylex interface{}) { 37 yylex.(*Tokenizer).nesting-- 38 } 39 40 func forceEOF(yylex interface{}) { 41 yylex.(*Tokenizer).ForceEOF = true 42 } 43 44 %} 45 46 %union { 47 empty struct{} 48 statement Statement 49 selStmt SelectStatement 50 ins *Insert 51 byt byte 52 bytes []byte 53 bytes2 [][]byte 54 str string 55 selectExprs SelectExprs 56 selectExpr SelectExpr 57 columns Columns 58 colName *ColName 59 tableExprs TableExprs 60 tableExpr TableExpr 61 tableName TableName 62 tableNames TableNames 63 indexHints *IndexHints 64 expr Expr 65 exprs Exprs 66 boolVal BoolVal 67 colTuple ColTuple 68 values Values 69 valTuple ValTuple 70 subquery *Subquery 71 whens []*When 72 when *When 73 orderBy OrderBy 74 order *Order 75 limit *Limit 76 updateExprs UpdateExprs 77 updateExpr *UpdateExpr 78 colIdent ColIdent 79 colIdents []ColIdent 80 tableIdent TableIdent 81 convertType *ConvertType 82 aliasedTableName *AliasedTableExpr 83 } 84 85 %token LEX_ERROR 86 %left <bytes> UNION 87 %token <bytes> SELECT INSERT UPDATE DELETE FROM WHERE GROUP HAVING ORDER BY LIMIT OFFSET FOR 88 %token <bytes> ALL DISTINCT AS EXISTS ASC DESC INTO DUPLICATE KEY DEFAULT SET LOCK 89 %token <bytes> VALUES LAST_INSERT_ID 90 %token <bytes> NEXT VALUE SHARE MODE 91 %token <bytes> SQL_NO_CACHE SQL_CACHE 92 %left <bytes> JOIN STRAIGHT_JOIN LEFT RIGHT INNER OUTER CROSS NATURAL USE FORCE 93 %left <bytes> ON 94 %token <empty> '(' ',' ')' 95 %token <bytes> ID HEX STRING INTEGRAL FLOAT HEXNUM VALUE_ARG LIST_ARG COMMENT 96 %token <bytes> NULL TRUE FALSE 97 98 // Precedence dictated by mysql. But the vitess grammar is simplified. 99 // Some of these operators don't conflict in our situation. Nevertheless, 100 // it's better to have these listed in the correct order. Also, we don't 101 // support all operators yet. 102 %left <bytes> OR 103 %left <bytes> AND 104 %right <bytes> NOT '!' 105 %left <bytes> BETWEEN CASE WHEN THEN ELSE END 106 %left <bytes> '=' '<' '>' LE GE NE NULL_SAFE_EQUAL IS LIKE REGEXP IN 107 %left <bytes> '|' 108 %left <bytes> '&' 109 %left <bytes> SHIFT_LEFT SHIFT_RIGHT 110 %left <bytes> '+' '-' 111 %left <bytes> '*' '/' DIV '%' MOD 112 %left <bytes> '^' 113 %right <bytes> '~' UNARY 114 %left <bytes> COLLATE 115 %right <bytes> BINARY 116 %right <bytes> INTERVAL 117 %nonassoc <bytes> '.' 118 119 // There is no need to define precedence for the JSON 120 // operators because the syntax is restricted enough that 121 // they don't cause conflicts. 122 %token <empty> JSON_EXTRACT_OP JSON_UNQUOTE_EXTRACT_OP 123 124 // DDL Tokens 125 %token <bytes> CREATE ALTER DROP RENAME ANALYZE 126 %token <bytes> TABLE INDEX VIEW TO IGNORE IF UNIQUE USING 127 %token <bytes> SHOW DESCRIBE EXPLAIN DATE ESCAPE REPAIR OPTIMIZE TRUNCATE 128 129 // Supported SHOW tokens 130 %token <bytes> DATABASES TABLES VITESS_KEYSPACES VITESS_SHARDS VSCHEMA_TABLES 131 132 // Convert Type Tokens 133 %token <bytes> INTEGER CHARACTER 134 135 // Functions 136 %token <bytes> CURRENT_TIMESTAMP DATABASE CURRENT_DATE 137 %token <bytes> CURRENT_TIME LOCALTIME LOCALTIMESTAMP 138 %token <bytes> UTC_DATE UTC_TIME UTC_TIMESTAMP 139 %token <bytes> REPLACE 140 %token <bytes> CONVERT CAST 141 %token <bytes> GROUP_CONCAT SEPARATOR 142 143 // Match 144 %token <bytes> MATCH AGAINST BOOLEAN LANGUAGE WITH QUERY EXPANSION 145 146 // MySQL reserved words that are unused by this grammar will map to this token. 147 %token <bytes> UNUSED 148 149 %type <statement> command 150 %type <selStmt> select_statement base_select union_lhs union_rhs 151 %type <statement> insert_statement update_statement delete_statement set_statement 152 %type <statement> create_statement alter_statement rename_statement drop_statement 153 %type <statement> analyze_statement show_statement use_statement other_statement 154 %type <bytes2> comment_opt comment_list 155 %type <str> union_op insert_or_replace 156 %type <str> distinct_opt straight_join_opt cache_opt match_option separator_opt 157 %type <expr> like_escape_opt 158 %type <selectExprs> select_expression_list select_expression_list_opt 159 %type <selectExpr> select_expression 160 %type <expr> expression 161 %type <tableExprs> from_opt table_references 162 %type <tableExpr> table_reference table_factor join_table 163 %type <tableNames> table_name_list 164 %type <str> inner_join outer_join natural_join 165 %type <tableName> table_name into_table_name 166 %type <aliasedTableName> aliased_table_name 167 %type <indexHints> index_hint_list 168 %type <colIdents> index_list 169 %type <expr> where_expression_opt 170 %type <expr> condition 171 %type <boolVal> boolean_value 172 %type <str> compare 173 %type <ins> insert_data 174 %type <expr> value value_expression num_val 175 %type <expr> function_call_keyword function_call_nonkeyword function_call_generic function_call_conflict 176 %type <str> is_suffix 177 %type <colTuple> col_tuple 178 %type <exprs> expression_list 179 %type <values> tuple_list 180 %type <valTuple> row_tuple tuple_or_empty 181 %type <expr> tuple_expression 182 %type <subquery> subquery 183 %type <colName> column_name 184 %type <whens> when_expression_list 185 %type <when> when_expression 186 %type <expr> expression_opt else_expression_opt 187 %type <exprs> group_by_opt 188 %type <expr> having_opt 189 %type <orderBy> order_by_opt order_list 190 %type <order> order 191 %type <str> asc_desc_opt 192 %type <limit> limit_opt 193 %type <str> lock_opt 194 %type <columns> ins_column_list 195 %type <updateExprs> on_dup_opt 196 %type <updateExprs> update_list 197 %type <updateExpr> update_expression 198 %type <bytes> for_from 199 %type <str> ignore_opt 200 %type <byt> exists_opt 201 %type <empty> not_exists_opt non_rename_operation to_opt index_opt constraint_opt using_opt 202 %type <bytes> reserved_keyword non_reserved_keyword 203 %type <colIdent> sql_id reserved_sql_id col_alias as_ci_opt 204 %type <tableIdent> table_id reserved_table_id table_alias as_opt_id 205 %type <empty> as_opt 206 %type <empty> force_eof ddl_force_eof 207 %type <str> charset 208 %type <convertType> convert_type 209 %type <str> show_statement_type 210 %start any_command 211 212 %% 213 214 any_command: 215 command semicolon_opt 216 { 217 setParseTree(yylex, $1) 218 } 219 220 semicolon_opt: 221 /*empty*/ {} 222 | ';' {} 223 224 command: 225 select_statement 226 { 227 $$ = $1 228 } 229 | insert_statement 230 | update_statement 231 | delete_statement 232 | set_statement 233 | create_statement 234 | alter_statement 235 | rename_statement 236 | drop_statement 237 | analyze_statement 238 | show_statement 239 | use_statement 240 | other_statement 241 242 select_statement: 243 base_select order_by_opt limit_opt lock_opt 244 { 245 sel := $1.(*Select) 246 sel.OrderBy = $2 247 sel.Limit = $3 248 sel.Lock = $4 249 $$ = sel 250 } 251 | union_lhs union_op union_rhs order_by_opt limit_opt lock_opt 252 { 253 $$ = &Union{Type: $2, Left: $1, Right: $3, OrderBy: $4, Limit: $5, Lock: $6} 254 } 255 | SELECT comment_opt cache_opt NEXT num_val for_from table_name 256 { 257 $$ = &Select{Comments: Comments($2), Cache: $3, SelectExprs: SelectExprs{Nextval{Expr: $5}}, From: TableExprs{&AliasedTableExpr{Expr: $7}}} 258 } 259 260 // base_select is an unparenthesized SELECT with no order by clause or beyond. 261 base_select: 262 SELECT comment_opt cache_opt distinct_opt straight_join_opt select_expression_list from_opt where_expression_opt group_by_opt having_opt 263 { 264 $$ = &Select{Comments: Comments($2), Cache: $3, Distinct: $4, Hints: $5, SelectExprs: $6, From: $7, Where: NewWhere(WhereStr, $8), GroupBy: GroupBy($9), Having: NewWhere(HavingStr, $10)} 265 } 266 267 union_lhs: 268 select_statement 269 { 270 $$ = $1 271 } 272 | openb select_statement closeb 273 { 274 $$ = &ParenSelect{Select: $2} 275 } 276 277 union_rhs: 278 base_select 279 { 280 $$ = $1 281 } 282 | openb select_statement closeb 283 { 284 $$ = &ParenSelect{Select: $2} 285 } 286 287 288 insert_statement: 289 insert_or_replace comment_opt ignore_opt into_table_name insert_data on_dup_opt 290 { 291 // insert_data returns a *Insert pre-filled with Columns & Values 292 ins := $5 293 ins.Action = $1 294 ins.Comments = $2 295 ins.Ignore = $3 296 ins.Table = $4 297 ins.OnDup = OnDup($6) 298 $$ = ins 299 } 300 | insert_or_replace comment_opt ignore_opt into_table_name SET update_list on_dup_opt 301 { 302 cols := make(Columns, 0, len($6)) 303 vals := make(ValTuple, 0, len($7)) 304 for _, updateList := range $6 { 305 cols = append(cols, updateList.Name.Name) 306 vals = append(vals, updateList.Expr) 307 } 308 $$ = &Insert{Action: $1, Comments: Comments($2), Ignore: $3, Table: $4, Columns: cols, Rows: Values{vals}, OnDup: OnDup($7)} 309 } 310 311 insert_or_replace: 312 INSERT 313 { 314 $$ = InsertStr 315 } 316 | REPLACE 317 { 318 $$ = ReplaceStr 319 } 320 321 update_statement: 322 UPDATE comment_opt table_references SET update_list where_expression_opt order_by_opt limit_opt 323 { 324 $$ = &Update{Comments: Comments($2), TableExprs: $3, Exprs: $5, Where: NewWhere(WhereStr, $6), OrderBy: $7, Limit: $8} 325 } 326 327 delete_statement: 328 DELETE comment_opt FROM table_name where_expression_opt order_by_opt limit_opt 329 { 330 $$ = &Delete{Comments: Comments($2), TableExprs: TableExprs{&AliasedTableExpr{Expr:$4}}, Where: NewWhere(WhereStr, $5), OrderBy: $6, Limit: $7} 331 } 332 | DELETE comment_opt table_name_list from_or_using table_references where_expression_opt 333 { 334 $$ = &Delete{Comments: Comments($2), Targets: $3, TableExprs: $5, Where: NewWhere(WhereStr, $6)} 335 } 336 337 from_or_using: 338 FROM {} 339 | USING {} 340 341 table_name_list: 342 table_name 343 { 344 $$ = TableNames{$1} 345 } 346 | table_name_list ',' table_name 347 { 348 $$ = append($$, $3) 349 } 350 351 set_statement: 352 SET comment_opt update_list 353 { 354 $$ = &Set{Comments: Comments($2), Exprs: $3} 355 } 356 357 create_statement: 358 CREATE TABLE not_exists_opt table_name ddl_force_eof 359 { 360 $$ = &DDL{Action: CreateStr, NewName: $4} 361 } 362 | CREATE constraint_opt INDEX ID using_opt ON table_name ddl_force_eof 363 { 364 // Change this to an alter statement 365 $$ = &DDL{Action: AlterStr, Table: $7, NewName:$7} 366 } 367 | CREATE VIEW table_name ddl_force_eof 368 { 369 $$ = &DDL{Action: CreateStr, NewName: $3.ToViewName()} 370 } 371 | CREATE OR REPLACE VIEW table_name ddl_force_eof 372 { 373 $$ = &DDL{Action: CreateStr, NewName: $5.ToViewName()} 374 } 375 376 alter_statement: 377 ALTER ignore_opt TABLE table_name non_rename_operation force_eof 378 { 379 $$ = &DDL{Action: AlterStr, Table: $4, NewName: $4} 380 } 381 | ALTER ignore_opt TABLE table_name RENAME to_opt table_name 382 { 383 // Change this to a rename statement 384 $$ = &DDL{Action: RenameStr, Table: $4, NewName: $7} 385 } 386 | ALTER ignore_opt TABLE table_name RENAME index_opt force_eof 387 { 388 // Rename an index can just be an alter 389 $$ = &DDL{Action: AlterStr, Table: $4, NewName: $4} 390 } 391 | ALTER VIEW table_name ddl_force_eof 392 { 393 $$ = &DDL{Action: AlterStr, Table: $3.ToViewName(), NewName: $3.ToViewName()} 394 } 395 396 rename_statement: 397 RENAME TABLE table_name TO table_name 398 { 399 $$ = &DDL{Action: RenameStr, Table: $3, NewName: $5} 400 } 401 402 drop_statement: 403 DROP TABLE exists_opt table_name 404 { 405 var exists bool 406 if $3 != 0 { 407 exists = true 408 } 409 $$ = &DDL{Action: DropStr, Table: $4, IfExists: exists} 410 } 411 | DROP INDEX ID ON table_name 412 { 413 // Change this to an alter statement 414 $$ = &DDL{Action: AlterStr, Table: $5, NewName: $5} 415 } 416 | DROP VIEW exists_opt table_name ddl_force_eof 417 { 418 var exists bool 419 if $3 != 0 { 420 exists = true 421 } 422 $$ = &DDL{Action: DropStr, Table: $4.ToViewName(), IfExists: exists} 423 } 424 425 analyze_statement: 426 ANALYZE TABLE table_name 427 { 428 $$ = &DDL{Action: AlterStr, Table: $3, NewName: $3} 429 } 430 431 show_statement_type: 432 ID 433 { 434 $$ = ShowUnsupportedStr 435 } 436 | reserved_keyword 437 { 438 switch v := string($1); v { 439 case ShowDatabasesStr, ShowTablesStr, ShowKeyspacesStr, ShowShardsStr, ShowVSchemaTablesStr: 440 $$ = v 441 default: 442 $$ = ShowUnsupportedStr 443 } 444 } 445 | non_reserved_keyword 446 { 447 $$ = ShowUnsupportedStr 448 } 449 450 show_statement: 451 SHOW show_statement_type force_eof 452 { 453 $$ = &Show{Type: $2} 454 } 455 456 use_statement: 457 USE table_id 458 { 459 $$ = &Use{DBName: $2} 460 } 461 462 other_statement: 463 DESC force_eof 464 { 465 $$ = &OtherRead{} 466 } 467 | DESCRIBE force_eof 468 { 469 $$ = &OtherRead{} 470 } 471 | EXPLAIN force_eof 472 { 473 $$ = &OtherRead{} 474 } 475 | REPAIR force_eof 476 { 477 $$ = &OtherAdmin{} 478 } 479 | OPTIMIZE force_eof 480 { 481 $$ = &OtherAdmin{} 482 } 483 | TRUNCATE force_eof 484 { 485 $$ = &OtherAdmin{} 486 } 487 488 comment_opt: 489 { 490 setAllowComments(yylex, true) 491 } 492 comment_list 493 { 494 $$ = $2 495 setAllowComments(yylex, false) 496 } 497 498 comment_list: 499 { 500 $$ = nil 501 } 502 | comment_list COMMENT 503 { 504 $$ = append($1, $2) 505 } 506 507 union_op: 508 UNION 509 { 510 $$ = UnionStr 511 } 512 | UNION ALL 513 { 514 $$ = UnionAllStr 515 } 516 | UNION DISTINCT 517 { 518 $$ = UnionDistinctStr 519 } 520 521 cache_opt: 522 { 523 $$ = "" 524 } 525 | SQL_NO_CACHE 526 { 527 $$ = SQLNoCacheStr 528 } 529 | SQL_CACHE 530 { 531 $$ = SQLCacheStr 532 } 533 534 distinct_opt: 535 { 536 $$ = "" 537 } 538 | DISTINCT 539 { 540 $$ = DistinctStr 541 } 542 543 straight_join_opt: 544 { 545 $$ = "" 546 } 547 | STRAIGHT_JOIN 548 { 549 $$ = StraightJoinHint 550 } 551 552 select_expression_list_opt: 553 { 554 $$ = nil 555 } 556 | select_expression_list 557 { 558 $$ = $1 559 } 560 561 select_expression_list: 562 select_expression 563 { 564 $$ = SelectExprs{$1} 565 } 566 | select_expression_list ',' select_expression 567 { 568 $$ = append($$, $3) 569 } 570 571 select_expression: 572 '*' 573 { 574 $$ = &StarExpr{} 575 } 576 | expression as_ci_opt 577 { 578 $$ = &AliasedExpr{Expr: $1, As: $2} 579 } 580 | table_id '.' '*' 581 { 582 $$ = &StarExpr{TableName: TableName{Name: $1}} 583 } 584 | table_id '.' reserved_table_id '.' '*' 585 { 586 $$ = &StarExpr{TableName: TableName{Qualifier: $1, Name: $3}} 587 } 588 589 as_ci_opt: 590 { 591 $$ = ColIdent{} 592 } 593 | col_alias 594 { 595 $$ = $1 596 } 597 | AS col_alias 598 { 599 $$ = $2 600 } 601 602 col_alias: 603 sql_id 604 | STRING 605 { 606 $$ = NewColIdent(string($1)) 607 } 608 609 from_opt: 610 { 611 $$ = TableExprs{&AliasedTableExpr{Expr:TableName{Name: NewTableIdent("dual")}}} 612 } 613 | FROM table_references 614 { 615 $$ = $2 616 } 617 618 table_references: 619 table_reference 620 { 621 $$ = TableExprs{$1} 622 } 623 | table_references ',' table_reference 624 { 625 $$ = append($$, $3) 626 } 627 628 table_reference: 629 table_factor 630 | join_table 631 632 table_factor: 633 aliased_table_name 634 { 635 $$ = $1 636 } 637 | subquery as_opt table_id 638 { 639 $$ = &AliasedTableExpr{Expr:$1, As: $3} 640 } 641 | openb table_references closeb 642 { 643 $$ = &ParenTableExpr{Exprs: $2} 644 } 645 646 aliased_table_name: 647 table_name as_opt_id index_hint_list 648 { 649 $$ = &AliasedTableExpr{Expr:$1, As: $2, Hints: $3} 650 } 651 652 // There is a grammar conflict here: 653 // 1: INSERT INTO a SELECT * FROM b JOIN c ON b.i = c.i 654 // 2: INSERT INTO a SELECT * FROM b JOIN c ON DUPLICATE KEY UPDATE a.i = 1 655 // When yacc encounters the ON clause, it cannot determine which way to 656 // resolve. The %prec override below makes the parser choose the 657 // first construct, which automatically makes the second construct a 658 // syntax error. This is the same behavior as MySQL. 659 join_table: 660 table_reference inner_join table_factor %prec JOIN 661 { 662 $$ = &JoinTableExpr{LeftExpr: $1, Join: $2, RightExpr: $3} 663 } 664 | table_reference inner_join table_factor ON expression 665 { 666 $$ = &JoinTableExpr{LeftExpr: $1, Join: $2, RightExpr: $3, On: $5} 667 } 668 | table_reference outer_join table_reference ON expression 669 { 670 $$ = &JoinTableExpr{LeftExpr: $1, Join: $2, RightExpr: $3, On: $5} 671 } 672 | table_reference natural_join table_factor 673 { 674 $$ = &JoinTableExpr{LeftExpr: $1, Join: $2, RightExpr: $3} 675 } 676 677 as_opt: 678 { $$ = struct{}{} } 679 | AS 680 { $$ = struct{}{} } 681 682 as_opt_id: 683 { 684 $$ = NewTableIdent("") 685 } 686 | table_alias 687 { 688 $$ = $1 689 } 690 | AS table_alias 691 { 692 $$ = $2 693 } 694 695 table_alias: 696 table_id 697 | STRING 698 { 699 $$ = NewTableIdent(string($1)) 700 } 701 702 inner_join: 703 JOIN 704 { 705 $$ = JoinStr 706 } 707 | INNER JOIN 708 { 709 $$ = JoinStr 710 } 711 | CROSS JOIN 712 { 713 $$ = JoinStr 714 } 715 | STRAIGHT_JOIN 716 { 717 $$ = StraightJoinStr 718 } 719 720 outer_join: 721 LEFT JOIN 722 { 723 $$ = LeftJoinStr 724 } 725 | LEFT OUTER JOIN 726 { 727 $$ = LeftJoinStr 728 } 729 | RIGHT JOIN 730 { 731 $$ = RightJoinStr 732 } 733 | RIGHT OUTER JOIN 734 { 735 $$ = RightJoinStr 736 } 737 738 natural_join: 739 NATURAL JOIN 740 { 741 $$ = NaturalJoinStr 742 } 743 | NATURAL outer_join 744 { 745 if $2 == LeftJoinStr { 746 $$ = NaturalLeftJoinStr 747 } else { 748 $$ = NaturalRightJoinStr 749 } 750 } 751 752 into_table_name: 753 INTO table_name 754 { 755 $$ = $2 756 } 757 | table_name 758 { 759 $$ = $1 760 } 761 762 table_name: 763 table_id 764 { 765 $$ = TableName{Name: $1} 766 } 767 | table_id '.' reserved_table_id 768 { 769 $$ = TableName{Qualifier: $1, Name: $3} 770 } 771 772 index_hint_list: 773 { 774 $$ = nil 775 } 776 | USE INDEX openb index_list closeb 777 { 778 $$ = &IndexHints{Type: UseStr, Indexes: $4} 779 } 780 | IGNORE INDEX openb index_list closeb 781 { 782 $$ = &IndexHints{Type: IgnoreStr, Indexes: $4} 783 } 784 | FORCE INDEX openb index_list closeb 785 { 786 $$ = &IndexHints{Type: ForceStr, Indexes: $4} 787 } 788 789 index_list: 790 sql_id 791 { 792 $$ = []ColIdent{$1} 793 } 794 | index_list ',' sql_id 795 { 796 $$ = append($1, $3) 797 } 798 799 where_expression_opt: 800 { 801 $$ = nil 802 } 803 | WHERE expression 804 { 805 $$ = $2 806 } 807 808 expression: 809 condition 810 { 811 $$ = $1 812 } 813 | expression AND expression 814 { 815 $$ = &AndExpr{Left: $1, Right: $3} 816 } 817 | expression OR expression 818 { 819 $$ = &OrExpr{Left: $1, Right: $3} 820 } 821 | NOT expression 822 { 823 $$ = &NotExpr{Expr: $2} 824 } 825 | expression IS is_suffix 826 { 827 $$ = &IsExpr{Operator: $3, Expr: $1} 828 } 829 | value_expression 830 { 831 $$ = $1 832 } 833 | DEFAULT 834 { 835 $$ = &Default{} 836 } 837 838 boolean_value: 839 TRUE 840 { 841 $$ = BoolVal(true) 842 } 843 | FALSE 844 { 845 $$ = BoolVal(false) 846 } 847 848 condition: 849 value_expression compare value_expression 850 { 851 $$ = &ComparisonExpr{Left: $1, Operator: $2, Right: $3} 852 } 853 | value_expression IN col_tuple 854 { 855 $$ = &ComparisonExpr{Left: $1, Operator: InStr, Right: $3} 856 } 857 | value_expression NOT IN col_tuple 858 { 859 $$ = &ComparisonExpr{Left: $1, Operator: NotInStr, Right: $4} 860 } 861 | value_expression LIKE value_expression like_escape_opt 862 { 863 $$ = &ComparisonExpr{Left: $1, Operator: LikeStr, Right: $3, Escape: $4} 864 } 865 | value_expression NOT LIKE value_expression like_escape_opt 866 { 867 $$ = &ComparisonExpr{Left: $1, Operator: NotLikeStr, Right: $4, Escape: $5} 868 } 869 | value_expression REGEXP value_expression 870 { 871 $$ = &ComparisonExpr{Left: $1, Operator: RegexpStr, Right: $3} 872 } 873 | value_expression NOT REGEXP value_expression 874 { 875 $$ = &ComparisonExpr{Left: $1, Operator: NotRegexpStr, Right: $4} 876 } 877 | value_expression BETWEEN value_expression AND value_expression 878 { 879 $$ = &RangeCond{Left: $1, Operator: BetweenStr, From: $3, To: $5} 880 } 881 | value_expression NOT BETWEEN value_expression AND value_expression 882 { 883 $$ = &RangeCond{Left: $1, Operator: NotBetweenStr, From: $4, To: $6} 884 } 885 | EXISTS subquery 886 { 887 $$ = &ExistsExpr{Subquery: $2} 888 } 889 890 is_suffix: 891 NULL 892 { 893 $$ = IsNullStr 894 } 895 | NOT NULL 896 { 897 $$ = IsNotNullStr 898 } 899 | TRUE 900 { 901 $$ = IsTrueStr 902 } 903 | NOT TRUE 904 { 905 $$ = IsNotTrueStr 906 } 907 | FALSE 908 { 909 $$ = IsFalseStr 910 } 911 | NOT FALSE 912 { 913 $$ = IsNotFalseStr 914 } 915 916 compare: 917 '=' 918 { 919 $$ = EqualStr 920 } 921 | '<' 922 { 923 $$ = LessThanStr 924 } 925 | '>' 926 { 927 $$ = GreaterThanStr 928 } 929 | LE 930 { 931 $$ = LessEqualStr 932 } 933 | GE 934 { 935 $$ = GreaterEqualStr 936 } 937 | NE 938 { 939 $$ = NotEqualStr 940 } 941 | NULL_SAFE_EQUAL 942 { 943 $$ = NullSafeEqualStr 944 } 945 946 like_escape_opt: 947 { 948 $$ = nil 949 } 950 | ESCAPE value_expression 951 { 952 $$ = $2 953 } 954 955 col_tuple: 956 row_tuple 957 { 958 $$ = $1 959 } 960 | subquery 961 { 962 $$ = $1 963 } 964 | LIST_ARG 965 { 966 $$ = ListArg($1) 967 } 968 969 subquery: 970 openb select_statement closeb 971 { 972 $$ = &Subquery{$2} 973 } 974 975 expression_list: 976 expression 977 { 978 $$ = Exprs{$1} 979 } 980 | expression_list ',' expression 981 { 982 $$ = append($1, $3) 983 } 984 985 charset: 986 ID 987 { 988 $$ = string($1) 989 } 990 | STRING 991 { 992 $$ = string($1) 993 } 994 | BINARY 995 { 996 $$ = string($1) 997 } 998 | DATE 999 { 1000 $$ = string($1) 1001 } 1002 1003 value_expression: 1004 value 1005 { 1006 $$ = $1 1007 } 1008 | boolean_value 1009 { 1010 $$ = $1 1011 } 1012 | column_name 1013 { 1014 $$ = $1 1015 } 1016 | tuple_expression 1017 { 1018 $$ = $1 1019 } 1020 | subquery 1021 { 1022 $$ = $1 1023 } 1024 | value_expression '&' value_expression 1025 { 1026 $$ = &BinaryExpr{Left: $1, Operator: BitAndStr, Right: $3} 1027 } 1028 | value_expression '|' value_expression 1029 { 1030 $$ = &BinaryExpr{Left: $1, Operator: BitOrStr, Right: $3} 1031 } 1032 | value_expression '^' value_expression 1033 { 1034 $$ = &BinaryExpr{Left: $1, Operator: BitXorStr, Right: $3} 1035 } 1036 | value_expression '+' value_expression 1037 { 1038 $$ = &BinaryExpr{Left: $1, Operator: PlusStr, Right: $3} 1039 } 1040 | value_expression '-' value_expression 1041 { 1042 $$ = &BinaryExpr{Left: $1, Operator: MinusStr, Right: $3} 1043 } 1044 | value_expression '*' value_expression 1045 { 1046 $$ = &BinaryExpr{Left: $1, Operator: MultStr, Right: $3} 1047 } 1048 | value_expression '/' value_expression 1049 { 1050 $$ = &BinaryExpr{Left: $1, Operator: DivStr, Right: $3} 1051 } 1052 | value_expression DIV value_expression 1053 { 1054 $$ = &BinaryExpr{Left: $1, Operator: IntDivStr, Right: $3} 1055 } 1056 | value_expression '%' value_expression 1057 { 1058 $$ = &BinaryExpr{Left: $1, Operator: ModStr, Right: $3} 1059 } 1060 | value_expression MOD value_expression 1061 { 1062 $$ = &BinaryExpr{Left: $1, Operator: ModStr, Right: $3} 1063 } 1064 | value_expression SHIFT_LEFT value_expression 1065 { 1066 $$ = &BinaryExpr{Left: $1, Operator: ShiftLeftStr, Right: $3} 1067 } 1068 | value_expression SHIFT_RIGHT value_expression 1069 { 1070 $$ = &BinaryExpr{Left: $1, Operator: ShiftRightStr, Right: $3} 1071 } 1072 | column_name JSON_EXTRACT_OP value 1073 { 1074 $$ = &BinaryExpr{Left: $1, Operator: JSONExtractOp, Right: $3} 1075 } 1076 | column_name JSON_UNQUOTE_EXTRACT_OP value 1077 { 1078 $$ = &BinaryExpr{Left: $1, Operator: JSONUnquoteExtractOp, Right: $3} 1079 } 1080 | value_expression COLLATE charset 1081 { 1082 $$ = &CollateExpr{Expr: $1, Charset: $3} 1083 } 1084 | BINARY value_expression %prec UNARY 1085 { 1086 $$ = &UnaryExpr{Operator: BinaryStr, Expr: $2} 1087 } 1088 | '+' value_expression %prec UNARY 1089 { 1090 if num, ok := $2.(*SQLVal); ok && num.Type == IntVal { 1091 $$ = num 1092 } else { 1093 $$ = &UnaryExpr{Operator: UPlusStr, Expr: $2} 1094 } 1095 } 1096 | '-' value_expression %prec UNARY 1097 { 1098 if num, ok := $2.(*SQLVal); ok && num.Type == IntVal { 1099 // Handle double negative 1100 if num.Val[0] == '-' { 1101 num.Val = num.Val[1:] 1102 $$ = num 1103 } else { 1104 $$ = NewIntVal(append([]byte("-"), num.Val...)) 1105 } 1106 } else { 1107 $$ = &UnaryExpr{Operator: UMinusStr, Expr: $2} 1108 } 1109 } 1110 | '~' value_expression 1111 { 1112 $$ = &UnaryExpr{Operator: TildaStr, Expr: $2} 1113 } 1114 | '!' value_expression %prec UNARY 1115 { 1116 $$ = &UnaryExpr{Operator: BangStr, Expr: $2} 1117 } 1118 | INTERVAL value_expression sql_id 1119 { 1120 // This rule prevents the usage of INTERVAL 1121 // as a function. If support is needed for that, 1122 // we'll need to revisit this. The solution 1123 // will be non-trivial because of grammar conflicts. 1124 $$ = &IntervalExpr{Expr: $2, Unit: $3} 1125 } 1126 | function_call_generic 1127 | function_call_keyword 1128 | function_call_nonkeyword 1129 | function_call_conflict 1130 1131 /* 1132 Regular function calls without special token or syntax, guaranteed to not 1133 introduce side effects due to being a simple identifier 1134 */ 1135 function_call_generic: 1136 sql_id openb select_expression_list_opt closeb 1137 { 1138 $$ = &FuncExpr{Name: $1, Exprs: $3} 1139 } 1140 | sql_id openb DISTINCT select_expression_list closeb 1141 { 1142 $$ = &FuncExpr{Name: $1, Distinct: true, Exprs: $4} 1143 } 1144 | table_id '.' reserved_sql_id openb select_expression_list_opt closeb 1145 { 1146 $$ = &FuncExpr{Qualifier: $1, Name: $3, Exprs: $5} 1147 } 1148 1149 /* 1150 Function calls using reserved keywords, with dedicated grammar rules 1151 as a result 1152 */ 1153 function_call_keyword: 1154 LEFT openb select_expression_list closeb 1155 { 1156 $$ = &FuncExpr{Name: NewColIdent("left"), Exprs: $3} 1157 } 1158 | RIGHT openb select_expression_list closeb 1159 { 1160 $$ = &FuncExpr{Name: NewColIdent("right"), Exprs: $3} 1161 } 1162 | CONVERT openb expression ',' convert_type closeb 1163 { 1164 $$ = &ConvertExpr{Expr: $3, Type: $5} 1165 } 1166 | CAST openb expression AS convert_type closeb 1167 { 1168 $$ = &ConvertExpr{Expr: $3, Type: $5} 1169 } 1170 | CONVERT openb expression USING charset closeb 1171 { 1172 $$ = &ConvertUsingExpr{Expr: $3, Type: $5} 1173 } 1174 | MATCH openb select_expression_list closeb AGAINST openb value_expression match_option closeb 1175 { 1176 $$ = &MatchExpr{Columns: $3, Expr: $7, Option: $8} 1177 } 1178 | GROUP_CONCAT openb distinct_opt select_expression_list order_by_opt separator_opt closeb 1179 { 1180 $$ = &GroupConcatExpr{Distinct: $3, Exprs: $4, OrderBy: $5, Separator: $6} 1181 } 1182 | CASE expression_opt when_expression_list else_expression_opt END 1183 { 1184 $$ = &CaseExpr{Expr: $2, Whens: $3, Else: $4} 1185 } 1186 | VALUES openb sql_id closeb 1187 { 1188 $$ = &ValuesFuncExpr{Name: $3} 1189 } 1190 1191 /* 1192 Function calls using non reserved keywords but with special syntax forms. 1193 Dedicated grammar rules are needed because of the special syntax 1194 */ 1195 function_call_nonkeyword: 1196 CURRENT_TIMESTAMP func_datetime_precision_opt 1197 { 1198 $$ = &FuncExpr{Name:NewColIdent("current_timestamp")} 1199 } 1200 | UTC_TIMESTAMP func_datetime_precision_opt 1201 { 1202 $$ = &FuncExpr{Name:NewColIdent("utc_timestamp")} 1203 } 1204 | UTC_TIME func_datetime_precision_opt 1205 { 1206 $$ = &FuncExpr{Name:NewColIdent("utc_time")} 1207 } 1208 | UTC_DATE func_datetime_precision_opt 1209 { 1210 $$ = &FuncExpr{Name:NewColIdent("utc_date")} 1211 } 1212 // now 1213 | LOCALTIME func_datetime_precision_opt 1214 { 1215 $$ = &FuncExpr{Name:NewColIdent("localtime")} 1216 } 1217 // now 1218 | LOCALTIMESTAMP func_datetime_precision_opt 1219 { 1220 $$ = &FuncExpr{Name:NewColIdent("localtimestamp")} 1221 } 1222 // curdate 1223 | CURRENT_DATE func_datetime_precision_opt 1224 { 1225 $$ = &FuncExpr{Name:NewColIdent("current_date")} 1226 } 1227 // curtime 1228 | CURRENT_TIME func_datetime_precision_opt 1229 { 1230 $$ = &FuncExpr{Name:NewColIdent("current_time")} 1231 } 1232 1233 func_datetime_precision_opt: 1234 /* empty */ 1235 | openb closeb 1236 1237 /* 1238 Function calls using non reserved keywords with *normal* syntax forms. Because 1239 the names are non-reserved, they need a dedicated rule so as not to conflict 1240 */ 1241 function_call_conflict: 1242 IF openb select_expression_list closeb 1243 { 1244 $$ = &FuncExpr{Name: NewColIdent("if"), Exprs: $3} 1245 } 1246 | DATABASE openb select_expression_list_opt closeb 1247 { 1248 $$ = &FuncExpr{Name: NewColIdent("database"), Exprs: $3} 1249 } 1250 | MOD openb select_expression_list closeb 1251 { 1252 $$ = &FuncExpr{Name: NewColIdent("mod"), Exprs: $3} 1253 } 1254 | REPLACE openb select_expression_list closeb 1255 { 1256 $$ = &FuncExpr{Name: NewColIdent("replace"), Exprs: $3} 1257 } 1258 1259 match_option: 1260 /*empty*/ 1261 { 1262 $$ = "" 1263 } 1264 | IN BOOLEAN MODE 1265 { 1266 $$ = BooleanModeStr 1267 } 1268 | IN NATURAL LANGUAGE MODE 1269 { 1270 $$ = NaturalLanguageModeStr 1271 } 1272 | IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION 1273 { 1274 $$ = NaturalLanguageModeWithQueryExpansionStr 1275 } 1276 | WITH QUERY EXPANSION 1277 { 1278 $$ = QueryExpansionStr 1279 } 1280 1281 1282 convert_type: 1283 charset 1284 { 1285 $$ = &ConvertType{Type: $1} 1286 } 1287 | charset INTEGER 1288 { 1289 $$ = &ConvertType{Type: $1} 1290 } 1291 | charset openb INTEGRAL closeb 1292 { 1293 $$ = &ConvertType{Type: $1, Length: NewIntVal($3)} 1294 } 1295 | charset openb INTEGRAL closeb charset 1296 { 1297 $$ = &ConvertType{Type: $1, Length: NewIntVal($3), Charset: $5} 1298 } 1299 | charset openb INTEGRAL closeb CHARACTER SET charset 1300 { 1301 $$ = &ConvertType{Type: $1, Length: NewIntVal($3), Charset: $7, Operator: CharacterSetStr} 1302 } 1303 | charset charset 1304 { 1305 $$ = &ConvertType{Type: $1, Charset: $2} 1306 } 1307 | charset CHARACTER SET charset 1308 { 1309 $$ = &ConvertType{Type: $1, Charset: $4, Operator: CharacterSetStr} 1310 } 1311 | charset openb INTEGRAL ',' INTEGRAL closeb 1312 { 1313 $$ = &ConvertType{Type: $1, Length: NewIntVal($3), Scale: NewIntVal($5)} 1314 } 1315 1316 expression_opt: 1317 { 1318 $$ = nil 1319 } 1320 | expression 1321 { 1322 $$ = $1 1323 } 1324 1325 separator_opt: 1326 { 1327 $$ = string("") 1328 } 1329 | SEPARATOR STRING 1330 { 1331 $$ = " separator '"+string($2)+"'" 1332 } 1333 1334 when_expression_list: 1335 when_expression 1336 { 1337 $$ = []*When{$1} 1338 } 1339 | when_expression_list when_expression 1340 { 1341 $$ = append($1, $2) 1342 } 1343 1344 when_expression: 1345 WHEN expression THEN expression 1346 { 1347 $$ = &When{Cond: $2, Val: $4} 1348 } 1349 1350 else_expression_opt: 1351 { 1352 $$ = nil 1353 } 1354 | ELSE expression 1355 { 1356 $$ = $2 1357 } 1358 1359 column_name: 1360 sql_id 1361 { 1362 $$ = &ColName{Name: $1} 1363 } 1364 | table_id '.' reserved_sql_id 1365 { 1366 $$ = &ColName{Qualifier: TableName{Name: $1}, Name: $3} 1367 } 1368 | table_id '.' reserved_table_id '.' reserved_sql_id 1369 { 1370 $$ = &ColName{Qualifier: TableName{Qualifier: $1, Name: $3}, Name: $5} 1371 } 1372 1373 value: 1374 STRING 1375 { 1376 $$ = NewStrVal($1) 1377 } 1378 | HEX 1379 { 1380 $$ = NewHexVal($1) 1381 } 1382 | INTEGRAL 1383 { 1384 $$ = NewIntVal($1) 1385 } 1386 | FLOAT 1387 { 1388 $$ = NewFloatVal($1) 1389 } 1390 | HEXNUM 1391 { 1392 $$ = NewHexNum($1) 1393 } 1394 | VALUE_ARG 1395 { 1396 v := NewValArg($1) 1397 v.Seq = yylex.(*Tokenizer).posVarIndex 1398 $$ = v 1399 } 1400 | NULL 1401 { 1402 $$ = &NullVal{} 1403 } 1404 1405 num_val: 1406 sql_id 1407 { 1408 // TODO(sougou): Deprecate this construct. 1409 if $1.Lowered() != "value" { 1410 yylex.Error("expecting value after next") 1411 return 1 1412 } 1413 $$ = NewIntVal([]byte("1")) 1414 } 1415 | INTEGRAL VALUES 1416 { 1417 $$ = NewIntVal($1) 1418 } 1419 | VALUE_ARG VALUES 1420 { 1421 v := NewValArg($1) 1422 v.Seq = yylex.(*Tokenizer).posVarIndex 1423 $$ = v 1424 } 1425 1426 group_by_opt: 1427 { 1428 $$ = nil 1429 } 1430 | GROUP BY expression_list 1431 { 1432 $$ = $3 1433 } 1434 1435 having_opt: 1436 { 1437 $$ = nil 1438 } 1439 | HAVING expression 1440 { 1441 $$ = $2 1442 } 1443 1444 order_by_opt: 1445 { 1446 $$ = nil 1447 } 1448 | ORDER BY order_list 1449 { 1450 $$ = $3 1451 } 1452 1453 order_list: 1454 order 1455 { 1456 $$ = OrderBy{$1} 1457 } 1458 | order_list ',' order 1459 { 1460 $$ = append($1, $3) 1461 } 1462 1463 order: 1464 expression asc_desc_opt 1465 { 1466 $$ = &Order{Expr: $1, Direction: $2} 1467 } 1468 1469 asc_desc_opt: 1470 { 1471 $$ = AscScr 1472 } 1473 | ASC 1474 { 1475 $$ = AscScr 1476 } 1477 | DESC 1478 { 1479 $$ = DescScr 1480 } 1481 1482 limit_opt: 1483 { 1484 $$ = nil 1485 } 1486 | LIMIT expression 1487 { 1488 $$ = &Limit{Rowcount: $2} 1489 } 1490 | LIMIT expression ',' expression 1491 { 1492 $$ = &Limit{Offset: $2, Rowcount: $4} 1493 } 1494 | LIMIT expression OFFSET expression 1495 { 1496 $$ = &Limit{Offset: $4, Rowcount: $2} 1497 } 1498 1499 lock_opt: 1500 { 1501 $$ = "" 1502 } 1503 | FOR UPDATE 1504 { 1505 $$ = ForUpdateStr 1506 } 1507 | LOCK IN SHARE MODE 1508 { 1509 $$ = ShareModeStr 1510 } 1511 1512 // insert_data expands all combinations into a single rule. 1513 // This avoids a shift/reduce conflict while encountering the 1514 // following two possible constructs: 1515 // insert into t1(a, b) (select * from t2) 1516 // insert into t1(select * from t2) 1517 // Because the rules are together, the parser can keep shifting 1518 // the tokens until it disambiguates a as sql_id and select as keyword. 1519 insert_data: 1520 VALUES tuple_list 1521 { 1522 $$ = &Insert{Rows: $2} 1523 } 1524 | select_statement 1525 { 1526 $$ = &Insert{Rows: $1} 1527 } 1528 | openb select_statement closeb 1529 { 1530 // Drop the redundant parenthesis. 1531 $$ = &Insert{Rows: $2} 1532 } 1533 | openb ins_column_list closeb VALUES tuple_list 1534 { 1535 $$ = &Insert{Columns: $2, Rows: $5} 1536 } 1537 | openb ins_column_list closeb select_statement 1538 { 1539 $$ = &Insert{Columns: $2, Rows: $4} 1540 } 1541 | openb ins_column_list closeb openb select_statement closeb 1542 { 1543 // Drop the redundant parenthesis. 1544 $$ = &Insert{Columns: $2, Rows: $5} 1545 } 1546 1547 ins_column_list: 1548 sql_id 1549 { 1550 $$ = Columns{$1} 1551 } 1552 | sql_id '.' sql_id 1553 { 1554 $$ = Columns{$3} 1555 } 1556 | ins_column_list ',' sql_id 1557 { 1558 $$ = append($$, $3) 1559 } 1560 | ins_column_list ',' sql_id '.' sql_id 1561 { 1562 $$ = append($$, $5) 1563 } 1564 1565 on_dup_opt: 1566 { 1567 $$ = nil 1568 } 1569 | ON DUPLICATE KEY UPDATE update_list 1570 { 1571 $$ = $5 1572 } 1573 1574 tuple_list: 1575 tuple_or_empty 1576 { 1577 $$ = Values{$1} 1578 } 1579 | tuple_list ',' tuple_or_empty 1580 { 1581 $$ = append($1, $3) 1582 } 1583 1584 tuple_or_empty: 1585 row_tuple 1586 { 1587 $$ = $1 1588 } 1589 | openb closeb 1590 { 1591 $$ = ValTuple{} 1592 } 1593 1594 row_tuple: 1595 openb expression_list closeb 1596 { 1597 $$ = ValTuple($2) 1598 } 1599 1600 tuple_expression: 1601 row_tuple 1602 { 1603 if len($1) == 1 { 1604 $$ = &ParenExpr{$1[0]} 1605 } else { 1606 $$ = $1 1607 } 1608 } 1609 1610 update_list: 1611 update_expression 1612 { 1613 $$ = UpdateExprs{$1} 1614 } 1615 | update_list ',' update_expression 1616 { 1617 $$ = append($1, $3) 1618 } 1619 1620 update_expression: 1621 column_name '=' expression 1622 { 1623 $$ = &UpdateExpr{Name: $1, Expr: $3} 1624 } 1625 1626 for_from: 1627 FOR 1628 | FROM 1629 1630 exists_opt: 1631 { $$ = 0 } 1632 | IF EXISTS 1633 { $$ = 1 } 1634 1635 not_exists_opt: 1636 { $$ = struct{}{} } 1637 | IF NOT EXISTS 1638 { $$ = struct{}{} } 1639 1640 ignore_opt: 1641 { $$ = "" } 1642 | IGNORE 1643 { $$ = IgnoreStr } 1644 1645 non_rename_operation: 1646 ALTER 1647 { $$ = struct{}{} } 1648 | DEFAULT 1649 { $$ = struct{}{} } 1650 | DROP 1651 { $$ = struct{}{} } 1652 | ORDER 1653 { $$ = struct{}{} } 1654 | CONVERT 1655 { $$ = struct{}{} } 1656 | UNUSED 1657 { $$ = struct{}{} } 1658 | ID 1659 { $$ = struct{}{} } 1660 1661 to_opt: 1662 { $$ = struct{}{} } 1663 | TO 1664 { $$ = struct{}{} } 1665 | AS 1666 { $$ = struct{}{} } 1667 1668 index_opt: 1669 INDEX 1670 { $$ = struct{}{} } 1671 | KEY 1672 { $$ = struct{}{} } 1673 1674 constraint_opt: 1675 { $$ = struct{}{} } 1676 | UNIQUE 1677 { $$ = struct{}{} } 1678 | sql_id 1679 { $$ = struct{}{} } 1680 1681 using_opt: 1682 { $$ = struct{}{} } 1683 | USING sql_id 1684 { $$ = struct{}{} } 1685 1686 sql_id: 1687 ID 1688 { 1689 $$ = NewColIdent(string($1)) 1690 } 1691 | non_reserved_keyword 1692 { 1693 $$ = NewColIdent(string($1)) 1694 } 1695 1696 reserved_sql_id: 1697 sql_id 1698 | reserved_keyword 1699 { 1700 $$ = NewColIdent(string($1)) 1701 } 1702 1703 table_id: 1704 ID 1705 { 1706 $$ = NewTableIdent(string($1)) 1707 } 1708 | non_reserved_keyword 1709 { 1710 $$ = NewTableIdent(string($1)) 1711 } 1712 1713 reserved_table_id: 1714 table_id 1715 | reserved_keyword 1716 { 1717 $$ = NewTableIdent(string($1)) 1718 } 1719 1720 /* 1721 These are not all necessarily reserved in MySQL, but some are. 1722 These are more importantly reserved because they may conflict with our grammar. 1723 If you want to move one that is not reserved in MySQL (i.e. ESCAPE) to the 1724 non_reserved_keywords, you'll need to deal with any conflicts. 1725 1726 Sorted alphabetically 1727 */ 1728 reserved_keyword: 1729 AND 1730 | AS 1731 | ASC 1732 | BETWEEN 1733 | BINARY 1734 | BY 1735 | CASE 1736 | COLLATE 1737 | CONVERT 1738 | CREATE 1739 | CROSS 1740 | CURRENT_DATE 1741 | CURRENT_TIME 1742 | CURRENT_TIMESTAMP 1743 | DATABASE 1744 | DATABASES 1745 | DEFAULT 1746 | DELETE 1747 | DESC 1748 | DESCRIBE 1749 | DISTINCT 1750 | DIV 1751 | DROP 1752 | ELSE 1753 | END 1754 | ESCAPE 1755 | EXISTS 1756 | EXPLAIN 1757 | FALSE 1758 | FOR 1759 | FORCE 1760 | FROM 1761 | GROUP 1762 | HAVING 1763 | IF 1764 | IGNORE 1765 | IN 1766 | INDEX 1767 | INNER 1768 | INSERT 1769 | INTERVAL 1770 | INTO 1771 | IS 1772 | JOIN 1773 | KEY 1774 | LEFT 1775 | LIKE 1776 | LIMIT 1777 | LOCALTIME 1778 | LOCALTIMESTAMP 1779 | LOCK 1780 | MATCH 1781 | MOD 1782 | NATURAL 1783 | NEXT // next should be doable as non-reserved, but is not due to the special `select next num_val` query that vitess supports 1784 | NOT 1785 | NULL 1786 | ON 1787 | OR 1788 | ORDER 1789 | OUTER 1790 | REGEXP 1791 | RENAME 1792 | REPLACE 1793 | RIGHT 1794 | SELECT 1795 | SEPARATOR 1796 | SET 1797 | VITESS_KEYSPACES 1798 | VITESS_SHARDS 1799 | VSCHEMA_TABLES 1800 | SHOW 1801 | STRAIGHT_JOIN 1802 | TABLE 1803 | TABLES 1804 | THEN 1805 | TO 1806 | TRUE 1807 | UNION 1808 | UNIQUE 1809 | UPDATE 1810 | USE 1811 | USING 1812 | UTC_DATE 1813 | UTC_TIME 1814 | UTC_TIMESTAMP 1815 | VALUES 1816 | WHEN 1817 | WHERE 1818 1819 /* 1820 These are non-reserved Vitess, because they don't cause conflicts in the grammar. 1821 Some of them may be reserved in MySQL. The good news is we backtick quote them 1822 when we rewrite the query, so no issue should arise. 1823 1824 Sorted alphabetically 1825 */ 1826 non_reserved_keyword: 1827 AGAINST 1828 | DATE 1829 | DUPLICATE 1830 | EXPANSION 1831 | INTEGER 1832 | LANGUAGE 1833 | MODE 1834 | OFFSET 1835 | OPTIMIZE 1836 | QUERY 1837 | REPAIR 1838 | SHARE 1839 | TRUNCATE 1840 | UNUSED 1841 | VIEW 1842 | WITH 1843 | LAST_INSERT_ID 1844 1845 openb: 1846 '(' 1847 { 1848 if incNesting(yylex) { 1849 yylex.Error("max nesting level reached") 1850 return 1 1851 } 1852 } 1853 1854 closeb: 1855 ')' 1856 { 1857 decNesting(yylex) 1858 } 1859 1860 force_eof: 1861 { 1862 forceEOF(yylex) 1863 } 1864 1865 ddl_force_eof: 1866 { 1867 forceEOF(yylex) 1868 } 1869 | openb 1870 { 1871 forceEOF(yylex) 1872 } 1873 | reserved_sql_id 1874 { 1875 forceEOF(yylex) 1876 }