Merge pull request #977 from pingcap/shenli/fix-974

*: Support more create table options
This commit is contained in:
Shen Li
2016-03-16 11:07:35 +08:00
6 changed files with 12343 additions and 11487 deletions

View File

@ -198,6 +198,39 @@ func (n *ColumnOption) Accept(v Visitor) (Node, bool) {
return v.Leave(n)
}
// IndexType is the type of index
type IndexType int
// IndexTypes
const (
IndexTypeBtree = iota + 1
IndexTypeHash
)
// IndexOption is the index options.
// KEY_BLOCK_SIZE [=] value
// | index_type
// | WITH PARSER parser_name
// | COMMENT 'string'
// See: http://dev.mysql.com/doc/refman/5.7/en/create-table.html
type IndexOption struct {
node
KeyBlockSize uint64
Tp IndexType
Comment string
}
// Accept implements Node Accept interface.
func (n *IndexOption) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*IndexOption)
return v.Leave(n)
}
// ConstraintType is the type for Constraint.
type ConstraintType int
@ -428,6 +461,17 @@ const (
TableOptionMaxRows
TableOptionMinRows
TableOptionDelayKeyWrite
TableOptionRowFormat
)
// RowFormat types
const (
RowFormatDefault uint64 = iota + 1
RowFormatDynamic
RowFormatFixed
RowFormatCompressed
RowFormatRedundant
RowFormatCompact
)
// TableOption is used for parsing table option from SQL.

File diff suppressed because it is too large Load Diff

View File

