diff options
Diffstat (limited to 'vendor/github.com/pingcap/tidb/parser/parser.y')
-rw-r--r-- | vendor/github.com/pingcap/tidb/parser/parser.y | 4688 |
1 files changed, 0 insertions, 4688 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 - -%% |