github.com/XiaoMi/Gaea@v1.2.5/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/XiaoMi/Gaea/mysql" 32 "github.com/XiaoMi/Gaea/parser/ast" 33 "github.com/XiaoMi/Gaea/parser/model" 34 "github.com/XiaoMi/Gaea/parser/opcode" 35 "github.com/XiaoMi/Gaea/parser/auth" 36 "github.com/XiaoMi/Gaea/parser/types" 37 ) 38 39 %} 40 41 %union { 42 offset int // offset 43 item interface{} 44 ident string 45 expr ast.ExprNode 46 statement ast.StmtNode 47 } 48 49 %token <ident> 50 /*yy:token "%c" */ identifier "identifier" 51 /*yy:token "_%c" */ underscoreCS "UNDERSCORE_CHARSET" 52 /*yy:token "\"%c\"" */ stringLit "string literal" 53 singleAtIdentifier "identifier with single leading at" 54 doubleAtIdentifier "identifier with double leading at" 55 invalid "a special token never used by parser, used by lexer to indicate error" 56 hintBegin "hintBegin is a virtual token for optimizer hint grammar" 57 hintEnd "hintEnd is a virtual token for optimizer hint grammar" 58 andand "&&" 59 pipes "||" 60 61 /* The following tokens belong to ODBCDateTimeType. */ 62 odbcDateType "d" 63 odbcTimeType "t" 64 odbcTimestampType "ts" 65 66 /* The following tokens belong to ReservedKeyword. */ 67 add "ADD" 68 all "ALL" 69 alter "ALTER" 70 analyze "ANALYZE" 71 and "AND" 72 as "AS" 73 asc "ASC" 74 between "BETWEEN" 75 bigIntType "BIGINT" 76 binaryType "BINARY" 77 blobType "BLOB" 78 both "BOTH" 79 by "BY" 80 cascade "CASCADE" 81 caseKwd "CASE" 82 change "CHANGE" 83 character "CHARACTER" 84 charType "CHAR" 85 check "CHECK" 86 collate "COLLATE" 87 column "COLUMN" 88 constraint "CONSTRAINT" 89 convert "CONVERT" 90 create "CREATE" 91 cross "CROSS" 92 cumeDist "CUME_DIST" 93 currentDate "CURRENT_DATE" 94 currentTime "CURRENT_TIME" 95 currentTs "CURRENT_TIMESTAMP" 96 currentUser "CURRENT_USER" 97 database "DATABASE" 98 databases "DATABASES" 99 dayHour "DAY_HOUR" 100 dayMicrosecond "DAY_MICROSECOND" 101 dayMinute "DAY_MINUTE" 102 daySecond "DAY_SECOND" 103 decimalType "DECIMAL" 104 defaultKwd "DEFAULT" 105 delayed "DELAYED" 106 deleteKwd "DELETE" 107 denseRank "DENSE_RANK" 108 desc "DESC" 109 describe "DESCRIBE" 110 distinct "DISTINCT" 111 distinctRow "DISTINCTROW" 112 div "DIV" 113 doubleType "DOUBLE" 114 drop "DROP" 115 dual "DUAL" 116 elseKwd "ELSE" 117 enclosed "ENCLOSED" 118 escaped "ESCAPED" 119 exists "EXISTS" 120 explain "EXPLAIN" 121 except "EXCEPT" 122 falseKwd "FALSE" 123 firstValue "FIRST_VALUE" 124 floatType "FLOAT" 125 forKwd "FOR" 126 force "FORCE" 127 foreign "FOREIGN" 128 from "FROM" 129 fulltext "FULLTEXT" 130 generated "GENERATED" 131 grant "GRANT" 132 group "GROUP" 133 groups "GROUPS" 134 having "HAVING" 135 highPriority "HIGH_PRIORITY" 136 hourMicrosecond "HOUR_MICROSECOND" 137 hourMinute "HOUR_MINUTE" 138 hourSecond "HOUR_SECOND" 139 ifKwd "IF" 140 ignore "IGNORE" 141 in "IN" 142 index "INDEX" 143 infile "INFILE" 144 inner "INNER" 145 integerType "INTEGER" 146 interval "INTERVAL" 147 into "INTO" 148 is "IS" 149 insert "INSERT" 150 intType "INT" 151 int1Type "INT1" 152 int2Type "INT2" 153 int3Type "INT3" 154 int4Type "INT4" 155 int8Type "INT8" 156 join "JOIN" 157 key "KEY" 158 keys "KEYS" 159 kill "KILL" 160 lag "LAG" 161 lastValue "LAST_VALUE" 162 lead "LEAD" 163 leading "LEADING" 164 left "LEFT" 165 like "LIKE" 166 limit "LIMIT" 167 lines "LINES" 168 load "LOAD" 169 localTime "LOCALTIME" 170 localTs "LOCALTIMESTAMP" 171 lock "LOCK" 172 longblobType "LONGBLOB" 173 longtextType "LONGTEXT" 174 lowPriority "LOW_PRIORITY" 175 maxValue "MAXVALUE" 176 mediumblobType "MEDIUMBLOB" 177 mediumIntType "MEDIUMINT" 178 mediumtextType "MEDIUMTEXT" 179 minuteMicrosecond "MINUTE_MICROSECOND" 180 minuteSecond "MINUTE_SECOND" 181 mod "MOD" 182 not "NOT" 183 noWriteToBinLog "NO_WRITE_TO_BINLOG" 184 nthValue "NTH_VALUE" 185 ntile "NTILE" 186 null "NULL" 187 numericType "NUMERIC" 188 nvarcharType "NVARCHAR" 189 on "ON" 190 option "OPTION" 191 optionally "OPTIONALLY" 192 or "OR" 193 order "ORDER" 194 outer "OUTER" 195 over "OVER" 196 packKeys "PACK_KEYS" 197 partition "PARTITION" 198 percentRank "PERCENT_RANK" 199 precisionType "PRECISION" 200 primary "PRIMARY" 201 procedure "PROCEDURE" 202 shardRowIDBits "SHARD_ROW_ID_BITS" 203 rangeKwd "RANGE" 204 rank "RANK" 205 read "READ" 206 realType "REAL" 207 references "REFERENCES" 208 regexpKwd "REGEXP" 209 rename "RENAME" 210 repeat "REPEAT" 211 replace "REPLACE" 212 restrict "RESTRICT" 213 revoke "REVOKE" 214 right "RIGHT" 215 rlike "RLIKE" 216 row "ROW" 217 rows "ROWS" 218 rowNumber "ROW_NUMBER" 219 secondMicrosecond "SECOND_MICROSECOND" 220 selectKwd "SELECT" 221 set "SET" 222 show "SHOW" 223 smallIntType "SMALLINT" 224 sql "SQL" 225 sqlCalcFoundRows "SQL_CALC_FOUND_ROWS" 226 starting "STARTING" 227 straightJoin "STRAIGHT_JOIN" 228 tableKwd "TABLE" 229 stored "STORED" 230 terminated "TERMINATED" 231 then "THEN" 232 tinyblobType "TINYBLOB" 233 tinyIntType "TINYINT" 234 tinytextType "TINYTEXT" 235 to "TO" 236 trailing "TRAILING" 237 trigger "TRIGGER" 238 trueKwd "TRUE" 239 unique "UNIQUE" 240 union "UNION" 241 unlock "UNLOCK" 242 unsigned "UNSIGNED" 243 update "UPDATE" 244 usage "USAGE" 245 use "USE" 246 using "USING" 247 utcDate "UTC_DATE" 248 utcTimestamp "UTC_TIMESTAMP" 249 utcTime "UTC_TIME" 250 values "VALUES" 251 long "LONG" 252 varcharType "VARCHAR" 253 varbinaryType "VARBINARY" 254 virtual "VIRTUAL" 255 when "WHEN" 256 where "WHERE" 257 write "WRITE" 258 window "WINDOW" 259 with "WITH" 260 xor "XOR" 261 yearMonth "YEAR_MONTH" 262 zerofill "ZEROFILL" 263 natural "NATURAL" 264 265 /* The following tokens belong to UnReservedKeyword. */ 266 action "ACTION" 267 after "AFTER" 268 always "ALWAYS" 269 algorithm "ALGORITHM" 270 any "ANY" 271 ascii "ASCII" 272 autoIncrement "AUTO_INCREMENT" 273 avgRowLength "AVG_ROW_LENGTH" 274 avg "AVG" 275 begin "BEGIN" 276 binlog "BINLOG" 277 bitType "BIT" 278 booleanType "BOOLEAN" 279 boolType "BOOL" 280 btree "BTREE" 281 byteType "BYTE" 282 cascaded "CASCADED" 283 charsetKwd "CHARSET" 284 checksum "CHECKSUM" 285 cleanup "CLEANUP" 286 client "CLIENT" 287 coalesce "COALESCE" 288 collation "COLLATION" 289 columns "COLUMNS" 290 comment "COMMENT" 291 commit "COMMIT" 292 committed "COMMITTED" 293 compact "COMPACT" 294 compressed "COMPRESSED" 295 compression "COMPRESSION" 296 connection "CONNECTION" 297 consistent "CONSISTENT" 298 current "CURRENT" 299 day "DAY" 300 data "DATA" 301 dateType "DATE" 302 datetimeType "DATETIME" 303 deallocate "DEALLOCATE" 304 definer "DEFINER" 305 delayKeyWrite "DELAY_KEY_WRITE" 306 disable "DISABLE" 307 do "DO" 308 duplicate "DUPLICATE" 309 dynamic "DYNAMIC" 310 enable "ENABLE" 311 end "END" 312 engine "ENGINE" 313 engines "ENGINES" 314 enum "ENUM" 315 event "EVENT" 316 events "EVENTS" 317 escape "ESCAPE" 318 exclusive "EXCLUSIVE" 319 execute "EXECUTE" 320 fields "FIELDS" 321 first "FIRST" 322 fixed "FIXED" 323 flush "FLUSH" 324 following "FOLLOWING" 325 format "FORMAT" 326 full "FULL" 327 function "FUNCTION" 328 grants "GRANTS" 329 hash "HASH" 330 hour "HOUR" 331 identified "IDENTIFIED" 332 isolation "ISOLATION" 333 indexes "INDEXES" 334 invoker "INVOKER" 335 jsonType "JSON" 336 keyBlockSize "KEY_BLOCK_SIZE" 337 local "LOCAL" 338 last "LAST" 339 less "LESS" 340 level "LEVEL" 341 master "MASTER" 342 microsecond "MICROSECOND" 343 minute "MINUTE" 344 mode "MODE" 345 modify "MODIFY" 346 month "MONTH" 347 maxRows "MAX_ROWS" 348 maxConnectionsPerHour "MAX_CONNECTIONS_PER_HOUR" 349 maxQueriesPerHour "MAX_QUERIES_PER_HOUR" 350 maxUpdatesPerHour "MAX_UPDATES_PER_HOUR" 351 maxUserConnections "MAX_USER_CONNECTIONS" 352 merge "MERGE" 353 minRows "MIN_ROWS" 354 names "NAMES" 355 national "NATIONAL" 356 no "NO" 357 none "NONE" 358 nulls "NULLS" 359 offset "OFFSET" 360 only "ONLY" 361 password "PASSWORD" 362 partitions "PARTITIONS" 363 pipesAsOr 364 plugins "PLUGINS" 365 preceding "PRECEDING" 366 prepare "PREPARE" 367 privileges "PRIVILEGES" 368 process "PROCESS" 369 processlist "PROCESSLIST" 370 profiles "PROFILES" 371 quarter "QUARTER" 372 query "QUERY" 373 queries "QUERIES" 374 quick "QUICK" 375 recover "RECOVER" 376 redundant "REDUNDANT" 377 reload "RELOAD" 378 repeatable "REPEATABLE" 379 respect "RESPECT" 380 replication "REPLICATION" 381 reverse "REVERSE" 382 role "ROLE" 383 rollback "ROLLBACK" 384 routine "ROUTINE" 385 rowCount "ROW_COUNT" 386 rowFormat "ROW_FORMAT" 387 savepoint "SAVEPOINT" 388 second "SECOND" 389 security "SECURITY" 390 separator "SEPARATOR" 391 serializable "SERIALIZABLE" 392 session "SESSION" 393 share "SHARE" 394 shared "SHARED" 395 signed "SIGNED" 396 slave "SLAVE" 397 slow "SLOW" 398 snapshot "SNAPSHOT" 399 sqlCache "SQL_CACHE" 400 sqlNoCache "SQL_NO_CACHE" 401 start "START" 402 statsPersistent "STATS_PERSISTENT" 403 status "STATUS" 404 subpartition "SUBPARTITION" 405 subpartitions "SUBPARTITIONS" 406 super "SUPER" 407 some "SOME" 408 global "GLOBAL" 409 tables "TABLES" 410 tablespace "TABLESPACE" 411 temporary "TEMPORARY" 412 temptable "TEMPTABLE" 413 textType "TEXT" 414 than "THAN" 415 timeType "TIME" 416 timestampType "TIMESTAMP" 417 trace "TRACE" 418 transaction "TRANSACTION" 419 triggers "TRIGGERS" 420 truncate "TRUNCATE" 421 unbounded "UNBOUNDED" 422 uncommitted "UNCOMMITTED" 423 unknown "UNKNOWN" 424 user "USER" 425 undefined "UNDEFINED" 426 value "VALUE" 427 variables "VARIABLES" 428 view "VIEW" 429 binding "BINDING" 430 bindings "BINDINGS" 431 warnings "WARNINGS" 432 identSQLErrors "ERRORS" 433 week "WEEK" 434 yearType "YEAR" 435 work "WORK" 436 chain "CHAIN" 437 release "RELEASE" 438 439 /* The following tokens belong to NotKeywordToken. */ 440 addDate "ADDDATE" 441 bitAnd "BIT_AND" 442 bitOr "BIT_OR" 443 bitXor "BIT_XOR" 444 cast "CAST" 445 copyKwd "COPY" 446 count "COUNT" 447 curTime "CURTIME" 448 dateAdd "DATE_ADD" 449 dateSub "DATE_SUB" 450 extract "EXTRACT" 451 getFormat "GET_FORMAT" 452 groupConcat "GROUP_CONCAT" 453 next_row_id "NEXT_ROW_ID" 454 inplace "INPLACE" 455 instant "INSTANT" 456 internal "INTERNAL" 457 min "MIN" 458 max "MAX" 459 maxExecutionTime "MAX_EXECUTION_TIME" 460 now "NOW" 461 position "POSITION" 462 recent "RECENT" 463 std "STD" 464 stddev "STDDEV" 465 stddevPop "STDDEV_POP" 466 stddevSamp "STDDEV_SAMP" 467 subDate "SUBDATE" 468 sum "SUM" 469 substring "SUBSTRING" 470 timestampAdd "TIMESTAMPADD" 471 timestampDiff "TIMESTAMPDIFF" 472 top "TOP" 473 trim "TRIM" 474 variance "VARIANCE" 475 varPop "VAR_POP" 476 varSamp "VAR_SAMP" 477 478 /* The following tokens belong to TiDBKeyword. */ 479 admin "ADMIN" 480 buckets "BUCKETS" 481 cancel "CANCEL" 482 ddl "DDL" 483 drainer "DRAINER" 484 jobs "JOBS" 485 job "JOB" 486 pump "PUMP" 487 stats "STATS" 488 statsMeta "STATS_META" 489 statsHistograms "STATS_HISTOGRAMS" 490 statsBuckets "STATS_BUCKETS" 491 statsHealthy "STATS_HEALTHY" 492 tidb "TIDB" 493 tidbHJ "TIDB_HJ" 494 tidbSMJ "TIDB_SMJ" 495 tidbINLJ "TIDB_INLJ" 496 restore "RESTORE" 497 498 builtinAddDate 499 builtinBitAnd 500 builtinBitOr 501 builtinBitXor 502 builtinCast 503 builtinCount 504 builtinCurDate 505 builtinCurTime 506 builtinDateAdd 507 builtinDateSub 508 builtinExtract 509 builtinGroupConcat 510 builtinMax 511 builtinMin 512 builtinNow 513 builtinPosition 514 builtinSubDate 515 builtinSubstring 516 builtinSum 517 builtinSysDate 518 builtinStddevPop 519 builtinStddevSamp 520 builtinTrim 521 builtinUser 522 builtinVarPop 523 builtinVarSamp 524 525 %token <item> 526 527 /*yy:token "1.%d" */ floatLit "floating-point literal" 528 /*yy:token "1.%d" */ decLit "decimal literal" 529 /*yy:token "%d" */ intLit "integer literal" 530 /*yy:token "%x" */ hexLit "hexadecimal literal" 531 /*yy:token "%b" */ bitLit "bit literal" 532 533 andnot "&^" 534 assignmentEq ":=" 535 eq "=" 536 ge ">=" 537 le "<=" 538 jss "->" 539 juss "->>" 540 lsh "<<" 541 neq "!=" 542 neqSynonym "<>" 543 nulleq "<=>" 544 paramMarker "?" 545 rsh ">>" 546 547 %token not2 548 549 %type <expr> 550 Expression "expression" 551 MaxValueOrExpression "maxvalue or expression" 552 BoolPri "boolean primary expression" 553 ExprOrDefault "expression or default" 554 PredicateExpr "Predicate expression factor" 555 SetExpr "Set variable statement value's expression" 556 BitExpr "bit expression" 557 SimpleExpr "simple expression" 558 SimpleIdent "Simple Identifier expression" 559 SumExpr "aggregate functions" 560 FunctionCallGeneric "Function call with Identifier" 561 FunctionCallKeyword "Function call with keyword as function name" 562 FunctionCallNonKeyword "Function call with nonkeyword as function name" 563 Literal "literal value" 564 Variable "User or system variable" 565 SystemVariable "System defined variable name" 566 UserVariable "User defined variable name" 567 SubSelect "Sub Select" 568 StringLiteral "text literal" 569 ExpressionOpt "Optional expression" 570 SignedLiteral "Literal or NumLiteral with sign" 571 DefaultValueExpr "DefaultValueExpr(Now or Signed Literal)" 572 NowSymOptionFraction "NowSym with optional fraction part" 573 574 %type <statement> 575 AdminStmt "Check table statement or show ddl statement" 576 AlterTableStmt "Alter table statement" 577 AlterUserStmt "Alter user statement" 578 AnalyzeTableStmt "Analyze table statement" 579 BeginTransactionStmt "BEGIN TRANSACTION statement" 580 BinlogStmt "Binlog base64 statement" 581 CommitStmt "COMMIT statement" 582 CreateTableStmt "CREATE TABLE statement" 583 CreateViewStmt "CREATE VIEW stetement" 584 CreateUserStmt "CREATE User statement" 585 CreateRoleStmt "CREATE Role statement" 586 CreateDatabaseStmt "Create Database Statement" 587 CreateIndexStmt "CREATE INDEX statement" 588 CreateBindingStmt "CREATE BINDING statement" 589 DoStmt "Do statement" 590 DropDatabaseStmt "DROP DATABASE statement" 591 DropIndexStmt "DROP INDEX statement" 592 DropStatsStmt "DROP STATS statement" 593 DropTableStmt "DROP TABLE statement" 594 DropUserStmt "DROP USER" 595 DropRoleStmt "DROP ROLE" 596 DropViewStmt "DROP VIEW statement" 597 DropBindingStmt "DROP BINDING statement" 598 DeallocateStmt "Deallocate prepared statement" 599 DeleteFromStmt "DELETE FROM statement" 600 EmptyStmt "empty statement" 601 ExecuteStmt "Execute statement" 602 ExplainStmt "EXPLAIN statement" 603 ExplainableStmt "explainable statement" 604 FlushStmt "Flush statement" 605 GrantStmt "Grant statement" 606 GrantRoleStmt "Grant role statement" 607 InsertIntoStmt "INSERT INTO statement" 608 KillStmt "Kill statement" 609 LoadDataStmt "Load data statement" 610 LoadStatsStmt "Load statistic statement" 611 LockTablesStmt "Lock tables statement" 612 PreparedStmt "PreparedStmt" 613 SelectStmt "SELECT statement" 614 RenameTableStmt "rename table statement" 615 ReplaceIntoStmt "REPLACE INTO statement" 616 RevokeStmt "Revoke statement" 617 RevokeRoleStmt "Revoke role statement" 618 RollbackStmt "ROLLBACK statement" 619 SavepointStmt "SAVEPOINT statement" 620 SetStmt "Set variable statement" 621 SetRoleStmt "Set active role statement" 622 SetDefaultRoleStmt "Set default statement for some user" 623 ShowStmt "Show engines/databases/tables/user/columns/warnings/status statement" 624 Statement "statement" 625 TraceStmt "TRACE statement" 626 TraceableStmt "traceable statment" 627 TruncateTableStmt "TRUNCATE TABLE statement" 628 UnlockTablesStmt "Unlock tables statement" 629 UpdateStmt "UPDATE statement" 630 UnionStmt "Union select state ment" 631 UseStmt "USE statement" 632 633 %type <item> 634 AdminShowSlow "Admin Show Slow statement" 635 AlterAlgorithm "Alter table algorithm" 636 AlterTableOptionListOpt "Alter table option list opt" 637 AlterTableSpec "Alter table specification" 638 AlterTableSpecList "Alter table specification list" 639 AnyOrAll "Any or All for subquery" 640 Assignment "assignment" 641 AssignmentList "assignment list" 642 AssignmentListOpt "assignment list opt" 643 AuthOption "User auth option" 644 AuthString "Password string value" 645 OptionalBraces "optional braces" 646 CastType "Cast function target type" 647 CharsetName "Character set name" 648 ColumnDef "table column definition" 649 ColumnDefList "table column definition list" 650 ColumnName "column name" 651 ColumnNameList "column name list" 652 ColumnList "column list" 653 ColumnNameListOpt "column name list opt" 654 ColumnNameListOptWithBrackets "column name list opt with brackets" 655 ColumnSetValue "insert statement set value by column name" 656 ColumnSetValueList "insert statement set value by column name list" 657 CommitOpt "Commit options" 658 CompareOp "Compare opcode" 659 ColumnOption "column definition option" 660 ColumnOptionList "column definition option list" 661 VirtualOrStored "indicate generated column is stored or not" 662 ColumnOptionListOpt "optional column definition option list" 663 Constraint "table constraint" 664 ConstraintElem "table constraint element" 665 ConstraintKeywordOpt "Constraint Keyword or empty" 666 CreateIndexStmtUnique "CREATE INDEX optional UNIQUE clause" 667 CreateTableOptionListOpt "create table option list opt" 668 CreateTableSelectOpt "Select/Union statement in CREATE TABLE ... SELECT" 669 DatabaseOption "CREATE Database specification" 670 DatabaseOptionList "CREATE Database specification list" 671 DatabaseOptionListOpt "CREATE Database specification list opt" 672 DBName "Database Name" 673 DistinctOpt "Explicit distinct option" 674 DefaultFalseDistinctOpt "Distinct option which defaults to false" 675 DefaultTrueDistinctOpt "Distinct option which defaults to true" 676 BuggyDefaultFalseDistinctOpt "Distinct option which accepts DISTINCT ALL and defaults to false" 677 Enclosed "Enclosed by" 678 EqOpt "= or empty" 679 EscapedTableRef "escaped table reference" 680 Escaped "Escaped by" 681 ExpressionList "expression list" 682 MaxValueOrExpressionList "maxvalue or expression list" 683 ExpressionListOpt "expression list opt" 684 FuncDatetimePrecListOpt "Function datetime precision list opt" 685 FuncDatetimePrecList "Function datetime precision list" 686 Field "field expression" 687 Fields "Fields clause" 688 FieldsTerminated "Fields terminated by" 689 FieldAsName "Field alias name" 690 FieldAsNameOpt "Field alias name opt" 691 FieldList "field expression list" 692 FlushOption "Flush option" 693 PluginNameList "Plugin Name List" 694 TableRefsClause "Table references clause" 695 FuncDatetimePrec "Function datetime precision" 696 GlobalScope "The scope of variable" 697 GroupByClause "GROUP BY clause" 698 HashString "Hashed string" 699 HavingClause "HAVING clause" 700 HandleRange "handle range" 701 HandleRangeList "handle range list" 702 IfExists "If Exists" 703 IfNotExists "If Not Exists" 704 IgnoreOptional "IGNORE or empty" 705 IndexColName "Index column name" 706 IndexColNameList "List of index column name" 707 IndexHint "index hint" 708 IndexHintList "index hint list" 709 IndexHintListOpt "index hint list opt" 710 IndexHintScope "index hint scope" 711 IndexHintType "index hint type" 712 IndexName "index name" 713 IndexNameList "index name list" 714 IndexOption "Index Option" 715 IndexOptionList "Index Option List or empty" 716 IndexType "index type" 717 IndexTypeOpt "Optional index type" 718 InsertValues "Rest part of INSERT/REPLACE INTO statement" 719 JoinTable "join table" 720 JoinType "join type" 721 KillOrKillTiDB "Kill or Kill TiDB" 722 LikeEscapeOpt "like escape option" 723 LikeTableWithOrWithoutParen "LIKE table_name or ( LIKE table_name )" 724 LimitClause "LIMIT clause" 725 LimitOption "Limit option could be integer or parameter marker." 726 Lines "Lines clause" 727 LinesTerminated "Lines terminated by" 728 LocalOpt "Local opt" 729 LockClause "Alter table lock clause" 730 MaxNumBuckets "Max number of buckets" 731 NumLiteral "Num/Int/Float/Decimal Literal" 732 NoWriteToBinLogAliasOpt "NO_WRITE_TO_BINLOG alias LOCAL or empty" 733 ObjectType "Grant statement object type" 734 OnDuplicateKeyUpdate "ON DUPLICATE KEY UPDATE value list" 735 DuplicateOpt "[IGNORE|REPLACE] in CREATE TABLE ... SELECT statement" 736 OptFull "Full or empty" 737 Order "ORDER BY clause optional collation specification" 738 OrderBy "ORDER BY clause" 739 OrReplace "or replace" 740 ByItem "BY item" 741 OrderByOptional "Optional ORDER BY clause optional" 742 ByList "BY list" 743 QuickOptional "QUICK or empty" 744 PartitionDefinition "Partition definition" 745 PartitionDefinitionList "Partition definition list" 746 PartitionDefinitionListOpt "Partition definition list option" 747 PartitionOpt "Partition option" 748 PartitionNameList "Partition name list" 749 PartitionNameListOpt "table partition names list optional" 750 PartitionNumOpt "PARTITION NUM option" 751 PartDefValuesOpt "VALUES {LESS THAN {(expr | value_list) | MAXVALUE} | IN {value_list}" 752 PartDefOptionsOpt "PartDefOptionList option" 753 PartDefOptionList "PartDefOption list" 754 PartDefOption "COMMENT [=] xxx | TABLESPACE [=] tablespace_name | ENGINE [=] xxx" 755 PasswordOpt "Password option" 756 ColumnPosition "Column position [First|After ColumnName]" 757 PrepareSQL "Prepare statement sql string" 758 PriorityOpt "Statement priority option" 759 PrivElem "Privilege element" 760 PrivElemList "Privilege element list" 761 PrivLevel "Privilege scope" 762 PrivType "Privilege type" 763 ReferDef "Reference definition" 764 OnDeleteOpt "optional ON DELETE clause" 765 OnUpdateOpt "optional ON UPDATE clause" 766 OptGConcatSeparator "optional GROUP_CONCAT SEPARATOR" 767 ReferOpt "reference option" 768 Rolename "Rolename" 769 RolenameList "RolenameList" 770 RoleSpec "Rolename and auth option" 771 RoleSpecList "Rolename and auth option list" 772 RoleNameString "role name string" 773 RowFormat "Row format option" 774 RowValue "Row value" 775 SelectLockOpt "FOR UPDATE or LOCK IN SHARE MODE," 776 SelectStmtCalcFoundRows "SELECT statement optional SQL_CALC_FOUND_ROWS" 777 SelectStmtSQLCache "SELECT statement optional SQL_CAHCE/SQL_NO_CACHE" 778 SelectStmtStraightJoin "SELECT statement optional STRAIGHT_JOIN" 779 SelectStmtFieldList "SELECT statement field list" 780 SelectStmtLimit "SELECT statement optional LIMIT clause" 781 SelectStmtOpts "Select statement options" 782 SelectStmtBasic "SELECT statement from constant value" 783 SelectStmtFromDualTable "SELECT statement from dual table" 784 SelectStmtFromTable "SELECT statement from table" 785 SelectStmtGroup "SELECT statement optional GROUP BY clause" 786 SetRoleOpt "Set role options" 787 SetDefaultRoleOpt "Set default role options" 788 ShowTargetFilterable "Show target that can be filtered by WHERE or LIKE" 789 ShowDatabaseNameOpt "Show tables/columns statement database name option" 790 ShowTableAliasOpt "Show table alias option" 791 ShowLikeOrWhereOpt "Show like or where clause option" 792 Starting "Starting by" 793 StatementList "statement list" 794 StatsPersistentVal "stats_persistent value" 795 StringName "string literal or identifier" 796 StringList "string list" 797 SubPartitionOpt "SubPartition option" 798 SubPartitionNumOpt "SubPartition NUM option" 799 Symbol "Constraint Symbol" 800 TableAsName "table alias name" 801 TableAsNameOpt "table alias name optional" 802 TableElement "table definition element" 803 TableElementList "table definition element list" 804 TableElementListOpt "table definition element list optional" 805 TableFactor "table factor" 806 TableLock "Table name and lock type" 807 TableLockList "Table lock list" 808 TableName "Table name" 809 TableNameList "Table name list" 810 TableNameListOpt "Table name list opt" 811 TableOption "create table option" 812 TableOptionList "create table option list" 813 TableRef "table reference" 814 TableRefs "table references" 815 TableToTable "rename table to table" 816 TableToTableList "rename table to table by list" 817 818 TransactionChar "Transaction characteristic" 819 TransactionChars "Transaction characteristic list" 820 TrimDirection "Trim string direction" 821 UnionOpt "Union Option(empty/ALL/DISTINCT)" 822 UnionClauseList "Union select clause list" 823 UnionSelect "Union (select) item" 824 Username "Username" 825 UsernameList "UsernameList" 826 UserSpec "Username and auth option" 827 UserSpecList "Username and auth option list" 828 UserVariableList "User defined variable name list" 829 Values "values" 830 ValuesList "values list" 831 ValuesOpt "values optional" 832 VariableAssignment "set variable value" 833 VariableAssignmentList "set variable value list" 834 ViewAlgorithm "view algorithm" 835 ViewCheckOption "view check option" 836 ViewDefiner "view definer" 837 ViewName "view name" 838 ViewFieldList "create view statement field list" 839 ViewSQLSecurity "view sql security" 840 WhereClause "WHERE clause" 841 WhereClauseOptional "Optional WHERE clause" 842 WhenClause "When clause" 843 WhenClauseList "When clause list" 844 WithReadLockOpt "With Read Lock opt" 845 WithGrantOptionOpt "With Grant Option opt" 846 ElseOpt "Optional else clause" 847 Type "Types" 848 849 OptExistingWindowName "Optional existing WINDOW name" 850 OptFromFirstLast "Optional FROM FIRST/LAST" 851 OptLLDefault "Optional LEAD/LAG default" 852 OptLeadLagInfo "Optional LEAD/LAG info" 853 OptNullTreatment "Optional NULL treatment" 854 OptPartitionClause "Optional PARTITION clause" 855 OptWindowOrderByClause "Optional ORDER BY clause in WINDOW" 856 OptWindowFrameClause "Optional FRAME clause in WINDOW" 857 OptWindowingClause "Optional OVER clause" 858 WindowingClause "OVER clause" 859 WindowClauseOptional "Optional WINDOW clause" 860 WindowDefinitionList "WINDOW definition list" 861 WindowDefinition "WINDOW definition" 862 WindowFrameUnits "WINDOW frame units" 863 WindowFrameBetween "WINDOW frame between" 864 WindowFrameBound "WINDOW frame bound" 865 WindowFrameExtent "WINDOW frame extent" 866 WindowFrameStart "WINDOW frame start" 867 WindowFuncCall "WINDOW function call" 868 WindowName "WINDOW name" 869 WindowNameOrSpec "WINDOW name or spec" 870 WindowSpec "WINDOW spec" 871 WindowSpecDetails "WINDOW spec details" 872 873 BetweenOrNotOp "Between predicate" 874 IsOrNotOp "Is predicate" 875 InOrNotOp "In predicate" 876 LikeOrNotOp "Like predicate" 877 RegexpOrNotOp "Regexp predicate" 878 879 NumericType "Numeric types" 880 IntegerType "Integer Types types" 881 BooleanType "Boolean Types types" 882 FixedPointType "Exact value types" 883 FloatingPointType "Approximate value types" 884 BitValueType "bit value types" 885 StringType "String types" 886 BlobType "Blob types" 887 TextType "Text types" 888 DateAndTimeType "Date and Time types" 889 890 OptFieldLen "Field length or empty" 891 FieldLen "Field length" 892 FieldOpts "Field type definition option list" 893 FieldOpt "Field type definition option" 894 FloatOpt "Floating-point type option" 895 Precision "Floating-point precision option" 896 OptBinary "Optional BINARY" 897 OptBinMod "Optional BINARY mode" 898 OptCharset "Optional Character setting" 899 OptCollate "Optional Collate setting" 900 IgnoreLines "Ignore num(int) lines" 901 NUM "A number" 902 NumList "Some numbers" 903 LengthNum "Field length num(uint64)" 904 HintTableList "Table list in optimizer hint" 905 TableOptimizerHintOpt "Table level optimizer hint" 906 TableOptimizerHints "Table level optimizer hints" 907 TableOptimizerHintList "Table level optimizer hint list" 908 909 %type <ident> 910 AsOpt "AS or EmptyString" 911 KeyOrIndex "{KEY|INDEX}" 912 ColumnKeywordOpt "Column keyword or empty" 913 PrimaryOpt "Optional primary keyword" 914 NowSym "CURRENT_TIMESTAMP/LOCALTIME/LOCALTIMESTAMP" 915 NowSymFunc "CURRENT_TIMESTAMP/LOCALTIME/LOCALTIMESTAMP/NOW" 916 DefaultKwdOpt "optional DEFAULT keyword" 917 DatabaseSym "DATABASE or SCHEMA" 918 ExplainSym "EXPLAIN or DESCRIBE or DESC" 919 RegexpSym "REGEXP or RLIKE" 920 IntoOpt "INTO or EmptyString" 921 ValueSym "Value or Values" 922 Varchar "{NATIONAL VARCHAR|VARCHAR|NVARCHAR}" 923 TimeUnit "Time unit for 'DATE_ADD', 'DATE_SUB', 'ADDDATE', 'SUBDATE', 'EXTRACT'" 924 TimestampUnit "Time unit for 'TIMESTAMPADD' and 'TIMESTAMPDIFF'" 925 DeallocateSym "Deallocate or drop" 926 OuterOpt "optional OUTER clause" 927 CrossOpt "Cross join option" 928 TablesTerminalSym "{TABLE|TABLES}" 929 IsolationLevel "Isolation level" 930 ShowIndexKwd "Show index/indexs/key keyword" 931 DistinctKwd "DISTINCT/DISTINCTROW keyword" 932 FromOrIn "From or In" 933 OptTable "Optional table keyword" 934 OptInteger "Optional Integer keyword" 935 NationalOpt "National option" 936 CharsetKw "charset or charater set" 937 CommaOpt "optional comma" 938 LockType "Table locks type" 939 logAnd "logical and operator" 940 logOr "logical or operator" 941 FieldsOrColumns "Fields or columns" 942 GetFormatSelector "{DATE|DATETIME|TIME|TIMESTAMP}" 943 944 %type <ident> 945 ODBCDateTimeType "ODBC type keywords for date and time literals" 946 Identifier "identifier or unreserved keyword" 947 NotKeywordToken "Tokens not mysql keyword but treated specially" 948 UnReservedKeyword "MySQL unreserved keywords" 949 TiDBKeyword "TiDB added keywords" 950 FunctionNameConflict "Built-in function call names which are conflict with keywords" 951 FunctionNameOptionalBraces "Function with optional braces, all of them are reserved keywords." 952 FunctionNameDatetimePrecision "Function with optional datetime precision, all of them are reserved keywords." 953 FunctionNameDateArith "Date arith function call names (date_add or date_sub)" 954 FunctionNameDateArithMultiForms "Date arith function call names (adddate or subdate)" 955 956 %precedence empty 957 958 %precedence sqlCache sqlNoCache 959 %precedence lowerThanIntervalKeyword 960 %precedence interval 961 %precedence lowerThanStringLitToken 962 %precedence stringLit 963 %precedence lowerThanSetKeyword 964 %precedence set 965 %precedence lowerThanInsertValues 966 %precedence insertValues 967 %precedence lowerThanCreateTableSelect 968 %precedence createTableSelect 969 %precedence lowerThanKey 970 %precedence key 971 972 %left join straightJoin inner cross left right full natural 973 /* A dummy token to force the priority of TableRef production in a join. */ 974 %left tableRefPriority 975 %precedence lowerThanOn 976 %precedence on using 977 %right assignmentEq 978 %left pipes or pipesAsOr 979 %left xor 980 %left andand and 981 %left between 982 %precedence lowerThanEq 983 %left eq ge le neq neqSynonym '>' '<' is like in 984 %left '|' 985 %left '&' 986 %left rsh lsh 987 %left '-' '+' 988 %left '*' '/' '%' div mod 989 %left '^' 990 %left '~' neg 991 %right not not2 992 %right collate 993 994 %precedence '(' 995 %precedence quick 996 %precedence escape 997 %precedence lowerThanComma 998 %precedence ',' 999 %precedence higherThanComma 1000 1001 %start Start 1002 1003 %% 1004 1005 Start: 1006 StatementList 1007 1008 /**************************************AlterTableStmt*************************************** 1009 * See https://dev.mysql.com/doc/refman/5.7/en/alter-table.html 1010 *******************************************************************************************/ 1011 AlterTableStmt: 1012 "ALTER" IgnoreOptional "TABLE" TableName AlterTableSpecList 1013 { 1014 $$ = &ast.AlterTableStmt{ 1015 Table: $4.(*ast.TableName), 1016 Specs: $5.([]*ast.AlterTableSpec), 1017 } 1018 } 1019 | "ALTER" IgnoreOptional "TABLE" TableName "ANALYZE" "PARTITION" PartitionNameList MaxNumBuckets 1020 { 1021 $$ = &ast.AnalyzeTableStmt{TableNames: []*ast.TableName{$4.(*ast.TableName)}, PartitionNames: $7.([]model.CIStr), MaxNumBuckets: $8.(uint64),} 1022 } 1023 | "ALTER" IgnoreOptional "TABLE" TableName "ANALYZE" "PARTITION" PartitionNameList "INDEX" IndexNameList MaxNumBuckets 1024 { 1025 $$ = &ast.AnalyzeTableStmt{ 1026 TableNames: []*ast.TableName{$4.(*ast.TableName)}, 1027 PartitionNames: $7.([]model.CIStr), 1028 IndexNames: $9.([]model.CIStr), 1029 IndexFlag: true, 1030 MaxNumBuckets: $10.(uint64), 1031 } 1032 } 1033 1034 AlterTableSpec: 1035 AlterTableOptionListOpt 1036 { 1037 $$ = &ast.AlterTableSpec{ 1038 Tp: ast.AlterTableOption, 1039 Options:$1.([]*ast.TableOption), 1040 } 1041 } 1042 | "CONVERT" "TO" CharsetKw CharsetName OptCollate 1043 { 1044 op := &ast.AlterTableSpec{ 1045 Tp: ast.AlterTableOption, 1046 Options:[]*ast.TableOption{{Tp: ast.TableOptionCharset, StrValue: $4.(string)}}, 1047 } 1048 if $5 != "" { 1049 op.Options = append(op.Options, &ast.TableOption{Tp: ast.TableOptionCollate, StrValue: $5.(string)}) 1050 } 1051 $$ = op 1052 } 1053 | "ADD" ColumnKeywordOpt ColumnDef ColumnPosition 1054 { 1055 $$ = &ast.AlterTableSpec{ 1056 Tp: ast.AlterTableAddColumns, 1057 NewColumns: []*ast.ColumnDef{$3.(*ast.ColumnDef)}, 1058 Position: $4.(*ast.ColumnPosition), 1059 } 1060 } 1061 | "ADD" ColumnKeywordOpt '(' ColumnDefList ')' 1062 { 1063 $$ = &ast.AlterTableSpec{ 1064 Tp: ast.AlterTableAddColumns, 1065 NewColumns: $4.([]*ast.ColumnDef), 1066 } 1067 } 1068 | "ADD" Constraint 1069 { 1070 constraint := $2.(*ast.Constraint) 1071 $$ = &ast.AlterTableSpec{ 1072 Tp: ast.AlterTableAddConstraint, 1073 Constraint: constraint, 1074 } 1075 } 1076 | "ADD" "PARTITION" PartitionDefinitionListOpt 1077 { 1078 var defs []*ast.PartitionDefinition 1079 if $3 != nil { 1080 defs = $3.([]*ast.PartitionDefinition) 1081 } 1082 $$ = &ast.AlterTableSpec{ 1083 Tp: ast.AlterTableAddPartitions, 1084 PartDefinitions: defs, 1085 } 1086 } 1087 | "ADD" "PARTITION" "PARTITIONS" NUM 1088 { 1089 $$ = &ast.AlterTableSpec{ 1090 Tp: ast.AlterTableAddPartitions, 1091 Num: getUint64FromNUM($4), 1092 } 1093 } 1094 | "COALESCE" "PARTITION" NUM 1095 { 1096 $$ = &ast.AlterTableSpec{ 1097 Tp: ast.AlterTableCoalescePartitions, 1098 Num: getUint64FromNUM($3), 1099 } 1100 } 1101 | "DROP" ColumnKeywordOpt ColumnName RestrictOrCascadeOpt 1102 { 1103 $$ = &ast.AlterTableSpec{ 1104 Tp: ast.AlterTableDropColumn, 1105 OldColumnName: $3.(*ast.ColumnName), 1106 } 1107 } 1108 | "DROP" "PRIMARY" "KEY" 1109 { 1110 $$ = &ast.AlterTableSpec{Tp: ast.AlterTableDropPrimaryKey} 1111 } 1112 | "DROP" "PARTITION" Identifier 1113 { 1114 $$ = &ast.AlterTableSpec{ 1115 Tp: ast.AlterTableDropPartition, 1116 Name: $3, 1117 } 1118 } 1119 | "TRUNCATE" "PARTITION" Identifier 1120 { 1121 $$ = &ast.AlterTableSpec{ 1122 Tp: ast.AlterTableTruncatePartition, 1123 Name: $3, 1124 } 1125 } 1126 | "DROP" KeyOrIndex Identifier 1127 { 1128 $$ = &ast.AlterTableSpec{ 1129 Tp: ast.AlterTableDropIndex, 1130 Name: $3, 1131 } 1132 } 1133 | "DROP" "FOREIGN" "KEY" Symbol 1134 { 1135 $$ = &ast.AlterTableSpec{ 1136 Tp: ast.AlterTableDropForeignKey, 1137 Name: $4.(string), 1138 } 1139 } 1140 | "DISABLE" "KEYS" 1141 { 1142 $$ = &ast.AlterTableSpec{} 1143 } 1144 | "ENABLE" "KEYS" 1145 { 1146 $$ = &ast.AlterTableSpec{} 1147 } 1148 | "MODIFY" ColumnKeywordOpt ColumnDef ColumnPosition 1149 { 1150 $$ = &ast.AlterTableSpec{ 1151 Tp: ast.AlterTableModifyColumn, 1152 NewColumns: []*ast.ColumnDef{$3.(*ast.ColumnDef)}, 1153 Position: $4.(*ast.ColumnPosition), 1154 } 1155 } 1156 | "CHANGE" ColumnKeywordOpt ColumnName ColumnDef ColumnPosition 1157 { 1158 $$ = &ast.AlterTableSpec{ 1159 Tp: ast.AlterTableChangeColumn, 1160 OldColumnName: $3.(*ast.ColumnName), 1161 NewColumns: []*ast.ColumnDef{$4.(*ast.ColumnDef)}, 1162 Position: $5.(*ast.ColumnPosition), 1163 } 1164 } 1165 | "ALTER" ColumnKeywordOpt ColumnName "SET" "DEFAULT" SignedLiteral 1166 { 1167 option := &ast.ColumnOption{Expr: $6} 1168 colDef := &ast.ColumnDef{ 1169 Name: $3.(*ast.ColumnName), 1170 Options: []*ast.ColumnOption{option}, 1171 } 1172 $$ = &ast.AlterTableSpec{ 1173 Tp: ast.AlterTableAlterColumn, 1174 NewColumns: []*ast.ColumnDef{colDef}, 1175 } 1176 } 1177 | "ALTER" ColumnKeywordOpt ColumnName "DROP" "DEFAULT" 1178 { 1179 colDef := &ast.ColumnDef{ 1180 Name: $3.(*ast.ColumnName), 1181 } 1182 $$ = &ast.AlterTableSpec{ 1183 Tp: ast.AlterTableAlterColumn, 1184 NewColumns: []*ast.ColumnDef{colDef}, 1185 } 1186 } 1187 | "RENAME" "TO" TableName 1188 { 1189 $$ = &ast.AlterTableSpec{ 1190 Tp: ast.AlterTableRenameTable, 1191 NewTable: $3.(*ast.TableName), 1192 } 1193 } 1194 | "RENAME" TableName 1195 { 1196 $$ = &ast.AlterTableSpec{ 1197 Tp: ast.AlterTableRenameTable, 1198 NewTable: $2.(*ast.TableName), 1199 } 1200 } 1201 | "RENAME" "AS" TableName 1202 { 1203 $$ = &ast.AlterTableSpec{ 1204 Tp: ast.AlterTableRenameTable, 1205 NewTable: $3.(*ast.TableName), 1206 } 1207 } 1208 | "RENAME" KeyOrIndex Identifier "TO" Identifier 1209 { 1210 $$ = &ast.AlterTableSpec{ 1211 Tp: ast.AlterTableRenameIndex, 1212 FromKey: model.NewCIStr($3), 1213 ToKey: model.NewCIStr($5), 1214 } 1215 } 1216 | LockClause 1217 { 1218 $$ = &ast.AlterTableSpec{ 1219 Tp: ast.AlterTableLock, 1220 LockType: $1.(ast.LockType), 1221 } 1222 } 1223 | "ALGORITHM" EqOpt AlterAlgorithm 1224 { 1225 // Parse it and ignore it. Just for compatibility. 1226 $$ = &ast.AlterTableSpec{ 1227 Tp: ast.AlterTableAlgorithm, 1228 Algorithm: $3.(ast.AlterAlgorithm), 1229 } 1230 } 1231 | "FORCE" 1232 { 1233 // Parse it and ignore it. Just for compatibility. 1234 $$ = &ast.AlterTableSpec{ 1235 Tp: ast.AlterTableForce, 1236 } 1237 } 1238 1239 1240 AlterAlgorithm: 1241 "DEFAULT" 1242 { 1243 $$ = ast.AlterAlgorithmDefault 1244 } 1245 | "COPY" 1246 { 1247 $$ = ast.AlterAlgorithmCopy 1248 } 1249 | "INPLACE" 1250 { 1251 $$ = ast.AlterAlgorithmInplace 1252 } 1253 | "INSTANT" 1254 { 1255 $$ = ast.AlterAlgorithmInstant 1256 } 1257 1258 1259 LockClauseOpt: 1260 {} 1261 | LockClause {} 1262 1263 LockClause: 1264 "LOCK" eq "NONE" 1265 { 1266 $$ = ast.LockTypeNone 1267 } 1268 | "LOCK" eq "DEFAULT" 1269 { 1270 $$ = ast.LockTypeDefault 1271 } 1272 | "LOCK" eq "SHARED" 1273 { 1274 $$ = ast.LockTypeShared 1275 } 1276 | "LOCK" eq "EXCLUSIVE" 1277 { 1278 $$ = ast.LockTypeExclusive 1279 } 1280 1281 KeyOrIndex: "KEY" | "INDEX" 1282 1283 1284 KeyOrIndexOpt: 1285 {} 1286 | KeyOrIndex 1287 1288 ColumnKeywordOpt: 1289 {} 1290 | "COLUMN" 1291 1292 ColumnPosition: 1293 { 1294 $$ = &ast.ColumnPosition{Tp: ast.ColumnPositionNone} 1295 } 1296 | "FIRST" 1297 { 1298 $$ = &ast.ColumnPosition{Tp: ast.ColumnPositionFirst} 1299 } 1300 | "AFTER" ColumnName 1301 { 1302 $$ = &ast.ColumnPosition{ 1303 Tp: ast.ColumnPositionAfter, 1304 RelativeColumn: $2.(*ast.ColumnName), 1305 } 1306 } 1307 1308 AlterTableSpecList: 1309 AlterTableSpec 1310 { 1311 $$ = []*ast.AlterTableSpec{$1.(*ast.AlterTableSpec)} 1312 } 1313 | AlterTableSpecList ',' AlterTableSpec 1314 { 1315 $$ = append($1.([]*ast.AlterTableSpec), $3.(*ast.AlterTableSpec)) 1316 } 1317 1318 PartitionNameList: 1319 Identifier 1320 { 1321 $$ = []model.CIStr{model.NewCIStr($1)} 1322 } 1323 | PartitionNameList ',' Identifier 1324 { 1325 $$ = append($1.([]model.CIStr), model.NewCIStr($3)) 1326 } 1327 1328 ConstraintKeywordOpt: 1329 { 1330 $$ = nil 1331 } 1332 | "CONSTRAINT" 1333 { 1334 $$ = nil 1335 } 1336 | "CONSTRAINT" Symbol 1337 { 1338 $$ = $2.(string) 1339 } 1340 1341 Symbol: 1342 Identifier 1343 { 1344 $$ = $1 1345 } 1346 1347 /**************************************RenameTableStmt*************************************** 1348 * See http://dev.mysql.com/doc/refman/5.7/en/rename-table.html 1349 * 1350 * TODO: refactor this when you are going to add full support for multiple schema changes. 1351 * Currently it is only useful for syncer which depends heavily on tidb parser to do some dirty work. 1352 *******************************************************************************************/ 1353 RenameTableStmt: 1354 "RENAME" "TABLE" TableToTableList 1355 { 1356 $$ = &ast.RenameTableStmt{ 1357 OldTable: $3.([]*ast.TableToTable)[0].OldTable, 1358 NewTable: $3.([]*ast.TableToTable)[0].NewTable, 1359 TableToTables: $3.([]*ast.TableToTable), 1360 } 1361 } 1362 1363 TableToTableList: 1364 TableToTable 1365 { 1366 $$ = []*ast.TableToTable{$1.(*ast.TableToTable)} 1367 } 1368 | TableToTableList ',' TableToTable 1369 { 1370 $$ = append($1.([]*ast.TableToTable), $3.(*ast.TableToTable)) 1371 } 1372 1373 TableToTable: 1374 TableName "TO" TableName 1375 { 1376 $$ = &ast.TableToTable{ 1377 OldTable: $1.(*ast.TableName), 1378 NewTable: $3.(*ast.TableName), 1379 } 1380 } 1381 1382 1383 /*******************************************************************************************/ 1384 1385 AnalyzeTableStmt: 1386 "ANALYZE" "TABLE" TableNameList MaxNumBuckets 1387 { 1388 $$ = &ast.AnalyzeTableStmt{TableNames: $3.([]*ast.TableName), MaxNumBuckets: $4.(uint64)} 1389 } 1390 | "ANALYZE" "TABLE" TableName "INDEX" IndexNameList MaxNumBuckets 1391 { 1392 $$ = &ast.AnalyzeTableStmt{TableNames: []*ast.TableName{$3.(*ast.TableName)}, IndexNames: $5.([]model.CIStr), IndexFlag: true, MaxNumBuckets: $6.(uint64)} 1393 } 1394 | "ANALYZE" "TABLE" TableName "PARTITION" PartitionNameList MaxNumBuckets 1395 { 1396 $$ = &ast.AnalyzeTableStmt{TableNames: []*ast.TableName{$3.(*ast.TableName)}, PartitionNames: $5.([]model.CIStr), MaxNumBuckets: $6.(uint64),} 1397 } 1398 | "ANALYZE" "TABLE" TableName "PARTITION" PartitionNameList "INDEX" IndexNameList MaxNumBuckets 1399 { 1400 $$ = &ast.AnalyzeTableStmt{ 1401 TableNames: []*ast.TableName{$3.(*ast.TableName)}, 1402 PartitionNames: $5.([]model.CIStr), 1403 IndexNames: $7.([]model.CIStr), 1404 IndexFlag: true, 1405 MaxNumBuckets: $8.(uint64), 1406 } 1407 } 1408 1409 MaxNumBuckets: 1410 { 1411 $$ = uint64(0) 1412 } 1413 | "WITH" NUM "BUCKETS" 1414 { 1415 $$ = getUint64FromNUM($2) 1416 } 1417 1418 /*******************************************************************************************/ 1419 Assignment: 1420 ColumnName eq Expression 1421 { 1422 $$ = &ast.Assignment{Column: $1.(*ast.ColumnName), Expr:$3} 1423 } 1424 1425 AssignmentList: 1426 Assignment 1427 { 1428 $$ = []*ast.Assignment{$1.(*ast.Assignment)} 1429 } 1430 | AssignmentList ',' Assignment 1431 { 1432 $$ = append($1.([]*ast.Assignment), $3.(*ast.Assignment)) 1433 } 1434 1435 AssignmentListOpt: 1436 /* EMPTY */ 1437 { 1438 $$ = []*ast.Assignment{} 1439 } 1440 | AssignmentList 1441 1442 BeginTransactionStmt: 1443 "BEGIN" 1444 { 1445 $$ = &ast.BeginStmt{} 1446 } 1447 | "START" "TRANSACTION" 1448 { 1449 $$ = &ast.BeginStmt{} 1450 } 1451 | "START" "TRANSACTION" "WITH" "CONSISTENT" "SNAPSHOT" 1452 { 1453 $$ = &ast.BeginStmt{} 1454 } 1455 1456 BinlogStmt: 1457 "BINLOG" stringLit 1458 { 1459 $$ = &ast.BinlogStmt{Str: $2} 1460 } 1461 1462 ColumnDefList: 1463 ColumnDef 1464 { 1465 $$ = []*ast.ColumnDef{$1.(*ast.ColumnDef)} 1466 } 1467 | ColumnDefList ',' ColumnDef 1468 { 1469 $$ = append($1.([]*ast.ColumnDef), $3.(*ast.ColumnDef)) 1470 } 1471 1472 ColumnDef: 1473 ColumnName Type ColumnOptionListOpt 1474 { 1475 $$ = &ast.ColumnDef{Name: $1.(*ast.ColumnName), Tp: $2.(*types.FieldType), Options: $3.([]*ast.ColumnOption)} 1476 } 1477 1478 ColumnName: 1479 Identifier 1480 { 1481 $$ = &ast.ColumnName{Name: model.NewCIStr($1)} 1482 } 1483 | Identifier '.' Identifier 1484 { 1485 $$ = &ast.ColumnName{Table: model.NewCIStr($1), Name: model.NewCIStr($3)} 1486 } 1487 | Identifier '.' Identifier '.' Identifier 1488 { 1489 $$ = &ast.ColumnName{Schema: model.NewCIStr($1), Table: model.NewCIStr($3), Name: model.NewCIStr($5)} 1490 } 1491 1492 ColumnNameList: 1493 ColumnName 1494 { 1495 $$ = []*ast.ColumnName{$1.(*ast.ColumnName)} 1496 } 1497 | ColumnNameList ',' ColumnName 1498 { 1499 $$ = append($1.([]*ast.ColumnName), $3.(*ast.ColumnName)) 1500 } 1501 1502 ColumnNameListOpt: 1503 /* EMPTY */ 1504 { 1505 $$ = []*ast.ColumnName{} 1506 } 1507 | ColumnNameList 1508 { 1509 $$ = $1.([]*ast.ColumnName) 1510 } 1511 1512 ColumnNameListOptWithBrackets: 1513 /* EMPTY */ 1514 { 1515 $$ = []*ast.ColumnName{} 1516 } 1517 | '(' ColumnNameListOpt ')' 1518 { 1519 $$ = $2.([]*ast.ColumnName) 1520 } 1521 1522 CommitOpt: 1523 "WORK" 1524 { 1525 $$ = $1 1526 } 1527 | "WORK" "AND" "NO" "CHAIN" "NO" "RELEASE" 1528 { 1529 $$ = "" 1530 } 1531 | "WORK" "AND" "CHAIN" "NO" "RELEASE" 1532 { 1533 $$ = "" 1534 } 1535 | "WORK" "AND" "NO" "CHAIN" "RELEASE" 1536 { 1537 $$ = "" 1538 } 1539 | "WORK" "NO" "RELEASE" 1540 { 1541 $$ = "" 1542 } 1543 | "WORK" "RELEASE" 1544 { 1545 $$ = "" 1546 } 1547 | "AND" "NO" "CHAIN" "NO" "RELEASE" 1548 { 1549 $$ = "" 1550 } 1551 | "AND" "CHAIN" "NO" "RELEASE" 1552 { 1553 $$ = "" 1554 } 1555 | "AND" "NO" "CHAIN" "RELEASE" 1556 { 1557 $$ = "" 1558 } 1559 | "NO" "RELEASE" 1560 { 1561 $$ = "" 1562 } 1563 | "RELEASE" 1564 { 1565 $$ = "" 1566 } 1567 1568 CommitStmt: 1569 "COMMIT" 1570 { 1571 $$ = &ast.CommitStmt{} 1572 } 1573 | "COMMIT" CommitOpt 1574 { 1575 $$ = &ast.CommitStmt{} 1576 } 1577 1578 PrimaryOpt: 1579 {} 1580 | "PRIMARY" 1581 1582 ColumnOption: 1583 "NOT" "NULL" 1584 { 1585 $$ = &ast.ColumnOption{Tp: ast.ColumnOptionNotNull} 1586 } 1587 | "NULL" 1588 { 1589 $$ = &ast.ColumnOption{Tp: ast.ColumnOptionNull} 1590 } 1591 | "AUTO_INCREMENT" 1592 { 1593 $$ = &ast.ColumnOption{Tp: ast.ColumnOptionAutoIncrement} 1594 } 1595 | PrimaryOpt "KEY" 1596 { 1597 // KEY is normally a synonym for INDEX. The key attribute PRIMARY KEY 1598 // can also be specified as just KEY when given in a column definition. 1599 // See http://dev.mysql.com/doc/refman/5.7/en/create-table.html 1600 $$ = &ast.ColumnOption{Tp: ast.ColumnOptionPrimaryKey} 1601 } 1602 | "UNIQUE" %prec lowerThanKey 1603 { 1604 $$ = &ast.ColumnOption{Tp: ast.ColumnOptionUniqKey} 1605 } 1606 | "UNIQUE" "KEY" 1607 { 1608 $$ = &ast.ColumnOption{Tp: ast.ColumnOptionUniqKey} 1609 } 1610 | "DEFAULT" DefaultValueExpr 1611 { 1612 $$ = &ast.ColumnOption{Tp: ast.ColumnOptionDefaultValue, Expr: $2} 1613 } 1614 | "ON" "UPDATE" NowSymOptionFraction 1615 { 1616 nowFunc := &ast.FuncCallExpr{FnName: model.NewCIStr("CURRENT_TIMESTAMP")} 1617 $$ = &ast.ColumnOption{Tp: ast.ColumnOptionOnUpdate, Expr: nowFunc} 1618 } 1619 | "COMMENT" stringLit 1620 { 1621 $$ = &ast.ColumnOption{Tp: ast.ColumnOptionComment, Expr: ast.NewValueExpr($2)} 1622 } 1623 | "CHECK" '(' Expression ')' 1624 { 1625 // See https://dev.mysql.com/doc/refman/5.7/en/create-table.html 1626 // The CHECK clause is parsed but ignored by all storage engines. 1627 $$ = &ast.ColumnOption{} 1628 } 1629 | GeneratedAlways "AS" '(' Expression ')' VirtualOrStored 1630 { 1631 startOffset := parser.startOffset(&yyS[yypt-2]) 1632 endOffset := parser.endOffset(&yyS[yypt-1]) 1633 expr := $4 1634 expr.SetText(parser.src[startOffset:endOffset]) 1635 1636 $$ = &ast.ColumnOption{ 1637 Tp: ast.ColumnOptionGenerated, 1638 Expr: expr, 1639 Stored: $6.(bool), 1640 } 1641 } 1642 | ReferDef 1643 { 1644 $$ = &ast.ColumnOption{ 1645 Tp: ast.ColumnOptionReference, 1646 Refer: $1.(*ast.ReferenceDef), 1647 } 1648 } 1649 1650 GeneratedAlways: | "GENERATED" "ALWAYS" 1651 1652 VirtualOrStored: 1653 { 1654 $$ = false 1655 } 1656 | "VIRTUAL" 1657 { 1658 $$ = false 1659 } 1660 | "STORED" 1661 { 1662 $$ = true 1663 } 1664 1665 ColumnOptionList: 1666 ColumnOption 1667 { 1668 $$ = []*ast.ColumnOption{$1.(*ast.ColumnOption)} 1669 } 1670 | ColumnOptionList ColumnOption 1671 { 1672 $$ = append($1.([]*ast.ColumnOption), $2.(*ast.ColumnOption)) 1673 } 1674 1675 ColumnOptionListOpt: 1676 { 1677 $$ = []*ast.ColumnOption{} 1678 } 1679 | ColumnOptionList 1680 { 1681 $$ = $1.([]*ast.ColumnOption) 1682 } 1683 1684 ConstraintElem: 1685 "PRIMARY" "KEY" IndexName IndexTypeOpt '(' IndexColNameList ')' IndexOptionList 1686 { 1687 c := &ast.Constraint{ 1688 Tp: ast.ConstraintPrimaryKey, 1689 Keys: $6.([]*ast.IndexColName), 1690 } 1691 if $8 != nil { 1692 c.Option = $8.(*ast.IndexOption) 1693 } 1694 if $4 != nil { 1695 if c.Option == nil { 1696 c.Option = &ast.IndexOption{} 1697 } 1698 c.Option.Tp = $4.(model.IndexType) 1699 } 1700 $$ = c 1701 } 1702 | "FULLTEXT" KeyOrIndexOpt IndexName '(' IndexColNameList ')' IndexOptionList 1703 { 1704 c := &ast.Constraint{ 1705 Tp: ast.ConstraintFulltext, 1706 Keys: $5.([]*ast.IndexColName), 1707 Name: $3.(string), 1708 } 1709 if $7 != nil { 1710 c.Option = $7.(*ast.IndexOption) 1711 } 1712 $$ = c 1713 } 1714 | KeyOrIndex IndexName IndexTypeOpt '(' IndexColNameList ')' IndexOptionList 1715 { 1716 c := &ast.Constraint{ 1717 Tp: ast.ConstraintIndex, 1718 Keys: $5.([]*ast.IndexColName), 1719 Name: $2.(string), 1720 } 1721 if $7 != nil { 1722 c.Option = $7.(*ast.IndexOption) 1723 } 1724 if $3 != nil { 1725 if c.Option == nil { 1726 c.Option = &ast.IndexOption{} 1727 } 1728 c.Option.Tp = $3.(model.IndexType) 1729 } 1730 $$ = c 1731 } 1732 | "UNIQUE" KeyOrIndexOpt IndexName IndexTypeOpt '(' IndexColNameList ')' IndexOptionList 1733 { 1734 c := &ast.Constraint{ 1735 Tp: ast.ConstraintUniq, 1736 Keys: $6.([]*ast.IndexColName), 1737 Name: $3.(string), 1738 } 1739 if $8 != nil { 1740 c.Option = $8.(*ast.IndexOption) 1741 } 1742 if $4 != nil { 1743 if c.Option == nil { 1744 c.Option = &ast.IndexOption{} 1745 } 1746 c.Option.Tp = $4.(model.IndexType) 1747 } 1748 $$ = c 1749 } 1750 | "FOREIGN" "KEY" IndexName '(' IndexColNameList ')' ReferDef 1751 { 1752 $$ = &ast.Constraint{ 1753 Tp: ast.ConstraintForeignKey, 1754 Keys: $5.([]*ast.IndexColName), 1755 Name: $3.(string), 1756 Refer: $7.(*ast.ReferenceDef), 1757 } 1758 } 1759 1760 ReferDef: 1761 "REFERENCES" TableName '(' IndexColNameList ')' OnDeleteOpt OnUpdateOpt 1762 { 1763 var onDeleteOpt *ast.OnDeleteOpt 1764 if $6 != nil { 1765 onDeleteOpt = $6.(*ast.OnDeleteOpt) 1766 } 1767 var onUpdateOpt *ast.OnUpdateOpt 1768 if $7 != nil { 1769 onUpdateOpt = $7.(*ast.OnUpdateOpt) 1770 } 1771 $$ = &ast.ReferenceDef{ 1772 Table: $2.(*ast.TableName), 1773 IndexColNames: $4.([]*ast.IndexColName), 1774 OnDelete: onDeleteOpt, 1775 OnUpdate: onUpdateOpt, 1776 } 1777 } 1778 1779 OnDeleteOpt: 1780 { 1781 $$ = &ast.OnDeleteOpt{} 1782 } %prec lowerThanOn 1783 | "ON" "DELETE" ReferOpt 1784 { 1785 $$ = &ast.OnDeleteOpt{ReferOpt: $3.(ast.ReferOptionType)} 1786 } 1787 1788 OnUpdateOpt: 1789 { 1790 $$ = &ast.OnUpdateOpt{} 1791 } %prec lowerThanOn 1792 | "ON" "UPDATE" ReferOpt 1793 { 1794 $$ = &ast.OnUpdateOpt{ReferOpt: $3.(ast.ReferOptionType)} 1795 } 1796 1797 ReferOpt: 1798 "RESTRICT" 1799 { 1800 $$ = ast.ReferOptionRestrict 1801 } 1802 | "CASCADE" 1803 { 1804 $$ = ast.ReferOptionCascade 1805 } 1806 | "SET" "NULL" 1807 { 1808 $$ = ast.ReferOptionSetNull 1809 } 1810 | "NO" "ACTION" 1811 { 1812 $$ = ast.ReferOptionNoAction 1813 } 1814 1815 /* 1816 * The DEFAULT clause specifies a default value for a column. 1817 * With one exception, the default value must be a constant; 1818 * it cannot be a function or an expression. This means, for example, 1819 * that you cannot set the default for a date column to be the value of 1820 * a function such as NOW() or CURRENT_DATE. The exception is that you 1821 * can specify CURRENT_TIMESTAMP as the default for a TIMESTAMP or DATETIME column. 1822 * 1823 * See http://dev.mysql.com/doc/refman/5.7/en/create-table.html 1824 * https://github.com/mysql/mysql-server/blob/5.7/sql/sql_yacc.yy#L6832 1825 */ 1826 DefaultValueExpr: 1827 NowSymOptionFraction | SignedLiteral 1828 1829 NowSymOptionFraction: 1830 NowSym 1831 { 1832 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr("CURRENT_TIMESTAMP")} 1833 } 1834 | NowSymFunc '(' ')' 1835 { 1836 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr("CURRENT_TIMESTAMP")} 1837 } 1838 | NowSymFunc '(' NUM ')' 1839 { 1840 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr("CURRENT_TIMESTAMP"), Args: []ast.ExprNode{ast.NewValueExpr($3)}} 1841 } 1842 1843 /* 1844 * See https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_localtime 1845 * TODO: Process other three keywords 1846 */ 1847 NowSymFunc: 1848 "CURRENT_TIMESTAMP" | "LOCALTIME" | "LOCALTIMESTAMP" | builtinNow 1849 NowSym: 1850 "CURRENT_TIMESTAMP" | "LOCALTIME" | "LOCALTIMESTAMP" 1851 1852 1853 SignedLiteral: 1854 Literal 1855 { 1856 $$ = ast.NewValueExpr($1) 1857 } 1858 | '+' NumLiteral 1859 { 1860 $$ = &ast.UnaryOperationExpr{Op: opcode.Plus, V: ast.NewValueExpr($2)} 1861 } 1862 | '-' NumLiteral 1863 { 1864 $$ = &ast.UnaryOperationExpr{Op: opcode.Minus, V: ast.NewValueExpr($2)} 1865 } 1866 1867 NumLiteral: 1868 intLit 1869 | floatLit 1870 | decLit 1871 1872 1873 CreateIndexStmt: 1874 "CREATE" CreateIndexStmtUnique "INDEX" Identifier IndexTypeOpt "ON" TableName '(' IndexColNameList ')' IndexOptionList LockClauseOpt 1875 { 1876 var indexOption *ast.IndexOption 1877 if $11 != nil { 1878 indexOption = $11.(*ast.IndexOption) 1879 if indexOption.Tp == model.IndexTypeInvalid { 1880 if $5 != nil { 1881 indexOption.Tp = $5.(model.IndexType) 1882 } 1883 } 1884 } else { 1885 indexOption = &ast.IndexOption{} 1886 if $5 != nil { 1887 indexOption.Tp = $5.(model.IndexType) 1888 } 1889 } 1890 $$ = &ast.CreateIndexStmt{ 1891 Unique: $2.(bool), 1892 IndexName: $4, 1893 Table: $7.(*ast.TableName), 1894 IndexColNames: $9.([]*ast.IndexColName), 1895 IndexOption: indexOption, 1896 } 1897 } 1898 1899 CreateIndexStmtUnique: 1900 { 1901 $$ = false 1902 } 1903 | "UNIQUE" 1904 { 1905 $$ = true 1906 } 1907 1908 IndexColName: 1909 ColumnName OptFieldLen Order 1910 { 1911 //Order is parsed but just ignored as MySQL did 1912 $$ = &ast.IndexColName{Column: $1.(*ast.ColumnName), Length: $2.(int)} 1913 } 1914 1915 IndexColNameList: 1916 IndexColName 1917 { 1918 $$ = []*ast.IndexColName{$1.(*ast.IndexColName)} 1919 } 1920 | IndexColNameList ',' IndexColName 1921 { 1922 $$ = append($1.([]*ast.IndexColName), $3.(*ast.IndexColName)) 1923 } 1924 1925 1926 1927 /******************************************************************* 1928 * 1929 * Create Database Statement 1930 * CREATE {DATABASE | SCHEMA} [IF NOT EXISTS] db_name 1931 * [create_specification] ... 1932 * 1933 * create_specification: 1934 * [DEFAULT] CHARACTER SET [=] charset_name 1935 * | [DEFAULT] COLLATE [=] collation_name 1936 *******************************************************************/ 1937 CreateDatabaseStmt: 1938 "CREATE" DatabaseSym IfNotExists DBName DatabaseOptionListOpt 1939 { 1940 $$ = &ast.CreateDatabaseStmt{ 1941 IfNotExists: $3.(bool), 1942 Name: $4.(string), 1943 Options: $5.([]*ast.DatabaseOption), 1944 } 1945 } 1946 1947 DBName: 1948 Identifier 1949 { 1950 $$ = $1 1951 } 1952 1953 DatabaseOption: 1954 DefaultKwdOpt CharsetKw EqOpt CharsetName 1955 { 1956 $$ = &ast.DatabaseOption{Tp: ast.DatabaseOptionCharset, Value: $4.(string)} 1957 } 1958 | DefaultKwdOpt "COLLATE" EqOpt StringName 1959 { 1960 $$ = &ast.DatabaseOption{Tp: ast.DatabaseOptionCollate, Value: $4.(string)} 1961 } 1962 1963 DatabaseOptionListOpt: 1964 { 1965 $$ = []*ast.DatabaseOption{} 1966 } 1967 | DatabaseOptionList 1968 1969 DatabaseOptionList: 1970 DatabaseOption 1971 { 1972 $$ = []*ast.DatabaseOption{$1.(*ast.DatabaseOption)} 1973 } 1974 | DatabaseOptionList DatabaseOption 1975 { 1976 $$ = append($1.([]*ast.DatabaseOption), $2.(*ast.DatabaseOption)) 1977 } 1978 1979 /******************************************************************* 1980 * 1981 * Create Table Statement 1982 * 1983 * Example: 1984 * CREATE TABLE Persons 1985 * ( 1986 * P_Id int NOT NULL, 1987 * LastName varchar(255) NOT NULL, 1988 * FirstName varchar(255), 1989 * Address varchar(255), 1990 * City varchar(255), 1991 * PRIMARY KEY (P_Id) 1992 * ) 1993 *******************************************************************/ 1994 1995 CreateTableStmt: 1996 "CREATE" "TABLE" IfNotExists TableName TableElementListOpt CreateTableOptionListOpt PartitionOpt DuplicateOpt AsOpt CreateTableSelectOpt 1997 { 1998 stmt := $5.(*ast.CreateTableStmt) 1999 stmt.Table = $4.(*ast.TableName) 2000 stmt.IfNotExists = $3.(bool) 2001 stmt.Options = $6.([]*ast.TableOption) 2002 if $7 != nil { 2003 stmt.Partition = $7.(*ast.PartitionOptions) 2004 } 2005 stmt.OnDuplicate = $8.(ast.OnDuplicateCreateTableSelectType) 2006 stmt.Select = $10.(*ast.CreateTableStmt).Select 2007 $$ = stmt 2008 } 2009 | "CREATE" "TABLE" IfNotExists TableName LikeTableWithOrWithoutParen 2010 { 2011 $$ = &ast.CreateTableStmt{ 2012 Table: $4.(*ast.TableName), 2013 ReferTable: $5.(*ast.TableName), 2014 IfNotExists: $3.(bool), 2015 } 2016 } 2017 2018 DefaultKwdOpt: 2019 {} 2020 | "DEFAULT" 2021 2022 PartitionOpt: 2023 { 2024 $$ = nil 2025 } 2026 | "PARTITION" "BY" "KEY" '(' ColumnNameList ')' PartitionNumOpt PartitionDefinitionListOpt 2027 { 2028 $$ = nil 2029 } 2030 | "PARTITION" "BY" "HASH" '(' Expression ')' PartitionNumOpt 2031 { 2032 tmp := &ast.PartitionOptions{ 2033 Tp: model.PartitionTypeHash, 2034 Expr: $5.(ast.ExprNode), 2035 // If you do not include a PARTITIONS clause, the number of partitions defaults to 1 2036 Num: 1, 2037 } 2038 if $7 != nil { 2039 tmp.Num = getUint64FromNUM($7) 2040 } 2041 $$ = tmp 2042 } 2043 | "PARTITION" "BY" "RANGE" '(' Expression ')' PartitionNumOpt SubPartitionOpt PartitionDefinitionListOpt 2044 { 2045 var defs []*ast.PartitionDefinition 2046 if $9 != nil { 2047 defs = $9.([]*ast.PartitionDefinition) 2048 } 2049 $$ = &ast.PartitionOptions{ 2050 Tp: model.PartitionTypeRange, 2051 Expr: $5.(ast.ExprNode), 2052 Definitions: defs, 2053 } 2054 } 2055 | "PARTITION" "BY" "RANGE" "COLUMNS" '(' ColumnNameList ')' PartitionNumOpt PartitionDefinitionListOpt 2056 { 2057 var defs []*ast.PartitionDefinition 2058 if $9 != nil { 2059 defs = $9.([]*ast.PartitionDefinition) 2060 } 2061 $$ = &ast.PartitionOptions{ 2062 Tp: model.PartitionTypeRange, 2063 ColumnNames: $6.([]*ast.ColumnName), 2064 Definitions: defs, 2065 } 2066 } 2067 2068 SubPartitionOpt: 2069 {} 2070 | "SUBPARTITION" "BY" "HASH" '(' Expression ')' SubPartitionNumOpt 2071 {} 2072 | "SUBPARTITION" "BY" "KEY" '(' ColumnNameList ')' SubPartitionNumOpt 2073 {} 2074 2075 SubPartitionNumOpt: 2076 {} 2077 | "SUBPARTITIONS" NUM 2078 {} 2079 2080 PartitionNumOpt: 2081 { 2082 $$ = nil 2083 } 2084 | "PARTITIONS" NUM 2085 { 2086 $$ = $2 2087 } 2088 2089 PartitionDefinitionListOpt: 2090 /* empty */ %prec lowerThanCreateTableSelect 2091 { 2092 $$ = nil 2093 } 2094 | '(' PartitionDefinitionList ')' 2095 { 2096 $$ = $2.([]*ast.PartitionDefinition) 2097 } 2098 2099 PartitionDefinitionList: 2100 PartitionDefinition 2101 { 2102 $$ = []*ast.PartitionDefinition{$1.(*ast.PartitionDefinition)} 2103 } 2104 | PartitionDefinitionList ',' PartitionDefinition 2105 { 2106 $$ = append($1.([]*ast.PartitionDefinition), $3.(*ast.PartitionDefinition)) 2107 } 2108 2109 PartitionDefinition: 2110 "PARTITION" Identifier PartDefValuesOpt PartDefOptionsOpt 2111 { 2112 partDef := &ast.PartitionDefinition{ 2113 Name: model.NewCIStr($2), 2114 } 2115 switch $3.(type) { 2116 case []ast.ExprNode: 2117 partDef.LessThan = $3.([]ast.ExprNode) 2118 case ast.ExprNode: 2119 partDef.LessThan = make([]ast.ExprNode, 1) 2120 partDef.LessThan[0] = $3.(ast.ExprNode) 2121 } 2122 2123 if comment, ok := $4.(string); ok { 2124 partDef.Comment = comment 2125 } 2126 $$ = partDef 2127 } 2128 2129 PartDefOptionsOpt: 2130 { 2131 $$ = nil 2132 } 2133 | PartDefOptionList 2134 { 2135 $$ = $1 2136 } 2137 2138 PartDefOptionList: 2139 PartDefOption 2140 { 2141 $$ = $1 2142 } 2143 | PartDefOptionList PartDefOption 2144 { 2145 if $1 != nil { 2146 $$ = $1 2147 } else { 2148 $$ = $2 2149 } 2150 } 2151 2152 PartDefOption: 2153 "COMMENT" EqOpt stringLit 2154 { 2155 $$ = $3 2156 } 2157 | "ENGINE" EqOpt Identifier 2158 { 2159 $$ = nil 2160 } 2161 | "TABLESPACE" EqOpt Identifier 2162 { 2163 $$ = nil 2164 } 2165 2166 2167 PartDefValuesOpt: 2168 { 2169 $$ = nil 2170 } 2171 | "VALUES" "LESS" "THAN" "MAXVALUE" 2172 { 2173 $$ = &ast.MaxValueExpr{} 2174 } 2175 | "VALUES" "LESS" "THAN" '(' MaxValueOrExpressionList ')' 2176 { 2177 $$ = $5 2178 } 2179 2180 DuplicateOpt: 2181 { 2182 $$ = ast.OnDuplicateCreateTableSelectError 2183 } 2184 | "IGNORE" 2185 { 2186 $$ = ast.OnDuplicateCreateTableSelectIgnore 2187 } 2188 | "REPLACE" 2189 { 2190 $$ = ast.OnDuplicateCreateTableSelectReplace 2191 } 2192 2193 AsOpt: 2194 {} 2195 | "AS" 2196 {} 2197 2198 CreateTableSelectOpt: 2199 /* empty */ 2200 { 2201 $$ = &ast.CreateTableStmt{} 2202 } 2203 | 2204 SelectStmt 2205 { 2206 $$ = &ast.CreateTableStmt{Select: $1} 2207 } 2208 | 2209 UnionStmt 2210 { 2211 $$ = &ast.CreateTableStmt{Select: $1} 2212 } 2213 | 2214 SubSelect %prec createTableSelect 2215 // TODO: We may need better solution as issue #320. 2216 { 2217 $$ = &ast.CreateTableStmt{Select: $1} 2218 } 2219 2220 LikeTableWithOrWithoutParen: 2221 "LIKE" TableName 2222 { 2223 $$ = $2 2224 } 2225 | 2226 '(' "LIKE" TableName ')' 2227 { 2228 $$ = $3 2229 } 2230 2231 /******************************************************************* 2232 * 2233 * Create View Statement 2234 * 2235 * Example: 2236 * CREATE VIEW OR REPLACE ALGORITHM = MERGE DEFINER="root@localhost" SQL SECURITY = definer view_name (col1,col2) 2237 * as select Col1,Col2 from table WITH LOCAL CHECK OPTION 2238 *******************************************************************/ 2239 CreateViewStmt: 2240 "CREATE" OrReplace ViewAlgorithm ViewDefiner ViewSQLSecurity "VIEW" ViewName ViewFieldList "AS" SelectStmt ViewCheckOption 2241 { 2242 startOffset := parser.startOffset(&yyS[yypt-1]) 2243 selStmt := $10.(*ast.SelectStmt) 2244 selStmt.SetText(strings.TrimSpace(parser.src[startOffset:])) 2245 x := &ast.CreateViewStmt { 2246 OrReplace: $2.(bool), 2247 ViewName: $7.(*ast.TableName), 2248 Select: selStmt, 2249 Algorithm: $3.(model.ViewAlgorithm), 2250 Definer: $4.(*auth.UserIdentity), 2251 Security: $5.(model.ViewSecurity), 2252 } 2253 if $8 != nil{ 2254 x.Cols = $8.([]model.CIStr) 2255 } 2256 if $11 !=nil { 2257 x.CheckOption = $11.(model.ViewCheckOption) 2258 endOffset := parser.startOffset(&yyS[yypt]) 2259 selStmt.SetText(strings.TrimSpace(parser.src[startOffset:endOffset])) 2260 } else { 2261 x.CheckOption = model.CheckOptionCascaded 2262 } 2263 $$ = x 2264 } 2265 2266 OrReplace: 2267 { 2268 $$ = false 2269 } 2270 | "OR" "REPLACE" 2271 { 2272 $$ = true 2273 } 2274 2275 ViewAlgorithm: 2276 /* EMPTY */ 2277 { 2278 $$ = model.AlgorithmUndefined 2279 } 2280 | "ALGORITHM" "=" "UNDEFINED" 2281 { 2282 $$ = model.AlgorithmUndefined 2283 } 2284 | "ALGORITHM" "=" "MERGE" 2285 { 2286 $$ = model.AlgorithmMerge 2287 } 2288 | "ALGORITHM" "=" "TEMPTABLE" 2289 { 2290 $$ = model.AlgorithmTemptable 2291 } 2292 2293 ViewDefiner: 2294 /* EMPTY */ 2295 { 2296 $$ = &auth.UserIdentity{CurrentUser: true} 2297 } 2298 | "DEFINER" "=" Username 2299 { 2300 $$ = $3 2301 } 2302 2303 ViewSQLSecurity: 2304 /* EMPTY */ 2305 { 2306 $$ = model.SecurityDefiner 2307 } 2308 | "SQL" "SECURITY" "DEFINER" 2309 { 2310 $$ = model.SecurityDefiner 2311 } 2312 | "SQL" "SECURITY" "INVOKER" 2313 { 2314 $$ = model.SecurityInvoker 2315 } 2316 2317 ViewName: 2318 TableName 2319 { 2320 $$ = $1.(*ast.TableName) 2321 } 2322 2323 ViewFieldList: 2324 /* Empty */ 2325 { 2326 $$ = nil 2327 } 2328 | '(' ColumnList ')' 2329 { 2330 $$ = $2.([]model.CIStr) 2331 } 2332 2333 ColumnList: 2334 Identifier 2335 { 2336 $$ = []model.CIStr{model.NewCIStr($1)} 2337 } 2338 | ColumnList ',' Identifier 2339 { 2340 $$ = append($1.([]model.CIStr), model.NewCIStr($3)) 2341 } 2342 2343 ViewCheckOption: 2344 /* EMPTY */ 2345 { 2346 $$ = nil 2347 } 2348 | "WITH" "CASCADED" "CHECK" "OPTION" 2349 { 2350 $$ = model.CheckOptionCascaded 2351 } 2352 | "WITH" "LOCAL" "CHECK" "OPTION" 2353 { 2354 $$ = model.CheckOptionLocal 2355 } 2356 2357 /****************************************************************** 2358 * Do statement 2359 * See https://dev.mysql.com/doc/refman/5.7/en/do.html 2360 ******************************************************************/ 2361 DoStmt: 2362 "DO" ExpressionList 2363 { 2364 $$ = &ast.DoStmt { 2365 Exprs: $2.([]ast.ExprNode), 2366 } 2367 } 2368 2369 /******************************************************************* 2370 * 2371 * Delete Statement 2372 * 2373 *******************************************************************/ 2374 DeleteFromStmt: 2375 "DELETE" TableOptimizerHints PriorityOpt QuickOptional IgnoreOptional "FROM" TableName IndexHintListOpt WhereClauseOptional OrderByOptional LimitClause 2376 { 2377 // Single Table 2378 tn := $7.(*ast.TableName) 2379 tn.IndexHints = $8.([]*ast.IndexHint) 2380 join := &ast.Join{Left: &ast.TableSource{Source: tn}, Right: nil} 2381 x := &ast.DeleteStmt{ 2382 TableRefs: &ast.TableRefsClause{TableRefs: join}, 2383 Priority: $3.(mysql.PriorityEnum), 2384 Quick: $4.(bool), 2385 IgnoreErr: $5.(bool), 2386 } 2387 if $9 != nil { 2388 x.Where = $9.(ast.ExprNode) 2389 } 2390 if $10 != nil { 2391 x.Order = $10.(*ast.OrderByClause) 2392 } 2393 if $11 != nil { 2394 x.Limit = $11.(*ast.Limit) 2395 } 2396 2397 $$ = x 2398 } 2399 | "DELETE" TableOptimizerHints PriorityOpt QuickOptional IgnoreOptional TableNameList "FROM" TableRefs WhereClauseOptional 2400 { 2401 // Multiple Table 2402 x := &ast.DeleteStmt{ 2403 Priority: $3.(mysql.PriorityEnum), 2404 Quick: $4.(bool), 2405 IgnoreErr: $5.(bool), 2406 IsMultiTable: true, 2407 BeforeFrom: true, 2408 Tables: &ast.DeleteTableList{Tables: $6.([]*ast.TableName)}, 2409 TableRefs: &ast.TableRefsClause{TableRefs: $8.(*ast.Join)}, 2410 } 2411 if $2 != nil { 2412 x.TableHints = $2.([]*ast.TableOptimizerHint) 2413 } 2414 if $9 != nil { 2415 x.Where = $9.(ast.ExprNode) 2416 } 2417 $$ = x 2418 } 2419 2420 | "DELETE" TableOptimizerHints PriorityOpt QuickOptional IgnoreOptional "FROM" TableNameList "USING" TableRefs WhereClauseOptional 2421 { 2422 // Multiple Table 2423 x := &ast.DeleteStmt{ 2424 Priority: $3.(mysql.PriorityEnum), 2425 Quick: $4.(bool), 2426 IgnoreErr: $5.(bool), 2427 IsMultiTable: true, 2428 Tables: &ast.DeleteTableList{Tables: $7.([]*ast.TableName)}, 2429 TableRefs: &ast.TableRefsClause{TableRefs: $9.(*ast.Join)}, 2430 } 2431 if $2 != nil { 2432 x.TableHints = $2.([]*ast.TableOptimizerHint) 2433 } 2434 if $10 != nil { 2435 x.Where = $10.(ast.ExprNode) 2436 } 2437 $$ = x 2438 } 2439 2440 DatabaseSym: 2441 "DATABASE" 2442 2443 DropDatabaseStmt: 2444 "DROP" DatabaseSym IfExists DBName 2445 { 2446 $$ = &ast.DropDatabaseStmt{IfExists: $3.(bool), Name: $4.(string)} 2447 } 2448 2449 DropIndexStmt: 2450 "DROP" "INDEX" IfExists Identifier "ON" TableName 2451 { 2452 $$ = &ast.DropIndexStmt{IfExists: $3.(bool), IndexName: $4, Table: $6.(*ast.TableName)} 2453 } 2454 2455 DropTableStmt: 2456 "DROP" TableOrTables TableNameList RestrictOrCascadeOpt 2457 { 2458 $$ = &ast.DropTableStmt{Tables: $3.([]*ast.TableName), IsView: false} 2459 } 2460 | "DROP" TableOrTables "IF" "EXISTS" TableNameList RestrictOrCascadeOpt 2461 { 2462 $$ = &ast.DropTableStmt{IfExists: true, Tables: $5.([]*ast.TableName), IsView: false} 2463 } 2464 2465 DropViewStmt: 2466 "DROP" "VIEW" TableNameList RestrictOrCascadeOpt 2467 { 2468 $$ = &ast.DropTableStmt{Tables: $3.([]*ast.TableName), IsView: true} 2469 } 2470 | 2471 "DROP" "VIEW" "IF" "EXISTS" TableNameList RestrictOrCascadeOpt 2472 { 2473 $$ = &ast.DropTableStmt{IfExists: true, Tables: $5.([]*ast.TableName), IsView: true} 2474 } 2475 2476 DropUserStmt: 2477 "DROP" "USER" UsernameList 2478 { 2479 $$ = &ast.DropUserStmt{IfExists: false, UserList: $3.([]*auth.UserIdentity)} 2480 } 2481 | "DROP" "USER" "IF" "EXISTS" UsernameList 2482 { 2483 $$ = &ast.DropUserStmt{IfExists: true, UserList: $5.([]*auth.UserIdentity)} 2484 } 2485 2486 DropRoleStmt: 2487 "DROP" "ROLE" RolenameList 2488 { 2489 } 2490 | "DROP" "ROLE" "IF" "EXISTS" RolenameList 2491 { 2492 } 2493 2494 DropStatsStmt: 2495 "DROP" "STATS" TableName 2496 { 2497 $$ = &ast.DropStatsStmt{Table: $3.(*ast.TableName)} 2498 } 2499 2500 RestrictOrCascadeOpt: 2501 {} 2502 | "RESTRICT" 2503 | "CASCADE" 2504 2505 TableOrTables: 2506 "TABLE" 2507 | "TABLES" 2508 2509 EqOpt: 2510 {} 2511 | eq 2512 2513 EmptyStmt: 2514 /* EMPTY */ 2515 { 2516 $$ = nil 2517 } 2518 2519 TraceStmt: 2520 "TRACE" TraceableStmt 2521 { 2522 $$ = &ast.TraceStmt{ 2523 Stmt: $2, 2524 Format: "json", 2525 } 2526 startOffset := parser.startOffset(&yyS[yypt]) 2527 $2.SetText(string(parser.src[startOffset:])) 2528 } 2529 | "TRACE" "FORMAT" "=" stringLit TraceableStmt 2530 { 2531 $$ = &ast.TraceStmt{ 2532 Stmt: $5, 2533 Format: $4, 2534 } 2535 startOffset := parser.startOffset(&yyS[yypt]) 2536 $5.SetText(string(parser.src[startOffset:])) 2537 } 2538 2539 ExplainSym: 2540 "EXPLAIN" | "DESCRIBE" | "DESC" 2541 2542 ExplainStmt: 2543 ExplainSym TableName 2544 { 2545 $$ = &ast.ExplainStmt{ 2546 Stmt: &ast.ShowStmt{ 2547 Tp: ast.ShowColumns, 2548 Table: $2.(*ast.TableName), 2549 }, 2550 } 2551 } 2552 | ExplainSym TableName ColumnName 2553 { 2554 $$ = &ast.ExplainStmt{ 2555 Stmt: &ast.ShowStmt{ 2556 Tp: ast.ShowColumns, 2557 Table: $2.(*ast.TableName), 2558 Column: $3.(*ast.ColumnName), 2559 }, 2560 } 2561 } 2562 | ExplainSym ExplainableStmt 2563 { 2564 $$ = &ast.ExplainStmt{ 2565 Stmt: $2, 2566 Format: "row", 2567 } 2568 } 2569 | ExplainSym "FORMAT" "=" stringLit ExplainableStmt 2570 { 2571 $$ = &ast.ExplainStmt{ 2572 Stmt: $5, 2573 Format: $4, 2574 } 2575 } 2576 | ExplainSym "ANALYZE" ExplainableStmt 2577 { 2578 $$ = &ast.ExplainStmt { 2579 Stmt: $3, 2580 Format: "row", 2581 Analyze: true, 2582 } 2583 } 2584 2585 LengthNum: 2586 NUM 2587 { 2588 $$ = getUint64FromNUM($1) 2589 } 2590 2591 NUM: 2592 intLit 2593 2594 Expression: 2595 singleAtIdentifier assignmentEq Expression %prec assignmentEq 2596 { 2597 v := $1 2598 v = strings.TrimPrefix(v, "@") 2599 $$ = &ast.VariableExpr{ 2600 Name: v, 2601 IsGlobal: false, 2602 IsSystem: false, 2603 Value: $3, 2604 } 2605 } 2606 | Expression logOr Expression %prec pipes 2607 { 2608 $$ = &ast.BinaryOperationExpr{Op: opcode.LogicOr, L: $1, R: $3} 2609 } 2610 | Expression "XOR" Expression %prec xor 2611 { 2612 $$ = &ast.BinaryOperationExpr{Op: opcode.LogicXor, L: $1, R: $3} 2613 } 2614 | Expression logAnd Expression %prec andand 2615 { 2616 $$ = &ast.BinaryOperationExpr{Op: opcode.LogicAnd, L: $1, R: $3} 2617 } 2618 | "NOT" Expression %prec not 2619 { 2620 expr, ok := $2.(*ast.ExistsSubqueryExpr) 2621 if ok { 2622 expr.Not = true 2623 $$ = $2 2624 } else { 2625 $$ = &ast.UnaryOperationExpr{Op: opcode.Not, V: $2} 2626 } 2627 } 2628 | BoolPri IsOrNotOp trueKwd %prec is 2629 { 2630 $$ = &ast.IsTruthExpr{Expr:$1, Not: !$2.(bool), True: int64(1)} 2631 } 2632 | BoolPri IsOrNotOp falseKwd %prec is 2633 { 2634 $$ = &ast.IsTruthExpr{Expr:$1, Not: !$2.(bool), True: int64(0)} 2635 } 2636 | BoolPri IsOrNotOp "UNKNOWN" %prec is 2637 { 2638 /* https://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html#operator_is */ 2639 $$ = &ast.IsNullExpr{Expr: $1, Not: !$2.(bool)} 2640 } 2641 | BoolPri 2642 2643 MaxValueOrExpression: 2644 "MAXVALUE" 2645 { 2646 $$ = &ast.MaxValueExpr{} 2647 } 2648 | Expression 2649 { 2650 $$ = $1 2651 } 2652 2653 2654 logOr: 2655 pipesAsOr 2656 | "OR" 2657 2658 logAnd: 2659 "&&" | "AND" 2660 2661 ExpressionList: 2662 Expression 2663 { 2664 $$ = []ast.ExprNode{$1} 2665 } 2666 | ExpressionList ',' Expression 2667 { 2668 $$ = append($1.([]ast.ExprNode), $3) 2669 } 2670 2671 MaxValueOrExpressionList: 2672 MaxValueOrExpression 2673 { 2674 $$ = []ast.ExprNode{$1} 2675 } 2676 | MaxValueOrExpressionList ',' MaxValueOrExpression 2677 { 2678 $$ = append($1.([]ast.ExprNode), $3) 2679 } 2680 2681 2682 ExpressionListOpt: 2683 { 2684 $$ = []ast.ExprNode{} 2685 } 2686 | ExpressionList 2687 2688 FuncDatetimePrecListOpt: 2689 { 2690 $$ = []ast.ExprNode{} 2691 } 2692 | FuncDatetimePrecList 2693 { 2694 $$ = $1 2695 } 2696 2697 FuncDatetimePrecList: 2698 intLit 2699 { 2700 expr := ast.NewValueExpr($1) 2701 $$ = []ast.ExprNode{expr} 2702 } 2703 2704 BoolPri: 2705 BoolPri IsOrNotOp "NULL" %prec is 2706 { 2707 $$ = &ast.IsNullExpr{Expr: $1, Not: !$2.(bool)} 2708 } 2709 | BoolPri CompareOp PredicateExpr %prec eq 2710 { 2711 $$ = &ast.BinaryOperationExpr{Op: $2.(opcode.Op), L: $1, R: $3} 2712 } 2713 | BoolPri CompareOp AnyOrAll SubSelect %prec eq 2714 { 2715 sq := $4.(*ast.SubqueryExpr) 2716 sq.MultiRows = true 2717 $$ = &ast.CompareSubqueryExpr{Op: $2.(opcode.Op), L: $1, R: sq, All: $3.(bool)} 2718 } 2719 | BoolPri CompareOp singleAtIdentifier assignmentEq PredicateExpr %prec assignmentEq 2720 { 2721 v := $3 2722 v = strings.TrimPrefix(v, "@") 2723 variable := &ast.VariableExpr{ 2724 Name: v, 2725 IsGlobal: false, 2726 IsSystem: false, 2727 Value: $5, 2728 } 2729 $$ = &ast.BinaryOperationExpr{Op: $2.(opcode.Op), L: $1, R: variable} 2730 } 2731 | PredicateExpr 2732 2733 CompareOp: 2734 ">=" 2735 { 2736 $$ = opcode.GE 2737 } 2738 | '>' 2739 { 2740 $$ = opcode.GT 2741 } 2742 | "<=" 2743 { 2744 $$ = opcode.LE 2745 } 2746 | '<' 2747 { 2748 $$ = opcode.LT 2749 } 2750 | "!=" 2751 { 2752 $$ = opcode.NE 2753 } 2754 | "<>" 2755 { 2756 $$ = opcode.NE 2757 } 2758 | "=" 2759 { 2760 $$ = opcode.EQ 2761 } 2762 | "<=>" 2763 { 2764 $$ = opcode.NullEQ 2765 } 2766 2767 BetweenOrNotOp: 2768 "BETWEEN" 2769 { 2770 $$ = true 2771 } 2772 | "NOT" "BETWEEN" 2773 { 2774 $$ = false 2775 } 2776 2777 IsOrNotOp: 2778 "IS" 2779 { 2780 $$ = true 2781 } 2782 | "IS" "NOT" 2783 { 2784 $$ = false 2785 } 2786 2787 InOrNotOp: 2788 "IN" 2789 { 2790 $$ = true 2791 } 2792 | "NOT" "IN" 2793 { 2794 $$ = false 2795 } 2796 2797 LikeOrNotOp: 2798 "LIKE" 2799 { 2800 $$ = true 2801 } 2802 | "NOT" "LIKE" 2803 { 2804 $$ = false 2805 } 2806 2807 RegexpOrNotOp: 2808 RegexpSym 2809 { 2810 $$ = true 2811 } 2812 | "NOT" RegexpSym 2813 { 2814 $$ = false 2815 } 2816 2817 AnyOrAll: 2818 "ANY" 2819 { 2820 $$ = false 2821 } 2822 | "SOME" 2823 { 2824 $$ = false 2825 } 2826 | "ALL" 2827 { 2828 $$ = true 2829 } 2830 2831 PredicateExpr: 2832 BitExpr InOrNotOp '(' ExpressionList ')' 2833 { 2834 $$ = &ast.PatternInExpr{Expr: $1, Not: !$2.(bool), List: $4.([]ast.ExprNode)} 2835 } 2836 | BitExpr InOrNotOp SubSelect 2837 { 2838 sq := $3.(*ast.SubqueryExpr) 2839 sq.MultiRows = true 2840 $$ = &ast.PatternInExpr{Expr: $1, Not: !$2.(bool), Sel: sq} 2841 } 2842 | BitExpr BetweenOrNotOp BitExpr "AND" PredicateExpr 2843 { 2844 $$ = &ast.BetweenExpr{ 2845 Expr: $1, 2846 Left: $3, 2847 Right: $5, 2848 Not: !$2.(bool), 2849 } 2850 } 2851 | BitExpr LikeOrNotOp SimpleExpr LikeEscapeOpt 2852 { 2853 escape := $4.(string) 2854 if len(escape) > 1 { 2855 yylex.Errorf("Incorrect arguments %s to ESCAPE", escape) 2856 return 1 2857 } else if len(escape) == 0 { 2858 escape = "\\" 2859 } 2860 $$ = &ast.PatternLikeExpr{ 2861 Expr: $1, 2862 Pattern: $3, 2863 Not: !$2.(bool), 2864 Escape: escape[0], 2865 } 2866 } 2867 | BitExpr RegexpOrNotOp SimpleExpr 2868 { 2869 $$ = &ast.PatternRegexpExpr{Expr: $1, Pattern: $3, Not: !$2.(bool)} 2870 } 2871 | BitExpr 2872 2873 RegexpSym: 2874 "REGEXP" | "RLIKE" 2875 2876 LikeEscapeOpt: 2877 %prec empty 2878 { 2879 $$ = "\\" 2880 } 2881 | "ESCAPE" stringLit 2882 { 2883 $$ = $2 2884 } 2885 2886 Field: 2887 '*' 2888 { 2889 $$ = &ast.SelectField{WildCard: &ast.WildCardField{}} 2890 } 2891 | Identifier '.' '*' 2892 { 2893 wildCard := &ast.WildCardField{Table: model.NewCIStr($1)} 2894 $$ = &ast.SelectField{WildCard: wildCard} 2895 } 2896 | Identifier '.' Identifier '.' '*' 2897 { 2898 wildCard := &ast.WildCardField{Schema: model.NewCIStr($1), Table: model.NewCIStr($3)} 2899 $$ = &ast.SelectField{WildCard: wildCard} 2900 } 2901 | Expression FieldAsNameOpt 2902 { 2903 expr := $1 2904 asName := $2.(string) 2905 $$ = &ast.SelectField{Expr: expr, AsName: model.NewCIStr(asName)} 2906 } 2907 | '{' Identifier Expression '}' FieldAsNameOpt 2908 { 2909 /* 2910 * ODBC escape syntax. 2911 * See https://dev.mysql.com/doc/refman/5.7/en/expressions.html 2912 */ 2913 expr := $3 2914 asName := $5.(string) 2915 $$ = &ast.SelectField{Expr: expr, AsName: model.NewCIStr(asName)} 2916 } 2917 2918 FieldAsNameOpt: 2919 /* EMPTY */ 2920 { 2921 $$ = "" 2922 } 2923 | FieldAsName 2924 { 2925 $$ = $1 2926 } 2927 2928 FieldAsName: 2929 Identifier 2930 { 2931 $$ = $1 2932 } 2933 | "AS" Identifier 2934 { 2935 $$ = $2 2936 } 2937 | stringLit 2938 { 2939 $$ = $1 2940 } 2941 | "AS" stringLit 2942 { 2943 $$ = $2 2944 } 2945 2946 FieldList: 2947 Field 2948 { 2949 field := $1.(*ast.SelectField) 2950 field.Offset = parser.startOffset(&yyS[yypt]) 2951 $$ = []*ast.SelectField{field} 2952 } 2953 | FieldList ',' Field 2954 { 2955 2956 fl := $1.([]*ast.SelectField) 2957 last := fl[len(fl)-1] 2958 if last.Expr != nil && last.AsName.O == "" { 2959 lastEnd := parser.endOffset(&yyS[yypt-1]) 2960 last.SetText(parser.src[last.Offset:lastEnd]) 2961 } 2962 newField := $3.(*ast.SelectField) 2963 newField.Offset = parser.startOffset(&yyS[yypt]) 2964 $$ = append(fl, newField) 2965 } 2966 2967 GroupByClause: 2968 "GROUP" "BY" ByList 2969 { 2970 $$ = &ast.GroupByClause{Items: $3.([]*ast.ByItem)} 2971 } 2972 2973 HavingClause: 2974 { 2975 $$ = nil 2976 } 2977 | "HAVING" Expression 2978 { 2979 $$ = &ast.HavingClause{Expr: $2} 2980 } 2981 2982 IfExists: 2983 { 2984 $$ = false 2985 } 2986 | "IF" "EXISTS" 2987 { 2988 $$ = true 2989 } 2990 2991 IfNotExists: 2992 { 2993 $$ = false 2994 } 2995 | "IF" "NOT" "EXISTS" 2996 { 2997 $$ = true 2998 } 2999 3000 3001 IgnoreOptional: 3002 { 3003 $$ = false 3004 } 3005 | "IGNORE" 3006 { 3007 $$ = true 3008 } 3009 3010 IndexName: 3011 { 3012 $$ = "" 3013 } 3014 | Identifier 3015 { 3016 //"index name" 3017 $$ = $1 3018 } 3019 3020 IndexOptionList: 3021 { 3022 $$ = nil 3023 } 3024 | IndexOptionList IndexOption 3025 { 3026 // Merge the options 3027 if $1 == nil { 3028 $$ = $2 3029 } else { 3030 opt1 := $1.(*ast.IndexOption) 3031 opt2 := $2.(*ast.IndexOption) 3032 if len(opt2.Comment) > 0 { 3033 opt1.Comment = opt2.Comment 3034 } else if opt2.Tp != 0 { 3035 opt1.Tp = opt2.Tp 3036 } else if opt2.KeyBlockSize > 0 { 3037 opt1.KeyBlockSize = opt2.KeyBlockSize 3038 } 3039 $$ = opt1 3040 } 3041 } 3042 3043 3044 IndexOption: 3045 "KEY_BLOCK_SIZE" EqOpt LengthNum 3046 { 3047 $$ = &ast.IndexOption{ 3048 KeyBlockSize: $3.(uint64), 3049 } 3050 } 3051 | IndexType 3052 { 3053 $$ = &ast.IndexOption { 3054 Tp: $1.(model.IndexType), 3055 } 3056 } 3057 | "COMMENT" stringLit 3058 { 3059 $$ = &ast.IndexOption { 3060 Comment: $2, 3061 } 3062 } 3063 3064 IndexType: 3065 "USING" "BTREE" 3066 { 3067 $$ = model.IndexTypeBtree 3068 } 3069 | "USING" "HASH" 3070 { 3071 $$ = model.IndexTypeHash 3072 } 3073 3074 IndexTypeOpt: 3075 { 3076 $$ = nil 3077 } 3078 | IndexType 3079 { 3080 $$ = $1 3081 } 3082 3083 /**********************************Identifier********************************************/ 3084 Identifier: 3085 identifier | UnReservedKeyword | NotKeywordToken | TiDBKeyword 3086 3087 UnReservedKeyword: 3088 "ACTION" | "ASCII" | "AUTO_INCREMENT" | "AFTER" | "ALWAYS" | "AVG" | "BEGIN" | "BIT" | "BOOL" | "BOOLEAN" | "BTREE" | "BYTE" | "CLEANUP" | "CHARSET" 3089 | "COLUMNS" | "COMMIT" | "COMPACT" | "COMPRESSED" | "CONSISTENT" | "CURRENT" | "DATA" | "DATE" %prec lowerThanStringLitToken| "DATETIME" | "DAY" | "DEALLOCATE" | "DO" | "DUPLICATE" 3090 | "DYNAMIC"| "END" | "ENGINE" | "ENGINES" | "ENUM" | "ERRORS" | "ESCAPE" | "EXECUTE" | "FIELDS" | "FIRST" | "FIXED" | "FLUSH" | "FOLLOWING" | "FORMAT" | "FULL" |"GLOBAL" 3091 | "HASH" | "HOUR" | "LESS" | "LOCAL" | "LAST" | "NAMES" | "OFFSET" | "PASSWORD" %prec lowerThanEq | "PREPARE" | "QUICK" | "REDUNDANT" 3092 | "ROLE" | "ROLLBACK" | "SAVEPOINT" | "SESSION" | "SIGNED" | "SNAPSHOT" | "START" | "STATUS" | "SUBPARTITIONS" | "SUBPARTITION" | "TABLES" | "TABLESPACE" | "TEXT" | "THAN" | "TIME" %prec lowerThanStringLitToken 3093 | "TIMESTAMP" %prec lowerThanStringLitToken | "TRACE" | "TRANSACTION" | "TRUNCATE" | "UNBOUNDED" | "UNKNOWN" | "VALUE" | "WARNINGS" | "YEAR" | "MODE" | "WEEK" | "ANY" | "SOME" | "USER" | "IDENTIFIED" 3094 | "COLLATION" | "COMMENT" | "AVG_ROW_LENGTH" | "CONNECTION" | "CHECKSUM" | "COMPRESSION" | "KEY_BLOCK_SIZE" | "MASTER" | "MAX_ROWS" 3095 | "MIN_ROWS" | "NATIONAL" | "ROW_FORMAT" | "QUARTER" | "GRANTS" | "TRIGGERS" | "DELAY_KEY_WRITE" | "ISOLATION" | "JSON" 3096 | "REPEATABLE" | "RESPECT" | "COMMITTED" | "UNCOMMITTED" | "ONLY" | "SERIALIZABLE" | "LEVEL" | "VARIABLES" | "SQL_CACHE" | "INDEXES" | "PROCESSLIST" 3097 | "SQL_NO_CACHE" | "DISABLE" | "ENABLE" | "REVERSE" | "PRIVILEGES" | "NO" | "BINLOG" | "FUNCTION" | "VIEW" | "BINDING" | "BINDINGS" | "MODIFY" | "EVENTS" | "PARTITIONS" 3098 | "NONE" | "NULLS" | "SUPER" | "EXCLUSIVE" | "STATS_PERSISTENT" | "ROW_COUNT" | "COALESCE" | "MONTH" | "PROCESS" | "PROFILES" 3099 | "MICROSECOND" | "MINUTE" | "PLUGINS" | "PRECEDING" | "QUERY" | "QUERIES" | "SECOND" | "SEPARATOR" | "SHARE" | "SHARED" | "SLOW" | "MAX_CONNECTIONS_PER_HOUR" | "MAX_QUERIES_PER_HOUR" | "MAX_UPDATES_PER_HOUR" 3100 | "MAX_USER_CONNECTIONS" | "REPLICATION" | "CLIENT" | "SLAVE" | "RELOAD" | "TEMPORARY" | "ROUTINE" | "EVENT" | "ALGORITHM" | "DEFINER" | "INVOKER" | "MERGE" | "TEMPTABLE" | "UNDEFINED" | "SECURITY" | "CASCADED" | "RECOVER" 3101 3102 3103 3104 TiDBKeyword: 3105 "ADMIN" | "BUCKETS" | "CANCEL" | "DDL" | "DRAINER" | "JOBS" | "JOB" | "PUMP" | "STATS" | "STATS_META" | "STATS_HISTOGRAMS" | "STATS_BUCKETS" | "STATS_HEALTHY" | "TIDB" | "TIDB_HJ" | "TIDB_SMJ" | "TIDB_INLJ" | "RESTORE" 3106 3107 NotKeywordToken: 3108 "ADDDATE" | "BIT_AND" | "BIT_OR" | "BIT_XOR" | "CAST" | "COPY" | "COUNT" | "CURTIME" | "DATE_ADD" | "DATE_SUB" | "EXTRACT" | "GET_FORMAT" | "GROUP_CONCAT" 3109 | "INPLACE" | "INSTANT" | "INTERNAL" |"MIN" | "MAX" | "MAX_EXECUTION_TIME" | "NOW" | "RECENT" | "POSITION" | "SUBDATE" | "SUBSTRING" | "SUM" 3110 | "STD" | "STDDEV" | "STDDEV_POP" | "STDDEV_SAMP" | "VARIANCE" | "VAR_POP" | "VAR_SAMP" 3111 | "TIMESTAMPADD" | "TIMESTAMPDIFF" | "TOP" | "TRIM" | "NEXT_ROW_ID" 3112 3113 /************************************************************************************ 3114 * 3115 * Insert Statements 3116 * 3117 * TODO: support PARTITION 3118 **********************************************************************************/ 3119 InsertIntoStmt: 3120 "INSERT" PriorityOpt IgnoreOptional IntoOpt TableName InsertValues OnDuplicateKeyUpdate 3121 { 3122 x := $6.(*ast.InsertStmt) 3123 x.Priority = $2.(mysql.PriorityEnum) 3124 x.IgnoreErr = $3.(bool) 3125 // Wraps many layers here so that it can be processed the same way as select statement. 3126 ts := &ast.TableSource{Source: $5.(*ast.TableName)} 3127 x.Table = &ast.TableRefsClause{TableRefs: &ast.Join{Left: ts}} 3128 if $7 != nil { 3129 x.OnDuplicate = $7.([]*ast.Assignment) 3130 } 3131 $$ = x 3132 } 3133 3134 IntoOpt: 3135 {} 3136 | "INTO" 3137 3138 InsertValues: 3139 '(' ColumnNameListOpt ')' ValueSym ValuesList 3140 { 3141 $$ = &ast.InsertStmt{ 3142 Columns: $2.([]*ast.ColumnName), 3143 Lists: $5.([][]ast.ExprNode), 3144 } 3145 } 3146 | '(' ColumnNameListOpt ')' SelectStmt 3147 { 3148 $$ = &ast.InsertStmt{Columns: $2.([]*ast.ColumnName), Select: $4.(*ast.SelectStmt)} 3149 } 3150 | '(' ColumnNameListOpt ')' '(' SelectStmt ')' 3151 { 3152 $$ = &ast.InsertStmt{Columns: $2.([]*ast.ColumnName), Select: $5.(*ast.SelectStmt)} 3153 } 3154 | '(' ColumnNameListOpt ')' UnionStmt 3155 { 3156 $$ = &ast.InsertStmt{Columns: $2.([]*ast.ColumnName), Select: $4.(*ast.UnionStmt)} 3157 } 3158 | ValueSym ValuesList %prec insertValues 3159 { 3160 $$ = &ast.InsertStmt{Lists: $2.([][]ast.ExprNode)} 3161 } 3162 | '(' SelectStmt ')' 3163 { 3164 $$ = &ast.InsertStmt{Select: $2.(*ast.SelectStmt)} 3165 } 3166 | SelectStmt 3167 { 3168 $$ = &ast.InsertStmt{Select: $1.(*ast.SelectStmt)} 3169 } 3170 | UnionStmt 3171 { 3172 $$ = &ast.InsertStmt{Select: $1.(*ast.UnionStmt)} 3173 } 3174 | "SET" ColumnSetValueList 3175 { 3176 $$ = &ast.InsertStmt{Setlist: $2.([]*ast.Assignment)} 3177 } 3178 3179 ValueSym: 3180 "VALUE" | "VALUES" 3181 3182 ValuesList: 3183 RowValue 3184 { 3185 $$ = [][]ast.ExprNode{$1.([]ast.ExprNode)} 3186 } 3187 | ValuesList ',' RowValue 3188 { 3189 $$ = append($1.([][]ast.ExprNode), $3.([]ast.ExprNode)) 3190 } 3191 3192 RowValue: 3193 '(' ValuesOpt ')' 3194 { 3195 $$ = $2 3196 } 3197 3198 ValuesOpt: 3199 { 3200 $$ = []ast.ExprNode{} 3201 } 3202 | Values 3203 3204 Values: 3205 Values ',' ExprOrDefault 3206 { 3207 $$ = append($1.([]ast.ExprNode), $3) 3208 } 3209 | ExprOrDefault 3210 { 3211 $$ = []ast.ExprNode{$1} 3212 } 3213 3214 ExprOrDefault: 3215 Expression 3216 | "DEFAULT" 3217 { 3218 $$ = &ast.DefaultExpr{} 3219 } 3220 3221 ColumnSetValue: 3222 ColumnName eq Expression 3223 { 3224 $$ = &ast.Assignment{ 3225 Column: $1.(*ast.ColumnName), 3226 Expr: $3, 3227 } 3228 } 3229 3230 ColumnSetValueList: 3231 { 3232 $$ = []*ast.Assignment{} 3233 } 3234 | ColumnSetValue 3235 { 3236 $$ = []*ast.Assignment{$1.(*ast.Assignment)} 3237 } 3238 | ColumnSetValueList ',' ColumnSetValue 3239 { 3240 $$ = append($1.([]*ast.Assignment), $3.(*ast.Assignment)) 3241 } 3242 3243 /* 3244 * ON DUPLICATE KEY UPDATE col_name=expr [, col_name=expr] ... 3245 * See https://dev.mysql.com/doc/refman/5.7/en/insert-on-duplicate.html 3246 */ 3247 OnDuplicateKeyUpdate: 3248 { 3249 $$ = nil 3250 } 3251 | "ON" "DUPLICATE" "KEY" "UPDATE" AssignmentList 3252 { 3253 $$ = $5 3254 } 3255 3256 /***********************************Insert Statements END************************************/ 3257 3258 /************************************************************************************ 3259 * Replace Statements 3260 * See https://dev.mysql.com/doc/refman/5.7/en/replace.html 3261 * 3262 * TODO: support PARTITION 3263 **********************************************************************************/ 3264 ReplaceIntoStmt: 3265 "REPLACE" PriorityOpt IntoOpt TableName InsertValues 3266 { 3267 x := $5.(*ast.InsertStmt) 3268 x.IsReplace = true 3269 x.Priority = $2.(mysql.PriorityEnum) 3270 ts := &ast.TableSource{Source: $4.(*ast.TableName)} 3271 x.Table = &ast.TableRefsClause{TableRefs: &ast.Join{Left: ts}} 3272 $$ = x 3273 } 3274 3275 /***********************************Replace Statements END************************************/ 3276 3277 ODBCDateTimeType: 3278 "d" 3279 { 3280 $$ = ast.DateLiteral 3281 } 3282 | "t" 3283 { 3284 $$ = ast.TimeLiteral 3285 } 3286 | "ts" 3287 { 3288 $$ = ast.TimestampLiteral 3289 } 3290 3291 Literal: 3292 "FALSE" 3293 { 3294 $$ = ast.NewValueExpr(false) 3295 } 3296 | "NULL" 3297 { 3298 $$ = ast.NewValueExpr(nil) 3299 } 3300 | "TRUE" 3301 { 3302 $$ = ast.NewValueExpr(true) 3303 } 3304 | floatLit 3305 { 3306 $$ = ast.NewValueExpr($1) 3307 } 3308 | decLit 3309 { 3310 $$ = ast.NewValueExpr($1) 3311 } 3312 | intLit 3313 { 3314 $$ = ast.NewValueExpr($1) 3315 } 3316 | StringLiteral %prec lowerThanStringLitToken 3317 { 3318 $$ = $1 3319 } 3320 | "UNDERSCORE_CHARSET" stringLit 3321 { 3322 // See https://dev.mysql.com/doc/refman/5.7/en/charset-literal.html 3323 co, err := mysql.GetDefaultCollation($1) 3324 if err != nil { 3325 yylex.Errorf("Get collation error for charset: %s", $1) 3326 return 1 3327 } 3328 expr := ast.NewValueExpr($2) 3329 tp := expr.GetType() 3330 tp.Charset = $1 3331 tp.Collate = co 3332 if tp.Collate == mysql.CollationBin { 3333 tp.Flag |= mysql.BinaryFlag 3334 } 3335 $$ = expr 3336 } 3337 | hexLit 3338 { 3339 $$ = ast.NewValueExpr($1) 3340 } 3341 | bitLit 3342 { 3343 $$ = ast.NewValueExpr($1) 3344 } 3345 3346 StringLiteral: 3347 stringLit 3348 { 3349 expr := ast.NewValueExpr($1) 3350 $$ = expr 3351 } 3352 | StringLiteral stringLit 3353 { 3354 valExpr := $1.(ast.ValueExpr) 3355 strLit := valExpr.GetString() 3356 expr := ast.NewValueExpr(strLit+$2) 3357 // Fix #4239, use first string literal as projection name. 3358 if valExpr.GetProjectionOffset() >= 0 { 3359 expr.SetProjectionOffset(valExpr.GetProjectionOffset()) 3360 } else { 3361 expr.SetProjectionOffset(len(strLit)) 3362 } 3363 $$ = expr 3364 } 3365 3366 3367 OrderBy: 3368 "ORDER" "BY" ByList 3369 { 3370 $$ = &ast.OrderByClause{Items: $3.([]*ast.ByItem)} 3371 } 3372 3373 ByList: 3374 ByItem 3375 { 3376 $$ = []*ast.ByItem{$1.(*ast.ByItem)} 3377 } 3378 | ByList ',' ByItem 3379 { 3380 $$ = append($1.([]*ast.ByItem), $3.(*ast.ByItem)) 3381 } 3382 3383 ByItem: 3384 Expression Order 3385 { 3386 expr := $1 3387 valueExpr, ok := expr.(ast.ValueExpr) 3388 if ok { 3389 position, isPosition := valueExpr.GetValue().(int64) 3390 if isPosition { 3391 expr = &ast.PositionExpr{N: int(position)} 3392 } 3393 } 3394 $$ = &ast.ByItem{Expr: expr, Desc: $2.(bool)} 3395 } 3396 3397 Order: 3398 /* EMPTY */ 3399 { 3400 $$ = false // ASC by default 3401 } 3402 | "ASC" 3403 { 3404 $$ = false 3405 } 3406 | "DESC" 3407 { 3408 $$ = true 3409 } 3410 3411 OrderByOptional: 3412 { 3413 $$ = nil 3414 } 3415 | OrderBy 3416 { 3417 $$ = $1 3418 } 3419 3420 BitExpr: 3421 BitExpr '|' BitExpr %prec '|' 3422 { 3423 $$ = &ast.BinaryOperationExpr{Op: opcode.Or, L: $1, R: $3} 3424 } 3425 | BitExpr '&' BitExpr %prec '&' 3426 { 3427 $$ = &ast.BinaryOperationExpr{Op: opcode.And, L: $1, R: $3} 3428 } 3429 | BitExpr "<<" BitExpr %prec lsh 3430 { 3431 $$ = &ast.BinaryOperationExpr{Op: opcode.LeftShift, L: $1, R: $3} 3432 } 3433 | BitExpr ">>" BitExpr %prec rsh 3434 { 3435 $$ = &ast.BinaryOperationExpr{Op: opcode.RightShift, L: $1, R: $3} 3436 } 3437 | BitExpr '+' BitExpr %prec '+' 3438 { 3439 $$ = &ast.BinaryOperationExpr{Op: opcode.Plus, L: $1, R: $3} 3440 } 3441 | BitExpr '-' BitExpr %prec '-' 3442 { 3443 $$ = &ast.BinaryOperationExpr{Op: opcode.Minus, L: $1, R: $3} 3444 } 3445 | BitExpr '+' "INTERVAL" Expression TimeUnit %prec '+' 3446 { 3447 $$ = &ast.FuncCallExpr{ 3448 FnName: model.NewCIStr("DATE_ADD"), 3449 Args: []ast.ExprNode{ 3450 $1, 3451 $4, 3452 ast.NewValueExpr($5), 3453 }, 3454 } 3455 } 3456 | BitExpr '-' "INTERVAL" Expression TimeUnit %prec '+' 3457 { 3458 $$ = &ast.FuncCallExpr{ 3459 FnName: model.NewCIStr("DATE_SUB"), 3460 Args: []ast.ExprNode{ 3461 $1, 3462 $4, 3463 ast.NewValueExpr($5), 3464 }, 3465 } 3466 } 3467 | BitExpr '*' BitExpr %prec '*' 3468 { 3469 $$ = &ast.BinaryOperationExpr{Op: opcode.Mul, L: $1, R: $3} 3470 } 3471 | BitExpr '/' BitExpr %prec '/' 3472 { 3473 $$ = &ast.BinaryOperationExpr{Op: opcode.Div, L: $1, R: $3} 3474 } 3475 | BitExpr '%' BitExpr %prec '%' 3476 { 3477 $$ = &ast.BinaryOperationExpr{Op: opcode.Mod, L: $1, R: $3} 3478 } 3479 | BitExpr "DIV" BitExpr %prec div 3480 { 3481 $$ = &ast.BinaryOperationExpr{Op: opcode.IntDiv, L: $1, R: $3} 3482 } 3483 | BitExpr "MOD" BitExpr %prec mod 3484 { 3485 $$ = &ast.BinaryOperationExpr{Op: opcode.Mod, L: $1, R: $3} 3486 } 3487 | BitExpr '^' BitExpr 3488 { 3489 $$ = &ast.BinaryOperationExpr{Op: opcode.Xor, L: $1, R: $3} 3490 } 3491 | SimpleExpr 3492 3493 SimpleIdent: 3494 Identifier 3495 { 3496 $$ = &ast.ColumnNameExpr{Name: &ast.ColumnName{ 3497 Name: model.NewCIStr($1), 3498 }} 3499 } 3500 | Identifier '.' Identifier 3501 { 3502 $$ = &ast.ColumnNameExpr{Name: &ast.ColumnName{ 3503 Table: model.NewCIStr($1), 3504 Name: model.NewCIStr($3), 3505 }} 3506 } 3507 | '.' Identifier '.' Identifier 3508 { 3509 $$ = &ast.ColumnNameExpr{Name: &ast.ColumnName{ 3510 Table: model.NewCIStr($2), 3511 Name: model.NewCIStr($4), 3512 }} 3513 } 3514 | Identifier '.' Identifier '.' Identifier 3515 { 3516 $$ = &ast.ColumnNameExpr{Name: &ast.ColumnName{ 3517 Schema: model.NewCIStr($1), 3518 Table: model.NewCIStr($3), 3519 Name: model.NewCIStr($5), 3520 }} 3521 } 3522 3523 SimpleExpr: 3524 SimpleIdent 3525 | FunctionCallKeyword 3526 | FunctionCallNonKeyword 3527 | FunctionCallGeneric 3528 | SimpleExpr "COLLATE" StringName %prec neg 3529 { 3530 // TODO: Create a builtin function hold expr and collation. When do evaluation, convert expr result using the collation. 3531 $$ = $1 3532 } 3533 | WindowFuncCall 3534 { 3535 $$ = $1.(*ast.WindowFuncExpr) 3536 } 3537 | Literal 3538 | paramMarker 3539 { 3540 $$ = ast.NewParamMarkerExpr(yyS[yypt].offset) 3541 } 3542 | Variable 3543 | SumExpr 3544 | '!' SimpleExpr %prec neg 3545 { 3546 $$ = &ast.UnaryOperationExpr{Op: opcode.Not, V: $2} 3547 } 3548 | '~' SimpleExpr %prec neg 3549 { 3550 $$ = &ast.UnaryOperationExpr{Op: opcode.BitNeg, V: $2} 3551 } 3552 | '-' SimpleExpr %prec neg 3553 { 3554 $$ = &ast.UnaryOperationExpr{Op: opcode.Minus, V: $2} 3555 } 3556 | '+' SimpleExpr %prec neg 3557 { 3558 $$ = &ast.UnaryOperationExpr{Op: opcode.Plus, V: $2} 3559 } 3560 | SimpleExpr pipes SimpleExpr 3561 { 3562 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr(ast.Concat), Args: []ast.ExprNode{$1, $3}} 3563 } 3564 | not2 SimpleExpr %prec neg 3565 { 3566 $$ = &ast.UnaryOperationExpr{Op: opcode.Not, V: $2} 3567 } 3568 | SubSelect 3569 | '(' Expression ')' { 3570 startOffset := parser.startOffset(&yyS[yypt-1]) 3571 endOffset := parser.endOffset(&yyS[yypt]) 3572 expr := $2 3573 expr.SetText(parser.src[startOffset:endOffset]) 3574 $$ = &ast.ParenthesesExpr{Expr: expr} 3575 } 3576 | '(' ExpressionList ',' Expression ')' 3577 { 3578 values := append($2.([]ast.ExprNode), $4) 3579 $$ = &ast.RowExpr{Values: values} 3580 } 3581 | "ROW" '(' ExpressionList ',' Expression ')' 3582 { 3583 values := append($3.([]ast.ExprNode), $5) 3584 $$ = &ast.RowExpr{Values: values} 3585 } 3586 | "EXISTS" SubSelect 3587 { 3588 sq := $2.(*ast.SubqueryExpr) 3589 sq.Exists = true 3590 $$ = &ast.ExistsSubqueryExpr{Sel: sq} 3591 } 3592 | "BINARY" SimpleExpr %prec neg 3593 { 3594 // See https://dev.mysql.com/doc/refman/5.7/en/cast-functions.html#operator_binary 3595 x := types.NewFieldType(mysql.TypeString) 3596 x.Charset = mysql.CharsetBin 3597 x.Collate = mysql.CharsetBin 3598 $$ = &ast.FuncCastExpr{ 3599 Expr: $2, 3600 Tp: x, 3601 FunctionType: ast.CastBinaryOperator, 3602 } 3603 } 3604 | builtinCast '(' Expression "AS" CastType ')' 3605 { 3606 /* See https://dev.mysql.com/doc/refman/5.7/en/cast-functions.html#function_cast */ 3607 tp := $5.(*types.FieldType) 3608 defaultFlen, defaultDecimal := mysql.GetDefaultFieldLengthAndDecimalForCast(tp.Tp) 3609 if tp.Flen == types.UnspecifiedLength { 3610 tp.Flen = defaultFlen 3611 } 3612 if tp.Decimal == types.UnspecifiedLength { 3613 tp.Decimal = defaultDecimal 3614 } 3615 $$ = &ast.FuncCastExpr{ 3616 Expr: $3, 3617 Tp: tp, 3618 FunctionType: ast.CastFunction, 3619 } 3620 } 3621 | "CASE" ExpressionOpt WhenClauseList ElseOpt "END" 3622 { 3623 x := &ast.CaseExpr{WhenClauses: $3.([]*ast.WhenClause)} 3624 if $2 != nil { 3625 x.Value = $2 3626 } 3627 if $4 != nil { 3628 x.ElseClause = $4.(ast.ExprNode) 3629 } 3630 $$ = x 3631 } 3632 | "CONVERT" '(' Expression ',' CastType ')' 3633 { 3634 // See https://dev.mysql.com/doc/refman/5.7/en/cast-functions.html#function_convert 3635 tp := $5.(*types.FieldType) 3636 defaultFlen, defaultDecimal := mysql.GetDefaultFieldLengthAndDecimalForCast(tp.Tp) 3637 if tp.Flen == types.UnspecifiedLength { 3638 tp.Flen = defaultFlen 3639 } 3640 if tp.Decimal == types.UnspecifiedLength { 3641 tp.Decimal = defaultDecimal 3642 } 3643 $$ = &ast.FuncCastExpr{ 3644 Expr: $3, 3645 Tp: tp, 3646 FunctionType: ast.CastConvertFunction, 3647 } 3648 } 3649 | "CONVERT" '(' Expression "USING" StringName ')' 3650 { 3651 // See https://dev.mysql.com/doc/refman/5.7/en/cast-functions.html#function_convert 3652 charset1 := ast.NewValueExpr($5) 3653 $$ = &ast.FuncCallExpr{ 3654 FnName: model.NewCIStr($1), 3655 Args: []ast.ExprNode{$3, charset1}, 3656 } 3657 } 3658 | "DEFAULT" '(' SimpleIdent ')' 3659 { 3660 $$ = &ast.DefaultExpr{Name: $3.(*ast.ColumnNameExpr).Name} 3661 } 3662 | "VALUES" '(' SimpleIdent ')' %prec lowerThanInsertValues 3663 { 3664 $$ = &ast.ValuesExpr{Column: $3.(*ast.ColumnNameExpr)} 3665 } 3666 | SimpleIdent jss stringLit 3667 { 3668 expr := ast.NewValueExpr($3) 3669 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr(ast.JSONExtract), Args: []ast.ExprNode{$1, expr}} 3670 } 3671 | SimpleIdent juss stringLit 3672 { 3673 expr := ast.NewValueExpr($3) 3674 extract := &ast.FuncCallExpr{FnName: model.NewCIStr(ast.JSONExtract), Args: []ast.ExprNode{$1, expr}} 3675 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr(ast.JSONUnquote), Args: []ast.ExprNode{extract}} 3676 } 3677 3678 DistinctKwd: 3679 "DISTINCT" 3680 | "DISTINCTROW" 3681 3682 DistinctOpt: 3683 "ALL" 3684 { 3685 $$ = false 3686 } 3687 | DistinctKwd 3688 { 3689 $$ = true 3690 } 3691 3692 DefaultFalseDistinctOpt: 3693 { 3694 $$ = false 3695 } 3696 | DistinctOpt 3697 3698 DefaultTrueDistinctOpt: 3699 { 3700 $$ = true 3701 } 3702 | DistinctOpt 3703 3704 BuggyDefaultFalseDistinctOpt: 3705 DefaultFalseDistinctOpt 3706 | DistinctKwd "ALL" 3707 { 3708 $$ = true 3709 } 3710 3711 3712 FunctionNameConflict: 3713 "ASCII" 3714 | "CHARSET" 3715 | "COALESCE" 3716 | "COLLATION" 3717 | "DATE" 3718 | "DATABASE" 3719 | "DAY" 3720 | "HOUR" 3721 | "IF" 3722 | "INTERVAL" %prec lowerThanIntervalKeyword 3723 | "FORMAT" 3724 | "LEFT" 3725 | "MICROSECOND" 3726 | "MINUTE" 3727 | "MONTH" 3728 | builtinNow 3729 | "QUARTER" 3730 | "REPEAT" 3731 | "REPLACE" 3732 | "REVERSE" 3733 | "RIGHT" 3734 | "ROW_COUNT" 3735 | "SECOND" 3736 | "TIME" 3737 | "TIMESTAMP" 3738 | "TRUNCATE" 3739 | "USER" 3740 | "WEEK" 3741 | "YEAR" 3742 3743 OptionalBraces: 3744 {} | '(' ')' {} 3745 3746 FunctionNameOptionalBraces: 3747 "CURRENT_USER" 3748 | "CURRENT_DATE" 3749 | "UTC_DATE" 3750 3751 FunctionNameDatetimePrecision: 3752 "CURRENT_TIME" 3753 | "CURRENT_TIMESTAMP" 3754 | "LOCALTIME" 3755 | "LOCALTIMESTAMP" 3756 | "UTC_TIME" 3757 | "UTC_TIMESTAMP" 3758 3759 FunctionCallKeyword: 3760 FunctionNameConflict '(' ExpressionListOpt ')' 3761 { 3762 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1), Args: $3.([]ast.ExprNode)} 3763 } 3764 | builtinUser '(' ExpressionListOpt ')' 3765 { 3766 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1), Args: $3.([]ast.ExprNode)} 3767 } 3768 | FunctionNameOptionalBraces OptionalBraces 3769 { 3770 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1)} 3771 } 3772 | builtinCurDate '(' ')' 3773 { 3774 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1)} 3775 } 3776 | FunctionNameDatetimePrecision FuncDatetimePrec 3777 { 3778 args := []ast.ExprNode{} 3779 if $2 != nil { 3780 args = append(args, $2.(ast.ExprNode)) 3781 } 3782 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1), Args: args} 3783 } 3784 | "CHAR" '(' ExpressionList ')' 3785 { 3786 nilVal := ast.NewValueExpr(nil) 3787 args := $3.([]ast.ExprNode) 3788 $$ = &ast.FuncCallExpr{ 3789 FnName: model.NewCIStr(ast.CharFunc), 3790 Args: append(args, nilVal), 3791 } 3792 } 3793 | "CHAR" '(' ExpressionList "USING" StringName ')' 3794 { 3795 charset1 := ast.NewValueExpr($5) 3796 args := $3.([]ast.ExprNode) 3797 $$ = &ast.FuncCallExpr{ 3798 FnName: model.NewCIStr(ast.CharFunc), 3799 Args: append(args, charset1), 3800 } 3801 } 3802 | "DATE" stringLit 3803 { 3804 expr := ast.NewValueExpr($2) 3805 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr(ast.DateLiteral), Args: []ast.ExprNode{expr}} 3806 } 3807 | "TIME" stringLit 3808 { 3809 expr := ast.NewValueExpr($2) 3810 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr(ast.TimeLiteral), Args: []ast.ExprNode{expr}} 3811 } 3812 | "TIMESTAMP" stringLit 3813 { 3814 expr := ast.NewValueExpr($2) 3815 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr(ast.TimestampLiteral), Args: []ast.ExprNode{expr}} 3816 } 3817 | "INSERT" '(' ExpressionListOpt ')' 3818 { 3819 $$ = &ast.FuncCallExpr{FnName:model.NewCIStr(ast.InsertFunc), Args: $3.([]ast.ExprNode)} 3820 } 3821 | "MOD" '(' BitExpr ',' BitExpr ')' 3822 { 3823 $$ = &ast.BinaryOperationExpr{Op: opcode.Mod, L: $3, R: $5} 3824 } 3825 | "PASSWORD" '(' ExpressionListOpt ')' 3826 { 3827 $$ = &ast.FuncCallExpr{FnName:model.NewCIStr(ast.PasswordFunc), Args: $3.([]ast.ExprNode)} 3828 } 3829 | '{' ODBCDateTimeType stringLit '}' 3830 { 3831 // This is ODBC syntax for date and time literals. 3832 // See: https://dev.mysql.com/doc/refman/5.7/en/date-and-time-literals.html 3833 expr := ast.NewValueExpr($3) 3834 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($2), Args: []ast.ExprNode{expr}} 3835 } 3836 3837 FunctionCallNonKeyword: 3838 builtinCurTime '(' FuncDatetimePrecListOpt ')' 3839 { 3840 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1), Args: $3.([]ast.ExprNode)} 3841 } 3842 | builtinSysDate '(' FuncDatetimePrecListOpt ')' 3843 { 3844 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1), Args: $3.([]ast.ExprNode)} 3845 } 3846 | FunctionNameDateArithMultiForms '(' Expression ',' Expression ')' 3847 { 3848 $$ = &ast.FuncCallExpr{ 3849 FnName: model.NewCIStr($1), 3850 Args: []ast.ExprNode{ 3851 $3, 3852 $5, 3853 ast.NewValueExpr("DAY"), 3854 }, 3855 } 3856 } 3857 | FunctionNameDateArithMultiForms '(' Expression ',' "INTERVAL" Expression TimeUnit ')' 3858 { 3859 $$ = &ast.FuncCallExpr{ 3860 FnName: model.NewCIStr($1), 3861 Args: []ast.ExprNode{ 3862 $3, 3863 $6, 3864 ast.NewValueExpr($7), 3865 }, 3866 } 3867 } 3868 | FunctionNameDateArith '(' Expression ',' "INTERVAL" Expression TimeUnit ')' 3869 { 3870 $$ = &ast.FuncCallExpr{ 3871 FnName: model.NewCIStr($1), 3872 Args: []ast.ExprNode{ 3873 $3, 3874 $6, 3875 ast.NewValueExpr($7), 3876 }, 3877 } 3878 } 3879 | builtinExtract '(' TimeUnit "FROM" Expression ')' 3880 { 3881 timeUnit := ast.NewValueExpr($3) 3882 $$ = &ast.FuncCallExpr{ 3883 FnName: model.NewCIStr($1), 3884 Args: []ast.ExprNode{timeUnit, $5}, 3885 } 3886 } 3887 | "GET_FORMAT" '(' GetFormatSelector ',' Expression ')' 3888 { 3889 $$ = &ast.FuncCallExpr{ 3890 FnName: model.NewCIStr($1), 3891 Args: []ast.ExprNode{ast.NewValueExpr($3), $5}, 3892 } 3893 } 3894 | builtinPosition '(' BitExpr "IN" Expression ')' 3895 { 3896 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1), Args: []ast.ExprNode{$3, $5}} 3897 } 3898 | builtinSubstring '(' Expression ',' Expression ')' 3899 { 3900 $$ = &ast.FuncCallExpr{ 3901 FnName: model.NewCIStr($1), 3902 Args: []ast.ExprNode{$3, $5}, 3903 } 3904 } 3905 | builtinSubstring '(' Expression "FROM" Expression ')' 3906 { 3907 $$ = &ast.FuncCallExpr{ 3908 FnName: model.NewCIStr($1), 3909 Args: []ast.ExprNode{$3, $5}, 3910 } 3911 } 3912 | builtinSubstring '(' Expression ',' Expression ',' Expression ')' 3913 { 3914 $$ = &ast.FuncCallExpr{ 3915 FnName: model.NewCIStr($1), 3916 Args: []ast.ExprNode{$3, $5, $7}, 3917 } 3918 } 3919 | builtinSubstring '(' Expression "FROM" Expression "FOR" Expression ')' 3920 { 3921 $$ = &ast.FuncCallExpr{ 3922 FnName: model.NewCIStr($1), 3923 Args: []ast.ExprNode{$3, $5, $7}, 3924 } 3925 } 3926 | "TIMESTAMPADD" '(' TimestampUnit ',' Expression ',' Expression ')' 3927 { 3928 $$ = &ast.FuncCallExpr{ 3929 FnName: model.NewCIStr($1), 3930 Args: []ast.ExprNode{ast.NewValueExpr($3), $5, $7}, 3931 } 3932 } 3933 | "TIMESTAMPDIFF" '(' TimestampUnit ',' Expression ',' Expression ')' 3934 { 3935 $$ = &ast.FuncCallExpr{ 3936 FnName: model.NewCIStr($1), 3937 Args: []ast.ExprNode{ast.NewValueExpr($3), $5, $7}, 3938 } 3939 } 3940 | builtinTrim '(' Expression ')' 3941 { 3942 $$ = &ast.FuncCallExpr{ 3943 FnName: model.NewCIStr($1), 3944 Args: []ast.ExprNode{$3}, 3945 } 3946 } 3947 | builtinTrim '(' Expression "FROM" Expression ')' 3948 { 3949 $$ = &ast.FuncCallExpr{ 3950 FnName: model.NewCIStr($1), 3951 Args: []ast.ExprNode{$5, $3}, 3952 } 3953 } 3954 | builtinTrim '(' TrimDirection "FROM" Expression ')' 3955 { 3956 nilVal := ast.NewValueExpr(nil) 3957 direction := ast.NewValueExpr(int($3.(ast.TrimDirectionType))) 3958 $$ = &ast.FuncCallExpr{ 3959 FnName: model.NewCIStr($1), 3960 Args: []ast.ExprNode{$5, nilVal, direction}, 3961 } 3962 } 3963 | builtinTrim '(' TrimDirection Expression "FROM" Expression ')' 3964 { 3965 direction := ast.NewValueExpr(int($3.(ast.TrimDirectionType))) 3966 $$ = &ast.FuncCallExpr{ 3967 FnName: model.NewCIStr($1), 3968 Args: []ast.ExprNode{$6, $4, direction}, 3969 } 3970 } 3971 3972 GetFormatSelector: 3973 "DATE" 3974 { 3975 $$ = strings.ToUpper($1) 3976 } 3977 | "DATETIME" 3978 { 3979 $$ = strings.ToUpper($1) 3980 } 3981 | "TIME" 3982 { 3983 $$ = strings.ToUpper($1) 3984 } 3985 | "TIMESTAMP" 3986 { 3987 $$ = strings.ToUpper($1) 3988 } 3989 3990 3991 FunctionNameDateArith: 3992 builtinDateAdd 3993 | builtinDateSub 3994 3995 3996 FunctionNameDateArithMultiForms: 3997 builtinAddDate 3998 | builtinSubDate 3999 4000 4001 TrimDirection: 4002 "BOTH" 4003 { 4004 $$ = ast.TrimBoth 4005 } 4006 | "LEADING" 4007 { 4008 $$ = ast.TrimLeading 4009 } 4010 | "TRAILING" 4011 { 4012 $$ = ast.TrimTrailing 4013 } 4014 4015 SumExpr: 4016 "AVG" '(' BuggyDefaultFalseDistinctOpt Expression ')' OptWindowingClause 4017 { 4018 if $6 != nil { 4019 $$ = &ast.WindowFuncExpr{F: $1, Args: []ast.ExprNode{$4}, Distinct: $3.(bool), Spec: *($6.(*ast.WindowSpec)),} 4020 } else { 4021 $$ = &ast.AggregateFuncExpr{F: $1, Args: []ast.ExprNode{$4}, Distinct: $3.(bool)} 4022 } 4023 } 4024 | builtinBitAnd '(' Expression ')' OptWindowingClause 4025 { 4026 if $5 != nil { 4027 $$ = &ast.WindowFuncExpr{F: $1, Args: []ast.ExprNode{$3}, Spec: *($5.(*ast.WindowSpec)),} 4028 } else { 4029 $$ = &ast.AggregateFuncExpr{F: $1, Args: []ast.ExprNode{$3},} 4030 } 4031 } 4032 | builtinBitAnd '(' "ALL" Expression ')' OptWindowingClause 4033 { 4034 if $6 != nil { 4035 $$ = &ast.WindowFuncExpr{F: $1, Args: []ast.ExprNode{$4}, Spec: *($6.(*ast.WindowSpec)),} 4036 } else { 4037 $$ = &ast.AggregateFuncExpr{F: $1, Args: []ast.ExprNode{$4},} 4038 } 4039 } 4040 | builtinBitOr '(' Expression ')' OptWindowingClause 4041 { 4042 if $5 != nil { 4043 $$ = &ast.WindowFuncExpr{F: $1, Args: []ast.ExprNode{$3}, Spec: *($5.(*ast.WindowSpec)),} 4044 } else { 4045 $$ = &ast.AggregateFuncExpr{F: $1, Args: []ast.ExprNode{$3},} 4046 } 4047 } 4048 | builtinBitOr '(' "ALL" Expression ')' OptWindowingClause 4049 { 4050 if $6 != nil { 4051 $$ = &ast.WindowFuncExpr{F: $1, Args: []ast.ExprNode{$4}, Spec: *($6.(*ast.WindowSpec)),} 4052 } else { 4053 $$ = &ast.AggregateFuncExpr{F: $1, Args: []ast.ExprNode{$4},} 4054 } 4055 } 4056 | builtinBitXor '(' Expression ')' OptWindowingClause 4057 { 4058 if $5 != nil { 4059 $$ = &ast.WindowFuncExpr{F: $1, Args: []ast.ExprNode{$3}, Spec: *($5.(*ast.WindowSpec)),} 4060 } else { 4061 $$ = &ast.AggregateFuncExpr{F: $1, Args: []ast.ExprNode{$3},} 4062 } 4063 } 4064 | builtinBitXor '(' "ALL" Expression ')' OptWindowingClause 4065 { 4066 if $6 != nil { 4067 $$ = &ast.WindowFuncExpr{F: $1, Args: []ast.ExprNode{$4}, Spec: *($6.(*ast.WindowSpec)),} 4068 } else { 4069 $$ = &ast.AggregateFuncExpr{F: $1, Args: []ast.ExprNode{$4},} 4070 } 4071 } 4072 | builtinCount '(' DistinctKwd ExpressionList ')' 4073 { 4074 $$ = &ast.AggregateFuncExpr{F: $1, Args: $4.([]ast.ExprNode), Distinct: true} 4075 } 4076 | builtinCount '(' "ALL" Expression ')' OptWindowingClause 4077 { 4078 if $6 != nil { 4079 $$ = &ast.WindowFuncExpr{F: $1, Args: []ast.ExprNode{$4}, Spec: *($6.(*ast.WindowSpec)),} 4080 } else { 4081 $$ = &ast.AggregateFuncExpr{F: $1, Args: []ast.ExprNode{$4},} 4082 } 4083 } 4084 | builtinCount '(' Expression ')' OptWindowingClause 4085 { 4086 if $5 != nil { 4087 $$ = &ast.WindowFuncExpr{F: $1, Args: []ast.ExprNode{$3}, Spec: *($5.(*ast.WindowSpec)),} 4088 } else { 4089 $$ = &ast.AggregateFuncExpr{F: $1, Args: []ast.ExprNode{$3},} 4090 } 4091 } 4092 | builtinCount '(' '*' ')' OptWindowingClause 4093 { 4094 args := []ast.ExprNode{ast.NewValueExpr(1)} 4095 if $5 != nil { 4096 $$ = &ast.WindowFuncExpr{F: $1, Args: args, Spec: *($5.(*ast.WindowSpec)),} 4097 } else { 4098 $$ = &ast.AggregateFuncExpr{F: $1, Args: args,} 4099 } 4100 } 4101 | builtinGroupConcat '(' BuggyDefaultFalseDistinctOpt ExpressionList OrderByOptional OptGConcatSeparator ')' 4102 { 4103 args := $4.([]ast.ExprNode) 4104 args = append(args, $6.(ast.ExprNode)) 4105 $$ = &ast.AggregateFuncExpr{F: $1, Args: args, Distinct: $3.(bool)} 4106 } 4107 | builtinMax '(' BuggyDefaultFalseDistinctOpt Expression ')' OptWindowingClause 4108 { 4109 if $6 != nil { 4110 $$ = &ast.WindowFuncExpr{F: $1, Args: []ast.ExprNode{$4}, Distinct: $3.(bool), Spec: *($6.(*ast.WindowSpec)),} 4111 } else { 4112 $$ = &ast.AggregateFuncExpr{F: $1, Args: []ast.ExprNode{$4}, Distinct: $3.(bool)} 4113 } 4114 } 4115 | builtinMin '(' BuggyDefaultFalseDistinctOpt Expression ')' OptWindowingClause 4116 { 4117 if $6 != nil { 4118 $$ = &ast.WindowFuncExpr{F: $1, Args: []ast.ExprNode{$4}, Distinct: $3.(bool), Spec: *($6.(*ast.WindowSpec)),} 4119 } else { 4120 $$ = &ast.AggregateFuncExpr{F: $1, Args: []ast.ExprNode{$4}, Distinct: $3.(bool)} 4121 } 4122 } 4123 | builtinSum '(' BuggyDefaultFalseDistinctOpt Expression ')' OptWindowingClause 4124 { 4125 if $6 != nil { 4126 $$ = &ast.WindowFuncExpr{F: $1, Args: []ast.ExprNode{$4}, Distinct: $3.(bool), Spec: *($6.(*ast.WindowSpec)),} 4127 } else { 4128 $$ = &ast.AggregateFuncExpr{F: $1, Args: []ast.ExprNode{$4}, Distinct: $3.(bool)} 4129 } 4130 } 4131 | builtinStddevPop '(' BuggyDefaultFalseDistinctOpt Expression ')' OptWindowingClause 4132 { 4133 if $6 != nil { 4134 $$ = &ast.WindowFuncExpr{F: $1, Args: []ast.ExprNode{$4}, Distinct: $3.(bool), Spec: *($6.(*ast.WindowSpec)),} 4135 } else { 4136 $$ = &ast.AggregateFuncExpr{F: $1, Args: []ast.ExprNode{$4}, Distinct: $3.(bool)} 4137 } 4138 } 4139 | builtinStddevSamp '(' BuggyDefaultFalseDistinctOpt Expression ')' OptWindowingClause 4140 { 4141 if $6 != nil { 4142 $$ = &ast.WindowFuncExpr{F: $1, Args: []ast.ExprNode{$4}, Distinct: $3.(bool), Spec: *($6.(*ast.WindowSpec)),} 4143 } else { 4144 $$ = &ast.AggregateFuncExpr{F: $1, Args: []ast.ExprNode{$4}, Distinct: $3.(bool)} 4145 } 4146 } 4147 | builtinVarPop '(' BuggyDefaultFalseDistinctOpt Expression ')' OptWindowingClause 4148 { 4149 $$ = &ast.AggregateFuncExpr{F: ast.AggFuncVarPop, Args: []ast.ExprNode{$4}, Distinct: $3.(bool)} 4150 } 4151 | builtinVarSamp '(' BuggyDefaultFalseDistinctOpt Expression ')' OptWindowingClause 4152 { 4153 $$ = &ast.AggregateFuncExpr{F: $1, Args: []ast.ExprNode{$4}, Distinct: $3.(bool)} 4154 } 4155 4156 OptGConcatSeparator: 4157 { 4158 $$ = ast.NewValueExpr(",") 4159 } 4160 | "SEPARATOR" stringLit 4161 { 4162 $$ = ast.NewValueExpr($2) 4163 } 4164 4165 4166 FunctionCallGeneric: 4167 identifier '(' ExpressionListOpt ')' 4168 { 4169 $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1), Args: $3.([]ast.ExprNode)} 4170 } 4171 4172 FuncDatetimePrec: 4173 { 4174 $$ = nil 4175 } 4176 | '(' ')' 4177 { 4178 $$ = nil 4179 } 4180 | '(' intLit ')' 4181 { 4182 expr := ast.NewValueExpr($2) 4183 $$ = expr 4184 } 4185 4186 TimeUnit: 4187 "MICROSECOND" 4188 { 4189 $$ = strings.ToUpper($1) 4190 } 4191 | "SECOND" 4192 { 4193 $$ = strings.ToUpper($1) 4194 } 4195 | "MINUTE" 4196 { 4197 $$ = strings.ToUpper($1) 4198 } 4199 | "HOUR" 4200 { 4201 $$ = strings.ToUpper($1) 4202 } 4203 | "DAY" 4204 { 4205 $$ = strings.ToUpper($1) 4206 } 4207 | "WEEK" 4208 { 4209 $$ = strings.ToUpper($1) 4210 } 4211 | "MONTH" 4212 { 4213 $$ = strings.ToUpper($1) 4214 } 4215 | "QUARTER" 4216 { 4217 $$ = strings.ToUpper($1) 4218 } 4219 | "YEAR" 4220 { 4221 $$ = strings.ToUpper($1) 4222 } 4223 | "SECOND_MICROSECOND" 4224 { 4225 $$ = strings.ToUpper($1) 4226 } 4227 | "MINUTE_MICROSECOND" 4228 { 4229 $$ = strings.ToUpper($1) 4230 } 4231 | "MINUTE_SECOND" 4232 { 4233 $$ = strings.ToUpper($1) 4234 } 4235 | "HOUR_MICROSECOND" 4236 { 4237 $$ = strings.ToUpper($1) 4238 } 4239 | "HOUR_SECOND" 4240 { 4241 $$ = strings.ToUpper($1) 4242 } 4243 | "HOUR_MINUTE" 4244 { 4245 $$ = strings.ToUpper($1) 4246 } 4247 | "DAY_MICROSECOND" 4248 { 4249 $$ = strings.ToUpper($1) 4250 } 4251 | "DAY_SECOND" 4252 { 4253 $$ = strings.ToUpper($1) 4254 } 4255 | "DAY_MINUTE" 4256 { 4257 $$ = strings.ToUpper($1) 4258 } 4259 | "DAY_HOUR" 4260 { 4261 $$ = strings.ToUpper($1) 4262 } 4263 | "YEAR_MONTH" 4264 { 4265 $$ = strings.ToUpper($1) 4266 } 4267 4268 TimestampUnit: 4269 "MICROSECOND" 4270 { 4271 $$ = strings.ToUpper($1) 4272 } 4273 | "SECOND" 4274 { 4275 $$ = strings.ToUpper($1) 4276 } 4277 | "MINUTE" 4278 { 4279 $$ = strings.ToUpper($1) 4280 } 4281 | "HOUR" 4282 { 4283 $$ = strings.ToUpper($1) 4284 } 4285 | "DAY" 4286 { 4287 $$ = strings.ToUpper($1) 4288 } 4289 | "WEEK" 4290 { 4291 $$ = strings.ToUpper($1) 4292 } 4293 | "MONTH" 4294 { 4295 $$ = strings.ToUpper($1) 4296 } 4297 | "QUARTER" 4298 { 4299 $$ = strings.ToUpper($1) 4300 } 4301 | "YEAR" 4302 { 4303 $$ = strings.ToUpper($1) 4304 } 4305 4306 ExpressionOpt: 4307 { 4308 $$ = nil 4309 } 4310 | Expression 4311 { 4312 $$ = $1 4313 } 4314 4315 WhenClauseList: 4316 WhenClause 4317 { 4318 $$ = []*ast.WhenClause{$1.(*ast.WhenClause)} 4319 } 4320 | WhenClauseList WhenClause 4321 { 4322 $$ = append($1.([]*ast.WhenClause), $2.(*ast.WhenClause)) 4323 } 4324 4325 WhenClause: 4326 "WHEN" Expression "THEN" Expression 4327 { 4328 $$ = &ast.WhenClause{ 4329 Expr: $2, 4330 Result: $4, 4331 } 4332 } 4333 4334 ElseOpt: 4335 /* empty */ 4336 { 4337 $$ = nil 4338 } 4339 | "ELSE" Expression 4340 { 4341 $$ = $2 4342 } 4343 4344 CastType: 4345 "BINARY" OptFieldLen 4346 { 4347 x := types.NewFieldType(mysql.TypeVarString) 4348 x.Flen = $2.(int) // TODO: Flen should be the flen of expression 4349 if x.Flen != types.UnspecifiedLength { 4350 x.Tp = mysql.TypeString 4351 } 4352 x.Charset = mysql.CharsetBin 4353 x.Collate = mysql.CollationBin 4354 x.Flag |= mysql.BinaryFlag 4355 $$ = x 4356 } 4357 | "CHAR" OptFieldLen OptBinary 4358 { 4359 x := types.NewFieldType(mysql.TypeVarString) 4360 x.Flen = $2.(int) // TODO: Flen should be the flen of expression 4361 x.Charset = $3.(*ast.OptBinary).Charset 4362 if $3.(*ast.OptBinary).IsBinary{ 4363 x.Flag |= mysql.BinaryFlag 4364 } 4365 if x.Charset == "" { 4366 x.Charset = mysql.DefaultCharset 4367 x.Collate = mysql.DefaultCollationName 4368 } 4369 $$ = x 4370 } 4371 | "DATE" 4372 { 4373 x := types.NewFieldType(mysql.TypeDate) 4374 x.Charset = mysql.CharsetBin 4375 x.Collate = mysql.CollationBin 4376 x.Flag |= mysql.BinaryFlag 4377 $$ = x 4378 } 4379 | "DATETIME" OptFieldLen 4380 { 4381 x := types.NewFieldType(mysql.TypeDatetime) 4382 x.Flen, _ = mysql.GetDefaultFieldLengthAndDecimalForCast(mysql.TypeDatetime) 4383 x.Decimal = $2.(int) 4384 if x.Decimal > 0 { 4385 x.Flen = x.Flen + 1 + x.Decimal 4386 } 4387 x.Charset = mysql.CharsetBin 4388 x.Collate = mysql.CollationBin 4389 x.Flag |= mysql.BinaryFlag 4390 $$ = x 4391 } 4392 | "DECIMAL" FloatOpt 4393 { 4394 fopt := $2.(*ast.FloatOpt) 4395 x := types.NewFieldType(mysql.TypeNewDecimal) 4396 x.Flen = fopt.Flen 4397 x.Decimal = fopt.Decimal 4398 x.Charset = mysql.CharsetBin 4399 x.Collate = mysql.CollationBin 4400 x.Flag |= mysql.BinaryFlag 4401 $$ = x 4402 } 4403 | "TIME" OptFieldLen 4404 { 4405 x := types.NewFieldType(mysql.TypeDuration) 4406 x.Flen, _ = mysql.GetDefaultFieldLengthAndDecimalForCast(mysql.TypeDuration) 4407 x.Decimal = $2.(int) 4408 if x.Decimal > 0 { 4409 x.Flen = x.Flen + 1 + x.Decimal 4410 } 4411 x.Charset = mysql.CharsetBin 4412 x.Collate = mysql.CollationBin 4413 x.Flag |= mysql.BinaryFlag 4414 $$ = x 4415 } 4416 | "SIGNED" OptInteger 4417 { 4418 x := types.NewFieldType(mysql.TypeLonglong) 4419 x.Charset = mysql.CharsetBin 4420 x.Collate = mysql.CollationBin 4421 x.Flag |= mysql.BinaryFlag 4422 $$ = x 4423 } 4424 | "UNSIGNED" OptInteger 4425 { 4426 x := types.NewFieldType(mysql.TypeLonglong) 4427 x.Flag |= mysql.UnsignedFlag | mysql.BinaryFlag 4428 x.Charset = mysql.CharsetBin 4429 x.Collate = mysql.CollationBin 4430 $$ = x 4431 } 4432 | "JSON" 4433 { 4434 x := types.NewFieldType(mysql.TypeJSON) 4435 x.Flag |= mysql.BinaryFlag | (mysql.ParseToJSONFlag) 4436 x.Charset = mysql.DefaultCharset 4437 x.Collate = mysql.DefaultCollationName 4438 $$ = x 4439 } 4440 4441 PriorityOpt: 4442 { 4443 $$ = mysql.NoPriority 4444 } 4445 | "LOW_PRIORITY" 4446 { 4447 $$ = mysql.LowPriority 4448 } 4449 | "HIGH_PRIORITY" 4450 { 4451 $$ = mysql.HighPriority 4452 } 4453 | "DELAYED" 4454 { 4455 $$ = mysql.DelayedPriority 4456 } 4457 4458 TableName: 4459 Identifier 4460 { 4461 $$ = &ast.TableName{Name:model.NewCIStr($1)} 4462 } 4463 | Identifier '.' Identifier 4464 { 4465 $$ = &ast.TableName{Schema:model.NewCIStr($1), Name:model.NewCIStr($3)} 4466 } 4467 | Identifier '.' '*' 4468 { 4469 $$ = &ast.TableName{Name:model.NewCIStr($1)} 4470 } 4471 4472 TableNameList: 4473 TableName 4474 { 4475 tbl := []*ast.TableName{$1.(*ast.TableName)} 4476 $$ = tbl 4477 } 4478 | TableNameList ',' TableName 4479 { 4480 $$ = append($1.([]*ast.TableName), $3.(*ast.TableName)) 4481 } 4482 4483 QuickOptional: 4484 %prec empty 4485 { 4486 $$ = false 4487 } 4488 | "QUICK" 4489 { 4490 $$ = true 4491 } 4492 4493 /***************************Prepared Statement Start****************************** 4494 * See https://dev.mysql.com/doc/refman/5.7/en/prepare.html 4495 * Example: 4496 * PREPARE stmt_name FROM 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse'; 4497 * OR 4498 * SET @s = 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse'; 4499 * PREPARE stmt_name FROM @s; 4500 */ 4501 4502 PreparedStmt: 4503 "PREPARE" Identifier "FROM" PrepareSQL 4504 { 4505 var sqlText string 4506 var sqlVar *ast.VariableExpr 4507 switch $4.(type) { 4508 case string: 4509 sqlText = $4.(string) 4510 case *ast.VariableExpr: 4511 sqlVar = $4.(*ast.VariableExpr) 4512 } 4513 $$ = &ast.PrepareStmt{ 4514 Name: $2, 4515 SQLText: sqlText, 4516 SQLVar: sqlVar, 4517 } 4518 } 4519 4520 PrepareSQL: 4521 stringLit 4522 { 4523 $$ = $1 4524 } 4525 | UserVariable 4526 { 4527 $$ = $1.(interface{}) 4528 } 4529 4530 4531 /* 4532 * See https://dev.mysql.com/doc/refman/5.7/en/execute.html 4533 * Example: 4534 * EXECUTE stmt1 USING @a, @b; 4535 * OR 4536 * EXECUTE stmt1; 4537 */ 4538 ExecuteStmt: 4539 "EXECUTE" Identifier 4540 { 4541 $$ = &ast.ExecuteStmt{Name: $2} 4542 } 4543 | "EXECUTE" Identifier "USING" UserVariableList 4544 { 4545 $$ = &ast.ExecuteStmt{ 4546 Name: $2, 4547 UsingVars: $4.([]ast.ExprNode), 4548 } 4549 } 4550 4551 UserVariableList: 4552 UserVariable 4553 { 4554 $$ = []ast.ExprNode{$1} 4555 } 4556 | UserVariableList ',' UserVariable 4557 { 4558 $$ = append($1.([]ast.ExprNode), $3) 4559 } 4560 4561 /* 4562 * See https://dev.mysql.com/doc/refman/5.0/en/deallocate-prepare.html 4563 */ 4564 4565 DeallocateStmt: 4566 DeallocateSym "PREPARE" Identifier 4567 { 4568 $$ = &ast.DeallocateStmt{Name: $3} 4569 } 4570 4571 DeallocateSym: 4572 "DEALLOCATE" | "DROP" 4573 4574 /****************************Prepared Statement End*******************************/ 4575 4576 RollbackStmt: 4577 "ROLLBACK" 4578 { 4579 $$ = &ast.RollbackStmt{} 4580 } 4581 | "ROLLBACK" CommitOpt 4582 { 4583 $$ = &ast.RollbackStmt{} 4584 } 4585 | "ROLLBACK" "WORK" "TO" "SAVEPOINT" StringName 4586 { 4587 $$ = &ast.RollbackStmt{Savepoint: $5.(string)} 4588 } 4589 | "ROLLBACK" "WORK" "TO" StringName 4590 { 4591 $$ = &ast.RollbackStmt{Savepoint: $4.(string)} 4592 } 4593 | "ROLLBACK" "TO" "SAVEPOINT" StringName 4594 { 4595 $$ = &ast.RollbackStmt{Savepoint: $4.(string)} 4596 } 4597 | "ROLLBACK" "TO" StringName 4598 { 4599 $$ = &ast.RollbackStmt{Savepoint: $3.(string)} 4600 } 4601 4602 SavepointStmt: 4603 "SAVEPOINT" StringName 4604 { 4605 $$ = &ast.SavepointStmt{Savepoint : $2.(string)} 4606 } 4607 | "RELEASE" "SAVEPOINT" StringName 4608 { 4609 $$ = &ast.SavepointStmt{Savepoint : $3.(string), Release: true} 4610 } 4611 4612 SelectStmtBasic: 4613 "SELECT" SelectStmtOpts SelectStmtFieldList 4614 { 4615 st := &ast.SelectStmt { 4616 SelectStmtOpts: $2.(*ast.SelectStmtOpts), 4617 Distinct: $2.(*ast.SelectStmtOpts).Distinct, 4618 Fields: $3.(*ast.FieldList), 4619 } 4620 $$ = st 4621 } 4622 4623 SelectStmtFromDualTable: 4624 SelectStmtBasic FromDual WhereClauseOptional 4625 { 4626 st := $1.(*ast.SelectStmt) 4627 lastField := st.Fields.Fields[len(st.Fields.Fields)-1] 4628 if lastField.Expr != nil && lastField.AsName.O == "" { 4629 lastEnd := yyS[yypt-1].offset-1 4630 lastField.SetText(parser.src[lastField.Offset:lastEnd]) 4631 } 4632 if $3 != nil { 4633 st.Where = $3.(ast.ExprNode) 4634 } 4635 } 4636 4637 SelectStmtFromTable: 4638 SelectStmtBasic "FROM" 4639 TableRefsClause WhereClauseOptional SelectStmtGroup HavingClause WindowClauseOptional 4640 { 4641 st := $1.(*ast.SelectStmt) 4642 st.From = $3.(*ast.TableRefsClause) 4643 if st.SelectStmtOpts.TableHints != nil { 4644 st.TableHints = st.SelectStmtOpts.TableHints 4645 } 4646 lastField := st.Fields.Fields[len(st.Fields.Fields)-1] 4647 if lastField.Expr != nil && lastField.AsName.O == "" { 4648 lastEnd := parser.endOffset(&yyS[yypt-5]) 4649 lastField.SetText(parser.src[lastField.Offset:lastEnd]) 4650 } 4651 if $4 != nil { 4652 st.Where = $4.(ast.ExprNode) 4653 } 4654 if $5 != nil { 4655 st.GroupBy = $5.(*ast.GroupByClause) 4656 } 4657 if $6 != nil { 4658 st.Having = $6.(*ast.HavingClause) 4659 } 4660 if $7 != nil { 4661 st.WindowSpecs = ($7.([]ast.WindowSpec)) 4662 } 4663 $$ = st 4664 } 4665 4666 SelectStmt: 4667 SelectStmtBasic OrderByOptional SelectStmtLimit SelectLockOpt 4668 { 4669 st := $1.(*ast.SelectStmt) 4670 st.LockTp = $4.(ast.SelectLockType) 4671 lastField := st.Fields.Fields[len(st.Fields.Fields)-1] 4672 if lastField.Expr != nil && lastField.AsName.O == "" { 4673 src := parser.src 4674 var lastEnd int 4675 if $2 != nil { 4676 lastEnd = yyS[yypt-2].offset-1 4677 } else if $3 != nil { 4678 lastEnd = yyS[yypt-1].offset-1 4679 } else if $4 != ast.SelectLockNone { 4680 lastEnd = yyS[yypt].offset-1 4681 } else { 4682 lastEnd = len(src) 4683 if src[lastEnd-1] == ';' { 4684 lastEnd-- 4685 } 4686 } 4687 lastField.SetText(src[lastField.Offset:lastEnd]) 4688 } 4689 if $2 != nil { 4690 st.OrderBy = $2.(*ast.OrderByClause) 4691 } 4692 if $3 != nil { 4693 st.Limit = $3.(*ast.Limit) 4694 } 4695 $$ = st 4696 } 4697 | SelectStmtFromDualTable OrderByOptional SelectStmtLimit SelectLockOpt 4698 { 4699 st := $1.(*ast.SelectStmt) 4700 if $2 != nil { 4701 st.OrderBy = $2.(*ast.OrderByClause) 4702 } 4703 if $3 != nil { 4704 st.Limit = $3.(*ast.Limit) 4705 } 4706 st.LockTp = $4.(ast.SelectLockType) 4707 $$ = st 4708 } 4709 | SelectStmtFromTable OrderByOptional SelectStmtLimit SelectLockOpt 4710 { 4711 st := $1.(*ast.SelectStmt) 4712 st.LockTp = $4.(ast.SelectLockType) 4713 if $2 != nil { 4714 st.OrderBy = $2.(*ast.OrderByClause) 4715 } 4716 if $3 != nil { 4717 st.Limit = $3.(*ast.Limit) 4718 } 4719 $$ = st 4720 } 4721 4722 FromDual: 4723 "FROM" "DUAL" 4724 4725 WindowClauseOptional: 4726 { 4727 $$ = nil 4728 } 4729 | "WINDOW" WindowDefinitionList 4730 { 4731 $$ = $2.([]ast.WindowSpec) 4732 } 4733 4734 WindowDefinitionList: 4735 WindowDefinition 4736 { 4737 $$ = []ast.WindowSpec{$1.(ast.WindowSpec)} 4738 } 4739 | WindowDefinitionList ',' WindowDefinition 4740 { 4741 $$ = append($1.([]ast.WindowSpec), $3.(ast.WindowSpec)) 4742 } 4743 4744 WindowDefinition: 4745 WindowName "AS" WindowSpec 4746 { 4747 var spec = $3.(ast.WindowSpec) 4748 spec.Name = $1.(model.CIStr) 4749 $$ = spec 4750 } 4751 4752 WindowName: 4753 Identifier 4754 { 4755 $$ = model.NewCIStr($1) 4756 } 4757 4758 WindowSpec: 4759 '(' WindowSpecDetails ')' 4760 { 4761 $$ = $2.(ast.WindowSpec) 4762 } 4763 4764 WindowSpecDetails: 4765 OptExistingWindowName OptPartitionClause OptWindowOrderByClause OptWindowFrameClause 4766 { 4767 spec := ast.WindowSpec{Ref: $1.(model.CIStr),} 4768 if $2 != nil { 4769 spec.PartitionBy = $2.(*ast.PartitionByClause) 4770 } 4771 if $3 != nil { 4772 spec.OrderBy = $3.(*ast.OrderByClause) 4773 } 4774 if $4 != nil { 4775 spec.Frame = $4.(*ast.FrameClause) 4776 } 4777 $$ = spec 4778 } 4779 4780 OptExistingWindowName: 4781 { 4782 $$ = model.CIStr{} 4783 } 4784 | WindowName 4785 { 4786 $$ = $1.(model.CIStr) 4787 } 4788 4789 OptPartitionClause: 4790 { 4791 $$ = nil 4792 } 4793 | "PARTITION" "BY" ByList 4794 { 4795 $$ = &ast.PartitionByClause{Items: $3.([]*ast.ByItem)} 4796 } 4797 4798 OptWindowOrderByClause: 4799 { 4800 $$ = nil 4801 } 4802 | "ORDER" "BY" ByList 4803 { 4804 $$ = &ast.OrderByClause{Items: $3.([]*ast.ByItem)} 4805 } 4806 4807 OptWindowFrameClause: 4808 { 4809 $$ = nil 4810 } 4811 | WindowFrameUnits WindowFrameExtent 4812 { 4813 $$ = &ast.FrameClause{ 4814 Type: $1.(ast.FrameType), 4815 Extent: $2.(ast.FrameExtent), 4816 } 4817 } 4818 4819 WindowFrameUnits: 4820 "ROWS" 4821 { 4822 $$ = ast.FrameType(ast.Rows) 4823 } 4824 | "RANGE" 4825 { 4826 $$ = ast.FrameType(ast.Ranges) 4827 } 4828 | "GROUPS" 4829 { 4830 $$ = ast.FrameType(ast.Groups) 4831 } 4832 4833 WindowFrameExtent: 4834 WindowFrameStart 4835 { 4836 $$ = ast.FrameExtent { 4837 Start: $1.(ast.FrameBound), 4838 End: ast.FrameBound{Type: ast.CurrentRow,}, 4839 } 4840 } 4841 | WindowFrameBetween 4842 { 4843 $$ = $1.(ast.FrameExtent) 4844 } 4845 4846 WindowFrameStart: 4847 "UNBOUNDED" "PRECEDING" 4848 { 4849 $$ = ast.FrameBound{Type: ast.Preceding, UnBounded: true,} 4850 } 4851 | NumLiteral "PRECEDING" 4852 { 4853 $$ = ast.FrameBound{Type: ast.Preceding, Expr: ast.NewValueExpr($1),} 4854 } 4855 | paramMarker "PRECEDING" 4856 { 4857 $$ = ast.FrameBound{Type: ast.Preceding, Expr: ast.NewParamMarkerExpr(yyS[yypt].offset),} 4858 } 4859 | "INTERVAL" Expression TimeUnit "PRECEDING" 4860 { 4861 $$ = ast.FrameBound{Type: ast.Preceding, Expr: $2, Unit: ast.NewValueExpr($3),} 4862 } 4863 | "CURRENT" "ROW" 4864 { 4865 $$ = ast.FrameBound{Type: ast.CurrentRow,} 4866 } 4867 4868 WindowFrameBetween: 4869 "BETWEEN" WindowFrameBound "AND" WindowFrameBound 4870 { 4871 $$ = ast.FrameExtent{Start: $2.(ast.FrameBound), End: $4.(ast.FrameBound),} 4872 } 4873 4874 WindowFrameBound: 4875 WindowFrameStart 4876 { 4877 $$ = $1.(ast.FrameBound) 4878 } 4879 | "UNBOUNDED" "FOLLOWING" 4880 { 4881 $$ = ast.FrameBound{Type: ast.Following, UnBounded: true,} 4882 } 4883 | NumLiteral "FOLLOWING" 4884 { 4885 $$ = ast.FrameBound{Type: ast.Following, Expr: ast.NewValueExpr($1),} 4886 } 4887 | paramMarker "FOLLOWING" 4888 { 4889 $$ = ast.FrameBound{Type: ast.Following, Expr: ast.NewParamMarkerExpr(yyS[yypt].offset),} 4890 } 4891 | "INTERVAL" Expression TimeUnit "FOLLOWING" 4892 { 4893 $$ = ast.FrameBound{Type: ast.Following, Expr: $2, Unit: ast.NewValueExpr($3),} 4894 } 4895 4896 OptWindowingClause: 4897 { 4898 $$ = nil 4899 } 4900 | WindowingClause 4901 { 4902 spec := $1.(ast.WindowSpec) 4903 $$ = &spec 4904 } 4905 4906 WindowingClause: 4907 "OVER" WindowNameOrSpec 4908 { 4909 $$ = $2.(ast.WindowSpec) 4910 } 4911 4912 WindowNameOrSpec: 4913 WindowName 4914 { 4915 $$ = ast.WindowSpec{Ref: $1.(model.CIStr)} 4916 } 4917 | WindowSpec 4918 { 4919 $$ = $1.(ast.WindowSpec) 4920 } 4921 4922 WindowFuncCall: 4923 "ROW_NUMBER" '(' ')' WindowingClause 4924 { 4925 $$ = &ast.WindowFuncExpr{F: $1, Spec: $4.(ast.WindowSpec),} 4926 } 4927 | "RANK" '(' ')' WindowingClause 4928 { 4929 $$ = &ast.WindowFuncExpr{F: $1, Spec: $4.(ast.WindowSpec),} 4930 } 4931 | "DENSE_RANK" '(' ')' WindowingClause 4932 { 4933 $$ = &ast.WindowFuncExpr{F: $1, Spec: $4.(ast.WindowSpec),} 4934 } 4935 | "CUME_DIST" '(' ')' WindowingClause 4936 { 4937 $$ = &ast.WindowFuncExpr{F: $1, Spec: $4.(ast.WindowSpec),} 4938 } 4939 | "PERCENT_RANK" '(' ')' WindowingClause 4940 { 4941 $$ = &ast.WindowFuncExpr{F: $1, Spec: $4.(ast.WindowSpec),} 4942 } 4943 | "NTILE" '(' SimpleExpr ')' WindowingClause 4944 { 4945 $$ = &ast.WindowFuncExpr{F: $1, Args: []ast.ExprNode{$3}, Spec: $5.(ast.WindowSpec),} 4946 } 4947 | "LEAD" '(' Expression OptLeadLagInfo ')' OptNullTreatment WindowingClause 4948 { 4949 args := []ast.ExprNode{$3} 4950 if $4 != nil { 4951 args = append(args, $4.([]ast.ExprNode)...) 4952 } 4953 $$ = &ast.WindowFuncExpr{F: $1, Args: args, IgnoreNull: $6.(bool), Spec: $7.(ast.WindowSpec),} 4954 } 4955 | "LAG" '(' Expression OptLeadLagInfo ')' OptNullTreatment WindowingClause 4956 { 4957 args := []ast.ExprNode{$3} 4958 if $4 != nil { 4959 args = append(args, $4.([]ast.ExprNode)...) 4960 } 4961 $$ = &ast.WindowFuncExpr{F: $1, Args: args, IgnoreNull: $6.(bool), Spec: $7.(ast.WindowSpec),} 4962 } 4963 | "FIRST_VALUE" '(' Expression ')' OptNullTreatment WindowingClause 4964 { 4965 $$ = &ast.WindowFuncExpr{F: $1, Args: []ast.ExprNode{$3}, IgnoreNull: $5.(bool), Spec: $6.(ast.WindowSpec),} 4966 } 4967 | "LAST_VALUE" '(' Expression ')' OptNullTreatment WindowingClause 4968 { 4969 $$ = &ast.WindowFuncExpr{F: $1, Args: []ast.ExprNode{$3}, IgnoreNull: $5.(bool), Spec: $6.(ast.WindowSpec),} 4970 } 4971 | "NTH_VALUE" '(' Expression ',' SimpleExpr ')' OptFromFirstLast OptNullTreatment WindowingClause 4972 { 4973 $$ = &ast.WindowFuncExpr{F: $1, Args: []ast.ExprNode{$3, $5}, FromLast: $7.(bool), IgnoreNull: $8.(bool), Spec: $9.(ast.WindowSpec),} 4974 } 4975 4976 OptLeadLagInfo: 4977 { 4978 $$ = nil 4979 } 4980 | ',' NumLiteral OptLLDefault 4981 { 4982 args := []ast.ExprNode{ast.NewValueExpr($2)} 4983 if $3 != nil { 4984 args = append(args, $3.(ast.ExprNode)) 4985 } 4986 $$ = args 4987 } 4988 | ',' paramMarker OptLLDefault 4989 { 4990 args := []ast.ExprNode{ast.NewValueExpr($2)} 4991 if $3 != nil { 4992 args = append(args, $3.(ast.ExprNode)) 4993 } 4994 $$ = args 4995 } 4996 4997 OptLLDefault: 4998 { 4999 $$ = nil 5000 } 5001 | ',' Expression 5002 { 5003 $$ = $2 5004 } 5005 5006 OptNullTreatment: 5007 { 5008 $$ = false 5009 } 5010 | "RESPECT" "NULLS" 5011 { 5012 $$ = false 5013 } 5014 | "IGNORE" "NULLS" 5015 { 5016 $$ = true 5017 } 5018 5019 OptFromFirstLast: 5020 { 5021 $$ = false 5022 } 5023 | "FROM" "FIRST" 5024 { 5025 $$ = false 5026 } 5027 | "FROM" "LAST" 5028 { 5029 $$ = true 5030 } 5031 5032 TableRefsClause: 5033 TableRefs 5034 { 5035 $$ = &ast.TableRefsClause{TableRefs: $1.(*ast.Join)} 5036 } 5037 5038 TableRefs: 5039 EscapedTableRef 5040 { 5041 if j, ok := $1.(*ast.Join); ok { 5042 // if $1 is Join, use it directly 5043 $$ = j 5044 } else { 5045 $$ = &ast.Join{Left: $1.(ast.ResultSetNode), Right: nil} 5046 } 5047 } 5048 | TableRefs ',' EscapedTableRef 5049 { 5050 /* from a, b is default cross join */ 5051 $$ = &ast.Join{Left: $1.(ast.ResultSetNode), Right: $3.(ast.ResultSetNode), Tp: ast.CrossJoin} 5052 } 5053 5054 EscapedTableRef: 5055 TableRef %prec lowerThanSetKeyword 5056 { 5057 $$ = $1 5058 } 5059 | '{' Identifier TableRef '}' 5060 { 5061 /* 5062 * ODBC escape syntax for outer join is { OJ join_table } 5063 * Use an Identifier for OJ 5064 */ 5065 $$ = $3 5066 } 5067 5068 TableRef: 5069 TableFactor 5070 { 5071 $$ = $1 5072 } 5073 | JoinTable 5074 { 5075 $$ = $1 5076 } 5077 5078 TableFactor: 5079 TableName PartitionNameListOpt TableAsNameOpt IndexHintListOpt 5080 { 5081 tn := $1.(*ast.TableName) 5082 tn.PartitionNames = $2.([]model.CIStr) 5083 tn.IndexHints = $4.([]*ast.IndexHint) 5084 $$ = &ast.TableSource{Source: tn, AsName: $3.(model.CIStr)} 5085 } 5086 | '(' SelectStmt ')' TableAsName 5087 { 5088 st := $2.(*ast.SelectStmt) 5089 endOffset := parser.endOffset(&yyS[yypt-1]) 5090 parser.setLastSelectFieldText(st, endOffset) 5091 $$ = &ast.TableSource{Source: $2.(*ast.SelectStmt), AsName: $4.(model.CIStr)} 5092 } 5093 | '(' UnionStmt ')' TableAsName 5094 { 5095 $$ = &ast.TableSource{Source: $2.(*ast.UnionStmt), AsName: $4.(model.CIStr)} 5096 } 5097 | '(' TableRefs ')' 5098 { 5099 $$ = $2 5100 } 5101 5102 PartitionNameListOpt: 5103 /* empty */ 5104 { 5105 $$ = []model.CIStr{} 5106 } 5107 | "PARTITION" '(' PartitionNameList ')' 5108 { 5109 $$ = $3 5110 } 5111 5112 TableAsNameOpt: 5113 { 5114 $$ = model.CIStr{} 5115 } 5116 | TableAsName 5117 { 5118 $$ = $1 5119 } 5120 5121 TableAsName: 5122 Identifier 5123 { 5124 $$ = model.NewCIStr($1) 5125 } 5126 | "AS" Identifier 5127 { 5128 $$ = model.NewCIStr($2) 5129 } 5130 5131 IndexHintType: 5132 "USE" KeyOrIndex 5133 { 5134 $$ = ast.HintUse 5135 } 5136 | "IGNORE" KeyOrIndex 5137 { 5138 $$ = ast.HintIgnore 5139 } 5140 | "FORCE" KeyOrIndex 5141 { 5142 $$ = ast.HintForce 5143 } 5144 5145 IndexHintScope: 5146 { 5147 $$ = ast.HintForScan 5148 } 5149 | "FOR" "JOIN" 5150 { 5151 $$ = ast.HintForJoin 5152 } 5153 | "FOR" "ORDER" "BY" 5154 { 5155 $$ = ast.HintForOrderBy 5156 } 5157 | "FOR" "GROUP" "BY" 5158 { 5159 $$ = ast.HintForGroupBy 5160 } 5161 5162 5163 IndexHint: 5164 IndexHintType IndexHintScope '(' IndexNameList ')' 5165 { 5166 $$ = &ast.IndexHint{ 5167 IndexNames: $4.([]model.CIStr), 5168 HintType: $1.(ast.IndexHintType), 5169 HintScope: $2.(ast.IndexHintScope), 5170 } 5171 } 5172 5173 IndexNameList: 5174 { 5175 var nameList []model.CIStr 5176 $$ = nameList 5177 } 5178 | Identifier 5179 { 5180 $$ = []model.CIStr{model.NewCIStr($1)} 5181 } 5182 | IndexNameList ',' Identifier 5183 { 5184 $$ = append($1.([]model.CIStr), model.NewCIStr($3)) 5185 } 5186 | "PRIMARY" 5187 { 5188 $$ = []model.CIStr{model.NewCIStr($1)} 5189 } 5190 5191 IndexHintList: 5192 IndexHint 5193 { 5194 $$ = []*ast.IndexHint{$1.(*ast.IndexHint)} 5195 } 5196 | IndexHintList IndexHint 5197 { 5198 $$ = append($1.([]*ast.IndexHint), $2.(*ast.IndexHint)) 5199 } 5200 5201 IndexHintListOpt: 5202 { 5203 var hintList []*ast.IndexHint 5204 $$ = hintList 5205 } 5206 | IndexHintList 5207 { 5208 $$ = $1 5209 } 5210 5211 JoinTable: 5212 /* Use %prec to evaluate production TableRef before cross join */ 5213 TableRef CrossOpt TableRef %prec tableRefPriority 5214 { 5215 $$ = &ast.Join{Left: $1.(ast.ResultSetNode), Right: $3.(ast.ResultSetNode), Tp: ast.CrossJoin} 5216 } 5217 | TableRef CrossOpt TableRef "ON" Expression 5218 { 5219 on := &ast.OnCondition{Expr: $5} 5220 $$ = &ast.Join{Left: $1.(ast.ResultSetNode), Right: $3.(ast.ResultSetNode), Tp: ast.CrossJoin, On: on} 5221 } 5222 | TableRef CrossOpt TableRef "USING" '(' ColumnNameList ')' 5223 { 5224 $$ = &ast.Join{Left: $1.(ast.ResultSetNode), Right: $3.(ast.ResultSetNode), Tp: ast.CrossJoin, Using: $6.([]*ast.ColumnName)} 5225 } 5226 | TableRef JoinType OuterOpt "JOIN" TableRef "ON" Expression 5227 { 5228 on := &ast.OnCondition{Expr: $7} 5229 $$ = &ast.Join{Left: $1.(ast.ResultSetNode), Right: $5.(ast.ResultSetNode), Tp: $2.(ast.JoinType), On: on} 5230 } 5231 | TableRef JoinType OuterOpt "JOIN" TableRef "USING" '(' ColumnNameList ')' 5232 { 5233 $$ = &ast.Join{Left: $1.(ast.ResultSetNode), Right: $5.(ast.ResultSetNode), Tp: $2.(ast.JoinType), Using: $8.([]*ast.ColumnName)} 5234 } 5235 | TableRef "NATURAL" "JOIN" TableRef 5236 { 5237 $$ = &ast.Join{Left: $1.(ast.ResultSetNode), Right: $4.(ast.ResultSetNode), NaturalJoin: true} 5238 } 5239 | TableRef "NATURAL" JoinType OuterOpt "JOIN" TableRef 5240 { 5241 $$ = &ast.Join{Left: $1.(ast.ResultSetNode), Right: $6.(ast.ResultSetNode), Tp: $3.(ast.JoinType), NaturalJoin: true} 5242 } 5243 | TableRef "STRAIGHT_JOIN" TableRef 5244 { 5245 $$ = &ast.Join{Left: $1.(ast.ResultSetNode), Right: $3.(ast.ResultSetNode), StraightJoin: true} 5246 } 5247 | TableRef "STRAIGHT_JOIN" TableRef "ON" Expression 5248 { 5249 on := &ast.OnCondition{Expr: $5} 5250 $$ = &ast.Join{Left: $1.(ast.ResultSetNode), Right: $3.(ast.ResultSetNode), StraightJoin: true, On: on} 5251 } 5252 5253 JoinType: 5254 "LEFT" 5255 { 5256 $$ = ast.LeftJoin 5257 } 5258 | "RIGHT" 5259 { 5260 $$ = ast.RightJoin 5261 } 5262 5263 OuterOpt: 5264 {} 5265 | "OUTER" 5266 5267 CrossOpt: 5268 "JOIN" 5269 | "CROSS" "JOIN" 5270 | "INNER" "JOIN" 5271 5272 5273 LimitClause: 5274 { 5275 $$ = nil 5276 } 5277 | "LIMIT" LimitOption 5278 { 5279 $$ = &ast.Limit{Count: $2.(ast.ValueExpr)} 5280 } 5281 5282 LimitOption: 5283 LengthNum 5284 { 5285 $$ = ast.NewValueExpr($1) 5286 } 5287 | paramMarker 5288 { 5289 $$ = ast.NewParamMarkerExpr(yyS[yypt].offset) 5290 } 5291 5292 SelectStmtLimit: 5293 { 5294 $$ = nil 5295 } 5296 | "LIMIT" LimitOption 5297 { 5298 $$ = &ast.Limit{Count: $2.(ast.ExprNode)} 5299 } 5300 | "LIMIT" LimitOption ',' LimitOption 5301 { 5302 $$ = &ast.Limit{Offset: $2.(ast.ExprNode), Count: $4.(ast.ExprNode)} 5303 } 5304 | "LIMIT" LimitOption "OFFSET" LimitOption 5305 { 5306 $$ = &ast.Limit{Offset: $4.(ast.ExprNode), Count: $2.(ast.ExprNode)} 5307 } 5308 5309 5310 SelectStmtOpts: 5311 TableOptimizerHints DefaultFalseDistinctOpt PriorityOpt SelectStmtSQLCache SelectStmtCalcFoundRows SelectStmtStraightJoin 5312 { 5313 opt := &ast.SelectStmtOpts{} 5314 if $1 != nil { 5315 opt.TableHints = $1.([]*ast.TableOptimizerHint) 5316 } 5317 if $2 != nil { 5318 opt.Distinct = $2.(bool) 5319 } 5320 if $3 != nil { 5321 opt.Priority = $3.(mysql.PriorityEnum) 5322 } 5323 if $4 != nil { 5324 opt.SQLCache = $4.(bool) 5325 } 5326 if $5 != nil { 5327 opt.CalcFoundRows = $5.(bool) 5328 } 5329 if $6 != nil { 5330 opt.StraightJoin = $6.(bool) 5331 } 5332 5333 $$ = opt 5334 } 5335 5336 TableOptimizerHints: 5337 /* empty */ 5338 { 5339 $$ = nil 5340 } 5341 | hintBegin TableOptimizerHintList hintEnd 5342 { 5343 $$ = $2 5344 } 5345 | hintBegin error hintEnd 5346 { 5347 yyerrok() 5348 parser.lastErrorAsWarn() 5349 $$ = nil 5350 } 5351 5352 HintTableList: 5353 Identifier 5354 { 5355 $$ = []model.CIStr{model.NewCIStr($1)} 5356 } 5357 | HintTableList ',' Identifier 5358 { 5359 $$ = append($1.([]model.CIStr), model.NewCIStr($3)) 5360 } 5361 5362 TableOptimizerHintList: 5363 TableOptimizerHintOpt 5364 { 5365 $$ = []*ast.TableOptimizerHint{$1.(*ast.TableOptimizerHint)} 5366 } 5367 | TableOptimizerHintList TableOptimizerHintOpt 5368 { 5369 $$ = append($1.([]*ast.TableOptimizerHint), $2.(*ast.TableOptimizerHint)) 5370 } 5371 5372 TableOptimizerHintOpt: 5373 tidbSMJ '(' HintTableList ')' 5374 { 5375 $$ = &ast.TableOptimizerHint{HintName: model.NewCIStr($1), Tables: $3.([]model.CIStr)} 5376 } 5377 | tidbINLJ '(' HintTableList ')' 5378 { 5379 $$ = &ast.TableOptimizerHint{HintName: model.NewCIStr($1), Tables: $3.([]model.CIStr)} 5380 } 5381 | tidbHJ '(' HintTableList ')' 5382 { 5383 $$ = &ast.TableOptimizerHint{HintName: model.NewCIStr($1), Tables: $3.([]model.CIStr)} 5384 } 5385 | maxExecutionTime '(' NUM ')' 5386 { 5387 $$ = &ast.TableOptimizerHint{HintName: model.NewCIStr($1), MaxExecutionTime: getUint64FromNUM($3)} 5388 } 5389 5390 SelectStmtCalcFoundRows: 5391 { 5392 $$ = false 5393 } 5394 | "SQL_CALC_FOUND_ROWS" 5395 { 5396 $$ = true 5397 } 5398 SelectStmtSQLCache: 5399 %prec empty 5400 { 5401 $$ = true 5402 } 5403 | "SQL_CACHE" 5404 { 5405 $$ = true 5406 } 5407 | "SQL_NO_CACHE" 5408 { 5409 $$ = false 5410 } 5411 SelectStmtStraightJoin: 5412 %prec empty 5413 { 5414 $$ = false 5415 } 5416 | "STRAIGHT_JOIN" 5417 { 5418 $$ = true 5419 } 5420 5421 SelectStmtFieldList: 5422 FieldList 5423 { 5424 $$ = &ast.FieldList{Fields: $1.([]*ast.SelectField)} 5425 } 5426 5427 SelectStmtGroup: 5428 /* EMPTY */ 5429 { 5430 $$ = nil 5431 } 5432 | GroupByClause 5433 5434 // See https://dev.mysql.com/doc/refman/5.7/en/subqueries.html 5435 SubSelect: 5436 '(' SelectStmt ')' 5437 { 5438 s := $2.(*ast.SelectStmt) 5439 endOffset := parser.endOffset(&yyS[yypt]) 5440 parser.setLastSelectFieldText(s, endOffset) 5441 src := parser.src 5442 // See the implementation of yyParse function 5443 s.SetText(src[yyS[yypt-1].offset:yyS[yypt].offset]) 5444 $$ = &ast.SubqueryExpr{Query: s} 5445 } 5446 | '(' UnionStmt ')' 5447 { 5448 s := $2.(*ast.UnionStmt) 5449 src := parser.src 5450 // See the implementation of yyParse function 5451 s.SetText(src[yyS[yypt-1].offset:yyS[yypt].offset]) 5452 $$ = &ast.SubqueryExpr{Query: s} 5453 } 5454 5455 // See https://dev.mysql.com/doc/refman/5.7/en/innodb-locking-reads.html 5456 SelectLockOpt: 5457 /* empty */ 5458 { 5459 $$ = ast.SelectLockNone 5460 } 5461 | "FOR" "UPDATE" 5462 { 5463 $$ = ast.SelectLockForUpdate 5464 } 5465 | "LOCK" "IN" "SHARE" "MODE" 5466 { 5467 $$ = ast.SelectLockInShareMode 5468 } 5469 5470 // See https://dev.mysql.com/doc/refman/5.7/en/union.html 5471 UnionStmt: 5472 UnionClauseList "UNION" UnionOpt SelectStmtBasic OrderByOptional SelectStmtLimit SelectLockOpt 5473 { 5474 st := $4.(*ast.SelectStmt) 5475 union := $1.(*ast.UnionStmt) 5476 st.IsAfterUnionDistinct = $3.(bool) 5477 lastSelect := union.SelectList.Selects[len(union.SelectList.Selects)-1] 5478 endOffset := parser.endOffset(&yyS[yypt-5]) 5479 parser.setLastSelectFieldText(lastSelect, endOffset) 5480 union.SelectList.Selects = append(union.SelectList.Selects, st) 5481 if $5 != nil { 5482 union.OrderBy = $5.(*ast.OrderByClause) 5483 } 5484 if $6 != nil { 5485 union.Limit = $6.(*ast.Limit) 5486 } 5487 if $5 == nil && $6 == nil { 5488 st.LockTp = $7.(ast.SelectLockType) 5489 } 5490 $$ = union 5491 } 5492 | UnionClauseList "UNION" UnionOpt SelectStmtFromDualTable OrderByOptional 5493 SelectStmtLimit SelectLockOpt 5494 { 5495 st := $4.(*ast.SelectStmt) 5496 union := $1.(*ast.UnionStmt) 5497 st.IsAfterUnionDistinct = $3.(bool) 5498 lastSelect := union.SelectList.Selects[len(union.SelectList.Selects)-1] 5499 endOffset := parser.endOffset(&yyS[yypt-5]) 5500 parser.setLastSelectFieldText(lastSelect, endOffset) 5501 union.SelectList.Selects = append(union.SelectList.Selects, st) 5502 if $5 != nil { 5503 union.OrderBy = $5.(*ast.OrderByClause) 5504 } 5505 if $6 != nil { 5506 union.Limit = $6.(*ast.Limit) 5507 } 5508 if $5 == nil && $6 == nil { 5509 st.LockTp = $7.(ast.SelectLockType) 5510 } 5511 $$ = union 5512 } 5513 | UnionClauseList "UNION" UnionOpt SelectStmtFromTable OrderByOptional 5514 SelectStmtLimit SelectLockOpt 5515 { 5516 st := $4.(*ast.SelectStmt) 5517 union := $1.(*ast.UnionStmt) 5518 st.IsAfterUnionDistinct = $3.(bool) 5519 lastSelect := union.SelectList.Selects[len(union.SelectList.Selects)-1] 5520 endOffset := parser.endOffset(&yyS[yypt-5]) 5521 parser.setLastSelectFieldText(lastSelect, endOffset) 5522 union.SelectList.Selects = append(union.SelectList.Selects, st) 5523 if $5 != nil { 5524 union.OrderBy = $5.(*ast.OrderByClause) 5525 } 5526 if $6 != nil { 5527 union.Limit = $6.(*ast.Limit) 5528 } 5529 if $5 == nil && $6 == nil { 5530 st.LockTp = $7.(ast.SelectLockType) 5531 } 5532 $$ = union 5533 } 5534 | UnionClauseList "UNION" UnionOpt '(' SelectStmt ')' OrderByOptional SelectStmtLimit 5535 { 5536 union := $1.(*ast.UnionStmt) 5537 lastSelect := union.SelectList.Selects[len(union.SelectList.Selects)-1] 5538 endOffset := parser.endOffset(&yyS[yypt-6]) 5539 parser.setLastSelectFieldText(lastSelect, endOffset) 5540 st := $5.(*ast.SelectStmt) 5541 st.IsInBraces = true 5542 st.IsAfterUnionDistinct = $3.(bool) 5543 endOffset = parser.endOffset(&yyS[yypt-2]) 5544 parser.setLastSelectFieldText(st, endOffset) 5545 union.SelectList.Selects = append(union.SelectList.Selects, st) 5546 if $7 != nil { 5547 union.OrderBy = $7.(*ast.OrderByClause) 5548 } 5549 if $8 != nil { 5550 union.Limit = $8.(*ast.Limit) 5551 } 5552 $$ = union 5553 } 5554 5555 UnionClauseList: 5556 UnionSelect 5557 { 5558 selectList := &ast.UnionSelectList{Selects: []*ast.SelectStmt{$1.(*ast.SelectStmt)}} 5559 $$ = &ast.UnionStmt{ 5560 SelectList: selectList, 5561 } 5562 } 5563 | UnionClauseList "UNION" UnionOpt UnionSelect 5564 { 5565 union := $1.(*ast.UnionStmt) 5566 st := $4.(*ast.SelectStmt) 5567 st.IsAfterUnionDistinct = $3.(bool) 5568 lastSelect := union.SelectList.Selects[len(union.SelectList.Selects)-1] 5569 endOffset := parser.endOffset(&yyS[yypt-2]) 5570 parser.setLastSelectFieldText(lastSelect, endOffset) 5571 union.SelectList.Selects = append(union.SelectList.Selects, st) 5572 $$ = union 5573 } 5574 5575 UnionSelect: 5576 SelectStmt 5577 { 5578 $$ = $1.(interface{}) 5579 } 5580 | '(' SelectStmt ')' 5581 { 5582 st := $2.(*ast.SelectStmt) 5583 st.IsInBraces = true 5584 endOffset := parser.endOffset(&yyS[yypt]) 5585 parser.setLastSelectFieldText(st, endOffset) 5586 $$ = $2 5587 } 5588 5589 UnionOpt: 5590 DefaultTrueDistinctOpt 5591 5592 5593 /********************Set Statement*******************************/ 5594 SetStmt: 5595 "SET" VariableAssignmentList 5596 { 5597 $$ = &ast.SetStmt{Variables: $2.([]*ast.VariableAssignment)} 5598 } 5599 | "SET" "PASSWORD" eq PasswordOpt 5600 { 5601 $$ = &ast.SetPwdStmt{Password: $4.(string)} 5602 } 5603 | "SET" "PASSWORD" "FOR" Username eq PasswordOpt 5604 { 5605 $$ = &ast.SetPwdStmt{User: $4.(*auth.UserIdentity), Password: $6.(string)} 5606 } 5607 | "SET" "GLOBAL" "TRANSACTION" TransactionChars 5608 { 5609 vars := $4.([]*ast.VariableAssignment) 5610 for _, v := range vars { 5611 v.IsGlobal = true 5612 } 5613 $$ = &ast.SetStmt{Variables: vars} 5614 } 5615 | "SET" "SESSION" "TRANSACTION" TransactionChars 5616 { 5617 $$ = &ast.SetStmt{Variables: $4.([]*ast.VariableAssignment)} 5618 } 5619 | "SET" "TRANSACTION" TransactionChars 5620 { 5621 assigns := $3.([]*ast.VariableAssignment) 5622 for i:=0; i<len(assigns); i++ { 5623 if assigns[i].Name == "tx_isolation" { 5624 // A special session variable that make setting tx_isolation take effect one time. 5625 assigns[i].Name = "tx_isolation_one_shot" 5626 } 5627 } 5628 $$ = &ast.SetStmt{Variables: assigns} 5629 } 5630 5631 SetRoleStmt: 5632 "SET" "ROLE" SetRoleOpt 5633 { 5634 } 5635 5636 SetDefaultRoleStmt: 5637 "SET" "DEFAULT" "ROLE" SetDefaultRoleOpt "TO" UsernameList 5638 { 5639 } 5640 5641 SetDefaultRoleOpt: 5642 "NONE" 5643 { 5644 } 5645 | "ALL" 5646 { 5647 } 5648 | RolenameList 5649 { 5650 } 5651 5652 SetRoleOpt: 5653 "ALL" "EXCEPT" RolenameList 5654 { 5655 } 5656 | SetDefaultRoleOpt 5657 { 5658 } 5659 | "DEFAULT" 5660 { 5661 } 5662 5663 5664 TransactionChars: 5665 TransactionChar 5666 { 5667 if $1 != nil { 5668 $$ = $1 5669 } else { 5670 $$ = []*ast.VariableAssignment{} 5671 } 5672 } 5673 | TransactionChars ',' TransactionChar 5674 { 5675 if $3 != nil { 5676 varAssigns := $3.([]*ast.VariableAssignment) 5677 $$ = append($1.([]*ast.VariableAssignment), varAssigns...) 5678 } else { 5679 $$ = $1 5680 } 5681 } 5682 5683 TransactionChar: 5684 "ISOLATION" "LEVEL" IsolationLevel 5685 { 5686 varAssigns := []*ast.VariableAssignment{} 5687 expr := ast.NewValueExpr($3) 5688 varAssigns = append(varAssigns, &ast.VariableAssignment{Name: "tx_isolation", Value: expr, IsSystem: true}) 5689 $$ = varAssigns 5690 } 5691 | "READ" "WRITE" 5692 { 5693 varAssigns := []*ast.VariableAssignment{} 5694 expr := ast.NewValueExpr("0") 5695 varAssigns = append(varAssigns, &ast.VariableAssignment{Name: "tx_read_only", Value: expr, IsSystem: true}) 5696 $$ = varAssigns 5697 } 5698 | "READ" "ONLY" 5699 { 5700 varAssigns := []*ast.VariableAssignment{} 5701 expr := ast.NewValueExpr("1") 5702 varAssigns = append(varAssigns, &ast.VariableAssignment{Name: "tx_read_only", Value: expr, IsSystem: true}) 5703 $$ = varAssigns 5704 } 5705 5706 IsolationLevel: 5707 "REPEATABLE" "READ" 5708 { 5709 $$ = ast.RepeatableRead 5710 } 5711 | "READ" "COMMITTED" 5712 { 5713 $$ = ast.ReadCommitted 5714 } 5715 | "READ" "UNCOMMITTED" 5716 { 5717 $$ = ast.ReadUncommitted 5718 } 5719 | "SERIALIZABLE" 5720 { 5721 $$ = ast.Serializable 5722 } 5723 5724 SetExpr: 5725 "ON" 5726 { 5727 $$ = ast.NewValueExpr("ON") 5728 } 5729 | ExprOrDefault 5730 5731 VariableAssignment: 5732 Identifier eq SetExpr 5733 { 5734 $$ = &ast.VariableAssignment{Name: $1, Value: $3, IsSystem: true} 5735 } 5736 | "GLOBAL" Identifier eq SetExpr 5737 { 5738 $$ = &ast.VariableAssignment{Name: $2, Value: $4, IsGlobal: true, IsSystem: true} 5739 } 5740 | "SESSION" Identifier eq SetExpr 5741 { 5742 $$ = &ast.VariableAssignment{Name: $2, Value: $4, IsSystem: true} 5743 } 5744 | "LOCAL" Identifier eq Expression 5745 { 5746 $$ = &ast.VariableAssignment{Name: $2, Value: $4, IsSystem: true} 5747 } 5748 | doubleAtIdentifier eq SetExpr 5749 { 5750 v := strings.ToLower($1) 5751 var isGlobal bool 5752 if strings.HasPrefix(v, "@@global.") { 5753 isGlobal = true 5754 v = strings.TrimPrefix(v, "@@global.") 5755 } else if strings.HasPrefix(v, "@@session.") { 5756 v = strings.TrimPrefix(v, "@@session.") 5757 } else if strings.HasPrefix(v, "@@local.") { 5758 v = strings.TrimPrefix(v, "@@local.") 5759 } else if strings.HasPrefix(v, "@@") { 5760 v = strings.TrimPrefix(v, "@@") 5761 } 5762 $$ = &ast.VariableAssignment{Name: v, Value: $3, IsGlobal: isGlobal, IsSystem: true} 5763 } 5764 | singleAtIdentifier eq Expression 5765 { 5766 v := $1 5767 v = strings.TrimPrefix(v, "@") 5768 $$ = &ast.VariableAssignment{Name: v, Value: $3} 5769 } 5770 | singleAtIdentifier assignmentEq Expression 5771 { 5772 v := $1 5773 v = strings.TrimPrefix(v, "@") 5774 $$ = &ast.VariableAssignment{Name: v, Value: $3} 5775 } 5776 | "NAMES" CharsetName 5777 { 5778 $$ = &ast.VariableAssignment{ 5779 Name: ast.SetNames, 5780 Value: ast.NewValueExpr($2.(string)), 5781 } 5782 } 5783 | "NAMES" CharsetName "COLLATE" "DEFAULT" 5784 { 5785 $$ = &ast.VariableAssignment{ 5786 Name: ast.SetNames, 5787 Value: ast.NewValueExpr($2.(string)), 5788 } 5789 } 5790 | "NAMES" CharsetName "COLLATE" StringName 5791 { 5792 $$ = &ast.VariableAssignment{ 5793 Name: ast.SetNames, 5794 Value: ast.NewValueExpr($2.(string)), 5795 ExtendValue: ast.NewValueExpr($4.(string)), 5796 } 5797 } 5798 | CharsetKw CharsetName 5799 { 5800 $$ = &ast.VariableAssignment{ 5801 Name: ast.SetNames, 5802 Value: ast.NewValueExpr($2.(string)), 5803 } 5804 } 5805 5806 CharsetName: 5807 StringName 5808 { 5809 $$ = $1 5810 } 5811 | binaryType 5812 { 5813 $$ = mysql.CharsetBin 5814 } 5815 5816 VariableAssignmentList: 5817 { 5818 $$ = []*ast.VariableAssignment{} 5819 } 5820 | VariableAssignment 5821 { 5822 $$ = []*ast.VariableAssignment{$1.(*ast.VariableAssignment)} 5823 } 5824 | VariableAssignmentList ',' VariableAssignment 5825 { 5826 $$ = append($1.([]*ast.VariableAssignment), $3.(*ast.VariableAssignment)) 5827 } 5828 5829 Variable: 5830 SystemVariable | UserVariable 5831 5832 SystemVariable: 5833 doubleAtIdentifier 5834 { 5835 v := strings.ToLower($1) 5836 var isGlobal bool 5837 explicitScope := true 5838 if strings.HasPrefix(v, "@@global.") { 5839 isGlobal = true 5840 v = strings.TrimPrefix(v, "@@global.") 5841 } else if strings.HasPrefix(v, "@@session.") { 5842 v = strings.TrimPrefix(v, "@@session.") 5843 } else if strings.HasPrefix(v, "@@local.") { 5844 v = strings.TrimPrefix(v, "@@local.") 5845 } else if strings.HasPrefix(v, "@@") { 5846 v, explicitScope = strings.TrimPrefix(v, "@@"), false 5847 } 5848 $$ = &ast.VariableExpr{Name: v, IsGlobal: isGlobal, IsSystem: true, ExplicitScope: explicitScope} 5849 } 5850 5851 UserVariable: 5852 singleAtIdentifier 5853 { 5854 v := $1 5855 v = strings.TrimPrefix(v, "@") 5856 $$ = &ast.VariableExpr{Name: v, IsGlobal: false, IsSystem: false} 5857 } 5858 5859 Username: 5860 StringName 5861 { 5862 $$ = &auth.UserIdentity{Username: $1.(string), Hostname: "%"} 5863 } 5864 | StringName '@' StringName 5865 { 5866 $$ = &auth.UserIdentity{Username: $1.(string), Hostname: $3.(string)} 5867 } 5868 | StringName singleAtIdentifier 5869 { 5870 $$ = &auth.UserIdentity{Username: $1.(string), Hostname: strings.TrimPrefix($2, "@")} 5871 } 5872 | "CURRENT_USER" OptionalBraces 5873 { 5874 $$ = &auth.UserIdentity{CurrentUser: true} 5875 } 5876 5877 UsernameList: 5878 Username 5879 { 5880 $$ = []*auth.UserIdentity{$1.(*auth.UserIdentity)} 5881 } 5882 | UsernameList ',' Username 5883 { 5884 $$ = append($1.([]*auth.UserIdentity), $3.(*auth.UserIdentity)) 5885 } 5886 5887 PasswordOpt: 5888 stringLit 5889 { 5890 $$ = $1 5891 } 5892 | "PASSWORD" '(' AuthString ')' 5893 { 5894 $$ = $3.(string) 5895 } 5896 5897 AuthString: 5898 stringLit 5899 { 5900 $$ = $1 5901 } 5902 5903 RoleNameString: 5904 stringLit 5905 { 5906 $$ = $1 5907 } 5908 | identifier 5909 { 5910 $$ = $1 5911 } 5912 5913 5914 Rolename: 5915 RoleNameString 5916 { 5917 $$ = &auth.RoleIdentity{Username: $1.(string), Hostname: "%"} 5918 } 5919 | StringName '@' StringName 5920 { 5921 $$ = &auth.RoleIdentity{Username: $1.(string), Hostname: $3.(string)} 5922 } 5923 | StringName singleAtIdentifier 5924 { 5925 $$ = &auth.RoleIdentity{Username: $1.(string), Hostname: strings.TrimPrefix($2, "@")} 5926 } 5927 5928 RolenameList: 5929 Rolename 5930 { 5931 $$ = []*auth.RoleIdentity{$1.(*auth.RoleIdentity)} 5932 } 5933 | RolenameList ',' Rolename 5934 { 5935 $$ = append($1.([]*auth.RoleIdentity), $3.(*auth.RoleIdentity)) 5936 } 5937 5938 /****************************Admin Statement*******************************/ 5939 AdminStmt: 5940 "ADMIN" "SHOW" "DDL" 5941 { 5942 $$ = &ast.AdminStmt{Tp: ast.AdminShowDDL} 5943 } 5944 | "ADMIN" "SHOW" "DDL" "JOBS" 5945 { 5946 $$ = &ast.AdminStmt{Tp: ast.AdminShowDDLJobs} 5947 } 5948 | "ADMIN" "SHOW" "DDL" "JOBS" NUM 5949 { 5950 $$ = &ast.AdminStmt{ 5951 Tp: ast.AdminShowDDLJobs, 5952 JobNumber: $5.(int64), 5953 } 5954 } 5955 | "ADMIN" "SHOW" TableName "NEXT_ROW_ID" 5956 { 5957 $$ = &ast.AdminStmt{ 5958 Tp: ast.AdminShowNextRowID, 5959 Tables: []*ast.TableName{$3.(*ast.TableName)}, 5960 } 5961 } 5962 | "ADMIN" "CHECK" "TABLE" TableNameList 5963 { 5964 $$ = &ast.AdminStmt{ 5965 Tp: ast.AdminCheckTable, 5966 Tables: $4.([]*ast.TableName), 5967 } 5968 } 5969 | "ADMIN" "CHECK" "INDEX" TableName Identifier 5970 { 5971 $$ = &ast.AdminStmt{ 5972 Tp: ast.AdminCheckIndex, 5973 Tables: []*ast.TableName{$4.(*ast.TableName)}, 5974 Index: string($5), 5975 } 5976 } 5977 | "ADMIN" "RECOVER" "INDEX" TableName Identifier 5978 { 5979 $$ = &ast.AdminStmt{ 5980 Tp: ast.AdminRecoverIndex, 5981 Tables: []*ast.TableName{$4.(*ast.TableName)}, 5982 Index: string($5), 5983 } 5984 } 5985 | "ADMIN" "RESTORE" "TABLE" "BY" "JOB" NUM 5986 { 5987 $$ = &ast.AdminStmt{ 5988 Tp: ast.AdminRestoreTable, 5989 JobIDs: []int64{$6.(int64)}, 5990 } 5991 } 5992 | "ADMIN" "RESTORE" "TABLE" TableName 5993 { 5994 $$ = &ast.AdminStmt{ 5995 Tp: ast.AdminRestoreTable, 5996 Tables: []*ast.TableName{$4.(*ast.TableName)}, 5997 } 5998 } 5999 | "ADMIN" "RESTORE" "TABLE" TableName NUM 6000 { 6001 $$ = &ast.AdminStmt{ 6002 Tp: ast.AdminRestoreTable, 6003 Tables: []*ast.TableName{$4.(*ast.TableName)}, 6004 JobNumber: $5.(int64), 6005 } 6006 } 6007 | "ADMIN" "CLEANUP" "INDEX" TableName Identifier 6008 { 6009 $$ = &ast.AdminStmt{ 6010 Tp: ast.AdminCleanupIndex, 6011 Tables: []*ast.TableName{$4.(*ast.TableName)}, 6012 Index: string($5), 6013 } 6014 } 6015 | "ADMIN" "CHECK" "INDEX" TableName Identifier HandleRangeList 6016 { 6017 $$ = &ast.AdminStmt{ 6018 Tp: ast.AdminCheckIndexRange, 6019 Tables: []*ast.TableName{$4.(*ast.TableName)}, 6020 Index: string($5), 6021 HandleRanges: $6.([]ast.HandleRange), 6022 } 6023 } 6024 | "ADMIN" "CHECKSUM" "TABLE" TableNameList 6025 { 6026 $$ = &ast.AdminStmt{ 6027 Tp: ast.AdminChecksumTable, 6028 Tables: $4.([]*ast.TableName), 6029 } 6030 } 6031 | "ADMIN" "CANCEL" "DDL" "JOBS" NumList 6032 { 6033 $$ = &ast.AdminStmt{ 6034 Tp: ast.AdminCancelDDLJobs, 6035 JobIDs: $5.([]int64), 6036 } 6037 } 6038 | "ADMIN" "SHOW" "DDL" "JOB" "QUERIES" NumList 6039 { 6040 $$ = &ast.AdminStmt{ 6041 Tp: ast.AdminShowDDLJobQueries, 6042 JobIDs: $6.([]int64), 6043 } 6044 } 6045 | "ADMIN" "SHOW" "SLOW" AdminShowSlow 6046 { 6047 $$ = &ast.AdminStmt{ 6048 Tp: ast.AdminShowSlow, 6049 ShowSlow: $4.(*ast.ShowSlow), 6050 } 6051 } 6052 6053 AdminShowSlow: 6054 "RECENT" NUM 6055 { 6056 $$ = &ast.ShowSlow{ 6057 Tp: ast.ShowSlowRecent, 6058 Count: getUint64FromNUM($2), 6059 } 6060 } 6061 | "TOP" NUM 6062 { 6063 $$ = &ast.ShowSlow{ 6064 Tp: ast.ShowSlowTop, 6065 Kind: ast.ShowSlowKindDefault, 6066 Count: getUint64FromNUM($2), 6067 } 6068 } 6069 | "TOP" "INTERNAL" NUM 6070 { 6071 $$ = &ast.ShowSlow{ 6072 Tp: ast.ShowSlowTop, 6073 Kind: ast.ShowSlowKindInternal, 6074 Count: getUint64FromNUM($3), 6075 } 6076 } 6077 | "TOP" "ALL" NUM 6078 { 6079 $$ = &ast.ShowSlow{ 6080 Tp: ast.ShowSlowTop, 6081 Kind: ast.ShowSlowKindAll, 6082 Count: getUint64FromNUM($3), 6083 } 6084 } 6085 6086 HandleRangeList: 6087 HandleRange 6088 { 6089 $$ = []ast.HandleRange{$1.(ast.HandleRange)} 6090 } 6091 | HandleRangeList ',' HandleRange 6092 { 6093 $$ = append($1.([]ast.HandleRange), $3.(ast.HandleRange)) 6094 } 6095 6096 HandleRange: 6097 '(' NUM ',' NUM ')' 6098 { 6099 $$ = ast.HandleRange{Begin: $2.(int64), End: $4.(int64)} 6100 } 6101 6102 6103 NumList: 6104 NUM 6105 { 6106 $$ = []int64{$1.(int64)} 6107 } 6108 | 6109 NumList ',' NUM 6110 { 6111 $$ = append($1.([]int64), $3.(int64)) 6112 } 6113 6114 /****************************Show Statement*******************************/ 6115 ShowStmt: 6116 "SHOW" ShowTargetFilterable ShowLikeOrWhereOpt 6117 { 6118 stmt := $2.(*ast.ShowStmt) 6119 if $3 != nil { 6120 if x, ok := $3.(*ast.PatternLikeExpr); ok && x.Expr == nil { 6121 stmt.Pattern = x 6122 } else { 6123 stmt.Where = $3.(ast.ExprNode) 6124 } 6125 } 6126 $$ = stmt 6127 } 6128 | "SHOW" "CREATE" "TABLE" TableName 6129 { 6130 $$ = &ast.ShowStmt{ 6131 Tp: ast.ShowCreateTable, 6132 Table: $4.(*ast.TableName), 6133 } 6134 } 6135 | "SHOW" "CREATE" "VIEW" TableName 6136 { 6137 $$ = &ast.ShowStmt{ 6138 Tp: ast.ShowCreateView, 6139 Table: $4.(*ast.TableName), 6140 } 6141 } 6142 | "SHOW" "CREATE" "DATABASE" IfNotExists DBName 6143 { 6144 $$ = &ast.ShowStmt{ 6145 Tp: ast.ShowCreateDatabase, 6146 IfNotExists: $4.(bool), 6147 DBName: $5.(string), 6148 } 6149 } 6150 | "SHOW" "CREATE" "USER" Username 6151 { 6152 // See https://dev.mysql.com/doc/refman/5.7/en/show-create-user.html 6153 $$ = &ast.ShowStmt{ 6154 Tp: ast.ShowCreateUser, 6155 User: $4.(*auth.UserIdentity), 6156 } 6157 } 6158 | "SHOW" "GRANTS" 6159 { 6160 // See https://dev.mysql.com/doc/refman/5.7/en/show-grants.html 6161 $$ = &ast.ShowStmt{Tp: ast.ShowGrants} 6162 } 6163 | "SHOW" "GRANTS" "FOR" Username 6164 { 6165 // See https://dev.mysql.com/doc/refman/5.7/en/show-grants.html 6166 $$ = &ast.ShowStmt{ 6167 Tp: ast.ShowGrants, 6168 User: $4.(*auth.UserIdentity), 6169 } 6170 } 6171 | "SHOW" "MASTER" "STATUS" 6172 { 6173 $$ = &ast.ShowStmt{ 6174 Tp: ast.ShowMasterStatus, 6175 } 6176 } 6177 | "SHOW" OptFull "PROCESSLIST" 6178 { 6179 $$ = &ast.ShowStmt{ 6180 Tp: ast.ShowProcessList, 6181 Full: $2.(bool), 6182 } 6183 } 6184 | "SHOW" "STATS_META" ShowLikeOrWhereOpt 6185 { 6186 stmt := &ast.ShowStmt{ 6187 Tp: ast.ShowStatsMeta, 6188 } 6189 if $3 != nil { 6190 if x, ok := $3.(*ast.PatternLikeExpr); ok && x.Expr == nil { 6191 stmt.Pattern = x 6192 } else { 6193 stmt.Where = $3.(ast.ExprNode) 6194 } 6195 } 6196 $$ = stmt 6197 } 6198 | "SHOW" "STATS_HISTOGRAMS" ShowLikeOrWhereOpt 6199 { 6200 stmt := &ast.ShowStmt{ 6201 Tp: ast.ShowStatsHistograms, 6202 } 6203 if $3 != nil { 6204 if x, ok := $3.(*ast.PatternLikeExpr); ok && x.Expr == nil { 6205 stmt.Pattern = x 6206 } else { 6207 stmt.Where = $3.(ast.ExprNode) 6208 } 6209 } 6210 $$ = stmt 6211 } 6212 | "SHOW" "STATS_BUCKETS" ShowLikeOrWhereOpt 6213 { 6214 stmt := &ast.ShowStmt{ 6215 Tp: ast.ShowStatsBuckets, 6216 } 6217 if $3 != nil { 6218 if x, ok := $3.(*ast.PatternLikeExpr); ok && x.Expr == nil { 6219 stmt.Pattern = x 6220 } else { 6221 stmt.Where = $3.(ast.ExprNode) 6222 } 6223 } 6224 $$ = stmt 6225 } 6226 | "SHOW" "STATS_HEALTHY" ShowLikeOrWhereOpt 6227 { 6228 stmt := &ast.ShowStmt{ 6229 Tp: ast.ShowStatsHealthy, 6230 } 6231 if $3 != nil { 6232 if x, ok := $3.(*ast.PatternLikeExpr); ok && x.Expr == nil { 6233 stmt.Pattern = x 6234 } else { 6235 stmt.Where = $3.(ast.ExprNode) 6236 } 6237 } 6238 $$ = stmt 6239 } 6240 | "SHOW" "PROFILES" 6241 { 6242 $$ = &ast.ShowStmt{ 6243 Tp: ast.ShowProfiles, 6244 } 6245 } 6246 | "SHOW" "PRIVILEGES" 6247 { 6248 $$ = &ast.ShowStmt{ 6249 Tp: ast.ShowPrivileges, 6250 } 6251 } 6252 6253 ShowIndexKwd: 6254 "INDEX" 6255 | "INDEXES" 6256 | "KEYS" 6257 6258 FromOrIn: 6259 "FROM" | "IN" 6260 6261 ShowTargetFilterable: 6262 "ENGINES" 6263 { 6264 $$ = &ast.ShowStmt{Tp: ast.ShowEngines} 6265 } 6266 | "DATABASES" 6267 { 6268 $$ = &ast.ShowStmt{Tp: ast.ShowDatabases} 6269 } 6270 | CharsetKw 6271 { 6272 $$ = &ast.ShowStmt{Tp: ast.ShowCharset} 6273 } 6274 | OptFull "TABLES" ShowDatabaseNameOpt 6275 { 6276 $$ = &ast.ShowStmt{ 6277 Tp: ast.ShowTables, 6278 DBName: $3.(string), 6279 Full: $1.(bool), 6280 } 6281 } 6282 | "TABLE" "STATUS" ShowDatabaseNameOpt 6283 { 6284 $$ = &ast.ShowStmt{ 6285 Tp: ast.ShowTableStatus, 6286 DBName: $3.(string), 6287 } 6288 } 6289 | ShowIndexKwd FromOrIn TableName 6290 { 6291 $$ = &ast.ShowStmt{ 6292 Tp: ast.ShowIndex, 6293 Table: $3.(*ast.TableName), 6294 } 6295 } 6296 | ShowIndexKwd FromOrIn Identifier FromOrIn Identifier 6297 { 6298 show := &ast.ShowStmt{ 6299 Tp: ast.ShowIndex, 6300 Table: &ast.TableName{Name:model.NewCIStr($3), Schema: model.NewCIStr($5)}, 6301 } 6302 $$ = show 6303 } 6304 | OptFull "COLUMNS" ShowTableAliasOpt ShowDatabaseNameOpt 6305 { 6306 $$ = &ast.ShowStmt{ 6307 Tp: ast.ShowColumns, 6308 Table: $3.(*ast.TableName), 6309 DBName: $4.(string), 6310 Full: $1.(bool), 6311 } 6312 } 6313 | OptFull "FIELDS" ShowTableAliasOpt ShowDatabaseNameOpt 6314 { 6315 // SHOW FIELDS is a synonym for SHOW COLUMNS. 6316 $$ = &ast.ShowStmt{ 6317 Tp: ast.ShowColumns, 6318 Table: $3.(*ast.TableName), 6319 DBName: $4.(string), 6320 Full: $1.(bool), 6321 } 6322 } 6323 | "WARNINGS" 6324 { 6325 $$ = &ast.ShowStmt{Tp: ast.ShowWarnings} 6326 } 6327 | "ERRORS" 6328 { 6329 $$ = &ast.ShowStmt{Tp: ast.ShowErrors} 6330 } 6331 | GlobalScope "VARIABLES" 6332 { 6333 $$ = &ast.ShowStmt{ 6334 Tp: ast.ShowVariables, 6335 GlobalScope: $1.(bool), 6336 } 6337 } 6338 | GlobalScope "STATUS" 6339 { 6340 $$ = &ast.ShowStmt{ 6341 Tp: ast.ShowStatus, 6342 GlobalScope: $1.(bool), 6343 } 6344 } 6345 | GlobalScope "BINDINGS" 6346 { 6347 $$ = &ast.ShowStmt{ 6348 Tp: ast.ShowBindings, 6349 GlobalScope: $1.(bool), 6350 } 6351 } 6352 | "COLLATION" 6353 { 6354 $$ = &ast.ShowStmt{ 6355 Tp: ast.ShowCollation, 6356 } 6357 } 6358 | "TRIGGERS" ShowDatabaseNameOpt 6359 { 6360 $$ = &ast.ShowStmt{ 6361 Tp: ast.ShowTriggers, 6362 DBName: $2.(string), 6363 } 6364 } 6365 | "PROCEDURE" "STATUS" 6366 { 6367 $$ = &ast.ShowStmt { 6368 Tp: ast.ShowProcedureStatus, 6369 } 6370 } 6371 | "PUMP" "STATUS" 6372 { 6373 $$ = &ast.ShowStmt { 6374 Tp: ast.ShowPumpStatus, 6375 } 6376 } 6377 | "DRAINER" "STATUS" 6378 { 6379 $$ = &ast.ShowStmt { 6380 Tp: ast.ShowDrainerStatus, 6381 } 6382 } 6383 | "FUNCTION" "STATUS" 6384 { 6385 // This statement is similar to SHOW PROCEDURE STATUS but for stored functions. 6386 // See http://dev.mysql.com/doc/refman/5.7/en/show-function-status.html 6387 // We do not support neither stored functions nor stored procedures. 6388 // So we reuse show procedure status process logic. 6389 $$ = &ast.ShowStmt { 6390 Tp: ast.ShowProcedureStatus, 6391 } 6392 } 6393 | "EVENTS" ShowDatabaseNameOpt 6394 { 6395 $$ = &ast.ShowStmt{ 6396 Tp: ast.ShowEvents, 6397 DBName: $2.(string), 6398 } 6399 } 6400 | "PLUGINS" 6401 { 6402 $$ = &ast.ShowStmt{ 6403 Tp: ast.ShowPlugins, 6404 } 6405 } 6406 ShowLikeOrWhereOpt: 6407 { 6408 $$ = nil 6409 } 6410 | "LIKE" SimpleExpr 6411 { 6412 $$ = &ast.PatternLikeExpr{ 6413 Pattern: $2, 6414 Escape: '\\', 6415 } 6416 } 6417 | "WHERE" Expression 6418 { 6419 $$ = $2 6420 } 6421 6422 GlobalScope: 6423 { 6424 $$ = false 6425 } 6426 | "GLOBAL" 6427 { 6428 $$ = true 6429 } 6430 | "SESSION" 6431 { 6432 $$ = false 6433 } 6434 6435 OptFull: 6436 { 6437 $$ = false 6438 } 6439 | "FULL" 6440 { 6441 $$ = true 6442 } 6443 6444 ShowDatabaseNameOpt: 6445 { 6446 $$ = "" 6447 } 6448 | FromOrIn DBName 6449 { 6450 $$ = $2.(string) 6451 } 6452 6453 ShowTableAliasOpt: 6454 FromOrIn TableName 6455 { 6456 $$ = $2.(*ast.TableName) 6457 } 6458 6459 FlushStmt: 6460 "FLUSH" NoWriteToBinLogAliasOpt FlushOption 6461 { 6462 tmp := $3.(*ast.FlushStmt) 6463 tmp.NoWriteToBinLog = $2.(bool) 6464 $$ = tmp 6465 } 6466 6467 PluginNameList: 6468 Identifier 6469 { 6470 $$ = []string{$1} 6471 } 6472 | PluginNameList ',' Identifier 6473 { 6474 $$ = append($1.([]string), $3) 6475 } 6476 6477 FlushOption: 6478 "PRIVILEGES" 6479 { 6480 $$ = &ast.FlushStmt{ 6481 Tp: ast.FlushPrivileges, 6482 } 6483 } 6484 | "STATUS" 6485 { 6486 $$ = &ast.FlushStmt{ 6487 Tp: ast.FlushStatus, 6488 } 6489 } 6490 | "TIDB" "PLUGINS" PluginNameList 6491 { 6492 $$ = &ast.FlushStmt{ 6493 Tp: ast.FlushTiDBPlugin, 6494 Plugins: $3.([]string), 6495 } 6496 } 6497 | TableOrTables TableNameListOpt WithReadLockOpt 6498 { 6499 $$ = &ast.FlushStmt{ 6500 Tp: ast.FlushTables, 6501 Tables: $2.([]*ast.TableName), 6502 ReadLock: $3.(bool), 6503 } 6504 } 6505 6506 NoWriteToBinLogAliasOpt: 6507 { 6508 $$ = false 6509 } 6510 | "NO_WRITE_TO_BINLOG" 6511 { 6512 $$ = true 6513 } 6514 | "LOCAL" 6515 { 6516 $$ = true 6517 } 6518 6519 TableNameListOpt: 6520 %prec empty 6521 { 6522 $$ = []*ast.TableName{} 6523 } 6524 | TableNameList 6525 { 6526 $$ = $1 6527 } 6528 6529 WithReadLockOpt: 6530 { 6531 $$ = false 6532 } 6533 | "WITH" "READ" "LOCK" 6534 { 6535 $$ = true 6536 } 6537 6538 Statement: 6539 EmptyStmt 6540 | AdminStmt 6541 | AlterTableStmt 6542 | AlterUserStmt 6543 | AnalyzeTableStmt 6544 | BeginTransactionStmt 6545 | BinlogStmt 6546 | CommitStmt 6547 | DeallocateStmt 6548 | DeleteFromStmt 6549 | ExecuteStmt 6550 | ExplainStmt 6551 | CreateDatabaseStmt 6552 | CreateIndexStmt 6553 | CreateTableStmt 6554 | CreateViewStmt 6555 | CreateUserStmt 6556 | CreateRoleStmt 6557 | CreateBindingStmt 6558 | DoStmt 6559 | DropDatabaseStmt 6560 | DropIndexStmt 6561 | DropTableStmt 6562 | DropViewStmt 6563 | DropUserStmt 6564 | DropRoleStmt 6565 | DropStatsStmt 6566 | DropBindingStmt 6567 | FlushStmt 6568 | GrantStmt 6569 | GrantRoleStmt 6570 | InsertIntoStmt 6571 | KillStmt 6572 | LoadDataStmt 6573 | LoadStatsStmt 6574 | PreparedStmt 6575 | RollbackStmt 6576 | RenameTableStmt 6577 | ReplaceIntoStmt 6578 | RevokeStmt 6579 | RevokeRoleStmt 6580 | SavepointStmt 6581 | SelectStmt 6582 | UnionStmt 6583 | SetStmt 6584 | SetRoleStmt 6585 | SetDefaultRoleStmt 6586 | ShowStmt 6587 | SubSelect 6588 { 6589 // `(select 1)`; is a valid select statement 6590 // TODO: This is used to fix issue #320. There may be a better solution. 6591 $$ = $1.(*ast.SubqueryExpr).Query.(ast.StmtNode) 6592 } 6593 | TraceStmt 6594 | TruncateTableStmt 6595 | UpdateStmt 6596 | UseStmt 6597 | UnlockTablesStmt 6598 | LockTablesStmt 6599 6600 TraceableStmt: 6601 SelectStmt 6602 | DeleteFromStmt 6603 | UpdateStmt 6604 | InsertIntoStmt 6605 | ReplaceIntoStmt 6606 | UnionStmt 6607 6608 ExplainableStmt: 6609 SelectStmt 6610 | DeleteFromStmt 6611 | UpdateStmt 6612 | InsertIntoStmt 6613 | ReplaceIntoStmt 6614 | UnionStmt 6615 6616 StatementList: 6617 Statement 6618 { 6619 if $1 != nil { 6620 s := $1 6621 if lexer, ok := yylex.(stmtTexter); ok { 6622 s.SetText(lexer.stmtText()) 6623 } 6624 parser.result = append(parser.result, s) 6625 } 6626 } 6627 | StatementList ';' Statement 6628 { 6629 if $3 != nil { 6630 s := $3 6631 if lexer, ok := yylex.(stmtTexter); ok { 6632 s.SetText(lexer.stmtText()) 6633 } 6634 parser.result = append(parser.result, s) 6635 } 6636 } 6637 6638 Constraint: 6639 ConstraintKeywordOpt ConstraintElem 6640 { 6641 cst := $2.(*ast.Constraint) 6642 if $1 != nil { 6643 cst.Name = $1.(string) 6644 } 6645 $$ = cst 6646 } 6647 6648 TableElement: 6649 ColumnDef 6650 { 6651 $$ = $1.(*ast.ColumnDef) 6652 } 6653 | Constraint 6654 { 6655 $$ = $1.(*ast.Constraint) 6656 } 6657 | "CHECK" '(' Expression ')' 6658 { 6659 /* Nothing to do now */ 6660 $$ = nil 6661 } 6662 6663 TableElementList: 6664 TableElement 6665 { 6666 if $1 != nil { 6667 $$ = []interface{}{$1.(interface{})} 6668 } else { 6669 $$ = []interface{}{} 6670 } 6671 } 6672 | TableElementList ',' TableElement 6673 { 6674 if $3 != nil { 6675 $$ = append($1.([]interface{}), $3) 6676 } else { 6677 $$ = $1 6678 } 6679 } 6680 6681 TableElementListOpt: 6682 /* empty */ %prec lowerThanCreateTableSelect 6683 { 6684 var columnDefs []*ast.ColumnDef 6685 var constraints []*ast.Constraint 6686 $$ = &ast.CreateTableStmt{ 6687 Cols: columnDefs, 6688 Constraints: constraints, 6689 } 6690 } 6691 | 6692 '(' TableElementList ')' 6693 { 6694 tes := $2.([]interface {}) 6695 var columnDefs []*ast.ColumnDef 6696 var constraints []*ast.Constraint 6697 for _, te := range tes { 6698 switch te := te.(type) { 6699 case *ast.ColumnDef: 6700 columnDefs = append(columnDefs, te) 6701 case *ast.Constraint: 6702 constraints = append(constraints, te) 6703 } 6704 } 6705 $$ = &ast.CreateTableStmt{ 6706 Cols: columnDefs, 6707 Constraints: constraints, 6708 } 6709 } 6710 6711 TableOption: 6712 "ENGINE" StringName 6713 { 6714 $$ = &ast.TableOption{Tp: ast.TableOptionEngine, StrValue: $2.(string)} 6715 } 6716 | "ENGINE" eq StringName 6717 { 6718 $$ = &ast.TableOption{Tp: ast.TableOptionEngine, StrValue: $3.(string)} 6719 } 6720 | DefaultKwdOpt CharsetKw EqOpt CharsetName 6721 { 6722 $$ = &ast.TableOption{Tp: ast.TableOptionCharset, StrValue: $4.(string)} 6723 } 6724 | DefaultKwdOpt "COLLATE" EqOpt StringName 6725 { 6726 $$ = &ast.TableOption{Tp: ast.TableOptionCollate, StrValue: $4.(string)} 6727 } 6728 | "AUTO_INCREMENT" EqOpt LengthNum 6729 { 6730 $$ = &ast.TableOption{Tp: ast.TableOptionAutoIncrement, UintValue: $3.(uint64)} 6731 } 6732 | "COMMENT" EqOpt stringLit 6733 { 6734 $$ = &ast.TableOption{Tp: ast.TableOptionComment, StrValue: $3} 6735 } 6736 | "AVG_ROW_LENGTH" EqOpt LengthNum 6737 { 6738 $$ = &ast.TableOption{Tp: ast.TableOptionAvgRowLength, UintValue: $3.(uint64)} 6739 } 6740 | "CONNECTION" EqOpt stringLit 6741 { 6742 $$ = &ast.TableOption{Tp: ast.TableOptionConnection, StrValue: $3} 6743 } 6744 | "CHECKSUM" EqOpt LengthNum 6745 { 6746 $$ = &ast.TableOption{Tp: ast.TableOptionCheckSum, UintValue: $3.(uint64)} 6747 } 6748 | "PASSWORD" EqOpt stringLit 6749 { 6750 $$ = &ast.TableOption{Tp: ast.TableOptionPassword, StrValue: $3} 6751 } 6752 | "COMPRESSION" EqOpt stringLit 6753 { 6754 $$ = &ast.TableOption{Tp: ast.TableOptionCompression, StrValue: $3} 6755 } 6756 | "KEY_BLOCK_SIZE" EqOpt LengthNum 6757 { 6758 $$ = &ast.TableOption{Tp: ast.TableOptionKeyBlockSize, UintValue: $3.(uint64)} 6759 } 6760 | "MAX_ROWS" EqOpt LengthNum 6761 { 6762 $$ = &ast.TableOption{Tp: ast.TableOptionMaxRows, UintValue: $3.(uint64)} 6763 } 6764 | "MIN_ROWS" EqOpt LengthNum 6765 { 6766 $$ = &ast.TableOption{Tp: ast.TableOptionMinRows, UintValue: $3.(uint64)} 6767 } 6768 | "DELAY_KEY_WRITE" EqOpt LengthNum 6769 { 6770 $$ = &ast.TableOption{Tp: ast.TableOptionDelayKeyWrite, UintValue: $3.(uint64)} 6771 } 6772 | RowFormat 6773 { 6774 $$ = &ast.TableOption{Tp: ast.TableOptionRowFormat, UintValue: $1.(uint64)} 6775 } 6776 | "STATS_PERSISTENT" EqOpt StatsPersistentVal 6777 { 6778 $$ = &ast.TableOption{Tp: ast.TableOptionStatsPersistent} 6779 } 6780 | "SHARD_ROW_ID_BITS" EqOpt LengthNum 6781 { 6782 $$ = &ast.TableOption{Tp: ast.TableOptionShardRowID, UintValue: $3.(uint64)} 6783 } 6784 | "PACK_KEYS" EqOpt StatsPersistentVal 6785 { 6786 // Parse it but will ignore it. 6787 $$ = &ast.TableOption{Tp: ast.TableOptionPackKeys} 6788 } 6789 6790 StatsPersistentVal: 6791 "DEFAULT" 6792 {} 6793 | LengthNum 6794 {} 6795 6796 AlterTableOptionListOpt: 6797 { 6798 $$ = []*ast.TableOption{} 6799 } 6800 | TableOptionList %prec higherThanComma 6801 6802 CreateTableOptionListOpt: 6803 /* empty */ %prec lowerThanCreateTableSelect 6804 { 6805 $$ = []*ast.TableOption{} 6806 } 6807 | TableOptionList %prec lowerThanComma 6808 6809 TableOptionList: 6810 TableOption 6811 { 6812 $$ = []*ast.TableOption{$1.(*ast.TableOption)} 6813 } 6814 | TableOptionList TableOption 6815 { 6816 $$ = append($1.([]*ast.TableOption), $2.(*ast.TableOption)) 6817 } 6818 | TableOptionList ',' TableOption 6819 { 6820 $$ = append($1.([]*ast.TableOption), $3.(*ast.TableOption)) 6821 } 6822 6823 OptTable: 6824 {} 6825 | "TABLE" 6826 6827 TruncateTableStmt: 6828 "TRUNCATE" OptTable TableName 6829 { 6830 $$ = &ast.TruncateTableStmt{Table: $3.(*ast.TableName)} 6831 } 6832 6833 RowFormat: 6834 "ROW_FORMAT" EqOpt "DEFAULT" 6835 { 6836 $$ = ast.RowFormatDefault 6837 } 6838 | "ROW_FORMAT" EqOpt "DYNAMIC" 6839 { 6840 $$ = ast.RowFormatDynamic 6841 } 6842 | "ROW_FORMAT" EqOpt "FIXED" 6843 { 6844 $$ = ast.RowFormatFixed 6845 } 6846 | "ROW_FORMAT" EqOpt "COMPRESSED" 6847 { 6848 $$ = ast.RowFormatCompressed 6849 } 6850 | "ROW_FORMAT" EqOpt "REDUNDANT" 6851 { 6852 $$ = ast.RowFormatRedundant 6853 } 6854 | "ROW_FORMAT" EqOpt "COMPACT" 6855 { 6856 $$ = ast.RowFormatCompact 6857 } 6858 6859 /*************************************Type Begin***************************************/ 6860 Type: 6861 NumericType 6862 { 6863 $$ = $1 6864 } 6865 | StringType 6866 { 6867 $$ = $1 6868 } 6869 | DateAndTimeType 6870 { 6871 $$ = $1 6872 } 6873 6874 NumericType: 6875 IntegerType OptFieldLen FieldOpts 6876 { 6877 // TODO: check flen 0 6878 x := types.NewFieldType($1.(byte)) 6879 x.Flen = $2.(int) 6880 for _, o := range $3.([]*ast.TypeOpt) { 6881 if o.IsUnsigned { 6882 x.Flag |= mysql.UnsignedFlag 6883 } 6884 if o.IsZerofill { 6885 x.Flag |= mysql.ZerofillFlag 6886 } 6887 } 6888 $$ = x 6889 } 6890 | BooleanType FieldOpts 6891 { 6892 // TODO: check flen 0 6893 x := types.NewFieldType($1.(byte)) 6894 x.Flen = 1 6895 for _, o := range $2.([]*ast.TypeOpt) { 6896 if o.IsUnsigned { 6897 x.Flag |= mysql.UnsignedFlag 6898 } 6899 if o.IsZerofill { 6900 x.Flag |= mysql.ZerofillFlag 6901 } 6902 } 6903 $$ = x 6904 } 6905 | FixedPointType FloatOpt FieldOpts 6906 { 6907 fopt := $2.(*ast.FloatOpt) 6908 x := types.NewFieldType($1.(byte)) 6909 x.Flen = fopt.Flen 6910 x.Decimal = fopt.Decimal 6911 for _, o := range $3.([]*ast.TypeOpt) { 6912 if o.IsUnsigned { 6913 x.Flag |= mysql.UnsignedFlag 6914 } 6915 if o.IsZerofill { 6916 x.Flag |= mysql.ZerofillFlag 6917 } 6918 } 6919 $$ = x 6920 } 6921 | FloatingPointType FloatOpt FieldOpts 6922 { 6923 fopt := $2.(*ast.FloatOpt) 6924 x := types.NewFieldType($1.(byte)) 6925 x.Flen = fopt.Flen 6926 if x.Tp == mysql.TypeFloat { 6927 if x.Flen > 24 { 6928 x.Tp = mysql.TypeDouble 6929 } 6930 } 6931 x.Decimal = fopt.Decimal 6932 for _, o := range $3.([]*ast.TypeOpt) { 6933 if o.IsUnsigned { 6934 x.Flag |= mysql.UnsignedFlag 6935 } 6936 if o.IsZerofill { 6937 x.Flag |= mysql.ZerofillFlag 6938 } 6939 } 6940 $$ = x 6941 } 6942 | BitValueType OptFieldLen 6943 { 6944 x := types.NewFieldType($1.(byte)) 6945 x.Flen = $2.(int) 6946 if x.Flen == types.UnspecifiedLength || x.Flen == 0 { 6947 x.Flen = 1 6948 } else if x.Flen > 64 { 6949 yylex.Errorf("invalid field length %d for bit type, must in [1, 64]", x.Flen) 6950 } 6951 $$ = x 6952 } 6953 6954 IntegerType: 6955 "TINYINT" 6956 { 6957 $$ = mysql.TypeTiny 6958 } 6959 | "SMALLINT" 6960 { 6961 $$ = mysql.TypeShort 6962 } 6963 | "MEDIUMINT" 6964 { 6965 $$ = mysql.TypeInt24 6966 } 6967 | "INT" 6968 { 6969 $$ = mysql.TypeLong 6970 } 6971 | "INT1" 6972 { 6973 $$ = mysql.TypeTiny 6974 } 6975 | "INT2" 6976 { 6977 $$ = mysql.TypeShort 6978 } 6979 | "INT3" 6980 { 6981 $$ = mysql.TypeInt24 6982 } 6983 | "INT4" 6984 { 6985 $$ = mysql.TypeLong 6986 } 6987 | "INT8" 6988 { 6989 $$ = mysql.TypeLonglong 6990 } 6991 | "INTEGER" 6992 { 6993 $$ = mysql.TypeLong 6994 } 6995 | "BIGINT" 6996 { 6997 $$ = mysql.TypeLonglong 6998 } 6999 7000 7001 BooleanType: 7002 "BOOL" 7003 { 7004 $$ = mysql.TypeTiny 7005 } 7006 | "BOOLEAN" 7007 { 7008 $$ = mysql.TypeTiny 7009 } 7010 7011 OptInteger: 7012 {} 7013 | "INTEGER" 7014 | "INT" 7015 7016 FixedPointType: 7017 "DECIMAL" 7018 { 7019 $$ = mysql.TypeNewDecimal 7020 } 7021 | "NUMERIC" 7022 { 7023 $$ = mysql.TypeNewDecimal 7024 } 7025 7026 FloatingPointType: 7027 "FLOAT" 7028 { 7029 $$ = mysql.TypeFloat 7030 } 7031 | "REAL" 7032 { 7033 if parser.lexer.GetSQLMode().HasRealAsFloatMode() { 7034 $$ = mysql.TypeFloat 7035 } else { 7036 $$ = mysql.TypeDouble 7037 } 7038 } 7039 | "DOUBLE" 7040 { 7041 $$ = mysql.TypeDouble 7042 } 7043 | "DOUBLE" "PRECISION" 7044 { 7045 $$ = mysql.TypeDouble 7046 } 7047 7048 BitValueType: 7049 "BIT" 7050 { 7051 $$ = mysql.TypeBit 7052 } 7053 7054 StringType: 7055 NationalOpt "CHAR" FieldLen OptBinary OptCollate 7056 { 7057 x := types.NewFieldType(mysql.TypeString) 7058 x.Flen = $3.(int) 7059 x.Charset = $4.(*ast.OptBinary).Charset 7060 x.Collate = $5.(string) 7061 if $4.(*ast.OptBinary).IsBinary { 7062 x.Flag |= mysql.BinaryFlag 7063 } 7064 $$ = x 7065 } 7066 | NationalOpt "CHAR" OptBinary OptCollate 7067 { 7068 x := types.NewFieldType(mysql.TypeString) 7069 x.Charset = $3.(*ast.OptBinary).Charset 7070 x.Collate = $4.(string) 7071 if $3.(*ast.OptBinary).IsBinary { 7072 x.Flag |= mysql.BinaryFlag 7073 } 7074 $$ = x 7075 } 7076 | "NATIONAL" "CHARACTER" FieldLen OptBinary OptCollate 7077 { 7078 x := types.NewFieldType(mysql.TypeString) 7079 x.Flen = $3.(int) 7080 x.Charset = $4.(*ast.OptBinary).Charset 7081 x.Collate = $5.(string) 7082 if $4.(*ast.OptBinary).IsBinary { 7083 x.Flag |= mysql.BinaryFlag 7084 } 7085 $$ = x 7086 } 7087 | Varchar FieldLen OptBinary OptCollate 7088 { 7089 x := types.NewFieldType(mysql.TypeVarchar) 7090 x.Flen = $2.(int) 7091 x.Charset = $3.(*ast.OptBinary).Charset 7092 x.Collate = $4.(string) 7093 if $3.(*ast.OptBinary).IsBinary { 7094 x.Flag |= mysql.BinaryFlag 7095 } 7096 $$ = x 7097 } 7098 | "BINARY" OptFieldLen 7099 { 7100 x := types.NewFieldType(mysql.TypeString) 7101 x.Flen = $2.(int) 7102 x.Charset = mysql.CharsetBin 7103 x.Collate = mysql.CharsetBin 7104 x.Flag |= mysql.BinaryFlag 7105 $$ = x 7106 } 7107 | "VARBINARY" FieldLen 7108 { 7109 x := types.NewFieldType(mysql.TypeVarchar) 7110 x.Flen = $2.(int) 7111 x.Charset = mysql.CharsetBin 7112 x.Collate = mysql.CharsetBin 7113 x.Flag |= mysql.BinaryFlag 7114 $$ = x 7115 } 7116 | BlobType 7117 { 7118 x := $1.(*types.FieldType) 7119 x.Charset = mysql.CharsetBin 7120 x.Collate = mysql.CharsetBin 7121 x.Flag |= mysql.BinaryFlag 7122 $$ = $1.(*types.FieldType) 7123 } 7124 | TextType OptBinary OptCollate 7125 { 7126 x := $1.(*types.FieldType) 7127 x.Charset = $2.(*ast.OptBinary).Charset 7128 x.Collate = $3.(string) 7129 if $2.(*ast.OptBinary).IsBinary { 7130 x.Flag |= mysql.BinaryFlag 7131 } 7132 $$ = x 7133 } 7134 | "ENUM" '(' StringList ')' OptCharset OptCollate 7135 { 7136 x := types.NewFieldType(mysql.TypeEnum) 7137 x.Elems = $3.([]string) 7138 x.Charset = $5.(string) 7139 x.Collate = $6.(string) 7140 $$ = x 7141 } 7142 | "SET" '(' StringList ')' OptCharset OptCollate 7143 { 7144 x := types.NewFieldType(mysql.TypeSet) 7145 x.Elems = $3.([]string) 7146 x.Charset = $5.(string) 7147 x.Collate = $6.(string) 7148 $$ = x 7149 } 7150 | "JSON" 7151 { 7152 x := types.NewFieldType(mysql.TypeJSON) 7153 x.Decimal = 0 7154 x.Charset = mysql.CharsetBin 7155 x.Collate = mysql.CollationBin 7156 $$ = x 7157 } 7158 7159 NationalOpt: 7160 {} 7161 | "NATIONAL" 7162 7163 Varchar: 7164 "NATIONAL" "VARCHAR" 7165 | "VARCHAR" 7166 | "NVARCHAR" 7167 7168 7169 BlobType: 7170 "TINYBLOB" 7171 { 7172 x := types.NewFieldType(mysql.TypeTinyBlob) 7173 $$ = x 7174 } 7175 | "BLOB" OptFieldLen 7176 { 7177 x := types.NewFieldType(mysql.TypeBlob) 7178 x.Flen = $2.(int) 7179 $$ = x 7180 } 7181 | "MEDIUMBLOB" 7182 { 7183 x := types.NewFieldType(mysql.TypeMediumBlob) 7184 $$ = x 7185 } 7186 | "LONGBLOB" 7187 { 7188 x := types.NewFieldType(mysql.TypeLongBlob) 7189 $$ = x 7190 } 7191 7192 TextType: 7193 "TINYTEXT" 7194 { 7195 x := types.NewFieldType(mysql.TypeTinyBlob) 7196 $$ = x 7197 7198 } 7199 | "TEXT" OptFieldLen 7200 { 7201 x := types.NewFieldType(mysql.TypeBlob) 7202 x.Flen = $2.(int) 7203 $$ = x 7204 } 7205 | "MEDIUMTEXT" 7206 { 7207 x := types.NewFieldType(mysql.TypeMediumBlob) 7208 $$ = x 7209 } 7210 | "LONGTEXT" 7211 { 7212 x := types.NewFieldType(mysql.TypeLongBlob) 7213 $$ = x 7214 } 7215 | "LONG" "VARCHAR" 7216 { 7217 x := types.NewFieldType(mysql.TypeMediumBlob) 7218 $$ = x 7219 } 7220 7221 7222 DateAndTimeType: 7223 "DATE" 7224 { 7225 x := types.NewFieldType(mysql.TypeDate) 7226 $$ = x 7227 } 7228 | "DATETIME" OptFieldLen 7229 { 7230 x := types.NewFieldType(mysql.TypeDatetime) 7231 x.Flen = mysql.MaxDatetimeWidthNoFsp 7232 x.Decimal = $2.(int) 7233 if x.Decimal > 0 { 7234 x.Flen = x.Flen + 1 + x.Decimal 7235 } 7236 $$ = x 7237 } 7238 | "TIMESTAMP" OptFieldLen 7239 { 7240 x := types.NewFieldType(mysql.TypeTimestamp) 7241 x.Flen = mysql.MaxDatetimeWidthNoFsp 7242 x.Decimal = $2.(int) 7243 if x.Decimal > 0 { 7244 x.Flen = x.Flen + 1 + x.Decimal 7245 } 7246 $$ = x 7247 } 7248 | "TIME" OptFieldLen 7249 { 7250 x := types.NewFieldType(mysql.TypeDuration) 7251 x.Flen = mysql.MaxDurationWidthNoFsp 7252 x.Decimal = $2.(int) 7253 if x.Decimal > 0 { 7254 x.Flen = x.Flen + 1 + x.Decimal 7255 } 7256 $$ = x 7257 } 7258 | "YEAR" OptFieldLen FieldOpts 7259 { 7260 x := types.NewFieldType(mysql.TypeYear) 7261 x.Flen = $2.(int) 7262 if x.Flen != types.UnspecifiedLength && x.Flen != 4 { 7263 yylex.Errorf("Supports only YEAR or YEAR(4) column.") 7264 return -1 7265 } 7266 $$ = x 7267 } 7268 7269 FieldLen: 7270 '(' LengthNum ')' 7271 { 7272 $$ = int($2.(uint64)) 7273 } 7274 7275 OptFieldLen: 7276 { 7277 $$ = types.UnspecifiedLength 7278 } 7279 | FieldLen 7280 { 7281 $$ = $1.(int) 7282 } 7283 7284 FieldOpt: 7285 "UNSIGNED" 7286 { 7287 $$ = &ast.TypeOpt{IsUnsigned: true} 7288 } 7289 | "SIGNED" 7290 { 7291 $$ = &ast.TypeOpt{IsUnsigned: false} 7292 } 7293 | "ZEROFILL" 7294 { 7295 $$ = &ast.TypeOpt{IsZerofill: true, IsUnsigned: true} 7296 } 7297 7298 FieldOpts: 7299 { 7300 $$ = []*ast.TypeOpt{} 7301 } 7302 | FieldOpts FieldOpt 7303 { 7304 $$ = append($1.([]*ast.TypeOpt), $2.(*ast.TypeOpt)) 7305 } 7306 7307 FloatOpt: 7308 { 7309 $$ = &ast.FloatOpt{Flen: types.UnspecifiedLength, Decimal: types.UnspecifiedLength} 7310 } 7311 | FieldLen 7312 { 7313 $$ = &ast.FloatOpt{Flen: $1.(int), Decimal: types.UnspecifiedLength} 7314 } 7315 | Precision 7316 { 7317 $$ = $1.(*ast.FloatOpt) 7318 } 7319 7320 Precision: 7321 '(' LengthNum ',' LengthNum ')' 7322 { 7323 $$ = &ast.FloatOpt{Flen: int($2.(uint64)), Decimal: int($4.(uint64))} 7324 } 7325 7326 OptBinMod: 7327 { 7328 $$ = false 7329 } 7330 | "BINARY" 7331 { 7332 $$ = true 7333 } 7334 7335 OptBinary: 7336 { 7337 $$ = &ast.OptBinary{ 7338 IsBinary: false, 7339 Charset: "", 7340 } 7341 } 7342 | "BINARY" OptCharset 7343 { 7344 $$ = &ast.OptBinary{ 7345 IsBinary: true, 7346 Charset: $2.(string), 7347 } 7348 } 7349 | CharsetKw CharsetName OptBinMod 7350 { 7351 $$ = &ast.OptBinary{ 7352 IsBinary: $3.(bool), 7353 Charset: $2.(string), 7354 } 7355 } 7356 7357 OptCharset: 7358 { 7359 $$ = "" 7360 } 7361 | CharsetKw CharsetName 7362 { 7363 $$ = $2.(string) 7364 } 7365 7366 CharsetKw: 7367 "CHARACTER" "SET" 7368 | "CHARSET" 7369 7370 OptCollate: 7371 { 7372 $$ = "" 7373 } 7374 | "COLLATE" StringName 7375 { 7376 $$ = $2.(string) 7377 } 7378 7379 StringList: 7380 stringLit 7381 { 7382 $$ = []string{$1} 7383 } 7384 | StringList ',' stringLit 7385 { 7386 $$ = append($1.([]string), $3) 7387 } 7388 7389 StringName: 7390 stringLit 7391 { 7392 $$ = $1 7393 } 7394 | Identifier 7395 { 7396 $$ = $1 7397 } 7398 7399 /*********************************************************************************** 7400 * Update Statement 7401 * See https://dev.mysql.com/doc/refman/5.7/en/update.html 7402 ***********************************************************************************/ 7403 UpdateStmt: 7404 "UPDATE" TableOptimizerHints PriorityOpt IgnoreOptional TableRef "SET" AssignmentList WhereClauseOptional OrderByOptional LimitClause 7405 { 7406 var refs *ast.Join 7407 if x, ok := $5.(*ast.Join); ok { 7408 refs = x 7409 } else { 7410 refs = &ast.Join{Left: $5.(ast.ResultSetNode)} 7411 } 7412 st := &ast.UpdateStmt{ 7413 Priority: $3.(mysql.PriorityEnum), 7414 TableRefs: &ast.TableRefsClause{TableRefs: refs}, 7415 List: $7.([]*ast.Assignment), 7416 IgnoreErr: $4.(bool), 7417 } 7418 if $2 != nil { 7419 st.TableHints = $2.([]*ast.TableOptimizerHint) 7420 } 7421 if $8 != nil { 7422 st.Where = $8.(ast.ExprNode) 7423 } 7424 if $9 != nil { 7425 st.Order = $9.(*ast.OrderByClause) 7426 } 7427 if $10 != nil { 7428 st.Limit = $10.(*ast.Limit) 7429 } 7430 $$ = st 7431 } 7432 | "UPDATE" TableOptimizerHints PriorityOpt IgnoreOptional TableRefs "SET" AssignmentList WhereClauseOptional 7433 { 7434 st := &ast.UpdateStmt{ 7435 Priority: $3.(mysql.PriorityEnum), 7436 TableRefs: &ast.TableRefsClause{TableRefs: $5.(*ast.Join)}, 7437 List: $7.([]*ast.Assignment), 7438 IgnoreErr: $4.(bool), 7439 } 7440 if $2 != nil { 7441 st.TableHints = $2.([]*ast.TableOptimizerHint) 7442 } 7443 if $8 != nil { 7444 st.Where = $8.(ast.ExprNode) 7445 } 7446 $$ = st 7447 } 7448 7449 UseStmt: 7450 "USE" DBName 7451 { 7452 $$ = &ast.UseStmt{DBName: $2.(string)} 7453 } 7454 7455 WhereClause: 7456 "WHERE" Expression 7457 { 7458 $$ = $2 7459 } 7460 7461 WhereClauseOptional: 7462 { 7463 $$ = nil 7464 } 7465 | WhereClause 7466 { 7467 $$ = $1 7468 } 7469 7470 CommaOpt: 7471 {} 7472 | ',' 7473 {} 7474 7475 /************************************************************************************ 7476 * Account Management Statements 7477 * https://dev.mysql.com/doc/refman/5.7/en/account-management-sql.html 7478 ************************************************************************************/ 7479 CreateUserStmt: 7480 "CREATE" "USER" IfNotExists UserSpecList 7481 { 7482 // See https://dev.mysql.com/doc/refman/5.7/en/create-user.html 7483 $$ = &ast.CreateUserStmt{ 7484 IsCreateRole: false, 7485 IfNotExists: $3.(bool), 7486 Specs: $4.([]*ast.UserSpec), 7487 } 7488 } 7489 7490 CreateRoleStmt: 7491 "CREATE" "ROLE" IfNotExists RoleSpecList 7492 { 7493 // See https://dev.mysql.com/doc/refman/8.0/en/create-role.html 7494 $$ = &ast.CreateUserStmt{ 7495 IsCreateRole: true, 7496 IfNotExists: $3.(bool), 7497 Specs: $4.([]*ast.UserSpec), 7498 } 7499 } 7500 7501 /* See http://dev.mysql.com/doc/refman/5.7/en/alter-user.html */ 7502 AlterUserStmt: 7503 "ALTER" "USER" IfExists UserSpecList 7504 { 7505 $$ = &ast.AlterUserStmt{ 7506 IfExists: $3.(bool), 7507 Specs: $4.([]*ast.UserSpec), 7508 } 7509 } 7510 | "ALTER" "USER" IfExists "USER" '(' ')' "IDENTIFIED" "BY" AuthString 7511 { 7512 auth := &ast.AuthOption { 7513 AuthString: $9.(string), 7514 ByAuthString: true, 7515 } 7516 $$ = &ast.AlterUserStmt{ 7517 IfExists: $3.(bool), 7518 CurrentAuth: auth, 7519 } 7520 } 7521 7522 UserSpec: 7523 Username AuthOption 7524 { 7525 userSpec := &ast.UserSpec{ 7526 User: $1.(*auth.UserIdentity), 7527 } 7528 if $2 != nil { 7529 userSpec.AuthOpt = $2.(*ast.AuthOption) 7530 } 7531 $$ = userSpec 7532 } 7533 7534 UserSpecList: 7535 UserSpec 7536 { 7537 $$ = []*ast.UserSpec{$1.(*ast.UserSpec)} 7538 } 7539 | UserSpecList ',' UserSpec 7540 { 7541 $$ = append($1.([]*ast.UserSpec), $3.(*ast.UserSpec)) 7542 } 7543 7544 AuthOption: 7545 { 7546 $$ = nil 7547 } 7548 | "IDENTIFIED" "BY" AuthString 7549 { 7550 $$ = &ast.AuthOption { 7551 AuthString: $3.(string), 7552 ByAuthString: true, 7553 } 7554 } 7555 | "IDENTIFIED" "WITH" StringName 7556 { 7557 $$ = nil 7558 } 7559 | "IDENTIFIED" "WITH" StringName "BY" AuthString 7560 { 7561 $$ = &ast.AuthOption { 7562 AuthString: $5.(string), 7563 ByAuthString: true, 7564 } 7565 } 7566 | "IDENTIFIED" "WITH" StringName "AS" HashString 7567 { 7568 $$ = &ast.AuthOption{ 7569 HashString: $5.(string), 7570 } 7571 } 7572 | "IDENTIFIED" "BY" "PASSWORD" HashString 7573 { 7574 $$ = &ast.AuthOption{ 7575 HashString: $4.(string), 7576 } 7577 } 7578 7579 HashString: 7580 stringLit 7581 { 7582 $$ = $1 7583 } 7584 7585 RoleSpec: 7586 Rolename 7587 { 7588 role := $1.(*auth.RoleIdentity) 7589 roleSpec := &ast.UserSpec{ 7590 User: &auth.UserIdentity { 7591 Username: role.Username, 7592 Hostname: role.Hostname, 7593 }, 7594 IsRole: true, 7595 } 7596 $$ = roleSpec 7597 } 7598 7599 RoleSpecList: 7600 RoleSpec 7601 { 7602 $$ = []*ast.UserSpec{$1.(*ast.UserSpec)} 7603 } 7604 | RoleSpecList ',' RoleSpec 7605 { 7606 $$ = append($1.([]*ast.UserSpec), $3.(*ast.UserSpec)) 7607 } 7608 7609 /******************************************************************* 7610 * 7611 * Create Binding Statement 7612 * 7613 * Example: 7614 * CREATE GLOBAL BINDING FOR select Col1,Col2 from table USING select Col1,Col2 from table use index(Col1) 7615 *******************************************************************/ 7616 CreateBindingStmt: 7617 "CREATE" GlobalScope "BINDING" "FOR" SelectStmt "USING" SelectStmt 7618 { 7619 startOffset := parser.startOffset(&yyS[yypt-2]) 7620 endOffset := parser.startOffset(&yyS[yypt-1]) 7621 selStmt := $5.(*ast.SelectStmt) 7622 selStmt.SetText(strings.TrimSpace(parser.src[startOffset:endOffset])) 7623 7624 startOffset = parser.startOffset(&yyS[yypt]) 7625 hintedSelStmt := $7.(*ast.SelectStmt) 7626 hintedSelStmt.SetText(strings.TrimSpace(parser.src[startOffset:])) 7627 7628 x := &ast.CreateBindingStmt { 7629 OriginSel: selStmt, 7630 HintedSel: hintedSelStmt, 7631 GlobalScope: $2.(bool), 7632 } 7633 7634 $$ = x 7635 } 7636 /******************************************************************* 7637 * 7638 * Drop Binding Statement 7639 * 7640 * Example: 7641 * DROP GLOBAL BINDING FOR select Col1,Col2 from table 7642 *******************************************************************/ 7643 DropBindingStmt: 7644 "DROP" GlobalScope "BINDING" "FOR" SelectStmt 7645 { 7646 startOffset := parser.startOffset(&yyS[yypt]) 7647 selStmt := $5.(*ast.SelectStmt) 7648 selStmt.SetText(strings.TrimSpace(parser.src[startOffset:])) 7649 7650 x := &ast.DropBindingStmt { 7651 OriginSel: selStmt, 7652 GlobalScope: $2.(bool), 7653 } 7654 7655 $$ = x 7656 } 7657 7658 /************************************************************************************* 7659 * Grant statement 7660 * See https://dev.mysql.com/doc/refman/5.7/en/grant.html 7661 *************************************************************************************/ 7662 GrantStmt: 7663 "GRANT" PrivElemList "ON" ObjectType PrivLevel "TO" UserSpecList WithGrantOptionOpt 7664 { 7665 $$ = &ast.GrantStmt{ 7666 Privs: $2.([]*ast.PrivElem), 7667 ObjectType: $4.(ast.ObjectTypeType), 7668 Level: $5.(*ast.GrantLevel), 7669 Users: $7.([]*ast.UserSpec), 7670 WithGrant: $8.(bool), 7671 } 7672 } 7673 7674 GrantRoleStmt: 7675 "GRANT" RolenameList "TO" UsernameList 7676 { 7677 } 7678 7679 WithGrantOptionOpt: 7680 { 7681 $$ = false 7682 } 7683 | "WITH" "GRANT" "OPTION" 7684 { 7685 $$ = true 7686 } 7687 | "WITH" "MAX_QUERIES_PER_HOUR" NUM 7688 { 7689 $$ = false 7690 } 7691 | "WITH" "MAX_UPDATES_PER_HOUR" NUM 7692 { 7693 $$ = false 7694 } 7695 | "WITH" "MAX_CONNECTIONS_PER_HOUR" NUM 7696 { 7697 $$ = false 7698 } 7699 | "WITH" "MAX_USER_CONNECTIONS" NUM 7700 { 7701 $$ = false 7702 } 7703 7704 PrivElem: 7705 PrivType 7706 { 7707 $$ = &ast.PrivElem{ 7708 Priv: $1.(mysql.PrivilegeType), 7709 } 7710 } 7711 | PrivType '(' ColumnNameList ')' 7712 { 7713 $$ = &ast.PrivElem{ 7714 Priv: $1.(mysql.PrivilegeType), 7715 Cols: $3.([]*ast.ColumnName), 7716 } 7717 } 7718 7719 PrivElemList: 7720 PrivElem 7721 { 7722 $$ = []*ast.PrivElem{$1.(*ast.PrivElem)} 7723 } 7724 | PrivElemList ',' PrivElem 7725 { 7726 $$ = append($1.([]*ast.PrivElem), $3.(*ast.PrivElem)) 7727 } 7728 7729 PrivType: 7730 "ALL" 7731 { 7732 $$ = mysql.AllPriv 7733 } 7734 | "ALL" "PRIVILEGES" 7735 { 7736 $$ = mysql.AllPriv 7737 } 7738 | "ALTER" 7739 { 7740 $$ = mysql.AlterPriv 7741 } 7742 | "CREATE" 7743 { 7744 $$ = mysql.CreatePriv 7745 } 7746 | "CREATE" "USER" 7747 { 7748 $$ = mysql.CreateUserPriv 7749 } 7750 | "TRIGGER" 7751 { 7752 $$ = mysql.TriggerPriv 7753 } 7754 | "DELETE" 7755 { 7756 $$ = mysql.DeletePriv 7757 } 7758 | "DROP" 7759 { 7760 $$ = mysql.DropPriv 7761 } 7762 | "PROCESS" 7763 { 7764 $$ = mysql.ProcessPriv 7765 } 7766 | "EXECUTE" 7767 { 7768 $$ = mysql.ExecutePriv 7769 } 7770 | "INDEX" 7771 { 7772 $$ = mysql.IndexPriv 7773 } 7774 | "INSERT" 7775 { 7776 $$ = mysql.InsertPriv 7777 } 7778 | "SELECT" 7779 { 7780 $$ = mysql.SelectPriv 7781 } 7782 | "SUPER" 7783 { 7784 $$ = mysql.SuperPriv 7785 } 7786 | "SHOW" "DATABASES" 7787 { 7788 $$ = mysql.ShowDBPriv 7789 } 7790 | "UPDATE" 7791 { 7792 $$ = mysql.UpdatePriv 7793 } 7794 | "GRANT" "OPTION" 7795 { 7796 $$ = mysql.GrantPriv 7797 } 7798 | "REFERENCES" 7799 { 7800 $$ = mysql.ReferencesPriv 7801 } 7802 | "REPLICATION" "SLAVE" 7803 { 7804 $$ = mysql.PrivilegeType(0) 7805 } 7806 | "REPLICATION" "CLIENT" 7807 { 7808 $$ = mysql.PrivilegeType(0) 7809 } 7810 | "USAGE" 7811 { 7812 $$ = mysql.PrivilegeType(0) 7813 } 7814 | "RELOAD" 7815 { 7816 $$ = mysql.PrivilegeType(0) 7817 } 7818 | "CREATE" "TEMPORARY" "TABLES" 7819 { 7820 $$ = mysql.PrivilegeType(0) 7821 } 7822 | "LOCK" "TABLES" 7823 { 7824 $$ = mysql.PrivilegeType(0) 7825 } 7826 | "CREATE" "VIEW" 7827 { 7828 $$ = mysql.CreateViewPriv 7829 } 7830 | "SHOW" "VIEW" 7831 { 7832 $$ = mysql.ShowViewPriv 7833 } 7834 | "CREATE" "ROLE" 7835 { 7836 $$ = mysql.CreateRolePriv 7837 } 7838 | "DROP" "ROLE" 7839 { 7840 $$ = mysql.DropRolePriv 7841 } 7842 | "CREATE" "ROUTINE" 7843 { 7844 $$ = mysql.PrivilegeType(0) 7845 } 7846 | "ALTER" "ROUTINE" 7847 { 7848 $$ = mysql.PrivilegeType(0) 7849 } 7850 | "EVENT" 7851 { 7852 $$ = mysql.PrivilegeType(0) 7853 } 7854 7855 ObjectType: 7856 { 7857 $$ = ast.ObjectTypeNone 7858 } 7859 | "TABLE" 7860 { 7861 $$ = ast.ObjectTypeTable 7862 } 7863 7864 PrivLevel: 7865 '*' 7866 { 7867 $$ = &ast.GrantLevel { 7868 Level: ast.GrantLevelDB, 7869 } 7870 } 7871 | '*' '.' '*' 7872 { 7873 $$ = &ast.GrantLevel { 7874 Level: ast.GrantLevelGlobal, 7875 } 7876 } 7877 | Identifier '.' '*' 7878 { 7879 $$ = &ast.GrantLevel { 7880 Level: ast.GrantLevelDB, 7881 DBName: $1, 7882 } 7883 } 7884 | Identifier '.' Identifier 7885 { 7886 $$ = &ast.GrantLevel { 7887 Level: ast.GrantLevelTable, 7888 DBName: $1, 7889 TableName: $3, 7890 } 7891 } 7892 | Identifier 7893 { 7894 $$ = &ast.GrantLevel { 7895 Level: ast.GrantLevelTable, 7896 TableName: $1, 7897 } 7898 } 7899 7900 /**************************************RevokeStmt******************************************* 7901 * See https://dev.mysql.com/doc/refman/5.7/en/revoke.html 7902 *******************************************************************************************/ 7903 RevokeStmt: 7904 "REVOKE" PrivElemList "ON" ObjectType PrivLevel "FROM" UserSpecList 7905 { 7906 $$ = &ast.RevokeStmt{ 7907 Privs: $2.([]*ast.PrivElem), 7908 ObjectType: $4.(ast.ObjectTypeType), 7909 Level: $5.(*ast.GrantLevel), 7910 Users: $7.([]*ast.UserSpec), 7911 } 7912 } 7913 7914 RevokeRoleStmt: 7915 "REVOKE" RolenameList "FROM" UsernameList 7916 { 7917 } 7918 7919 /**************************************LoadDataStmt***************************************** 7920 * See https://dev.mysql.com/doc/refman/5.7/en/load-data.html 7921 *******************************************************************************************/ 7922 LoadDataStmt: 7923 "LOAD" "DATA" LocalOpt "INFILE" stringLit "INTO" "TABLE" TableName CharsetOpt Fields Lines IgnoreLines ColumnNameListOptWithBrackets 7924 { 7925 x := &ast.LoadDataStmt{ 7926 Path: $5, 7927 Table: $8.(*ast.TableName), 7928 Columns: $13.([]*ast.ColumnName), 7929 IgnoreLines:$12.(uint64), 7930 } 7931 if $3 != nil { 7932 x.IsLocal = true 7933 } 7934 if $10 != nil { 7935 x.FieldsInfo = $10.(*ast.FieldsClause) 7936 } 7937 if $11 != nil { 7938 x.LinesInfo = $11.(*ast.LinesClause) 7939 } 7940 $$ = x 7941 } 7942 7943 IgnoreLines: 7944 { 7945 $$ = uint64(0) 7946 } 7947 | "IGNORE" NUM "LINES" 7948 { 7949 $$ = getUint64FromNUM($2) 7950 } 7951 7952 CharsetOpt: 7953 {} 7954 | "CHARACTER" "SET" CharsetName 7955 7956 LocalOpt: 7957 { 7958 $$ = nil 7959 } 7960 | "LOCAL" 7961 { 7962 $$ = $1 7963 } 7964 7965 Fields: 7966 { 7967 escape := "\\" 7968 $$ = &ast.FieldsClause{ 7969 Terminated: "\t", 7970 Escaped: escape[0], 7971 } 7972 } 7973 | FieldsOrColumns FieldsTerminated Enclosed Escaped 7974 { 7975 escape := $4.(string) 7976 if escape != "\\" && len(escape) > 1 { 7977 yylex.Errorf("Incorrect arguments %s to ESCAPE", escape) 7978 return 1 7979 } 7980 var enclosed byte 7981 str := $3.(string) 7982 if len(str) > 1 { 7983 yylex.Errorf("Incorrect arguments %s to ENCLOSED", escape) 7984 return 1 7985 }else if len(str) != 0 { 7986 enclosed = str[0] 7987 } 7988 var escaped byte 7989 if len(escape) > 0 { 7990 escaped = escape[0] 7991 } 7992 $$ = &ast.FieldsClause{ 7993 Terminated: $2.(string), 7994 Enclosed: enclosed, 7995 Escaped: escaped, 7996 } 7997 } 7998 7999 FieldsOrColumns: 8000 "FIELDS" | "COLUMNS" 8001 8002 FieldsTerminated: 8003 { 8004 $$ = "\t" 8005 } 8006 | "TERMINATED" "BY" stringLit 8007 { 8008 $$ = $3 8009 } 8010 8011 Enclosed: 8012 { 8013 $$ = "" 8014 } 8015 | "OPTIONALLY" "ENCLOSED" "BY" stringLit 8016 { 8017 $$ = $4 8018 } 8019 | "ENCLOSED" "BY" stringLit 8020 { 8021 $$ = $3 8022 } 8023 8024 Escaped: 8025 { 8026 $$ = "\\" 8027 } 8028 | "ESCAPED" "BY" stringLit 8029 { 8030 $$ = $3 8031 } 8032 8033 Lines: 8034 { 8035 $$ = &ast.LinesClause{Terminated: "\n"} 8036 } 8037 | "LINES" Starting LinesTerminated 8038 { 8039 $$ = &ast.LinesClause{Starting: $2.(string), Terminated: $3.(string)} 8040 } 8041 8042 Starting: 8043 { 8044 $$ = "" 8045 } 8046 | "STARTING" "BY" stringLit 8047 { 8048 $$ = $3 8049 } 8050 8051 LinesTerminated: 8052 { 8053 $$ = "\n" 8054 } 8055 | "TERMINATED" "BY" stringLit 8056 { 8057 $$ = $3 8058 } 8059 8060 8061 /********************************************************************* 8062 * Lock/Unlock Tables 8063 * See http://dev.mysql.com/doc/refman/5.7/en/lock-tables.html 8064 * All the statement leaves empty. This is used to prevent mysqldump error. 8065 *********************************************************************/ 8066 8067 UnlockTablesStmt: 8068 "UNLOCK" TablesTerminalSym {} 8069 8070 LockTablesStmt: 8071 "LOCK" TablesTerminalSym TableLockList 8072 {} 8073 8074 TablesTerminalSym: 8075 "TABLES" 8076 | "TABLE" 8077 8078 TableLock: 8079 TableName LockType 8080 8081 LockType: 8082 "READ" 8083 | "READ" "LOCAL" 8084 | "WRITE" 8085 8086 TableLockList: 8087 TableLock 8088 | TableLockList ',' TableLock 8089 8090 8091 /******************************************************************** 8092 * Kill Statement 8093 * See https://dev.mysql.com/doc/refman/5.7/en/kill.html 8094 *******************************************************************/ 8095 8096 KillStmt: 8097 KillOrKillTiDB NUM 8098 { 8099 $$ = &ast.KillStmt{ 8100 ConnectionID: getUint64FromNUM($2), 8101 TiDBExtension: $1.(bool), 8102 } 8103 } 8104 | KillOrKillTiDB "CONNECTION" NUM 8105 { 8106 $$ = &ast.KillStmt{ 8107 ConnectionID: getUint64FromNUM($3), 8108 TiDBExtension: $1.(bool), 8109 } 8110 } 8111 | KillOrKillTiDB "QUERY" NUM 8112 { 8113 $$ = &ast.KillStmt{ 8114 ConnectionID: getUint64FromNUM($3), 8115 Query: true, 8116 TiDBExtension: $1.(bool), 8117 } 8118 } 8119 8120 KillOrKillTiDB: 8121 "KILL" 8122 { 8123 $$ = false 8124 } 8125 /* KILL TIDB is a special grammar extension in TiDB, it can be used only when 8126 the client connect to TiDB directly, not proxied under LVS. */ 8127 | "KILL" "TIDB" 8128 { 8129 $$ = true 8130 } 8131 8132 /*******************************************************************************************/ 8133 8134 LoadStatsStmt: 8135 "LOAD" "STATS" stringLit 8136 { 8137 $$ = &ast.LoadStatsStmt{ 8138 Path: $3, 8139 } 8140 } 8141 8142 %%