@ -76,6 +76,7 @@ import (
begin "BEGIN"
between "BETWEEN"
both "BOTH"
btree "BTREE"
by "BY"
byteType "BYTE"
caseKwd "CASE"
@ -92,6 +93,8 @@ import (
comment "COMMENT"
commit "COMMIT"
committed "COMMITTED"
compact "COMPACT"
compressed "COMPRESSED"
compression "COMPRESSION"
concat "CONCAT"
concatWs "CONCAT_WS"
@ -130,6 +133,7 @@ import (
drop "DROP"
dual "DUAL"
duplicate "DUPLICATE"
dynamic "DYNAMIC"
elseKwd "ELSE"
end "END"
engine "ENGINE"
@ -144,6 +148,7 @@ import (
falseKwd "false"
fields "FIELDS"
first "FIRST"
fixed "FIXED"
foreign "FOREIGN"
forKwd "FOR"
foundRows "FOUND_ROWS"
@ -156,6 +161,7 @@ import (
grants "GRANTS"
group "GROUP"
groupConcat "GROUP_CONCAT"
hash "HASH"
having "HAVING"
highPriority "HIGH_PRIORITY"
hour "HOUR"
@ -223,6 +229,7 @@ import (
quick "QUICK"
rand "RAND"
read "READ"
redundant "REDUNDANT"
references "REFERENCES"
regexpKwd "REGEXP"
repeat "REPEAT"
@ -232,6 +239,7 @@ import (
rlike "RLIKE"
rollback "ROLLBACK"
row "ROW"
rowFormat "ROW_FORMAT"
rsh ">>"
schema "SCHEMA"
schemas "SCHEMAS"
@ -452,7 +460,9 @@ import (
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"
@ -501,6 +511,7 @@ import (
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"
@ -905,11 +916,11 @@ ColumnOptionListOpt:
}
ConstraintElem:
"PRIMARY" "KEY" '(' IndexColNameList ')'
"PRIMARY" "KEY" IndexTypeOpt '(' IndexColNameList ')' IndexOption
{
$$ = &ast.Constraint{Tp: ast.ConstraintPrimaryKey, Keys: $4.([]*ast.IndexColName)}
$$ = &ast.Constraint{Tp: ast.ConstraintPrimaryKey, Keys: $5.([]*ast.IndexColName)}
}
| "FULLTEXT" "KEY" IndexName '(' IndexColNameList ')'
| "FULLTEXT" "KEY" IndexName '(' IndexColNameList ')' IndexOption
{
$$ = &ast.Constraint{
Tp: ast.ConstraintFulltext,
@ -917,40 +928,40 @@ ConstraintElem:
Name: $3.(string),
}
}
| "INDEX" IndexName '(' IndexColNameList ')'
| "INDEX" IndexName IndexTypeOpt '(' IndexColNameList ')' IndexOption
{
$$ = &ast.Constraint{
Tp: ast.ConstraintIndex,
Keys: $4.([]*ast.IndexColName),
Keys: $5.([]*ast.IndexColName),
Name: $2.(string),
}
}
| "KEY" IndexName '(' IndexColNameList ')'
| "KEY" IndexName IndexTypeOpt '(' IndexColNameList ')' IndexOption
{
$$ = &ast.Constraint{
Tp: ast.ConstraintKey,
Keys: $4.([]*ast.IndexColName),
Keys: $5.([]*ast.IndexColName),
Name: $2.(string)}
}
| "UNIQUE" IndexName '(' IndexColNameList ')'
| "UNIQUE" IndexName IndexTypeOpt '(' IndexColNameList ')' IndexOption
{
$$ = &ast.Constraint{
Tp: ast.ConstraintUniq,
Keys: $4.([]*ast.IndexColName),
Keys: $5.([]*ast.IndexColName),
Name: $2.(string)}
}
| "UNIQUE" "INDEX" IndexName '(' IndexColNameList ')'
| "UNIQUE" "INDEX" IndexName IndexTypeOpt '(' IndexColNameList ')' IndexOption
{
$$ = &ast.Constraint{
Tp: ast.ConstraintUniqIndex,
Keys: $5.([]*ast.IndexColName),
Keys: $6.([]*ast.IndexColName),
Name: $3.(string)}
}
| "UNIQUE" "KEY" IndexName '(' IndexColNameList ')'
| "UNIQUE" "KEY" IndexName IndexTypeOpt '(' IndexColNameList ')' IndexOption
{
$$ = &ast.Constraint{
Tp: ast.ConstraintUniqKey,
Keys: $5.([]*ast.IndexColName),
Keys: $6.([]*ast.IndexColName),
Name: $3.(string)}
}
| "FOREIGN" "KEY" IndexName '(' IndexColNameList ')' ReferDef
@ -1671,11 +1682,42 @@ IndexName:
$$ = $1.(string)
}
IndexType:
Identifier
IndexOption:
{}
| "KEY_BLOCK_SIZE" EqOpt LengthNum
{
// TODO: "index type"
$$ = $1.(string)
$$ = &ast.IndexOption{
KeyBlockSize: $1.(uint64),
}
}
| IndexType
{
$$ = &ast.IndexOption {
Tp: $1.(ast.IndexType),
}
}
| "COMMENT" stringLit
{
$$ = &ast.IndexOption {
Comment: $2.(string),
}
}
IndexType:
"USING" "BTREE"
{
$$ = ast.IndexTypeBtree
}
| "USING" "HASH"
{
$$ = ast.IndexTypeHash
}
IndexTypeOpt:
{}
| IndexType
{
$$ = $1
}
/**********************************Identifier********************************************/
@ -1683,13 +1725,13 @@ Identifier:
identifier | UnReservedKeyword | NotKeywordToken
UnReservedKeyword:
"AUTO_INCREMENT" | "AFTER" | "AVG" | "BEGIN" | "BIT" | "BOOL" | "BOOLEAN" | "CHARSET" | "COLUMNS" | "COMMIT"
| "DATE" | "DATETIME" | "DEALLOCATE" | "DO" | "END" | "ENGINE" | "ENGINES" | "EXECUTE" | "FIRST" | "FULL"
| "LOCAL" | "NAMES" | "OFFSET" | "PASSWORD" %prec lowerThanEq | "PREPARE" | "QUICK" | "ROLLBACK" | "SESSION" | "SIGNED"
"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" | "QUARTER" | "ESCAPE" | "GRANTS" | "FIELDS" | "TRIGGERS" | "DELAY_KEY_WRITE" | "ISOLATION"
| "NATIONAL" | "ROW" | "ROW_FORMAT" | "QUARTER" | "ESCAPE" | "GRANTS" | "FIELDS" | "TRIGGERS" | "DELAY_KEY_WRITE" | "ISOLATION"
| "REPEATABLE" | "COMMITTED" | "UNCOMMITTED" | "ONLY" | "SERIALIZABLE" | "LEVEL" | "VARIABLES"
NotKeywordToken:
@ -3747,6 +3789,10 @@ TableOption:
{
$$ = &ast.TableOption{Tp: ast.TableOptionDelayKeyWrite, UintValue: $3.(uint64)}
}
| RowFormat
{
$$ = &ast.TableOption{Tp: ast.TableOptionRowFormat, UintValue: $1.(uint64)}
}
TableOptionListOpt:
@ -3776,6 +3822,32 @@ TruncateTableStmt:
$$ = &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

View File

@ -41,7 +41,8 @@ func (s *testParserSuite) TestSimple(c *C) {
"collation", "comment", "avg_row_length", "checksum", "compression", "connection", "key_block_size",
"max_rows", "min_rows", "national", "row", "quarter", "escape", "grants", "status", "fields", "triggers",
"delay_key_write", "isolation", "repeatable", "committed", "uncommitted", "only", "serializable", "level",
"curtime", "variables", "dayname", "version",
"curtime", "variables", "dayname", "version", "btree", "hash", "row_format", "dynamic", "fixed", "compressed",
"compact", "redundant",
}
for _, kw := range unreservedKws {
src := fmt.Sprintf("SELECT %s FROM tbl;", kw)
@ -629,6 +630,13 @@ func (s *testParserSuite) TestDDL(c *C) {
{"create table t (c int) password 'abc'", true},
{"create table t (c int) DELAY_KEY_WRITE=1", true},
{"create table t (c int) DELAY_KEY_WRITE 1", true},
{"create table t (c int) ROW_FORMAT = default", true},
{"create table t (c int) ROW_FORMAT default", true},
{"create table t (c int) ROW_FORMAT = fixed", true},
{"create table t (c int) ROW_FORMAT = compressed", true},
{"create table t (c int) ROW_FORMAT = compact", true},
{"create table t (c int) ROW_FORMAT = redundant", true},
{"create table t (c int) ROW_FORMAT = dynamic", true},
// For check clause
{"create table t (c1 bool, c2 bool, check (c1 in (0, 1)), check (c2 in (0, 1)))", true},
{"CREATE TABLE Customer (SD integer CHECK (SD > 0), First_Name varchar(30));", true},
@ -652,6 +660,67 @@ func (s *testParserSuite) TestDDL(c *C) {
{"drop tables xxx, yyy", true},
{"drop table if exists xxx", true},
{"drop table if not exists xxx", false},
// For issue 974
{`CREATE TABLE address (
id bigint(20) NOT NULL AUTO_INCREMENT,
create_at datetime NOT NULL,
deleted tinyint(1) NOT NULL,
update_at datetime NOT NULL,
version bigint(20) DEFAULT NULL,
address varchar(128) NOT NULL,
address_detail varchar(128) NOT NULL,
cellphone varchar(16) NOT NULL,
latitude double NOT NULL,
longitude double NOT NULL,
name varchar(16) NOT NULL,
sex tinyint(1) NOT NULL,
user_id bigint(20) NOT NULL,
PRIMARY KEY (id),
CONSTRAINT FK_7rod8a71yep5vxasb0ms3osbg FOREIGN KEY (user_id) REFERENCES waimaiqa.user (id),
INDEX FK_7rod8a71yep5vxasb0ms3osbg (user_id) comment ''
) ENGINE=InnoDB AUTO_INCREMENT=30 DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ROW_FORMAT=COMPACT COMMENT='' CHECKSUM=0 DELAY_KEY_WRITE=0;`, true},
// For issue 975
{`CREATE TABLE test_data (
id bigint(20) NOT NULL AUTO_INCREMENT,
create_at datetime NOT NULL,
deleted tinyint(1) NOT NULL,
update_at datetime NOT NULL,
version bigint(20) DEFAULT NULL,
address varchar(255) NOT NULL,
amount decimal(19,2) DEFAULT NULL,
charge_id varchar(32) DEFAULT NULL,
paid_amount decimal(19,2) DEFAULT NULL,
transaction_no varchar(64) DEFAULT NULL,
wx_mp_app_id varchar(32) DEFAULT NULL,
contacts varchar(50) DEFAULT NULL,
deliver_fee decimal(19,2) DEFAULT NULL,
deliver_info varchar(255) DEFAULT NULL,
deliver_time varchar(255) DEFAULT NULL,
description varchar(255) DEFAULT NULL,
invoice varchar(255) DEFAULT NULL,
order_from int(11) DEFAULT NULL,
order_state int(11) NOT NULL,
packing_fee decimal(19,2) DEFAULT NULL,
payment_time datetime DEFAULT NULL,
payment_type int(11) DEFAULT NULL,
phone varchar(50) NOT NULL,
store_employee_id bigint(20) DEFAULT NULL,
store_id bigint(20) NOT NULL,
user_id bigint(20) NOT NULL,
payment_mode int(11) NOT NULL,
current_latitude double NOT NULL,
current_longitude double NOT NULL,
address_latitude double NOT NULL,
address_longitude double NOT NULL,
PRIMARY KEY (id),
CONSTRAINT food_order_ibfk_1 FOREIGN KEY (user_id) REFERENCES waimaiqa.user (id),
CONSTRAINT food_order_ibfk_2 FOREIGN KEY (store_id) REFERENCES waimaiqa.store (id),
CONSTRAINT food_order_ibfk_3 FOREIGN KEY (store_employee_id) REFERENCES waimaiqa.store_employee (id),
UNIQUE FK_UNIQUE_charge_id USING BTREE (charge_id) comment '',
INDEX FK_eqst2x1xisn3o0wbrlahnnqq8 USING BTREE (store_employee_id) comment '',
INDEX FK_8jcmec4kb03f4dod0uqwm54o9 USING BTREE (store_id) comment '',
INDEX FK_a3t0m9apja9jmrn60uab30pqd USING BTREE (user_id) comment ''
) ENGINE=InnoDB AUTO_INCREMENT=95 DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ROW_FORMAT=COMPACT COMMENT='' CHECKSUM=0 DELAY_KEY_WRITE=0;`, true},
}
s.RunTest(c, table)
}

File diff suppressed because it is too large Load Diff

View File

@ -297,6 +297,7 @@ avg_row_length {a}{v}{g}_{r}{o}{w}_{l}{e}{n}{g}{t}{h}
begin {b}{e}{g}{i}{n}
between {b}{e}{t}{w}{e}{e}{n}
both {b}{o}{t}{h}
btree {b}{t}{r}{e}{e}
by {b}{y}
case {c}{a}{s}{e}
cast {c}{a}{s}{t}
@ -312,6 +313,8 @@ columns {c}{o}{l}{u}{m}{n}{s}
comment {c}{o}{m}{m}{e}{n}{t}
commit {c}{o}{m}{m}{i}{t}
committed {c}{o}{m}{m}{i}{t}{t}{e}{d}
compact {c}{o}{m}{p}{a}{c}{t}
compressed {c}{o}{m}{p}{r}{e}{s}{s}{e}{d}
compression {c}{o}{m}{p}{r}{e}{s}{s}{i}{o}{n}
concat {c}{o}{n}{c}{a}{t}
concat_ws {c}{o}{n}{c}{a}{t}_{w}{s}
@ -350,6 +353,7 @@ div {d}{i}{v}
do {d}{o}
dual {d}{u}{a}{l}
duplicate {d}{u}{p}{l}{i}{c}{a}{t}{e}
dynamic {d}{y}{n}{a}{m}{i}{c}
else {e}{l}{s}{e}
end {e}{n}{d}
engine {e}{n}{g}{i}{n}{e}
@ -361,6 +365,7 @@ explain {e}{x}{p}{l}{a}{i}{n}
extract {e}{x}{t}{r}{a}{c}{t}
fields {f}{i}{e}{l}{d}{s}
first {f}{i}{r}{s}{t}
fixed {f}{i}{x}{e}{d}
for {f}{o}{r}
foreign {f}{o}{r}{e}{i}{g}{n}
found_rows {f}{o}{u}{n}{d}_{r}{o}{w}{s}
@ -372,6 +377,7 @@ grant {g}{r}{a}{n}{t}
grants {g}{r}{a}{n}{t}{s}
group {g}{r}{o}{u}{p}
group_concat {g}{r}{o}{u}{p}_{c}{o}{n}{c}{a}{t}
hash {h}{a}{s}{h}
having {h}{a}{v}{i}{n}{g}
high_priority {h}{i}{g}{h}_{p}{r}{i}{o}{r}{i}{t}{y}
hour {h}{o}{u}{r}
@ -433,10 +439,12 @@ repeatable {r}{e}{p}{e}{a}{t}{a}{b}{l}{e}
references {r}{e}{f}{e}{r}{e}{n}{c}{e}{s}
regexp {r}{e}{g}{e}{x}{p}
replace {r}{e}{p}{l}{a}{c}{e}
redundant {r}{e}{d}{u}{n}{d}{a}{n}{t}
right {r}{i}{g}{h}{t}
rlike {r}{l}{i}{k}{e}
rollback {r}{o}{l}{l}{b}{a}{c}{k}
row {r}{o}{w}
row_format {r}{o}{w}_{f}{o}{r}{m}{a}{t}
schema {s}{c}{h}{e}{m}{a}
schemas {s}{c}{h}{e}{m}{a}{s}
second {s}{e}{c}{o}{n}{d}
@ -662,6 +670,8 @@ year_month {y}{e}{a}{r}_{m}{o}{n}{t}{h}
return begin
{between} return between
{both} return both
{btree} lval.item = string(l.val)
return btree
{by} return by
{case} return caseKwd
{cast} lval.item = string(l.val)
@ -686,6 +696,10 @@ year_month {y}{e}{a}{r}_{m}{o}{n}{t}{h}
return commit
{committed} lval.item = string(l.val)
return committed
{compact} lval.item = string(l.val)
return compact
{compressed} lval.item = string(l.val)
return compressed
{compression} lval.item = string(l.val)
return compression
{concat} lval.item = string(l.val)
@ -756,6 +770,8 @@ year_month {y}{e}{a}{r}_{m}{o}{n}{t}{h}
{dual} return dual
{duplicate} lval.item = string(l.val)
return duplicate
{dynamic} lval.item = string(l.val)
return dynamic
{else} return elseKwd
{end} lval.item = string(l.val)
return end
@ -776,6 +792,8 @@ year_month {y}{e}{a}{r}_{m}{o}{n}{t}{h}
return fields
{first} lval.item = string(l.val)
return first
{fixed} lval.item = string(l.val)
return fixed
{for} return forKwd
{foreign} return foreign
{found_rows} lval.item = string(l.val)
@ -790,6 +808,8 @@ year_month {y}{e}{a}{r}_{m}{o}{n}{t}{h}
{group} return group
{group_concat} lval.item = string(l.val)
return groupConcat
{hash} lval.item = string(l.val)
return hash
{having} return having
{high_priority} return highPriority
{hour} lval.item = string(l.val)
@ -886,11 +906,15 @@ year_month {y}{e}{a}{r}_{m}{o}{n}{t}{h}
return quarter
{quick} lval.item = string(l.val)
return quick
redundant lval.item = string(l.val)
return redundant
{right} return right
{rollback} lval.item = string(l.val)
return rollback
{row} lval.item = string(l.val)
return row
{row_format} lval.item = string(l.val)
return rowFormat
{schema} lval.item = string(l.val)
return schema
{schemas} return schemas