diff --git a/parser/parser.y b/parser/parser.y index 8b70e02903..f3557e88d7 100644 --- a/parser/parser.y +++ b/parser/parser.y @@ -425,6 +425,7 @@ import ( Identifier "identifier or unreserved keyword" UnReservedKeyword "MySQL unreserved keywords" + NotKeywordToken "Tokens not mysql keyword but treated specially" WhenClause "When clause" WhenClauseList "When clause list" @@ -470,7 +471,7 @@ import ( %left xor %left andand and %left between -%precedence lower_than_eq +%precedence lowerThanEq %left eq ge le neq neqSynonym '>' '<' is like in %left '|' %left '&' @@ -1526,15 +1527,17 @@ IndexType: /**********************************Identifier********************************************/ Identifier: - identifier | UnReservedKeyword + identifier | UnReservedKeyword | NotKeywordToken -// TODO: Add Data Type UnReserved Keywords UnReservedKeyword: - "AUTO_INCREMENT" | "BEGIN" | "BIT" | "BOOL" | "BOOLEAN" | "CHARSET" | "COLUMN" | "COLUMNS" | "DATE" | "DATETIME" -| "ENGINE" | "FULL" | "LOCAL" | "NAMES" | "OFFSET" | "PASSWORD" %prec lower_than_eq | "QUICK" | "ROLLBACK" | "SESSION" | "GLOBAL" -| "TABLES"| "TEXT" | "TIME" | "TIMESTAMP" | "TRANSACTION" | "TRUNCATE" | "VALUE" | "WARNINGS" | "YEAR" | "NOW" -| "SUBSTRING" | "MODE" + "AUTO_INCREMENT" | "AFTER" | "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" +| "START" | "GLOBAL" | "TABLES"| "TEXT" | "TIME" | "TIMESTAMP" | "TRANSACTION" | "TRUNCATE" | "UNKNOWN" +| "VALUE" | "WARNINGS" | "YEAR" | "NOW" | "MODE" +NotKeywordToken: + "SQL_CALC_FOUND_ROWS" | "SUBSTRING" /************************************************************************************ * diff --git a/parser/parser_test.go b/parser/parser_test.go index 9aa2c0590d..12b46a28d9 100644 --- a/parser/parser_test.go +++ b/parser/parser_test.go @@ -268,9 +268,6 @@ func (s *testParserSuite) TestParser0(c *C) { // For time fsp {"CREATE TABLE t( c1 TIME(2), c2 DATETIME(2), c3 TIMESTAMP(2) );", true}, - - // For unreserved keywords - {"SELECT id, user_id, repo_id, mode FROM access WHERE repo_id=1 AND mode>=1;", true}, } for _, t := range table { @@ -287,6 +284,21 @@ func (s *testParserSuite) TestParser0(c *C) { } } + // Testcase for unreserved keywords + unreservedKws := []string{ + "auto_increment", "after", "begin", "bit", "bool", "boolean", "charset", "columns", "commit", + "date", "datetime", "deallocate", "do", "end", "engine", "engines", "execute", "first", "full", + "local", "names", "offset", "password", "prepare", "quick", "rollback", "session", "signed", + "start", "global", "tables", "text", "time", "timestamp", "transaction", "truncate", "unknown", + "value", "warnings", "year", "now", "substring", "mode", + } + for _, kw := range unreservedKws { + src := fmt.Sprintf("SELECT %s FROM tbl;", kw) + l := NewLexer(src) + c.Assert(yyParse(l), Equals, 0) + c.Assert(l.errs, HasLen, 0, Commentf("source %s", src)) + } + // Testcase for prepared statement src := "SELECT id+?, id+? from t;" l := NewLexer(src) diff --git a/parser/scanner.l b/parser/scanner.l index f1ca9cf658..6a917dd58f 100644 --- a/parser/scanner.l +++ b/parser/scanner.l @@ -452,7 +452,8 @@ sys_var "@@"(({global}".")|({session}".")|{local}".")?{ident} "?" return placeholder {add} return add -{after} return after +{after} lval.item = string(l.val) + return after {all} return all {alter} return alter {and} return and @@ -467,20 +468,22 @@ sys_var "@@"(({global}".")|({session}".")|{local}".")?{ident} {case} return caseKwd {cast} return cast {character} return character -{charset} return charsetKwd +{charset} lval.item = string(l.val) + return charsetKwd {collate} return collation -{column} lval.item = string(l.val) - return column +{column} return column {columns} lval.item = string(l.val) return columns -{commit} return commit +{commit} lval.item = string(l.val) + return commit {constraint} return constraint {convert} return convert {create} return create {cross} return cross {database} return database {databases} return databases -{deallocate} return deallocate +{deallocate} lval.item = string(l.val) + return deallocate {default} return defaultKwd {delayed} return delayed {delete} return deleteKwd @@ -489,17 +492,23 @@ sys_var "@@"(({global}".")|({session}".")|{local}".")?{ident} {drop} return drop {distinct} return distinct {div} return div -{do} return do -{duplicate} return duplicate +{do} lval.item = string(l.val) + return do +{duplicate} lval.item = string(l.val) + return duplicate {else} return elseKwd -{end} return end +{end} lval.item = string(l.val) + return end {engine} lval.item = string(l.val) return engine -{engines} return engines -{execute} return execute +{engines} lval.item = string(l.val) + return engines +{execute} lval.item = string(l.val) + return execute {exists} return exists {explain} return explain -{first} return first +{first} lval.item = string(l.val) + return first {for} return forKwd {foreign} return foreign {from} return from @@ -540,7 +549,8 @@ sys_var "@@"(({global}".")|({session}".")|{local}".")?{ident} {outer} return outer {password} lval.item = string(l.val) return password -{prepare} return prepare +{prepare} lval.item = string(l.val) + return prepare {primary} return primary {quick} lval.item = string(l.val) return quick @@ -551,7 +561,8 @@ sys_var "@@"(({global}".")|({session}".")|{local}".")?{ident} {schemas} return schemas {session} lval.item = string(l.val) return session -{start} return start +{start} lval.item = string(l.val) + return start {global} lval.item = string(l.val) return global {regexp} return regexp @@ -582,7 +593,8 @@ sys_var "@@"(({global}".")|({session}".")|{local}".")?{ident} {update} return update {union} return union {unique} return unique -{unknown} return unknown +{unknown} lval.item = string(l.val) + return unknown {use} return use {using} return using {value} lval.item = string(l.val) @@ -594,7 +606,8 @@ sys_var "@@"(({global}".")|({session}".")|{local}".")?{ident} {where} return where {xor} return xor -{signed} return signed +{signed} lval.item = string(l.val) + return signed {unsigned} return unsigned {zerofill} return zerofill @@ -605,7 +618,8 @@ sys_var "@@"(({global}".")|({session}".")|{local}".")?{ident} {true} return trueKwd -{calc_found_rows} return calcFoundRows +{calc_found_rows} lval.item = string(l.val) + return calcFoundRows {current_ts} return currentTs {localtime} return localTime