From f09bdf46e2fc4cebf344d85661dfe016ee993f71 Mon Sep 17 00:00:00 2001 From: Lynn Date: Sat, 5 May 2018 23:05:32 +0800 Subject: [PATCH] parser: support opt_bin_mod (#6456) --- ast/ast.go | 6 +++++ parser/parser.y | 63 +++++++++++++++++++++++++++++-------------- parser/parser_test.go | 3 +++ 3 files changed, 52 insertions(+), 20 deletions(-) diff --git a/ast/ast.go b/ast/ast.go index f61e9519b4..c3ef956851 100644 --- a/ast/ast.go +++ b/ast/ast.go @@ -83,6 +83,12 @@ type ExprNode interface { Format(w io.Writer) } +// OptBinary is used for parser. +type OptBinary struct { + IsBinary bool + Charset string +} + // FuncNode represents function call expression node. type FuncNode interface { ExprNode diff --git a/parser/parser.y b/parser/parser.y index 1dee5a9ce9..5d43f337d5 100644 --- a/parser/parser.y +++ b/parser/parser.y @@ -782,6 +782,7 @@ import ( FloatOpt "Floating-point type option" Precision "Floating-point precision option" OptBinary "Optional BINARY" + OptBinMod "Optional BINARY mode" OptCharset "Optional Character setting" OptCollate "Optional Collate setting" NUM "A number" @@ -3834,12 +3835,12 @@ CastType: x.Flag |= mysql.BinaryFlag $$ = x } -| "CHAR" OptFieldLen OptBinary OptCharset +| "CHAR" OptFieldLen OptBinary { x := types.NewFieldType(mysql.TypeVarString) x.Flen = $2.(int) // TODO: Flen should be the flen of expression - x.Charset = $4.(string) - if $3.(bool) { + x.Charset = $3.(*ast.OptBinary).Charset + if $3.(*ast.OptBinary).IsBinary{ x.Flag |= mysql.BinaryFlag } if x.Charset == "" { @@ -5850,34 +5851,34 @@ BitValueType: } StringType: - NationalOpt "CHAR" FieldLen OptBinary OptCharset OptCollate + NationalOpt "CHAR" FieldLen OptBinary OptCollate { x := types.NewFieldType(mysql.TypeString) x.Flen = $3.(int) - x.Charset = $5.(string) - x.Collate = $6.(string) - if $4.(bool) { + x.Charset = $4.(*ast.OptBinary).Charset + x.Collate = $5.(string) + if $4.(*ast.OptBinary).IsBinary { x.Flag |= mysql.BinaryFlag } $$ = x } -| NationalOpt "CHAR" OptBinary OptCharset OptCollate +| NationalOpt "CHAR" OptBinary OptCollate { x := types.NewFieldType(mysql.TypeString) - x.Charset = $4.(string) - x.Collate = $5.(string) - if $3.(bool) { + x.Charset = $3.(*ast.OptBinary).Charset + x.Collate = $4.(string) + if $3.(*ast.OptBinary).IsBinary { x.Flag |= mysql.BinaryFlag } $$ = x } -| Varchar FieldLen OptBinary OptCharset OptCollate +| Varchar FieldLen OptBinary OptCollate { x := types.NewFieldType(mysql.TypeVarchar) x.Flen = $2.(int) - x.Charset = $4.(string) - x.Collate = $5.(string) - if $3.(bool) { + x.Charset = $3.(*ast.OptBinary).Charset + x.Collate = $4.(string) + if $3.(*ast.OptBinary).IsBinary { x.Flag |= mysql.BinaryFlag } $$ = x @@ -5908,12 +5909,12 @@ StringType: x.Flag |= mysql.BinaryFlag $$ = $1.(*types.FieldType) } -| TextType OptBinary OptCharset OptCollate +| TextType OptBinary OptCollate { x := $1.(*types.FieldType) - x.Charset = $3.(string) - x.Collate = $4.(string) - if $2.(bool) { + x.Charset = $2.(*ast.OptBinary).Charset + x.Collate = $3.(string) + if $2.(*ast.OptBinary).IsBinary { x.Flag |= mysql.BinaryFlag } $$ = x @@ -6110,7 +6111,7 @@ Precision: $$ = &ast.FloatOpt{Flen: int($2.(uint64)), Decimal: int($4.(uint64))} } -OptBinary: +OptBinMod: { $$ = false } @@ -6119,6 +6120,28 @@ OptBinary: $$ = true } +OptBinary: + { + $$ = &ast.OptBinary{ + IsBinary: false, + Charset: "", + } + } +| "BINARY" OptCharset + { + $$ = &ast.OptBinary{ + IsBinary: true, + Charset: $2.(string), + } + } +| CharsetKw CharsetName OptBinMod + { + $$ = &ast.OptBinary{ + IsBinary: $3.(bool), + Charset: $2.(string), + } + } + OptCharset: { $$ = "" diff --git a/parser/parser_test.go b/parser/parser_test.go index da747fd8d0..9d36073188 100644 --- a/parser/parser_test.go +++ b/parser/parser_test.go @@ -1347,6 +1347,8 @@ func (s *testParserSuite) TestDDL(c *C) { {"CREATE TABLE foo (name CHAR(50) BINARY)", true}, {"CREATE TABLE foo (name CHAR(50) COLLATE utf8_bin)", true}, {"CREATE TABLE foo (name CHAR(50) CHARACTER SET utf8)", true}, + {"CREATE TABLE foo (name CHAR(50) CHARACTER SET utf8 BINARY)", true}, + {"CREATE TABLE foo (name CHAR(50) CHARACTER SET utf8 BINARY CHARACTER set utf8)", false}, {"CREATE TABLE foo (name CHAR(50) BINARY CHARACTER SET utf8 COLLATE utf8_bin)", true}, {"CREATE TABLE foo (a.b, b);", false}, {"CREATE TABLE foo (a, b.c);", false}, @@ -1555,6 +1557,7 @@ func (s *testParserSuite) TestDDL(c *C) { {"ALTER TABLE t ENABLE KEYS", true}, {"ALTER TABLE t MODIFY COLUMN a varchar(255)", true}, {"ALTER TABLE t CHANGE COLUMN a b varchar(255)", true}, + {"ALTER TABLE t CHANGE COLUMN a b varchar(255) CHARACTER SET utf8 BINARY", true}, {"ALTER TABLE t CHANGE COLUMN a b varchar(255) FIRST", true}, {"ALTER TABLE db.t RENAME to db1.t1", true}, {"ALTER TABLE db.t RENAME db1.t1", true},