diff options
Diffstat (limited to 'vendor/github.com/pingcap/tidb/parser')
-rw-r--r-- | vendor/github.com/pingcap/tidb/parser/parser.y | 4688 | ||||
-rw-r--r-- | vendor/github.com/pingcap/tidb/parser/scanner.l | 1259 |
2 files changed, 0 insertions, 5947 deletions
diff --git a/vendor/github.com/pingcap/tidb/parser/parser.y b/vendor/github.com/pingcap/tidb/parser/parser.y deleted file mode 100644 index f3642f24ed..0000000000 --- a/vendor/github.com/pingcap/tidb/parser/parser.y +++ /dev/null @@ -1,4688 +0,0 @@ -%{ -// Copyright 2013 The ql Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSES/QL-LICENSE file. - -// Copyright 2015 PingCAP, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// See the License for the specific language governing permissions and -// limitations under the License. - -// Inital yacc source generated by ebnf2y[1] -// at 2013-10-04 23:10:47.861401015 +0200 CEST -// -// $ ebnf2y -o ql.y -oe ql.ebnf -start StatementList -pkg ql -p _ -// -// [1]: http://github.com/cznic/ebnf2y - -package parser - -import ( - "strings" - - "github.com/pingcap/tidb/mysql" - "github.com/pingcap/tidb/ast" - "github.com/pingcap/tidb/model" - "github.com/pingcap/tidb/parser/opcode" - "github.com/pingcap/tidb/util/charset" - "github.com/pingcap/tidb/util/types" -) - -%} - -%union { - offset int // offset - line int - col int - item interface{} - list []interface{} -} - -%token <item> - - /*yy:token "1.%d" */ floatLit "floating-point literal" - /*yy:token "%c" */ identifier "identifier" - /*yy:token "%d" */ intLit "integer literal" - /*yy:token "\"%c\"" */ stringLit "string literal" - /*yy:token "%x" */ hexLit "hexadecimal literal" - /*yy:token "%b" */ bitLit "bit literal" - - - abs "ABS" - add "ADD" - addDate "ADDDATE" - admin "ADMIN" - after "AFTER" - all "ALL" - alter "ALTER" - and "AND" - andand "&&" - andnot "&^" - any "ANY" - as "AS" - asc "ASC" - at "AT" - autoIncrement "AUTO_INCREMENT" - avg "AVG" - avgRowLength "AVG_ROW_LENGTH" - begin "BEGIN" - between "BETWEEN" - both "BOTH" - btree "BTREE" - by "BY" - byteType "BYTE" - caseKwd "CASE" - cast "CAST" - character "CHARACTER" - charsetKwd "CHARSET" - check "CHECK" - checksum "CHECKSUM" - coalesce "COALESCE" - collate "COLLATE" - collation "COLLATION" - column "COLUMN" - columns "COLUMNS" - comment "COMMENT" - commit "COMMIT" - committed "COMMITTED" - compact "COMPACT" - compressed "COMPRESSED" - compression "COMPRESSION" - concat "CONCAT" - concatWs "CONCAT_WS" - connection "CONNECTION" - connectionID "CONNECTION_ID" - constraint "CONSTRAINT" - convert "CONVERT" - count "COUNT" - create "CREATE" - cross "CROSS" - curDate "CURDATE" - currentDate "CURRENT_DATE" - curTime "CUR_TIME" - currentTime "CURRENT_TIME" - currentUser "CURRENT_USER" - database "DATABASE" - databases "DATABASES" - dateAdd "DATE_ADD" - dateSub "DATE_SUB" - day "DAY" - dayname "DAYNAME" - dayofmonth "DAYOFMONTH" - dayofweek "DAYOFWEEK" - dayofyear "DAYOFYEAR" - ddl "DDL" - deallocate "DEALLOCATE" - defaultKwd "DEFAULT" - delayed "DELAYED" - delayKeyWrite "DELAY_KEY_WRITE" - deleteKwd "DELETE" - desc "DESC" - describe "DESCRIBE" - distinct "DISTINCT" - div "DIV" - do "DO" - drop "DROP" - dual "DUAL" - duplicate "DUPLICATE" - dynamic "DYNAMIC" - elseKwd "ELSE" - end "END" - engine "ENGINE" - engines "ENGINES" - enum "ENUM" - eq "=" - escape "ESCAPE" - execute "EXECUTE" - exists "EXISTS" - explain "EXPLAIN" - extract "EXTRACT" - falseKwd "false" - fields "FIELDS" - first "FIRST" - fixed "FIXED" - foreign "FOREIGN" - forKwd "FOR" - foundRows "FOUND_ROWS" - from "FROM" - full "FULL" - fulltext "FULLTEXT" - ge ">=" - global "GLOBAL" - grant "GRANT" - grants "GRANTS" - group "GROUP" - groupConcat "GROUP_CONCAT" - hash "HASH" - having "HAVING" - highPriority "HIGH_PRIORITY" - hour "HOUR" - identified "IDENTIFIED" - ignore "IGNORE" - ifKwd "IF" - ifNull "IFNULL" - in "IN" - index "INDEX" - inner "INNER" - insert "INSERT" - interval "INTERVAL" - into "INTO" - is "IS" - isolation "ISOLATION" - join "JOIN" - key "KEY" - keyBlockSize "KEY_BLOCK_SIZE" - le "<=" - leading "LEADING" - left "LEFT" - length "LENGTH" - level "LEVEL" - like "LIKE" - limit "LIMIT" - local "LOCAL" - locate "LOCATE" - lock "LOCK" - lower "LOWER" - lowPriority "LOW_PRIORITY" - lsh "<<" - max "MAX" - maxRows "MAX_ROWS" - microsecond "MICROSECOND" - min "MIN" - minute "MINUTE" - minRows "MIN_ROWS" - mod "MOD" - mode "MODE" - month "MONTH" - names "NAMES" - national "NATIONAL" - neq "!=" - neqSynonym "<>" - not "NOT" - null "NULL" - nulleq "<=>" - nullIf "NULLIF" - offset "OFFSET" - on "ON" - only "ONLY" - option "OPTION" - or "OR" - order "ORDER" - oror "||" - outer "OUTER" - password "PASSWORD" - placeholder "PLACEHOLDER" - pow "POW" - power "POWER" - prepare "PREPARE" - primary "PRIMARY" - procedure "PROCEDURE" - quarter "QUARTER" - quick "QUICK" - rand "RAND" - read "READ" - redundant "REDUNDANT" - references "REFERENCES" - regexpKwd "REGEXP" - repeat "REPEAT" - repeatable "REPEATABLE" - replace "REPLACE" - right "RIGHT" - rlike "RLIKE" - rollback "ROLLBACK" - row "ROW" - rowFormat "ROW_FORMAT" - rsh ">>" - schema "SCHEMA" - schemas "SCHEMAS" - second "SECOND" - selectKwd "SELECT" - serializable "SERIALIZABLE" - session "SESSION" - set "SET" - share "SHARE" - show "SHOW" - signed "SIGNED" - some "SOME" - start "START" - status "STATUS" - stringType "string" - subDate "SUBDATE" - strcmp "STRCMP" - substring "SUBSTRING" - substringIndex "SUBSTRING_INDEX" - sum "SUM" - sysVar "SYS_VAR" - sysDate "SYSDATE" - tableKwd "TABLE" - tables "TABLES" - then "THEN" - to "TO" - trailing "TRAILING" - transaction "TRANSACTION" - triggers "TRIGGERS" - trim "TRIM" - trueKwd "true" - truncate "TRUNCATE" - uncommitted "UNCOMMITTED" - underscoreCS "UNDERSCORE_CHARSET" - unknown "UNKNOWN" - union "UNION" - unique "UNIQUE" - unlock "UNLOCK" - unsigned "UNSIGNED" - update "UPDATE" - upper "UPPER" - use "USE" - user "USER" - using "USING" - userVar "USER_VAR" - value "VALUE" - values "VALUES" - variables "VARIABLES" - version "VERSION" - warnings "WARNINGS" - week "WEEK" - weekday "WEEKDAY" - weekofyear "WEEKOFYEAR" - when "WHEN" - where "WHERE" - write "WRITE" - xor "XOR" - yearweek "YEARWEEK" - zerofill "ZEROFILL" - - calcFoundRows "SQL_CALC_FOUND_ROWS" - - currentTs "CURRENT_TIMESTAMP" - localTime "LOCALTIME" - localTs "LOCALTIMESTAMP" - now "NOW" - - tinyIntType "TINYINT" - smallIntType "SMALLINT" - mediumIntType "MEDIUMINT" - intType "INT" - integerType "INTEGER" - bigIntType "BIGINT" - bitType "BIT" - - decimalType "DECIMAL" - numericType "NUMERIC" - floatType "float" - doubleType "DOUBLE" - precisionType "PRECISION" - realType "REAL" - - dateType "DATE" - timeType "TIME" - datetimeType "DATETIME" - timestampType "TIMESTAMP" - yearType "YEAR" - - charType "CHAR" - varcharType "VARCHAR" - binaryType "BINARY" - varbinaryType "VARBINARY" - tinyblobType "TINYBLOB" - blobType "BLOB" - mediumblobType "MEDIUMBLOB" - longblobType "LONGBLOB" - tinytextType "TINYTEXT" - textType "TEXT" - mediumtextType "MEDIUMTEXT" - longtextType "LONGTEXT" - - int16Type "int16" - int24Type "int24" - int32Type "int32" - int64Type "int64" - int8Type "int8" - uintType "uint" - uint16Type "uint16" - uint32Type "uint32" - uint64Type "uint64" - uint8Type "uint8", - float32Type "float32" - float64Type "float64" - boolType "BOOL" - booleanType "BOOLEAN" - - parseExpression "parse expression prefix" - - secondMicrosecond "SECOND_MICROSECOND" - minuteMicrosecond "MINUTE_MICROSECOND" - minuteSecond "MINUTE_SECOND" - hourMicrosecond "HOUR_MICROSECOND" - hourSecond "HOUR_SECOND" - hourMinute "HOUR_MINUTE" - dayMicrosecond "DAY_MICROSECOND" - daySecond "DAY_SECOND" - dayMinute "DAY_MINUTE" - dayHour "DAY_HOUR" - yearMonth "YEAR_MONTH" - -%type <item> - AdminStmt "Check table statement or show ddl statement" - AlterTableStmt "Alter table statement" - AlterTableSpec "Alter table specification" - AlterTableSpecList "Alter table specification list" - AnyOrAll "Any or All for subquery" - Assignment "assignment" - AssignmentList "assignment list" - AssignmentListOpt "assignment list opt" - AuthOption "User auth option" - AuthString "Password string value" - BeginTransactionStmt "BEGIN TRANSACTION statement" - CastType "Cast function target type" - ColumnDef "table column definition" - ColumnName "column name" - ColumnNameList "column name list" - ColumnNameListOpt "column name list opt" - ColumnKeywordOpt "Column keyword or empty" - ColumnSetValue "insert statement set value by column name" - ColumnSetValueList "insert statement set value by column name list" - CommaOpt "optional comma" - CommitStmt "COMMIT statement" - CompareOp "Compare opcode" - ColumnOption "column definition option" - ColumnOptionList "column definition option list" - ColumnOptionListOpt "optional column definition option list" - Constraint "table constraint" - ConstraintElem "table constraint element" - ConstraintKeywordOpt "Constraint Keyword or empty" - CreateDatabaseStmt "Create Database Statement" - CreateIndexStmt "CREATE INDEX statement" - CreateIndexStmtUnique "CREATE INDEX optional UNIQUE clause" - DatabaseOption "CREATE Database specification" - DatabaseOptionList "CREATE Database specification list" - DatabaseOptionListOpt "CREATE Database specification list opt" - CreateTableStmt "CREATE TABLE statement" - CreateUserStmt "CREATE User statement" - CrossOpt "Cross join option" - DateArithOpt "Date arith dateadd or datesub option" - DateArithMultiFormsOpt "Date arith adddate or subdate option" - DateArithInterval "Date arith interval part" - DatabaseSym "DATABASE or SCHEMA" - DBName "Database Name" - DeallocateSym "Deallocate or drop" - DeallocateStmt "Deallocate prepared statement" - Default "DEFAULT clause" - DefaultOpt "optional DEFAULT clause" - DefaultKwdOpt "optional DEFAULT keyword" - DefaultValueExpr "DefaultValueExpr(Now or Signed Literal)" - DeleteFromStmt "DELETE FROM statement" - DistinctOpt "Distinct option" - DoStmt "Do statement" - DropDatabaseStmt "DROP DATABASE statement" - DropIndexStmt "DROP INDEX statement" - DropTableStmt "DROP TABLE statement" - EmptyStmt "empty statement" - EqOpt "= or empty" - EscapedTableRef "escaped table reference" - ExecuteStmt "Execute statement" - ExplainSym "EXPLAIN or DESCRIBE or DESC" - ExplainStmt "EXPLAIN statement" - Expression "expression" - ExpressionList "expression list" - ExpressionListOpt "expression list opt" - ExpressionListList "expression list list" - Factor "expression factor" - PredicateExpr "Predicate expression factor" - Field "field expression" - FieldAsName "Field alias name" - FieldAsNameOpt "Field alias name opt" - FieldList "field expression list" - TableRefsClause "Table references clause" - Function "function expr" - FunctionCallAgg "Function call on aggregate data" - FunctionCallConflict "Function call with reserved keyword as function name" - FunctionCallKeyword "Function call with keyword as function name" - FunctionCallNonKeyword "Function call with nonkeyword as function name" - FunctionNameConflict "Built-in function call names which are conflict with keywords" - FuncDatetimePrec "Function datetime precision" - GlobalScope "The scope of variable" - GrantStmt "Grant statement" - GroupByClause "GROUP BY clause" - HashString "Hashed string" - HavingClause "HAVING clause" - IfExists "If Exists" - IfNotExists "If Not Exists" - IgnoreOptional "IGNORE or empty" - IndexColName "Index column name" - IndexColNameList "List of index column name" - IndexName "index name" - IndexOption "Index Option" - IndexType "index type" - IndexTypeOpt "Optional index type" - InsertIntoStmt "INSERT INTO statement" - InsertValues "Rest part of INSERT/REPLACE INTO statement" - IntoOpt "INTO or EmptyString" - IsolationLevel "Isolation level" - JoinTable "join table" - JoinType "join type" - KeyOrIndex "{KEY|INDEX}" - LikeEscapeOpt "like escape option" - LimitClause "LIMIT clause" - Literal "literal value" - LockTablesStmt "Lock tables statement" - LockType "Table locks type" - logAnd "logical and operator" - logOr "logical or operator" - LowPriorityOptional "LOW_PRIORITY or empty" - name "name" - NationalOpt "National option" - NotOpt "optional NOT" - NowSym "CURRENT_TIMESTAMP/LOCALTIME/LOCALTIMESTAMP/NOW" - NumLiteral "Num/Int/Float/Decimal Literal" - ObjectType "Grant statement object type" - OnDuplicateKeyUpdate "ON DUPLICATE KEY UPDATE value list" - Operand "operand" - OptFull "Full or empty" - OptInteger "Optional Integer keyword" - Order "ORDER BY clause optional collation specification" - OrderBy "ORDER BY clause" - ByItem "BY item" - OrderByOptional "Optional ORDER BY clause optional" - ByList "BY list" - OuterOpt "optional OUTER clause" - QuickOptional "QUICK or empty" - PasswordOpt "Password option" - ColumnPosition "Column position [First|After ColumnName]" - PreparedStmt "PreparedStmt" - PrepareSQL "Prepare statement sql string" - PrimaryExpression "primary expression" - PrimaryFactor "primary expression factor" - Priority "insert statement priority" - PrivElem "Privilege element" - PrivElemList "Privilege element list" - PrivLevel "Privilege scope" - PrivType "Privilege type" - ReferDef "Reference definition" - RegexpSym "REGEXP or RLIKE" - ReplaceIntoStmt "REPLACE INTO statement" - ReplacePriority "replace statement priority" - RollbackStmt "ROLLBACK statement" - RowFormat "Row format option" - SelectLockOpt "FOR UPDATE or LOCK IN SHARE MODE," - SelectStmt "SELECT statement" - SelectStmtCalcFoundRows "SELECT statement optional SQL_CALC_FOUND_ROWS" - SelectStmtDistinct "SELECT statement optional DISTINCT clause" - SelectStmtFieldList "SELECT statement field list" - SelectStmtLimit "SELECT statement optional LIMIT clause" - SelectStmtOpts "Select statement options" - SelectStmtGroup "SELECT statement optional GROUP BY clause" - SetStmt "Set variable statement" - ShowStmt "Show engines/databases/tables/columns/warnings/status statement" - ShowTargetFilterable "Show target that can be filtered by WHERE or LIKE" - ShowDatabaseNameOpt "Show tables/columns statement database name option" - ShowTableAliasOpt "Show table alias option" - ShowLikeOrWhereOpt "Show like or where clause option" - SignedLiteral "Literal or NumLiteral with sign" - Statement "statement" - StatementList "statement list" - StringName "string literal or identifier" - StringList "string list" - ExplainableStmt "explainable statement" - SubSelect "Sub Select" - Symbol "Constraint Symbol" - SystemVariable "System defined variable name" - TableAsName "table alias name" - TableAsNameOpt "table alias name optional" - TableElement "table definition element" - TableElementList "table definition element list" - TableFactor "table factor" - TableLock "Table name and lock type" - TableLockList "Table lock list" - TableName "Table name" - TableNameList "Table name list" - TableOption "create table option" - TableOptionList "create table option list" - TableOptionListOpt "create table option list opt" - TableRef "table reference" - TableRefs "table references" - TimeUnit "Time unit" - TransactionChar "Transaction characteristic" - TransactionChars "Transaction characteristic list" - TrimDirection "Trim string direction" - TruncateTableStmt "TRANSACTION TABLE statement" - UnionOpt "Union Option(empty/ALL/DISTINCT)" - UnionStmt "Union select state ment" - UnionClauseList "Union select clause list" - UnionSelect "Union (select) item" - UnlockTablesStmt "Unlock tables statement" - UpdateStmt "UPDATE statement" - Username "Username" - UserSpec "Username and auth option" - UserSpecList "Username and auth option list" - UserVariable "User defined variable name" - UserVariableList "User defined variable name list" - UseStmt "USE statement" - ValueSym "Value or Values" - VariableAssignment "set variable value" - VariableAssignmentList "set variable value list" - Variable "User or system variable" - WhereClause "WHERE clause" - WhereClauseOptional "Optinal WHERE clause" - - Identifier "identifier or unreserved keyword" - UnReservedKeyword "MySQL unreserved keywords" - NotKeywordToken "Tokens not mysql keyword but treated specially" - - WhenClause "When clause" - WhenClauseList "When clause list" - ElseOpt "Optional else clause" - ExpressionOpt "Optional expression" - - Type "Types" - - NumericType "Numeric types" - IntegerType "Integer Types types" - FixedPointType "Exact value types" - FloatingPointType "Approximate value types" - BitValueType "bit value types" - - StringType "String types" - BlobType "Blob types" - TextType "Text types" - - DateAndTimeType "Date and Time types" - - OptFieldLen "Field length or empty" - FieldLen "Field length" - FieldOpts "Field type definition option list" - FieldOpt "Field type definition option" - FloatOpt "Floating-point type option" - Precision "Floating-point precision option" - OptBinary "Optional BINARY" - CharsetKw "charset or charater set" - OptCharset "Optional Character setting" - OptCollate "Optional Collate setting" - NUM "numbers" - LengthNum "Field length num(uint64)" - -%token tableRefPriority - -%precedence lowerThanCalcFoundRows -%precedence calcFoundRows - -%precedence lowerThanSetKeyword -%precedence set - -%precedence lowerThanInsertValues -%precedence insertValues - -%left join inner cross left right full -/* A dummy token to force the priority of TableRef production in a join. */ -%left tableRefPriority -%precedence on -%left oror or -%left xor -%left andand and -%left between -%precedence lowerThanEq -%left eq ge le neq neqSynonym '>' '<' is like in -%left '|' -%left '&' -%left rsh lsh -%left '-' '+' -%left '*' '/' '%' div mod -%left '^' -%left '~' neg -%right not -%right collate - -%precedence lowerThanLeftParen -%precedence '(' -%precedence lowerThanQuick -%precedence quick -%precedence lowerThanEscape -%precedence escape -%precedence lowerThanComma -%precedence ',' - -%start Start - -%% - -Start: - StatementList -| parseExpression Expression - { - yylex.(*lexer).expr = $2.(ast.ExprNode) - } - -/**************************************AlterTableStmt*************************************** - * See: https://dev.mysql.com/doc/refman/5.7/en/alter-table.html - *******************************************************************************************/ -AlterTableStmt: - "ALTER" IgnoreOptional "TABLE" TableName AlterTableSpecList - { - $$ = &ast.AlterTableStmt{ - Table: $4.(*ast.TableName), - Specs: $5.([]*ast.AlterTableSpec), - } - } - -AlterTableSpec: - TableOptionListOpt - { - $$ = &ast.AlterTableSpec{ - Tp: ast.AlterTableOption, - Options:$1.([]*ast.TableOption), - } - } -| "ADD" ColumnKeywordOpt ColumnDef ColumnPosition - { - $$ = &ast.AlterTableSpec{ - Tp: ast.AlterTableAddColumn, - Column: $3.(*ast.ColumnDef), - Position: $4.(*ast.ColumnPosition), - } - } -| "ADD" Constraint - { - constraint := $2.(*ast.Constraint) - $$ = &ast.AlterTableSpec{ - Tp: ast.AlterTableAddConstraint, - Constraint: constraint, - } - } -| "DROP" ColumnKeywordOpt ColumnName - { - $$ = &ast.AlterTableSpec{ - Tp: ast.AlterTableDropColumn, - DropColumn: $3.(*ast.ColumnName), - } - } -| "DROP" "PRIMARY" "KEY" - { - $$ = &ast.AlterTableSpec{Tp: ast.AlterTableDropPrimaryKey} - } -| "DROP" KeyOrIndex IndexName - { - $$ = &ast.AlterTableSpec{ - Tp: ast.AlterTableDropIndex, - Name: $3.(string), - } - } -| "DROP" "FOREIGN" "KEY" Symbol - { - $$ = &ast.AlterTableSpec{ - Tp: ast.AlterTableDropForeignKey, - Name: $4.(string), - } - } - -KeyOrIndex: - "KEY"|"INDEX" - -ColumnKeywordOpt: - {} -| "COLUMN" - -ColumnPosition: - { - $$ = &ast.ColumnPosition{Tp: ast.ColumnPositionNone} - } -| "FIRST" - { - $$ = &ast.ColumnPosition{Tp: ast.ColumnPositionFirst} - } -| "AFTER" ColumnName - { - $$ = &ast.ColumnPosition{ - Tp: ast.ColumnPositionAfter, - RelativeColumn: $2.(*ast.ColumnName), - } - } - -AlterTableSpecList: - AlterTableSpec - { - $$ = []*ast.AlterTableSpec{$1.(*ast.AlterTableSpec)} - } -| AlterTableSpecList ',' AlterTableSpec - { - $$ = append($1.([]*ast.AlterTableSpec), $3.(*ast.AlterTableSpec)) - } - -ConstraintKeywordOpt: - { - $$ = nil - } -| "CONSTRAINT" - { - $$ = nil - } -| "CONSTRAINT" Symbol - { - $$ = $2.(string) - } - -Symbol: - Identifier - -/*******************************************************************************************/ -Assignment: - ColumnName eq Expression - { - $$ = &ast.Assignment{Column: $1.(*ast.ColumnName), Expr:$3.(ast.ExprNode)} - } - -AssignmentList: - Assignment - { - $$ = []*ast.Assignment{$1.(*ast.Assignment)} - } -| AssignmentList ',' Assignment - { - $$ = append($1.([]*ast.Assignment), $3.(*ast.Assignment)) - } - -AssignmentListOpt: - /* EMPTY */ - { - $$ = []*ast.Assignment{} - } -| AssignmentList - -BeginTransactionStmt: - "BEGIN" - { - $$ = &ast.BeginStmt{} - } -| "START" "TRANSACTION" - { - $$ = &ast.BeginStmt{} - } - -ColumnDef: - ColumnName Type ColumnOptionListOpt - { - $$ = &ast.ColumnDef{Name: $1.(*ast.ColumnName), Tp: $2.(*types.FieldType), Options: $3.([]*ast.ColumnOption)} - } - -ColumnName: - Identifier - { - $$ = &ast.ColumnName{Name: model.NewCIStr($1.(string))} - } -| Identifier '.' Identifier - { - $$ = &ast.ColumnName{Table: model.NewCIStr($1.(string)), Name: model.NewCIStr($3.(string))} - } -| Identifier '.' Identifier '.' Identifier - { - $$ = &ast.ColumnName{Schema: model.NewCIStr($1.(string)), Table: model.NewCIStr($3.(string)), Name: model.NewCIStr($5.(string))} - } - -ColumnNameList: - ColumnName - { - $$ = []*ast.ColumnName{$1.(*ast.ColumnName)} - } -| ColumnNameList ',' ColumnName - { - $$ = append($1.([]*ast.ColumnName), $3.(*ast.ColumnName)) - } - -ColumnNameListOpt: - /* EMPTY */ - { - $$ = []*ast.ColumnName{} - } -| ColumnNameList - { - $$ = $1.([]*ast.ColumnName) - } - -CommitStmt: - "COMMIT" - { - $$ = &ast.CommitStmt{} - } - -ColumnOption: - "NOT" "NULL" - { - $$ = &ast.ColumnOption{Tp: ast.ColumnOptionNotNull} - } -| "NULL" - { - $$ = &ast.ColumnOption{Tp: ast.ColumnOptionNull} - } -| "AUTO_INCREMENT" - { - $$ = &ast.ColumnOption{Tp: ast.ColumnOptionAutoIncrement} - } -| "PRIMARY" "KEY" - { - $$ = &ast.ColumnOption{Tp: ast.ColumnOptionPrimaryKey} - } -| "UNIQUE" - { - $$ = &ast.ColumnOption{Tp: ast.ColumnOptionUniq} - } -| "UNIQUE" "KEY" - { - $$ = &ast.ColumnOption{Tp: ast.ColumnOptionUniqKey} - } -| "DEFAULT" DefaultValueExpr - { - $$ = &ast.ColumnOption{Tp: ast.ColumnOptionDefaultValue, Expr: $2.(ast.ExprNode)} - } -| "ON" "UPDATE" NowSym - { - nowFunc := &ast.FuncCallExpr{FnName: model.NewCIStr("CURRENT_TIMESTAMP")} - $$ = &ast.ColumnOption{Tp: ast.ColumnOptionOnUpdate, Expr: nowFunc} - } -| "COMMENT" stringLit - { - $$ = &ast.ColumnOption{Tp: ast.ColumnOptionComment} - } -| "CHECK" '(' Expression ')' - { - // See: https://dev.mysql.com/doc/refman/5.7/en/create-table.html - // The CHECK clause is parsed but ignored by all storage engines. - $$ = &ast.ColumnOption{} - } - -ColumnOptionList: - ColumnOption - { - $$ = []*ast.ColumnOption{$1.(*ast.ColumnOption)} - } -| ColumnOptionList ColumnOption - { - $$ = append($1.([]*ast.ColumnOption), $2.(*ast.ColumnOption)) - } - -ColumnOptionListOpt: - { - $$ = []*ast.ColumnOption{} - } -| ColumnOptionList - { - $$ = $1.([]*ast.ColumnOption) - } - -ConstraintElem: - "PRIMARY" "KEY" IndexTypeOpt '(' IndexColNameList ')' IndexOption - { - c := &ast.Constraint{ - Tp: ast.ConstraintPrimaryKey, - Keys: $5.([]*ast.IndexColName), - } - if $7 != nil { - c.Option = $7.(*ast.IndexOption) - } - if $3 != nil { - if c.Option == nil { - c.Option = &ast.IndexOption{} - } - c.Option.Tp = $3.(model.IndexType) - } - $$ = c - } -| "FULLTEXT" "KEY" IndexName '(' IndexColNameList ')' IndexOption - { - c := &ast.Constraint{ - Tp: ast.ConstraintFulltext, - Keys: $5.([]*ast.IndexColName), - Name: $3.(string), - } - if $7 != nil { - c.Option = $7.(*ast.IndexOption) - } - $$ = c - } -| "INDEX" IndexName IndexTypeOpt '(' IndexColNameList ')' IndexOption - { - c := &ast.Constraint{ - Tp: ast.ConstraintIndex, - Keys: $5.([]*ast.IndexColName), - Name: $2.(string), - } - if $7 != nil { - c.Option = $7.(*ast.IndexOption) - } - if $3 != nil { - if c.Option == nil { - c.Option = &ast.IndexOption{} - } - c.Option.Tp = $3.(model.IndexType) - } - $$ = c - } -| "KEY" IndexName IndexTypeOpt '(' IndexColNameList ')' IndexOption - { - c := &ast.Constraint{ - Tp: ast.ConstraintKey, - Keys: $5.([]*ast.IndexColName), - Name: $2.(string), - } - if $7 != nil { - c.Option = $7.(*ast.IndexOption) - } - if $3 != nil { - if c.Option == nil { - c.Option = &ast.IndexOption{} - } - c.Option.Tp = $3.(model.IndexType) - } - $$ = c - } -| "UNIQUE" IndexName IndexTypeOpt '(' IndexColNameList ')' IndexOption - { - c := &ast.Constraint{ - Tp: ast.ConstraintUniq, - Keys: $5.([]*ast.IndexColName), - Name: $2.(string), - } - if $7 != nil { - c.Option = $7.(*ast.IndexOption) - } - if $3 != nil { - if c.Option == nil { - c.Option = &ast.IndexOption{} - } - c.Option.Tp = $3.(model.IndexType) - } - $$ = c - } -| "UNIQUE" "INDEX" IndexName IndexTypeOpt '(' IndexColNameList ')' IndexOption - { - c := &ast.Constraint{ - Tp: ast.ConstraintUniqIndex, - Keys: $6.([]*ast.IndexColName), - Name: $3.(string), - } - if $8 != nil { - c.Option = $8.(*ast.IndexOption) - } - if $4 != nil { - if c.Option == nil { - c.Option = &ast.IndexOption{} - } - c.Option.Tp = $4.(model.IndexType) - } - $$ = c - } -| "UNIQUE" "KEY" IndexName IndexTypeOpt '(' IndexColNameList ')' IndexOption - { - c := &ast.Constraint{ - Tp: ast.ConstraintUniqKey, - Keys: $6.([]*ast.IndexColName), - Name: $3.(string), - } - if $8 != nil { - c.Option = $8.(*ast.IndexOption) - } - if $4 != nil { - if c.Option == nil { - c.Option = &ast.IndexOption{} - } - c.Option.Tp = $4.(model.IndexType) - } - $$ = c - } -| "FOREIGN" "KEY" IndexName '(' IndexColNameList ')' ReferDef - { - $$ = &ast.Constraint{ - Tp: ast.ConstraintForeignKey, - Keys: $5.([]*ast.IndexColName), - Name: $3.(string), - Refer: $7.(*ast.ReferenceDef), - } - } - -ReferDef: - "REFERENCES" TableName '(' IndexColNameList ')' - { - $$ = &ast.ReferenceDef{Table: $2.(*ast.TableName), IndexColNames: $4.([]*ast.IndexColName)} - } - -/* - * The DEFAULT clause specifies a default value for a column. - * With one exception, the default value must be a constant; - * it cannot be a function or an expression. This means, for example, - * that you cannot set the default for a date column to be the value of - * a function such as NOW() or CURRENT_DATE. The exception is that you - * can specify CURRENT_TIMESTAMP as the default for a TIMESTAMP or DATETIME column. - * - * See: http://dev.mysql.com/doc/refman/5.7/en/create-table.html - * https://github.com/mysql/mysql-server/blob/5.7/sql/sql_yacc.yy#L6832 - */ -DefaultValueExpr: - NowSym - { - $$ = &ast.FuncCallExpr{FnName: model.NewCIStr("CURRENT_TIMESTAMP")} - } -| NowSym '(' ')' - { - $$ = &ast.FuncCallExpr{FnName: model.NewCIStr("CURRENT_TIMESTAMP")} - } -| SignedLiteral - -// TODO: Process other three keywords -NowSym: - "CURRENT_TIMESTAMP" -| "LOCALTIME" -| "LOCALTIMESTAMP" -| "NOW" - -SignedLiteral: - Literal - { - $$ = ast.NewValueExpr($1) - } -| '+' NumLiteral - { - $$ = &ast.UnaryOperationExpr{Op: opcode.Plus, V: ast.NewValueExpr($2)} - } -| '-' NumLiteral - { - $$ = &ast.UnaryOperationExpr{Op: opcode.Minus, V: ast.NewValueExpr($2)} - } - -// TODO: support decimal literal -NumLiteral: - intLit -| floatLit - - -CreateIndexStmt: - "CREATE" CreateIndexStmtUnique "INDEX" Identifier "ON" TableName '(' IndexColNameList ')' - { - $$ = &ast.CreateIndexStmt{ - Unique: $2.(bool), - IndexName: $4.(string), - Table: $6.(*ast.TableName), - IndexColNames: $8.([]*ast.IndexColName), - } - if yylex.(*lexer).root { - break - } - } - -CreateIndexStmtUnique: - { - $$ = false - } -| "UNIQUE" - { - $$ = true - } - -IndexColName: - ColumnName OptFieldLen Order - { - //Order is parsed but just ignored as MySQL did - $$ = &ast.IndexColName{Column: $1.(*ast.ColumnName), Length: $2.(int)} - } - -IndexColNameList: - { - $$ = []*ast.IndexColName{} - } -| IndexColName - { - $$ = []*ast.IndexColName{$1.(*ast.IndexColName)} - } -| IndexColNameList ',' IndexColName - { - $$ = append($1.([]*ast.IndexColName), $3.(*ast.IndexColName)) - } - - - -/******************************************************************* - * - * Create Database Statement - * CREATE {DATABASE | SCHEMA} [IF NOT EXISTS] db_name - * [create_specification] ... - * - * create_specification: - * [DEFAULT] CHARACTER SET [=] charset_name - * | [DEFAULT] COLLATE [=] collation_name - *******************************************************************/ -CreateDatabaseStmt: - "CREATE" DatabaseSym IfNotExists DBName DatabaseOptionListOpt - { - $$ = &ast.CreateDatabaseStmt{ - IfNotExists: $3.(bool), - Name: $4.(string), - Options: $5.([]*ast.DatabaseOption), - } - - if yylex.(*lexer).root { - break - } - } - -DBName: - Identifier - -DatabaseOption: - DefaultKwdOpt CharsetKw EqOpt StringName - { - $$ = &ast.DatabaseOption{Tp: ast.DatabaseOptionCharset, Value: $4.(string)} - } -| DefaultKwdOpt "COLLATE" EqOpt StringName - { - $$ = &ast.DatabaseOption{Tp: ast.DatabaseOptionCollate, Value: $4.(string)} - } - -DatabaseOptionListOpt: - { - $$ = []*ast.DatabaseOption{} - } -| DatabaseOptionList - -DatabaseOptionList: - DatabaseOption - { - $$ = []*ast.DatabaseOption{$1.(*ast.DatabaseOption)} - } -| DatabaseOptionList DatabaseOption - { - $$ = append($1.([]*ast.DatabaseOption), $2.(*ast.DatabaseOption)) - } - -/******************************************************************* - * - * Create Table Statement - * - * Example: - * CREATE TABLE Persons - * ( - * P_Id int NOT NULL, - * LastName varchar(255) NOT NULL, - * FirstName varchar(255), - * Address varchar(255), - * City varchar(255), - * PRIMARY KEY (P_Id) - * ) - *******************************************************************/ -CreateTableStmt: - "CREATE" "TABLE" IfNotExists TableName '(' TableElementList ')' TableOptionListOpt - { - tes := $6.([]interface {}) - var columnDefs []*ast.ColumnDef - var constraints []*ast.Constraint - for _, te := range tes { - switch te := te.(type) { - case *ast.ColumnDef: - columnDefs = append(columnDefs, te) - case *ast.Constraint: - constraints = append(constraints, te) - } - } - if len(columnDefs) == 0 { - yylex.(*lexer).err("Column Definition List can't be empty.") - return 1 - } - $$ = &ast.CreateTableStmt{ - Table: $4.(*ast.TableName), - IfNotExists: $3.(bool), - Cols: columnDefs, - Constraints: constraints, - Options: $8.([]*ast.TableOption), - } - } - -Default: - "DEFAULT" Expression - { - $$ = $2 - } - -DefaultOpt: - { - $$ = nil - } -| Default - -DefaultKwdOpt: - {} -| "DEFAULT" - -/****************************************************************** - * Do statement - * See: https://dev.mysql.com/doc/refman/5.7/en/do.html - ******************************************************************/ -DoStmt: - "DO" ExpressionList - { - $$ = &ast.DoStmt { - Exprs: $2.([]ast.ExprNode), - } - } - -/******************************************************************* - * - * Delete Statement - * - *******************************************************************/ -DeleteFromStmt: - "DELETE" LowPriorityOptional QuickOptional IgnoreOptional "FROM" TableName WhereClauseOptional OrderByOptional LimitClause - { - // Single Table - join := &ast.Join{Left: &ast.TableSource{Source: $6.(ast.ResultSetNode)}, Right: nil} - x := &ast.DeleteStmt{ - TableRefs: &ast.TableRefsClause{TableRefs: join}, - LowPriority: $2.(bool), - Quick: $3.(bool), - Ignore: $4.(bool), - } - if $7 != nil { - x.Where = $7.(ast.ExprNode) - } - if $8 != nil { - x.Order = $8.(*ast.OrderByClause) - } - if $9 != nil { - x.Limit = $9.(*ast.Limit) - } - - $$ = x - if yylex.(*lexer).root { - break - } - } -| "DELETE" LowPriorityOptional QuickOptional IgnoreOptional TableNameList "FROM" TableRefs WhereClauseOptional - { - // Multiple Table - x := &ast.DeleteStmt{ - LowPriority: $2.(bool), - Quick: $3.(bool), - Ignore: $4.(bool), - IsMultiTable: true, - BeforeFrom: true, - Tables: &ast.DeleteTableList{Tables: $5.([]*ast.TableName)}, - TableRefs: &ast.TableRefsClause{TableRefs: $7.(*ast.Join)}, - } - if $8 != nil { - x.Where = $8.(ast.ExprNode) - } - $$ = x - if yylex.(*lexer).root { - break - } - } -| "DELETE" LowPriorityOptional QuickOptional IgnoreOptional "FROM" TableNameList "USING" TableRefs WhereClauseOptional - { - // Multiple Table - x := &ast.DeleteStmt{ - LowPriority: $2.(bool), - Quick: $3.(bool), - Ignore: $4.(bool), - IsMultiTable: true, - Tables: &ast.DeleteTableList{Tables: $6.([]*ast.TableName)}, - TableRefs: &ast.TableRefsClause{TableRefs: $8.(*ast.Join)}, - } - if $9 != nil { - x.Where = $9.(ast.ExprNode) - } - $$ = x - if yylex.(*lexer).root { - break - } - } - -DatabaseSym: - "DATABASE" | "SCHEMA" - -DropDatabaseStmt: - "DROP" DatabaseSym IfExists DBName - { - $$ = &ast.DropDatabaseStmt{IfExists: $3.(bool), Name: $4.(string)} - if yylex.(*lexer).root { - break - } - } - -DropIndexStmt: - "DROP" "INDEX" IfExists Identifier "ON" TableName - { - $$ = &ast.DropIndexStmt{IfExists: $3.(bool), IndexName: $4.(string), Table: $6.(*ast.TableName)} - } - -DropTableStmt: - "DROP" TableOrTables TableNameList - { - $$ = &ast.DropTableStmt{Tables: $3.([]*ast.TableName)} - if yylex.(*lexer).root { - break - } - } -| "DROP" TableOrTables "IF" "EXISTS" TableNameList - { - $$ = &ast.DropTableStmt{IfExists: true, Tables: $5.([]*ast.TableName)} - if yylex.(*lexer).root { - break - } - } - -TableOrTables: - "TABLE" -| "TABLES" - -EqOpt: - { - } -| eq - { - } - -EmptyStmt: - /* EMPTY */ - { - $$ = nil - } - -ExplainSym: - "EXPLAIN" -| "DESCRIBE" -| "DESC" - -ExplainStmt: - ExplainSym TableName - { - $$ = &ast.ExplainStmt{ - Stmt: &ast.ShowStmt{ - Tp: ast.ShowColumns, - Table: $2.(*ast.TableName), - }, - } - } -| ExplainSym TableName ColumnName - { - $$ = &ast.ExplainStmt{ - Stmt: &ast.ShowStmt{ - Tp: ast.ShowColumns, - Table: $2.(*ast.TableName), - Column: $3.(*ast.ColumnName), - }, - } - } -| ExplainSym ExplainableStmt - { - $$ = &ast.ExplainStmt{Stmt: $2.(ast.StmtNode)} - } - -LengthNum: - NUM - { - switch v := $1.(type) { - case int64: - $$ = uint64(v) - case uint64: - $$ = uint64(v) - } - } - -NUM: - intLit - -Expression: - Expression logOr Expression %prec oror - { - $$ = &ast.BinaryOperationExpr{Op: opcode.OrOr, L: $1.(ast.ExprNode), R: $3.(ast.ExprNode)} - } -| Expression "XOR" Expression %prec xor - { - $$ = &ast.BinaryOperationExpr{Op: opcode.LogicXor, L: $1.(ast.ExprNode), R: $3.(ast.ExprNode)} - } -| Expression logAnd Expression %prec andand - { - $$ = &ast.BinaryOperationExpr{Op: opcode.AndAnd, L: $1.(ast.ExprNode), R: $3.(ast.ExprNode)} - } -| "NOT" Expression %prec not - { - $$ = &ast.UnaryOperationExpr{Op: opcode.Not, V: $2.(ast.ExprNode)} - } -| Factor "IS" NotOpt trueKwd %prec is - { - $$ = &ast.IsTruthExpr{Expr:$1.(ast.ExprNode), Not: $3.(bool), True: int64(1)} - } -| Factor "IS" NotOpt falseKwd %prec is - { - $$ = &ast.IsTruthExpr{Expr:$1.(ast.ExprNode), Not: $3.(bool), True: int64(0)} - } -| Factor "IS" NotOpt "UNKNOWN" %prec is - { - /* https://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html#operator_is */ - $$ = &ast.IsNullExpr{Expr: $1.(ast.ExprNode), Not: $3.(bool)} - } -| Factor - - -logOr: - "||" - { - } -| "OR" - { - } - -logAnd: - "&&" - { - } -| "AND" - { - } - -name: - Identifier - -ExpressionList: - Expression - { - $$ = []ast.ExprNode{$1.(ast.ExprNode)} - } -| ExpressionList ',' Expression - { - $$ = append($1.([]ast.ExprNode), $3.(ast.ExprNode)) - } - -ExpressionListOpt: - { - $$ = []ast.ExprNode{} - } -| ExpressionList - -Factor: - Factor "IS" NotOpt "NULL" %prec is - { - $$ = &ast.IsNullExpr{Expr: $1.(ast.ExprNode), Not: $3.(bool)} - } -| Factor CompareOp PredicateExpr %prec eq - { - $$ = &ast.BinaryOperationExpr{Op: $2.(opcode.Op), L: $1.(ast.ExprNode), R: $3.(ast.ExprNode)} - } -| Factor CompareOp AnyOrAll SubSelect %prec eq - { - $$ = &ast.CompareSubqueryExpr{Op: $2.(opcode.Op), L: $1.(ast.ExprNode), R: $4.(*ast.SubqueryExpr), All: $3.(bool)} - } -| PredicateExpr - -CompareOp: - ">=" - { - $$ = opcode.GE - } -| '>' - { - $$ = opcode.GT - } -| "<=" - { - $$ = opcode.LE - } -| '<' - { - $$ = opcode.LT - } -| "!=" - { - $$ = opcode.NE - } -| "<>" - { - $$ = opcode.NE - } -| "=" - { - $$ = opcode.EQ - } -| "<=>" - { - $$ = opcode.NullEQ - } - -AnyOrAll: - "ANY" - { - $$ = false - } -| "SOME" - { - $$ = false - } -| "ALL" - { - $$ = true - } - -PredicateExpr: - PrimaryFactor NotOpt "IN" '(' ExpressionList ')' - { - $$ = &ast.PatternInExpr{Expr: $1.(ast.ExprNode), Not: $2.(bool), List: $5.([]ast.ExprNode)} - } -| PrimaryFactor NotOpt "IN" SubSelect - { - $$ = &ast.PatternInExpr{Expr: $1.(ast.ExprNode), Not: $2.(bool), Sel: $4.(*ast.SubqueryExpr)} - } -| PrimaryFactor NotOpt "BETWEEN" PrimaryFactor "AND" PredicateExpr - { - $$ = &ast.BetweenExpr{ - Expr: $1.(ast.ExprNode), - Left: $4.(ast.ExprNode), - Right: $6.(ast.ExprNode), - Not: $2.(bool), - } - } -| PrimaryFactor NotOpt "LIKE" PrimaryExpression LikeEscapeOpt - { - escape := $5.(string) - if len(escape) > 1 { - yylex.(*lexer).errf("Incorrect arguments %s to ESCAPE", escape) - return 1 - } else if len(escape) == 0 { - escape = "\\" - } - $$ = &ast.PatternLikeExpr{ - Expr: $1.(ast.ExprNode), - Pattern: $4.(ast.ExprNode), - Not: $2.(bool), - Escape: escape[0], - } - } -| PrimaryFactor NotOpt RegexpSym PrimaryExpression - { - $$ = &ast.PatternRegexpExpr{Expr: $1.(ast.ExprNode), Pattern: $4.(ast.ExprNode), Not: $2.(bool)} - } -| PrimaryFactor - -RegexpSym: - "REGEXP" -| "RLIKE" - -LikeEscapeOpt: - %prec lowerThanEscape - { - $$ = "\\" - } -| "ESCAPE" stringLit - { - $$ = $2 - } - -NotOpt: - { - $$ = false - } -| "NOT" - { - $$ = true - } - -Field: - '*' - { - $$ = &ast.SelectField{WildCard: &ast.WildCardField{}} - } -| Identifier '.' '*' - { - wildCard := &ast.WildCardField{Table: model.NewCIStr($1.(string))} - $$ = &ast.SelectField{WildCard: wildCard} - } -| Identifier '.' Identifier '.' '*' - { - wildCard := &ast.WildCardField{Schema: model.NewCIStr($1.(string)), Table: model.NewCIStr($3.(string))} - $$ = &ast.SelectField{WildCard: wildCard} - } -| Expression FieldAsNameOpt - { - expr := $1.(ast.ExprNode) - asName := $2.(string) - $$ = &ast.SelectField{Expr: expr, AsName: model.NewCIStr(asName)} - } - -FieldAsNameOpt: - /* EMPTY */ - { - $$ = "" - } -| FieldAsName - { - $$ = $1 - } - -FieldAsName: - Identifier - { - $$ = $1 - } -| "AS" Identifier - { - $$ = $2 - } -| stringLit - { - $$ = $1 - } -| "AS" stringLit - { - $$ = $2 - } - -FieldList: - Field - { - field := $1.(*ast.SelectField) - field.Offset = yylex.(*lexer).startOffset(yyS[yypt].offset) - $$ = []*ast.SelectField{field} - } -| FieldList ',' Field - { - - fl := $1.([]*ast.SelectField) - last := fl[len(fl)-1] - l := yylex.(*lexer) - if last.Expr != nil && last.AsName.O == "" { - lastEnd := l.endOffset(yyS[yypt-1].offset) - last.SetText(l.src[last.Offset:lastEnd]) - } - newField := $3.(*ast.SelectField) - newField.Offset = l.startOffset(yyS[yypt].offset) - $$ = append(fl, newField) - } - -GroupByClause: - "GROUP" "BY" ByList - { - $$ = &ast.GroupByClause{Items: $3.([]*ast.ByItem)} - } - -HavingClause: - { - $$ = nil - } -| "HAVING" Expression - { - $$ = &ast.HavingClause{Expr: $2.(ast.ExprNode)} - } - -IfExists: - { - $$ = false - } -| "IF" "EXISTS" - { - $$ = true - } - -IfNotExists: - { - $$ = false - } -| "IF" "NOT" "EXISTS" - { - $$ = true - } - - -IgnoreOptional: - { - $$ = false - } -| "IGNORE" - { - $$ = true - } - -IndexName: - { - $$ = "" - } -| Identifier - { - //"index name" - $$ = $1.(string) - } - -IndexOption: - { - $$ = nil - } -| "KEY_BLOCK_SIZE" EqOpt LengthNum - { - $$ = &ast.IndexOption{ - KeyBlockSize: $1.(uint64), - } - } -| IndexType - { - $$ = &ast.IndexOption { - Tp: $1.(model.IndexType), - } - } -| "COMMENT" stringLit - { - $$ = &ast.IndexOption { - Comment: $2.(string), - } - } - -IndexType: - "USING" "BTREE" - { - $$ = model.IndexTypeBtree - } -| "USING" "HASH" - { - $$ = model.IndexTypeHash - } - -IndexTypeOpt: - { - $$ = nil - } -| IndexType - { - $$ = $1 - } - -/**********************************Identifier********************************************/ -Identifier: - identifier | UnReservedKeyword | NotKeywordToken - -UnReservedKeyword: - "AUTO_INCREMENT" | "AFTER" | "AVG" | "BEGIN" | "BIT" | "BOOL" | "BOOLEAN" | "BTREE" | "CHARSET" | "COLUMNS" | "COMMIT" | "COMPACT" | "COMPRESSED" -| "DATE" | "DATETIME" | "DEALLOCATE" | "DO" | "DYNAMIC" | "END" | "ENGINE" | "ENGINES" | "EXECUTE" | "FIRST" | "FIXED" | "FULL" | "HASH" -| "LOCAL" | "NAMES" | "OFFSET" | "PASSWORD" %prec lowerThanEq | "PREPARE" | "QUICK" | "REDUNDANT" | "ROLLBACK" | "SESSION" | "SIGNED" -| "START" | "STATUS" | "GLOBAL" | "TABLES"| "TEXT" | "TIME" | "TIMESTAMP" | "TRANSACTION" | "TRUNCATE" | "UNKNOWN" -| "VALUE" | "WARNINGS" | "YEAR" | "MODE" | "WEEK" | "ANY" | "SOME" | "USER" | "IDENTIFIED" | "COLLATION" -| "COMMENT" | "AVG_ROW_LENGTH" | "CONNECTION" | "CHECKSUM" | "COMPRESSION" | "KEY_BLOCK_SIZE" | "MAX_ROWS" | "MIN_ROWS" -| "NATIONAL" | "ROW" | "ROW_FORMAT" | "QUARTER" | "ESCAPE" | "GRANTS" | "FIELDS" | "TRIGGERS" | "DELAY_KEY_WRITE" | "ISOLATION" -| "REPEATABLE" | "COMMITTED" | "UNCOMMITTED" | "ONLY" | "SERIALIZABLE" | "LEVEL" | "VARIABLES" - -NotKeywordToken: - "ABS" | "ADDDATE" | "ADMIN" | "COALESCE" | "CONCAT" | "CONCAT_WS" | "CONNECTION_ID" | "CUR_TIME"| "COUNT" | "DAY" -| "DATE_ADD" | "DATE_SUB" | "DAYNAME" | "DAYOFMONTH" | "DAYOFWEEK" | "DAYOFYEAR" | "FOUND_ROWS" | "GROUP_CONCAT"| "HOUR" -| "IFNULL" | "LENGTH" | "LOCATE" | "MAX" | "MICROSECOND" | "MIN" | "MINUTE" | "NULLIF" | "MONTH" | "NOW" | "POW" -| "POWER" | "RAND" | "SECOND" | "SQL_CALC_FOUND_ROWS" | "SUBDATE" | "SUBSTRING" %prec lowerThanLeftParen -| "SUBSTRING_INDEX" | "SUM" | "TRIM" | "VERSION" | "WEEKDAY" | "WEEKOFYEAR" | "YEARWEEK" - -/************************************************************************************ - * - * Insert Statments - * - * TODO: support PARTITION - **********************************************************************************/ -InsertIntoStmt: - "INSERT" Priority IgnoreOptional IntoOpt TableName InsertValues OnDuplicateKeyUpdate - { - x := $6.(*ast.InsertStmt) - x.Priority = $2.(int) - // Wraps many layers here so that it can be processed the same way as select statement. - ts := &ast.TableSource{Source: $5.(*ast.TableName)} - x.Table = &ast.TableRefsClause{TableRefs: &ast.Join{Left: ts}} - if $7 != nil { - x.OnDuplicate = $7.([]*ast.Assignment) - } - $$ = x - if yylex.(*lexer).root { - break - } - } - -IntoOpt: - { - } -| "INTO" - { - } - -InsertValues: - '(' ColumnNameListOpt ')' ValueSym ExpressionListList - { - $$ = &ast.InsertStmt{ - Columns: $2.([]*ast.ColumnName), - Lists: $5.([][]ast.ExprNode), - } - } -| '(' ColumnNameListOpt ')' SelectStmt - { - $$ = &ast.InsertStmt{Columns: $2.([]*ast.ColumnName), Select: $4.(*ast.SelectStmt)} - } -| '(' ColumnNameListOpt ')' UnionStmt - { - $$ = &ast.InsertStmt{Columns: $2.([]*ast.ColumnName), Select: $4.(*ast.UnionStmt)} - } -| ValueSym ExpressionListList %prec insertValues - { - $$ = &ast.InsertStmt{Lists: $2.([][]ast.ExprNode)} - } -| SelectStmt - { - $$ = &ast.InsertStmt{Select: $1.(*ast.SelectStmt)} - } -| UnionStmt - { - $$ = &ast.InsertStmt{Select: $1.(*ast.UnionStmt)} - } -| "SET" ColumnSetValueList - { - $$ = &ast.InsertStmt{Setlist: $2.([]*ast.Assignment)} - } - -ValueSym: - "VALUE" -| "VALUES" - -ExpressionListList: - '(' ')' - { - $$ = [][]ast.ExprNode{[]ast.ExprNode{}} - } -| '(' ')' ',' ExpressionListList - { - $$ = append([][]ast.ExprNode{[]ast.ExprNode{}}, $4.([][]ast.ExprNode)...) - } -| '(' ExpressionList ')' - { - $$ = [][]ast.ExprNode{$2.([]ast.ExprNode)} - } -| '(' ExpressionList ')' ',' ExpressionListList - { - $$ = append([][]ast.ExprNode{$2.([]ast.ExprNode)}, $5.([][]ast.ExprNode)...) - } - -ColumnSetValue: - ColumnName eq Expression - { - $$ = &ast.Assignment{ - Column: $1.(*ast.ColumnName), - Expr: $3.(ast.ExprNode), - } - } - -ColumnSetValueList: - { - $$ = []*ast.Assignment{} - } -| ColumnSetValue - { - $$ = []*ast.Assignment{$1.(*ast.Assignment)} - } -| ColumnSetValueList ',' ColumnSetValue - { - $$ = append($1.([]*ast.Assignment), $3.(*ast.Assignment)) - } - -/* - * ON DUPLICATE KEY UPDATE col_name=expr [, col_name=expr] ... - * See: https://dev.mysql.com/doc/refman/5.7/en/insert-on-duplicate.html - */ -OnDuplicateKeyUpdate: - { - $$ = nil - } -| "ON" "DUPLICATE" "KEY" "UPDATE" AssignmentList - { - $$ = $5 - } - -/***********************************Insert Statements END************************************/ - -/************************************************************************************ - * Replace Statements - * See: https://dev.mysql.com/doc/refman/5.7/en/replace.html - * - * TODO: support PARTITION - **********************************************************************************/ -ReplaceIntoStmt: - "REPLACE" ReplacePriority IntoOpt TableName InsertValues - { - x := $5.(*ast.InsertStmt) - x.IsReplace = true - x.Priority = $2.(int) - ts := &ast.TableSource{Source: $4.(*ast.TableName)} - x.Table = &ast.TableRefsClause{TableRefs: &ast.Join{Left: ts}} - $$ = x - } - -ReplacePriority: - { - $$ = ast.NoPriority - } -| "LOW_PRIORITY" - { - $$ = ast.LowPriority - } -| "DELAYED" - { - $$ = ast.DelayedPriority - } - -/***********************************Replace Statments END************************************/ - -Literal: - "false" - { - $$ = int64(0) - } -| "NULL" -| "true" - { - $$ = int64(1) - } -| floatLit -| intLit -| stringLit - { - tp := types.NewFieldType(mysql.TypeString) - l := yylex.(*lexer) - tp.Charset, tp.Collate = l.GetCharsetInfo() - expr := ast.NewValueExpr($1) - expr.SetType(tp) - $$ = expr - } -| "UNDERSCORE_CHARSET" stringLit - { - // See: https://dev.mysql.com/doc/refman/5.7/en/charset-literal.html - tp := types.NewFieldType(mysql.TypeString) - tp.Charset = $1.(string) - co, err := charset.GetDefaultCollation(tp.Charset) - if err != nil { - l := yylex.(*lexer) - l.errf("Get collation error for charset: %s", tp.Charset) - return 1 - } - tp.Collate = co - expr := ast.NewValueExpr($2) - expr.SetType(tp) - $$ = expr - } -| hexLit -| bitLit - -Operand: - Literal - { - $$ = ast.NewValueExpr($1) - } -| ColumnName - { - $$ = &ast.ColumnNameExpr{Name: $1.(*ast.ColumnName)} - } -| '(' Expression ')' - { - l := yylex.(*lexer) - startOffset := l.startOffset(yyS[yypt-1].offset) - endOffset := l.endOffset(yyS[yypt].offset) - expr := $2.(ast.ExprNode) - expr.SetText(l.src[startOffset:endOffset]) - $$ = &ast.ParenthesesExpr{Expr: expr} - } -| "DEFAULT" %prec lowerThanLeftParen - { - $$ = &ast.DefaultExpr{} - } -| "DEFAULT" '(' ColumnName ')' - { - $$ = &ast.DefaultExpr{Name: $3.(*ast.ColumnName)} - } -| Variable - { - $$ = $1 - } -| "PLACEHOLDER" - { - $$ = &ast.ParamMarkerExpr{ - Offset: yyS[yypt].offset, - } - } -| "ROW" '(' Expression ',' ExpressionList ')' - { - values := append([]ast.ExprNode{$3.(ast.ExprNode)}, $5.([]ast.ExprNode)...) - $$ = &ast.RowExpr{Values: values} - } -| '(' Expression ',' ExpressionList ')' - { - values := append([]ast.ExprNode{$2.(ast.ExprNode)}, $4.([]ast.ExprNode)...) - $$ = &ast.RowExpr{Values: values} - } -| "EXISTS" SubSelect - { - $$ = &ast.ExistsSubqueryExpr{Sel: $2.(*ast.SubqueryExpr)} - } - -OrderBy: - "ORDER" "BY" ByList - { - $$ = &ast.OrderByClause{Items: $3.([]*ast.ByItem)} - } - -ByList: - ByItem - { - $$ = []*ast.ByItem{$1.(*ast.ByItem)} - } -| ByList ',' ByItem - { - $$ = append($1.([]*ast.ByItem), $3.(*ast.ByItem)) - } - -ByItem: - Expression Order - { - expr := $1 - valueExpr, ok := expr.(*ast.ValueExpr) - if ok { - position, isPosition := valueExpr.GetValue().(int64) - if isPosition { - expr = &ast.PositionExpr{N: int(position)} - } - } - $$ = &ast.ByItem{Expr: expr.(ast.ExprNode), Desc: $2.(bool)} - } - -Order: - /* EMPTY */ - { - $$ = false // ASC by default - } -| "ASC" - { - $$ = false - } -| "DESC" - { - $$ = true - } - -OrderByOptional: - { - $$ = nil - } -| OrderBy - { - $$ = $1 - } - -PrimaryExpression: - Operand -| Function -| SubSelect -| '!' PrimaryExpression %prec neg - { - $$ = &ast.UnaryOperationExpr{Op: opcode.Not, V: $2.(ast.ExprNode)} - } -| '~' PrimaryExpression %prec neg - { - $$ = &ast.UnaryOperationExpr{Op: opcode.BitNeg, V: $2.(ast.ExprNode)} - } -| '-' PrimaryExpression %prec neg - { - $$ = &ast.UnaryOperationExpr{Op: opcode.Minus, V: $2.(ast.ExprNode)} - } -| '+' PrimaryExpression %prec neg - { - $$ = &ast.UnaryOperationExpr{Op: opcode.Plus, V: $2.(ast.ExprNode)} - } -| "BINARY" PrimaryExpression %prec neg - { - // See: https://dev.mysql.com/doc/refman/5.7/en/cast-functions.html#operator_binary - x := types.NewFieldType(mysql.TypeString) - x.Charset = charset.CharsetBin - x.Collate = charset.CharsetBin - $$ = &ast.FuncCastExpr{ - Expr: $2.(ast.ExprNode), - Tp: x, - FunctionType: ast.CastBinaryOperator, - } - } -| PrimaryExpression "COLLATE" StringName %prec neg - { - // TODO: Create a builtin function hold expr and collation. When do evaluation, convert expr result using the collation. - $$ = $1 - } - -Function: - FunctionCallKeyword -| FunctionCallNonKeyword -| FunctionCallConflict -| FunctionCallAgg - -FunctionNameConflict: - "DATABASE" | "SCHEMA" | "IF" | "LEFT" | "REPEAT" | "CURRENT_USER" | "CURRENT_DATE" | "VERSION" - -FunctionCallConflict: - FunctionNameConflict '(' ExpressionListOpt ')' - { - $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: $3.([]ast.ExprNode)} - } -| "CURRENT_USER" - { - // See: https://dev.mysql.com/doc/refman/5.7/en/information-functions.html#function_current-user - $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string))} - } -| "CURRENT_DATE" - { - $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string))} - } - -DistinctOpt: - { - $$ = false - } -| "ALL" - { - $$ = false - } -| "DISTINCT" - { - $$ = true - } -| "DISTINCT" "ALL" - { - $$ = true - } - -FunctionCallKeyword: - "CAST" '(' Expression "AS" CastType ')' - { - /* See: https://dev.mysql.com/doc/refman/5.7/en/cast-functions.html#function_cast */ - $$ = &ast.FuncCastExpr{ - Expr: $3.(ast.ExprNode), - Tp: $5.(*types.FieldType), - FunctionType: ast.CastFunction, - } - } -| "CASE" ExpressionOpt WhenClauseList ElseOpt "END" - { - x := &ast.CaseExpr{WhenClauses: $3.([]*ast.WhenClause)} - if $2 != nil { - x.Value = $2.(ast.ExprNode) - } - if $4 != nil { - x.ElseClause = $4.(ast.ExprNode) - } - $$ = x - } -| "CONVERT" '(' Expression "USING" StringName ')' - { - // See: https://dev.mysql.com/doc/refman/5.7/en/cast-functions.html#function_convert - charset := ast.NewValueExpr($5) - $$ = &ast.FuncCallExpr{ - FnName: model.NewCIStr($1.(string)), - Args: []ast.ExprNode{$3.(ast.ExprNode), charset}, - } - } -| "CONVERT" '(' Expression ',' CastType ')' - { - // See: https://dev.mysql.com/doc/refman/5.7/en/cast-functions.html#function_convert - $$ = &ast.FuncCastExpr{ - Expr: $3.(ast.ExprNode), - Tp: $5.(*types.FieldType), - FunctionType: ast.CastConvertFunction, - } - } -| "DATE" '(' Expression ')' - { - $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}} - } -| "USER" '(' ')' - { - $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string))} - } -| "VALUES" '(' ColumnName ')' %prec lowerThanInsertValues - { - // TODO: support qualified identifier for column_name - $$ = &ast.ValuesExpr{Column: &ast.ColumnNameExpr{Name: $3.(*ast.ColumnName)}} - } -| "WEEK" '(' ExpressionList ')' - { - $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: $3.([]ast.ExprNode)} - } -| "YEAR" '(' Expression ')' - { - $$ = &ast.FuncCallExpr{FnName:model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}} - } - -FunctionCallNonKeyword: - "COALESCE" '(' ExpressionList ')' - { - $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: $3.([]ast.ExprNode)} - } -| "CURDATE" '(' ')' - { - $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string))} - } -| "CUR_TIME" '(' ExpressionOpt ')' - { - args := []ast.ExprNode{} - if $3 != nil { - args = append(args, $3.(ast.ExprNode)) - } - $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: args} - } -| "CURRENT_TIME" FuncDatetimePrec - { - args := []ast.ExprNode{} - if $2 != nil { - args = append(args, $2.(ast.ExprNode)) - } - $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: args} - } -| "CURRENT_TIMESTAMP" FuncDatetimePrec - { - args := []ast.ExprNode{} - if $2 != nil { - args = append(args, $2.(ast.ExprNode)) - } - $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: args} - } -| "ABS" '(' Expression ')' - { - $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}} - } -| "CONCAT" '(' ExpressionList ')' - { - $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: $3.([]ast.ExprNode)} - } -| "CONCAT_WS" '(' ExpressionList ')' - { - $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: $3.([]ast.ExprNode)} - } -| "DAY" '(' Expression ')' - { - $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}} - } -| "DAYNAME" '(' Expression ')' - { - $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}} - } -| "DAYOFWEEK" '(' Expression ')' - { - $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}} - } -| "DAYOFMONTH" '(' Expression ')' - { - $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}} - } -| "DAYOFYEAR" '(' Expression ')' - { - $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}} - } -| DateArithOpt '(' Expression ',' "INTERVAL" Expression TimeUnit ')' - { - op := ast.NewValueExpr($1) - dateArithInterval := ast.NewValueExpr( - ast.DateArithInterval{ - Unit: $7.(string), - Interval: $6.(ast.ExprNode), - }, - ) - - $$ = &ast.FuncCallExpr{ - FnName: model.NewCIStr("DATE_ARITH"), - Args: []ast.ExprNode{ - op, - $3.(ast.ExprNode), - dateArithInterval, - }, - } - } -| DateArithMultiFormsOpt '(' Expression ',' DateArithInterval')' - { - op := ast.NewValueExpr($1) - dateArithInterval := ast.NewValueExpr($5) - $$ = &ast.FuncCallExpr{ - FnName: model.NewCIStr("DATE_ARITH"), - Args: []ast.ExprNode{ - op, - $3.(ast.ExprNode), - dateArithInterval, - }, - } - } -| "EXTRACT" '(' TimeUnit "FROM" Expression ')' - { - timeUnit := ast.NewValueExpr($3) - $$ = &ast.FuncCallExpr{ - FnName: model.NewCIStr($1.(string)), - Args: []ast.ExprNode{timeUnit, $5.(ast.ExprNode)}, - } - } -| "FOUND_ROWS" '(' ')' - { - $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string))} - } -| "HOUR" '(' Expression ')' - { - $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}} - } -| "IFNULL" '(' ExpressionList ')' - { - $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: $3.([]ast.ExprNode)} - } -| "LENGTH" '(' Expression ')' - { - $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}} - } -| "LOCATE" '(' Expression ',' Expression ')' - { - $$ = &ast.FuncCallExpr{ - FnName: model.NewCIStr($1.(string)), - Args: []ast.ExprNode{$3.(ast.ExprNode), $5.(ast.ExprNode)}, - } - } -| "LOCATE" '(' Expression ',' Expression ',' Expression ')' - { - $$ = &ast.FuncCallExpr{ - FnName: model.NewCIStr($1.(string)), - Args: []ast.ExprNode{$3.(ast.ExprNode), $5.(ast.ExprNode), $7.(ast.ExprNode)}, - } - } -| "LOWER" '(' Expression ')' - { - $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}} - } -| "MICROSECOND" '(' Expression ')' - { - $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}} - } -| "MINUTE" '(' Expression ')' - { - $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}} - } -| "MONTH" '(' Expression ')' - { - $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}} - } -| "NOW" '(' ExpressionOpt ')' - { - args := []ast.ExprNode{} - if $3 != nil { - args = append(args, $3.(ast.ExprNode)) - } - $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: args} - } -| "NULLIF" '(' ExpressionList ')' - { - $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: $3.([]ast.ExprNode)} - } -| "POW" '(' Expression ',' Expression ')' - { - args := []ast.ExprNode{$3.(ast.ExprNode), $5.(ast.ExprNode)} - $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: args} - } -| "POWER" '(' Expression ',' Expression ')' - { - args := []ast.ExprNode{$3.(ast.ExprNode), $5.(ast.ExprNode)} - $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: args} - } -| "RAND" '(' ExpressionOpt ')' - { - - args := []ast.ExprNode{} - if $3 != nil { - args = append(args, $3.(ast.ExprNode)) - } - $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: args} - } -| "REPLACE" '(' Expression ',' Expression ',' Expression ')' - { - args := []ast.ExprNode{$3.(ast.ExprNode), $5.(ast.ExprNode), $7.(ast.ExprNode)} - $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: args} - } -| "SECOND" '(' Expression ')' - { - $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}} - } -| "STRCMP" '(' Expression ',' Expression ')' - { - $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode), $5.(ast.ExprNode)}} - } -| "SUBSTRING" '(' Expression ',' Expression ')' - { - $$ = &ast.FuncCallExpr{ - FnName: model.NewCIStr($1.(string)), - Args: []ast.ExprNode{$3.(ast.ExprNode), $5.(ast.ExprNode)}, - } - } -| "SUBSTRING" '(' Expression "FROM" Expression ')' - { - $$ = &ast.FuncCallExpr{ - FnName: model.NewCIStr($1.(string)), - Args: []ast.ExprNode{$3.(ast.ExprNode), $5.(ast.ExprNode)}, - } - } -| "SUBSTRING" '(' Expression ',' Expression ',' Expression ')' - { - $$ = &ast.FuncCallExpr{ - FnName: model.NewCIStr($1.(string)), - Args: []ast.ExprNode{$3.(ast.ExprNode), $5.(ast.ExprNode), $7.(ast.ExprNode)}, - } - } -| "SUBSTRING" '(' Expression "FROM" Expression "FOR" Expression ')' - { - $$ = &ast.FuncCallExpr{ - FnName: model.NewCIStr($1.(string)), - Args: []ast.ExprNode{$3.(ast.ExprNode), $5.(ast.ExprNode), $7.(ast.ExprNode)}, - } - } -| "SUBSTRING_INDEX" '(' Expression ',' Expression ',' Expression ')' - { - $$ = &ast.FuncCallExpr{ - FnName: model.NewCIStr($1.(string)), - Args: []ast.ExprNode{$3.(ast.ExprNode), $5.(ast.ExprNode), $7.(ast.ExprNode)}, - } - } -| "SYSDATE" '(' ExpressionOpt ')' - { - args := []ast.ExprNode{} - if $3 != nil { - args = append(args, $3.(ast.ExprNode)) - } - $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: args} - } -| "TRIM" '(' Expression ')' - { - $$ = &ast.FuncCallExpr{ - FnName: model.NewCIStr($1.(string)), - Args: []ast.ExprNode{$3.(ast.ExprNode)}, - } - } -| "TRIM" '(' Expression "FROM" Expression ')' - { - $$ = &ast.FuncCallExpr{ - FnName: model.NewCIStr($1.(string)), - Args: []ast.ExprNode{$5.(ast.ExprNode), $3.(ast.ExprNode)}, - } - } -| "TRIM" '(' TrimDirection "FROM" Expression ')' - { - nilVal := ast.NewValueExpr(nil) - direction := ast.NewValueExpr($3) - $$ = &ast.FuncCallExpr{ - FnName: model.NewCIStr($1.(string)), - Args: []ast.ExprNode{$5.(ast.ExprNode), nilVal, direction}, - } - } -| "TRIM" '(' TrimDirection Expression "FROM" Expression ')' - { - direction := ast.NewValueExpr($3) - $$ = &ast.FuncCallExpr{ - FnName: model.NewCIStr($1.(string)), - Args: []ast.ExprNode{$6.(ast.ExprNode),$4.(ast.ExprNode), direction}, - } - } -| "UPPER" '(' Expression ')' - { - $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}} - } -| "WEEKDAY" '(' Expression ')' - { - $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}} - } -| "WEEKOFYEAR" '(' Expression ')' - { - $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: []ast.ExprNode{$3.(ast.ExprNode)}} - } -| "YEARWEEK" '(' ExpressionList ')' - { - $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string)), Args: $3.([]ast.ExprNode)} - } -| "CONNECTION_ID" '(' ')' - { - $$ = &ast.FuncCallExpr{FnName: model.NewCIStr($1.(string))} - } - -DateArithOpt: - "DATE_ADD" - { - $$ = ast.DateAdd - } -| "DATE_SUB" - { - $$ = ast.DateSub - } - -DateArithMultiFormsOpt: - "ADDDATE" - { - $$ = ast.DateAdd - } -| "SUBDATE" - { - $$ = ast.DateSub - } - -DateArithInterval: - Expression - { - $$ = ast.DateArithInterval{ - Unit: "day", - Interval: $1.(ast.ExprNode), - } - } -| "INTERVAL" Expression TimeUnit - { - $$ = ast.DateArithInterval{Unit: $3.(string), Interval: $2.(ast.ExprNode)} - } - -TrimDirection: - "BOTH" - { - $$ = ast.TrimBoth - } -| "LEADING" - { - $$ = ast.TrimLeading - } -| "TRAILING" - { - $$ = ast.TrimTrailing - } - -FunctionCallAgg: - "AVG" '(' DistinctOpt ExpressionList ')' - { - $$ = &ast.AggregateFuncExpr{F: $1.(string), Args: $4.([]ast.ExprNode), Distinct: $3.(bool)} - } -| "COUNT" '(' DistinctOpt ExpressionList ')' - { - $$ = &ast.AggregateFuncExpr{F: $1.(string), Args: $4.([]ast.ExprNode), Distinct: $3.(bool)} - } -| "COUNT" '(' DistinctOpt '*' ')' - { - args := []ast.ExprNode{ast.NewValueExpr(ast.UnquoteString("*"))} - $$ = &ast.AggregateFuncExpr{F: $1.(string), Args: args, Distinct: $3.(bool)} - } -| "GROUP_CONCAT" '(' DistinctOpt ExpressionList ')' - { - $$ = &ast.AggregateFuncExpr{F: $1.(string), Args: $4.([]ast.ExprNode), Distinct: $3.(bool)} - } -| "MAX" '(' DistinctOpt Expression ')' - { - $$ = &ast.AggregateFuncExpr{F: $1.(string), Args: []ast.ExprNode{$4.(ast.ExprNode)}, Distinct: $3.(bool)} - } -| "MIN" '(' DistinctOpt Expression ')' - { - $$ = &ast.AggregateFuncExpr{F: $1.(string), Args: []ast.ExprNode{$4.(ast.ExprNode)}, Distinct: $3.(bool)} - } -| "SUM" '(' DistinctOpt Expression ')' - { - $$ = &ast.AggregateFuncExpr{F: $1.(string), Args: []ast.ExprNode{$4.(ast.ExprNode)}, Distinct: $3.(bool)} - } - -FuncDatetimePrec: - { - $$ = nil - } -| '(' ')' - { - $$ = nil - } -| '(' Expression ')' - { - $$ = $2 - } - -TimeUnit: - "MICROSECOND" | "SECOND" | "MINUTE" | "HOUR" | "DAY" | "WEEK" -| "MONTH" | "QUARTER" | "YEAR" | "SECOND_MICROSECOND" | "MINUTE_MICROSECOND" -| "MINUTE_SECOND" | "HOUR_MICROSECOND" | "HOUR_SECOND" | "HOUR_MINUTE" -| "DAY_MICROSECOND" | "DAY_SECOND" | "DAY_MINUTE" | "DAY_HOUR" | "YEAR_MONTH" - -ExpressionOpt: - { - $$ = nil - } -| Expression - { - $$ = $1 - } - -WhenClauseList: - WhenClause - { - $$ = []*ast.WhenClause{$1.(*ast.WhenClause)} - } -| WhenClauseList WhenClause - { - $$ = append($1.([]*ast.WhenClause), $2.(*ast.WhenClause)) - } - -WhenClause: - "WHEN" Expression "THEN" Expression - { - $$ = &ast.WhenClause{ - Expr: $2.(ast.ExprNode), - Result: $4.(ast.ExprNode), - } - } - -ElseOpt: - /* empty */ - { - $$ = nil - } -| "ELSE" Expression - { - $$ = $2 - } - -CastType: - "BINARY" OptFieldLen - { - x := types.NewFieldType(mysql.TypeString) - x.Flen = $2.(int) - x.Charset = charset.CharsetBin - x.Collate = charset.CharsetBin - $$ = x - } -| "CHAR" OptFieldLen OptBinary OptCharset - { - x := types.NewFieldType(mysql.TypeString) - x.Flen = $2.(int) - if $3.(bool) { - x.Flag |= mysql.BinaryFlag - } - x.Charset = $4.(string) - $$ = x - } -| "DATE" - { - x := types.NewFieldType(mysql.TypeDate) - $$ = x - } -| "DATETIME" OptFieldLen - { - x := types.NewFieldType(mysql.TypeDatetime) - x.Decimal = $2.(int) - $$ = x - } -| "DECIMAL" FloatOpt - { - fopt := $2.(*ast.FloatOpt) - x := types.NewFieldType(mysql.TypeNewDecimal) - x.Flen = fopt.Flen - x.Decimal = fopt.Decimal - $$ = x - } -| "TIME" OptFieldLen - { - x := types.NewFieldType(mysql.TypeDuration) - x.Decimal = $2.(int) - $$ = x - } -| "SIGNED" OptInteger - { - x := types.NewFieldType(mysql.TypeLonglong) - $$ = x - } -| "UNSIGNED" OptInteger - { - x := types.NewFieldType(mysql.TypeLonglong) - x.Flag |= mysql.UnsignedFlag - $$ = x - } - - -PrimaryFactor: - PrimaryFactor '|' PrimaryFactor %prec '|' - { - $$ = &ast.BinaryOperationExpr{Op: opcode.Or, L: $1.(ast.ExprNode), R: $3.(ast.ExprNode)} - } -| PrimaryFactor '&' PrimaryFactor %prec '&' - { - $$ = &ast.BinaryOperationExpr{Op: opcode.And, L: $1.(ast.ExprNode), R: $3.(ast.ExprNode)} - } -| PrimaryFactor "<<" PrimaryFactor %prec lsh - { - $$ = &ast.BinaryOperationExpr{Op: opcode.LeftShift, L: $1.(ast.ExprNode), R: $3.(ast.ExprNode)} - } -| PrimaryFactor ">>" PrimaryFactor %prec rsh - { - $$ = &ast.BinaryOperationExpr{Op: opcode.RightShift, L: $1.(ast.ExprNode), R: $3.(ast.ExprNode)} - } -| PrimaryFactor '+' PrimaryFactor %prec '+' - { - $$ = &ast.BinaryOperationExpr{Op: opcode.Plus, L: $1.(ast.ExprNode), R: $3.(ast.ExprNode)} - } -| PrimaryFactor '-' PrimaryFactor %prec '-' - { - $$ = &ast.BinaryOperationExpr{Op: opcode.Minus, L: $1.(ast.ExprNode), R: $3.(ast.ExprNode)} - } -| PrimaryFactor '*' PrimaryFactor %prec '*' - { - $$ = &ast.BinaryOperationExpr{Op: opcode.Mul, L: $1.(ast.ExprNode), R: $3.(ast.ExprNode)} - } -| PrimaryFactor '/' PrimaryFactor %prec '/' - { - $$ = &ast.BinaryOperationExpr{Op: opcode.Div, L: $1.(ast.ExprNode), R: $3.(ast.ExprNode)} - } -| PrimaryFactor '%' PrimaryFactor %prec '%' - { - $$ = &ast.BinaryOperationExpr{Op: opcode.Mod, L: $1.(ast.ExprNode), R: $3.(ast.ExprNode)} - } -| PrimaryFactor "DIV" PrimaryFactor %prec div - { - $$ = &ast.BinaryOperationExpr{Op: opcode.IntDiv, L: $1.(ast.ExprNode), R: $3.(ast.ExprNode)} - } -| PrimaryFactor "MOD" PrimaryFactor %prec mod - { - $$ = &ast.BinaryOperationExpr{Op: opcode.Mod, L: $1.(ast.ExprNode), R: $3.(ast.ExprNode)} - } -| PrimaryFactor '^' PrimaryFactor - { - $$ = &ast.BinaryOperationExpr{Op: opcode.Xor, L: $1.(ast.ExprNode), R: $3.(ast.ExprNode)} - } -| PrimaryExpression - - -Priority: - { - $$ = ast.NoPriority - } -| "LOW_PRIORITY" - { - $$ = ast.LowPriority - } -| "HIGH_PRIORITY" - { - $$ = ast.HighPriority - } -| "DELAYED" - { - $$ = ast.DelayedPriority - } - -LowPriorityOptional: - { - $$ = false - } -| "LOW_PRIORITY" - { - $$ = true - } - -TableName: - Identifier - { - $$ = &ast.TableName{Name:model.NewCIStr($1.(string))} - } -| Identifier '.' Identifier - { - $$ = &ast.TableName{Schema:model.NewCIStr($1.(string)), Name:model.NewCIStr($3.(string))} - } - -TableNameList: - TableName - { - tbl := []*ast.TableName{$1.(*ast.TableName)} - $$ = tbl - } -| TableNameList ',' TableName - { - $$ = append($1.([]*ast.TableName), $3.(*ast.TableName)) - } - -QuickOptional: - %prec lowerThanQuick - { - $$ = false - } -| "QUICK" - { - $$ = true - } - -/***************************Prepared Statement Start****************************** - * See: https://dev.mysql.com/doc/refman/5.7/en/prepare.html - * Example: - * PREPARE stmt_name FROM 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse'; - * OR - * SET @s = 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse'; - * PREPARE stmt_name FROM @s; - */ - -PreparedStmt: - "PREPARE" Identifier "FROM" PrepareSQL - { - var sqlText string - var sqlVar *ast.VariableExpr - switch $4.(type) { - case string: - sqlText = $4.(string) - case *ast.VariableExpr: - sqlVar = $4.(*ast.VariableExpr) - } - $$ = &ast.PrepareStmt{ - Name: $2.(string), - SQLText: sqlText, - SQLVar: sqlVar, - } - } - -PrepareSQL: - stringLit -| UserVariable - - -/* - * See: https://dev.mysql.com/doc/refman/5.7/en/execute.html - * Example: - * EXECUTE stmt1 USING @a, @b; - * OR - * EXECUTE stmt1; - */ -ExecuteStmt: - "EXECUTE" Identifier - { - $$ = &ast.ExecuteStmt{Name: $2.(string)} - } -| "EXECUTE" Identifier "USING" UserVariableList - { - $$ = &ast.ExecuteStmt{ - Name: $2.(string), - UsingVars: $4.([]ast.ExprNode), - } - } - -UserVariableList: - UserVariable - { - $$ = []ast.ExprNode{$1.(ast.ExprNode)} - } -| UserVariableList ',' UserVariable - { - $$ = append($1.([]ast.ExprNode), $3.(ast.ExprNode)) - } - -/* - * See: https://dev.mysql.com/doc/refman/5.0/en/deallocate-prepare.html - */ - -DeallocateStmt: - DeallocateSym "PREPARE" Identifier - { - $$ = &ast.DeallocateStmt{Name: $3.(string)} - } - -DeallocateSym: - "DEALLOCATE" | "DROP" - -/****************************Prepared Statement End*******************************/ - - -RollbackStmt: - "ROLLBACK" - { - $$ = &ast.RollbackStmt{} - } - -SelectStmt: - "SELECT" SelectStmtOpts SelectStmtFieldList SelectStmtLimit SelectLockOpt - { - st := &ast.SelectStmt { - Distinct: $2.(bool), - Fields: $3.(*ast.FieldList), - LockTp: $5.(ast.SelectLockType), - } - lastField := st.Fields.Fields[len(st.Fields.Fields)-1] - if lastField.Expr != nil && lastField.AsName.O == "" { - src := yylex.(*lexer).src - var lastEnd int - if $4 != nil { - lastEnd = yyS[yypt-1].offset-1 - } else if $5 != ast.SelectLockNone { - lastEnd = yyS[yypt].offset-1 - } else { - lastEnd = len(src) - if src[lastEnd-1] == ';' { - lastEnd-- - } - } - lastField.SetText(src[lastField.Offset:lastEnd]) - } - if $4 != nil { - st.Limit = $4.(*ast.Limit) - } - $$ = st - } -| "SELECT" SelectStmtOpts SelectStmtFieldList FromDual WhereClauseOptional SelectStmtLimit SelectLockOpt - { - st := &ast.SelectStmt { - Distinct: $2.(bool), - Fields: $3.(*ast.FieldList), - LockTp: $7.(ast.SelectLockType), - } - lastField := st.Fields.Fields[len(st.Fields.Fields)-1] - if lastField.Expr != nil && lastField.AsName.O == "" { - lastEnd := yyS[yypt-3].offset-1 - lastField.SetText(yylex.(*lexer).src[lastField.Offset:lastEnd]) - } - if $5 != nil { - st.Where = $5.(ast.ExprNode) - } - if $6 != nil { - st.Limit = $6.(*ast.Limit) - } - $$ = st - } -| "SELECT" SelectStmtOpts SelectStmtFieldList "FROM" - TableRefsClause WhereClauseOptional SelectStmtGroup HavingClause OrderByOptional - SelectStmtLimit SelectLockOpt - { - st := &ast.SelectStmt{ - Distinct: $2.(bool), - Fields: $3.(*ast.FieldList), - From: $5.(*ast.TableRefsClause), - LockTp: $11.(ast.SelectLockType), - } - - lastField := st.Fields.Fields[len(st.Fields.Fields)-1] - if lastField.Expr != nil && lastField.AsName.O == "" { - lastEnd := yyS[yypt-7].offset-1 - lastField.SetText(yylex.(*lexer).src[lastField.Offset:lastEnd]) - } - - if $6 != nil { - st.Where = $6.(ast.ExprNode) - } - - if $7 != nil { - st.GroupBy = $7.(*ast.GroupByClause) - } - - if $8 != nil { - st.Having = $8.(*ast.HavingClause) - } - - if $9 != nil { - st.OrderBy = $9.(*ast.OrderByClause) - } - - if $10 != nil { - st.Limit = $10.(*ast.Limit) - } - - $$ = st - } - -FromDual: - "FROM" "DUAL" - - -TableRefsClause: - TableRefs - { - $$ = &ast.TableRefsClause{TableRefs: $1.(*ast.Join)} - } - -TableRefs: - EscapedTableRef - { - if j, ok := $1.(*ast.Join); ok { - // if $1 is Join, use it directly - $$ = j - } else { - $$ = &ast.Join{Left: $1.(ast.ResultSetNode), Right: nil} - } - } -| TableRefs ',' EscapedTableRef - { - /* from a, b is default cross join */ - $$ = &ast.Join{Left: $1.(ast.ResultSetNode), Right: $3.(ast.ResultSetNode), Tp: ast.CrossJoin} - } - -EscapedTableRef: - TableRef %prec lowerThanSetKeyword - { - $$ = $1 - } -| '{' Identifier TableRef '}' - { - /* - * ODBC escape syntax for outer join is { OJ join_table } - * Use an Identifier for OJ - */ - $$ = $3 - } - -TableRef: - TableFactor - { - $$ = $1 - } -| JoinTable - { - $$ = $1 - } - -TableFactor: - TableName TableAsNameOpt - { - $$ = &ast.TableSource{Source: $1.(*ast.TableName), AsName: $2.(model.CIStr)} - } -| '(' SelectStmt ')' TableAsName - { - st := $2.(*ast.SelectStmt) - l := yylex.(*lexer) - endOffset := l.endOffset(yyS[yypt-1].offset) - l.SetLastSelectFieldText(st, endOffset) - $$ = &ast.TableSource{Source: $2.(*ast.SelectStmt), AsName: $4.(model.CIStr)} - } -| '(' UnionStmt ')' TableAsName - { - $$ = &ast.TableSource{Source: $2.(*ast.UnionStmt), AsName: $4.(model.CIStr)} - } -| '(' TableRefs ')' - { - $$ = $2 - } - -TableAsNameOpt: - { - $$ = model.CIStr{} - } -| TableAsName - { - $$ = $1 - } - -TableAsName: - Identifier - { - $$ = model.NewCIStr($1.(string)) - } -| "AS" Identifier - { - $$ = model.NewCIStr($2.(string)) - } - -JoinTable: - /* Use %prec to evaluate production TableRef before cross join */ - TableRef CrossOpt TableRef %prec tableRefPriority - { - $$ = &ast.Join{Left: $1.(ast.ResultSetNode), Right: $3.(ast.ResultSetNode), Tp: ast.CrossJoin} - } -| TableRef CrossOpt TableRef "ON" Expression - { - on := &ast.OnCondition{Expr: $5.(ast.ExprNode)} - $$ = &ast.Join{Left: $1.(ast.ResultSetNode), Right: $3.(ast.ResultSetNode), Tp: ast.CrossJoin, On: on} - } -| TableRef JoinType OuterOpt "JOIN" TableRef "ON" Expression - { - on := &ast.OnCondition{Expr: $7.(ast.ExprNode)} - $$ = &ast.Join{Left: $1.(ast.ResultSetNode), Right: $5.(ast.ResultSetNode), Tp: $2.(ast.JoinType), On: on} - } - /* Support Using */ - -JoinType: - "LEFT" - { - $$ = ast.LeftJoin - } -| "RIGHT" - { - $$ = ast.RightJoin - } - -OuterOpt: - { - $$ = nil - } -| "OUTER" - - -CrossOpt: - "JOIN" -| "CROSS" "JOIN" -| "INNER" "JOIN" - - -LimitClause: - { - $$ = nil - } -| "LIMIT" LengthNum - { - $$ = &ast.Limit{Count: $2.(uint64)} - } - -SelectStmtLimit: - { - $$ = nil - } -| "LIMIT" LengthNum - { - $$ = &ast.Limit{Count: $2.(uint64)} - } -| "LIMIT" LengthNum ',' LengthNum - { - $$ = &ast.Limit{Offset: $2.(uint64), Count: $4.(uint64)} - } -| "LIMIT" LengthNum "OFFSET" LengthNum - { - $$ = &ast.Limit{Offset: $4.(uint64), Count: $2.(uint64)} - } - -SelectStmtDistinct: - /* EMPTY */ - { - $$ = false - } -| "ALL" - { - $$ = false - } -| "DISTINCT" - { - $$ = true - } - -SelectStmtOpts: - SelectStmtDistinct SelectStmtCalcFoundRows - { - // TODO: return calc_found_rows opt and support more other options - $$ = $1 - } - -SelectStmtCalcFoundRows: - %prec lowerThanCalcFoundRows - { - $$ = false - } -| "SQL_CALC_FOUND_ROWS" - { - $$ = true - } - -SelectStmtFieldList: - FieldList - { - $$ = &ast.FieldList{Fields: $1.([]*ast.SelectField)} - } - -SelectStmtGroup: - /* EMPTY */ - { - $$ = nil - } -| GroupByClause - -// See: https://dev.mysql.com/doc/refman/5.7/en/subqueries.html -SubSelect: - '(' SelectStmt ')' - { - s := $2.(*ast.SelectStmt) - l := yylex.(*lexer) - endOffset := l.endOffset(yyS[yypt].offset) - l.SetLastSelectFieldText(s, endOffset) - src := yylex.(*lexer).src - // See the implemention of yyParse function - s.SetText(src[yyS[yypt-1].offset-1:yyS[yypt].offset-1]) - $$ = &ast.SubqueryExpr{Query: s} - } -| '(' UnionStmt ')' - { - s := $2.(*ast.UnionStmt) - src := yylex.(*lexer).src - // See the implemention of yyParse function - s.SetText(src[yyS[yypt-1].offset-1:yyS[yypt].offset-1]) - $$ = &ast.SubqueryExpr{Query: s} - } - -// See: https://dev.mysql.com/doc/refman/5.7/en/innodb-locking-reads.html -SelectLockOpt: - /* empty */ - { - $$ = ast.SelectLockNone - } -| "FOR" "UPDATE" - { - $$ = ast.SelectLockForUpdate - } -| "LOCK" "IN" "SHARE" "MODE" - { - $$ = ast.SelectLockInShareMode - } - -// See: https://dev.mysql.com/doc/refman/5.7/en/union.html -UnionStmt: - UnionClauseList "UNION" UnionOpt SelectStmt - { - union := $1.(*ast.UnionStmt) - union.Distinct = union.Distinct || $3.(bool) - lastSelect := union.SelectList.Selects[len(union.SelectList.Selects)-1] - l := yylex.(*lexer) - endOffset := l.endOffset(yyS[yypt-2].offset) - l.SetLastSelectFieldText(lastSelect, endOffset) - union.SelectList.Selects = append(union.SelectList.Selects, $4.(*ast.SelectStmt)) - $$ = union - } -| UnionClauseList "UNION" UnionOpt '(' SelectStmt ')' OrderByOptional SelectStmtLimit - { - union := $1.(*ast.UnionStmt) - union.Distinct = union.Distinct || $3.(bool) - lastSelect := union.SelectList.Selects[len(union.SelectList.Selects)-1] - l := yylex.(*lexer) - endOffset := l.endOffset(yyS[yypt-6].offset) - l.SetLastSelectFieldText(lastSelect, endOffset) - st := $5.(*ast.SelectStmt) - endOffset = l.endOffset(yyS[yypt-2].offset) - l.SetLastSelectFieldText(st, endOffset) - union.SelectList.Selects = append(union.SelectList.Selects, st) - if $7 != nil { - union.OrderBy = $7.(*ast.OrderByClause) - } - if $8 != nil { - union.Limit = $8.(*ast.Limit) - } - $$ = union - } - -UnionClauseList: - UnionSelect - { - selectList := &ast.UnionSelectList{Selects: []*ast.SelectStmt{$1.(*ast.SelectStmt)}} - $$ = &ast.UnionStmt{ - SelectList: selectList, - } - } -| UnionClauseList "UNION" UnionOpt UnionSelect - { - union := $1.(*ast.UnionStmt) - union.Distinct = union.Distinct || $3.(bool) - lastSelect := union.SelectList.Selects[len(union.SelectList.Selects)-1] - l := yylex.(*lexer) - endOffset := l.endOffset(yyS[yypt-2].offset) - l.SetLastSelectFieldText(lastSelect, endOffset) - union.SelectList.Selects = append(union.SelectList.Selects, $4.(*ast.SelectStmt)) - $$ = union - } - -UnionSelect: - SelectStmt -| '(' SelectStmt ')' - { - st := $2.(*ast.SelectStmt) - l := yylex.(*lexer) - endOffset := l.endOffset(yyS[yypt].offset) - l.SetLastSelectFieldText(st, endOffset) - $$ = st - } - -UnionOpt: - { - $$ = true - } -| "ALL" - { - $$ = false - } -| "DISTINCT" - { - $$ = true - } - - -/********************Set Statement*******************************/ -SetStmt: - "SET" VariableAssignmentList - { - $$ = &ast.SetStmt{Variables: $2.([]*ast.VariableAssignment)} - } -| "SET" "NAMES" StringName - { - $$ = &ast.SetCharsetStmt{Charset: $3.(string)} - } -| "SET" "NAMES" StringName "COLLATE" StringName - { - $$ = &ast.SetCharsetStmt{ - Charset: $3.(string), - Collate: $5.(string), - } - } -| "SET" CharsetKw StringName - { - $$ = &ast.SetCharsetStmt{Charset: $3.(string)} - } -| "SET" "PASSWORD" eq PasswordOpt - { - $$ = &ast.SetPwdStmt{Password: $4.(string)} - } -| "SET" "PASSWORD" "FOR" Username eq PasswordOpt - { - $$ = &ast.SetPwdStmt{User: $4.(string), Password: $6.(string)} - } -| "SET" "GLOBAL" "TRANSACTION" TransactionChars - { - // Parsed but ignored - } -| "SET" "SESSION" "TRANSACTION" TransactionChars - { - // Parsed but ignored - } - -TransactionChars: - TransactionChar -| TransactionChars ',' TransactionChar - -TransactionChar: - "ISOLATION" "LEVEL" IsolationLevel -| "READ" "WRITE" -| "READ" "ONLY" - -IsolationLevel: - "REPEATABLE" "READ" -| "READ" "COMMITTED" -| "READ" "UNCOMMITTED" -| "SERIALIZABLE" - -VariableAssignment: - Identifier eq Expression - { - $$ = &ast.VariableAssignment{Name: $1.(string), Value: $3.(ast.ExprNode), IsSystem: true} - } -| "GLOBAL" Identifier eq Expression - { - $$ = &ast.VariableAssignment{Name: $2.(string), Value: $4.(ast.ExprNode), IsGlobal: true, IsSystem: true} - } -| "SESSION" Identifier eq Expression - { - $$ = &ast.VariableAssignment{Name: $2.(string), Value: $4.(ast.ExprNode), IsSystem: true} - } -| "LOCAL" Identifier eq Expression - { - $$ = &ast.VariableAssignment{Name: $2.(string), Value: $4.(ast.ExprNode), IsSystem: true} - } -| "SYS_VAR" eq Expression - { - v := strings.ToLower($1.(string)) - var isGlobal bool - if strings.HasPrefix(v, "@@global.") { - isGlobal = true - v = strings.TrimPrefix(v, "@@global.") - } else if strings.HasPrefix(v, "@@session.") { - v = strings.TrimPrefix(v, "@@session.") - } else if strings.HasPrefix(v, "@@local.") { - v = strings.TrimPrefix(v, "@@local.") - } else if strings.HasPrefix(v, "@@") { - v = strings.TrimPrefix(v, "@@") - } - $$ = &ast.VariableAssignment{Name: v, Value: $3.(ast.ExprNode), IsGlobal: isGlobal, IsSystem: true} - } -| "USER_VAR" eq Expression - { - v := $1.(string) - v = strings.TrimPrefix(v, "@") - $$ = &ast.VariableAssignment{Name: v, Value: $3.(ast.ExprNode)} - } - -VariableAssignmentList: - { - $$ = []*ast.VariableAssignment{} - } -| VariableAssignment - { - $$ = []*ast.VariableAssignment{$1.(*ast.VariableAssignment)} - } -| VariableAssignmentList ',' VariableAssignment - { - $$ = append($1.([]*ast.VariableAssignment), $3.(*ast.VariableAssignment)) - } - -Variable: - SystemVariable | UserVariable - -SystemVariable: - "SYS_VAR" - { - v := strings.ToLower($1.(string)) - var isGlobal bool - if strings.HasPrefix(v, "@@global.") { - isGlobal = true - v = strings.TrimPrefix(v, "@@global.") - } else if strings.HasPrefix(v, "@@session.") { - v = strings.TrimPrefix(v, "@@session.") - } else if strings.HasPrefix(v, "@@local.") { - v = strings.TrimPrefix(v, "@@local.") - } else if strings.HasPrefix(v, "@@") { - v = strings.TrimPrefix(v, "@@") - } - $$ = &ast.VariableExpr{Name: v, IsGlobal: isGlobal, IsSystem: true} - } - -UserVariable: - "USER_VAR" - { - v := $1.(string) - v = strings.TrimPrefix(v, "@") - $$ = &ast.VariableExpr{Name: v, IsGlobal: false, IsSystem: false} - } - -Username: - stringLit "AT" stringLit - { - $$ = $1.(string) + "@" + $3.(string) - } - -PasswordOpt: - stringLit - { - $$ = $1.(string) - } -| "PASSWORD" '(' AuthString ')' - { - $$ = $3.(string) - } - -AuthString: - stringLit - { - $$ = $1.(string) - } - -/****************************Admin Statement*******************************/ -AdminStmt: - "ADMIN" "SHOW" "DDL" - { - $$ = &ast.AdminStmt{Tp: ast.AdminShowDDL} - } -| "ADMIN" "CHECK" "TABLE" TableNameList - { - $$ = &ast.AdminStmt{ - Tp: ast.AdminCheckTable, - Tables: $4.([]*ast.TableName), - } - } - -/****************************Show Statement*******************************/ -ShowStmt: - "SHOW" ShowTargetFilterable ShowLikeOrWhereOpt - { - stmt := $2.(*ast.ShowStmt) - if $3 != nil { - if x, ok := $3.(*ast.PatternLikeExpr); ok { - stmt.Pattern = x - } else { - stmt.Where = $3.(ast.ExprNode) - } - } - $$ = stmt - } -| "SHOW" "CREATE" "TABLE" TableName - { - $$ = &ast.ShowStmt{ - Tp: ast.ShowCreateTable, - Table: $4.(*ast.TableName), - } - } -| "SHOW" "GRANTS" - { - // See: https://dev.mysql.com/doc/refman/5.7/en/show-grants.html - $$ = &ast.ShowStmt{Tp: ast.ShowGrants} - } -| "SHOW" "GRANTS" "FOR" Username - { - // See: https://dev.mysql.com/doc/refman/5.7/en/show-grants.html - $$ = &ast.ShowStmt{ - Tp: ast.ShowGrants, - User: $4.(string), - } - } -| "SHOW" "INDEX" "FROM" TableName - { - $$ = &ast.ShowStmt{ - Tp: ast.ShowIndex, - Table: $4.(*ast.TableName), - } - } - -ShowTargetFilterable: - "ENGINES" - { - $$ = &ast.ShowStmt{Tp: ast.ShowEngines} - } -| "DATABASES" - { - $$ = &ast.ShowStmt{Tp: ast.ShowDatabases} - } -| "SCHEMAS" - { - $$ = &ast.ShowStmt{Tp: ast.ShowDatabases} - } -| "CHARACTER" "SET" - { - $$ = &ast.ShowStmt{Tp: ast.ShowCharset} - } -| OptFull "TABLES" ShowDatabaseNameOpt - { - $$ = &ast.ShowStmt{ - Tp: ast.ShowTables, - DBName: $3.(string), - Full: $1.(bool), - } - } -| "TABLE" "STATUS" ShowDatabaseNameOpt - { - $$ = &ast.ShowStmt{ - Tp: ast.ShowTableStatus, - DBName: $3.(string), - } - } -| OptFull "COLUMNS" ShowTableAliasOpt ShowDatabaseNameOpt - { - $$ = &ast.ShowStmt{ - Tp: ast.ShowColumns, - Table: $3.(*ast.TableName), - DBName: $4.(string), - Full: $1.(bool), - } - } -| OptFull "FIELDS" ShowTableAliasOpt ShowDatabaseNameOpt - { - // SHOW FIELDS is a synonym for SHOW COLUMNS. - $$ = &ast.ShowStmt{ - Tp: ast.ShowColumns, - Table: $3.(*ast.TableName), - DBName: $4.(string), - Full: $1.(bool), - } - } -| "WARNINGS" - { - $$ = &ast.ShowStmt{Tp: ast.ShowWarnings} - } -| GlobalScope "VARIABLES" - { - $$ = &ast.ShowStmt{ - Tp: ast.ShowVariables, - GlobalScope: $1.(bool), - } - } -| GlobalScope "STATUS" - { - $$ = &ast.ShowStmt{ - Tp: ast.ShowStatus, - GlobalScope: $1.(bool), - } - } -| "COLLATION" - { - $$ = &ast.ShowStmt{ - Tp: ast.ShowCollation, - } - } -| "TRIGGERS" ShowDatabaseNameOpt - { - $$ = &ast.ShowStmt{ - Tp: ast.ShowTriggers, - DBName: $2.(string), - } - } -| "PROCEDURE" "STATUS" - { - $$ = &ast.ShowStmt { - Tp: ast.ShowProcedureStatus, - } - } - -ShowLikeOrWhereOpt: - { - $$ = nil - } -| "LIKE" PrimaryExpression - { - $$ = &ast.PatternLikeExpr{Pattern: $2.(ast.ExprNode)} - } -| "WHERE" Expression - { - $$ = $2.(ast.ExprNode) - } - -GlobalScope: - { - $$ = false - } -| "GLOBAL" - { - $$ = true - } -| "SESSION" - { - $$ = false - } - -OptFull: - { - $$ = false - } -| "FULL" - { - $$ = true - } - -ShowDatabaseNameOpt: - { - $$ = "" - } -| "FROM" DBName - { - $$ = $2.(string) - } -| "IN" DBName - { - $$ = $2.(string) - } - -ShowTableAliasOpt: - "FROM" TableName - { - $$ = $2.(*ast.TableName) - } -| "IN" TableName - { - $$ = $2.(*ast.TableName) - } - -Statement: - EmptyStmt -| AdminStmt -| AlterTableStmt -| BeginTransactionStmt -| CommitStmt -| DeallocateStmt -| DeleteFromStmt -| ExecuteStmt -| ExplainStmt -| CreateDatabaseStmt -| CreateIndexStmt -| CreateTableStmt -| CreateUserStmt -| DoStmt -| DropDatabaseStmt -| DropIndexStmt -| DropTableStmt -| GrantStmt -| InsertIntoStmt -| PreparedStmt -| RollbackStmt -| ReplaceIntoStmt -| SelectStmt -| UnionStmt -| SetStmt -| ShowStmt -| TruncateTableStmt -| UpdateStmt -| UseStmt -| SubSelect - { - // `(select 1)`; is a valid select statement - // TODO: This is used to fix issue #320. There may be a better solution. - $$ = $1.(*ast.SubqueryExpr).Query - } -| UnlockTablesStmt -| LockTablesStmt - -ExplainableStmt: - SelectStmt -| DeleteFromStmt -| UpdateStmt -| InsertIntoStmt -| ReplaceIntoStmt - -StatementList: - Statement - { - if $1 != nil { - s := $1.(ast.StmtNode) - s.SetText(yylex.(*lexer).stmtText()) - yylex.(*lexer).list = append(yylex.(*lexer).list, s) - } - } -| StatementList ';' Statement - { - if $3 != nil { - s := $3.(ast.StmtNode) - s.SetText(yylex.(*lexer).stmtText()) - yylex.(*lexer).list = append(yylex.(*lexer).list, s) - } - } - -Constraint: - ConstraintKeywordOpt ConstraintElem - { - cst := $2.(*ast.Constraint) - if $1 != nil { - cst.Name = $1.(string) - } - $$ = cst - } - -TableElement: - ColumnDef - { - $$ = $1.(*ast.ColumnDef) - } -| Constraint - { - $$ = $1.(*ast.Constraint) - } -| "CHECK" '(' Expression ')' - { - /* Nothing to do now */ - $$ = nil - } - -TableElementList: - TableElement - { - if $1 != nil { - $$ = []interface{}{$1.(interface{})} - } else { - $$ = []interface{}{} - } - } -| TableElementList ',' TableElement - { - if $3 != nil { - $$ = append($1.([]interface{}), $3) - } else { - $$ = $1 - } - } - -TableOption: - "ENGINE" Identifier - { - $$ = &ast.TableOption{Tp: ast.TableOptionEngine, StrValue: $2.(string)} - } -| "ENGINE" eq Identifier - { - $$ = &ast.TableOption{Tp: ast.TableOptionEngine, StrValue: $3.(string)} - } -| DefaultKwdOpt CharsetKw EqOpt StringName - { - $$ = &ast.TableOption{Tp: ast.TableOptionCharset, StrValue: $4.(string)} - } -| DefaultKwdOpt "COLLATE" EqOpt StringName - { - $$ = &ast.TableOption{Tp: ast.TableOptionCollate, StrValue: $4.(string)} - } -| "AUTO_INCREMENT" eq LengthNum - { - $$ = &ast.TableOption{Tp: ast.TableOptionAutoIncrement, UintValue: $3.(uint64)} - } -| "COMMENT" EqOpt stringLit - { - $$ = &ast.TableOption{Tp: ast.TableOptionComment, StrValue: $3.(string)} - } -| "AVG_ROW_LENGTH" EqOpt LengthNum - { - $$ = &ast.TableOption{Tp: ast.TableOptionAvgRowLength, UintValue: $3.(uint64)} - } -| "CONNECTION" EqOpt stringLit - { - $$ = &ast.TableOption{Tp: ast.TableOptionConnection, StrValue: $3.(string)} - } -| "CHECKSUM" EqOpt LengthNum - { - $$ = &ast.TableOption{Tp: ast.TableOptionCheckSum, UintValue: $3.(uint64)} - } -| "PASSWORD" EqOpt stringLit - { - $$ = &ast.TableOption{Tp: ast.TableOptionPassword, StrValue: $3.(string)} - } -| "COMPRESSION" EqOpt Identifier - { - $$ = &ast.TableOption{Tp: ast.TableOptionCompression, StrValue: $3.(string)} - } -| "KEY_BLOCK_SIZE" EqOpt LengthNum - { - $$ = &ast.TableOption{Tp: ast.TableOptionKeyBlockSize, UintValue: $3.(uint64)} - } -| "MAX_ROWS" EqOpt LengthNum - { - $$ = &ast.TableOption{Tp: ast.TableOptionMaxRows, UintValue: $3.(uint64)} - } -| "MIN_ROWS" EqOpt LengthNum - { - $$ = &ast.TableOption{Tp: ast.TableOptionMinRows, UintValue: $3.(uint64)} - } -| "DELAY_KEY_WRITE" EqOpt LengthNum - { - $$ = &ast.TableOption{Tp: ast.TableOptionDelayKeyWrite, UintValue: $3.(uint64)} - } -| RowFormat - { - $$ = &ast.TableOption{Tp: ast.TableOptionRowFormat, UintValue: $1.(uint64)} - } - - -TableOptionListOpt: - { - $$ = []*ast.TableOption{} - } -| TableOptionList %prec lowerThanComma - -TableOptionList: - TableOption - { - $$ = []*ast.TableOption{$1.(*ast.TableOption)} - } -| TableOptionList TableOption - { - $$ = append($1.([]*ast.TableOption), $2.(*ast.TableOption)) - } -| TableOptionList ',' TableOption - { - $$ = append($1.([]*ast.TableOption), $3.(*ast.TableOption)) - } - - -TruncateTableStmt: - "TRUNCATE" "TABLE" TableName - { - $$ = &ast.TruncateTableStmt{Table: $3.(*ast.TableName)} - } - -RowFormat: - "ROW_FORMAT" EqOpt "DEFAULT" - { - $$ = ast.RowFormatDefault - } -| "ROW_FORMAT" EqOpt "DYNAMIC" - { - $$ = ast.RowFormatDynamic - } -| "ROW_FORMAT" EqOpt "FIXED" - { - $$ = ast.RowFormatFixed - } -| "ROW_FORMAT" EqOpt "COMPRESSED" - { - $$ = ast.RowFormatCompressed - } -| "ROW_FORMAT" EqOpt "REDUNDANT" - { - $$ = ast.RowFormatRedundant - } -| "ROW_FORMAT" EqOpt "COMPACT" - { - $$ = ast.RowFormatCompact - } - -/*************************************Type Begin***************************************/ -Type: - NumericType - { - $$ = $1 - } -| StringType - { - $$ = $1 - } -| DateAndTimeType - { - $$ = $1 - } -| "float32" - { - x := types.NewFieldType($1.(byte)) - $$ = x - } -| "float64" - { - x := types.NewFieldType($1.(byte)) - $$ = x - } -| "int64" - { - x := types.NewFieldType($1.(byte)) - $$ = x - } -| "string" - { - x := types.NewFieldType($1.(byte)) - $$ = x - } -| "uint" - { - x := types.NewFieldType($1.(byte)) - $$ = x - } -| "uint64" - { - x := types.NewFieldType($1.(byte)) - $$ = x - } - -NumericType: - IntegerType OptFieldLen FieldOpts - { - // TODO: check flen 0 - x := types.NewFieldType($1.(byte)) - x.Flen = $2.(int) - for _, o := range $3.([]*ast.TypeOpt) { - if o.IsUnsigned { - x.Flag |= mysql.UnsignedFlag - } - if o.IsZerofill { - x.Flag |= mysql.ZerofillFlag - } - } - $$ = x - } -| FixedPointType FloatOpt FieldOpts - { - fopt := $2.(*ast.FloatOpt) - x := types.NewFieldType($1.(byte)) - x.Flen = fopt.Flen - x.Decimal = fopt.Decimal - for _, o := range $3.([]*ast.TypeOpt) { - if o.IsUnsigned { - x.Flag |= mysql.UnsignedFlag - } - if o.IsZerofill { - x.Flag |= mysql.ZerofillFlag - } - } - $$ = x - } -| FloatingPointType FloatOpt FieldOpts - { - fopt := $2.(*ast.FloatOpt) - x := types.NewFieldType($1.(byte)) - x.Flen = fopt.Flen - if x.Tp == mysql.TypeFloat { - // Fix issue #312 - if x.Flen > 53 { - yylex.(*lexer).errf("Float len(%d) should not be greater than 53", x.Flen) - return 1 - } - if x.Flen > 24 { - x.Tp = mysql.TypeDouble - } - } - x.Decimal =fopt.Decimal - for _, o := range $3.([]*ast.TypeOpt) { - if o.IsUnsigned { - x.Flag |= mysql.UnsignedFlag - } - if o.IsZerofill { - x.Flag |= mysql.ZerofillFlag - } - } - $$ = x - } -| BitValueType OptFieldLen - { - x := types.NewFieldType($1.(byte)) - x.Flen = $2.(int) - if x.Flen == -1 || x.Flen == 0 { - x.Flen = 1 - } else if x.Flen > 64 { - yylex.(*lexer).errf("invalid field length %d for bit type, must in [1, 64]", x.Flen) - } - $$ = x - } - -IntegerType: - "TINYINT" - { - $$ = mysql.TypeTiny - } -| "SMALLINT" - { - $$ = mysql.TypeShort - } -| "MEDIUMINT" - { - $$ = mysql.TypeInt24 - } -| "INT" - { - $$ = mysql.TypeLong - } -| "INTEGER" - { - $$ = mysql.TypeLong - } -| "BIGINT" - { - $$ = mysql.TypeLonglong - } -| "BOOL" - { - $$ = mysql.TypeTiny - } -| "BOOLEAN" - { - $$ = mysql.TypeTiny - } - -OptInteger: - {} | "INTEGER" - -FixedPointType: - "DECIMAL" - { - $$ = mysql.TypeNewDecimal - } -| "NUMERIC" - { - $$ = mysql.TypeNewDecimal - } - -FloatingPointType: - "float" - { - $$ = mysql.TypeFloat - } -| "REAL" - { - $$ = mysql.TypeDouble - } -| "DOUBLE" - { - $$ = mysql.TypeDouble - } -| "DOUBLE" "PRECISION" - { - $$ = mysql.TypeDouble - } - -BitValueType: - "BIT" - { - $$ = mysql.TypeBit - } - -StringType: - NationalOpt "CHAR" FieldLen OptBinary OptCharset OptCollate - { - x := types.NewFieldType(mysql.TypeString) - x.Flen = $3.(int) - if $4.(bool) { - x.Flag |= mysql.BinaryFlag - } - $$ = x - } -| NationalOpt "CHAR" OptBinary OptCharset OptCollate - { - x := types.NewFieldType(mysql.TypeString) - if $3.(bool) { - x.Flag |= mysql.BinaryFlag - } - $$ = x - } -| NationalOpt "VARCHAR" FieldLen OptBinary OptCharset OptCollate - { - x := types.NewFieldType(mysql.TypeVarchar) - x.Flen = $3.(int) - if $4.(bool) { - x.Flag |= mysql.BinaryFlag - } - x.Charset = $5.(string) - x.Collate = $6.(string) - $$ = x - } -| "BINARY" OptFieldLen - { - x := types.NewFieldType(mysql.TypeString) - x.Flen = $2.(int) - x.Charset = charset.CharsetBin - x.Collate = charset.CharsetBin - $$ = x - } -| "VARBINARY" FieldLen - { - x := types.NewFieldType(mysql.TypeVarchar) - x.Flen = $2.(int) - x.Charset = charset.CharsetBin - x.Collate = charset.CharsetBin - $$ = x - } -| BlobType - { - $$ = $1.(*types.FieldType) - } -| TextType OptBinary OptCharset OptCollate - { - x := $1.(*types.FieldType) - if $2.(bool) { - x.Flag |= mysql.BinaryFlag - } - x.Charset = $3.(string) - x.Collate = $4.(string) - $$ = x - } -| "ENUM" '(' StringList ')' OptCharset OptCollate - { - x := types.NewFieldType(mysql.TypeEnum) - x.Elems = $3.([]string) - x.Charset = $5.(string) - x.Collate = $6.(string) - $$ = x - } -| "SET" '(' StringList ')' OptCharset OptCollate - { - x := types.NewFieldType(mysql.TypeSet) - x.Elems = $3.([]string) - x.Charset = $5.(string) - x.Collate = $6.(string) - $$ = x - } - -NationalOpt: - { - - } -| "NATIONAL" - { - - } - -BlobType: - "TINYBLOB" - { - x := types.NewFieldType(mysql.TypeTinyBlob) - x.Charset = charset.CharsetBin - x.Collate = charset.CharsetBin - $$ = x - } -| "BLOB" OptFieldLen - { - x := types.NewFieldType(mysql.TypeBlob) - x.Flen = $2.(int) - x.Charset = charset.CharsetBin - x.Collate = charset.CharsetBin - $$ = x - } -| "MEDIUMBLOB" - { - x := types.NewFieldType(mysql.TypeMediumBlob) - x.Charset = charset.CharsetBin - x.Collate = charset.CharsetBin - $$ = x - } -| "LONGBLOB" - { - x := types.NewFieldType(mysql.TypeLongBlob) - x.Charset = charset.CharsetBin - x.Collate = charset.CharsetBin - $$ = x - } - -TextType: - "TINYTEXT" - { - x := types.NewFieldType(mysql.TypeTinyBlob) - $$ = x - - } -| "TEXT" OptFieldLen - { - x := types.NewFieldType(mysql.TypeBlob) - x.Flen = $2.(int) - $$ = x - } -| "MEDIUMTEXT" - { - x := types.NewFieldType(mysql.TypeMediumBlob) - $$ = x - } -| "LONGTEXT" - { - x := types.NewFieldType(mysql.TypeLongBlob) - $$ = x - } - - -DateAndTimeType: - "DATE" - { - x := types.NewFieldType(mysql.TypeDate) - $$ = x - } -| "DATETIME" OptFieldLen - { - x := types.NewFieldType(mysql.TypeDatetime) - x.Decimal = $2.(int) - $$ = x - } -| "TIMESTAMP" OptFieldLen - { - x := types.NewFieldType(mysql.TypeTimestamp) - x.Decimal = $2.(int) - $$ = x - } -| "TIME" OptFieldLen - { - x := types.NewFieldType(mysql.TypeDuration) - x.Decimal = $2.(int) - $$ = x - } -| "YEAR" OptFieldLen - { - x := types.NewFieldType(mysql.TypeYear) - x.Flen = $2.(int) - $$ = x - } - -FieldLen: - '(' LengthNum ')' - { - $$ = int($2.(uint64)) - } - -OptFieldLen: - { - /* -1 means unspecified field length*/ - $$ = types.UnspecifiedLength - } -| FieldLen - { - $$ = $1.(int) - } - -FieldOpt: - "UNSIGNED" - { - $$ = &ast.TypeOpt{IsUnsigned: true} - } -| "ZEROFILL" - { - $$ = &ast.TypeOpt{IsZerofill: true, IsUnsigned: true} - } - -FieldOpts: - { - $$ = []*ast.TypeOpt{} - } -| FieldOpts FieldOpt - { - $$ = append($1.([]*ast.TypeOpt), $2.(*ast.TypeOpt)) - } - -FloatOpt: - { - $$ = &ast.FloatOpt{Flen: types.UnspecifiedLength, Decimal: types.UnspecifiedLength} - } -| FieldLen - { - $$ = &ast.FloatOpt{Flen: $1.(int), Decimal: types.UnspecifiedLength} - } -| Precision - { - $$ = $1.(*ast.FloatOpt) - } - -Precision: - '(' LengthNum ',' LengthNum ')' - { - $$ = &ast.FloatOpt{Flen: int($2.(uint64)), Decimal: int($4.(uint64))} - } - -OptBinary: - { - $$ = false - } -| "BINARY" - { - $$ = true - } - -OptCharset: - { - $$ = "" - } -| CharsetKw StringName - { - $$ = $2.(string) - } - -CharsetKw: - "CHARACTER" "SET" -| "CHARSET" - -OptCollate: - { - $$ = "" - } -| "COLLATE" StringName - { - $$ = $2.(string) - } - -StringList: - stringLit - { - $$ = []string{$1.(string)} - } -| StringList ',' stringLit - { - $$ = append($1.([]string), $3.(string)) - } - -StringName: - stringLit - { - $$ = $1.(string) - } -| Identifier - { - $$ = $1.(string) - } - -/*********************************************************************************** - * Update Statement - * See: https://dev.mysql.com/doc/refman/5.7/en/update.html - ***********************************************************************************/ -UpdateStmt: - "UPDATE" LowPriorityOptional IgnoreOptional TableRef "SET" AssignmentList WhereClauseOptional OrderByOptional LimitClause - { - var refs *ast.Join - if x, ok := $4.(*ast.Join); ok { - refs = x - } else { - refs = &ast.Join{Left: $4.(ast.ResultSetNode)} - } - st := &ast.UpdateStmt{ - LowPriority: $2.(bool), - TableRefs: &ast.TableRefsClause{TableRefs: refs}, - List: $6.([]*ast.Assignment), - } - if $7 != nil { - st.Where = $7.(ast.ExprNode) - } - if $8 != nil { - st.Order = $8.(*ast.OrderByClause) - } - if $9 != nil { - st.Limit = $9.(*ast.Limit) - } - $$ = st - if yylex.(*lexer).root { - break - } - } -| "UPDATE" LowPriorityOptional IgnoreOptional TableRefs "SET" AssignmentList WhereClauseOptional - { - st := &ast.UpdateStmt{ - LowPriority: $2.(bool), - TableRefs: &ast.TableRefsClause{TableRefs: $4.(*ast.Join)}, - List: $6.([]*ast.Assignment), - } - if $7 != nil { - st.Where = $7.(ast.ExprNode) - } - $$ = st - if yylex.(*lexer).root { - break - } - } - -UseStmt: - "USE" DBName - { - $$ = &ast.UseStmt{DBName: $2.(string)} - if yylex.(*lexer).root { - break - } - } - -WhereClause: - "WHERE" Expression - { - $$ = $2.(ast.ExprNode) - } - -WhereClauseOptional: - { - $$ = nil - } -| WhereClause - { - $$ = $1 - } - -CommaOpt: - { - } -| ',' - { - } - -/************************************************************************************ - * Account Management Statements - * https://dev.mysql.com/doc/refman/5.7/en/account-management-sql.html - ************************************************************************************/ -CreateUserStmt: - "CREATE" "USER" IfNotExists UserSpecList - { - // See: https://dev.mysql.com/doc/refman/5.7/en/create-user.html - $$ = &ast.CreateUserStmt{ - IfNotExists: $3.(bool), - Specs: $4.([]*ast.UserSpec), - } - } - -UserSpec: - Username AuthOption - { - userSpec := &ast.UserSpec{ - User: $1.(string), - } - if $2 != nil { - userSpec.AuthOpt = $2.(*ast.AuthOption) - } - $$ = userSpec - } - -UserSpecList: - UserSpec - { - $$ = []*ast.UserSpec{$1.(*ast.UserSpec)} - } -| UserSpecList ',' UserSpec - { - $$ = append($1.([]*ast.UserSpec), $3.(*ast.UserSpec)) - } - -AuthOption: - { - $$ = nil - } -| "IDENTIFIED" "BY" AuthString - { - $$ = &ast.AuthOption { - AuthString: $3.(string), - ByAuthString: true, - } - } -| "IDENTIFIED" "BY" "PASSWORD" HashString - { - $$ = &ast.AuthOption{ - HashString: $4.(string), - } - } - -HashString: - stringLit - -/************************************************************************************* - * Grant statement - * See: https://dev.mysql.com/doc/refman/5.7/en/grant.html - *************************************************************************************/ -GrantStmt: - "GRANT" PrivElemList "ON" ObjectType PrivLevel "TO" UserSpecList - { - $$ = &ast.GrantStmt{ - Privs: $2.([]*ast.PrivElem), - ObjectType: $4.(ast.ObjectTypeType), - Level: $5.(*ast.GrantLevel), - Users: $7.([]*ast.UserSpec), - } - } - -PrivElem: - PrivType - { - $$ = &ast.PrivElem{ - Priv: $1.(mysql.PrivilegeType), - } - } -| PrivType '(' ColumnNameList ')' - { - $$ = &ast.PrivElem{ - Priv: $1.(mysql.PrivilegeType), - Cols: $3.([]*ast.ColumnName), - } - } - -PrivElemList: - PrivElem - { - $$ = []*ast.PrivElem{$1.(*ast.PrivElem)} - } -| PrivElemList ',' PrivElem - { - $$ = append($1.([]*ast.PrivElem), $3.(*ast.PrivElem)) - } - -PrivType: - "ALL" - { - $$ = mysql.AllPriv - } -| "ALTER" - { - $$ = mysql.AlterPriv - } -| "CREATE" - { - $$ = mysql.CreatePriv - } -| "CREATE" "USER" - { - $$ = mysql.CreateUserPriv - } -| "DELETE" - { - $$ = mysql.DeletePriv - } -| "DROP" - { - $$ = mysql.DropPriv - } -| "EXECUTE" - { - $$ = mysql.ExecutePriv - } -| "INDEX" - { - $$ = mysql.IndexPriv - } -| "INSERT" - { - $$ = mysql.InsertPriv - } -| "SELECT" - { - $$ = mysql.SelectPriv - } -| "SHOW" "DATABASES" - { - $$ = mysql.ShowDBPriv - } -| "UPDATE" - { - $$ = mysql.UpdatePriv - } -| "GRANT" "OPTION" - { - $$ = mysql.GrantPriv - } - -ObjectType: - { - $$ = ast.ObjectTypeNone - } -| "TABLE" - { - $$ = ast.ObjectTypeTable - } - -PrivLevel: - '*' - { - $$ = &ast.GrantLevel { - Level: ast.GrantLevelDB, - } - } -| '*' '.' '*' - { - $$ = &ast.GrantLevel { - Level: ast.GrantLevelGlobal, - } - } -| Identifier '.' '*' - { - $$ = &ast.GrantLevel { - Level: ast.GrantLevelDB, - DBName: $1.(string), - } - } -| Identifier '.' Identifier - { - $$ = &ast.GrantLevel { - Level: ast.GrantLevelTable, - DBName: $1.(string), - TableName: $3.(string), - } - } -| Identifier - { - $$ = &ast.GrantLevel { - Level: ast.GrantLevelTable, - TableName: $1.(string), - } - } - -/********************************************************************* - * Lock/Unlock Tables - * See: http://dev.mysql.com/doc/refman/5.7/en/lock-tables.html - * All the statement leaves empty. This is used to prevent mysqldump error. - *********************************************************************/ - -UnlockTablesStmt: - "UNLOCK" "TABLES" - -LockTablesStmt: - "LOCK" "TABLES" TableLockList - -TableLock: - TableName LockType - -LockType: - "READ" -| "READ" "LOCAL" -| "WRITE" - -TableLockList: - TableLock -| TableLockList ',' TableLock - -%% diff --git a/vendor/github.com/pingcap/tidb/parser/scanner.l b/vendor/github.com/pingcap/tidb/parser/scanner.l deleted file mode 100644 index a322b4080e..0000000000 --- a/vendor/github.com/pingcap/tidb/parser/scanner.l +++ /dev/null @@ -1,1259 +0,0 @@ -%{ -// Copyright 2013 The ql Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSES/QL-LICENSE file. - -// Copyright 2015 PingCAP, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// See the License for the specific language governing permissions and -// limitations under the License. - -package parser - -import ( - "fmt" - "math" - "strconv" - "strings" - "unicode" - - "github.com/pingcap/tidb/ast" - "github.com/pingcap/tidb/mysql" - "github.com/pingcap/tidb/util/charset" - "github.com/pingcap/tidb/util/stringutil" -) - -type lexer struct { - c int - col int - errs []error - expr ast.ExprNode - i int - inj int - lcol int - line int - list []ast.StmtNode - ncol int - nline int - sc int - src string - val []byte - ungetBuf []byte - root bool - prepare bool - stmtStartPos int - stringLit []byte - - // record token's offset of the input - tokenEndOffset int - tokenStartOffset int - - // Charset information - charset string - collation string -} - - -// NewLexer builds a new lexer. -func NewLexer(src string) (l *lexer) { - l = &lexer{ - src: src, - nline: 1, - ncol: 0, - } - l.next() - return -} - -func (l *lexer) Errors() []error { - return l.errs -} - -func (l *lexer) Stmts() []ast.StmtNode { - return l.list -} - -func (l *lexer) Expr() ast.ExprNode { - return l.expr -} - -func (l *lexer) Inj() int { - return l.inj -} - -func (l *lexer) SetInj(inj int) { - l.inj = inj -} - -func (l *lexer) SetPrepare() { - l.prepare = true -} - -func (l *lexer) IsPrepare() bool { - return l.prepare -} - -func (l *lexer) Root() bool { - return l.root -} - -func (l *lexer) SetRoot(root bool) { - l.root = root -} - -func (l *lexer) SetCharsetInfo(charset, collation string) { - l.charset = charset - l.collation = collation -} - -func (l *lexer) GetCharsetInfo() (string, string) { - return l.charset, l.collation -} - -// The select statement is not at the end of the whole statement, if the last -// field text was set from its offset to the end of the src string, update -// the last field text. -func (l *lexer) SetLastSelectFieldText(st *ast.SelectStmt, lastEnd int) { - lastField := st.Fields.Fields[len(st.Fields.Fields)-1] - if lastField.Offset + len(lastField.Text()) >= len(l.src)-1 { - lastField.SetText(l.src[lastField.Offset:lastEnd]) - } -} - -func (l *lexer) startOffset(offset int) int { - offset-- - for unicode.IsSpace(rune(l.src[offset])) { - offset++ - } - return offset -} - -func (l *lexer) endOffset(offset int) int { - offset-- - for offset > 0 && unicode.IsSpace(rune(l.src[offset-1])) { - offset-- - } - return offset -} - -func (l *lexer) unget(b byte) { - l.ungetBuf = append(l.ungetBuf, b) - l.i-- - l.ncol-- - l.tokenEndOffset-- -} - -func (l *lexer) next() int { - if un := len(l.ungetBuf); un > 0 { - nc := l.ungetBuf[0] - l.ungetBuf = l.ungetBuf[1:] - l.c = int(nc) - return l.c - } - - if l.c != 0 { - l.val = append(l.val, byte(l.c)) - } - l.c = 0 - if l.i < len(l.src) { - l.c = int(l.src[l.i]) - l.i++ - } - switch l.c { - case '\n': - l.lcol = l.ncol - l.nline++ - l.ncol = 0 - default: - l.ncol++ - } - l.tokenEndOffset++ - return l.c -} - -func (l *lexer) err0(ln, c int, arg interface{}) { - var argStr string - if arg != nil { - argStr = fmt.Sprintf(" %v", arg) - } - - err := fmt.Errorf("line %d column %d near \"%s\"%s", ln, c, l.val, argStr) - l.errs = append(l.errs, err) -} - -func (l *lexer) err(arg interface{}) { - l.err0(l.line, l.col, arg) -} - -func (l *lexer) errf(format string, args ...interface{}) { - s := fmt.Sprintf(format, args...) - l.err0(l.line, l.col, s) -} - -func (l *lexer) Error(s string) { - // Notice: ignore origin error info. - l.err(nil) -} - -func (l *lexer) stmtText() string { - endPos := l.i - if l.src[l.i-1] == '\n' { - endPos = l.i-1 // trim new line - } - if l.src[l.stmtStartPos] == '\n' { - l.stmtStartPos++ - } - - text := l.src[l.stmtStartPos:endPos] - - l.stmtStartPos = l.i - return text -} - - -func (l *lexer) Lex(lval *yySymType) (r int) { - defer func() { - lval.line, lval.col, lval.offset = l.line, l.col, l.tokenStartOffset - l.tokenStartOffset = l.tokenEndOffset - }() - const ( - INITIAL = iota - S1 - S2 - S3 - S4 - ) - - if n := l.inj; n != 0 { - l.inj = 0 - return n - } - - c0, c := 0, l.c -%} - -int_lit {decimal_lit}|{octal_lit} -decimal_lit [1-9][0-9]* -octal_lit 0[0-7]* -hex_lit 0[xX][0-9a-fA-F]+|[xX]"'"[0-9a-fA-F]+"'" -bit_lit 0[bB][01]+|[bB]"'"[01]+"'" - -float_lit {D}"."{D}?{E}?|{D}{E}|"."{D}{E}? -D [0-9]+ -E [eE][-+]?[0-9]+ - -imaginary_ilit {D}i -imaginary_lit {float_lit}i - -a [aA] -b [bB] -c [cC] -d [dD] -e [eE] -f [fF] -g [gG] -h [hH] -i [iI] -j [jJ] -k [kK] -l [lL] -m [mM] -n [nN] -o [oO] -p [pP] -q [qQ] -r [rR] -s [sS] -t [tT] -u [uU] -v [vV] -w [wW] -x [xX] -y [yY] -z [zZ] - -abs {a}{b}{s} -add {a}{d}{d} -adddate {a}{d}{d}{d}{a}{t}{e} -admin {a}{d}{m}{i}{n} -after {a}{f}{t}{e}{r} -all {a}{l}{l} -alter {a}{l}{t}{e}{r} -and {a}{n}{d} -any {a}{n}{y} -as {a}{s} -asc {a}{s}{c} -auto_increment {a}{u}{t}{o}_{i}{n}{c}{r}{e}{m}{e}{n}{t} -avg {a}{v}{g} -avg_row_length {a}{v}{g}_{r}{o}{w}_{l}{e}{n}{g}{t}{h} -begin {b}{e}{g}{i}{n} -between {b}{e}{t}{w}{e}{e}{n} -both {b}{o}{t}{h} -btree {b}{t}{r}{e}{e} -by {b}{y} -case {c}{a}{s}{e} -cast {c}{a}{s}{t} -character {c}{h}{a}{r}{a}{c}{t}{e}{r} -charset {c}{h}{a}{r}{s}{e}{t} -check {c}{h}{e}{c}{k} -checksum {c}{h}{e}{c}{k}{s}{u}{m} -coalesce {c}{o}{a}{l}{e}{s}{c}{e} -collate {c}{o}{l}{l}{a}{t}{e} -collation {c}{o}{l}{l}{a}{t}{i}{o}{n} -column {c}{o}{l}{u}{m}{n} -columns {c}{o}{l}{u}{m}{n}{s} -comment {c}{o}{m}{m}{e}{n}{t} -commit {c}{o}{m}{m}{i}{t} -committed {c}{o}{m}{m}{i}{t}{t}{e}{d} -compact {c}{o}{m}{p}{a}{c}{t} -compressed {c}{o}{m}{p}{r}{e}{s}{s}{e}{d} -compression {c}{o}{m}{p}{r}{e}{s}{s}{i}{o}{n} -concat {c}{o}{n}{c}{a}{t} -concat_ws {c}{o}{n}{c}{a}{t}_{w}{s} -connection {c}{o}{n}{n}{e}{c}{t}{i}{o}{n} -connection_id {c}{o}{n}{n}{e}{c}{t}{i}{o}{n}_{i}{d} -constraint {c}{o}{n}{s}{t}{r}{a}{i}{n}{t} -convert {c}{o}{n}{v}{e}{r}{t} -count {c}{o}{u}{n}{t} -create {c}{r}{e}{a}{t}{e} -cross {c}{r}{o}{s}{s} -curdate {c}{u}{r}{d}{a}{t}{e} -current_date {c}{u}{r}{r}{e}{n}{t}_{d}{a}{t}{e} -curtime {c}{u}{r}{t}{i}{m}{e} -current_time {c}{u}{r}{r}{e}{n}{t}_{t}{i}{m}{e} -current_user {c}{u}{r}{r}{e}{n}{t}_{u}{s}{e}{r} -database {d}{a}{t}{a}{b}{a}{s}{e} -databases {d}{a}{t}{a}{b}{a}{s}{e}{s} -date_add {d}{a}{t}{e}_{a}{d}{d} -date_sub {d}{a}{t}{e}_{s}{u}{b} -day {d}{a}{y} -dayname {d}{a}{y}{n}{a}{m}{e} -dayofweek {d}{a}{y}{o}{f}{w}{e}{e}{k} -dayofmonth {d}{a}{y}{o}{f}{m}{o}{n}{t}{h} -dayofyear {d}{a}{y}{o}{f}{y}{e}{a}{r} -ddl {d}{d}{l} -deallocate {d}{e}{a}{l}{l}{o}{c}{a}{t}{e} -default {d}{e}{f}{a}{u}{l}{t} -delayed {d}{e}{l}{a}{y}{e}{d} -delay_key_write {d}{e}{l}{a}{y}_{k}{e}{y}_{w}{r}{i}{t}{e} -delete {d}{e}{l}{e}{t}{e} -drop {d}{r}{o}{p} -desc {d}{e}{s}{c} -describe {d}{e}{s}{c}{r}{i}{b}{e} -distinct {d}{i}{s}{t}{i}{n}{c}{t} -div {d}{i}{v} -do {d}{o} -dual {d}{u}{a}{l} -duplicate {d}{u}{p}{l}{i}{c}{a}{t}{e} -dynamic {d}{y}{n}{a}{m}{i}{c} -else {e}{l}{s}{e} -end {e}{n}{d} -engine {e}{n}{g}{i}{n}{e} -engines {e}{n}{g}{i}{n}{e}{s} -escape {e}{s}{c}{a}{p}{e} -execute {e}{x}{e}{c}{u}{t}{e} -exists {e}{x}{i}{s}{t}{s} -explain {e}{x}{p}{l}{a}{i}{n} -extract {e}{x}{t}{r}{a}{c}{t} -fields {f}{i}{e}{l}{d}{s} -first {f}{i}{r}{s}{t} -fixed {f}{i}{x}{e}{d} -for {f}{o}{r} -foreign {f}{o}{r}{e}{i}{g}{n} -found_rows {f}{o}{u}{n}{d}_{r}{o}{w}{s} -from {f}{r}{o}{m} -full {f}{u}{l}{l} -fulltext {f}{u}{l}{l}{t}{e}{x}{t} -global {g}{l}{o}{b}{a}{l} -grant {g}{r}{a}{n}{t} -grants {g}{r}{a}{n}{t}{s} -group {g}{r}{o}{u}{p} -group_concat {g}{r}{o}{u}{p}_{c}{o}{n}{c}{a}{t} -hash {h}{a}{s}{h} -having {h}{a}{v}{i}{n}{g} -high_priority {h}{i}{g}{h}_{p}{r}{i}{o}{r}{i}{t}{y} -hour {h}{o}{u}{r} -identified {i}{d}{e}{n}{t}{i}{f}{i}{e}{d} -if {i}{f} -ifnull {i}{f}{n}{u}{l}{l} -ignore {i}{g}{n}{o}{r}{e} -in {i}{n} -index {i}{n}{d}{e}{x} -inner {i}{n}{n}{e}{r} -insert {i}{n}{s}{e}{r}{t} -interval {i}{n}{t}{e}{r}{v}{a}{l} -into {i}{n}{t}{o} -is {i}{s} -isolation {i}{s}{o}{l}{a}{t}{i}{o}{n} -join {j}{o}{i}{n} -key {k}{e}{y} -key_block_size {k}{e}{y}_{b}{l}{o}{c}{k}_{s}{i}{z}{e} -leading {l}{e}{a}{d}{i}{n}{g} -left {l}{e}{f}{t} -length {l}{e}{n}{g}{t}{h} -level {l}{e}{v}{e}{l} -like {l}{i}{k}{e} -limit {l}{i}{m}{i}{t} -local {l}{o}{c}{a}{l} -locate {l}{o}{c}{a}{t}{e} -lock {l}{o}{c}{k} -lower {l}{o}{w}{e}{r} -low_priority {l}{o}{w}_{p}{r}{i}{o}{r}{i}{t}{y} -max_rows {m}{a}{x}_{r}{o}{w}{s} -microsecond {m}{i}{c}{r}{o}{s}{e}{c}{o}{n}{d} -minute {m}{i}{n}{u}{t}{e} -min_rows {m}{i}{n}_{r}{o}{w}{s} -mod {m}{o}{d} -mode {m}{o}{d}{e} -month {m}{o}{n}{t}{h} -names {n}{a}{m}{e}{s} -national {n}{a}{t}{i}{o}{n}{a}{l} -not {n}{o}{t} -offset {o}{f}{f}{s}{e}{t} -on {o}{n} -only {o}{n}{l}{y} -option {o}{p}{t}{i}{o}{n} -or {o}{r} -order {o}{r}{d}{e}{r} -outer {o}{u}{t}{e}{r} -password {p}{a}{s}{s}{w}{o}{r}{d} -pow {p}{o}{w} -power {p}{o}{w}{e}{r} -prepare {p}{r}{e}{p}{a}{r}{e} -primary {p}{r}{i}{m}{a}{r}{y} -procedure {p}{r}{o}{c}{e}{d}{u}{r}{e} -quarter {q}{u}{a}{r}{t}{e}{r} -quick {q}{u}{i}{c}{k} -rand {r}{a}{n}{d} -read {r}{e}{a}{d} -repeat {r}{e}{p}{e}{a}{t} -repeatable {r}{e}{p}{e}{a}{t}{a}{b}{l}{e} -references {r}{e}{f}{e}{r}{e}{n}{c}{e}{s} -regexp {r}{e}{g}{e}{x}{p} -replace {r}{e}{p}{l}{a}{c}{e} -redundant {r}{e}{d}{u}{n}{d}{a}{n}{t} -right {r}{i}{g}{h}{t} -rlike {r}{l}{i}{k}{e} -rollback {r}{o}{l}{l}{b}{a}{c}{k} -row {r}{o}{w} -row_format {r}{o}{w}_{f}{o}{r}{m}{a}{t} -schema {s}{c}{h}{e}{m}{a} -schemas {s}{c}{h}{e}{m}{a}{s} -second {s}{e}{c}{o}{n}{d} -select {s}{e}{l}{e}{c}{t} -serializable {s}{e}{r}{i}{a}{l}{i}{z}{a}{b}{l}{e} -session {s}{e}{s}{s}{i}{o}{n} -set {s}{e}{t} -share {s}{h}{a}{r}{e} -show {s}{h}{o}{w} -some {s}{o}{m}{e} -start {s}{t}{a}{r}{t} -status {s}{t}{a}{t}{u}{s} -subdate {s}{u}{b}{d}{a}{t}{e} -strcmp {s}{t}{r}{c}{m}{p} -substr {s}{u}{b}{s}{t}{r} -substring {s}{u}{b}{s}{t}{r}{i}{n}{g} -substring_index {s}{u}{b}{s}{t}{r}{i}{n}{g}_{i}{n}{d}{e}{x} -sum {s}{u}{m} -sysdate {s}{y}{s}{d}{a}{t}{e} -table {t}{a}{b}{l}{e} -tables {t}{a}{b}{l}{e}{s} -then {t}{h}{e}{n} -to {t}{o} -trailing {t}{r}{a}{i}{l}{i}{n}{g} -transaction {t}{r}{a}{n}{s}{a}{c}{t}{i}{o}{n} -triggers {t}{r}{i}{g}{g}{e}{r}{s} -trim {t}{r}{i}{m} -truncate {t}{r}{u}{n}{c}{a}{t}{e} -max {m}{a}{x} -min {m}{i}{n} -uncommitted {u}{n}{c}{o}{m}{m}{i}{t}{t}{e}{d} -unknown {u}{n}{k}{n}{o}{w}{n} -union {u}{n}{i}{o}{n} -unique {u}{n}{i}{q}{u}{e} -unlock {u}{n}{l}{o}{c}{k} -nullif {n}{u}{l}{l}{i}{f} -update {u}{p}{d}{a}{t}{e} -upper {u}{p}{p}{e}{r} -value {v}{a}{l}{u}{e} -values {v}{a}{l}{u}{e}{s} -variables {v}{a}{r}{i}{a}{b}{l}{e}{s} -version {v}{e}{r}{s}{i}{o}{n} -warnings {w}{a}{r}{n}{i}{n}{g}{s} -week {w}{e}{e}{k} -weekday {w}{e}{e}{k}{d}{a}{y} -weekofyear {w}{e}{e}{k}{o}{f}{y}{e}{a}{r} -where {w}{h}{e}{r}{e} -when {w}{h}{e}{n} -write {w}{r}{i}{t}{e} -xor {x}{o}{r} -yearweek {y}{e}{a}{r}{w}{e}{e}{k} - -null {n}{u}{l}{l} -false {f}{a}{l}{s}{e} -true {t}{r}{u}{e} - -calc_found_rows {s}{q}{l}_{c}{a}{l}{c}_{f}{o}{u}{n}{d}_{r}{o}{w}{s} - -current_ts {c}{u}{r}{r}{e}{n}{t}_{t}{i}{m}{e}{s}{t}{a}{m}{p} -localtime {l}{o}{c}{a}{l}{t}{i}{m}{e} -localts {l}{o}{c}{a}{l}{t}{i}{m}{e}{s}{t}{a}{m}{p} -now {n}{o}{w} - -bit {b}{i}{t} -tiny {t}{i}{n}{y} -tinyint {t}{i}{n}{y}{i}{n}{t} -smallint {s}{m}{a}{l}{l}{i}{n}{t} -mediumint {m}{e}{d}{i}{u}{m}{i}{n}{t} -int {i}{n}{t} -integer {i}{n}{t}{e}{g}{e}{r} -bigint {b}{i}{g}{i}{n}{t} -real {r}{e}{a}{l} -double {d}{o}{u}{b}{l}{e} -float {f}{l}{o}{a}{t} -decimal {d}{e}{c}{i}{m}{a}{l} -numeric {n}{u}{m}{e}{r}{i}{c} -date {d}{a}{t}{e} -time {t}{i}{m}{e} -timestamp {t}{i}{m}{e}{s}{t}{a}{m}{p} -datetime {d}{a}{t}{e}{t}{i}{m}{e} -year {y}{e}{a}{r} -char {c}{h}{a}{r} -varchar {v}{a}{r}{c}{h}{a}{r} -binary {b}{i}{n}{a}{r}{y} -varbinary {v}{a}{r}{b}{i}{n}{a}{r}{y} -tinyblob {t}{i}{n}{y}{b}{l}{o}{b} -blob {b}{l}{o}{b} -mediumblob {m}{e}{d}{i}{u}{m}{b}{l}{o}{b} -longblob {l}{o}{n}{g}{b}{l}{o}{b} -tinytext {t}{i}{n}{y}{t}{e}{x}{t} -text {t}{e}{x}{t} -mediumtext {m}{e}{d}{i}{u}{m}{t}{e}{x}{t} -longtext {l}{o}{n}{g}{t}{e}{x}{t} -enum {e}{n}{u}{m} -precision {p}{r}{e}{c}{i}{s}{i}{o}{n} - -signed {s}{i}{g}{n}{e}{d} -unsigned {u}{n}{s}{i}{g}{n}{e}{d} -zerofill {z}{e}{r}{o}{f}{i}{l}{l} - -bigrat {b}{i}{g}{r}{a}{t} -bool {b}{o}{o}{l} -boolean {b}{o}{o}{l}{e}{a}{n} -byte {b}{y}{t}{e} -duration {d}{u}{r}{a}{t}{i}{o}{n} -rune {r}{u}{n}{e} -string {s}{t}{r}{i}{n}{g} -use {u}{s}{e} -user {u}{s}{e}{r} -using {u}{s}{i}{n}{g} - -idchar0 [a-zA-Z_] -idchars {idchar0}|[0-9$] // See: https://dev.mysql.com/doc/refman/5.7/en/identifiers.html -ident {idchar0}{idchars}* - -user_var "@"{ident} -sys_var "@@"(({global}".")|({session}".")|{local}".")?{ident} - -second_microsecond {s}{e}{c}{o}{n}{d}_{m}{i}{c}{r}{o}{s}{e}{c}{o}{n}{d} -minute_microsecond {m}{i}{n}{u}{t}{e}_{m}{i}{c}{r}{o}{s}{e}{c}{o}{n}{d} -minute_second {m}{i}{n}{u}{t}{e}_{s}{e}{c}{o}{n}{d} -hour_microsecond {h}{o}{u}{r}_{m}{i}{c}{r}{o}{s}{e}{c}{o}{n}{d} -hour_second {h}{o}{u}{r}_{s}{e}{c}{o}{n}{d} -hour_minute {h}{o}{u}{r}_{m}{i}{n}{u}{t}{e} -day_microsecond {d}{a}{y}_{m}{i}{c}{r}{o}{s}{e}{c}{o}{n}{d} -day_second {d}{a}{y}_{s}{e}{c}{o}{n}{d} -day_minute {d}{a}{y}_{m}{i}{n}{u}{t}{e} -day_hour {d}{a}{y}_{h}{o}{u}{r} -year_month {y}{e}{a}{r}_{m}{o}{n}{t}{h} - -%yyc c -%yyn c = l.next() -%yyt l.sc - -%x S1 S2 S3 S4 - -%% - l.val = l.val[:0] - c0, l.line, l.col = l.c, l.nline, l.ncol - -<*>\0 return 0 - -[ \t\n\r]+ -#.* -\/\/.* -\/\*([^*]|\*+[^*/])*\*+\/ --- l.sc = S3 -<S3>[ \t]+.* {l.sc = 0} -<S3>[^ \t] { - l.sc = 0 - l.c = '-' - n := len(l.val) - l.unget(l.val[n-1]) - return '-' - } - -{int_lit} return l.int(lval) -{float_lit} return l.float(lval) -{hex_lit} return l.hex(lval) -{bit_lit} return l.bit(lval) - -\" l.sc = S1 -' l.sc = S2 -` l.sc = S4 - -<S1>[^\"\\]* l.stringLit = append(l.stringLit, l.val...) -<S1>\\. l.stringLit = append(l.stringLit, l.val...) -<S1>\"\" l.stringLit = append(l.stringLit, '"') -<S1>\" l.stringLit = append(l.stringLit, '"') - l.sc = 0 - return l.str(lval, "\"") -<S2>[^'\\]* l.stringLit = append(l.stringLit, l.val...) -<S2>\\. l.stringLit = append(l.stringLit, l.val...) -<S2>'' l.stringLit = append(l.stringLit, '\'') -<S2>' l.stringLit = append(l.stringLit, '\'') - l.sc = 0 - return l.str(lval, "'") -<S4>[^`]* l.stringLit = append(l.stringLit, l.val...) -<S4>`` l.stringLit = append(l.stringLit, '`') -<S4>` l.sc = 0 - lval.item = string(l.stringLit) - l.stringLit = l.stringLit[0:0] - return identifier - -"&&" return andand -"&^" return andnot -"<<" return lsh -"<=" return le -"=" return eq -">=" return ge -"!=" return neq -"<>" return neq -"||" return oror -">>" return rsh -"<=>" return nulleq - -"@" return at -"?" return placeholder - -{abs} lval.item = string(l.val) - return abs -{add} return add -{adddate} lval.item = string(l.val) - return addDate -{admin} lval.item = string(l.val) - return admin -{after} lval.item = string(l.val) - return after -{all} return all -{alter} return alter -{and} return and -{any} lval.item = string(l.val) - return any -{asc} return asc -{as} return as -{auto_increment} lval.item = string(l.val) - return autoIncrement -{avg} lval.item = string(l.val) - return avg -{avg_row_length} lval.item = string(l.val) - return avgRowLength -{begin} lval.item = string(l.val) - return begin -{between} return between -{both} return both -{btree} lval.item = string(l.val) - return btree -{by} return by -{case} return caseKwd -{cast} lval.item = string(l.val) - return cast -{character} return character -{charset} lval.item = string(l.val) - return charsetKwd -{check} return check -{checksum} lval.item = string(l.val) - return checksum -{coalesce} lval.item = string(l.val) - return coalesce -{collate} return collate -{collation} lval.item = string(l.val) - return collation -{column} return column -{columns} lval.item = string(l.val) - return columns -{comment} lval.item = string(l.val) - return comment -{commit} lval.item = string(l.val) - return commit -{committed} lval.item = string(l.val) - return committed -{compact} lval.item = string(l.val) - return compact -{compressed} lval.item = string(l.val) - return compressed -{compression} lval.item = string(l.val) - return compression -{concat} lval.item = string(l.val) - return concat -{concat_ws} lval.item = string(l.val) - return concatWs -{connection} lval.item = string(l.val) - return connection -{connection_id} lval.item = string(l.val) - return connectionID -{constraint} return constraint -{convert} lval.item = string(l.val) - return convert -{count} lval.item = string(l.val) - return count -{create} return create -{cross} return cross -{curdate} lval.item = string(l.val) - return curDate -{current_date} lval.item = string(l.val) - return currentDate -{curtime} lval.item = string(l.val) - return curTime -{current_time} lval.item = string(l.val) - return currentTime -{current_user} lval.item = string(l.val) - return currentUser -{database} lval.item = string(l.val) - return database -{databases} return databases -{date_add} lval.item = string(l.val) - return dateAdd -{date_sub} lval.item = string(l.val) - return dateSub -{day} lval.item = string(l.val) - return day -{dayname} lval.item = string(l.val) - return dayname -{dayofweek} lval.item = string(l.val) - return dayofweek -{dayofmonth} lval.item = string(l.val) - return dayofmonth -{dayofyear} lval.item = string(l.val) - return dayofyear -{day_hour} lval.item = string(l.val) - return dayHour -{day_microsecond} lval.item = string(l.val) - return dayMicrosecond -{day_minute} lval.item = string(l.val) - return dayMinute -{day_second} lval.item = string(l.val) - return daySecond -{ddl} return ddl -{deallocate} lval.item = string(l.val) - return deallocate -{default} return defaultKwd -{delayed} return delayed -{delay_key_write} lval.item = string(l.val) - return delayKeyWrite -{delete} return deleteKwd -{desc} return desc -{describe} return describe -{drop} return drop -{distinct} return distinct -{div} return div -{do} lval.item = string(l.val) - return do -{dual} return dual -{duplicate} lval.item = string(l.val) - return duplicate -{dynamic} lval.item = string(l.val) - return dynamic -{else} return elseKwd -{end} lval.item = string(l.val) - return end -{engine} lval.item = string(l.val) - return engine -{engines} lval.item = string(l.val) - return engines -{execute} lval.item = string(l.val) - return execute -{enum} return enum -{escape} lval.item = string(l.val) - return escape -{exists} return exists -{explain} return explain -{extract} lval.item = string(l.val) - return extract -{fields} lval.item = string(l.val) - return fields -{first} lval.item = string(l.val) - return first -{fixed} lval.item = string(l.val) - return fixed -{for} return forKwd -{foreign} return foreign -{found_rows} lval.item = string(l.val) - return foundRows -{from} return from -{full} lval.item = string(l.val) - return full -{fulltext} return fulltext -{grant} return grant -{grants} lval.item = string(l.val) - return grants -{group} return group -{group_concat} lval.item = string(l.val) - return groupConcat -{hash} lval.item = string(l.val) - return hash -{having} return having -{high_priority} return highPriority -{hour} lval.item = string(l.val) - return hour -{hour_microsecond} lval.item = string(l.val) - return hourMicrosecond -{hour_minute} lval.item = string(l.val) - return hourMinute -{hour_second} lval.item = string(l.val) - return hourSecond -{identified} lval.item = string(l.val) - return identified -{if} lval.item = string(l.val) - return ifKwd -{ifnull} lval.item = string(l.val) - return ifNull -{ignore} return ignore -{index} return index -{inner} return inner -{insert} return insert -{interval} return interval -{into} return into -{in} return in -{is} return is -{isolation} lval.item = string(l.val) - return isolation -{join} return join -{key} return key -{key_block_size} lval.item = string(l.val) - return keyBlockSize -{leading} return leading -{left} lval.item = string(l.val) - return left -{length} lval.item = string(l.val) - return length -{level} lval.item = string(l.val) - return level -{like} return like -{limit} return limit -{local} lval.item = string(l.val) - return local -{locate} lval.item = string(l.val) - return locate -{lock} return lock -{lower} lval.item = string(l.val) - return lower -{low_priority} return lowPriority -{max} lval.item = string(l.val) - return max -{max_rows} lval.item = string(l.val) - return maxRows -{microsecond} lval.item = string(l.val) - return microsecond -{min} lval.item = string(l.val) - return min -{minute} lval.item = string(l.val) - return minute -{minute_microsecond} lval.item = string(l.val) - return minuteMicrosecond -{minute_second} lval.item = string(l.val) - return minuteSecond -{min_rows} lval.item = string(l.val) - return minRows -{mod} return mod -{mode} lval.item = string(l.val) - return mode -{month} lval.item = string(l.val) - return month -{names} lval.item = string(l.val) - return names -{national} lval.item = string(l.val) - return national -{not} return not -{offset} lval.item = string(l.val) - return offset -{on} return on -{only} lval.item = string(l.val) - return only -{option} return option -{order} return order -{or} return or -{outer} return outer -{password} lval.item = string(l.val) - return password -{pow} lval.item = string(l.val) - return pow -{power} lval.item = string(l.val) - return power -{prepare} lval.item = string(l.val) - return prepare -{primary} return primary -{procedure} return procedure -{quarter} lval.item = string(l.val) - return quarter -{quick} lval.item = string(l.val) - return quick -redundant lval.item = string(l.val) - return redundant -{right} return right -{rollback} lval.item = string(l.val) - return rollback -{row} lval.item = string(l.val) - return row -{row_format} lval.item = string(l.val) - return rowFormat -{schema} lval.item = string(l.val) - return schema -{schemas} return schemas -{serializable} lval.item = string(l.val) - return serializable -{session} lval.item = string(l.val) - return session -{some} lval.item = string(l.val) - return some -{start} lval.item = string(l.val) - return start -{status} lval.item = string(l.val) - return status -{global} lval.item = string(l.val) - return global -{rand} lval.item = string(l.val) - return rand -{read} return read -{repeat} lval.item = string(l.val) - return repeat -{repeatable} lval.item = string(l.val) - return repeatable -{regexp} return regexpKwd -{replace} lval.item = string(l.val) - return replace -{references} return references -{rlike} return rlike - -{sys_var} lval.item = string(l.val) - return sysVar - -{user_var} lval.item = string(l.val) - return userVar -{second} lval.item = string(l.val) - return second -{second_microsecond} lval.item= string(l.val) - return secondMicrosecond -{select} return selectKwd - -{set} return set -{share} return share -{show} return show -{subdate} lval.item = string(l.val) - return subDate -{strcmp} lval.item = string(l.val) - return strcmp -{substr} lval.item = string(l.val) - return substring -{substring} lval.item = string(l.val) - return substring -{substring_index} lval.item = string(l.val) - return substringIndex -{sum} lval.item = string(l.val) - return sum -{sysdate} lval.item = string(l.val) - return sysDate -{table} return tableKwd -{tables} lval.item = string(l.val) - return tables -{then} return then -{to} return to -{trailing} return trailing -{transaction} lval.item = string(l.val) - return transaction -{triggers} lval.item = string(l.val) - return triggers -{trim} lval.item = string(l.val) - return trim -{truncate} lval.item = string(l.val) - return truncate -{uncommitted} lval.item = string(l.val) - return uncommitted -{union} return union -{unique} return unique -{unknown} lval.item = string(l.val) - return unknown -{nullif} lval.item = string(l.val) - return nullIf -{unlock} return unlock -{update} return update -{upper} lval.item = string(l.val) - return upper -{use} return use -{user} lval.item = string(l.val) - return user -{using} return using -{value} lval.item = string(l.val) - return value -{values} return values -{variables} lval.item = string(l.val) - return variables -{version} lval.item = string(l.val) - return version -{warnings} lval.item = string(l.val) - return warnings -{week} lval.item = string(l.val) - return week -{weekday} lval.item = string(l.val) - return weekday -{weekofyear} lval.item = string(l.val) - return weekofyear -{when} return when -{where} return where -{write} return write -{xor} return xor -{yearweek} lval.item = string(l.val) - return yearweek -{year_month} lval.item = string(l.val) - return yearMonth - -{signed} lval.item = string(l.val) - return signed -{unsigned} return unsigned -{zerofill} return zerofill - -{null} lval.item = nil - return null - -{false} return falseKwd - -{true} return trueKwd - -{calc_found_rows} lval.item = string(l.val) - return calcFoundRows - -{current_ts} lval.item = string(l.val) - return currentTs -{localtime} return localTime -{localts} return localTs -{now} lval.item = string(l.val) - return now - -{bit} lval.item = string(l.val) - return bitType - -{tiny} lval.item = string(l.val) - return tinyIntType - -{tinyint} lval.item = string(l.val) - return tinyIntType - -{smallint} lval.item = string(l.val) - return smallIntType - -{mediumint} lval.item = string(l.val) - return mediumIntType - -{bigint} lval.item = string(l.val) - return bigIntType - -{decimal} lval.item = string(l.val) - return decimalType - -{numeric} lval.item = string(l.val) - return numericType - -{float} lval.item = string(l.val) - return floatType - -{double} lval.item = string(l.val) - return doubleType - -{precision} lval.item = string(l.val) - return precisionType - -{real} lval.item = string(l.val) - return realType - -{date} lval.item = string(l.val) - return dateType - -{time} lval.item = string(l.val) - return timeType - -{timestamp} lval.item = string(l.val) - return timestampType - -{datetime} lval.item = string(l.val) - return datetimeType - -{year} lval.item = string(l.val) - return yearType - -{char} lval.item = string(l.val) - return charType - -{varchar} lval.item = string(l.val) - return varcharType - -{binary} lval.item = string(l.val) - return binaryType - -{varbinary} lval.item = string(l.val) - return varbinaryType - -{tinyblob} lval.item = string(l.val) - return tinyblobType - -{blob} lval.item = string(l.val) - return blobType - -{mediumblob} lval.item = string(l.val) - return mediumblobType - -{longblob} lval.item = string(l.val) - return longblobType - -{tinytext} lval.item = string(l.val) - return tinytextType - -{mediumtext} lval.item = string(l.val) - return mediumtextType - -{text} lval.item = string(l.val) - return textType - -{longtext} lval.item = string(l.val) - return longtextType - -{bool} lval.item = string(l.val) - return boolType - -{boolean} lval.item = string(l.val) - return booleanType - -{byte} lval.item = string(l.val) - return byteType - -{int} lval.item = string(l.val) - return intType - -{integer} lval.item = string(l.val) - return integerType - -{ident} lval.item = string(l.val) - return l.handleIdent(lval) - -. return c0 - -%% - return int(unicode.ReplacementChar) -} - -func (l *lexer) npos() (line, col int) { - if line, col = l.nline, l.ncol; col == 0 { - line-- - col = l.lcol+1 - } - return -} - -func (l *lexer) str(lval *yySymType, pref string) int { - l.sc = 0 - // TODO: performance issue. - s := string(l.stringLit) - l.stringLit = l.stringLit[0:0] - if pref == "'" { - s = strings.Replace(s, "\\'", "'", -1) - s = strings.TrimSuffix(s, "'") + "\"" - pref = "\"" - } - v := stringutil.RemoveUselessBackslash(pref+s) - v, err := strconv.Unquote(v) - if err != nil { - v = strings.TrimSuffix(s, pref) - } - lval.item = v - return stringLit -} - -func (l *lexer) trimIdent(idt string) string { - idt = strings.TrimPrefix(idt, "`") - idt = strings.TrimSuffix(idt, "`") - return idt -} - -func (l *lexer) int(lval *yySymType) int { - n, err := strconv.ParseUint(string(l.val), 0, 64) - if err != nil { - l.errf("integer literal: %v", err) - return int(unicode.ReplacementChar) - } - - switch { - case n < math.MaxInt64: - lval.item = int64(n) - default: - lval.item = uint64(n) - } - return intLit -} - -func (l *lexer) float(lval *yySymType) int { - n, err := strconv.ParseFloat(string(l.val), 64) - if err != nil { - l.errf("float literal: %v", err) - return int(unicode.ReplacementChar) - } - - lval.item = float64(n) - return floatLit -} - -// https://dev.mysql.com/doc/refman/5.7/en/hexadecimal-literals.html -func (l *lexer) hex(lval *yySymType) int { - s := string(l.val) - h, err := mysql.ParseHex(s) - if err != nil { - l.errf("hexadecimal literal: %v", err) - return int(unicode.ReplacementChar) - } - lval.item = h - return hexLit -} - -// https://dev.mysql.com/doc/refman/5.7/en/bit-type.html -func (l *lexer) bit(lval *yySymType) int { - s := string(l.val) - b, err := mysql.ParseBit(s, -1) - if err != nil { - l.errf("bit literal: %v", err) - return int(unicode.ReplacementChar) - } - lval.item = b - return bitLit -} - -func (l *lexer) handleIdent(lval *yySymType) int { - s := lval.item.(string) - // A character string literal may have an optional character set introducer and COLLATE clause: - // [_charset_name]'string' [COLLATE collation_name] - // See: https://dev.mysql.com/doc/refman/5.7/en/charset-literal.html - if !strings.HasPrefix(s, "_") { - return identifier - } - cs, _, err := charset.GetCharsetInfo(s[1:]) - if err != nil { - return identifier - } - lval.item = cs - return underscoreCS -} |