diff --git a/ast/ddl.go b/ast/ddl.go index 1debb12be5..3651c8848c 100644 --- a/ast/ddl.go +++ b/ast/ddl.go @@ -646,6 +646,18 @@ const ( // TODO: Add more actions ) +// LockType is the type for AlterTableSpec. +// See https://dev.mysql.com/doc/refman/5.7/en/alter-table.html#alter-table-concurrency +type LockType byte + +// Lock Types. +const ( + LockTypeNone LockType = iota + 1 + LockTypeDefault + LockTypeShared + LockTypeExclusive +) + // AlterTableSpec represents alter table specification. type AlterTableSpec struct { node @@ -658,6 +670,7 @@ type AlterTableSpec struct { NewColumn *ColumnDef OldColumnName *ColumnName Position *ColumnPosition + LockType LockType } // Accept implements Node Accept interface. diff --git a/parser/misc.go b/parser/misc.go index c49a4f3aad..c448552a8e 100644 --- a/parser/misc.go +++ b/parser/misc.go @@ -248,6 +248,7 @@ var tokenMap = map[string]int{ "ENUM": enum, "ESCAPE": escape, "ESCAPED": escaped, + "EXCLUSIVE": exclusive, "EVENTS": events, "EXECUTE": execute, "EXISTS": exists, @@ -413,6 +414,7 @@ var tokenMap = map[string]int{ "SESSION": session, "SET": set, "SHARE": share, + "SHARED": shared, "SHOW": show, "SLEEP": sleep, "SIGN": sign, diff --git a/parser/parser.y b/parser/parser.y index b0d107565f..5538397e6b 100644 --- a/parser/parser.y +++ b/parser/parser.y @@ -442,6 +442,7 @@ import ( engine "ENGINE" engines "ENGINES" escape "ESCAPE" + exclusive "EXCLUSIVE" execute "EXECUTE" fields "FIELDS" first "FIRST" @@ -483,6 +484,7 @@ import ( serializable "SERIALIZABLE" session "SESSION" share "SHARE" + shared "SHARED" signed "SIGNED" snapshot "SNAPSHOT" space "SPACE" @@ -657,6 +659,7 @@ import ( LoadDataStmt "Load data statement" LocalOpt "Local opt" LockTablesStmt "Lock tables statement" + LockClause "Alter table lock clause" LowPriorityOptional "LOW_PRIORITY or empty" NumLiteral "Num/Int/Float/Decimal Literal" NoWriteToBinLogAliasOpt "NO_WRITE_TO_BINLOG alias LOCAL or empty" @@ -1030,13 +1033,31 @@ AlterTableSpec: NewTable: $3.(*ast.TableName), } } -| "LOCK" eq "NONE" +| LockClause { $$ = &ast.AlterTableSpec{ Tp: ast.AlterTableLock, + LockType: $1.(ast.LockType), } } +LockClause: + "LOCK" eq "NONE" + { + $$ = ast.LockTypeNone + } +| "LOCK" eq "DEFAULT" + { + $$ = ast.LockTypeDefault + } +| "LOCK" eq "SHARED" + { + $$ = ast.LockTypeShared + } +| "LOCK" eq "EXCLUSIVE" + { + $$ = ast.LockTypeExclusive + } KeyOrIndex: "KEY" | "INDEX" @@ -2326,7 +2347,7 @@ UnReservedKeyword: | "MIN_ROWS" | "NATIONAL" | "ROW" | "ROW_FORMAT" | "QUARTER" | "GRANTS" | "TRIGGERS" | "DELAY_KEY_WRITE" | "ISOLATION" | "JSON" | "REPEATABLE" | "COMMITTED" | "UNCOMMITTED" | "ONLY" | "SERIALIZABLE" | "LEVEL" | "VARIABLES" | "SQL_CACHE" | "INDEXES" | "PROCESSLIST" | "SQL_NO_CACHE" | "DISABLE" | "ENABLE" | "REVERSE" | "SPACE" | "PRIVILEGES" | "NO" | "BINLOG" | "FUNCTION" | "VIEW" | "MODIFY" | "EVENTS" | "PARTITIONS" -| "TIMESTAMPDIFF" | "NONE" | "SUPER" +| "TIMESTAMPDIFF" | "NONE" | "SUPER" | "SHARED" | "EXCLUSIVE" ReservedKeyword: "ADD" | "ALL" | "ALTER" | "ANALYZE" | "AND" | "AS" | "ASC" | "BETWEEN" | "BIGINT" @@ -3688,6 +3709,7 @@ GetFormatSelector: $$ = strings.ToUpper($1) } + FunctionNameDateArith: "DATE_ADD" | "DATE_SUB" diff --git a/parser/parser_test.go b/parser/parser_test.go index 70bd04db8f..c1884d00b4 100644 --- a/parser/parser_test.go +++ b/parser/parser_test.go @@ -91,7 +91,7 @@ func (s *testParserSuite) TestSimple(c *C) { "compact", "redundant", "sql_no_cache sql_no_cache", "sql_cache sql_cache", "action", "round", "enable", "disable", "reverse", "space", "privileges", "get_lock", "release_lock", "sleep", "no", "greatest", "least", "binlog", "hex", "unhex", "function", "indexes", "from_unixtime", "processlist", "events", "less", "than", "timediff", - "ln", "log", "log2", "log10", "timestampdiff", "pi", "quote", "none", "super", + "ln", "log", "log2", "log10", "timestampdiff", "pi", "quote", "none", "super", "default", "shared", "exclusive", } for _, kw := range unreservedKws { src := fmt.Sprintf("SELECT %s FROM tbl;", kw) @@ -1259,6 +1259,13 @@ func (s *testParserSuite) TestDDL(c *C) { {"ALTER TABLE t ALTER COLUMN a DROP DEFAULT", true}, {"ALTER TABLE t ALTER a DROP DEFAULT", true}, {"ALTER TABLE t ADD COLUMN a SMALLINT UNSIGNED, lock=none", true}, + {"ALTER TABLE t ADD COLUMN a SMALLINT UNSIGNED, lock=default", true}, + {"ALTER TABLE t ADD COLUMN a SMALLINT UNSIGNED, lock=shared", true}, + {"ALTER TABLE t ADD COLUMN a SMALLINT UNSIGNED, lock=exclusive", true}, + {"ALTER TABLE t ADD COLUMN a SMALLINT UNSIGNED, LOCK=NONE", true}, + {"ALTER TABLE t ADD COLUMN a SMALLINT UNSIGNED, LOCK=DEFAULT", true}, + {"ALTER TABLE t ADD COLUMN a SMALLINT UNSIGNED, LOCK=SHARED", true}, + {"ALTER TABLE t ADD COLUMN a SMALLINT UNSIGNED, LOCK=EXCLUSIVE", true}, // for rename table statement {"RENAME TABLE t TO t1", true},