From 01dac873baa102c4a8ae9a99b7253d03f9044c90 Mon Sep 17 00:00:00 2001 From: Shen Li Date: Sat, 31 Oct 2015 22:37:27 +0800 Subject: [PATCH] *: Address ci problem --- ast/expressions.go | 4 +++- ast/parser/parser.y | 18 ++++++++++++++++++ ast/parser/scanner.l | 19 ++++++++++++++++++- 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/ast/expressions.go b/ast/expressions.go index 6c09874750..7c82ed2d2a 100644 --- a/ast/expressions.go +++ b/ast/expressions.go @@ -56,7 +56,7 @@ type ValueExpr struct { // NewValueExpr creates a ValueExpr with value, and sets default field type. func NewValueExpr(value interface{}) *ValueExpr { ve := &ValueExpr{} - ve.Data = value + ve.Data = types.RawData(value) // TODO: make it more precise. switch value.(type) { case nil: @@ -82,6 +82,8 @@ func NewValueExpr(value interface{}) *ValueExpr { ve.Type = types.NewFieldType(mysql.TypeVarchar) ve.Type.Charset = "binary" ve.Type.Collate = "binary" + case *types.DataItem: + ve.Type = value.(*types.DataItem).Type default: panic(fmt.Sprintf("illegal literal value type:%T", value)) } diff --git a/ast/parser/parser.y b/ast/parser/parser.y index 9c02a8e4c5..127a3b965d 100644 --- a/ast/parser/parser.y +++ b/ast/parser/parser.y @@ -239,6 +239,7 @@ import ( trim "TRIM" trueKwd "true" truncate "TRUNCATE" + underscoreCS "UNDERSCORE_CHARSET" unknown "UNKNOWN" union "UNION" unique "UNIQUE" @@ -1796,6 +1797,23 @@ Literal: | floatLit | intLit | stringLit +| "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 + $$ = &types.DataItem{ + Type: tp, + Data: $2.(string), + } + } | hexLit | bitLit diff --git a/ast/parser/scanner.l b/ast/parser/scanner.l index 048817d1b9..adaa662651 100644 --- a/ast/parser/scanner.l +++ b/ast/parser/scanner.l @@ -27,6 +27,7 @@ import ( "github.com/pingcap/tidb/ast" "github.com/pingcap/tidb/mysql" + "github.com/pingcap/tidb/util/charset" "github.com/pingcap/tidb/util/stringutil" ) @@ -1010,7 +1011,7 @@ year_month {y}{e}{a}{r}_{m}{o}{n}{t}{h} return integerType {ident} lval.item = string(l.val) - return identifier + return l.handleIdent(lval) . return c0 @@ -1101,3 +1102,19 @@ func (l *lexer) bit(lval *yySymType) int { lval.item = b return bitLit } + +func (l *lexer) handleIdent(lval *yySymType) int { + s := lval.item.(string) + // A character string literal may have an optional character set introducer and COLLATE clause: + // [_charset_name]'string' [COLLATE collation_name] + // See: https://dev.mysql.com/doc/refman/5.7/en/charset-literal.html + if !strings.HasPrefix(s, "_") { + return identifier + } + cs, _, err := charset.GetCharsetInfo(s[1:]) + if err != nil { + return identifier + } + lval.item = cs + return underscoreCS +}