github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/pingcap/tidb/parser/parser_test.go (about)

     1  // Copyright 2015 PingCAP, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package parser
    15  
    16  import (
    17  	"fmt"
    18  	"testing"
    19  
    20  	. "github.com/insionng/yougam/libraries/pingcap/check"
    21  	"github.com/insionng/yougam/libraries/pingcap/tidb/ast"
    22  	"github.com/insionng/yougam/libraries/pingcap/tidb/util/testleak"
    23  )
    24  
    25  func TestT(t *testing.T) {
    26  	TestingT(t)
    27  }
    28  
    29  var _ = Suite(&testParserSuite{})
    30  
    31  type testParserSuite struct {
    32  }
    33  
    34  func (s *testParserSuite) TestSimple(c *C) {
    35  	defer testleak.AfterTest(c)()
    36  	// Testcase for unreserved keywords
    37  	unreservedKws := []string{
    38  		"auto_increment", "after", "begin", "bit", "bool", "boolean", "charset", "columns", "commit",
    39  		"date", "datetime", "deallocate", "do", "end", "engine", "engines", "execute", "first", "full",
    40  		"local", "names", "offset", "password", "prepare", "quick", "rollback", "session", "signed",
    41  		"start", "global", "tables", "text", "time", "timestamp", "transaction", "truncate", "unknown",
    42  		"value", "warnings", "year", "now", "substr", "substring", "mode", "any", "some", "user", "identified",
    43  		"collation", "comment", "avg_row_length", "checksum", "compression", "connection", "key_block_size",
    44  		"max_rows", "min_rows", "national", "row", "quarter", "escape", "grants", "status", "fields", "triggers",
    45  		"delay_key_write", "isolation", "repeatable", "committed", "uncommitted", "only", "serializable", "level",
    46  		"curtime", "variables", "dayname", "version", "btree", "hash", "row_format", "dynamic", "fixed", "compressed",
    47  		"compact", "redundant", "sql_no_cache sql_no_cache", "sql_cache sql_cache", "action", "round",
    48  		"enable", "disable", "reverse",
    49  	}
    50  	for _, kw := range unreservedKws {
    51  		src := fmt.Sprintf("SELECT %s FROM tbl;", kw)
    52  		_, err := ParseOneStmt(src, "", "")
    53  		c.Assert(err, IsNil, Commentf("source %s", src))
    54  	}
    55  
    56  	// Testcase for prepared statement
    57  	src := "SELECT id+?, id+? from t;"
    58  	_, err := ParseOneStmt(src, "", "")
    59  	c.Assert(err, IsNil)
    60  
    61  	// Testcase for -- Comment and unary -- operator
    62  	src = "CREATE TABLE foo (a SMALLINT UNSIGNED, b INT UNSIGNED); -- foo\nSelect --1 from foo;"
    63  	stmts, err := Parse(src, "", "")
    64  	c.Assert(err, IsNil)
    65  	c.Assert(stmts, HasLen, 2)
    66  
    67  	// Testcase for /*! xx */
    68  	// See: http://dev.mysql.com/doc/refman/5.7/en/comments.html
    69  	// Fix: https://yougam/libraries/pingcap/tidb/issues/971
    70  	src = "/*!40101 SET character_set_client = utf8 */;"
    71  	stmts, err = Parse(src, "", "")
    72  	c.Assert(err, IsNil)
    73  	c.Assert(stmts, HasLen, 1)
    74  	stmt := stmts[0]
    75  	_, ok := stmt.(*ast.SetStmt)
    76  	c.Assert(ok, IsTrue)
    77  
    78  	// Testcase for CONVERT(expr,type)
    79  	src = "SELECT CONVERT('111', SIGNED);"
    80  	st, err := ParseOneStmt(src, "", "")
    81  	c.Assert(err, IsNil)
    82  	ss, ok := st.(*ast.SelectStmt)
    83  	c.Assert(ok, IsTrue)
    84  	c.Assert(len(ss.Fields.Fields), Equals, 1)
    85  	cv, ok := ss.Fields.Fields[0].Expr.(*ast.FuncCastExpr)
    86  	c.Assert(ok, IsTrue)
    87  	c.Assert(cv.FunctionType, Equals, ast.CastConvertFunction)
    88  
    89  	// For query start with comment
    90  	srcs := []string{
    91  		"/* some comments */ SELECT CONVERT('111', SIGNED) ;",
    92  		"/* some comments */ /*comment*/ SELECT CONVERT('111', SIGNED) ;",
    93  		"SELECT /*comment*/ CONVERT('111', SIGNED) ;",
    94  		"SELECT CONVERT('111', /*comment*/ SIGNED) ;",
    95  		"SELECT CONVERT('111', SIGNED) /*comment*/;",
    96  	}
    97  	for _, src := range srcs {
    98  		st, err = ParseOneStmt(src, "", "")
    99  		c.Assert(err, IsNil)
   100  		ss, ok = st.(*ast.SelectStmt)
   101  		c.Assert(ok, IsTrue)
   102  	}
   103  
   104  	// For issue #961
   105  	src = "create table t (c int key);"
   106  	st, err = ParseOneStmt(src, "", "")
   107  	c.Assert(err, IsNil)
   108  	cs, ok := st.(*ast.CreateTableStmt)
   109  	c.Assert(ok, IsTrue)
   110  	c.Assert(cs.Cols, HasLen, 1)
   111  	c.Assert(cs.Cols[0].Options, HasLen, 1)
   112  	c.Assert(cs.Cols[0].Options[0].Tp, Equals, ast.ColumnOptionPrimaryKey)
   113  }
   114  
   115  type testCase struct {
   116  	src string
   117  	ok  bool
   118  }
   119  
   120  func (s *testParserSuite) RunTest(c *C, table []testCase) {
   121  	for _, t := range table {
   122  		_, err := Parse(t.src, "", "")
   123  		comment := Commentf("source %v", t.src)
   124  		if t.ok {
   125  			c.Assert(err, IsNil, comment)
   126  		} else {
   127  			c.Assert(err, NotNil, comment)
   128  		}
   129  	}
   130  }
   131  func (s *testParserSuite) TestDMLStmt(c *C) {
   132  	defer testleak.AfterTest(c)()
   133  	table := []testCase{
   134  		{"", true},
   135  		{";", true},
   136  		{"INSERT INTO foo VALUES (1234)", true},
   137  		{"INSERT INTO foo VALUES (1234, 5678)", true},
   138  		// 15
   139  		{"INSERT INTO foo VALUES (1 || 2)", true},
   140  		{"INSERT INTO foo VALUES (1 | 2)", true},
   141  		{"INSERT INTO foo VALUES (false || true)", true},
   142  		{"INSERT INTO foo VALUES (bar(5678))", false},
   143  		// 20
   144  		{"INSERT INTO foo VALUES ()", true},
   145  		{"SELECT * FROM t", true},
   146  		{"SELECT * FROM t AS u", true},
   147  		// 25
   148  		{"SELECT * FROM t, v", true},
   149  		{"SELECT * FROM t AS u, v", true},
   150  		{"SELECT * FROM t, v AS w", true},
   151  		{"SELECT * FROM t AS u, v AS w", true},
   152  		{"SELECT * FROM foo, bar, foo", true},
   153  		// 30
   154  		{"SELECT DISTINCTS * FROM t", false},
   155  		{"SELECT DISTINCT * FROM t", true},
   156  		{"INSERT INTO foo (a) VALUES (42)", true},
   157  		{"INSERT INTO foo (a,) VALUES (42,)", false},
   158  		// 35
   159  		{"INSERT INTO foo (a,b) VALUES (42,314)", true},
   160  		{"INSERT INTO foo (a,b,) VALUES (42,314)", false},
   161  		{"INSERT INTO foo (a,b,) VALUES (42,314,)", false},
   162  		{"INSERT INTO foo () VALUES ()", true},
   163  		{"INSERT INTO foo VALUE ()", true},
   164  
   165  		{"REPLACE INTO foo VALUES (1 || 2)", true},
   166  		{"REPLACE INTO foo VALUES (1 | 2)", true},
   167  		{"REPLACE INTO foo VALUES (false || true)", true},
   168  		{"REPLACE INTO foo VALUES (bar(5678))", false},
   169  		{"REPLACE INTO foo VALUES ()", true},
   170  		{"REPLACE INTO foo (a,b) VALUES (42,314)", true},
   171  		{"REPLACE INTO foo (a,b,) VALUES (42,314)", false},
   172  		{"REPLACE INTO foo (a,b,) VALUES (42,314,)", false},
   173  		{"REPLACE INTO foo () VALUES ()", true},
   174  		{"REPLACE INTO foo VALUE ()", true},
   175  		// 40
   176  		{`SELECT stuff.id
   177  		FROM stuff
   178  		WHERE stuff.value >= ALL (SELECT stuff.value
   179  		FROM stuff)`, true},
   180  		{"BEGIN", true},
   181  		{"START TRANSACTION", true},
   182  		// 45
   183  		{"COMMIT", true},
   184  		{"ROLLBACK", true},
   185  		{`
   186  		BEGIN;
   187  			INSERT INTO foo VALUES (42, 3.14);
   188  			INSERT INTO foo VALUES (-1, 2.78);
   189  		COMMIT;`, true},
   190  		{` // A
   191  		BEGIN;
   192  			INSERT INTO tmp SELECT * from bar;
   193  		SELECT * from tmp;
   194  
   195  		// B
   196  		ROLLBACK;`, true},
   197  
   198  		// set
   199  		// user defined
   200  		{"SET @a = 1", true},
   201  		{"SET @b := 1", true},
   202  		// session system variables
   203  		{"SET SESSION autocommit = 1", true},
   204  		{"SET @@session.autocommit = 1", true},
   205  		{"SET LOCAL autocommit = 1", true},
   206  		{"SET @@local.autocommit = 1", true},
   207  		{"SET @@autocommit = 1", true},
   208  		{"SET autocommit = 1", true},
   209  		// global system variables
   210  		{"SET GLOBAL autocommit = 1", true},
   211  		{"SET @@global.autocommit = 1", true},
   212  		// SET CHARACTER SET
   213  		{"SET CHARACTER SET utf8mb4;", true},
   214  		{"SET CHARACTER SET 'utf8mb4';", true},
   215  		// Set password
   216  		{"SET PASSWORD = 'password';", true},
   217  		{"SET PASSWORD FOR 'root'@'localhost' = 'password';", true},
   218  		// SET TRANSACTION Syntax
   219  		{"SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ", true},
   220  		{"SET GLOBAL TRANSACTION ISOLATION LEVEL REPEATABLE READ", true},
   221  		{"SET SESSION TRANSACTION READ WRITE", true},
   222  		{"SET SESSION TRANSACTION READ ONLY", true},
   223  		{"SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED", true},
   224  		{"SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED", true},
   225  		{"SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE", true},
   226  
   227  		// qualified select
   228  		{"SELECT a.b.c FROM t", true},
   229  		{"SELECT a.b.*.c FROM t", false},
   230  		{"SELECT a.b.* FROM t", true},
   231  		{"SELECT a FROM t", true},
   232  		{"SELECT a.b.c.d FROM t", false},
   233  
   234  		// Do statement
   235  		{"DO 1", true},
   236  		{"DO 1 from t", false},
   237  
   238  		// Select for update
   239  		{"SELECT * from t for update", true},
   240  		{"SELECT * from t lock in share mode", true},
   241  
   242  		// For alter table
   243  		{"ALTER TABLE t ADD COLUMN a SMALLINT UNSIGNED", true},
   244  		{"ALTER TABLE t ADD COLUMN a SMALLINT UNSIGNED FIRST", true},
   245  		{"ALTER TABLE t ADD COLUMN a SMALLINT UNSIGNED AFTER b", true},
   246  		{"ALTER TABLE t DISABLE KEYS", true},
   247  		{"ALTER TABLE t ENABLE KEYS", true},
   248  
   249  		// from join
   250  		{"SELECT * from t1, t2, t3", true},
   251  		{"select * from t1 join t2 left join t3 on t2.id = t3.id", true},
   252  		{"select * from t1 right join t2 on t1.id = t2.id left join t3 on t3.id = t2.id", true},
   253  		{"select * from t1 right join t2 on t1.id = t2.id left join t3", false},
   254  
   255  		// For show full columns
   256  		{"show columns in t;", true},
   257  		{"show full columns in t;", true},
   258  
   259  		// For admin
   260  		{"admin show ddl;", true},
   261  		{"admin check table t1, t2;", true},
   262  
   263  		// For set names
   264  		{"set names utf8", true},
   265  		{"set names utf8 collate utf8_unicode_ci", true},
   266  
   267  		// For show character set
   268  		{"show character set;", true},
   269  		// For on duplicate key update
   270  		{"INSERT INTO t (a,b,c) VALUES (1,2,3),(4,5,6) ON DUPLICATE KEY UPDATE c=VALUES(a)+VALUES(b);", true},
   271  		{"INSERT IGNORE INTO t (a,b,c) VALUES (1,2,3),(4,5,6) ON DUPLICATE KEY UPDATE c=VALUES(a)+VALUES(b);", true},
   272  
   273  		// For SHOW statement
   274  		{"SHOW VARIABLES LIKE 'character_set_results'", true},
   275  		{"SHOW GLOBAL VARIABLES LIKE 'character_set_results'", true},
   276  		{"SHOW SESSION VARIABLES LIKE 'character_set_results'", true},
   277  		{"SHOW VARIABLES", true},
   278  		{"SHOW GLOBAL VARIABLES", true},
   279  		{"SHOW GLOBAL VARIABLES WHERE Variable_name = 'autocommit'", true},
   280  		{"SHOW STATUS", true},
   281  		{"SHOW GLOBAL STATUS", true},
   282  		{"SHOW SESSION STATUS", true},
   283  		{"SHOW STATUS LIKE 'Up%'", true},
   284  		{"SHOW STATUS WHERE Variable_name LIKE 'Up%'", true},
   285  		{`SHOW FULL TABLES FROM icar_qa LIKE play_evolutions`, true},
   286  		{`SHOW FULL TABLES WHERE Table_Type != 'VIEW'`, true},
   287  		{`SHOW GRANTS`, true},
   288  		{`SHOW GRANTS FOR 'test'@'localhost'`, true},
   289  		{`SHOW COLUMNS FROM City;`, true},
   290  		{`SHOW FIELDS FROM City;`, true},
   291  		{`SHOW TRIGGERS LIKE 't'`, true},
   292  		{`SHOW DATABASES LIKE 'test2'`, true},
   293  		{`SHOW PROCEDURE STATUS WHERE Db='test'`, true},
   294  		{`SHOW INDEX FROM t;`, true},
   295  
   296  		// For default value
   297  		{"CREATE TABLE sbtest (id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, k integer UNSIGNED DEFAULT '0' NOT NULL, c char(120) DEFAULT '' NOT NULL, pad char(60) DEFAULT '' NOT NULL, PRIMARY KEY  (id) )", true},
   298  		{"create table test (create_date TIMESTAMP NOT NULL COMMENT '创建日期 create date' DEFAULT now());", true},
   299  
   300  		// For truncate statement
   301  		{"TRUNCATE TABLE t1", true},
   302  		{"TRUNCATE t1", true},
   303  
   304  		// For delete statement
   305  		{"DELETE t1, t2 FROM t1 INNER JOIN t2 INNER JOIN t3 WHERE t1.id=t2.id AND t2.id=t3.id;", true},
   306  		{"DELETE FROM t1, t2 USING t1 INNER JOIN t2 INNER JOIN t3 WHERE t1.id=t2.id AND t2.id=t3.id;", true},
   307  		{"DELETE t1, t2 FROM t1 INNER JOIN t2 INNER JOIN t3 WHERE t1.id=t2.id AND t2.id=t3.id limit 10;", false},
   308  
   309  		// For update statement
   310  		{"UPDATE t SET id = id + 1 ORDER BY id DESC;", true},
   311  		{"UPDATE items,month SET items.price=month.price WHERE items.id=month.id;", true},
   312  		{"UPDATE items,month SET items.price=month.price WHERE items.id=month.id LIMIT 10;", false},
   313  		{"UPDATE user T0 LEFT OUTER JOIN user_profile T1 ON T1.id = T0.profile_id SET T0.profile_id = 1 WHERE T0.profile_id IN (1);", true},
   314  
   315  		// For select with where clause
   316  		{"SELECT * FROM t WHERE 1 = 1", true},
   317  
   318  		// For show collation
   319  		{"show collation", true},
   320  		{"show collation like 'utf8%'", true},
   321  		{"show collation where Charset = 'utf8' and Collation = 'utf8_bin'", true},
   322  
   323  		// For dual
   324  		{"select 1 from dual", true},
   325  		{"select 1 from dual limit 1", true},
   326  		{"select 1 where exists (select 2)", false},
   327  		{"select 1 from dual where not exists (select 2)", true},
   328  
   329  		// For show create table
   330  		{"show create table test.t", true},
   331  		{"show create table t", true},
   332  
   333  		// For https://yougam/libraries/pingcap/tidb/issues/320
   334  		{`(select 1);`, true},
   335  
   336  		// For https://yougam/libraries/pingcap/tidb/issues/1050
   337  		{`SELECT /*!40001 SQL_NO_CACHE */ * FROM test WHERE 1 limit 0, 2000;`, true},
   338  	}
   339  	s.RunTest(c, table)
   340  }
   341  
   342  func (s *testParserSuite) TestExpression(c *C) {
   343  	defer testleak.AfterTest(c)()
   344  	table := []testCase{
   345  		// Sign expression
   346  		{"SELECT ++1", true},
   347  		{"SELECT -*1", false},
   348  		{"SELECT -+1", true},
   349  		{"SELECT -1", true},
   350  		{"SELECT --1", true},
   351  
   352  		// For string literal
   353  		{`select '''a''', """a"""`, true},
   354  		{`select ''a''`, false},
   355  		{`select ""a""`, false},
   356  		{`select '''a''';`, true},
   357  		{`select '\'a\'';`, true},
   358  		{`select "\"a\"";`, true},
   359  		{`select """a""";`, true},
   360  		{`select _utf8"string";`, true},
   361  		// For comparison
   362  		{"select 1 <=> 0, 1 <=> null, 1 = null", true},
   363  	}
   364  	s.RunTest(c, table)
   365  }
   366  
   367  func (s *testParserSuite) TestBuiltin(c *C) {
   368  	defer testleak.AfterTest(c)()
   369  	table := []testCase{
   370  		// For buildin functions
   371  		{"SELECT POW(1, 2)", true},
   372  		{"SELECT POW(1, 0.5)", true},
   373  		{"SELECT POW(1, -1)", true},
   374  		{"SELECT POW(-1, 1)", true},
   375  		{"SELECT RAND();", true},
   376  		{"SELECT RAND(1);", true},
   377  		{"SELECT MOD(10, 2);", true},
   378  		{"SELECT ROUND(-1.23);", true},
   379  		{"SELECT ROUND(1.23, 1);", true},
   380  
   381  		{"SELECT SUBSTR('Quadratically',5);", true},
   382  		{"SELECT SUBSTR('Quadratically',5, 3);", true},
   383  		{"SELECT SUBSTR('Quadratically' FROM 5);", true},
   384  		{"SELECT SUBSTR('Quadratically' FROM 5 FOR 3);", true},
   385  
   386  		{"SELECT SUBSTRING('Quadratically',5);", true},
   387  		{"SELECT SUBSTRING('Quadratically',5, 3);", true},
   388  		{"SELECT SUBSTRING('Quadratically' FROM 5);", true},
   389  		{"SELECT SUBSTRING('Quadratically' FROM 5 FOR 3);", true},
   390  
   391  		{"SELECT CONVERT('111', SIGNED);", true},
   392  
   393  		// Information Functions
   394  		{"SELECT DATABASE();", true},
   395  		{"SELECT USER();", true},
   396  		{"SELECT CURRENT_USER();", true},
   397  		{"SELECT CURRENT_USER;", true},
   398  		{"SELECT CONNECTION_ID();", true},
   399  		{"SELECT VERSION();", true},
   400  
   401  		{"SELECT SUBSTRING_INDEX('www.mysql.com', '.', 2);", true},
   402  		{"SELECT SUBSTRING_INDEX('www.mysql.com', '.', -2);", true},
   403  
   404  		{`SELECT ASCII(""), ASCII("A"), ASCII(1);`, true},
   405  
   406  		{`SELECT LOWER("A"), UPPER("a")`, true},
   407  		{`SELECT LCASE("A"), UCASE("a")`, true},
   408  
   409  		{`SELECT REPLACE('www.mysql.com', 'w', 'Ww')`, true},
   410  
   411  		{`SELECT LOCATE('bar', 'foobarbar');`, true},
   412  		{`SELECT LOCATE('bar', 'foobarbar', 5);`, true},
   413  
   414  		// For time fsp
   415  		{"CREATE TABLE t( c1 TIME(2), c2 DATETIME(2), c3 TIMESTAMP(2) );", true},
   416  
   417  		// For row
   418  		{"select row(1)", false},
   419  		{"select row(1, 1,)", false},
   420  		{"select (1, 1,)", false},
   421  		{"select row(1, 1) > row(1, 1), row(1, 1, 1) > row(1, 1, 1)", true},
   422  		{"Select (1, 1) > (1, 1)", true},
   423  		{"create table t (row int)", true},
   424  
   425  		// For cast with charset
   426  		{"SELECT *, CAST(data AS CHAR CHARACTER SET utf8) FROM t;", true},
   427  
   428  		// For binary operator
   429  		{"SELECT binary 'a';", true},
   430  
   431  		// Select time
   432  		{"select current_timestamp", true},
   433  		{"select current_timestamp()", true},
   434  		{"select current_timestamp(6)", true},
   435  		{"select now()", true},
   436  		{"select now(6)", true},
   437  		{"select sysdate(), sysdate(6)", true},
   438  
   439  		// Select current_time
   440  		{"select current_time", true},
   441  		{"select current_time()", true},
   442  		{"select current_time(6)", true},
   443  		{"select curtime()", true},
   444  		{"select curtime(6)", true},
   445  
   446  		// for microsecond, second, minute, hour
   447  		{"SELECT MICROSECOND('2009-12-31 23:59:59.000010');", true},
   448  		{"SELECT SECOND('10:05:03');", true},
   449  		{"SELECT MINUTE('2008-02-03 10:05:03');", true},
   450  		{"SELECT HOUR('10:05:03');", true},
   451  
   452  		// for date, day, weekday
   453  		{"SELECT DATE('2003-12-31 01:02:03');", true},
   454  		{"SELECT CURRENT_DATE, CURRENT_DATE(), CURDATE()", true},
   455  		{"SELECT DAY('2007-02-03');", true},
   456  		{"SELECT DAYOFMONTH('2007-02-03');", true},
   457  		{"SELECT DAYOFWEEK('2007-02-03');", true},
   458  		{"SELECT DAYOFYEAR('2007-02-03');", true},
   459  		{"SELECT DAYNAME('2007-02-03');", true},
   460  		{"SELECT WEEKDAY('2007-02-03');", true},
   461  
   462  		// For utc_date
   463  		{"SELECT UTC_DATE, UTC_DATE();", true},
   464  
   465  		// for week, month, year
   466  		{"SELECT WEEK('2007-02-03');", true},
   467  		{"SELECT WEEK('2007-02-03', 0);", true},
   468  		{"SELECT WEEKOFYEAR('2007-02-03');", true},
   469  		{"SELECT MONTH('2007-02-03');", true},
   470  		{"SELECT YEAR('2007-02-03');", true},
   471  		{"SELECT YEARWEEK('2007-02-03');", true},
   472  		{"SELECT YEARWEEK('2007-02-03', 0);", true},
   473  
   474  		// For time extract
   475  		{`select extract(microsecond from "2011-11-11 10:10:10.123456")`, true},
   476  		{`select extract(second from "2011-11-11 10:10:10.123456")`, true},
   477  		{`select extract(minute from "2011-11-11 10:10:10.123456")`, true},
   478  		{`select extract(hour from "2011-11-11 10:10:10.123456")`, true},
   479  		{`select extract(day from "2011-11-11 10:10:10.123456")`, true},
   480  		{`select extract(week from "2011-11-11 10:10:10.123456")`, true},
   481  		{`select extract(month from "2011-11-11 10:10:10.123456")`, true},
   482  		{`select extract(quarter from "2011-11-11 10:10:10.123456")`, true},
   483  		{`select extract(year from "2011-11-11 10:10:10.123456")`, true},
   484  		{`select extract(second_microsecond from "2011-11-11 10:10:10.123456")`, true},
   485  		{`select extract(minute_microsecond from "2011-11-11 10:10:10.123456")`, true},
   486  		{`select extract(minute_second from "2011-11-11 10:10:10.123456")`, true},
   487  		{`select extract(hour_microsecond from "2011-11-11 10:10:10.123456")`, true},
   488  		{`select extract(hour_second from "2011-11-11 10:10:10.123456")`, true},
   489  		{`select extract(hour_minute from "2011-11-11 10:10:10.123456")`, true},
   490  		{`select extract(day_microsecond from "2011-11-11 10:10:10.123456")`, true},
   491  		{`select extract(day_second from "2011-11-11 10:10:10.123456")`, true},
   492  		{`select extract(day_minute from "2011-11-11 10:10:10.123456")`, true},
   493  		{`select extract(day_hour from "2011-11-11 10:10:10.123456")`, true},
   494  		{`select extract(year_month from "2011-11-11 10:10:10.123456")`, true},
   495  
   496  		// For issue 224
   497  		{`SELECT CAST('test collated returns' AS CHAR CHARACTER SET utf8) COLLATE utf8_bin;`, true},
   498  
   499  		// For string functions
   500  		// Trim
   501  		{`SELECT TRIM('  bar   ');`, true},
   502  		{`SELECT TRIM(LEADING 'x' FROM 'xxxbarxxx');`, true},
   503  		{`SELECT TRIM(BOTH 'x' FROM 'xxxbarxxx');`, true},
   504  		{`SELECT TRIM(TRAILING 'xyz' FROM 'barxxyz');`, true},
   505  		{`SELECT LTRIM(' foo ');`, true},
   506  		{`SELECT RTRIM(' bar ');`, true},
   507  
   508  		// Repeat
   509  		{`SELECT REPEAT("a", 10);`, true},
   510  
   511  		// For date_add
   512  		{`select date_add("2011-11-11 10:10:10.123456", interval 10 microsecond)`, true},
   513  		{`select date_add("2011-11-11 10:10:10.123456", interval 10 second)`, true},
   514  		{`select date_add("2011-11-11 10:10:10.123456", interval 10 minute)`, true},
   515  		{`select date_add("2011-11-11 10:10:10.123456", interval 10 hour)`, true},
   516  		{`select date_add("2011-11-11 10:10:10.123456", interval 10 day)`, true},
   517  		{`select date_add("2011-11-11 10:10:10.123456", interval 1 week)`, true},
   518  		{`select date_add("2011-11-11 10:10:10.123456", interval 1 month)`, true},
   519  		{`select date_add("2011-11-11 10:10:10.123456", interval 1 quarter)`, true},
   520  		{`select date_add("2011-11-11 10:10:10.123456", interval 1 year)`, true},
   521  		{`select date_add("2011-11-11 10:10:10.123456", interval "10.10" second_microsecond)`, true},
   522  		{`select date_add("2011-11-11 10:10:10.123456", interval "10:10.10" minute_microsecond)`, true},
   523  		{`select date_add("2011-11-11 10:10:10.123456", interval "10:10" minute_second)`, true},
   524  		{`select date_add("2011-11-11 10:10:10.123456", interval "10:10:10.10" hour_microsecond)`, true},
   525  		{`select date_add("2011-11-11 10:10:10.123456", interval "10:10:10" hour_second)`, true},
   526  		{`select date_add("2011-11-11 10:10:10.123456", interval "10:10" hour_minute)`, true},
   527  		{`select date_add("2011-11-11 10:10:10.123456", interval "11 10:10:10.10" day_microsecond)`, true},
   528  		{`select date_add("2011-11-11 10:10:10.123456", interval "11 10:10:10" day_second)`, true},
   529  		{`select date_add("2011-11-11 10:10:10.123456", interval "11 10:10" day_minute)`, true},
   530  		{`select date_add("2011-11-11 10:10:10.123456", interval "11 10" day_hour)`, true},
   531  		{`select date_add("2011-11-11 10:10:10.123456", interval "11-11" year_month)`, true},
   532  
   533  		// For adddate
   534  		{`select adddate("2011-11-11 10:10:10.123456", interval 10 microsecond)`, true},
   535  		{`select adddate("2011-11-11 10:10:10.123456", interval 10 second)`, true},
   536  		{`select adddate("2011-11-11 10:10:10.123456", interval 10 minute)`, true},
   537  		{`select adddate("2011-11-11 10:10:10.123456", interval 10 hour)`, true},
   538  		{`select adddate("2011-11-11 10:10:10.123456", interval 10 day)`, true},
   539  		{`select adddate("2011-11-11 10:10:10.123456", interval 1 week)`, true},
   540  		{`select adddate("2011-11-11 10:10:10.123456", interval 1 month)`, true},
   541  		{`select adddate("2011-11-11 10:10:10.123456", interval 1 quarter)`, true},
   542  		{`select adddate("2011-11-11 10:10:10.123456", interval 1 year)`, true},
   543  		{`select adddate("2011-11-11 10:10:10.123456", interval "10.10" second_microsecond)`, true},
   544  		{`select adddate("2011-11-11 10:10:10.123456", interval "10:10.10" minute_microsecond)`, true},
   545  		{`select adddate("2011-11-11 10:10:10.123456", interval "10:10" minute_second)`, true},
   546  		{`select adddate("2011-11-11 10:10:10.123456", interval "10:10:10.10" hour_microsecond)`, true},
   547  		{`select adddate("2011-11-11 10:10:10.123456", interval "10:10:10" hour_second)`, true},
   548  		{`select adddate("2011-11-11 10:10:10.123456", interval "10:10" hour_minute)`, true},
   549  		{`select adddate("2011-11-11 10:10:10.123456", interval "11 10:10:10.10" day_microsecond)`, true},
   550  		{`select adddate("2011-11-11 10:10:10.123456", interval "11 10:10:10" day_second)`, true},
   551  		{`select adddate("2011-11-11 10:10:10.123456", interval "11 10:10" day_minute)`, true},
   552  		{`select adddate("2011-11-11 10:10:10.123456", interval "11 10" day_hour)`, true},
   553  		{`select adddate("2011-11-11 10:10:10.123456", interval "11-11" year_month)`, true},
   554  		{`select adddate("2011-11-11 10:10:10.123456", 10)`, true},
   555  		{`select adddate("2011-11-11 10:10:10.123456", 0.10)`, true},
   556  		{`select adddate("2011-11-11 10:10:10.123456", "11,11")`, true},
   557  
   558  		// For date_sub
   559  		{`select date_sub("2011-11-11 10:10:10.123456", interval 10 microsecond)`, true},
   560  		{`select date_sub("2011-11-11 10:10:10.123456", interval 10 second)`, true},
   561  		{`select date_sub("2011-11-11 10:10:10.123456", interval 10 minute)`, true},
   562  		{`select date_sub("2011-11-11 10:10:10.123456", interval 10 hour)`, true},
   563  		{`select date_sub("2011-11-11 10:10:10.123456", interval 10 day)`, true},
   564  		{`select date_sub("2011-11-11 10:10:10.123456", interval 1 week)`, true},
   565  		{`select date_sub("2011-11-11 10:10:10.123456", interval 1 month)`, true},
   566  		{`select date_sub("2011-11-11 10:10:10.123456", interval 1 quarter)`, true},
   567  		{`select date_sub("2011-11-11 10:10:10.123456", interval 1 year)`, true},
   568  		{`select date_sub("2011-11-11 10:10:10.123456", interval "10.10" second_microsecond)`, true},
   569  		{`select date_sub("2011-11-11 10:10:10.123456", interval "10:10.10" minute_microsecond)`, true},
   570  		{`select date_sub("2011-11-11 10:10:10.123456", interval "10:10" minute_second)`, true},
   571  		{`select date_sub("2011-11-11 10:10:10.123456", interval "10:10:10.10" hour_microsecond)`, true},
   572  		{`select date_sub("2011-11-11 10:10:10.123456", interval "10:10:10" hour_second)`, true},
   573  		{`select date_sub("2011-11-11 10:10:10.123456", interval "10:10" hour_minute)`, true},
   574  		{`select date_sub("2011-11-11 10:10:10.123456", interval "11 10:10:10.10" day_microsecond)`, true},
   575  		{`select date_sub("2011-11-11 10:10:10.123456", interval "11 10:10:10" day_second)`, true},
   576  		{`select date_sub("2011-11-11 10:10:10.123456", interval "11 10:10" day_minute)`, true},
   577  		{`select date_sub("2011-11-11 10:10:10.123456", interval "11 10" day_hour)`, true},
   578  		{`select date_sub("2011-11-11 10:10:10.123456", interval "11-11" year_month)`, true},
   579  
   580  		// For subdate
   581  		{`select subdate("2011-11-11 10:10:10.123456", interval 10 microsecond)`, true},
   582  		{`select subdate("2011-11-11 10:10:10.123456", interval 10 second)`, true},
   583  		{`select subdate("2011-11-11 10:10:10.123456", interval 10 minute)`, true},
   584  		{`select subdate("2011-11-11 10:10:10.123456", interval 10 hour)`, true},
   585  		{`select subdate("2011-11-11 10:10:10.123456", interval 10 day)`, true},
   586  		{`select subdate("2011-11-11 10:10:10.123456", interval 1 week)`, true},
   587  		{`select subdate("2011-11-11 10:10:10.123456", interval 1 month)`, true},
   588  		{`select subdate("2011-11-11 10:10:10.123456", interval 1 quarter)`, true},
   589  		{`select subdate("2011-11-11 10:10:10.123456", interval 1 year)`, true},
   590  		{`select subdate("2011-11-11 10:10:10.123456", interval "10.10" second_microsecond)`, true},
   591  		{`select subdate("2011-11-11 10:10:10.123456", interval "10:10.10" minute_microsecond)`, true},
   592  		{`select subdate("2011-11-11 10:10:10.123456", interval "10:10" minute_second)`, true},
   593  		{`select subdate("2011-11-11 10:10:10.123456", interval "10:10:10.10" hour_microsecond)`, true},
   594  		{`select subdate("2011-11-11 10:10:10.123456", interval "10:10:10" hour_second)`, true},
   595  		{`select subdate("2011-11-11 10:10:10.123456", interval "10:10" hour_minute)`, true},
   596  		{`select subdate("2011-11-11 10:10:10.123456", interval "11 10:10:10.10" day_microsecond)`, true},
   597  		{`select subdate("2011-11-11 10:10:10.123456", interval "11 10:10:10" day_second)`, true},
   598  		{`select subdate("2011-11-11 10:10:10.123456", interval "11 10:10" day_minute)`, true},
   599  		{`select subdate("2011-11-11 10:10:10.123456", interval "11 10" day_hour)`, true},
   600  		{`select subdate("2011-11-11 10:10:10.123456", interval "11-11" year_month)`, true},
   601  		{`select adddate("2011-11-11 10:10:10.123456", 10)`, true},
   602  		{`select adddate("2011-11-11 10:10:10.123456", 0.10)`, true},
   603  		{`select adddate("2011-11-11 10:10:10.123456", "11,11")`, true},
   604  	}
   605  	s.RunTest(c, table)
   606  }
   607  
   608  func (s *testParserSuite) TestIdentifier(c *C) {
   609  	defer testleak.AfterTest(c)()
   610  	table := []testCase{
   611  		// For quote identifier
   612  		{"select `a`, `a.b`, `a b` from t", true},
   613  		// For unquoted identifier
   614  		{"create table MergeContextTest$Simple (value integer not null, primary key (value))", true},
   615  		// For as
   616  		{"select 1 as a, 1 as `a`, 1 as \"a\", 1 as 'a'", true},
   617  		{`select 1 as a, 1 as "a", 1 as 'a'`, true},
   618  		{`select 1 a, 1 "a", 1 'a'`, true},
   619  		{`select * from t as "a"`, false},
   620  		{`select * from t a`, true},
   621  		{`select * from t as a`, true},
   622  		{"select 1 full, 1 row, 1 abs", true},
   623  		{"select * from t full, t1 row, t2 abs", true},
   624  	}
   625  	s.RunTest(c, table)
   626  }
   627  
   628  func (s *testParserSuite) TestDDL(c *C) {
   629  	defer testleak.AfterTest(c)()
   630  	table := []testCase{
   631  		{"CREATE", false},
   632  		{"CREATE TABLE", false},
   633  		{"CREATE TABLE foo (", false},
   634  		{"CREATE TABLE foo ()", false},
   635  		{"CREATE TABLE foo ();", false},
   636  		{"CREATE TABLE foo (a TINYINT UNSIGNED);", true},
   637  		{"CREATE TABLE foo (a SMALLINT UNSIGNED, b INT UNSIGNED)", true},
   638  		{"CREATE TABLE foo (a bigint unsigned, b bool);", true},
   639  		{"CREATE TABLE foo (a TINYINT, b SMALLINT) CREATE TABLE bar (x INT, y int64)", false},
   640  		{"CREATE TABLE foo (a int, b float); CREATE TABLE bar (x double, y float)", true},
   641  		{"CREATE TABLE foo (a bytes)", false},
   642  		{"CREATE TABLE foo (a SMALLINT UNSIGNED, b INT UNSIGNED)", true},
   643  		{"CREATE TABLE foo (a SMALLINT UNSIGNED, b INT UNSIGNED) -- foo", true},
   644  		{"CREATE TABLE foo (a SMALLINT UNSIGNED, b INT UNSIGNED) // foo", true},
   645  		{"CREATE TABLE foo (a SMALLINT UNSIGNED, b INT UNSIGNED) /* foo */", true},
   646  		{"CREATE TABLE foo /* foo */ (a SMALLINT UNSIGNED, b INT UNSIGNED) /* foo */", true},
   647  		{"CREATE TABLE foo (name CHAR(50) BINARY)", true},
   648  		{"CREATE TABLE foo (name CHAR(50) COLLATE utf8_bin)", true},
   649  		{"CREATE TABLE foo (name CHAR(50) CHARACTER SET utf8)", true},
   650  		{"CREATE TABLE foo (name CHAR(50) BINARY CHARACTER SET utf8 COLLATE utf8_bin)", true},
   651  
   652  		{"CREATE TABLE foo (a.b, b);", false},
   653  		{"CREATE TABLE foo (a, b.c);", false},
   654  		// For table option
   655  		{"create table t (c int) avg_row_length = 3", true},
   656  		{"create table t (c int) avg_row_length 3", true},
   657  		{"create table t (c int) checksum = 0", true},
   658  		{"create table t (c int) checksum 1", true},
   659  		{"create table t (c int) compression = none", true},
   660  		{"create table t (c int) compression lz4", true},
   661  		{"create table t (c int) connection = 'abc'", true},
   662  		{"create table t (c int) connection 'abc'", true},
   663  		{"create table t (c int) key_block_size = 1024", true},
   664  		{"create table t (c int) key_block_size 1024", true},
   665  		{"create table t (c int) max_rows = 1000", true},
   666  		{"create table t (c int) max_rows 1000", true},
   667  		{"create table t (c int) min_rows = 1000", true},
   668  		{"create table t (c int) min_rows 1000", true},
   669  		{"create table t (c int) password = 'abc'", true},
   670  		{"create table t (c int) password 'abc'", true},
   671  		{"create table t (c int) DELAY_KEY_WRITE=1", true},
   672  		{"create table t (c int) DELAY_KEY_WRITE 1", true},
   673  		{"create table t (c int) ROW_FORMAT = default", true},
   674  		{"create table t (c int) ROW_FORMAT default", true},
   675  		{"create table t (c int) ROW_FORMAT = fixed", true},
   676  		{"create table t (c int) ROW_FORMAT = compressed", true},
   677  		{"create table t (c int) ROW_FORMAT = compact", true},
   678  		{"create table t (c int) ROW_FORMAT = redundant", true},
   679  		{"create table t (c int) ROW_FORMAT = dynamic", true},
   680  		// For check clause
   681  		{"create table t (c1 bool, c2 bool, check (c1 in (0, 1)), check (c2 in (0, 1)))", true},
   682  		{"CREATE TABLE Customer (SD integer CHECK (SD > 0), First_Name varchar(30));", true},
   683  
   684  		{"create database xxx", true},
   685  		{"create database if exists xxx", false},
   686  		{"create database if not exists xxx", true},
   687  		{"create schema xxx", true},
   688  		{"create schema if exists xxx", false},
   689  		{"create schema if not exists xxx", true},
   690  		// For drop datbase/schema/table
   691  		{"drop database xxx", true},
   692  		{"drop database if exists xxx", true},
   693  		{"drop database if not exists xxx", false},
   694  		{"drop schema xxx", true},
   695  		{"drop schema if exists xxx", true},
   696  		{"drop schema if not exists xxx", false},
   697  		{"drop table xxx", true},
   698  		{"drop table xxx, yyy", true},
   699  		{"drop tables xxx", true},
   700  		{"drop tables xxx, yyy", true},
   701  		{"drop table if exists xxx", true},
   702  		{"drop table if not exists xxx", false},
   703  		// For issue 974
   704  		{`CREATE TABLE address (
   705  		id bigint(20) NOT NULL AUTO_INCREMENT,
   706  		create_at datetime NOT NULL,
   707  		deleted tinyint(1) NOT NULL,
   708  		update_at datetime NOT NULL,
   709  		version bigint(20) DEFAULT NULL,
   710  		address varchar(128) NOT NULL,
   711  		address_detail varchar(128) NOT NULL,
   712  		cellphone varchar(16) NOT NULL,
   713  		latitude double NOT NULL,
   714  		longitude double NOT NULL,
   715  		name varchar(16) NOT NULL,
   716  		sex tinyint(1) NOT NULL,
   717  		user_id bigint(20) NOT NULL,
   718  		PRIMARY KEY (id),
   719  		CONSTRAINT FK_7rod8a71yep5vxasb0ms3osbg FOREIGN KEY (user_id) REFERENCES waimaiqa.user (id),
   720  		INDEX FK_7rod8a71yep5vxasb0ms3osbg (user_id) comment ''
   721  		) ENGINE=InnoDB AUTO_INCREMENT=30 DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ROW_FORMAT=COMPACT COMMENT='' CHECKSUM=0 DELAY_KEY_WRITE=0;`, true},
   722  		// For issue 975
   723  		{`CREATE TABLE test_data (
   724  		id bigint(20) NOT NULL AUTO_INCREMENT,
   725  		create_at datetime NOT NULL,
   726  		deleted tinyint(1) NOT NULL,
   727  		update_at datetime NOT NULL,
   728  		version bigint(20) DEFAULT NULL,
   729  		address varchar(255) NOT NULL,
   730  		amount decimal(19,2) DEFAULT NULL,
   731  		charge_id varchar(32) DEFAULT NULL,
   732  		paid_amount decimal(19,2) DEFAULT NULL,
   733  		transaction_no varchar(64) DEFAULT NULL,
   734  		wx_mp_app_id varchar(32) DEFAULT NULL,
   735  		contacts varchar(50) DEFAULT NULL,
   736  		deliver_fee decimal(19,2) DEFAULT NULL,
   737  		deliver_info varchar(255) DEFAULT NULL,
   738  		deliver_time varchar(255) DEFAULT NULL,
   739  		description varchar(255) DEFAULT NULL,
   740  		invoice varchar(255) DEFAULT NULL,
   741  		order_from int(11) DEFAULT NULL,
   742  		order_state int(11) NOT NULL,
   743  		packing_fee decimal(19,2) DEFAULT NULL,
   744  		payment_time datetime DEFAULT NULL,
   745  		payment_type int(11) DEFAULT NULL,
   746  		phone varchar(50) NOT NULL,
   747  		store_employee_id bigint(20) DEFAULT NULL,
   748  		store_id bigint(20) NOT NULL,
   749  		user_id bigint(20) NOT NULL,
   750  		payment_mode int(11) NOT NULL,
   751  		current_latitude double NOT NULL,
   752  		current_longitude double NOT NULL,
   753  		address_latitude double NOT NULL,
   754  		address_longitude double NOT NULL,
   755  		PRIMARY KEY (id),
   756  		CONSTRAINT food_order_ibfk_1 FOREIGN KEY (user_id) REFERENCES waimaiqa.user (id),
   757  		CONSTRAINT food_order_ibfk_2 FOREIGN KEY (store_id) REFERENCES waimaiqa.store (id),
   758  		CONSTRAINT food_order_ibfk_3 FOREIGN KEY (store_employee_id) REFERENCES waimaiqa.store_employee (id),
   759  		UNIQUE FK_UNIQUE_charge_id USING BTREE (charge_id) comment '',
   760  		INDEX FK_eqst2x1xisn3o0wbrlahnnqq8 USING BTREE (store_employee_id) comment '',
   761  		INDEX FK_8jcmec4kb03f4dod0uqwm54o9 USING BTREE (store_id) comment '',
   762  		INDEX FK_a3t0m9apja9jmrn60uab30pqd USING BTREE (user_id) comment ''
   763  		) ENGINE=InnoDB AUTO_INCREMENT=95 DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ROW_FORMAT=COMPACT COMMENT='' CHECKSUM=0 DELAY_KEY_WRITE=0;`, true},
   764  		{`create table t (c int KEY);`, true},
   765  		{`CREATE TABLE address (
   766  		id bigint(20) NOT NULL AUTO_INCREMENT,
   767  		create_at datetime NOT NULL,
   768  		deleted tinyint(1) NOT NULL,
   769  		update_at datetime NOT NULL,
   770  		version bigint(20) DEFAULT NULL,
   771  		address varchar(128) NOT NULL,
   772  		address_detail varchar(128) NOT NULL,
   773  		cellphone varchar(16) NOT NULL,
   774  		latitude double NOT NULL,
   775  		longitude double NOT NULL,
   776  		name varchar(16) NOT NULL,
   777  		sex tinyint(1) NOT NULL,
   778  		user_id bigint(20) NOT NULL,
   779  		PRIMARY KEY (id),
   780  		CONSTRAINT FK_7rod8a71yep5vxasb0ms3osbg FOREIGN KEY (user_id) REFERENCES waimaiqa.user (id) ON DELETE CASCADE ON UPDATE NO ACTION,
   781  		INDEX FK_7rod8a71yep5vxasb0ms3osbg (user_id) comment ''
   782  		) ENGINE=InnoDB AUTO_INCREMENT=30 DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ROW_FORMAT=COMPACT COMMENT='' CHECKSUM=0 DELAY_KEY_WRITE=0;`, true},
   783  	}
   784  	s.RunTest(c, table)
   785  }
   786  
   787  func (s *testParserSuite) TestType(c *C) {
   788  	defer testleak.AfterTest(c)()
   789  	table := []testCase{
   790  		// For time fsp
   791  		{"CREATE TABLE t( c1 TIME(2), c2 DATETIME(2), c3 TIMESTAMP(2) );", true},
   792  
   793  		// For hexadecimal
   794  		{"SELECT x'0a', X'11', 0x11", true},
   795  		{"select x'0xaa'", false},
   796  		{"select 0X11", false},
   797  		{"select 0x4920616D2061206C6F6E672068657820737472696E67", true},
   798  
   799  		// For bit
   800  		{"select 0b01, 0b0, b'11', B'11'", true},
   801  		{"select 0B01", false},
   802  		{"select 0b21", false},
   803  
   804  		// For enum and set type
   805  		{"create table t (c1 enum('a', 'b'), c2 set('a', 'b'))", true},
   806  		{"create table t (c1 enum)", false},
   807  		{"create table t (c1 set)", false},
   808  
   809  		// For blob and text field length
   810  		{"create table t (c1 blob(1024), c2 text(1024))", true},
   811  
   812  		// For year
   813  		{"create table t (y year(4), y1 year)", true},
   814  
   815  		// For national
   816  		{"create table t (c1 national char(2), c2 national varchar(2))", true},
   817  
   818  		// For https://yougam/libraries/pingcap/tidb/issues/312
   819  		{`create table t (c float(53));`, true},
   820  		{`create table t (c float(54));`, false},
   821  	}
   822  	s.RunTest(c, table)
   823  }
   824  
   825  func (s *testParserSuite) TestPrivilege(c *C) {
   826  	defer testleak.AfterTest(c)()
   827  	table := []testCase{
   828  		// For create user
   829  		{`CREATE USER IF NOT EXISTS 'root'@'localhost' IDENTIFIED BY 'new-password'`, true},
   830  		{`CREATE USER 'root'@'localhost' IDENTIFIED BY 'new-password'`, true},
   831  		{`CREATE USER 'root'@'localhost' IDENTIFIED BY PASSWORD 'hashstring'`, true},
   832  		{`CREATE USER 'root'@'localhost' IDENTIFIED BY 'new-password', 'root'@'127.0.0.1' IDENTIFIED BY PASSWORD 'hashstring'`, true},
   833  
   834  		// For grant statement
   835  		{"GRANT ALL ON db1.* TO 'jeffrey'@'localhost';", true},
   836  		{"GRANT SELECT ON db2.invoice TO 'jeffrey'@'localhost';", true},
   837  		{"GRANT ALL ON *.* TO 'someuser'@'somehost';", true},
   838  		{"GRANT SELECT, INSERT ON *.* TO 'someuser'@'somehost';", true},
   839  		{"GRANT ALL ON mydb.* TO 'someuser'@'somehost';", true},
   840  		{"GRANT SELECT, INSERT ON mydb.* TO 'someuser'@'somehost';", true},
   841  		{"GRANT ALL ON mydb.mytbl TO 'someuser'@'somehost';", true},
   842  		{"GRANT SELECT, INSERT ON mydb.mytbl TO 'someuser'@'somehost';", true},
   843  		{"GRANT SELECT (col1), INSERT (col1,col2) ON mydb.mytbl TO 'someuser'@'somehost';", true},
   844  	}
   845  	s.RunTest(c, table)
   846  }
   847  
   848  func (s *testParserSuite) TestComment(c *C) {
   849  	defer testleak.AfterTest(c)()
   850  	table := []testCase{
   851  		{"create table t (c int comment 'comment')", true},
   852  		{"create table t (c int) comment = 'comment'", true},
   853  		{"create table t (c int) comment 'comment'", true},
   854  		{"create table t (c int) comment comment", false},
   855  		{"create table t (comment text)", true},
   856  		// For comment in query
   857  		{"/*comment*/ /*comment*/ select c /* this is a comment */ from t;", true},
   858  	}
   859  	s.RunTest(c, table)
   860  }
   861  func (s *testParserSuite) TestSubquery(c *C) {
   862  	defer testleak.AfterTest(c)()
   863  	table := []testCase{
   864  		// For compare subquery
   865  		{"SELECT 1 > (select 1)", true},
   866  		{"SELECT 1 > ANY (select 1)", true},
   867  		{"SELECT 1 > ALL (select 1)", true},
   868  		{"SELECT 1 > SOME (select 1)", true},
   869  
   870  		// For exists subquery
   871  		{"SELECT EXISTS select 1", false},
   872  		{"SELECT EXISTS (select 1)", true},
   873  		{"SELECT + EXISTS (select 1)", true},
   874  		{"SELECT - EXISTS (select 1)", true},
   875  		{"SELECT NOT EXISTS (select 1)", true},
   876  		{"SELECT + NOT EXISTS (select 1)", false},
   877  		{"SELECT - NOT EXISTS (select 1)", false},
   878  	}
   879  	s.RunTest(c, table)
   880  }
   881  func (s *testParserSuite) TestUnion(c *C) {
   882  	defer testleak.AfterTest(c)()
   883  	table := []testCase{
   884  		{"select c1 from t1 union select c2 from t2", true},
   885  		{"select c1 from t1 union (select c2 from t2)", true},
   886  		{"select c1 from t1 union (select c2 from t2) order by c1", true},
   887  		{"select c1 from t1 union select c2 from t2 order by c2", true},
   888  		{"select c1 from t1 union (select c2 from t2) limit 1", true},
   889  		{"select c1 from t1 union (select c2 from t2) limit 1, 1", true},
   890  		{"select c1 from t1 union (select c2 from t2) order by c1 limit 1", true},
   891  		{"(select c1 from t1) union distinct select c2 from t2", true},
   892  		{"(select c1 from t1) union all select c2 from t2", true},
   893  		{"(select c1 from t1) union (select c2 from t2) order by c1 union select c3 from t3", false},
   894  		{"(select c1 from t1) union (select c2 from t2) limit 1 union select c3 from t3", false},
   895  		{"(select c1 from t1) union select c2 from t2 union (select c3 from t3) order by c1 limit 1", true},
   896  		{"select (select 1 union select 1) as a", true},
   897  		{"select * from (select 1 union select 2) as a", true},
   898  		{"insert into t select c1 from t1 union select c2 from t2", true},
   899  		{"insert into t (c) select c1 from t1 union select c2 from t2", true},
   900  	}
   901  	s.RunTest(c, table)
   902  }
   903  
   904  func (s *testParserSuite) TestLikeEscape(c *C) {
   905  	defer testleak.AfterTest(c)()
   906  	table := []testCase{
   907  		// For like escape
   908  		{`select "abc_" like "abc\\_" escape ''`, true},
   909  		{`select "abc_" like "abc\\_" escape '\\'`, true},
   910  		{`select "abc_" like "abc\\_" escape '||'`, false},
   911  		{`select "abc" like "escape" escape '+'`, true},
   912  	}
   913  
   914  	s.RunTest(c, table)
   915  }
   916  
   917  func (s *testParserSuite) TestMysqlDump(c *C) {
   918  	defer testleak.AfterTest(c)()
   919  	// Statements used by mysqldump.
   920  	table := []testCase{
   921  		{`UNLOCK TABLES;`, true},
   922  		{`LOCK TABLES t1 READ;`, true},
   923  		{`show table status like 't'`, true},
   924  		{`LOCK TABLES t2 WRITE`, true},
   925  	}
   926  	s.RunTest(c, table)
   927  }
   928  
   929  func (s *testParserSuite) TestIndexHint(c *C) {
   930  	defer testleak.AfterTest(c)()
   931  	table := []testCase{
   932  		{`select * from t use index ();`, true},
   933  		{`select * from t use index (idx);`, true},
   934  		{`select * from t use index (idx1, idx2);`, true},
   935  		{`select * from t ignore key (idx1)`, true},
   936  		{`select * from t force index for join (idx1)`, true},
   937  		{`select * from t use index for order by (idx1)`, true},
   938  		{`select * from t force index for group by (idx1)`, true},
   939  		{`select * from t use index for group by (idx1) use index for order by (idx2), t2`, true},
   940  	}
   941  	s.RunTest(c, table)
   942  }