github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/pingcap/tidb/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 2015 PingCAP, Inc. 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 // See the License for the specific language governing permissions and 17 // limitations under the License. 18 19 // Initial yacc source generated by ebnf2y[1] 20 // at 2013-10-04 23:10:47.861401015 +0200 CEST 21 // 22 // $ ebnf2y -o ql.y -oe ql.ebnf -start StatementList -pkg ql -p _ 23 // 24 // [1]: http://github.com/cznic/ebnf2y 25 26 package parser 27 28 import ( 29 "strings" 30 31 "github.com/pingcap/tidb/mysql" 32 "github.com/pingcap/tidb/ast" 33 "github.com/pingcap/tidb/model" 34 "github.com/pingcap/tidb/parser/opcode" 35 "github.com/pingcap/tidb/util/charset" 36 "github.com/pingcap/tidb/util/types" 37 ) 38 39 %} 40 41 %union { 42 offset int // offset 43 line int 44 col int 45 item interface{} 46 list []interface{} 47 } 48 49 %token <item> 50 51 /*yy:token "1.%d" */ floatLit "floating-point literal" 52 /*yy:token "%c" */ identifier "identifier" 53 /*yy:token "%d" */ intLit "integer literal" 54 /*yy:token "\"%c\"" */ stringLit "string literal" 55 /*yy:token "%x" */ hexLit "hexadecimal literal" 56 /*yy:token "%b" */ bitLit "bit literal" 57 58 59 abs "ABS" 60 add "ADD" 61 addDate "ADDDATE" 62 admin "ADMIN" 63 after "AFTER" 64 all "ALL" 65 alter "ALTER" 66 and "AND" 67 andand "&&" 68 andnot "&^" 69 any "ANY" 70 as "AS" 71 asc "ASC" 72 ascii "ASCII" 73 assignmentEq ":=" 74 at "AT" 75 autoIncrement "AUTO_INCREMENT" 76 avg "AVG" 77 avgRowLength "AVG_ROW_LENGTH" 78 begin "BEGIN" 79 between "BETWEEN" 80 both "BOTH" 81 btree "BTREE" 82 by "BY" 83 byteType "BYTE" 84 caseKwd "CASE" 85 cast "CAST" 86 character "CHARACTER" 87 charsetKwd "CHARSET" 88 check "CHECK" 89 checksum "CHECKSUM" 90 coalesce "COALESCE" 91 collate "COLLATE" 92 collation "COLLATION" 93 column "COLUMN" 94 columns "COLUMNS" 95 comment "COMMENT" 96 commit "COMMIT" 97 committed "COMMITTED" 98 compact "COMPACT" 99 compressed "COMPRESSED" 100 compression "COMPRESSION" 101 concat "CONCAT" 102 concatWs "CONCAT_WS" 103 connection "CONNECTION" 104 connectionID "CONNECTION_ID" 105 constraint "CONSTRAINT" 106 convert "CONVERT" 107 count "COUNT" 108 create "CREATE" 109 cross "CROSS" 110 curDate "CURDATE" 111 utcDate "UTC_DATE" 112 currentDate "CURRENT_DATE" 113 curTime "CUR_TIME" 114 currentTime "CURRENT_TIME" 115 currentUser "CURRENT_USER" 116 database "DATABASE" 117 databases "DATABASES" 118 dateAdd "DATE_ADD" 119 dateSub "DATE_SUB" 120 day "DAY" 121 dayname "DAYNAME" 122 dayofmonth "DAYOFMONTH" 123 dayofweek "DAYOFWEEK" 124 dayofyear "DAYOFYEAR" 125 ddl "DDL" 126 deallocate "DEALLOCATE" 127 defaultKwd "DEFAULT" 128 delayed "DELAYED" 129 delayKeyWrite "DELAY_KEY_WRITE" 130 deleteKwd "DELETE" 131 desc "DESC" 132 describe "DESCRIBE" 133 disable "DISABLE" 134 distinct "DISTINCT" 135 div "DIV" 136 do "DO" 137 drop "DROP" 138 dual "DUAL" 139 duplicate "DUPLICATE" 140 dynamic "DYNAMIC" 141 elseKwd "ELSE" 142 enable "ENABLE" 143 end "END" 144 engine "ENGINE" 145 engines "ENGINES" 146 enum "ENUM" 147 eq "=" 148 escape "ESCAPE" 149 execute "EXECUTE" 150 exists "EXISTS" 151 explain "EXPLAIN" 152 extract "EXTRACT" 153 falseKwd "false" 154 fields "FIELDS" 155 first "FIRST" 156 fixed "FIXED" 157 foreign "FOREIGN" 158 forKwd "FOR" 159 force "FORCE" 160 foundRows "FOUND_ROWS" 161 from "FROM" 162 full "FULL" 163 fulltext "FULLTEXT" 164 ge ">=" 165 global "GLOBAL" 166 grant "GRANT" 167 grants "GRANTS" 168 group "GROUP" 169 groupConcat "GROUP_CONCAT" 170 hash "HASH" 171 having "HAVING" 172 highPriority "HIGH_PRIORITY" 173 hour "HOUR" 174 identified "IDENTIFIED" 175 ignore "IGNORE" 176 ifKwd "IF" 177 ifNull "IFNULL" 178 in "IN" 179 index "INDEX" 180 inner "INNER" 181 insert "INSERT" 182 interval "INTERVAL" 183 into "INTO" 184 is "IS" 185 isNull "ISNULL" 186 isolation "ISOLATION" 187 join "JOIN" 188 key "KEY" 189 keyBlockSize "KEY_BLOCK_SIZE" 190 keys "KEYS" 191 le "<=" 192 leading "LEADING" 193 left "LEFT" 194 length "LENGTH" 195 level "LEVEL" 196 like "LIKE" 197 limit "LIMIT" 198 local "LOCAL" 199 locate "LOCATE" 200 lock "LOCK" 201 lower "LOWER" 202 lcase "LCASE" 203 lowPriority "LOW_PRIORITY" 204 lsh "<<" 205 ltrim "LTRIM" 206 max "MAX" 207 maxRows "MAX_ROWS" 208 microsecond "MICROSECOND" 209 min "MIN" 210 minute "MINUTE" 211 minRows "MIN_ROWS" 212 mod "MOD" 213 mode "MODE" 214 month "MONTH" 215 names "NAMES" 216 national "NATIONAL" 217 neq "!=" 218 neqSynonym "<>" 219 not "NOT" 220 null "NULL" 221 nulleq "<=>" 222 nullIf "NULLIF" 223 offset "OFFSET" 224 on "ON" 225 only "ONLY" 226 option "OPTION" 227 or "OR" 228 order "ORDER" 229 oror "||" 230 outer "OUTER" 231 password "PASSWORD" 232 placeholder "PLACEHOLDER" 233 pow "POW" 234 power "POWER" 235 prepare "PREPARE" 236 primary "PRIMARY" 237 procedure "PROCEDURE" 238 quarter "QUARTER" 239 quick "QUICK" 240 rand "RAND" 241 read "READ" 242 redundant "REDUNDANT" 243 references "REFERENCES" 244 regexpKwd "REGEXP" 245 repeat "REPEAT" 246 repeatable "REPEATABLE" 247 replace "REPLACE" 248 right "RIGHT" 249 rlike "RLIKE" 250 rollback "ROLLBACK" 251 round "ROUND" 252 row "ROW" 253 rowFormat "ROW_FORMAT" 254 rsh ">>" 255 rtrim "RTRIM" 256 reverse "REVERSE" 257 schema "SCHEMA" 258 schemas "SCHEMAS" 259 second "SECOND" 260 selectKwd "SELECT" 261 serializable "SERIALIZABLE" 262 session "SESSION" 263 set "SET" 264 share "SHARE" 265 show "SHOW" 266 signed "SIGNED" 267 some "SOME" 268 start "START" 269 status "STATUS" 270 stringType "string" 271 subDate "SUBDATE" 272 strcmp "STRCMP" 273 substring "SUBSTRING" 274 substringIndex "SUBSTRING_INDEX" 275 sum "SUM" 276 sysVar "SYS_VAR" 277 sysDate "SYSDATE" 278 tableKwd "TABLE" 279 tables "TABLES" 280 then "THEN" 281 to "TO" 282 trailing "TRAILING" 283 transaction "TRANSACTION" 284 triggers "TRIGGERS" 285 trim "TRIM" 286 trueKwd "true" 287 truncate "TRUNCATE" 288 uncommitted "UNCOMMITTED" 289 underscoreCS "UNDERSCORE_CHARSET" 290 unknown "UNKNOWN" 291 union "UNION" 292 unique "UNIQUE" 293 unlock "UNLOCK" 294 unsigned "UNSIGNED" 295 update "UPDATE" 296 upper "UPPER" 297 ucase "UCASE" 298 use "USE" 299 user "USER" 300 using "USING" 301 userVar "USER_VAR" 302 value "VALUE" 303 values "VALUES" 304 variables "VARIABLES" 305 version "VERSION" 306 warnings "WARNINGS" 307 week "WEEK" 308 weekday "WEEKDAY" 309 weekofyear "WEEKOFYEAR" 310 when "WHEN" 311 where "WHERE" 312 write "WRITE" 313 xor "XOR" 314 yearweek "YEARWEEK" 315 zerofill "ZEROFILL" 316 317 calcFoundRows "SQL_CALC_FOUND_ROWS" 318 sqlCache "SQL_CACHE" 319 sqlNoCache "SQL_NO_CACHE" 320 321 currentTs "CURRENT_TIMESTAMP" 322 localTime "LOCALTIME" 323 localTs "LOCALTIMESTAMP" 324 now "NOW" 325 326 tinyIntType "TINYINT" 327 smallIntType "SMALLINT" 328 mediumIntType "MEDIUMINT" 329 intType "INT" 330 integerType "INTEGER" 331 bigIntType "BIGINT" 332 bitType "BIT" 333 334 decimalType "DECIMAL" 335 numericType "NUMERIC" 336 floatType "float" 337 doubleType "DOUBLE" 338 precisionType "PRECISION" 339 realType "REAL" 340 341 dateType "DATE" 342 timeType "TIME" 343 datetimeType "DATETIME" 344 timestampType "TIMESTAMP" 345 yearType "YEAR" 346 347 charType "CHAR" 348 varcharType "VARCHAR" 349 binaryType "BINARY" 350 varbinaryType "VARBINARY" 351 tinyblobType "TINYBLOB" 352 blobType "BLOB" 353 mediumblobType "MEDIUMBLOB" 354 longblobType "LONGBLOB" 355 tinytextType "TINYTEXT" 356 textType "TEXT" 357 mediumtextType "MEDIUMTEXT" 358 longtextType "LONGTEXT" 359 360 int16Type "int16" 361 int24Type "int24" 362 int32Type "int32" 363 int64Type "int64" 364 int8Type "int8" 365 uintType "uint" 366 uint16Type "uint16" 367 uint32Type "uint32" 368 uint64Type "uint64" 369 uint8Type "uint8" 370 float32Type "float32" 371 float64Type "float64" 372 boolType "BOOL" 373 booleanType "BOOLEAN" 374 375 parseExpression "parse expression prefix" 376 377 secondMicrosecond "SECOND_MICROSECOND" 378 minuteMicrosecond "MINUTE_MICROSECOND" 379 minuteSecond "MINUTE_SECOND" 380 hourMicrosecond "HOUR_MICROSECOND" 381 hourSecond "HOUR_SECOND" 382 hourMinute "HOUR_MINUTE" 383 dayMicrosecond "DAY_MICROSECOND" 384 daySecond "DAY_SECOND" 385 dayMinute "DAY_MINUTE" 386 dayHour "DAY_HOUR" 387 yearMonth "YEAR_MONTH" 388 389 restrict "RESTRICT" 390 cascade "CASCADE" 391 no "NO" 392 action "ACTION" 393 394 395 %type <item> 396 AdminStmt "Check table statement or show ddl statement" 397 AlterTableStmt "Alter table statement" 398 AlterTableSpec "Alter table specification" 399 AlterTableSpecList "Alter table specification list" 400 AnyOrAll "Any or All for subquery" 401 Assignment "assignment" 402 AssignmentList "assignment list" 403 AssignmentListOpt "assignment list opt" 404 AuthOption "User auth option" 405 AuthString "Password string value" 406 BeginTransactionStmt "BEGIN TRANSACTION statement" 407 CastType "Cast function target type" 408 ColumnDef "table column definition" 409 ColumnName "column name" 410 ColumnNameList "column name list" 411 ColumnNameListOpt "column name list opt" 412 ColumnKeywordOpt "Column keyword or empty" 413 ColumnSetValue "insert statement set value by column name" 414 ColumnSetValueList "insert statement set value by column name list" 415 CommaOpt "optional comma" 416 CommitStmt "COMMIT statement" 417 CompareOp "Compare opcode" 418 ColumnOption "column definition option" 419 ColumnOptionList "column definition option list" 420 ColumnOptionListOpt "optional column definition option list" 421 Constraint "table constraint" 422 ConstraintElem "table constraint element" 423 ConstraintKeywordOpt "Constraint Keyword or empty" 424 CreateDatabaseStmt "Create Database Statement" 425 CreateIndexStmt "CREATE INDEX statement" 426 CreateIndexStmtUnique "CREATE INDEX optional UNIQUE clause" 427 DatabaseOption "CREATE Database specification" 428 DatabaseOptionList "CREATE Database specification list" 429 DatabaseOptionListOpt "CREATE Database specification list opt" 430 CreateTableStmt "CREATE TABLE statement" 431 CreateUserStmt "CREATE User statement" 432 CrossOpt "Cross join option" 433 DateArithOpt "Date arith dateadd or datesub option" 434 DateArithMultiFormsOpt "Date arith adddate or subdate option" 435 DateArithInterval "Date arith interval part" 436 DatabaseSym "DATABASE or SCHEMA" 437 DBName "Database Name" 438 DeallocateSym "Deallocate or drop" 439 DeallocateStmt "Deallocate prepared statement" 440 Default "DEFAULT clause" 441 DefaultOpt "optional DEFAULT clause" 442 DefaultKwdOpt "optional DEFAULT keyword" 443 DefaultValueExpr "DefaultValueExpr(Now or Signed Literal)" 444 DeleteFromStmt "DELETE FROM statement" 445 DistinctOpt "Distinct option" 446 DoStmt "Do statement" 447 DropDatabaseStmt "DROP DATABASE statement" 448 DropIndexStmt "DROP INDEX statement" 449 DropTableStmt "DROP TABLE statement" 450 EmptyStmt "empty statement" 451 EqOpt "= or empty" 452 EscapedTableRef "escaped table reference" 453 ExecuteStmt "Execute statement" 454 ExplainSym "EXPLAIN or DESCRIBE or DESC" 455 ExplainStmt "EXPLAIN statement" 456 Expression "expression" 457 ExpressionList "expression list" 458 ExpressionListOpt "expression list opt" 459 ExpressionListList "expression list list" 460 Factor "expression factor" 461 PredicateExpr "Predicate expression factor" 462 Field "field expression" 463 FieldAsName "Field alias name" 464 FieldAsNameOpt "Field alias name opt" 465 FieldList "field expression list" 466 TableRefsClause "Table references clause" 467 Function "function expr" 468 FunctionCallAgg "Function call on aggregate data" 469 FunctionCallConflict "Function call with reserved keyword as function name" 470 FunctionCallKeyword "Function call with keyword as function name" 471 FunctionCallNonKeyword "Function call with nonkeyword as function name" 472 FunctionNameConflict "Built-in function call names which are conflict with keywords" 473 FuncDatetimePrec "Function datetime precision" 474 GlobalScope "The scope of variable" 475 GrantStmt "Grant statement" 476 GroupByClause "GROUP BY clause" 477 HashString "Hashed string" 478 HavingClause "HAVING clause" 479 IfExists "If Exists" 480 IfNotExists "If Not Exists" 481 IgnoreOptional "IGNORE or empty" 482 IndexColName "Index column name" 483 IndexColNameList "List of index column name" 484 IndexHint "index hint" 485 IndexHintList "index hint list" 486 IndexHintListOpt "index hint list opt" 487 IndexHintScope "index hint scope" 488 IndexHintType "index hint type" 489 IndexName "index name" 490 IndexNameList "index name list" 491 IndexOption "Index Option" 492 IndexType "index type" 493 IndexTypeOpt "Optional index type" 494 InsertIntoStmt "INSERT INTO statement" 495 InsertValues "Rest part of INSERT/REPLACE INTO statement" 496 IntoOpt "INTO or EmptyString" 497 IsolationLevel "Isolation level" 498 JoinTable "join table" 499 JoinType "join type" 500 KeyOrIndex "{KEY|INDEX}" 501 LikeEscapeOpt "like escape option" 502 LimitClause "LIMIT clause" 503 Literal "literal value" 504 LockTablesStmt "Lock tables statement" 505 LockType "Table locks type" 506 logAnd "logical and operator" 507 logOr "logical or operator" 508 LowPriorityOptional "LOW_PRIORITY or empty" 509 name "name" 510 NationalOpt "National option" 511 NotOpt "optional NOT" 512 NowSym "CURRENT_TIMESTAMP/LOCALTIME/LOCALTIMESTAMP/NOW" 513 NumLiteral "Num/Int/Float/Decimal Literal" 514 ObjectType "Grant statement object type" 515 OnDuplicateKeyUpdate "ON DUPLICATE KEY UPDATE value list" 516 Operand "operand" 517 OptFull "Full or empty" 518 OptInteger "Optional Integer keyword" 519 OptTable "Optional table keyword" 520 Order "ORDER BY clause optional collation specification" 521 OrderBy "ORDER BY clause" 522 ByItem "BY item" 523 OrderByOptional "Optional ORDER BY clause optional" 524 ByList "BY list" 525 OuterOpt "optional OUTER clause" 526 QuickOptional "QUICK or empty" 527 PasswordOpt "Password option" 528 ColumnPosition "Column position [First|After ColumnName]" 529 PreparedStmt "PreparedStmt" 530 PrepareSQL "Prepare statement sql string" 531 PrimaryExpression "primary expression" 532 PrimaryFactor "primary expression factor" 533 PrimaryOpt "Optional primary keyword" 534 Priority "insert statement priority" 535 PrivElem "Privilege element" 536 PrivElemList "Privilege element list" 537 PrivLevel "Privilege scope" 538 PrivType "Privilege type" 539 ReferDef "Reference definition" 540 OnDeleteOpt "optional ON DELETE clause" 541 OnUpdateOpt "optional ON UPDATE clause" 542 ReferOpt "reference option" 543 RegexpSym "REGEXP or RLIKE" 544 ReplaceIntoStmt "REPLACE INTO statement" 545 ReplacePriority "replace statement priority" 546 RollbackStmt "ROLLBACK statement" 547 RowFormat "Row format option" 548 SelectLockOpt "FOR UPDATE or LOCK IN SHARE MODE," 549 SelectStmt "SELECT statement" 550 SelectStmtCalcFoundRows "SELECT statement optional SQL_CALC_FOUND_ROWS" 551 SelectStmtSQLCache "SELECT statement optional SQL_CAHCE/SQL_NO_CACHE" 552 SelectStmtDistinct "SELECT statement optional DISTINCT clause" 553 SelectStmtFieldList "SELECT statement field list" 554 SelectStmtLimit "SELECT statement optional LIMIT clause" 555 SelectStmtOpts "Select statement options" 556 SelectStmtGroup "SELECT statement optional GROUP BY clause" 557 SetStmt "Set variable statement" 558 ShowStmt "Show engines/databases/tables/columns/warnings/status statement" 559 ShowTargetFilterable "Show target that can be filtered by WHERE or LIKE" 560 ShowDatabaseNameOpt "Show tables/columns statement database name option" 561 ShowTableAliasOpt "Show table alias option" 562 ShowLikeOrWhereOpt "Show like or where clause option" 563 SignedLiteral "Literal or NumLiteral with sign" 564 Statement "statement" 565 StatementList "statement list" 566 StringName "string literal or identifier" 567 StringList "string list" 568 ExplainableStmt "explainable statement" 569 SubSelect "Sub Select" 570 Symbol "Constraint Symbol" 571 SystemVariable "System defined variable name" 572 TableAsName "table alias name" 573 TableAsNameOpt "table alias name optional" 574 TableElement "table definition element" 575 TableElementList "table definition element list" 576 TableFactor "table factor" 577 TableLock "Table name and lock type" 578 TableLockList "Table lock list" 579 TableName "Table name" 580 TableNameList "Table name list" 581 TableOption "create table option" 582 TableOptionList "create table option list" 583 TableOptionListOpt "create table option list opt" 584 TableRef "table reference" 585 TableRefs "table references" 586 TimeUnit "Time unit" 587 TransactionChar "Transaction characteristic" 588 TransactionChars "Transaction characteristic list" 589 TrimDirection "Trim string direction" 590 TruncateTableStmt "TRANSACTION TABLE statement" 591 UnionOpt "Union Option(empty/ALL/DISTINCT)" 592 UnionStmt "Union select state ment" 593 UnionClauseList "Union select clause list" 594 UnionSelect "Union (select) item" 595 UnlockTablesStmt "Unlock tables statement" 596 UpdateStmt "UPDATE statement" 597 Username "Username" 598 UserSpec "Username and auth option" 599 UserSpecList "Username and auth option list" 600 UserVariable "User defined variable name" 601 UserVariableList "User defined variable name list" 602 UseStmt "USE statement" 603 ValueSym "Value or Values" 604 VariableAssignment "set variable value" 605 VariableAssignmentList "set variable value list" 606 Variable "User or system variable" 607 WhereClause "WHERE clause" 608 WhereClauseOptional "Optinal WHERE clause" 609 610 Identifier "identifier or unreserved keyword" 611 UnReservedKeyword "MySQL unreserved keywords" 612 NotKeywordToken "Tokens not mysql keyword but treated specially" 613 614 WhenClause "When clause" 615 WhenClauseList "When clause list" 616 ElseOpt "Optional else clause" 617 ExpressionOpt "Optional expression" 618 619 Type "Types" 620 621 NumericType "Numeric types" 622 IntegerType "Integer Types types" 623 FixedPointType "Exact value types" 624 FloatingPointType "Approximate value types" 625 BitValueType "bit value types" 626 627 StringType "String types" 628 BlobType "Blob types" 629 TextType "Text types" 630 631 DateAndTimeType "Date and Time types" 632 633 OptFieldLen "Field length or empty" 634 FieldLen "Field length" 635 FieldOpts "Field type definition option list" 636 FieldOpt "Field type definition option" 637 FloatOpt "Floating-point type option" 638 Precision "Floating-point precision option" 639 OptBinary "Optional BINARY" 640 CharsetKw "charset or charater set" 641 OptCharset "Optional Character setting" 642 OptCollate "Optional Collate setting" 643 NUM "numbers" 644 LengthNum "Field length num(uint64)" 645 646 %token tableRefPriority 647 648 %precedence lowerThanCalcFoundRows 649 %precedence calcFoundRows 650 651 %precedence lowerThanSQLCache 652 %precedence sqlCache sqlNoCache 653 654 %precedence lowerThanSetKeyword 655 %precedence set 656 657 %precedence lowerThanInsertValues 658 %precedence insertValues 659 660 %precedence lowerThanKey 661 %precedence key 662 663 %left join inner cross left right full 664 /* A dummy token to force the priority of TableRef production in a join. */ 665 %left tableRefPriority 666 %precedence lowerThanOn 667 %precedence on 668 %right assignmentEq 669 %left oror or 670 %left xor 671 %left andand and 672 %left between 673 %precedence lowerThanEq 674 %left eq ge le neq neqSynonym '>' '<' is like in 675 %left '|' 676 %left '&' 677 %left rsh lsh 678 %left '-' '+' 679 %left '*' '/' '%' div mod 680 %left '^' 681 %left '~' neg 682 %right not 683 %right collate 684 685 %precedence lowerThanLeftParen 686 %precedence '(' 687 %precedence lowerThanQuick 688 %precedence quick 689 %precedence lowerThanEscape 690 %precedence escape 691 %precedence lowerThanComma 692 %precedence ',' 693 694 %start Start 695 696 %% 697 698 Start: 699 StatementList 700 | parseExpression Expression 701 { 702 yylex.(*lexer).expr = $2.(ast.ExprNode) 703 } 704 705 /**************************************AlterTableStmt*************************************** 706 * See: https://dev.mysql.com/doc/refman/5.7/en/alter-table.html 707 *******************************************************************************************/ 708 AlterTableStmt: 709 "ALTER" IgnoreOptional "TABLE" TableName AlterTableSpecList 710 { 711 $$ = &ast.AlterTableStmt{ 712 Table: $4.(*ast.TableName), 713 Specs: $5.([]*ast.AlterTableSpec), 714 } 715 } 716 717 AlterTableSpec: 718 TableOptionListOpt 719 { 720 $$ = &ast.AlterTableSpec{ 721 Tp: ast.AlterTableOption, 722 Options:$1.([]*ast.TableOption), 723 } 724 } 725 | "ADD" ColumnKeywordOpt ColumnDef ColumnPosition 726 { 727 $$ = &ast.AlterTableSpec{ 728 Tp: ast.AlterTableAddColumn, 729 Column: $3.(*ast.ColumnDef), 730 Position: $4.(*ast.ColumnPosition), 731 } 732 } 733 | "ADD" Constraint 734 { 735 constraint := $2.(*ast.Constraint) 736 $$ = &ast.AlterTableSpec{ 737 Tp: ast.AlterTableAddConstraint, 738 Constraint: constraint, 739 } 740 } 741 | "DROP" ColumnKeywordOpt ColumnName 742 { 743 $$ = &ast.AlterTableSpec{ 744 Tp: ast.AlterTableDropColumn, 745 DropColumn: $3.(*ast.ColumnName), 746 } 747 } 748 | "DROP" "PRIMARY" "KEY" 749 { 750 $$ = &ast.AlterTableSpec{Tp: ast.AlterTableDropPrimaryKey} 751 } 752 | "DROP" KeyOrIndex IndexName 753 { 754 $$ = &ast.AlterTableSpec{ 755 Tp: ast.AlterTableDropIndex, 756 Name: $3.(string), 757 } 758 } 759 | "DROP" "FOREIGN" "KEY" Symbol 760 { 761 $$ = &ast.AlterTableSpec{ 762 Tp: ast.AlterTableDropForeignKey, 763 Name: $4.(string), 764 } 765 } 766 | "DISABLE" "KEYS" 767 { 768 $$ = &ast.AlterTableSpec{} 769 } 770 | "ENABLE" "KEYS" 771 { 772 $$ = &ast.AlterTableSpec{} 773 } 774 775 KeyOrIndex: 776 "KEY"|"INDEX" 777 778 ColumnKeywordOpt: 779 {} 780 | "COLUMN" 781 782 ColumnPosition: 783 { 784 $$ = &ast.ColumnPosition{Tp: ast.ColumnPositionNone} 785 } 786 | "FIRST" 787 { 788 $$ = &ast.ColumnPosition{Tp: ast.ColumnPositionFirst} 789 } 790 | "AFTER" ColumnName 791 { 792 $$ = &ast.ColumnPosition{ 793 Tp: ast.ColumnPositionAfter, 794 RelativeColumn: $2.(*ast.ColumnName), 795 } 796 } 797 798 AlterTableSpecList: 799 AlterTableSpec 800 { 801 $$ = []*ast.AlterTableSpec{$1.(*ast.AlterTableSpec)} 802 } 803 | AlterTableSpecList ',' AlterTableSpec 804 { 805 $$ = append($1.([]*ast.AlterTableSpec), $3.(*ast.AlterTableSpec)) 806 } 807 808 ConstraintKeywordOpt: 809 { 810 $$ = nil 811 } 812 | "CONSTRAINT" 813 { 814 $$ = nil 815 } 816 | "CONSTRAINT" Symbol 817 { 818 $$ = $2.(string) 819 } 820 821 Symbol: 822 Identifier 823 824 /*******************************************************************************************/ 825 Assignment: 826 ColumnName eq Expression 827 { 828 $$ = &ast.Assignment{Column: $1.(*ast.ColumnName), Expr:$3.(ast.ExprNode)} 829 } 830 831 AssignmentList: 832 Assignment 833 { 834 $$ = []*ast.Assignment{$1.(*ast.Assignment)} 835 } 836 | AssignmentList ',' Assignment 837 { 838 $$ = append($1.([]*ast.Assignment), $3.(*ast.Assignment)) 839 } 840 841 AssignmentListOpt: 842 /* EMPTY */ 843 { 844 $$ = []*ast.Assignment{} 845 } 846 | AssignmentList 847 848 BeginTransactionStmt: 849 "BEGIN" 850 { 851 $$ = &ast.BeginStmt{} 852 } 853 | "START" "TRANSACTION" 854 { 855 $$ = &ast.BeginStmt{} 856 } 857 858 ColumnDef: 859 ColumnName Type ColumnOptionListOpt 860 { 861 $$ = &ast.ColumnDef{Name: $1.(*ast.ColumnName), Tp: $2.(*types.FieldType), Options: $3.([]*ast.ColumnOption)} 862 } 863 864 ColumnName: 865 Identifier 866 { 867 $$ = &ast.ColumnName{Name: model.NewCIStr($1.(string))} 868 } 869 | Identifier '.' Identifier 870 { 871 $$ = &ast.ColumnName{Table: model.NewCIStr($1.(string)), Name: model.NewCIStr($3.(string))} 872 } 873 | Identifier '.' Identifier '.' Identifier 874 { 875 $$ = &ast.ColumnName{Schema: model.NewCIStr($1.(string)), Table: model.NewCIStr($3.(string)), Name: model.NewCIStr($5.(string))} 876 } 877 878 ColumnNameList: 879 ColumnName 880 { 881 $$ = []*ast.ColumnName{$1.(*ast.ColumnName)} 882 } 883 | ColumnNameList ',' ColumnName 884 { 885 $$ = append($1.([]*ast.ColumnName), $3.(*ast.ColumnName)) 886 } 887 888 ColumnNameListOpt: 889 /* EMPTY */ 890 { 891 $$ = []*ast.ColumnName{} 892 } 893 | ColumnNameList 894 { 895 $$ = $1.([]*ast.ColumnName) 896 } 897 898 CommitStmt: 899 "COMMIT" 900 { 901 $$ = &ast.CommitStmt{} 902 } 903 904 PrimaryOpt: 905 {} | "PRIMARY" 906 907 ColumnOption: 908 "NOT" "NULL" 909 { 910 $$ = &ast.ColumnOption{Tp: ast.ColumnOptionNotNull} 911 } 912 | "NULL" 913 { 914 $$ = &ast.ColumnOption{Tp: ast.ColumnOptionNull} 915 } 916 | "AUTO_INCREMENT" 917 { 918 $$ = &ast.ColumnOption{Tp: ast.ColumnOptionAutoIncrement} 919 } 920 | PrimaryOpt "KEY" 921 { 922 // KEY is normally a synonym for INDEX. The key attribute PRIMARY KEY 923 // can also be specified as just KEY when given in a column definition. 924 // See: http://dev.mysql.com/doc/refman/5.7/en/create-table.html 925 $$ = &ast.ColumnOption{Tp: ast.ColumnOptionPrimaryKey} 926 } 927 | "UNIQUE" %prec lowerThanKey 928 { 929 $$ = &ast.ColumnOption{Tp: ast.ColumnOptionUniqKey} 930 } 931 | "UNIQUE" "KEY" 932 { 933 $$ = &ast.ColumnOption{Tp: ast.ColumnOptionUniqKey} 934 } 935 | "DEFAULT" DefaultValueExpr 936 { 937 $$ = &ast.ColumnOption{Tp: ast.ColumnOptionDefaultValue, Expr: $2.(ast.ExprNode)} 938 } 939 | "ON" "UPDATE" NowSym 940 { 941 nowFunc := &ast.FuncCallExpr{FnName: model.NewCIStr("CURRENT_TIMESTAMP")} 942 $$ = &ast.ColumnOption{Tp: ast.ColumnOptionOnUpdate, Expr: nowFunc} 943 } 944 | "COMMENT" stringLit 945 { 946 $$ = &ast.ColumnOption{Tp: ast.ColumnOptionComment, Expr: ast.NewValueExpr($2)} 947 } 948 | "CHECK" '(' Expression ')' 949 { 950 // See: https://dev.mysql.com/doc/refman/5.7/en/create-table.html 951 // The CHECK clause is parsed but ignored by all storage engines. 952 $$ = &ast.ColumnOption{} 953 } 954 955 ColumnOptionList: 956 ColumnOption 957 { 958 $$ = []*ast.ColumnOption{$1.(*ast.ColumnOption)} 959 } 960 | ColumnOptionList ColumnOption 961 { 962 $$ = append($1.([]*ast.ColumnOption), $2.(*ast.ColumnOption)) 963 } 964 965 ColumnOptionListOpt: 966 { 967 $$ = []*ast.ColumnOption{} 968 } 969 | ColumnOptionList 970 { 971 $$ = $1.([]*ast.ColumnOption) 972 } 973 974 ConstraintElem: 975 "PRIMARY" "KEY" IndexTypeOpt '(' IndexColNameList ')' IndexOption 976 { 977 c := &ast.Constraint{ 978 Tp: ast.ConstraintPrimaryKey, 979 Keys: $5.([]*ast.IndexColName), 980 } 981 if $7 != nil { 982 c.Option = $7.(*ast.IndexOption) 983 } 984 if $3 != nil { 985 if c.Option == nil { 986 c.Option = &ast.IndexOption{} 987 } 988 c.Option.Tp = $3.(model.IndexType) 989 } 990 $$ = c 991 } 992 | "FULLTEXT" "KEY" IndexName '(' IndexColNameList ')' IndexOption 993 { 994 c := &ast.Constraint{ 995 Tp: ast.ConstraintFulltext, 996 Keys: $5.([]*ast.IndexColName), 997 Name: $3.(string), 998 } 999 if $7 != nil { 1000 c.Option = $7.(*ast.IndexOption) 1001 } 1002 $$ = c 1003 } 1004 | "INDEX" IndexName IndexTypeOpt '(' IndexColNameList ')' IndexOption 1005 { 1006 c := &ast.Constraint{ 1007 Tp: ast.ConstraintIndex, 1008 Keys: $5.([]*ast.IndexColName), 1009 Name: $2.(string), 1010 } 1011 if $7 != nil { 1012 c.Option = $7.(*ast.IndexOption) 1013 } 1014 if $3 != nil { 1015 if c.Option == nil { 1016 c.Option = &ast.IndexOption{} 1017 } 1018 c.Option.Tp = $3.(model.IndexType) 1019 } 1020 $$ = c 1021 } 1022 | "KEY" IndexName IndexTypeOpt '(' IndexColNameList ')' IndexOption 1023 { 1024 c := &ast.Constraint{ 1025 Tp: ast.ConstraintKey, 1026 Keys: $5.([]*ast.IndexColName), 1027 Name: $2.(string), 1028 } 1029 if $7 != nil { 1030 c.Option = $7.(*ast.IndexOption) 1031 } 1032 if $3 != nil { 1033 if c.Option == nil { 1034 c.Option = &ast.IndexOption{} 1035 } 1036 c.Option.Tp = $3.(model.IndexType) 1037 } 1038 $$ = c 1039 } 1040 | "UNIQUE" IndexName IndexTypeOpt '(' IndexColNameList ')' IndexOption 1041 { 1042 c := &ast.Constraint{ 1043 Tp: ast.ConstraintUniq, 1044 Keys: $5.([]*ast.IndexColName), 1045 Name: $2.(string), 1046 } 1047 if $7 != nil { 1048 c.Option = $7.(*ast.IndexOption) 1049 } 1050 if $3 != nil { 1051 if c.Option == nil { 1052 c.Option = &ast.IndexOption{} 1053 } 1054 c.Option.Tp = $3.(model.IndexType) 1055 } 1056 $$ = c 1057 } 1058 | "UNIQUE" "INDEX" IndexName IndexTypeOpt '(' IndexColNameList ')' IndexOption 1059 { 1060 c := &ast.Constraint{ 1061 Tp: ast.ConstraintUniqIndex, 1062 Keys: $6.([]*ast.IndexColName), 1063 Name: $3.(string), 1064 } 1065 if $8 != nil { 1066 c.Option = $8.(*ast.IndexOption) 1067 } 1068 if $4 != nil { 1069 if c.Option == nil { 1070 c.Option = &ast.IndexOption{} 1071 } 1072 c.Option.Tp = $4.(model.IndexType) 1073 } 1074 $$ = c 1075 } 1076 | "UNIQUE" "KEY" IndexName IndexTypeOpt '(' IndexColNameList ')' IndexOption 1077 { 1078 c := &ast.Constraint{ 1079 Tp: ast.ConstraintUniqKey, 1080 Keys: $6.([]*ast.IndexColName), 1081 Name: $3.(string), 1082 } 1083 if $8 != nil { 1084 c.Option = $8.(*ast.IndexOption) 1085 } 1086 if $4 != nil { 1087 if c.Option == nil { 1088 c.Option = &ast.IndexOption{} 1089 } 1090 c.Option.Tp = $4.(model.IndexType) 1091 } 1092 $$ = c 1093 } 1094 | "FOREIGN" "KEY" IndexName '(' IndexColNameList ')' ReferDef 1095 { 1096 $$ = &ast.Constraint{ 1097 Tp: ast.ConstraintForeignKey, 1098 Keys: $5.([]*ast.IndexColName), 1099 Name: $3.(string), 1100 Refer: $7.(*ast.ReferenceDef), 1101 } 1102 } 1103 1104 ReferDef: 1105 "REFERENCES" TableName '(' IndexColNameList ')' OnDeleteOpt OnUpdateOpt 1106 { 1107 var onDeleteOpt *ast.OnDeleteOpt 1108 if $6 != nil { 1109 onDeleteOpt = $6.(*ast.OnDeleteOpt) 1110 } 1111 var onUpdateOpt *ast.OnUpdateOpt 1112 if $7 != nil { 1113 onUpdateOpt = $7.(*ast.OnUpdateOpt) 1114 } 1115 $$ = &ast.ReferenceDef{ 1116 Table: $2.(*ast.TableName), 1117 IndexColNames: $4.([]*ast.IndexColName), 1118 OnDelete: onDeleteOpt, 1119 OnUpdate: onUpdateOpt, 1120 } 1121 } 1122 1123 OnDeleteOpt: 1124 { 1125 $$ = &ast.OnDeleteOpt{} 1126 } %prec lowerThanOn 1127 | "ON" "DELETE" ReferOpt 1128 { 1129 $$ = &ast.OnDeleteOpt{ReferOpt: $3.(ast.ReferOptionType)} 1130 } 1131 1132 OnUpdateOpt: 1133 { 1134 $$ = &ast.OnUpdateOpt{} 1135 } %prec lowerThanOn 1136 | "ON" "UPDATE" ReferOpt 1137 { 1138 $$ = &ast.OnUpdateOpt{ReferOpt: $3.(ast.ReferOptionType)} 1139 } 1140 1141 ReferOpt: 1142 "RESTRICT" 1143 { 1144 $$ = ast.ReferOptionRestrict 1145 } 1146 | "CASCADE" 1147 { 1148 $$ = ast.ReferOptionCascade 1149 } 1150 | "SET" "NULL" 1151 { 1152 $$ = ast.ReferOptionSetNull 1153 } 1154 | "NO" "ACTION" 1155 { 1156 $$ = ast.ReferOptionNoAction 1157 } 1158 1159 /* 1160 * The DEFAULT clause specifies a default value for a column. 1161 * With one exception, the default value must be a constant; 1162 * it cannot be a function or an expression. This means, for example, 1163 * that you cannot set the default for a date column to be the value of 1164 * a function such as NOW() or CURRENT_DATE. The exception is that you 1165 * can specify CURRENT_TIMESTAMP as the default for a TIMESTAMP or DATETIME column. 1166 * 1167 * See: http://dev.mysql.com/doc/refman/5.7/en/create-table.html 1168 * https://github.com/mysql/mysql-server/blob/5.7/sql/sql_yacc.yy#L6832 1169 */ 1170 DefaultValueExpr: 1171 NowSym 1172 { 1173 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr("CURRENT_TIMESTAMP")} 1174 } 1175 | NowSym '(' ')' 1176 { 1177 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr("CURRENT_TIMESTAMP")} 1178 } 1179 | SignedLiteral 1180 1181 // TODO: Process other three keywords 1182 NowSym: 1183 "CURRENT_TIMESTAMP" 1184 | "LOCALTIME" 1185 | "LOCALTIMESTAMP" 1186 | "NOW" 1187 1188 SignedLiteral: 1189 Literal 1190 { 1191 $$ = ast.NewValueExpr($1) 1192 } 1193 | '+' NumLiteral 1194 { 1195 $$ = &ast.UnaryOperationExpr{Op: opcode.Plus, V: ast.NewValueExpr($2)} 1196 } 1197 | '-' NumLiteral 1198 { 1199 $$ = &ast.UnaryOperationExpr{Op: opcode.Minus, V: ast.NewValueExpr($2)} 1200 } 1201 1202 // TODO: support decimal literal 1203 NumLiteral: 1204 intLit 1205 | floatLit 1206 1207 1208 CreateIndexStmt: 1209 "CREATE" CreateIndexStmtUnique "INDEX" Identifier "ON" TableName '(' IndexColNameList ')' 1210 { 1211 $$ = &ast.CreateIndexStmt{ 1212 Unique: $2.(bool), 1213 IndexName: $4.(string), 1214 Table: $6.(*ast.TableName), 1215 IndexColNames: $8.([]*ast.IndexColName), 1216 } 1217 if yylex.(*lexer).root { 1218 break 1219 } 1220 } 1221 1222 CreateIndexStmtUnique: 1223 { 1224 $$ = false 1225 } 1226 | "UNIQUE" 1227 { 1228 $$ = true 1229 } 1230 1231 IndexColName: 1232 ColumnName OptFieldLen Order 1233 { 1234 //Order is parsed but just ignored as MySQL did 1235 $$ = &ast.IndexColName{Column: $1.(*ast.ColumnName), Length: $2.(int)} 1236 } 1237 1238 IndexColNameList: 1239 { 1240 $$ = []*ast.IndexColName{} 1241 } 1242 | IndexColName 1243 { 1244 $$ = []*ast.IndexColName{$1.(*ast.IndexColName)} 1245 } 1246 | IndexColNameList ',' IndexColName 1247 { 1248 $$ = append($1.([]*ast.IndexColName), $3.(*ast.IndexColName)) 1249 } 1250 1251 1252 1253 /******************************************************************* 1254 * 1255 * Create Database Statement 1256 * CREATE {DATABASE | SCHEMA} [IF NOT EXISTS] db_name 1257 * [create_specification] ... 1258 * 1259 * create_specification: 1260 * [DEFAULT] CHARACTER SET [=] charset_name 1261 * | [DEFAULT] COLLATE [=] collation_name 1262 *******************************************************************/ 1263 CreateDatabaseStmt: 1264 "CREATE" DatabaseSym IfNotExists DBName DatabaseOptionListOpt 1265 { 1266 $$ = &ast.CreateDatabaseStmt{ 1267 IfNotExists: $3.(bool), 1268 Name: $4.(string), 1269 Options: $5.([]*ast.DatabaseOption), 1270 } 1271 1272 if yylex.(*lexer).root { 1273 break 1274 } 1275 } 1276 1277 DBName: 1278 Identifier 1279 1280 DatabaseOption: 1281 DefaultKwdOpt CharsetKw EqOpt StringName 1282 { 1283 $$ = &ast.DatabaseOption{Tp: ast.DatabaseOptionCharset, Value: $4.(string)} 1284 } 1285 | DefaultKwdOpt "COLLATE" EqOpt StringName 1286 { 1287 $$ = &ast.DatabaseOption{Tp: ast.DatabaseOptionCollate, Value: $4.(string)} 1288 } 1289 1290 DatabaseOptionListOpt: 1291 { 1292 $$ = []*ast.DatabaseOption{} 1293 } 1294 | DatabaseOptionList 1295 1296 DatabaseOptionList: 1297 DatabaseOption 1298 { 1299 $$ = []*ast.DatabaseOption{$1.(*ast.DatabaseOption)} 1300 } 1301 | DatabaseOptionList DatabaseOption 1302 { 1303 $$ = append($1.([]*ast.DatabaseOption), $2.(*ast.DatabaseOption)) 1304 } 1305 1306 /******************************************************************* 1307 * 1308 * Create Table Statement 1309 * 1310 * Example: 1311 * CREATE TABLE Persons 1312 * ( 1313 * P_Id int NOT NULL, 1314 * LastName varchar(255) NOT NULL, 1315 * FirstName varchar(255), 1316 * Address varchar(255), 1317 * City varchar(255), 1318 * PRIMARY KEY (P_Id) 1319 * ) 1320 *******************************************************************/ 1321 CreateTableStmt: 1322 "CREATE" "TABLE" IfNotExists TableName '(' TableElementList ')' TableOptionListOpt 1323 { 1324 tes := $6.([]interface {}) 1325 var columnDefs []*ast.ColumnDef 1326 var constraints []*ast.Constraint 1327 for _, te := range tes { 1328 switch te := te.(type) { 1329 case *ast.ColumnDef: 1330 columnDefs = append(columnDefs, te) 1331 case *ast.Constraint: 1332 constraints = append(constraints, te) 1333 } 1334 } 1335 if len(columnDefs) == 0 { 1336 yylex.(*lexer).err("Column Definition List can't be empty.") 1337 return 1 1338 } 1339 $$ = &ast.CreateTableStmt{ 1340 Table: $4.(*ast.TableName), 1341 IfNotExists: $3.(bool), 1342 Cols: columnDefs, 1343 Constraints: constraints, 1344 Options: $8.([]*ast.TableOption), 1345 } 1346 } 1347 1348 Default: 1349 "DEFAULT" Expression 1350 { 1351 $$ = $2 1352 } 1353 1354 DefaultOpt: 1355 { 1356 $$ = nil 1357 } 1358 | Default 1359 1360 DefaultKwdOpt: 1361 {} 1362 | "DEFAULT" 1363 1364 /****************************************************************** 1365 * Do statement 1366 * See: https://dev.mysql.com/doc/refman/5.7/en/do.html 1367 ******************************************************************/ 1368 DoStmt: 1369 "DO" ExpressionList 1370 { 1371 $$ = &ast.DoStmt { 1372 Exprs: $2.([]ast.ExprNode), 1373 } 1374 } 1375 1376 /******************************************************************* 1377 * 1378 * Delete Statement 1379 * 1380 *******************************************************************/ 1381 DeleteFromStmt: 1382 "DELETE" LowPriorityOptional QuickOptional IgnoreOptional "FROM" TableName WhereClauseOptional OrderByOptional LimitClause 1383 { 1384 // Single Table 1385 join := &ast.Join{Left: &ast.TableSource{Source: $6.(ast.ResultSetNode)}, Right: nil} 1386 x := &ast.DeleteStmt{ 1387 TableRefs: &ast.TableRefsClause{TableRefs: join}, 1388 LowPriority: $2.(bool), 1389 Quick: $3.(bool), 1390 Ignore: $4.(bool), 1391 } 1392 if $7 != nil { 1393 x.Where = $7.(ast.ExprNode) 1394 } 1395 if $8 != nil { 1396 x.Order = $8.(*ast.OrderByClause) 1397 } 1398 if $9 != nil { 1399 x.Limit = $9.(*ast.Limit) 1400 } 1401 1402 $$ = x 1403 if yylex.(*lexer).root { 1404 break 1405 } 1406 } 1407 | "DELETE" LowPriorityOptional QuickOptional IgnoreOptional TableNameList "FROM" TableRefs WhereClauseOptional 1408 { 1409 // Multiple Table 1410 x := &ast.DeleteStmt{ 1411 LowPriority: $2.(bool), 1412 Quick: $3.(bool), 1413 Ignore: $4.(bool), 1414 IsMultiTable: true, 1415 BeforeFrom: true, 1416 Tables: &ast.DeleteTableList{Tables: $5.([]*ast.TableName)}, 1417 TableRefs: &ast.TableRefsClause{TableRefs: $7.(*ast.Join)}, 1418 } 1419 if $8 != nil { 1420 x.Where = $8.(ast.ExprNode) 1421 } 1422 $$ = x 1423 if yylex.(*lexer).root { 1424 break 1425 } 1426 } 1427 | "DELETE" LowPriorityOptional QuickOptional IgnoreOptional "FROM" TableNameList "USING" TableRefs WhereClauseOptional 1428 { 1429 // Multiple Table 1430 x := &ast.DeleteStmt{ 1431 LowPriority: $2.(bool), 1432 Quick: $3.(bool), 1433 Ignore: $4.(bool), 1434 IsMultiTable: true, 1435 Tables: &ast.DeleteTableList{Tables: $6.([]*ast.TableName)}, 1436 TableRefs: &ast.TableRefsClause{TableRefs: $8.(*ast.Join)}, 1437 } 1438 if $9 != nil { 1439 x.Where = $9.(ast.ExprNode) 1440 } 1441 $$ = x 1442 if yylex.(*lexer).root { 1443 break 1444 } 1445 } 1446 1447 DatabaseSym: 1448 "DATABASE" | "SCHEMA" 1449 1450 DropDatabaseStmt: 1451 "DROP" DatabaseSym IfExists DBName 1452 { 1453 $$ = &ast.DropDatabaseStmt{IfExists: $3.(bool), Name: $4.(string)} 1454 if yylex.(*lexer).root { 1455 break 1456 } 1457 } 1458 1459 DropIndexStmt: 1460 "DROP" "INDEX" IfExists Identifier "ON" TableName 1461 { 1462 $$ = &ast.DropIndexStmt{IfExists: $3.(bool), IndexName: $4.(string), Table: $6.(*ast.TableName)} 1463 } 1464 1465 DropTableStmt: 1466 "DROP" TableOrTables TableNameList 1467 { 1468 $$ = &ast.DropTableStmt{Tables: $3.([]*ast.TableName)} 1469 if yylex.(*lexer).root { 1470 break 1471 } 1472 } 1473 | "DROP" TableOrTables "IF" "EXISTS" TableNameList 1474 { 1475 $$ = &ast.DropTableStmt{IfExists: true, Tables: $5.([]*ast.TableName)} 1476 if yylex.(*lexer).root { 1477 break 1478 } 1479 } 1480 1481 TableOrTables: 1482 "TABLE" 1483 | "TABLES" 1484 1485 EqOpt: 1486 { 1487 } 1488 | eq 1489 { 1490 } 1491 1492 EmptyStmt: 1493 /* EMPTY */ 1494 { 1495 $$ = nil 1496 } 1497 1498 ExplainSym: 1499 "EXPLAIN" 1500 | "DESCRIBE" 1501 | "DESC" 1502 1503 ExplainStmt: 1504 ExplainSym TableName 1505 { 1506 $$ = &ast.ExplainStmt{ 1507 Stmt: &ast.ShowStmt{ 1508 Tp: ast.ShowColumns, 1509 Table: $2.(*ast.TableName), 1510 }, 1511 } 1512 } 1513 | ExplainSym TableName ColumnName 1514 { 1515 $$ = &ast.ExplainStmt{ 1516 Stmt: &ast.ShowStmt{ 1517 Tp: ast.ShowColumns, 1518 Table: $2.(*ast.TableName), 1519 Column: $3.(*ast.ColumnName), 1520 }, 1521 } 1522 } 1523 | ExplainSym ExplainableStmt 1524 { 1525 $$ = &ast.ExplainStmt{Stmt: $2.(ast.StmtNode)} 1526 } 1527 1528 LengthNum: 1529 NUM 1530 { 1531 switch v := $1.(type) { 1532 case int64: 1533 $$ = uint64(v) 1534 case uint64: 1535 $$ = uint64(v) 1536 } 1537 } 1538 1539 NUM: 1540 intLit 1541 1542 Expression: 1543 "USER_VAR" assignmentEq Expression %prec assignmentEq 1544 { 1545 v := $1.(string) 1546 v = strings.TrimPrefix(v, "@") 1547 $$ = &ast.VariableExpr{ 1548 Name: v, 1549 IsGlobal: false, 1550 IsSystem: false, 1551 Value: $3.(ast.ExprNode), 1552 } 1553 } 1554 | Expression logOr Expression %prec oror 1555 { 1556 $$ = &ast.BinaryOperationExpr{Op: opcode.OrOr, L: $1.(ast.ExprNode), R: $3.(ast.ExprNode)} 1557 } 1558 | Expression "XOR" Expression %prec xor 1559 { 1560 $$ = &ast.BinaryOperationExpr{Op: opcode.LogicXor, L: $1.(ast.ExprNode), R: $3.(ast.ExprNode)} 1561 } 1562 | Expression logAnd Expression %prec andand 1563 { 1564 $$ = &ast.BinaryOperationExpr{Op: opcode.AndAnd, L: $1.(ast.ExprNode), R: $3.(ast.ExprNode)} 1565 } 1566 | "NOT" Expression %prec not 1567 { 1568 $$ = &ast.UnaryOperationExpr{Op: opcode.Not, V: $2.(ast.ExprNode)} 1569 } 1570 | Factor "IS" NotOpt trueKwd %prec is 1571 { 1572 $$ = &ast.IsTruthExpr{Expr:$1.(ast.ExprNode), Not: $3.(bool), True: int64(1)} 1573 } 1574 | Factor "IS" NotOpt falseKwd %prec is 1575 { 1576 $$ = &ast.IsTruthExpr{Expr:$1.(ast.ExprNode), Not: $3.(bool), True: int64(0)} 1577 } 1578 | Factor "IS" NotOpt "UNKNOWN" %prec is 1579 { 1580 /* https://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html#operator_is */ 1581 $$ = &ast.IsNullExpr{Expr: $1.(ast.ExprNode), Not: $3.(bool)} 1582 } 1583 | Factor 1584 1585 1586 logOr: 1587 "||" 1588 { 1589 } 1590 | "OR" 1591 { 1592 } 1593 1594 logAnd: 1595 "&&" 1596 { 1597 } 1598 | "AND" 1599 { 1600 } 1601 1602 name: 1603 Identifier 1604 1605 ExpressionList: 1606 Expression 1607 { 1608 $$ = []ast.ExprNode{$1.(ast.ExprNode)} 1609 } 1610 | ExpressionList ',' Expression 1611 { 1612 $$ = append($1.([]ast.ExprNode), $3.(ast.ExprNode)) 1613 } 1614 1615 ExpressionListOpt: 1616 { 1617 $$ = []ast.ExprNode{} 1618 } 1619 | ExpressionList 1620 1621 Factor: 1622 Factor "IS" NotOpt "NULL" %prec is 1623 { 1624 $$ = &ast.IsNullExpr{Expr: $1.(ast.ExprNode), Not: $3.(bool)} 1625 } 1626 | Factor CompareOp PredicateExpr %prec eq 1627 { 1628 $$ = &ast.BinaryOperationExpr{Op: $2.(opcode.Op), L: $1.(ast.ExprNode), R: $3.(ast.ExprNode)} 1629 } 1630 | Factor CompareOp "USER_VAR" assignmentEq PredicateExpr %prec assignmentEq 1631 { 1632 v := $3.(string) 1633 v = strings.TrimPrefix(v, "@") 1634 variable := &ast.VariableExpr{ 1635 Name: v, 1636 IsGlobal: false, 1637 IsSystem: false, 1638 Value: $5.(ast.ExprNode), 1639 } 1640 $$ = &ast.BinaryOperationExpr{Op: $2.(opcode.Op), L: $1.(ast.ExprNode), R: variable} 1641 } 1642 | Factor CompareOp AnyOrAll SubSelect %prec eq 1643 { 1644 sq := $4.(*ast.SubqueryExpr) 1645 sq.MultiRows = true 1646 $$ = &ast.CompareSubqueryExpr{Op: $2.(opcode.Op), L: $1.(ast.ExprNode), R: sq, All: $3.(bool)} 1647 } 1648 | PredicateExpr 1649 1650 CompareOp: 1651 ">=" 1652 { 1653 $$ = opcode.GE 1654 } 1655 | '>' 1656 { 1657 $$ = opcode.GT 1658 } 1659 | "<=" 1660 { 1661 $$ = opcode.LE 1662 } 1663 | '<' 1664 { 1665 $$ = opcode.LT 1666 } 1667 | "!=" 1668 { 1669 $$ = opcode.NE 1670 } 1671 | "<>" 1672 { 1673 $$ = opcode.NE 1674 } 1675 | "=" 1676 { 1677 $$ = opcode.EQ 1678 } 1679 | "<=>" 1680 { 1681 $$ = opcode.NullEQ 1682 } 1683 1684 AnyOrAll: 1685 "ANY" 1686 { 1687 $$ = false 1688 } 1689 | "SOME" 1690 { 1691 $$ = false 1692 } 1693 | "ALL" 1694 { 1695 $$ = true 1696 } 1697 1698 PredicateExpr: 1699 PrimaryFactor NotOpt "IN" '(' ExpressionList ')' 1700 { 1701 $$ = &ast.PatternInExpr{Expr: $1.(ast.ExprNode), Not: $2.(bool), List: $5.([]ast.ExprNode)} 1702 } 1703 | PrimaryFactor NotOpt "IN" SubSelect 1704 { 1705 sq := $4.(*ast.SubqueryExpr) 1706 sq.MultiRows = true 1707 $$ = &ast.PatternInExpr{Expr: $1.(ast.ExprNode), Not: $2.(bool), Sel: sq} 1708 } 1709 | PrimaryFactor NotOpt "BETWEEN" PrimaryFactor "AND" PredicateExpr 1710 { 1711 $$ = &ast.BetweenExpr{ 1712 Expr: $1.(ast.ExprNode), 1713 Left: $4.(ast.ExprNode), 1714 Right: $6.(ast.ExprNode), 1715 Not: $2.(bool), 1716 } 1717 } 1718 | PrimaryFactor NotOpt "LIKE" PrimaryExpression LikeEscapeOpt 1719 { 1720 escape := $5.(string) 1721 if len(escape) > 1 { 1722 yylex.(*lexer).errf("Incorrect arguments %s to ESCAPE", escape) 1723 return 1 1724 } else if len(escape) == 0 { 1725 escape = "\\" 1726 } 1727 $$ = &ast.PatternLikeExpr{ 1728 Expr: $1.(ast.ExprNode), 1729 Pattern: $4.(ast.ExprNode), 1730 Not: $2.(bool), 1731 Escape: escape[0], 1732 } 1733 } 1734 | PrimaryFactor NotOpt RegexpSym PrimaryExpression 1735 { 1736 $$ = &ast.PatternRegexpExpr{Expr: $1.(ast.ExprNode), Pattern: $4.(ast.ExprNode), Not: $2.(bool)} 1737 } 1738 | PrimaryFactor 1739 1740 RegexpSym: 1741 "REGEXP" 1742 | "RLIKE" 1743 1744 LikeEscapeOpt: 1745 %prec lowerThanEscape 1746 { 1747 $$ = "\\" 1748 } 1749 | "ESCAPE" stringLit 1750 { 1751 $$ = $2 1752 } 1753 1754 NotOpt: 1755 { 1756 $$ = false 1757 } 1758 | "NOT" 1759 { 1760 $$ = true 1761 } 1762 1763 Field: 1764 '*' 1765 { 1766 $$ = &ast.SelectField{WildCard: &ast.WildCardField{}} 1767 } 1768 | Identifier '.' '*' 1769 { 1770 wildCard := &ast.WildCardField{Table: model.NewCIStr($1.(string))} 1771 $$ = &ast.SelectField{WildCard: wildCard} 1772 } 1773 | Identifier '.' Identifier '.' '*' 1774 { 1775 wildCard := &ast.WildCardField{Schema: model.NewCIStr($1.(string)), Table: model.NewCIStr($3.(string))} 1776 $$ = &ast.SelectField{WildCard: wildCard} 1777 } 1778 | Expression FieldAsNameOpt 1779 { 1780 expr := $1.(ast.ExprNode) 1781 asName := $2.(string) 1782 $$ = &ast.SelectField{Expr: expr, AsName: model.NewCIStr(asName)} 1783 } 1784 1785 FieldAsNameOpt: 1786 /* EMPTY */ 1787 { 1788 $$ = "" 1789 } 1790 | FieldAsName 1791 { 1792 $$ = $1 1793 } 1794 1795 FieldAsName: 1796 Identifier 1797 { 1798 $$ = $1 1799 } 1800 | "AS" Identifier 1801 { 1802 $$ = $2 1803 } 1804 | stringLit 1805 { 1806 $$ = $1 1807 } 1808 | "AS" stringLit 1809 { 1810 $$ = $2 1811 } 1812 1813 FieldList: 1814 Field 1815 { 1816 field := $1.(*ast.SelectField) 1817 field.Offset = yylex.(*lexer).startOffset(yyS[yypt].offset) 1818 $$ = []*ast.SelectField{field} 1819 } 1820 | FieldList ',' Field 1821 { 1822 1823 fl := $1.([]*ast.SelectField) 1824 last := fl[len(fl)-1] 1825 l := yylex.(*lexer) 1826 if last.Expr != nil && last.AsName.O == "" { 1827 lastEnd := l.endOffset(yyS[yypt-1].offset) 1828 last.SetText(l.src[last.Offset:lastEnd]) 1829 } 1830 newField := $3.(*ast.SelectField) 1831 newField.Offset = l.startOffset(yyS[yypt].offset) 1832 $$ = append(fl, newField) 1833 } 1834 1835 GroupByClause: 1836 "GROUP" "BY" ByList 1837 { 1838 $$ = &ast.GroupByClause{Items: $3.([]*ast.ByItem)} 1839 } 1840 1841 HavingClause: 1842 { 1843 $$ = nil 1844 } 1845 | "HAVING" Expression 1846 { 1847 $$ = &ast.HavingClause{Expr: $2.(ast.ExprNode)} 1848 } 1849 1850 IfExists: 1851 { 1852 $$ = false 1853 } 1854 | "IF" "EXISTS" 1855 { 1856 $$ = true 1857 } 1858 1859 IfNotExists: 1860 { 1861 $$ = false 1862 } 1863 | "IF" "NOT" "EXISTS" 1864 { 1865 $$ = true 1866 } 1867 1868 1869 IgnoreOptional: 1870 { 1871 $$ = false 1872 } 1873 | "IGNORE" 1874 { 1875 $$ = true 1876 } 1877 1878 IndexName: 1879 { 1880 $$ = "" 1881 } 1882 | Identifier 1883 { 1884 //"index name" 1885 $$ = $1.(string) 1886 } 1887 1888 IndexOption: 1889 { 1890 $$ = nil 1891 } 1892 | "KEY_BLOCK_SIZE" EqOpt LengthNum 1893 { 1894 $$ = &ast.IndexOption{ 1895 KeyBlockSize: $1.(uint64), 1896 } 1897 } 1898 | IndexType 1899 { 1900 $$ = &ast.IndexOption { 1901 Tp: $1.(model.IndexType), 1902 } 1903 } 1904 | "COMMENT" stringLit 1905 { 1906 $$ = &ast.IndexOption { 1907 Comment: $2.(string), 1908 } 1909 } 1910 1911 IndexType: 1912 "USING" "BTREE" 1913 { 1914 $$ = model.IndexTypeBtree 1915 } 1916 | "USING" "HASH" 1917 { 1918 $$ = model.IndexTypeHash 1919 } 1920 1921 IndexTypeOpt: 1922 { 1923 $$ = nil 1924 } 1925 | IndexType 1926 { 1927 $$ = $1 1928 } 1929 1930 /**********************************Identifier********************************************/ 1931 Identifier: 1932 identifier | UnReservedKeyword | NotKeywordToken 1933 1934 UnReservedKeyword: 1935 "ASCII" | "AUTO_INCREMENT" | "AFTER" | "AVG" | "BEGIN" | "BIT" | "BOOL" | "BOOLEAN" | "BTREE" | "CHARSET" | "COLUMNS" | "COMMIT" | "COMPACT" | "COMPRESSED" 1936 | "DATE" | "DATETIME" | "DEALLOCATE" | "DO" | "DYNAMIC" | "END" | "ENGINE" | "ENGINES" | "EXECUTE" | "FIRST" | "FIXED" | "FULL" | "HASH" 1937 | "LOCAL" | "NAMES" | "OFFSET" | "PASSWORD" %prec lowerThanEq | "PREPARE" | "QUICK" | "REDUNDANT" | "ROLLBACK" | "SESSION" | "SIGNED" 1938 | "START" | "STATUS" | "GLOBAL" | "TABLES"| "TEXT" | "TIME" | "TIMESTAMP" | "TRANSACTION" | "TRUNCATE" | "UNKNOWN" 1939 | "VALUE" | "WARNINGS" | "YEAR" | "MODE" | "WEEK" | "ANY" | "SOME" | "USER" | "IDENTIFIED" | "COLLATION" 1940 | "COMMENT" | "AVG_ROW_LENGTH" | "CONNECTION" | "CHECKSUM" | "COMPRESSION" | "KEY_BLOCK_SIZE" | "MAX_ROWS" | "MIN_ROWS" 1941 | "NATIONAL" | "ROW" | "ROW_FORMAT" | "QUARTER" | "ESCAPE" | "GRANTS" | "FIELDS" | "TRIGGERS" | "DELAY_KEY_WRITE" | "ISOLATION" 1942 | "REPEATABLE" | "COMMITTED" | "UNCOMMITTED" | "ONLY" | "SERIALIZABLE" | "LEVEL" | "VARIABLES" | "SQL_CACHE" | "SQL_NO_CACHE" | "ACTION" | "DISABLE" | "ENABLE" | "REVERSE" 1943 1944 NotKeywordToken: 1945 "ABS" | "ADDDATE" | "ADMIN" | "COALESCE" | "CONCAT" | "CONCAT_WS" | "CONNECTION_ID" | "CUR_TIME"| "COUNT" | "DAY" 1946 | "DATE_ADD" | "DATE_SUB" | "DAYNAME" | "DAYOFMONTH" | "DAYOFWEEK" | "DAYOFYEAR" | "FOUND_ROWS" | "GROUP_CONCAT"| "HOUR" 1947 | "IFNULL" | "ISNULL" | "LCASE" | "LENGTH" | "LOCATE" | "LOWER" | "LTRIM" | "MAX" | "MICROSECOND" | "MIN" | "MINUTE" | "NULLIF" | "MONTH" | "NOW" | "POW" 1948 | "POWER" | "RAND" | "SECOND" | "SQL_CALC_FOUND_ROWS" | "SUBDATE" | "SUBSTRING" %prec lowerThanLeftParen 1949 | "SUBSTRING_INDEX" | "SUM" | "TRIM" | "RTRIM" | "UCASE" | "UPPER" | "VERSION" | "WEEKDAY" | "WEEKOFYEAR" | "YEARWEEK" | "ROUND" 1950 1951 /************************************************************************************ 1952 * 1953 * Insert Statements 1954 * 1955 * TODO: support PARTITION 1956 **********************************************************************************/ 1957 InsertIntoStmt: 1958 "INSERT" Priority IgnoreOptional IntoOpt TableName InsertValues OnDuplicateKeyUpdate 1959 { 1960 x := $6.(*ast.InsertStmt) 1961 x.Priority = $2.(int) 1962 // Wraps many layers here so that it can be processed the same way as select statement. 1963 ts := &ast.TableSource{Source: $5.(*ast.TableName)} 1964 x.Table = &ast.TableRefsClause{TableRefs: &ast.Join{Left: ts}} 1965 if $7 != nil { 1966 x.OnDuplicate = $7.([]*ast.Assignment) 1967 } 1968 $$ = x 1969 if yylex.(*lexer).root { 1970 break 1971 } 1972 } 1973 1974 IntoOpt: 1975 { 1976 } 1977 | "INTO" 1978 { 1979 } 1980 1981 InsertValues: 1982 '(' ColumnNameListOpt ')' ValueSym ExpressionListList 1983 { 1984 $$ = &ast.InsertStmt{ 1985 Columns: $2.([]*ast.ColumnName), 1986 Lists: $5.([][]ast.ExprNode), 1987 } 1988 } 1989 | '(' ColumnNameListOpt ')' SelectStmt 1990 { 1991 $$ = &ast.InsertStmt{Columns: $2.([]*ast.ColumnName), Select: $4.(*ast.SelectStmt)} 1992 } 1993 | '(' ColumnNameListOpt ')' UnionStmt 1994 { 1995 $$ = &ast.InsertStmt{Columns: $2.([]*ast.ColumnName), Select: $4.(*ast.UnionStmt)} 1996 } 1997 | ValueSym ExpressionListList %prec insertValues 1998 { 1999 $$ = &ast.InsertStmt{Lists: $2.([][]ast.ExprNode)} 2000 } 2001 | SelectStmt 2002 { 2003 $$ = &ast.InsertStmt{Select: $1.(*ast.SelectStmt)} 2004 } 2005 | UnionStmt 2006 { 2007 $$ = &ast.InsertStmt{Select: $1.(*ast.UnionStmt)} 2008 } 2009 | "SET" ColumnSetValueList 2010 { 2011 $$ = &ast.InsertStmt{Setlist: $2.([]*ast.Assignment)} 2012 } 2013 2014 ValueSym: 2015 "VALUE" 2016 | "VALUES" 2017 2018 ExpressionListList: 2019 '(' ')' 2020 { 2021 $$ = [][]ast.ExprNode{[]ast.ExprNode{}} 2022 } 2023 | '(' ')' ',' ExpressionListList 2024 { 2025 $$ = append([][]ast.ExprNode{[]ast.ExprNode{}}, $4.([][]ast.ExprNode)...) 2026 } 2027 | '(' ExpressionList ')' 2028 { 2029 $$ = [][]ast.ExprNode{$2.([]ast.ExprNode)} 2030 } 2031 | '(' ExpressionList ')' ',' ExpressionListList 2032 { 2033 $$ = append([][]ast.ExprNode{$2.([]ast.ExprNode)}, $5.([][]ast.ExprNode)...) 2034 } 2035 2036 ColumnSetValue: 2037 ColumnName eq Expression 2038 { 2039 $$ = &ast.Assignment{ 2040 Column: $1.(*ast.ColumnName), 2041 Expr: $3.(ast.ExprNode), 2042 } 2043 } 2044 2045 ColumnSetValueList: 2046 { 2047 $$ = []*ast.Assignment{} 2048 } 2049 | ColumnSetValue 2050 { 2051 $$ = []*ast.Assignment{$1.(*ast.Assignment)} 2052 } 2053 | ColumnSetValueList ',' ColumnSetValue 2054 { 2055 $$ = append($1.([]*ast.Assignment), $3.(*ast.Assignment)) 2056 } 2057 2058 /* 2059 * ON DUPLICATE KEY UPDATE col_name=expr [, col_name=expr] ... 2060 * See: https://dev.mysql.com/doc/refman/5.7/en/insert-on-duplicate.html 2061 */ 2062 OnDuplicateKeyUpdate: 2063 { 2064 $$ = nil 2065 } 2066 | "ON" "DUPLICATE" "KEY" "UPDATE" AssignmentList 2067 { 2068 $$ = $5 2069 } 2070 2071 /***********************************Insert Statements END************************************/ 2072 2073 /************************************************************************************ 2074 * Replace Statements 2075 * See: https://dev.mysql.com/doc/refman/5.7/en/replace.html 2076 * 2077 * TODO: support PARTITION 2078 **********************************************************************************/ 2079 ReplaceIntoStmt: 2080 "REPLACE" ReplacePriority IntoOpt TableName InsertValues 2081 { 2082 x := $5.(*ast.InsertStmt) 2083 x.IsReplace = true 2084 x.Priority = $2.(int) 2085 ts := &ast.TableSource{Source: $4.(*ast.TableName)} 2086 x.Table = &ast.TableRefsClause{TableRefs: &ast.Join{Left: ts}} 2087 $$ = x 2088 } 2089 2090 ReplacePriority: 2091 { 2092 $$ = ast.NoPriority 2093 } 2094 | "LOW_PRIORITY" 2095 { 2096 $$ = ast.LowPriority 2097 } 2098 | "DELAYED" 2099 { 2100 $$ = ast.DelayedPriority 2101 } 2102 2103 /***********************************Replace Statements END************************************/ 2104 2105 Literal: 2106 "false" 2107 { 2108 $$ = int64(0) 2109 } 2110 | "NULL" 2111 | "true" 2112 { 2113 $$ = int64(1) 2114 } 2115 | floatLit 2116 | intLit 2117 | stringLit 2118 { 2119 tp := types.NewFieldType(mysql.TypeString) 2120 l := yylex.(*lexer) 2121 tp.Charset, tp.Collate = l.GetCharsetInfo() 2122 expr := ast.NewValueExpr($1) 2123 expr.SetType(tp) 2124 $$ = expr 2125 } 2126 | "UNDERSCORE_CHARSET" stringLit 2127 { 2128 // See: https://dev.mysql.com/doc/refman/5.7/en/charset-literal.html 2129 tp := types.NewFieldType(mysql.TypeString) 2130 tp.Charset = $1.(string) 2131 co, err := charset.GetDefaultCollation(tp.Charset) 2132 if err != nil { 2133 l := yylex.(*lexer) 2134 l.errf("Get collation error for charset: %s", tp.Charset) 2135 return 1 2136 } 2137 tp.Collate = co 2138 expr := ast.NewValueExpr($2) 2139 expr.SetType(tp) 2140 $$ = expr 2141 } 2142 | hexLit 2143 | bitLit 2144 2145 Operand: 2146 Literal 2147 { 2148 $$ = ast.NewValueExpr($1) 2149 } 2150 | ColumnName 2151 { 2152 $$ = &ast.ColumnNameExpr{Name: $1.(*ast.ColumnName)} 2153 } 2154 | '(' Expression ')' 2155 { 2156 l := yylex.(*lexer) 2157 startOffset := l.startOffset(yyS[yypt-1].offset) 2158 endOffset := l.endOffset(yyS[yypt].offset) 2159 expr := $2.(ast.ExprNode) 2160 expr.SetText(l.src[startOffset:endOffset]) 2161 $$ = &ast.ParenthesesExpr{Expr: expr} 2162 } 2163 | "DEFAULT" %prec lowerThanLeftParen 2164 { 2165 $$ = &ast.DefaultExpr{} 2166 } 2167 | "DEFAULT" '(' ColumnName ')' 2168 { 2169 $$ = &ast.DefaultExpr{Name: $3.(*ast.ColumnName)} 2170 } 2171 | Variable 2172 { 2173 $$ = $1 2174 } 2175 | "PLACEHOLDER" 2176 { 2177 $$ = &ast.ParamMarkerExpr{ 2178 Offset: yyS[yypt].offset, 2179 } 2180 } 2181 | "ROW" '(' Expression ',' ExpressionList ')' 2182 { 2183 values := append([]ast.ExprNode{$3.(ast.ExprNode)}, $5.([]ast.ExprNode)...) 2184 $$ = &ast.RowExpr{Values: values} 2185 } 2186 | '(' Expression ',' ExpressionList ')' 2187 { 2188 values := append([]ast.ExprNode{$2.(ast.ExprNode)}, $4.([]ast.ExprNode)...) 2189 $$ = &ast.RowExpr{Values: values} 2190 } 2191 | "EXISTS" SubSelect 2192 { 2193 sq := $2.(*ast.SubqueryExpr) 2194 sq.Exists = true 2195 $$ = &ast.ExistsSubqueryExpr{Sel: sq} 2196 } 2197 2198 OrderBy: 2199 "ORDER" "BY" ByList 2200 { 2201 $$ = &ast.OrderByClause{Items: $3.([]*ast.ByItem)} 2202 } 2203 2204 ByList: 2205 ByItem 2206 { 2207 $$ = []*ast.ByItem{$1.(*ast.ByItem)} 2208 } 2209 | ByList ',' ByItem 2210 { 2211 $$ = append($1.([]*ast.ByItem), $3.(*ast.ByItem)) 2212 } 2213 2214 ByItem: 2215 Expression Order 2216 { 2217 expr := $1 2218 valueExpr, ok := expr.(*ast.ValueExpr) 2219 if ok { 2220 position, isPosition := valueExpr.GetValue().(int64) 2221 if isPosition { 2222 expr = &ast.PositionExpr{N: int(position)} 2223 } 2224 } 2225 $$ = &ast.ByItem{Expr: expr.(ast.ExprNode), Desc: $2.(bool)} 2226 } 2227 2228 Order: 2229 /* EMPTY */ 2230 { 2231 $$ = false // ASC by default 2232 } 2233 | "ASC" 2234 { 2235 $$ = false 2236 } 2237 | "DESC" 2238 { 2239 $$ = true 2240 } 2241 2242 OrderByOptional: 2243 { 2244 $$ = nil 2245 } 2246 | OrderBy 2247 { 2248 $$ = $1 2249 } 2250 2251 PrimaryExpression: 2252 Operand 2253 | Function 2254 | SubSelect 2255 | '!' PrimaryExpression %prec neg 2256 { 2257 $$ = &ast.UnaryOperationExpr{Op: opcode.Not, V: $2.(ast.ExprNode)} 2258 } 2259 | '~' PrimaryExpression %prec neg 2260 { 2261 $$ = &ast.UnaryOperationExpr{Op: opcode.BitNeg, V: $2.(ast.ExprNode)} 2262 } 2263 | '-' PrimaryExpression %prec neg 2264 { 2265 $$ = &ast.UnaryOperationExpr{Op: opcode.Minus, V: $2.(ast.ExprNode)} 2266 } 2267 | '+' PrimaryExpression %prec neg 2268 { 2269 $$ = &ast.UnaryOperationExpr{Op: opcode.Plus, V: $2.(ast.ExprNode)} 2270 } 2271 | "BINARY" PrimaryExpression %prec neg 2272 { 2273 // See: https://dev.mysql.com/doc/refman/5.7/en/cast-functions.html#operator_binary 2274 x := types.NewFieldType(mysql.TypeString) 2275 x.Charset = charset.CharsetBin 2276 x.Collate = charset.CharsetBin 2277 $$ = &ast.FuncCastExpr{ 2278 Expr: $2.(ast.ExprNode), 2279 Tp: x, 2280 FunctionType: ast.CastBinaryOperator, 2281 } 2282 } 2283 | PrimaryExpression "COLLATE" StringName %prec neg 2284 { 2285 // TODO: Create a builtin function hold expr and collation. When do evaluation, convert expr result using the collation. 2286 $$ = $1 2287 } 2288 2289 Function: 2290 FunctionCallKeyword 2291 | FunctionCallNonKeyword 2292 | FunctionCallConflict 2293 | FunctionCallAgg 2294 2295 FunctionNameConflict: 2296 "DATABASE" | "SCHEMA" | "IF" | "LEFT" | "REPEAT" | "CURRENT_USER" | "CURRENT_DATE" | "VERSION" | "UTC_DATE" 2297 2298 FunctionCallConflict: 2299 FunctionNameConflict '(' ExpressionListOpt ')' 2300 { 2301 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: $3.([]ast.ExprNode)} 2302 } 2303 | "CURRENT_USER" 2304 { 2305 // See: https://dev.mysql.com/doc/refman/5.7/en/information-functions.html#function_current-user 2306 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string))} 2307 } 2308 | "CURRENT_DATE" 2309 { 2310 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string))} 2311 } 2312 | "UTC_DATE" 2313 { 2314 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string))} 2315 } 2316 | "MOD" '(' PrimaryFactor ',' PrimaryFactor ')' 2317 { 2318 $$ = &ast.BinaryOperationExpr{Op: opcode.Mod, L: $3.(ast.ExprNode), R: $5.(ast.ExprNode)} 2319 } 2320 2321 DistinctOpt: 2322 { 2323 $$ = false 2324 } 2325 | "ALL" 2326 { 2327 $$ = false 2328 } 2329 | "DISTINCT" 2330 { 2331 $$ = true 2332 } 2333 | "DISTINCT" "ALL" 2334 { 2335 $$ = true 2336 } 2337 2338 FunctionCallKeyword: 2339 "CAST" '(' Expression "AS" CastType ')' 2340 { 2341 /* See: https://dev.mysql.com/doc/refman/5.7/en/cast-functions.html#function_cast */ 2342 $$ = &ast.FuncCastExpr{ 2343 Expr: $3.(ast.ExprNode), 2344 Tp: $5.(*types.FieldType), 2345 FunctionType: ast.CastFunction, 2346 } 2347 } 2348 | "CASE" ExpressionOpt WhenClauseList ElseOpt "END" 2349 { 2350 x := &ast.CaseExpr{WhenClauses: $3.([]*ast.WhenClause)} 2351 if $2 != nil { 2352 x.Value = $2.(ast.ExprNode) 2353 } 2354 if $4 != nil { 2355 x.ElseClause = $4.(ast.ExprNode) 2356 } 2357 $$ = x 2358 } 2359 | "CONVERT" '(' Expression "USING" StringName ')' 2360 { 2361 // See: https://dev.mysql.com/doc/refman/5.7/en/cast-functions.html#function_convert 2362 charset := ast.NewValueExpr($5) 2363 $$ = &ast.FuncCallExpr{ 2364 FnName: model.NewCIStr($1.(string)), 2365 Args: []ast.ExprNode{$3.(ast.ExprNode), charset}, 2366 } 2367 } 2368 | "CONVERT" '(' Expression ',' CastType ')' 2369 { 2370 // See: https://dev.mysql.com/doc/refman/5.7/en/cast-functions.html#function_convert 2371 $$ = &ast.FuncCastExpr{ 2372 Expr: $3.(ast.ExprNode), 2373 Tp: $5.(*types.FieldType), 2374 FunctionType: ast.CastConvertFunction, 2375 } 2376 } 2377 | "ASCII" '(' Expression ')' 2378 { 2379 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}} 2380 } 2381 | "DATE" '(' Expression ')' 2382 { 2383 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}} 2384 } 2385 | "USER" '(' ')' 2386 { 2387 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string))} 2388 } 2389 | "VALUES" '(' ColumnName ')' %prec lowerThanInsertValues 2390 { 2391 // TODO: support qualified identifier for column_name 2392 $$ = &ast.ValuesExpr{Column: &ast.ColumnNameExpr{Name: $3.(*ast.ColumnName)}} 2393 } 2394 | "WEEK" '(' ExpressionList ')' 2395 { 2396 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: $3.([]ast.ExprNode)} 2397 } 2398 | "YEAR" '(' Expression ')' 2399 { 2400 $$ = &ast.FuncCallExpr{FnName:model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}} 2401 } 2402 2403 FunctionCallNonKeyword: 2404 "COALESCE" '(' ExpressionList ')' 2405 { 2406 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: $3.([]ast.ExprNode)} 2407 } 2408 | "CURDATE" '(' ')' 2409 { 2410 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string))} 2411 } 2412 | "CUR_TIME" '(' ExpressionOpt ')' 2413 { 2414 args := []ast.ExprNode{} 2415 if $3 != nil { 2416 args = append(args, $3.(ast.ExprNode)) 2417 } 2418 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: args} 2419 } 2420 | "CURRENT_TIME" FuncDatetimePrec 2421 { 2422 args := []ast.ExprNode{} 2423 if $2 != nil { 2424 args = append(args, $2.(ast.ExprNode)) 2425 } 2426 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: args} 2427 } 2428 | "CURRENT_TIMESTAMP" FuncDatetimePrec 2429 { 2430 args := []ast.ExprNode{} 2431 if $2 != nil { 2432 args = append(args, $2.(ast.ExprNode)) 2433 } 2434 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: args} 2435 } 2436 | "ABS" '(' Expression ')' 2437 { 2438 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}} 2439 } 2440 | "CONCAT" '(' ExpressionList ')' 2441 { 2442 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: $3.([]ast.ExprNode)} 2443 } 2444 | "CONCAT_WS" '(' ExpressionList ')' 2445 { 2446 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: $3.([]ast.ExprNode)} 2447 } 2448 | "DAY" '(' Expression ')' 2449 { 2450 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}} 2451 } 2452 | "DAYNAME" '(' Expression ')' 2453 { 2454 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}} 2455 } 2456 | "DAYOFWEEK" '(' Expression ')' 2457 { 2458 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}} 2459 } 2460 | "DAYOFMONTH" '(' Expression ')' 2461 { 2462 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}} 2463 } 2464 | "DAYOFYEAR" '(' Expression ')' 2465 { 2466 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}} 2467 } 2468 | DateArithOpt '(' Expression ',' "INTERVAL" Expression TimeUnit ')' 2469 { 2470 op := ast.NewValueExpr($1) 2471 dateArithInterval := ast.NewValueExpr( 2472 ast.DateArithInterval{ 2473 Unit: $7.(string), 2474 Interval: $6.(ast.ExprNode), 2475 }, 2476 ) 2477 2478 $$ = &ast.FuncCallExpr{ 2479 FnName: model.NewCIStr("DATE_ARITH"), 2480 Args: []ast.ExprNode{ 2481 op, 2482 $3.(ast.ExprNode), 2483 dateArithInterval, 2484 }, 2485 } 2486 } 2487 | DateArithMultiFormsOpt '(' Expression ',' DateArithInterval')' 2488 { 2489 op := ast.NewValueExpr($1) 2490 dateArithInterval := ast.NewValueExpr($5) 2491 $$ = &ast.FuncCallExpr{ 2492 FnName: model.NewCIStr("DATE_ARITH"), 2493 Args: []ast.ExprNode{ 2494 op, 2495 $3.(ast.ExprNode), 2496 dateArithInterval, 2497 }, 2498 } 2499 } 2500 | "EXTRACT" '(' TimeUnit "FROM" Expression ')' 2501 { 2502 timeUnit := ast.NewValueExpr($3) 2503 $$ = &ast.FuncCallExpr{ 2504 FnName: model.NewCIStr($1.(string)), 2505 Args: []ast.ExprNode{timeUnit, $5.(ast.ExprNode)}, 2506 } 2507 } 2508 | "FOUND_ROWS" '(' ')' 2509 { 2510 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string))} 2511 } 2512 | "HOUR" '(' Expression ')' 2513 { 2514 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}} 2515 } 2516 | "IFNULL" '(' ExpressionList ')' 2517 { 2518 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: $3.([]ast.ExprNode)} 2519 } 2520 | "ISNULL" '(' Expression ')' 2521 { 2522 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}} 2523 } 2524 | "LENGTH" '(' Expression ')' 2525 { 2526 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}} 2527 } 2528 | "LOCATE" '(' Expression ',' Expression ')' 2529 { 2530 $$ = &ast.FuncCallExpr{ 2531 FnName: model.NewCIStr($1.(string)), 2532 Args: []ast.ExprNode{$3.(ast.ExprNode), $5.(ast.ExprNode)}, 2533 } 2534 } 2535 | "LOCATE" '(' Expression ',' Expression ',' Expression ')' 2536 { 2537 $$ = &ast.FuncCallExpr{ 2538 FnName: model.NewCIStr($1.(string)), 2539 Args: []ast.ExprNode{$3.(ast.ExprNode), $5.(ast.ExprNode), $7.(ast.ExprNode)}, 2540 } 2541 } 2542 | "LOWER" '(' Expression ')' 2543 { 2544 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}} 2545 } 2546 | "LCASE" '(' Expression ')' 2547 { 2548 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}} 2549 } 2550 | "LTRIM" '(' Expression ')' 2551 { 2552 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}} 2553 } 2554 | "MICROSECOND" '(' Expression ')' 2555 { 2556 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}} 2557 } 2558 | "MINUTE" '(' Expression ')' 2559 { 2560 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}} 2561 } 2562 | "MONTH" '(' Expression ')' 2563 { 2564 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}} 2565 } 2566 | "NOW" '(' ExpressionOpt ')' 2567 { 2568 args := []ast.ExprNode{} 2569 if $3 != nil { 2570 args = append(args, $3.(ast.ExprNode)) 2571 } 2572 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: args} 2573 } 2574 | "NULLIF" '(' ExpressionList ')' 2575 { 2576 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: $3.([]ast.ExprNode)} 2577 } 2578 | "POW" '(' Expression ',' Expression ')' 2579 { 2580 args := []ast.ExprNode{$3.(ast.ExprNode), $5.(ast.ExprNode)} 2581 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: args} 2582 } 2583 | "POWER" '(' Expression ',' Expression ')' 2584 { 2585 args := []ast.ExprNode{$3.(ast.ExprNode), $5.(ast.ExprNode)} 2586 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: args} 2587 } 2588 | "RAND" '(' ExpressionOpt ')' 2589 { 2590 2591 args := []ast.ExprNode{} 2592 if $3 != nil { 2593 args = append(args, $3.(ast.ExprNode)) 2594 } 2595 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: args} 2596 } 2597 | "REPLACE" '(' Expression ',' Expression ',' Expression ')' 2598 { 2599 args := []ast.ExprNode{$3.(ast.ExprNode), $5.(ast.ExprNode), $7.(ast.ExprNode)} 2600 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: args} 2601 } 2602 | "REVERSE" '(' Expression ')' 2603 { 2604 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}} 2605 } 2606 | "RTRIM" '(' Expression ')' 2607 { 2608 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}} 2609 } 2610 | "SECOND" '(' Expression ')' 2611 { 2612 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}} 2613 } 2614 | "STRCMP" '(' Expression ',' Expression ')' 2615 { 2616 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode), $5.(ast.ExprNode)}} 2617 } 2618 | "SUBSTRING" '(' Expression ',' Expression ')' 2619 { 2620 $$ = &ast.FuncCallExpr{ 2621 FnName: model.NewCIStr($1.(string)), 2622 Args: []ast.ExprNode{$3.(ast.ExprNode), $5.(ast.ExprNode)}, 2623 } 2624 } 2625 | "SUBSTRING" '(' Expression "FROM" Expression ')' 2626 { 2627 $$ = &ast.FuncCallExpr{ 2628 FnName: model.NewCIStr($1.(string)), 2629 Args: []ast.ExprNode{$3.(ast.ExprNode), $5.(ast.ExprNode)}, 2630 } 2631 } 2632 | "SUBSTRING" '(' Expression ',' Expression ',' Expression ')' 2633 { 2634 $$ = &ast.FuncCallExpr{ 2635 FnName: model.NewCIStr($1.(string)), 2636 Args: []ast.ExprNode{$3.(ast.ExprNode), $5.(ast.ExprNode), $7.(ast.ExprNode)}, 2637 } 2638 } 2639 | "SUBSTRING" '(' Expression "FROM" Expression "FOR" Expression ')' 2640 { 2641 $$ = &ast.FuncCallExpr{ 2642 FnName: model.NewCIStr($1.(string)), 2643 Args: []ast.ExprNode{$3.(ast.ExprNode), $5.(ast.ExprNode), $7.(ast.ExprNode)}, 2644 } 2645 } 2646 | "SUBSTRING_INDEX" '(' Expression ',' Expression ',' Expression ')' 2647 { 2648 $$ = &ast.FuncCallExpr{ 2649 FnName: model.NewCIStr($1.(string)), 2650 Args: []ast.ExprNode{$3.(ast.ExprNode), $5.(ast.ExprNode), $7.(ast.ExprNode)}, 2651 } 2652 } 2653 | "SYSDATE" '(' ExpressionOpt ')' 2654 { 2655 args := []ast.ExprNode{} 2656 if $3 != nil { 2657 args = append(args, $3.(ast.ExprNode)) 2658 } 2659 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: args} 2660 } 2661 | "TRIM" '(' Expression ')' 2662 { 2663 $$ = &ast.FuncCallExpr{ 2664 FnName: model.NewCIStr($1.(string)), 2665 Args: []ast.ExprNode{$3.(ast.ExprNode)}, 2666 } 2667 } 2668 | "TRIM" '(' Expression "FROM" Expression ')' 2669 { 2670 $$ = &ast.FuncCallExpr{ 2671 FnName: model.NewCIStr($1.(string)), 2672 Args: []ast.ExprNode{$5.(ast.ExprNode), $3.(ast.ExprNode)}, 2673 } 2674 } 2675 | "TRIM" '(' TrimDirection "FROM" Expression ')' 2676 { 2677 nilVal := ast.NewValueExpr(nil) 2678 direction := ast.NewValueExpr($3) 2679 $$ = &ast.FuncCallExpr{ 2680 FnName: model.NewCIStr($1.(string)), 2681 Args: []ast.ExprNode{$5.(ast.ExprNode), nilVal, direction}, 2682 } 2683 } 2684 | "TRIM" '(' TrimDirection Expression "FROM" Expression ')' 2685 { 2686 direction := ast.NewValueExpr($3) 2687 $$ = &ast.FuncCallExpr{ 2688 FnName: model.NewCIStr($1.(string)), 2689 Args: []ast.ExprNode{$6.(ast.ExprNode),$4.(ast.ExprNode), direction}, 2690 } 2691 } 2692 | "UPPER" '(' Expression ')' 2693 { 2694 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}} 2695 } 2696 | "UCASE" '(' Expression ')' 2697 { 2698 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}} 2699 } 2700 | "WEEKDAY" '(' Expression ')' 2701 { 2702 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}} 2703 } 2704 | "WEEKOFYEAR" '(' Expression ')' 2705 { 2706 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}} 2707 } 2708 | "YEARWEEK" '(' ExpressionList ')' 2709 { 2710 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: $3.([]ast.ExprNode)} 2711 } 2712 | "CONNECTION_ID" '(' ')' 2713 { 2714 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string))} 2715 } 2716 | "ROUND" '(' ExpressionList ')' 2717 { 2718 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: $3.([]ast.ExprNode)} 2719 } 2720 2721 DateArithOpt: 2722 "DATE_ADD" 2723 { 2724 $$ = ast.DateAdd 2725 } 2726 | "DATE_SUB" 2727 { 2728 $$ = ast.DateSub 2729 } 2730 2731 DateArithMultiFormsOpt: 2732 "ADDDATE" 2733 { 2734 $$ = ast.DateAdd 2735 } 2736 | "SUBDATE" 2737 { 2738 $$ = ast.DateSub 2739 } 2740 2741 DateArithInterval: 2742 Expression 2743 { 2744 $$ = ast.DateArithInterval{ 2745 Unit: "day", 2746 Interval: $1.(ast.ExprNode), 2747 } 2748 } 2749 | "INTERVAL" Expression TimeUnit 2750 { 2751 $$ = ast.DateArithInterval{Unit: $3.(string), Interval: $2.(ast.ExprNode)} 2752 } 2753 2754 TrimDirection: 2755 "BOTH" 2756 { 2757 $$ = ast.TrimBoth 2758 } 2759 | "LEADING" 2760 { 2761 $$ = ast.TrimLeading 2762 } 2763 | "TRAILING" 2764 { 2765 $$ = ast.TrimTrailing 2766 } 2767 2768 FunctionCallAgg: 2769 "AVG" '(' DistinctOpt ExpressionList ')' 2770 { 2771 $$ = &ast.AggregateFuncExpr{F: $1.(string), Args: $4.([]ast.ExprNode), Distinct: $3.(bool)} 2772 } 2773 | "COUNT" '(' DistinctOpt ExpressionList ')' 2774 { 2775 $$ = &ast.AggregateFuncExpr{F: $1.(string), Args: $4.([]ast.ExprNode), Distinct: $3.(bool)} 2776 } 2777 | "COUNT" '(' DistinctOpt '*' ')' 2778 { 2779 args := []ast.ExprNode{ast.NewValueExpr(ast.UnquoteString("*"))} 2780 $$ = &ast.AggregateFuncExpr{F: $1.(string), Args: args, Distinct: $3.(bool)} 2781 } 2782 | "GROUP_CONCAT" '(' DistinctOpt ExpressionList ')' 2783 { 2784 $$ = &ast.AggregateFuncExpr{F: $1.(string), Args: $4.([]ast.ExprNode), Distinct: $3.(bool)} 2785 } 2786 | "MAX" '(' DistinctOpt Expression ')' 2787 { 2788 $$ = &ast.AggregateFuncExpr{F: $1.(string), Args: []ast.ExprNode{$4.(ast.ExprNode)}, Distinct: $3.(bool)} 2789 } 2790 | "MIN" '(' DistinctOpt Expression ')' 2791 { 2792 $$ = &ast.AggregateFuncExpr{F: $1.(string), Args: []ast.ExprNode{$4.(ast.ExprNode)}, Distinct: $3.(bool)} 2793 } 2794 | "SUM" '(' DistinctOpt Expression ')' 2795 { 2796 $$ = &ast.AggregateFuncExpr{F: $1.(string), Args: []ast.ExprNode{$4.(ast.ExprNode)}, Distinct: $3.(bool)} 2797 } 2798 2799 FuncDatetimePrec: 2800 { 2801 $$ = nil 2802 } 2803 | '(' ')' 2804 { 2805 $$ = nil 2806 } 2807 | '(' Expression ')' 2808 { 2809 $$ = $2 2810 } 2811 2812 TimeUnit: 2813 "MICROSECOND" | "SECOND" | "MINUTE" | "HOUR" | "DAY" | "WEEK" 2814 | "MONTH" | "QUARTER" | "YEAR" | "SECOND_MICROSECOND" | "MINUTE_MICROSECOND" 2815 | "MINUTE_SECOND" | "HOUR_MICROSECOND" | "HOUR_SECOND" | "HOUR_MINUTE" 2816 | "DAY_MICROSECOND" | "DAY_SECOND" | "DAY_MINUTE" | "DAY_HOUR" | "YEAR_MONTH" 2817 2818 ExpressionOpt: 2819 { 2820 $$ = nil 2821 } 2822 | Expression 2823 { 2824 $$ = $1 2825 } 2826 2827 WhenClauseList: 2828 WhenClause 2829 { 2830 $$ = []*ast.WhenClause{$1.(*ast.WhenClause)} 2831 } 2832 | WhenClauseList WhenClause 2833 { 2834 $$ = append($1.([]*ast.WhenClause), $2.(*ast.WhenClause)) 2835 } 2836 2837 WhenClause: 2838 "WHEN" Expression "THEN" Expression 2839 { 2840 $$ = &ast.WhenClause{ 2841 Expr: $2.(ast.ExprNode), 2842 Result: $4.(ast.ExprNode), 2843 } 2844 } 2845 2846 ElseOpt: 2847 /* empty */ 2848 { 2849 $$ = nil 2850 } 2851 | "ELSE" Expression 2852 { 2853 $$ = $2 2854 } 2855 2856 CastType: 2857 "BINARY" OptFieldLen 2858 { 2859 x := types.NewFieldType(mysql.TypeString) 2860 x.Flen = $2.(int) 2861 x.Charset = charset.CharsetBin 2862 x.Collate = charset.CharsetBin 2863 $$ = x 2864 } 2865 | "CHAR" OptFieldLen OptBinary OptCharset 2866 { 2867 x := types.NewFieldType(mysql.TypeString) 2868 x.Flen = $2.(int) 2869 if $3.(bool) { 2870 x.Flag |= mysql.BinaryFlag 2871 } 2872 x.Charset = $4.(string) 2873 $$ = x 2874 } 2875 | "DATE" 2876 { 2877 x := types.NewFieldType(mysql.TypeDate) 2878 $$ = x 2879 } 2880 | "DATETIME" OptFieldLen 2881 { 2882 x := types.NewFieldType(mysql.TypeDatetime) 2883 x.Decimal = $2.(int) 2884 $$ = x 2885 } 2886 | "DECIMAL" FloatOpt 2887 { 2888 fopt := $2.(*ast.FloatOpt) 2889 x := types.NewFieldType(mysql.TypeNewDecimal) 2890 x.Flen = fopt.Flen 2891 x.Decimal = fopt.Decimal 2892 $$ = x 2893 } 2894 | "TIME" OptFieldLen 2895 { 2896 x := types.NewFieldType(mysql.TypeDuration) 2897 x.Decimal = $2.(int) 2898 $$ = x 2899 } 2900 | "SIGNED" OptInteger 2901 { 2902 x := types.NewFieldType(mysql.TypeLonglong) 2903 $$ = x 2904 } 2905 | "UNSIGNED" OptInteger 2906 { 2907 x := types.NewFieldType(mysql.TypeLonglong) 2908 x.Flag |= mysql.UnsignedFlag 2909 $$ = x 2910 } 2911 2912 2913 PrimaryFactor: 2914 PrimaryFactor '|' PrimaryFactor %prec '|' 2915 { 2916 $$ = &ast.BinaryOperationExpr{Op: opcode.Or, L: $1.(ast.ExprNode), R: $3.(ast.ExprNode)} 2917 } 2918 | PrimaryFactor '&' PrimaryFactor %prec '&' 2919 { 2920 $$ = &ast.BinaryOperationExpr{Op: opcode.And, L: $1.(ast.ExprNode), R: $3.(ast.ExprNode)} 2921 } 2922 | PrimaryFactor "<<" PrimaryFactor %prec lsh 2923 { 2924 $$ = &ast.BinaryOperationExpr{Op: opcode.LeftShift, L: $1.(ast.ExprNode), R: $3.(ast.ExprNode)} 2925 } 2926 | PrimaryFactor ">>" PrimaryFactor %prec rsh 2927 { 2928 $$ = &ast.BinaryOperationExpr{Op: opcode.RightShift, L: $1.(ast.ExprNode), R: $3.(ast.ExprNode)} 2929 } 2930 | PrimaryFactor '+' PrimaryFactor %prec '+' 2931 { 2932 $$ = &ast.BinaryOperationExpr{Op: opcode.Plus, L: $1.(ast.ExprNode), R: $3.(ast.ExprNode)} 2933 } 2934 | PrimaryFactor '-' PrimaryFactor %prec '-' 2935 { 2936 $$ = &ast.BinaryOperationExpr{Op: opcode.Minus, L: $1.(ast.ExprNode), R: $3.(ast.ExprNode)} 2937 } 2938 | PrimaryFactor '*' PrimaryFactor %prec '*' 2939 { 2940 $$ = &ast.BinaryOperationExpr{Op: opcode.Mul, L: $1.(ast.ExprNode), R: $3.(ast.ExprNode)} 2941 } 2942 | PrimaryFactor '/' PrimaryFactor %prec '/' 2943 { 2944 $$ = &ast.BinaryOperationExpr{Op: opcode.Div, L: $1.(ast.ExprNode), R: $3.(ast.ExprNode)} 2945 } 2946 | PrimaryFactor '%' PrimaryFactor %prec '%' 2947 { 2948 $$ = &ast.BinaryOperationExpr{Op: opcode.Mod, L: $1.(ast.ExprNode), R: $3.(ast.ExprNode)} 2949 } 2950 | PrimaryFactor "DIV" PrimaryFactor %prec div 2951 { 2952 $$ = &ast.BinaryOperationExpr{Op: opcode.IntDiv, L: $1.(ast.ExprNode), R: $3.(ast.ExprNode)} 2953 } 2954 | PrimaryFactor "MOD" PrimaryFactor %prec mod 2955 { 2956 $$ = &ast.BinaryOperationExpr{Op: opcode.Mod, L: $1.(ast.ExprNode), R: $3.(ast.ExprNode)} 2957 } 2958 | PrimaryFactor '^' PrimaryFactor 2959 { 2960 $$ = &ast.BinaryOperationExpr{Op: opcode.Xor, L: $1.(ast.ExprNode), R: $3.(ast.ExprNode)} 2961 } 2962 | PrimaryExpression 2963 2964 2965 Priority: 2966 { 2967 $$ = ast.NoPriority 2968 } 2969 | "LOW_PRIORITY" 2970 { 2971 $$ = ast.LowPriority 2972 } 2973 | "HIGH_PRIORITY" 2974 { 2975 $$ = ast.HighPriority 2976 } 2977 | "DELAYED" 2978 { 2979 $$ = ast.DelayedPriority 2980 } 2981 2982 LowPriorityOptional: 2983 { 2984 $$ = false 2985 } 2986 | "LOW_PRIORITY" 2987 { 2988 $$ = true 2989 } 2990 2991 TableName: 2992 Identifier 2993 { 2994 $$ = &ast.TableName{Name:model.NewCIStr($1.(string))} 2995 } 2996 | Identifier '.' Identifier 2997 { 2998 $$ = &ast.TableName{Schema:model.NewCIStr($1.(string)), Name:model.NewCIStr($3.(string))} 2999 } 3000 3001 TableNameList: 3002 TableName 3003 { 3004 tbl := []*ast.TableName{$1.(*ast.TableName)} 3005 $$ = tbl 3006 } 3007 | TableNameList ',' TableName 3008 { 3009 $$ = append($1.([]*ast.TableName), $3.(*ast.TableName)) 3010 } 3011 3012 QuickOptional: 3013 %prec lowerThanQuick 3014 { 3015 $$ = false 3016 } 3017 | "QUICK" 3018 { 3019 $$ = true 3020 } 3021 3022 /***************************Prepared Statement Start****************************** 3023 * See: https://dev.mysql.com/doc/refman/5.7/en/prepare.html 3024 * Example: 3025 * PREPARE stmt_name FROM 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse'; 3026 * OR 3027 * SET @s = 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse'; 3028 * PREPARE stmt_name FROM @s; 3029 */ 3030 3031 PreparedStmt: 3032 "PREPARE" Identifier "FROM" PrepareSQL 3033 { 3034 var sqlText string 3035 var sqlVar *ast.VariableExpr 3036 switch $4.(type) { 3037 case string: 3038 sqlText = $4.(string) 3039 case *ast.VariableExpr: 3040 sqlVar = $4.(*ast.VariableExpr) 3041 } 3042 $$ = &ast.PrepareStmt{ 3043 Name: $2.(string), 3044 SQLText: sqlText, 3045 SQLVar: sqlVar, 3046 } 3047 } 3048 3049 PrepareSQL: 3050 stringLit 3051 | UserVariable 3052 3053 3054 /* 3055 * See: https://dev.mysql.com/doc/refman/5.7/en/execute.html 3056 * Example: 3057 * EXECUTE stmt1 USING @a, @b; 3058 * OR 3059 * EXECUTE stmt1; 3060 */ 3061 ExecuteStmt: 3062 "EXECUTE" Identifier 3063 { 3064 $$ = &ast.ExecuteStmt{Name: $2.(string)} 3065 } 3066 | "EXECUTE" Identifier "USING" UserVariableList 3067 { 3068 $$ = &ast.ExecuteStmt{ 3069 Name: $2.(string), 3070 UsingVars: $4.([]ast.ExprNode), 3071 } 3072 } 3073 3074 UserVariableList: 3075 UserVariable 3076 { 3077 $$ = []ast.ExprNode{$1.(ast.ExprNode)} 3078 } 3079 | UserVariableList ',' UserVariable 3080 { 3081 $$ = append($1.([]ast.ExprNode), $3.(ast.ExprNode)) 3082 } 3083 3084 /* 3085 * See: https://dev.mysql.com/doc/refman/5.0/en/deallocate-prepare.html 3086 */ 3087 3088 DeallocateStmt: 3089 DeallocateSym "PREPARE" Identifier 3090 { 3091 $$ = &ast.DeallocateStmt{Name: $3.(string)} 3092 } 3093 3094 DeallocateSym: 3095 "DEALLOCATE" | "DROP" 3096 3097 /****************************Prepared Statement End*******************************/ 3098 3099 3100 RollbackStmt: 3101 "ROLLBACK" 3102 { 3103 $$ = &ast.RollbackStmt{} 3104 } 3105 3106 SelectStmt: 3107 "SELECT" SelectStmtOpts SelectStmtFieldList SelectStmtLimit SelectLockOpt 3108 { 3109 st := &ast.SelectStmt { 3110 Distinct: $2.(bool), 3111 Fields: $3.(*ast.FieldList), 3112 LockTp: $5.(ast.SelectLockType), 3113 } 3114 lastField := st.Fields.Fields[len(st.Fields.Fields)-1] 3115 if lastField.Expr != nil && lastField.AsName.O == "" { 3116 src := yylex.(*lexer).src 3117 var lastEnd int 3118 if $4 != nil { 3119 lastEnd = yyS[yypt-1].offset-1 3120 } else if $5 != ast.SelectLockNone { 3121 lastEnd = yyS[yypt].offset-1 3122 } else { 3123 lastEnd = len(src) 3124 if src[lastEnd-1] == ';' { 3125 lastEnd-- 3126 } 3127 } 3128 lastField.SetText(src[lastField.Offset:lastEnd]) 3129 } 3130 if $4 != nil { 3131 st.Limit = $4.(*ast.Limit) 3132 } 3133 $$ = st 3134 } 3135 | "SELECT" SelectStmtOpts SelectStmtFieldList FromDual WhereClauseOptional SelectStmtLimit SelectLockOpt 3136 { 3137 st := &ast.SelectStmt { 3138 Distinct: $2.(bool), 3139 Fields: $3.(*ast.FieldList), 3140 LockTp: $7.(ast.SelectLockType), 3141 } 3142 lastField := st.Fields.Fields[len(st.Fields.Fields)-1] 3143 if lastField.Expr != nil && lastField.AsName.O == "" { 3144 lastEnd := yyS[yypt-3].offset-1 3145 lastField.SetText(yylex.(*lexer).src[lastField.Offset:lastEnd]) 3146 } 3147 if $5 != nil { 3148 st.Where = $5.(ast.ExprNode) 3149 } 3150 if $6 != nil { 3151 st.Limit = $6.(*ast.Limit) 3152 } 3153 $$ = st 3154 } 3155 | "SELECT" SelectStmtOpts SelectStmtFieldList "FROM" 3156 TableRefsClause WhereClauseOptional SelectStmtGroup HavingClause OrderByOptional 3157 SelectStmtLimit SelectLockOpt 3158 { 3159 st := &ast.SelectStmt{ 3160 Distinct: $2.(bool), 3161 Fields: $3.(*ast.FieldList), 3162 From: $5.(*ast.TableRefsClause), 3163 LockTp: $11.(ast.SelectLockType), 3164 } 3165 3166 lastField := st.Fields.Fields[len(st.Fields.Fields)-1] 3167 if lastField.Expr != nil && lastField.AsName.O == "" { 3168 lastEnd := yyS[yypt-7].offset-1 3169 lastField.SetText(yylex.(*lexer).src[lastField.Offset:lastEnd]) 3170 } 3171 3172 if $6 != nil { 3173 st.Where = $6.(ast.ExprNode) 3174 } 3175 3176 if $7 != nil { 3177 st.GroupBy = $7.(*ast.GroupByClause) 3178 } 3179 3180 if $8 != nil { 3181 st.Having = $8.(*ast.HavingClause) 3182 } 3183 3184 if $9 != nil { 3185 st.OrderBy = $9.(*ast.OrderByClause) 3186 } 3187 3188 if $10 != nil { 3189 st.Limit = $10.(*ast.Limit) 3190 } 3191 3192 $$ = st 3193 } 3194 3195 FromDual: 3196 "FROM" "DUAL" 3197 3198 3199 TableRefsClause: 3200 TableRefs 3201 { 3202 $$ = &ast.TableRefsClause{TableRefs: $1.(*ast.Join)} 3203 } 3204 3205 TableRefs: 3206 EscapedTableRef 3207 { 3208 if j, ok := $1.(*ast.Join); ok { 3209 // if $1 is Join, use it directly 3210 $$ = j 3211 } else { 3212 $$ = &ast.Join{Left: $1.(ast.ResultSetNode), Right: nil} 3213 } 3214 } 3215 | TableRefs ',' EscapedTableRef 3216 { 3217 /* from a, b is default cross join */ 3218 $$ = &ast.Join{Left: $1.(ast.ResultSetNode), Right: $3.(ast.ResultSetNode), Tp: ast.CrossJoin} 3219 } 3220 3221 EscapedTableRef: 3222 TableRef %prec lowerThanSetKeyword 3223 { 3224 $$ = $1 3225 } 3226 | '{' Identifier TableRef '}' 3227 { 3228 /* 3229 * ODBC escape syntax for outer join is { OJ join_table } 3230 * Use an Identifier for OJ 3231 */ 3232 $$ = $3 3233 } 3234 3235 TableRef: 3236 TableFactor 3237 { 3238 $$ = $1 3239 } 3240 | JoinTable 3241 { 3242 $$ = $1 3243 } 3244 3245 TableFactor: 3246 TableName TableAsNameOpt IndexHintListOpt 3247 { 3248 tn := $1.(*ast.TableName) 3249 tn.IndexHints = $3.([]*ast.IndexHint) 3250 $$ = &ast.TableSource{Source: tn, AsName: $2.(model.CIStr)} 3251 } 3252 | '(' SelectStmt ')' TableAsName 3253 { 3254 st := $2.(*ast.SelectStmt) 3255 l := yylex.(*lexer) 3256 endOffset := l.endOffset(yyS[yypt-1].offset) 3257 l.SetLastSelectFieldText(st, endOffset) 3258 $$ = &ast.TableSource{Source: $2.(*ast.SelectStmt), AsName: $4.(model.CIStr)} 3259 } 3260 | '(' UnionStmt ')' TableAsName 3261 { 3262 $$ = &ast.TableSource{Source: $2.(*ast.UnionStmt), AsName: $4.(model.CIStr)} 3263 } 3264 | '(' TableRefs ')' 3265 { 3266 $$ = $2 3267 } 3268 3269 TableAsNameOpt: 3270 { 3271 $$ = model.CIStr{} 3272 } 3273 | TableAsName 3274 { 3275 $$ = $1 3276 } 3277 3278 TableAsName: 3279 Identifier 3280 { 3281 $$ = model.NewCIStr($1.(string)) 3282 } 3283 | "AS" Identifier 3284 { 3285 $$ = model.NewCIStr($2.(string)) 3286 } 3287 3288 IndexHintType: 3289 "USE" KeyOrIndex 3290 { 3291 $$ = ast.HintUse 3292 } 3293 | "IGNORE" KeyOrIndex 3294 { 3295 $$ = ast.HintIgnore 3296 } 3297 | "FORCE" KeyOrIndex 3298 { 3299 $$ = ast.HintForce 3300 } 3301 3302 IndexHintScope: 3303 { 3304 $$ = ast.HintForScan 3305 } 3306 | "FOR" "JOIN" 3307 { 3308 $$ = ast.HintForJoin 3309 } 3310 | "FOR" "ORDER" "BY" 3311 { 3312 $$ = ast.HintForOrderBy 3313 } 3314 | "FOR" "GROUP" "BY" 3315 { 3316 $$ = ast.HintForGroupBy 3317 } 3318 3319 3320 IndexHint: 3321 IndexHintType IndexHintScope '(' IndexNameList ')' 3322 { 3323 $$ = &ast.IndexHint{ 3324 IndexNames: $4.([]model.CIStr), 3325 HintType: $1.(ast.IndexHintType), 3326 HintScope: $2.(ast.IndexHintScope), 3327 } 3328 } 3329 3330 IndexNameList: 3331 { 3332 var nameList []model.CIStr 3333 $$ = nameList 3334 } 3335 | Identifier 3336 { 3337 $$ = []model.CIStr{model.NewCIStr($1.(string))} 3338 } 3339 | IndexNameList ',' Identifier 3340 { 3341 $$ = append($1.([]model.CIStr), model.NewCIStr($3.(string))) 3342 } 3343 3344 3345 IndexHintList: 3346 IndexHint 3347 { 3348 $$ = []*ast.IndexHint{$1.(*ast.IndexHint)} 3349 } 3350 | IndexHintList IndexHint 3351 { 3352 $$ = append($1.([]*ast.IndexHint), $2.(*ast.IndexHint)) 3353 } 3354 3355 IndexHintListOpt: 3356 { 3357 var hintList []*ast.IndexHint 3358 $$ = hintList 3359 } 3360 | IndexHintList 3361 { 3362 $$ = $1 3363 } 3364 3365 JoinTable: 3366 /* Use %prec to evaluate production TableRef before cross join */ 3367 TableRef CrossOpt TableRef %prec tableRefPriority 3368 { 3369 $$ = &ast.Join{Left: $1.(ast.ResultSetNode), Right: $3.(ast.ResultSetNode), Tp: ast.CrossJoin} 3370 } 3371 | TableRef CrossOpt TableRef "ON" Expression 3372 { 3373 on := &ast.OnCondition{Expr: $5.(ast.ExprNode)} 3374 $$ = &ast.Join{Left: $1.(ast.ResultSetNode), Right: $3.(ast.ResultSetNode), Tp: ast.CrossJoin, On: on} 3375 } 3376 | TableRef JoinType OuterOpt "JOIN" TableRef "ON" Expression 3377 { 3378 on := &ast.OnCondition{Expr: $7.(ast.ExprNode)} 3379 $$ = &ast.Join{Left: $1.(ast.ResultSetNode), Right: $5.(ast.ResultSetNode), Tp: $2.(ast.JoinType), On: on} 3380 } 3381 /* Support Using */ 3382 3383 JoinType: 3384 "LEFT" 3385 { 3386 $$ = ast.LeftJoin 3387 } 3388 | "RIGHT" 3389 { 3390 $$ = ast.RightJoin 3391 } 3392 3393 OuterOpt: 3394 { 3395 $$ = nil 3396 } 3397 | "OUTER" 3398 3399 3400 CrossOpt: 3401 "JOIN" 3402 | "CROSS" "JOIN" 3403 | "INNER" "JOIN" 3404 3405 3406 LimitClause: 3407 { 3408 $$ = nil 3409 } 3410 | "LIMIT" LengthNum 3411 { 3412 $$ = &ast.Limit{Count: $2.(uint64)} 3413 } 3414 3415 SelectStmtLimit: 3416 { 3417 $$ = nil 3418 } 3419 | "LIMIT" LengthNum 3420 { 3421 $$ = &ast.Limit{Count: $2.(uint64)} 3422 } 3423 | "LIMIT" LengthNum ',' LengthNum 3424 { 3425 $$ = &ast.Limit{Offset: $2.(uint64), Count: $4.(uint64)} 3426 } 3427 | "LIMIT" LengthNum "OFFSET" LengthNum 3428 { 3429 $$ = &ast.Limit{Offset: $4.(uint64), Count: $2.(uint64)} 3430 } 3431 3432 SelectStmtDistinct: 3433 /* EMPTY */ 3434 { 3435 $$ = false 3436 } 3437 | "ALL" 3438 { 3439 $$ = false 3440 } 3441 | "DISTINCT" 3442 { 3443 $$ = true 3444 } 3445 3446 SelectStmtOpts: 3447 SelectStmtDistinct SelectStmtSQLCache SelectStmtCalcFoundRows 3448 { 3449 // TODO: return calc_found_rows opt and support more other options 3450 $$ = $1 3451 } 3452 3453 SelectStmtCalcFoundRows: 3454 %prec lowerThanCalcFoundRows 3455 { 3456 $$ = false 3457 } 3458 | "SQL_CALC_FOUND_ROWS" 3459 { 3460 $$ = true 3461 } 3462 SelectStmtSQLCache: 3463 %prec lowerThanSQLCache 3464 { 3465 $$ = false 3466 } 3467 | "SQL_CACHE" 3468 { 3469 $$ = true 3470 } 3471 | "SQL_NO_CACHE" 3472 { 3473 $$ = false 3474 } 3475 3476 SelectStmtFieldList: 3477 FieldList 3478 { 3479 $$ = &ast.FieldList{Fields: $1.([]*ast.SelectField)} 3480 } 3481 3482 SelectStmtGroup: 3483 /* EMPTY */ 3484 { 3485 $$ = nil 3486 } 3487 | GroupByClause 3488 3489 // See: https://dev.mysql.com/doc/refman/5.7/en/subqueries.html 3490 SubSelect: 3491 '(' SelectStmt ')' 3492 { 3493 s := $2.(*ast.SelectStmt) 3494 l := yylex.(*lexer) 3495 endOffset := l.endOffset(yyS[yypt].offset) 3496 l.SetLastSelectFieldText(s, endOffset) 3497 src := yylex.(*lexer).src 3498 // See the implementation of yyParse function 3499 s.SetText(src[yyS[yypt-1].offset-1:yyS[yypt].offset-1]) 3500 $$ = &ast.SubqueryExpr{Query: s} 3501 } 3502 | '(' UnionStmt ')' 3503 { 3504 s := $2.(*ast.UnionStmt) 3505 src := yylex.(*lexer).src 3506 // See the implementation of yyParse function 3507 s.SetText(src[yyS[yypt-1].offset-1:yyS[yypt].offset-1]) 3508 $$ = &ast.SubqueryExpr{Query: s} 3509 } 3510 3511 // See: https://dev.mysql.com/doc/refman/5.7/en/innodb-locking-reads.html 3512 SelectLockOpt: 3513 /* empty */ 3514 { 3515 $$ = ast.SelectLockNone 3516 } 3517 | "FOR" "UPDATE" 3518 { 3519 $$ = ast.SelectLockForUpdate 3520 } 3521 | "LOCK" "IN" "SHARE" "MODE" 3522 { 3523 $$ = ast.SelectLockInShareMode 3524 } 3525 3526 // See: https://dev.mysql.com/doc/refman/5.7/en/union.html 3527 UnionStmt: 3528 UnionClauseList "UNION" UnionOpt SelectStmt 3529 { 3530 union := $1.(*ast.UnionStmt) 3531 union.Distinct = union.Distinct || $3.(bool) 3532 lastSelect := union.SelectList.Selects[len(union.SelectList.Selects)-1] 3533 l := yylex.(*lexer) 3534 endOffset := l.endOffset(yyS[yypt-2].offset) 3535 l.SetLastSelectFieldText(lastSelect, endOffset) 3536 union.SelectList.Selects = append(union.SelectList.Selects, $4.(*ast.SelectStmt)) 3537 $$ = union 3538 } 3539 | UnionClauseList "UNION" UnionOpt '(' SelectStmt ')' OrderByOptional SelectStmtLimit 3540 { 3541 union := $1.(*ast.UnionStmt) 3542 union.Distinct = union.Distinct || $3.(bool) 3543 lastSelect := union.SelectList.Selects[len(union.SelectList.Selects)-1] 3544 l := yylex.(*lexer) 3545 endOffset := l.endOffset(yyS[yypt-6].offset) 3546 l.SetLastSelectFieldText(lastSelect, endOffset) 3547 st := $5.(*ast.SelectStmt) 3548 endOffset = l.endOffset(yyS[yypt-2].offset) 3549 l.SetLastSelectFieldText(st, endOffset) 3550 union.SelectList.Selects = append(union.SelectList.Selects, st) 3551 if $7 != nil { 3552 union.OrderBy = $7.(*ast.OrderByClause) 3553 } 3554 if $8 != nil { 3555 union.Limit = $8.(*ast.Limit) 3556 } 3557 $$ = union 3558 } 3559 3560 UnionClauseList: 3561 UnionSelect 3562 { 3563 selectList := &ast.UnionSelectList{Selects: []*ast.SelectStmt{$1.(*ast.SelectStmt)}} 3564 $$ = &ast.UnionStmt{ 3565 SelectList: selectList, 3566 } 3567 } 3568 | UnionClauseList "UNION" UnionOpt UnionSelect 3569 { 3570 union := $1.(*ast.UnionStmt) 3571 union.Distinct = union.Distinct || $3.(bool) 3572 lastSelect := union.SelectList.Selects[len(union.SelectList.Selects)-1] 3573 l := yylex.(*lexer) 3574 endOffset := l.endOffset(yyS[yypt-2].offset) 3575 l.SetLastSelectFieldText(lastSelect, endOffset) 3576 union.SelectList.Selects = append(union.SelectList.Selects, $4.(*ast.SelectStmt)) 3577 $$ = union 3578 } 3579 3580 UnionSelect: 3581 SelectStmt 3582 | '(' SelectStmt ')' 3583 { 3584 st := $2.(*ast.SelectStmt) 3585 l := yylex.(*lexer) 3586 endOffset := l.endOffset(yyS[yypt].offset) 3587 l.SetLastSelectFieldText(st, endOffset) 3588 $$ = st 3589 } 3590 3591 UnionOpt: 3592 { 3593 $$ = true 3594 } 3595 | "ALL" 3596 { 3597 $$ = false 3598 } 3599 | "DISTINCT" 3600 { 3601 $$ = true 3602 } 3603 3604 3605 /********************Set Statement*******************************/ 3606 SetStmt: 3607 "SET" VariableAssignmentList 3608 { 3609 $$ = &ast.SetStmt{Variables: $2.([]*ast.VariableAssignment)} 3610 } 3611 | "SET" "NAMES" StringName 3612 { 3613 $$ = &ast.SetCharsetStmt{Charset: $3.(string)} 3614 } 3615 | "SET" "NAMES" StringName "COLLATE" StringName 3616 { 3617 $$ = &ast.SetCharsetStmt{ 3618 Charset: $3.(string), 3619 Collate: $5.(string), 3620 } 3621 } 3622 | "SET" CharsetKw StringName 3623 { 3624 $$ = &ast.SetCharsetStmt{Charset: $3.(string)} 3625 } 3626 | "SET" "PASSWORD" eq PasswordOpt 3627 { 3628 $$ = &ast.SetPwdStmt{Password: $4.(string)} 3629 } 3630 | "SET" "PASSWORD" "FOR" Username eq PasswordOpt 3631 { 3632 $$ = &ast.SetPwdStmt{User: $4.(string), Password: $6.(string)} 3633 } 3634 | "SET" "GLOBAL" "TRANSACTION" TransactionChars 3635 { 3636 // Parsed but ignored 3637 } 3638 | "SET" "SESSION" "TRANSACTION" TransactionChars 3639 { 3640 // Parsed but ignored 3641 } 3642 3643 TransactionChars: 3644 TransactionChar 3645 | TransactionChars ',' TransactionChar 3646 3647 TransactionChar: 3648 "ISOLATION" "LEVEL" IsolationLevel 3649 | "READ" "WRITE" 3650 | "READ" "ONLY" 3651 3652 IsolationLevel: 3653 "REPEATABLE" "READ" 3654 | "READ" "COMMITTED" 3655 | "READ" "UNCOMMITTED" 3656 | "SERIALIZABLE" 3657 3658 VariableAssignment: 3659 Identifier eq Expression 3660 { 3661 $$ = &ast.VariableAssignment{Name: $1.(string), Value: $3.(ast.ExprNode), IsSystem: true} 3662 } 3663 | "GLOBAL" Identifier eq Expression 3664 { 3665 $$ = &ast.VariableAssignment{Name: $2.(string), Value: $4.(ast.ExprNode), IsGlobal: true, IsSystem: true} 3666 } 3667 | "SESSION" Identifier eq Expression 3668 { 3669 $$ = &ast.VariableAssignment{Name: $2.(string), Value: $4.(ast.ExprNode), IsSystem: true} 3670 } 3671 | "LOCAL" Identifier eq Expression 3672 { 3673 $$ = &ast.VariableAssignment{Name: $2.(string), Value: $4.(ast.ExprNode), IsSystem: true} 3674 } 3675 | "SYS_VAR" eq Expression 3676 { 3677 v := strings.ToLower($1.(string)) 3678 var isGlobal bool 3679 if strings.HasPrefix(v, "@@global.") { 3680 isGlobal = true 3681 v = strings.TrimPrefix(v, "@@global.") 3682 } else if strings.HasPrefix(v, "@@session.") { 3683 v = strings.TrimPrefix(v, "@@session.") 3684 } else if strings.HasPrefix(v, "@@local.") { 3685 v = strings.TrimPrefix(v, "@@local.") 3686 } else if strings.HasPrefix(v, "@@") { 3687 v = strings.TrimPrefix(v, "@@") 3688 } 3689 $$ = &ast.VariableAssignment{Name: v, Value: $3.(ast.ExprNode), IsGlobal: isGlobal, IsSystem: true} 3690 } 3691 | "USER_VAR" eq Expression 3692 { 3693 v := $1.(string) 3694 v = strings.TrimPrefix(v, "@") 3695 $$ = &ast.VariableAssignment{Name: v, Value: $3.(ast.ExprNode)} 3696 } 3697 | "USER_VAR" assignmentEq Expression 3698 { 3699 v := $1.(string) 3700 v = strings.TrimPrefix(v, "@") 3701 $$ = &ast.VariableAssignment{Name: v, Value: $3.(ast.ExprNode)} 3702 } 3703 3704 VariableAssignmentList: 3705 { 3706 $$ = []*ast.VariableAssignment{} 3707 } 3708 | VariableAssignment 3709 { 3710 $$ = []*ast.VariableAssignment{$1.(*ast.VariableAssignment)} 3711 } 3712 | VariableAssignmentList ',' VariableAssignment 3713 { 3714 $$ = append($1.([]*ast.VariableAssignment), $3.(*ast.VariableAssignment)) 3715 } 3716 3717 Variable: 3718 SystemVariable | UserVariable 3719 3720 SystemVariable: 3721 "SYS_VAR" 3722 { 3723 v := strings.ToLower($1.(string)) 3724 var isGlobal bool 3725 if strings.HasPrefix(v, "@@global.") { 3726 isGlobal = true 3727 v = strings.TrimPrefix(v, "@@global.") 3728 } else if strings.HasPrefix(v, "@@session.") { 3729 v = strings.TrimPrefix(v, "@@session.") 3730 } else if strings.HasPrefix(v, "@@local.") { 3731 v = strings.TrimPrefix(v, "@@local.") 3732 } else if strings.HasPrefix(v, "@@") { 3733 v = strings.TrimPrefix(v, "@@") 3734 } 3735 $$ = &ast.VariableExpr{Name: v, IsGlobal: isGlobal, IsSystem: true} 3736 } 3737 3738 UserVariable: 3739 "USER_VAR" 3740 { 3741 v := $1.(string) 3742 v = strings.TrimPrefix(v, "@") 3743 $$ = &ast.VariableExpr{Name: v, IsGlobal: false, IsSystem: false} 3744 } 3745 3746 Username: 3747 stringLit "AT" stringLit 3748 { 3749 $$ = $1.(string) + "@" + $3.(string) 3750 } 3751 3752 PasswordOpt: 3753 stringLit 3754 { 3755 $$ = $1.(string) 3756 } 3757 | "PASSWORD" '(' AuthString ')' 3758 { 3759 $$ = $3.(string) 3760 } 3761 3762 AuthString: 3763 stringLit 3764 { 3765 $$ = $1.(string) 3766 } 3767 3768 /****************************Admin Statement*******************************/ 3769 AdminStmt: 3770 "ADMIN" "SHOW" "DDL" 3771 { 3772 $$ = &ast.AdminStmt{Tp: ast.AdminShowDDL} 3773 } 3774 | "ADMIN" "CHECK" "TABLE" TableNameList 3775 { 3776 $$ = &ast.AdminStmt{ 3777 Tp: ast.AdminCheckTable, 3778 Tables: $4.([]*ast.TableName), 3779 } 3780 } 3781 3782 /****************************Show Statement*******************************/ 3783 ShowStmt: 3784 "SHOW" ShowTargetFilterable ShowLikeOrWhereOpt 3785 { 3786 stmt := $2.(*ast.ShowStmt) 3787 if $3 != nil { 3788 if x, ok := $3.(*ast.PatternLikeExpr); ok { 3789 stmt.Pattern = x 3790 } else { 3791 stmt.Where = $3.(ast.ExprNode) 3792 } 3793 } 3794 $$ = stmt 3795 } 3796 | "SHOW" "CREATE" "TABLE" TableName 3797 { 3798 $$ = &ast.ShowStmt{ 3799 Tp: ast.ShowCreateTable, 3800 Table: $4.(*ast.TableName), 3801 } 3802 } 3803 | "SHOW" "GRANTS" 3804 { 3805 // See: https://dev.mysql.com/doc/refman/5.7/en/show-grants.html 3806 $$ = &ast.ShowStmt{Tp: ast.ShowGrants} 3807 } 3808 | "SHOW" "GRANTS" "FOR" Username 3809 { 3810 // See: https://dev.mysql.com/doc/refman/5.7/en/show-grants.html 3811 $$ = &ast.ShowStmt{ 3812 Tp: ast.ShowGrants, 3813 User: $4.(string), 3814 } 3815 } 3816 | "SHOW" "INDEX" "FROM" TableName 3817 { 3818 $$ = &ast.ShowStmt{ 3819 Tp: ast.ShowIndex, 3820 Table: $4.(*ast.TableName), 3821 } 3822 } 3823 3824 ShowTargetFilterable: 3825 "ENGINES" 3826 { 3827 $$ = &ast.ShowStmt{Tp: ast.ShowEngines} 3828 } 3829 | "DATABASES" 3830 { 3831 $$ = &ast.ShowStmt{Tp: ast.ShowDatabases} 3832 } 3833 | "SCHEMAS" 3834 { 3835 $$ = &ast.ShowStmt{Tp: ast.ShowDatabases} 3836 } 3837 | "CHARACTER" "SET" 3838 { 3839 $$ = &ast.ShowStmt{Tp: ast.ShowCharset} 3840 } 3841 | OptFull "TABLES" ShowDatabaseNameOpt 3842 { 3843 $$ = &ast.ShowStmt{ 3844 Tp: ast.ShowTables, 3845 DBName: $3.(string), 3846 Full: $1.(bool), 3847 } 3848 } 3849 | "TABLE" "STATUS" ShowDatabaseNameOpt 3850 { 3851 $$ = &ast.ShowStmt{ 3852 Tp: ast.ShowTableStatus, 3853 DBName: $3.(string), 3854 } 3855 } 3856 | OptFull "COLUMNS" ShowTableAliasOpt ShowDatabaseNameOpt 3857 { 3858 $$ = &ast.ShowStmt{ 3859 Tp: ast.ShowColumns, 3860 Table: $3.(*ast.TableName), 3861 DBName: $4.(string), 3862 Full: $1.(bool), 3863 } 3864 } 3865 | OptFull "FIELDS" ShowTableAliasOpt ShowDatabaseNameOpt 3866 { 3867 // SHOW FIELDS is a synonym for SHOW COLUMNS. 3868 $$ = &ast.ShowStmt{ 3869 Tp: ast.ShowColumns, 3870 Table: $3.(*ast.TableName), 3871 DBName: $4.(string), 3872 Full: $1.(bool), 3873 } 3874 } 3875 | "WARNINGS" 3876 { 3877 $$ = &ast.ShowStmt{Tp: ast.ShowWarnings} 3878 } 3879 | GlobalScope "VARIABLES" 3880 { 3881 $$ = &ast.ShowStmt{ 3882 Tp: ast.ShowVariables, 3883 GlobalScope: $1.(bool), 3884 } 3885 } 3886 | GlobalScope "STATUS" 3887 { 3888 $$ = &ast.ShowStmt{ 3889 Tp: ast.ShowStatus, 3890 GlobalScope: $1.(bool), 3891 } 3892 } 3893 | "COLLATION" 3894 { 3895 $$ = &ast.ShowStmt{ 3896 Tp: ast.ShowCollation, 3897 } 3898 } 3899 | "TRIGGERS" ShowDatabaseNameOpt 3900 { 3901 $$ = &ast.ShowStmt{ 3902 Tp: ast.ShowTriggers, 3903 DBName: $2.(string), 3904 } 3905 } 3906 | "PROCEDURE" "STATUS" 3907 { 3908 $$ = &ast.ShowStmt { 3909 Tp: ast.ShowProcedureStatus, 3910 } 3911 } 3912 3913 ShowLikeOrWhereOpt: 3914 { 3915 $$ = nil 3916 } 3917 | "LIKE" PrimaryExpression 3918 { 3919 $$ = &ast.PatternLikeExpr{ 3920 Pattern: $2.(ast.ExprNode), 3921 Escape: '\\', 3922 } 3923 } 3924 | "WHERE" Expression 3925 { 3926 $$ = $2.(ast.ExprNode) 3927 } 3928 3929 GlobalScope: 3930 { 3931 $$ = false 3932 } 3933 | "GLOBAL" 3934 { 3935 $$ = true 3936 } 3937 | "SESSION" 3938 { 3939 $$ = false 3940 } 3941 3942 OptFull: 3943 { 3944 $$ = false 3945 } 3946 | "FULL" 3947 { 3948 $$ = true 3949 } 3950 3951 ShowDatabaseNameOpt: 3952 { 3953 $$ = "" 3954 } 3955 | "FROM" DBName 3956 { 3957 $$ = $2.(string) 3958 } 3959 | "IN" DBName 3960 { 3961 $$ = $2.(string) 3962 } 3963 3964 ShowTableAliasOpt: 3965 "FROM" TableName 3966 { 3967 $$ = $2.(*ast.TableName) 3968 } 3969 | "IN" TableName 3970 { 3971 $$ = $2.(*ast.TableName) 3972 } 3973 3974 Statement: 3975 EmptyStmt 3976 | AdminStmt 3977 | AlterTableStmt 3978 | BeginTransactionStmt 3979 | CommitStmt 3980 | DeallocateStmt 3981 | DeleteFromStmt 3982 | ExecuteStmt 3983 | ExplainStmt 3984 | CreateDatabaseStmt 3985 | CreateIndexStmt 3986 | CreateTableStmt 3987 | CreateUserStmt 3988 | DoStmt 3989 | DropDatabaseStmt 3990 | DropIndexStmt 3991 | DropTableStmt 3992 | GrantStmt 3993 | InsertIntoStmt 3994 | PreparedStmt 3995 | RollbackStmt 3996 | ReplaceIntoStmt 3997 | SelectStmt 3998 | UnionStmt 3999 | SetStmt 4000 | ShowStmt 4001 | TruncateTableStmt 4002 | UpdateStmt 4003 | UseStmt 4004 | SubSelect 4005 { 4006 // `(select 1)`; is a valid select statement 4007 // TODO: This is used to fix issue #320. There may be a better solution. 4008 $$ = $1.(*ast.SubqueryExpr).Query 4009 } 4010 | UnlockTablesStmt 4011 | LockTablesStmt 4012 4013 ExplainableStmt: 4014 SelectStmt 4015 | DeleteFromStmt 4016 | UpdateStmt 4017 | InsertIntoStmt 4018 | ReplaceIntoStmt 4019 4020 StatementList: 4021 Statement 4022 { 4023 if $1 != nil { 4024 s := $1.(ast.StmtNode) 4025 s.SetText(yylex.(*lexer).stmtText()) 4026 yylex.(*lexer).list = append(yylex.(*lexer).list, s) 4027 } 4028 } 4029 | StatementList ';' Statement 4030 { 4031 if $3 != nil { 4032 s := $3.(ast.StmtNode) 4033 s.SetText(yylex.(*lexer).stmtText()) 4034 yylex.(*lexer).list = append(yylex.(*lexer).list, s) 4035 } 4036 } 4037 4038 Constraint: 4039 ConstraintKeywordOpt ConstraintElem 4040 { 4041 cst := $2.(*ast.Constraint) 4042 if $1 != nil { 4043 cst.Name = $1.(string) 4044 } 4045 $$ = cst 4046 } 4047 4048 TableElement: 4049 ColumnDef 4050 { 4051 $$ = $1.(*ast.ColumnDef) 4052 } 4053 | Constraint 4054 { 4055 $$ = $1.(*ast.Constraint) 4056 } 4057 | "CHECK" '(' Expression ')' 4058 { 4059 /* Nothing to do now */ 4060 $$ = nil 4061 } 4062 4063 TableElementList: 4064 TableElement 4065 { 4066 if $1 != nil { 4067 $$ = []interface{}{$1.(interface{})} 4068 } else { 4069 $$ = []interface{}{} 4070 } 4071 } 4072 | TableElementList ',' TableElement 4073 { 4074 if $3 != nil { 4075 $$ = append($1.([]interface{}), $3) 4076 } else { 4077 $$ = $1 4078 } 4079 } 4080 4081 TableOption: 4082 "ENGINE" Identifier 4083 { 4084 $$ = &ast.TableOption{Tp: ast.TableOptionEngine, StrValue: $2.(string)} 4085 } 4086 | "ENGINE" eq Identifier 4087 { 4088 $$ = &ast.TableOption{Tp: ast.TableOptionEngine, StrValue: $3.(string)} 4089 } 4090 | DefaultKwdOpt CharsetKw EqOpt StringName 4091 { 4092 $$ = &ast.TableOption{Tp: ast.TableOptionCharset, StrValue: $4.(string)} 4093 } 4094 | DefaultKwdOpt "COLLATE" EqOpt StringName 4095 { 4096 $$ = &ast.TableOption{Tp: ast.TableOptionCollate, StrValue: $4.(string)} 4097 } 4098 | "AUTO_INCREMENT" eq LengthNum 4099 { 4100 $$ = &ast.TableOption{Tp: ast.TableOptionAutoIncrement, UintValue: $3.(uint64)} 4101 } 4102 | "COMMENT" EqOpt stringLit 4103 { 4104 $$ = &ast.TableOption{Tp: ast.TableOptionComment, StrValue: $3.(string)} 4105 } 4106 | "AVG_ROW_LENGTH" EqOpt LengthNum 4107 { 4108 $$ = &ast.TableOption{Tp: ast.TableOptionAvgRowLength, UintValue: $3.(uint64)} 4109 } 4110 | "CONNECTION" EqOpt stringLit 4111 { 4112 $$ = &ast.TableOption{Tp: ast.TableOptionConnection, StrValue: $3.(string)} 4113 } 4114 | "CHECKSUM" EqOpt LengthNum 4115 { 4116 $$ = &ast.TableOption{Tp: ast.TableOptionCheckSum, UintValue: $3.(uint64)} 4117 } 4118 | "PASSWORD" EqOpt stringLit 4119 { 4120 $$ = &ast.TableOption{Tp: ast.TableOptionPassword, StrValue: $3.(string)} 4121 } 4122 | "COMPRESSION" EqOpt Identifier 4123 { 4124 $$ = &ast.TableOption{Tp: ast.TableOptionCompression, StrValue: $3.(string)} 4125 } 4126 | "KEY_BLOCK_SIZE" EqOpt LengthNum 4127 { 4128 $$ = &ast.TableOption{Tp: ast.TableOptionKeyBlockSize, UintValue: $3.(uint64)} 4129 } 4130 | "MAX_ROWS" EqOpt LengthNum 4131 { 4132 $$ = &ast.TableOption{Tp: ast.TableOptionMaxRows, UintValue: $3.(uint64)} 4133 } 4134 | "MIN_ROWS" EqOpt LengthNum 4135 { 4136 $$ = &ast.TableOption{Tp: ast.TableOptionMinRows, UintValue: $3.(uint64)} 4137 } 4138 | "DELAY_KEY_WRITE" EqOpt LengthNum 4139 { 4140 $$ = &ast.TableOption{Tp: ast.TableOptionDelayKeyWrite, UintValue: $3.(uint64)} 4141 } 4142 | RowFormat 4143 { 4144 $$ = &ast.TableOption{Tp: ast.TableOptionRowFormat, UintValue: $1.(uint64)} 4145 } 4146 4147 4148 TableOptionListOpt: 4149 { 4150 $$ = []*ast.TableOption{} 4151 } 4152 | TableOptionList %prec lowerThanComma 4153 4154 TableOptionList: 4155 TableOption 4156 { 4157 $$ = []*ast.TableOption{$1.(*ast.TableOption)} 4158 } 4159 | TableOptionList TableOption 4160 { 4161 $$ = append($1.([]*ast.TableOption), $2.(*ast.TableOption)) 4162 } 4163 | TableOptionList ',' TableOption 4164 { 4165 $$ = append($1.([]*ast.TableOption), $3.(*ast.TableOption)) 4166 } 4167 4168 OptTable: 4169 {} | "TABLE" 4170 4171 TruncateTableStmt: 4172 "TRUNCATE" OptTable TableName 4173 { 4174 $$ = &ast.TruncateTableStmt{Table: $3.(*ast.TableName)} 4175 } 4176 4177 RowFormat: 4178 "ROW_FORMAT" EqOpt "DEFAULT" 4179 { 4180 $$ = ast.RowFormatDefault 4181 } 4182 | "ROW_FORMAT" EqOpt "DYNAMIC" 4183 { 4184 $$ = ast.RowFormatDynamic 4185 } 4186 | "ROW_FORMAT" EqOpt "FIXED" 4187 { 4188 $$ = ast.RowFormatFixed 4189 } 4190 | "ROW_FORMAT" EqOpt "COMPRESSED" 4191 { 4192 $$ = ast.RowFormatCompressed 4193 } 4194 | "ROW_FORMAT" EqOpt "REDUNDANT" 4195 { 4196 $$ = ast.RowFormatRedundant 4197 } 4198 | "ROW_FORMAT" EqOpt "COMPACT" 4199 { 4200 $$ = ast.RowFormatCompact 4201 } 4202 4203 /*************************************Type Begin***************************************/ 4204 Type: 4205 NumericType 4206 { 4207 $$ = $1 4208 } 4209 | StringType 4210 { 4211 $$ = $1 4212 } 4213 | DateAndTimeType 4214 { 4215 $$ = $1 4216 } 4217 | "float32" 4218 { 4219 x := types.NewFieldType($1.(byte)) 4220 $$ = x 4221 } 4222 | "float64" 4223 { 4224 x := types.NewFieldType($1.(byte)) 4225 $$ = x 4226 } 4227 | "int64" 4228 { 4229 x := types.NewFieldType($1.(byte)) 4230 $$ = x 4231 } 4232 | "string" 4233 { 4234 x := types.NewFieldType($1.(byte)) 4235 $$ = x 4236 } 4237 | "uint" 4238 { 4239 x := types.NewFieldType($1.(byte)) 4240 $$ = x 4241 } 4242 | "uint64" 4243 { 4244 x := types.NewFieldType($1.(byte)) 4245 $$ = x 4246 } 4247 4248 NumericType: 4249 IntegerType OptFieldLen FieldOpts 4250 { 4251 // TODO: check flen 0 4252 x := types.NewFieldType($1.(byte)) 4253 x.Flen = $2.(int) 4254 for _, o := range $3.([]*ast.TypeOpt) { 4255 if o.IsUnsigned { 4256 x.Flag |= mysql.UnsignedFlag 4257 } 4258 if o.IsZerofill { 4259 x.Flag |= mysql.ZerofillFlag 4260 } 4261 } 4262 $$ = x 4263 } 4264 | FixedPointType FloatOpt FieldOpts 4265 { 4266 fopt := $2.(*ast.FloatOpt) 4267 x := types.NewFieldType($1.(byte)) 4268 x.Flen = fopt.Flen 4269 x.Decimal = fopt.Decimal 4270 for _, o := range $3.([]*ast.TypeOpt) { 4271 if o.IsUnsigned { 4272 x.Flag |= mysql.UnsignedFlag 4273 } 4274 if o.IsZerofill { 4275 x.Flag |= mysql.ZerofillFlag 4276 } 4277 } 4278 $$ = x 4279 } 4280 | FloatingPointType FloatOpt FieldOpts 4281 { 4282 fopt := $2.(*ast.FloatOpt) 4283 x := types.NewFieldType($1.(byte)) 4284 x.Flen = fopt.Flen 4285 if x.Tp == mysql.TypeFloat { 4286 // Fix issue #312 4287 if x.Flen > 53 { 4288 yylex.(*lexer).errf("Float len(%d) should not be greater than 53", x.Flen) 4289 return 1 4290 } 4291 if x.Flen > 24 { 4292 x.Tp = mysql.TypeDouble 4293 } 4294 } 4295 x.Decimal =fopt.Decimal 4296 for _, o := range $3.([]*ast.TypeOpt) { 4297 if o.IsUnsigned { 4298 x.Flag |= mysql.UnsignedFlag 4299 } 4300 if o.IsZerofill { 4301 x.Flag |= mysql.ZerofillFlag 4302 } 4303 } 4304 $$ = x 4305 } 4306 | BitValueType OptFieldLen 4307 { 4308 x := types.NewFieldType($1.(byte)) 4309 x.Flen = $2.(int) 4310 if x.Flen == -1 || x.Flen == 0 { 4311 x.Flen = 1 4312 } else if x.Flen > 64 { 4313 yylex.(*lexer).errf("invalid field length %d for bit type, must in [1, 64]", x.Flen) 4314 } 4315 $$ = x 4316 } 4317 4318 IntegerType: 4319 "TINYINT" 4320 { 4321 $$ = mysql.TypeTiny 4322 } 4323 | "SMALLINT" 4324 { 4325 $$ = mysql.TypeShort 4326 } 4327 | "MEDIUMINT" 4328 { 4329 $$ = mysql.TypeInt24 4330 } 4331 | "INT" 4332 { 4333 $$ = mysql.TypeLong 4334 } 4335 | "INTEGER" 4336 { 4337 $$ = mysql.TypeLong 4338 } 4339 | "BIGINT" 4340 { 4341 $$ = mysql.TypeLonglong 4342 } 4343 | "BOOL" 4344 { 4345 $$ = mysql.TypeTiny 4346 } 4347 | "BOOLEAN" 4348 { 4349 $$ = mysql.TypeTiny 4350 } 4351 4352 OptInteger: 4353 {} | "INTEGER" 4354 4355 FixedPointType: 4356 "DECIMAL" 4357 { 4358 $$ = mysql.TypeNewDecimal 4359 } 4360 | "NUMERIC" 4361 { 4362 $$ = mysql.TypeNewDecimal 4363 } 4364 4365 FloatingPointType: 4366 "float" 4367 { 4368 $$ = mysql.TypeFloat 4369 } 4370 | "REAL" 4371 { 4372 $$ = mysql.TypeDouble 4373 } 4374 | "DOUBLE" 4375 { 4376 $$ = mysql.TypeDouble 4377 } 4378 | "DOUBLE" "PRECISION" 4379 { 4380 $$ = mysql.TypeDouble 4381 } 4382 4383 BitValueType: 4384 "BIT" 4385 { 4386 $$ = mysql.TypeBit 4387 } 4388 4389 StringType: 4390 NationalOpt "CHAR" FieldLen OptBinary OptCharset OptCollate 4391 { 4392 x := types.NewFieldType(mysql.TypeString) 4393 x.Flen = $3.(int) 4394 if $4.(bool) { 4395 x.Flag |= mysql.BinaryFlag 4396 } 4397 $$ = x 4398 } 4399 | NationalOpt "CHAR" OptBinary OptCharset OptCollate 4400 { 4401 x := types.NewFieldType(mysql.TypeString) 4402 if $3.(bool) { 4403 x.Flag |= mysql.BinaryFlag 4404 } 4405 $$ = x 4406 } 4407 | NationalOpt "VARCHAR" FieldLen OptBinary OptCharset OptCollate 4408 { 4409 x := types.NewFieldType(mysql.TypeVarchar) 4410 x.Flen = $3.(int) 4411 if $4.(bool) { 4412 x.Flag |= mysql.BinaryFlag 4413 } 4414 x.Charset = $5.(string) 4415 x.Collate = $6.(string) 4416 $$ = x 4417 } 4418 | "BINARY" OptFieldLen 4419 { 4420 x := types.NewFieldType(mysql.TypeString) 4421 x.Flen = $2.(int) 4422 x.Charset = charset.CharsetBin 4423 x.Collate = charset.CharsetBin 4424 $$ = x 4425 } 4426 | "VARBINARY" FieldLen 4427 { 4428 x := types.NewFieldType(mysql.TypeVarchar) 4429 x.Flen = $2.(int) 4430 x.Charset = charset.CharsetBin 4431 x.Collate = charset.CharsetBin 4432 $$ = x 4433 } 4434 | BlobType 4435 { 4436 $$ = $1.(*types.FieldType) 4437 } 4438 | TextType OptBinary OptCharset OptCollate 4439 { 4440 x := $1.(*types.FieldType) 4441 if $2.(bool) { 4442 x.Flag |= mysql.BinaryFlag 4443 } 4444 x.Charset = $3.(string) 4445 x.Collate = $4.(string) 4446 $$ = x 4447 } 4448 | "ENUM" '(' StringList ')' OptCharset OptCollate 4449 { 4450 x := types.NewFieldType(mysql.TypeEnum) 4451 x.Elems = $3.([]string) 4452 x.Charset = $5.(string) 4453 x.Collate = $6.(string) 4454 $$ = x 4455 } 4456 | "SET" '(' StringList ')' OptCharset OptCollate 4457 { 4458 x := types.NewFieldType(mysql.TypeSet) 4459 x.Elems = $3.([]string) 4460 x.Charset = $5.(string) 4461 x.Collate = $6.(string) 4462 $$ = x 4463 } 4464 4465 NationalOpt: 4466 { 4467 4468 } 4469 | "NATIONAL" 4470 { 4471 4472 } 4473 4474 BlobType: 4475 "TINYBLOB" 4476 { 4477 x := types.NewFieldType(mysql.TypeTinyBlob) 4478 x.Charset = charset.CharsetBin 4479 x.Collate = charset.CharsetBin 4480 $$ = x 4481 } 4482 | "BLOB" OptFieldLen 4483 { 4484 x := types.NewFieldType(mysql.TypeBlob) 4485 x.Flen = $2.(int) 4486 x.Charset = charset.CharsetBin 4487 x.Collate = charset.CharsetBin 4488 $$ = x 4489 } 4490 | "MEDIUMBLOB" 4491 { 4492 x := types.NewFieldType(mysql.TypeMediumBlob) 4493 x.Charset = charset.CharsetBin 4494 x.Collate = charset.CharsetBin 4495 $$ = x 4496 } 4497 | "LONGBLOB" 4498 { 4499 x := types.NewFieldType(mysql.TypeLongBlob) 4500 x.Charset = charset.CharsetBin 4501 x.Collate = charset.CharsetBin 4502 $$ = x 4503 } 4504 4505 TextType: 4506 "TINYTEXT" 4507 { 4508 x := types.NewFieldType(mysql.TypeTinyBlob) 4509 $$ = x 4510 4511 } 4512 | "TEXT" OptFieldLen 4513 { 4514 x := types.NewFieldType(mysql.TypeBlob) 4515 x.Flen = $2.(int) 4516 $$ = x 4517 } 4518 | "MEDIUMTEXT" 4519 { 4520 x := types.NewFieldType(mysql.TypeMediumBlob) 4521 $$ = x 4522 } 4523 | "LONGTEXT" 4524 { 4525 x := types.NewFieldType(mysql.TypeLongBlob) 4526 $$ = x 4527 } 4528 4529 4530 DateAndTimeType: 4531 "DATE" 4532 { 4533 x := types.NewFieldType(mysql.TypeDate) 4534 $$ = x 4535 } 4536 | "DATETIME" OptFieldLen 4537 { 4538 x := types.NewFieldType(mysql.TypeDatetime) 4539 x.Decimal = $2.(int) 4540 $$ = x 4541 } 4542 | "TIMESTAMP" OptFieldLen 4543 { 4544 x := types.NewFieldType(mysql.TypeTimestamp) 4545 x.Decimal = $2.(int) 4546 $$ = x 4547 } 4548 | "TIME" OptFieldLen 4549 { 4550 x := types.NewFieldType(mysql.TypeDuration) 4551 x.Decimal = $2.(int) 4552 $$ = x 4553 } 4554 | "YEAR" OptFieldLen 4555 { 4556 x := types.NewFieldType(mysql.TypeYear) 4557 x.Flen = $2.(int) 4558 $$ = x 4559 } 4560 4561 FieldLen: 4562 '(' LengthNum ')' 4563 { 4564 $$ = int($2.(uint64)) 4565 } 4566 4567 OptFieldLen: 4568 { 4569 /* -1 means unspecified field length*/ 4570 $$ = types.UnspecifiedLength 4571 } 4572 | FieldLen 4573 { 4574 $$ = $1.(int) 4575 } 4576 4577 FieldOpt: 4578 "UNSIGNED" 4579 { 4580 $$ = &ast.TypeOpt{IsUnsigned: true} 4581 } 4582 | "ZEROFILL" 4583 { 4584 $$ = &ast.TypeOpt{IsZerofill: true, IsUnsigned: true} 4585 } 4586 4587 FieldOpts: 4588 { 4589 $$ = []*ast.TypeOpt{} 4590 } 4591 | FieldOpts FieldOpt 4592 { 4593 $$ = append($1.([]*ast.TypeOpt), $2.(*ast.TypeOpt)) 4594 } 4595 4596 FloatOpt: 4597 { 4598 $$ = &ast.FloatOpt{Flen: types.UnspecifiedLength, Decimal: types.UnspecifiedLength} 4599 } 4600 | FieldLen 4601 { 4602 $$ = &ast.FloatOpt{Flen: $1.(int), Decimal: types.UnspecifiedLength} 4603 } 4604 | Precision 4605 { 4606 $$ = $1.(*ast.FloatOpt) 4607 } 4608 4609 Precision: 4610 '(' LengthNum ',' LengthNum ')' 4611 { 4612 $$ = &ast.FloatOpt{Flen: int($2.(uint64)), Decimal: int($4.(uint64))} 4613 } 4614 4615 OptBinary: 4616 { 4617 $$ = false 4618 } 4619 | "BINARY" 4620 { 4621 $$ = true 4622 } 4623 4624 OptCharset: 4625 { 4626 $$ = "" 4627 } 4628 | CharsetKw StringName 4629 { 4630 $$ = $2.(string) 4631 } 4632 4633 CharsetKw: 4634 "CHARACTER" "SET" 4635 | "CHARSET" 4636 4637 OptCollate: 4638 { 4639 $$ = "" 4640 } 4641 | "COLLATE" StringName 4642 { 4643 $$ = $2.(string) 4644 } 4645 4646 StringList: 4647 stringLit 4648 { 4649 $$ = []string{$1.(string)} 4650 } 4651 | StringList ',' stringLit 4652 { 4653 $$ = append($1.([]string), $3.(string)) 4654 } 4655 4656 StringName: 4657 stringLit 4658 { 4659 $$ = $1.(string) 4660 } 4661 | Identifier 4662 { 4663 $$ = $1.(string) 4664 } 4665 4666 /*********************************************************************************** 4667 * Update Statement 4668 * See: https://dev.mysql.com/doc/refman/5.7/en/update.html 4669 ***********************************************************************************/ 4670 UpdateStmt: 4671 "UPDATE" LowPriorityOptional IgnoreOptional TableRef "SET" AssignmentList WhereClauseOptional OrderByOptional LimitClause 4672 { 4673 var refs *ast.Join 4674 if x, ok := $4.(*ast.Join); ok { 4675 refs = x 4676 } else { 4677 refs = &ast.Join{Left: $4.(ast.ResultSetNode)} 4678 } 4679 st := &ast.UpdateStmt{ 4680 LowPriority: $2.(bool), 4681 TableRefs: &ast.TableRefsClause{TableRefs: refs}, 4682 List: $6.([]*ast.Assignment), 4683 } 4684 if $7 != nil { 4685 st.Where = $7.(ast.ExprNode) 4686 } 4687 if $8 != nil { 4688 st.Order = $8.(*ast.OrderByClause) 4689 } 4690 if $9 != nil { 4691 st.Limit = $9.(*ast.Limit) 4692 } 4693 $$ = st 4694 if yylex.(*lexer).root { 4695 break 4696 } 4697 } 4698 | "UPDATE" LowPriorityOptional IgnoreOptional TableRefs "SET" AssignmentList WhereClauseOptional 4699 { 4700 st := &ast.UpdateStmt{ 4701 LowPriority: $2.(bool), 4702 TableRefs: &ast.TableRefsClause{TableRefs: $4.(*ast.Join)}, 4703 List: $6.([]*ast.Assignment), 4704 } 4705 if $7 != nil { 4706 st.Where = $7.(ast.ExprNode) 4707 } 4708 $$ = st 4709 if yylex.(*lexer).root { 4710 break 4711 } 4712 } 4713 4714 UseStmt: 4715 "USE" DBName 4716 { 4717 $$ = &ast.UseStmt{DBName: $2.(string)} 4718 if yylex.(*lexer).root { 4719 break 4720 } 4721 } 4722 4723 WhereClause: 4724 "WHERE" Expression 4725 { 4726 $$ = $2.(ast.ExprNode) 4727 } 4728 4729 WhereClauseOptional: 4730 { 4731 $$ = nil 4732 } 4733 | WhereClause 4734 { 4735 $$ = $1 4736 } 4737 4738 CommaOpt: 4739 { 4740 } 4741 | ',' 4742 { 4743 } 4744 4745 /************************************************************************************ 4746 * Account Management Statements 4747 * https://dev.mysql.com/doc/refman/5.7/en/account-management-sql.html 4748 ************************************************************************************/ 4749 CreateUserStmt: 4750 "CREATE" "USER" IfNotExists UserSpecList 4751 { 4752 // See: https://dev.mysql.com/doc/refman/5.7/en/create-user.html 4753 $$ = &ast.CreateUserStmt{ 4754 IfNotExists: $3.(bool), 4755 Specs: $4.([]*ast.UserSpec), 4756 } 4757 } 4758 4759 UserSpec: 4760 Username AuthOption 4761 { 4762 userSpec := &ast.UserSpec{ 4763 User: $1.(string), 4764 } 4765 if $2 != nil { 4766 userSpec.AuthOpt = $2.(*ast.AuthOption) 4767 } 4768 $$ = userSpec 4769 } 4770 4771 UserSpecList: 4772 UserSpec 4773 { 4774 $$ = []*ast.UserSpec{$1.(*ast.UserSpec)} 4775 } 4776 | UserSpecList ',' UserSpec 4777 { 4778 $$ = append($1.([]*ast.UserSpec), $3.(*ast.UserSpec)) 4779 } 4780 4781 AuthOption: 4782 { 4783 $$ = nil 4784 } 4785 | "IDENTIFIED" "BY" AuthString 4786 { 4787 $$ = &ast.AuthOption { 4788 AuthString: $3.(string), 4789 ByAuthString: true, 4790 } 4791 } 4792 | "IDENTIFIED" "BY" "PASSWORD" HashString 4793 { 4794 $$ = &ast.AuthOption{ 4795 HashString: $4.(string), 4796 } 4797 } 4798 4799 HashString: 4800 stringLit 4801 4802 /************************************************************************************* 4803 * Grant statement 4804 * See: https://dev.mysql.com/doc/refman/5.7/en/grant.html 4805 *************************************************************************************/ 4806 GrantStmt: 4807 "GRANT" PrivElemList "ON" ObjectType PrivLevel "TO" UserSpecList 4808 { 4809 $$ = &ast.GrantStmt{ 4810 Privs: $2.([]*ast.PrivElem), 4811 ObjectType: $4.(ast.ObjectTypeType), 4812 Level: $5.(*ast.GrantLevel), 4813 Users: $7.([]*ast.UserSpec), 4814 } 4815 } 4816 4817 PrivElem: 4818 PrivType 4819 { 4820 $$ = &ast.PrivElem{ 4821 Priv: $1.(mysql.PrivilegeType), 4822 } 4823 } 4824 | PrivType '(' ColumnNameList ')' 4825 { 4826 $$ = &ast.PrivElem{ 4827 Priv: $1.(mysql.PrivilegeType), 4828 Cols: $3.([]*ast.ColumnName), 4829 } 4830 } 4831 4832 PrivElemList: 4833 PrivElem 4834 { 4835 $$ = []*ast.PrivElem{$1.(*ast.PrivElem)} 4836 } 4837 | PrivElemList ',' PrivElem 4838 { 4839 $$ = append($1.([]*ast.PrivElem), $3.(*ast.PrivElem)) 4840 } 4841 4842 PrivType: 4843 "ALL" 4844 { 4845 $$ = mysql.AllPriv 4846 } 4847 | "ALTER" 4848 { 4849 $$ = mysql.AlterPriv 4850 } 4851 | "CREATE" 4852 { 4853 $$ = mysql.CreatePriv 4854 } 4855 | "CREATE" "USER" 4856 { 4857 $$ = mysql.CreateUserPriv 4858 } 4859 | "DELETE" 4860 { 4861 $$ = mysql.DeletePriv 4862 } 4863 | "DROP" 4864 { 4865 $$ = mysql.DropPriv 4866 } 4867 | "EXECUTE" 4868 { 4869 $$ = mysql.ExecutePriv 4870 } 4871 | "INDEX" 4872 { 4873 $$ = mysql.IndexPriv 4874 } 4875 | "INSERT" 4876 { 4877 $$ = mysql.InsertPriv 4878 } 4879 | "SELECT" 4880 { 4881 $$ = mysql.SelectPriv 4882 } 4883 | "SHOW" "DATABASES" 4884 { 4885 $$ = mysql.ShowDBPriv 4886 } 4887 | "UPDATE" 4888 { 4889 $$ = mysql.UpdatePriv 4890 } 4891 | "GRANT" "OPTION" 4892 { 4893 $$ = mysql.GrantPriv 4894 } 4895 4896 ObjectType: 4897 { 4898 $$ = ast.ObjectTypeNone 4899 } 4900 | "TABLE" 4901 { 4902 $$ = ast.ObjectTypeTable 4903 } 4904 4905 PrivLevel: 4906 '*' 4907 { 4908 $$ = &ast.GrantLevel { 4909 Level: ast.GrantLevelDB, 4910 } 4911 } 4912 | '*' '.' '*' 4913 { 4914 $$ = &ast.GrantLevel { 4915 Level: ast.GrantLevelGlobal, 4916 } 4917 } 4918 | Identifier '.' '*' 4919 { 4920 $$ = &ast.GrantLevel { 4921 Level: ast.GrantLevelDB, 4922 DBName: $1.(string), 4923 } 4924 } 4925 | Identifier '.' Identifier 4926 { 4927 $$ = &ast.GrantLevel { 4928 Level: ast.GrantLevelTable, 4929 DBName: $1.(string), 4930 TableName: $3.(string), 4931 } 4932 } 4933 | Identifier 4934 { 4935 $$ = &ast.GrantLevel { 4936 Level: ast.GrantLevelTable, 4937 TableName: $1.(string), 4938 } 4939 } 4940 4941 /********************************************************************* 4942 * Lock/Unlock Tables 4943 * See: http://dev.mysql.com/doc/refman/5.7/en/lock-tables.html 4944 * All the statement leaves empty. This is used to prevent mysqldump error. 4945 *********************************************************************/ 4946 4947 UnlockTablesStmt: 4948 "UNLOCK" "TABLES" 4949 4950 LockTablesStmt: 4951 "LOCK" "TABLES" TableLockList 4952 4953 TableLock: 4954 TableName LockType 4955 4956 LockType: 4957 "READ" 4958 | "READ" "LOCAL" 4959 | "WRITE" 4960 4961 TableLockList: 4962 TableLock 4963 | TableLockList ',' TableLock 4964 4965 %%