From 8b29d0f67507becc8e75c89a310d5b7b052e0822 Mon Sep 17 00:00:00 2001 From: AndrewDi Date: Sat, 5 Jan 2019 17:36:41 +0800 Subject: [PATCH 1/8] implement some restore func --- ast/dml.go | 143 ++++- ast/dml_test.go | 2 +- ast/expressions.go | 29 +- ast/functions.go | 46 +- ast/functions_test.go | 2 +- ast/misc.go | 15 +- ast/misc_test.go | 15 + ast/util_test.go | 4 + opcode/opcode.go | 6 +- parser_test.go | 1256 +++++++++++++++++++++-------------------- 10 files changed, 870 insertions(+), 648 deletions(-) diff --git a/ast/dml.go b/ast/dml.go index 9065c4f9d..c894545f9 100755 --- a/ast/dml.go +++ b/ast/dml.go @@ -756,7 +756,110 @@ type SelectStmt struct { // Restore implements Node interface. func (n *SelectStmt) Restore(ctx *RestoreCtx) error { - return errors.New("Not implemented") + ctx.WriteKeyWord("SELECT ") + + if n.SelectStmtOpts.Priority > 0 { + ctx.WriteKeyWord(mysql.Priority2Str[n.SelectStmtOpts.Priority]) + ctx.WritePlain(" ") + } + + if !n.SelectStmtOpts.SQLCache { + ctx.WriteKeyWord("SQL_NO_CACHE ") + } + + if n.TableHints != nil && len(n.TableHints) != 0 { + ctx.WritePlain("/*+ ") + for _, tableHint := range n.TableHints { + if err := tableHint.Restore(ctx); err != nil { + errors.Annotate(err, "An error occurred while restore SelectStmt.TableHints") + } + } + ctx.WritePlain("*/ ") + } + + if n.Distinct { + ctx.WriteKeyWord("DISTINCT ") + } + if n.SelectStmtOpts.StraightJoin { + ctx.WriteKeyWord("STRAIGHT_JOIN ") + } + if n.Fields != nil { + for i, field := range n.Fields.Fields { + if i != 0 { + ctx.WritePlain(",") + } + if err := field.Restore(ctx); err != nil { + errors.Annotate(err, "An error occurred while restore SelectStmt.Field") + } + } + } + + if n.From != nil { + ctx.WriteKeyWord(" FROM ") + if err := n.From.Restore(ctx); err != nil { + errors.Annotate(err, "An error occurred while restore SelectStmt.From") + } + } + + if n.From == nil && n.Where != nil { + ctx.WriteKeyWord(" FROM DUAL") + } + if n.Where != nil { + ctx.WriteKeyWord(" WHERE ") + if err := n.Where.Restore(ctx); err != nil { + errors.Annotate(err, "An error occurred while restore SelectStmt.Where") + } + } + + if n.GroupBy != nil { + ctx.WritePlain(" ") + if err := n.GroupBy.Restore(ctx); err != nil { + errors.Annotate(err, "An error occurred while restore SelectStmt.GroupBy") + } + } + + if n.Having != nil { + ctx.WritePlain(" ") + if err := n.Having.Restore(ctx); err != nil { + errors.Annotate(err, "An error occurred while restore SelectStmt.Having") + } + } + + if n.WindowSpecs != nil { + ctx.WriteKeyWord(" WINDOW ") + for i, windowsSpec := range n.WindowSpecs { + if i != 0 { + ctx.WritePlain(",") + } + if err := windowsSpec.Restore(ctx); err != nil { + errors.Annotate(err, "An error occurred while restore SelectStmt.WindowSpec") + } + } + } + + if n.OrderBy != nil { + ctx.WritePlain(" ") + if err := n.OrderBy.Restore(ctx); err != nil { + errors.Annotate(err, "An error occurred while restore SelectStmt.OrderBy") + } + } + + if n.Limit != nil { + ctx.WritePlain(" ") + if err := n.Limit.Restore(ctx); err != nil { + errors.Annotate(err, "An error occurred while restore SelectStmt.Limit") + } + } + + switch n.LockTp { + case SelectLockInShareMode: + ctx.WriteKeyWord(" LOCK ") + ctx.WriteKeyWord(n.LockTp.String()) + case SelectLockForUpdate: + ctx.WritePlain(" ") + ctx.WriteKeyWord(n.LockTp.String()) + } + return nil } // Accept implements Node Accept interface. @@ -855,7 +958,24 @@ type UnionSelectList struct { // Restore implements Node interface. func (n *UnionSelectList) Restore(ctx *RestoreCtx) error { - return errors.New("Not implemented") + for i, selectStmt := range n.Selects { + if i != 0 { + ctx.WriteKeyWord(" UNION ") + if !selectStmt.IsAfterUnionDistinct { + ctx.WriteKeyWord("ALL ") + } + } + if selectStmt.IsInBraces { + ctx.WritePlain("(") + } + if err := selectStmt.Restore(ctx); err != nil { + errors.Annotate(err, "An error occurred while restore UnionSelectList.SelectStmt") + } + if selectStmt.IsInBraces { + ctx.WritePlain(")") + } + } + return nil } // Accept implements Node Accept interface. @@ -888,7 +1008,24 @@ type UnionStmt struct { // Restore implements Node interface. func (n *UnionStmt) Restore(ctx *RestoreCtx) error { - return errors.New("Not implemented") + if err := n.SelectList.Restore(ctx); err != nil { + errors.Annotate(err, "An error occurred while restore UnionStmt.SelectList") + } + + if n.OrderBy != nil { + ctx.WritePlain(" ") + if err := n.OrderBy.Restore(ctx); err != nil { + errors.Annotate(err, "An error occurred while restore UnionStmt.OrderBy") + } + } + + if n.Limit != nil { + ctx.WritePlain(" ") + if err := n.Limit.Restore(ctx); err != nil { + errors.Annotate(err, "An error occurred while restore UnionStmt.Limit") + } + } + return nil } // Accept implements Node Accept interface. diff --git a/ast/dml_test.go b/ast/dml_test.go index 1bb286448..70b85b18a 100644 --- a/ast/dml_test.go +++ b/ast/dml_test.go @@ -196,7 +196,7 @@ func (tc *testDMLSuite) TestTableSourceRestore(c *C) { func (tc *testDMLSuite) TestOnConditionRestore(c *C) { testCases := []NodeRestoreTestCase{ {"on t1.a=t2.a", "ON `t1`.`a`=`t2`.`a`"}, - {"on t1.a=t2.a and t1.b=t2.b", "ON `t1`.`a`=`t2`.`a`&&`t1`.`b`=`t2`.`b`"}, + {"on t1.a=t2.a and t1.b=t2.b", "ON `t1`.`a`=`t2`.`a` AND `t1`.`b`=`t2`.`b`"}, } extractNodeFunc := func(node Node) Node { return node.(*SelectStmt).From.TableRefs.On diff --git a/ast/expressions.go b/ast/expressions.go index c98b12d44..cc78e69be 100755 --- a/ast/expressions.go +++ b/ast/expressions.go @@ -347,7 +347,12 @@ type SubqueryExpr struct { // Restore implements Node interface. func (n *SubqueryExpr) Restore(ctx *RestoreCtx) error { - return errors.New("Not implemented") + ctx.WritePlain("(") + if err := n.Query.Restore(ctx); err != nil { + return errors.Annotate(err, "An error occurred while restore SubqueryExpr.Query") + } + ctx.WritePlain(")") + return nil } // Format the ExprNode into a Writer. @@ -388,7 +393,21 @@ type CompareSubqueryExpr struct { // Restore implements Node interface. func (n *CompareSubqueryExpr) Restore(ctx *RestoreCtx) error { - return errors.New("Not implemented") + if err := n.L.Restore(ctx); err != nil { + return errors.Annotate(err, "An error occurred while restore CompareSubqueryExpr.L") + } + if err := n.Op.Restore(ctx.In); err != nil { + return errors.Annotate(err, "An error occurred while restore CompareSubqueryExpr.Op") + } + if n.All { + ctx.WriteKeyWord("ALL ") + } else { + ctx.WriteKeyWord("ANY ") + } + if err := n.R.Restore(ctx); err != nil { + return errors.Annotate(err, "An error occurred while restore CompareSubqueryExpr.R") + } + return nil } // Format the ExprNode into a Writer. @@ -817,6 +836,12 @@ func (n *PatternLikeExpr) Restore(ctx *RestoreCtx) error { return errors.Annotate(err, "An error occurred while restore PatternLikeExpr.Pattern") } + escape := string(n.Escape) + if escape != "\\" { + ctx.WriteKeyWord(" ESCAPE ") + ctx.WritePlainf("'%s'", escape) + + } return nil } diff --git a/ast/functions.go b/ast/functions.go index ab1bec9d6..3df6bb3fa 100755 --- a/ast/functions.go +++ b/ast/functions.go @@ -16,6 +16,7 @@ package ast import ( "fmt" "io" + "strings" "github.com/pingcap/errors" . "github.com/pingcap/parser/format" @@ -340,15 +341,7 @@ func (n *FuncCallExpr) Restore(ctx *RestoreCtx) error { } ctx.WriteKeyWord(" USING ") ctx.WriteKeyWord(n.Args[1].GetType().Charset) - case "adddate": - if err := n.Args[0].Restore(ctx); err != nil { - return errors.Annotatef(err, "An error occurred while restore FuncCallExpr") - } - ctx.WritePlain(", ") - if err := n.Args[1].Restore(ctx); err != nil { - return errors.Annotatef(err, "An error occurred while restore FuncCallExpr") - } - case "date_add": + case "adddate", "subdate", "date_add", "date_sub": if err := n.Args[0].Restore(ctx); err != nil { return errors.Annotatef(err, "An error occurred while restore FuncCallExpr") } @@ -413,6 +406,15 @@ func (n *FuncCallExpr) Restore(ctx *RestoreCtx) error { return errors.Annotatef(err, "An error occurred while restore FuncCallExpr") } } + case "timestampdiff", "timestampadd": + ctx.WriteKeyWord(n.Args[0].(ValueExpr).GetString()) + for i := 1; i < len(n.Args); { + ctx.WritePlain(", ") + if err := n.Args[i].Restore(ctx); err != nil { + return errors.Annotatef(err, "An error occurred while restore FuncCallExpr") + } + i++ + } default: for i, argv := range n.Args { if i != 0 { @@ -644,12 +646,28 @@ func (n *AggregateFuncExpr) Restore(ctx *RestoreCtx) error { if n.Distinct { ctx.WriteKeyWord("DISTINCT ") } - for i, argv := range n.Args { - if i != 0 { - ctx.WritePlain(", ") + switch strings.ToLower(n.F) { + case "group_concat": + for i := 0; i < len(n.Args)-1; i++ { + if i != 0 { + ctx.WritePlain(", ") + } + if err := n.Args[i].Restore(ctx); err != nil { + return errors.Annotatef(err, "An error occurred while restore AggregateFuncExpr.Args %d", i) + } + } + ctx.WriteKeyWord(" SEPARATOR ") + if err := n.Args[len(n.Args)-1].Restore(ctx); err != nil { + return errors.Annotatef(err, "An error occurred while restore AggregateFuncExpr.Args SEPARATOR") } - if err := argv.Restore(ctx); err != nil { - return errors.Annotatef(err, "An error occurred while restore AggregateFuncExpr.Args %d", i) + default: + for i, argv := range n.Args { + if i != 0 { + ctx.WritePlain(", ") + } + if err := argv.Restore(ctx); err != nil { + return errors.Annotatef(err, "An error occurred while restore AggregateFuncExpr.Args %d", i) + } } } ctx.WritePlain(")") diff --git a/ast/functions_test.go b/ast/functions_test.go index 15b5a8134..06acc0798 100644 --- a/ast/functions_test.go +++ b/ast/functions_test.go @@ -47,7 +47,7 @@ func (ts *testFunctionsSuite) TestFuncCallExprRestore(c *C) { {"CONV('a',16,2)", "CONV('a', 16, 2)"}, {"COS(PI())", "COS(PI())"}, {"RAND()", "RAND()"}, - {"ADDDATE('2000-01-01', 1)", "ADDDATE('2000-01-01', 1)"}, + {"ADDDATE('2000-01-01', 1)", "ADDDATE('2000-01-01', INTERVAL 1 DAY)"}, {"DATE_ADD('2000-01-01', INTERVAL 1 DAY)", "DATE_ADD('2000-01-01', INTERVAL 1 DAY)"}, {"DATE_ADD('2000-01-01', INTERVAL '1 1:12:23.100000' DAY_MICROSECOND)", "DATE_ADD('2000-01-01', INTERVAL '1 1:12:23.100000' DAY_MICROSECOND)"}, {"EXTRACT(DAY FROM '2000-01-01')", "EXTRACT(DAY FROM '2000-01-01')"}, diff --git a/ast/misc.go b/ast/misc.go index cc19e9a07..e42909f16 100755 --- a/ast/misc.go +++ b/ast/misc.go @@ -985,7 +985,20 @@ type TableOptimizerHint struct { // Restore implements Node interface. func (n *TableOptimizerHint) Restore(ctx *RestoreCtx) error { - return errors.New("Not implemented") + ctx.WriteKeyWord(n.HintName.String()) + ctx.WritePlain("(") + if n.HintName.O == "MAX_EXECUTION_TIME" { + ctx.WritePlainf("%d", n.MaxExecutionTime) + } else { + for i, table := range n.Tables { + if i != 0 { + ctx.WritePlain(", ") + } + ctx.WriteName(table.String()) + } + } + ctx.WritePlain(")") + return nil } // Accept implements Node Accept interface. diff --git a/ast/misc_test.go b/ast/misc_test.go index d86b189d4..543e379ad 100644 --- a/ast/misc_test.go +++ b/ast/misc_test.go @@ -188,3 +188,18 @@ func (ts *testMiscSuite) TestUserSpec(c *C) { c.Assert(ok, IsTrue) c.Assert(pwd, Equals, "") } + +func (ts *testMiscSuite) TestTableOptimizerHintRestore(c *C) { + testCases := []NodeRestoreTestCase{ + {"TIDB_SMJ(`t1`)", "TIDB_SMJ(`t1`)"}, + {"TIDB_SMJ(t1)", "TIDB_SMJ(`t1`)"}, + {"TIDB_SMJ(t1,t2)", "TIDB_SMJ(`t1`, `t2`)"}, + {"TIDB_INLJ(t1,t2)", "TIDB_INLJ(`t1`, `t2`)"}, + {"TIDB_HJ(t1,t2)", "TIDB_HJ(`t1`, `t2`)"}, + {"MAX_EXECUTION_TIME(3000)", "MAX_EXECUTION_TIME(3000)"}, + } + extractNodeFunc := func(node Node) Node { + return node.(*SelectStmt).TableHints[0] + } + RunNodeRestoreTest(c, testCases, "select /*+ %s */ * from t1 join t2", extractNodeFunc) +} diff --git a/ast/util_test.go b/ast/util_test.go index 4e34cba60..72059661d 100755 --- a/ast/util_test.go +++ b/ast/util_test.go @@ -74,6 +74,10 @@ func (checker *nodeTextCleaner) Enter(in Node) (out Node, skipChildren bool) { } case *AggregateFuncExpr: node.F = strings.ToLower(node.F) + case *FieldList: + for _, f := range node.Fields { + f.Offset = 0 + } } return in, false } diff --git a/opcode/opcode.go b/opcode/opcode.go index 7e2a0c687..4c17728ef 100644 --- a/opcode/opcode.go +++ b/opcode/opcode.go @@ -103,9 +103,9 @@ func (o Op) String() string { } var opsLiteral = map[Op]string{ - LogicAnd: "&&", - LogicOr: "||", - LogicXor: "^", + LogicAnd: " AND ", + LogicOr: " OR ", + LogicXor: " XOR ", LeftShift: "<<", RightShift: ">>", GE: ">=", diff --git a/parser_test.go b/parser_test.go index 19ef95080..063624294 100755 --- a/parser_test.go +++ b/parser_test.go @@ -23,7 +23,6 @@ import ( "github.com/pingcap/errors" "github.com/pingcap/parser/ast" "github.com/pingcap/parser/charset" - . "github.com/pingcap/parser/format" "github.com/pingcap/parser/model" "github.com/pingcap/parser/mysql" "github.com/pingcap/parser/terror" @@ -274,6 +273,7 @@ func (s *testParserSuite) RunTest(c *C, table []testCase) { func (s *testParserSuite) RunRestoreTest(c *C, sourceSQLs, expectSQLs string) { var sb strings.Builder parser := New() + parser.EnableWindowFunc(s.enableWindowFunc) comment := Commentf("source %v", sourceSQLs) stmts, _, err := parser.Parse(sourceSQLs, "", "") c.Assert(err, IsNil, comment) @@ -324,19 +324,19 @@ func (s *testParserSuite) TestDMLStmt(c *C) { {"INSERT INTO foo VALUES (bar(5678))", true, ""}, // 20 {"INSERT INTO foo VALUES ()", true, "INSERT INTO `foo` VALUES ()"}, - {"SELECT * FROM t", true, ""}, - {"SELECT * FROM t AS u", true, ""}, + {"SELECT * FROM t", true, "SELECT * FROM `t`"}, + {"SELECT * FROM t AS u", true, "SELECT * FROM `t` AS `u`"}, // 25 - {"SELECT * FROM t, v", true, ""}, - {"SELECT * FROM t AS u, v", true, ""}, - {"SELECT * FROM t, v AS w", true, ""}, - {"SELECT * FROM t AS u, v AS w", true, ""}, - {"SELECT * FROM foo, bar, foo", true, ""}, + {"SELECT * FROM t, v", true, "SELECT * FROM (`t`) JOIN `v`"}, + {"SELECT * FROM t AS u, v", true, "SELECT * FROM (`t` AS `u`) JOIN `v`"}, + {"SELECT * FROM t, v AS w", true, "SELECT * FROM (`t`) JOIN `v` AS `w`"}, + {"SELECT * FROM t AS u, v AS w", true, "SELECT * FROM (`t` AS `u`) JOIN `v` AS `w`"}, + {"SELECT * FROM foo, bar, foo", true, "SELECT * FROM ((`foo`) JOIN `bar`) JOIN `foo`"}, // 30 {"SELECT DISTINCTS * FROM t", false, ""}, - {"SELECT DISTINCT * FROM t", true, ""}, - {"SELECT DISTINCTROW * FROM t", true, ""}, - {"SELECT ALL * FROM t", true, ""}, + {"SELECT DISTINCT * FROM t", true, "SELECT DISTINCT * FROM `t`"}, + {"SELECT DISTINCTROW * FROM t", true, "SELECT DISTINCT * FROM `t`"}, + {"SELECT ALL * FROM t", true, "SELECT * FROM `t`"}, {"SELECT DISTINCT ALL * FROM t", false, ""}, {"SELECT DISTINCTROW ALL * FROM t", false, ""}, {"INSERT INTO foo (a) VALUES (42)", true, "INSERT INTO `foo` (`a`) VALUES (42)"}, @@ -382,10 +382,10 @@ func (s *testParserSuite) TestDMLStmt(c *C) { ROLLBACK;`, true, ""}, // qualified select - {"SELECT a.b.c FROM t", true, ""}, + {"SELECT a.b.c FROM t", true, "SELECT `a`.`b`.`c` FROM `t`"}, {"SELECT a.b.*.c FROM t", false, ""}, - {"SELECT a.b.* FROM t", true, ""}, - {"SELECT a FROM t", true, ""}, + {"SELECT a.b.* FROM t", true, "SELECT `a`.`b`.* FROM `t`"}, + {"SELECT a FROM t", true, "SELECT `a` FROM `t`"}, {"SELECT a.b.c.d FROM t", false, ""}, // do statement @@ -433,29 +433,29 @@ func (s *testParserSuite) TestDMLStmt(c *C) { {"load data local infile '/tmp/t.csv' into table t fields terminated by 'ab' enclosed by 'b' escaped by ''", true, ""}, // select for update - {"SELECT * from t for update", true, ""}, - {"SELECT * from t lock in share mode", true, ""}, + {"SELECT * from t for update", true, "SELECT * FROM `t` FOR UPDATE"}, + {"SELECT * from t lock in share mode", true, "SELECT * FROM `t` LOCK IN SHARE MODE"}, // from join - {"SELECT * from t1, t2, t3", true, ""}, - {"select * from t1 join t2 left join t3 on t2.id = t3.id", true, ""}, - {"select * from t1 right join t2 on t1.id = t2.id left join t3 on t3.id = t2.id", true, ""}, + {"SELECT * from t1, t2, t3", true, "SELECT * FROM ((`t1`) JOIN `t2`) JOIN `t3`"}, + {"select * from t1 join t2 left join t3 on t2.id = t3.id", true, "SELECT * FROM (`t1` JOIN `t2`) LEFT JOIN `t3` ON `t2`.`id`=`t3`.`id`"}, + {"select * from t1 right join t2 on t1.id = t2.id left join t3 on t3.id = t2.id", true, "SELECT * FROM (`t1` RIGHT JOIN `t2` ON `t1`.`id`=`t2`.`id`) LEFT JOIN `t3` ON `t3`.`id`=`t2`.`id`"}, {"select * from t1 right join t2 on t1.id = t2.id left join t3", false, ""}, - {"select * from t1 join t2 left join t3 using (id)", true, ""}, - {"select * from t1 right join t2 using (id) left join t3 using (id)", true, ""}, + {"select * from t1 join t2 left join t3 using (id)", true, "SELECT * FROM (`t1` JOIN `t2`) LEFT JOIN `t3` USING (`id`)"}, + {"select * from t1 right join t2 using (id) left join t3 using (id)", true, "SELECT * FROM (`t1` RIGHT JOIN `t2` USING (`id`)) LEFT JOIN `t3` USING (`id`)"}, {"select * from t1 right join t2 using (id) left join t3", false, ""}, - {"select * from t1 natural join t2", true, ""}, - {"select * from t1 natural right join t2", true, ""}, - {"select * from t1 natural left outer join t2", true, ""}, + {"select * from t1 natural join t2", true, "SELECT * FROM `t1` NATURAL JOIN `t2`"}, + {"select * from t1 natural right join t2", true, "SELECT * FROM `t1` NATURAL RIGHT JOIN `t2`"}, + {"select * from t1 natural left outer join t2", true, "SELECT * FROM `t1` NATURAL LEFT JOIN `t2`"}, {"select * from t1 natural inner join t2", false, ""}, {"select * from t1 natural cross join t2", false, ""}, // for straight_join - {"select * from t1 straight_join t2 on t1.id = t2.id", true, ""}, - {"select straight_join * from t1 join t2 on t1.id = t2.id", true, ""}, - {"select straight_join * from t1 left join t2 on t1.id = t2.id", true, ""}, - {"select straight_join * from t1 right join t2 on t1.id = t2.id", true, ""}, - {"select straight_join * from t1 straight_join t2 on t1.id = t2.id", true, ""}, + {"select * from t1 straight_join t2 on t1.id = t2.id", true, "SELECT * FROM `t1` STRAIGHT_JOIN `t2` ON `t1`.`id`=`t2`.`id`"}, + {"select straight_join * from t1 join t2 on t1.id = t2.id", true, "SELECT STRAIGHT_JOIN * FROM `t1` JOIN `t2` ON `t1`.`id`=`t2`.`id`"}, + {"select straight_join * from t1 left join t2 on t1.id = t2.id", true, "SELECT STRAIGHT_JOIN * FROM `t1` LEFT JOIN `t2` ON `t1`.`id`=`t2`.`id`"}, + {"select straight_join * from t1 right join t2 on t1.id = t2.id", true, "SELECT STRAIGHT_JOIN * FROM `t1` RIGHT JOIN `t2` ON `t1`.`id`=`t2`.`id`"}, + {"select straight_join * from t1 straight_join t2 on t1.id = t2.id", true, "SELECT STRAIGHT_JOIN * FROM `t1` STRAIGHT_JOIN `t2` ON `t1`.`id`=`t2`.`id`"}, // for "USE INDEX" in delete statement {"DELETE FROM t1 USE INDEX(idx_a) WHERE t1.id=1;", true, ""}, @@ -510,22 +510,22 @@ func (s *testParserSuite) TestDMLStmt(c *C) { {"UPDATE /*+ TiDB_SMJ(t1, t2) */ t1, t2 set t1.profile_id = 1, t2.profile_id = 1 where ta.a=t.ba", true, ""}, // for select with where clause - {"SELECT * FROM t WHERE 1 = 1", true, ""}, + {"SELECT * FROM t WHERE 1 = 1", true, "SELECT * FROM `t` WHERE 1=1"}, // for dual - {"select 1 from dual", true, ""}, - {"select 1 from dual limit 1", true, ""}, + {"select 1 from dual", true, "SELECT 1"}, + {"select 1 from dual limit 1", true, "SELECT 1 LIMIT 1"}, {"select 1 where exists (select 2)", false, ""}, {"select 1 from dual where not exists (select 2)", true, ""}, - {"select 1 as a from dual order by a", true, ""}, - {"select 1 as a from dual where 1 < any (select 2) order by a", true, ""}, - {"select 1 order by 1", true, ""}, + {"select 1 as a from dual order by a", true, "SELECT 1 AS `a` ORDER BY `a`"}, + {"select 1 as a from dual where 1 < any (select 2) order by a", true, "SELECT 1 AS `a` FROM DUAL WHERE 1 0, 1 <=> null, 1 = null", true, ""}, + {"select 1 <=> 0, 1 <=> null, 1 = null", true, "SELECT 1<=>0,1<=>NULL,1=NULL"}, // for date literal - {"select date'1989-09-10'", true, ""}, + {"select date'1989-09-10'", true, "SELECT DATELITERAL('1989-09-10')"}, {"select date 19890910", false, ""}, // for time literal - {"select time '00:00:00.111'", true, ""}, + {"select time '00:00:00.111'", true, "SELECT TIMELITERAL('00:00:00.111')"}, {"select time 19890910", false, ""}, // for timestamp literal - {"select timestamp '1989-09-10 11:11:11'", true, ""}, + {"select timestamp '1989-09-10 11:11:11'", true, "SELECT TIMESTAMPLITERAL('1989-09-10 11:11:11')"}, {"select timestamp 19890910", false, ""}, // The ODBC syntax for time/date/timestamp literal. // See: https://dev.mysql.com/doc/refman/5.7/en/date-and-time-literals.html - {"select {ts '1989-09-10 11:11:11'}", true, ""}, - {"select {d '1989-09-10'}", true, ""}, - {"select {t '00:00:00.111'}", true, ""}, + {"select {ts '1989-09-10 11:11:11'}", true, "SELECT '1989-09-10 11:11:11'"}, + {"select {d '1989-09-10'}", true, "SELECT '1989-09-10'"}, + {"select {t '00:00:00.111'}", true, "SELECT '00:00:00.111'"}, // If the identifier is not in (t, d, ts), we just ignore it and consider the following expression as the value. // See: https://dev.mysql.com/doc/refman/5.7/en/expressions.html - {"select {ts123 '1989-09-10 11:11:11'}", true, ""}, - {"select {ts123 123}", true, ""}, - {"select {ts123 1 xor 1}", true, ""}, + {"select {ts123 '1989-09-10 11:11:11'}", true, "SELECT '1989-09-10 11:11:11'"}, + {"select {ts123 123}", true, "SELECT 123"}, + {"select {ts123 1 xor 1}", true, "SELECT 1 XOR 1"}, } s.RunTest(c, table) } @@ -759,120 +759,120 @@ func (s *testParserSuite) TestExpression(c *C) { func (s *testParserSuite) TestBuiltin(c *C) { table := []testCase{ // for builtin functions - {"SELECT POW(1, 2)", true, ""}, - {"SELECT POW(1, 2, 1)", true, ""}, // illegal number of arguments shall pass too - {"SELECT POW(1, 0.5)", true, ""}, - {"SELECT POW(1, -1)", true, ""}, - {"SELECT POW(-1, 1)", true, ""}, - {"SELECT RAND();", true, ""}, - {"SELECT RAND(1);", true, ""}, - {"SELECT MOD(10, 2);", true, ""}, - {"SELECT ROUND(-1.23);", true, ""}, - {"SELECT ROUND(1.23, 1);", true, ""}, - {"SELECT ROUND(1.23, 1, 1);", true, ""}, - {"SELECT CEIL(-1.23);", true, ""}, - {"SELECT CEILING(1.23);", true, ""}, - {"SELECT FLOOR(-1.23);", true, ""}, - {"SELECT LN(1);", true, ""}, - {"SELECT LN(1, 2);", true, ""}, - {"SELECT LOG(-2);", true, ""}, - {"SELECT LOG(2, 65536);", true, ""}, - {"SELECT LOG(2, 65536, 1);", true, ""}, - {"SELECT LOG2(2);", true, ""}, - {"SELECT LOG2(2, 2);", true, ""}, - {"SELECT LOG10(10);", true, ""}, - {"SELECT LOG10(10, 1);", true, ""}, - {"SELECT ABS(10, 1);", true, ""}, - {"SELECT ABS(10);", true, ""}, - {"SELECT ABS();", true, ""}, - {"SELECT CONV(10+'10'+'10'+X'0a',10,10);", true, ""}, - {"SELECT CONV();", true, ""}, - {"SELECT CRC32('MySQL');", true, ""}, - {"SELECT CRC32();", true, ""}, - {"SELECT SIGN();", true, ""}, - {"SELECT SIGN(0);", true, ""}, - {"SELECT SQRT(0);", true, ""}, - {"SELECT SQRT();", true, ""}, - {"SELECT ACOS();", true, ""}, - {"SELECT ACOS(1);", true, ""}, - {"SELECT ACOS(1, 2);", true, ""}, - {"SELECT ASIN();", true, ""}, - {"SELECT ASIN(1);", true, ""}, - {"SELECT ASIN(1, 2);", true, ""}, - {"SELECT ATAN(0), ATAN(1), ATAN(1, 2);", true, ""}, - {"SELECT ATAN2(), ATAN2(1,2);", true, ""}, - {"SELECT COS(0);", true, ""}, - {"SELECT COS(1);", true, ""}, - {"SELECT COS(1, 2);", true, ""}, - {"SELECT COT();", true, ""}, - {"SELECT COT(1);", true, ""}, - {"SELECT COT(1, 2);", true, ""}, - {"SELECT DEGREES();", true, ""}, - {"SELECT DEGREES(0);", true, ""}, - {"SELECT EXP();", true, ""}, - {"SELECT EXP(1);", true, ""}, - {"SELECT PI();", true, ""}, - {"SELECT PI(1);", true, ""}, - {"SELECT RADIANS();", true, ""}, - {"SELECT RADIANS(1);", true, ""}, - {"SELECT SIN();", true, ""}, - {"SELECT SIN(1);", true, ""}, - {"SELECT TAN(1);", true, ""}, - {"SELECT TAN();", true, ""}, - {"SELECT TRUNCATE(1.223,1);", true, ""}, - {"SELECT TRUNCATE();", true, ""}, - - {"SELECT SUBSTR('Quadratically',5);", true, ""}, - {"SELECT SUBSTR('Quadratically',5, 3);", true, ""}, - {"SELECT SUBSTR('Quadratically' FROM 5);", true, ""}, - {"SELECT SUBSTR('Quadratically' FROM 5 FOR 3);", true, ""}, - - {"SELECT SUBSTRING('Quadratically',5);", true, ""}, - {"SELECT SUBSTRING('Quadratically',5, 3);", true, ""}, - {"SELECT SUBSTRING('Quadratically' FROM 5);", true, ""}, - {"SELECT SUBSTRING('Quadratically' FROM 5 FOR 3);", true, ""}, - - {"SELECT CONVERT('111', SIGNED);", true, ""}, - - {"SELECT LEAST(), LEAST(1, 2, 3);", true, ""}, - - {"SELECT INTERVAL(1, 0, 1, 2)", true, ""}, - {"SELECT DATE_ADD('2008-01-02', INTERVAL INTERVAL(1, 0, 1) DAY);", true, ""}, + {"SELECT POW(1, 2)", true, "SELECT POW(1, 2)"}, + {"SELECT POW(1, 2, 1)", true, "SELECT POW(1, 2, 1)"}, // illegal number of arguments shall pass too + {"SELECT POW(1, 0.5)", true, "SELECT POW(1, 0.5)"}, + {"SELECT POW(1, -1)", true, "SELECT POW(1, -1)"}, + {"SELECT POW(-1, 1)", true, "SELECT POW(-1, 1)"}, + {"SELECT RAND();", true, "SELECT RAND()"}, + {"SELECT RAND(1);", true, "SELECT RAND(1)"}, + {"SELECT MOD(10, 2);", true, "SELECT 10%2"}, + {"SELECT ROUND(-1.23);", true, "SELECT ROUND(-1.23)"}, + {"SELECT ROUND(1.23, 1);", true, "SELECT ROUND(1.23, 1)"}, + {"SELECT ROUND(1.23, 1, 1);", true, "SELECT ROUND(1.23, 1, 1)"}, + {"SELECT CEIL(-1.23);", true, "SELECT CEIL(-1.23)"}, + {"SELECT CEILING(1.23);", true, "SELECT CEILING(1.23)"}, + {"SELECT FLOOR(-1.23);", true, "SELECT FLOOR(-1.23)"}, + {"SELECT LN(1);", true, "SELECT LN(1)"}, + {"SELECT LN(1, 2);", true, "SELECT LN(1, 2)"}, + {"SELECT LOG(-2);", true, "SELECT LOG(-2)"}, + {"SELECT LOG(2, 65536);", true, "SELECT LOG(2, 65536)"}, + {"SELECT LOG(2, 65536, 1);", true, "SELECT LOG(2, 65536, 1)"}, + {"SELECT LOG2(2);", true, "SELECT LOG2(2)"}, + {"SELECT LOG2(2, 2);", true, "SELECT LOG2(2, 2)"}, + {"SELECT LOG10(10);", true, "SELECT LOG10(10)"}, + {"SELECT LOG10(10, 1);", true, "SELECT LOG10(10, 1)"}, + {"SELECT ABS(10, 1);", true, "SELECT ABS(10, 1)"}, + {"SELECT ABS(10);", true, "SELECT ABS(10)"}, + {"SELECT ABS();", true, "SELECT ABS()"}, + {"SELECT CONV(10+'10'+'10'+X'0a',10,10);", true, "SELECT CONV(10+'10'+'10'+x'0a', 10, 10)"}, + {"SELECT CONV();", true, "SELECT CONV()"}, + {"SELECT CRC32('MySQL');", true, "SELECT CRC32('MySQL')"}, + {"SELECT CRC32();", true, "SELECT CRC32()"}, + {"SELECT SIGN();", true, "SELECT SIGN()"}, + {"SELECT SIGN(0);", true, "SELECT SIGN(0)"}, + {"SELECT SQRT(0);", true, "SELECT SQRT(0)"}, + {"SELECT SQRT();", true, "SELECT SQRT()"}, + {"SELECT ACOS();", true, "SELECT ACOS()"}, + {"SELECT ACOS(1);", true, "SELECT ACOS(1)"}, + {"SELECT ACOS(1, 2);", true, "SELECT ACOS(1, 2)"}, + {"SELECT ASIN();", true, "SELECT ASIN()"}, + {"SELECT ASIN(1);", true, "SELECT ASIN(1)"}, + {"SELECT ASIN(1, 2);", true, "SELECT ASIN(1, 2)"}, + {"SELECT ATAN(0), ATAN(1), ATAN(1, 2);", true, "SELECT ATAN(0),ATAN(1),ATAN(1, 2)"}, + {"SELECT ATAN2(), ATAN2(1,2);", true, "SELECT ATAN2(),ATAN2(1, 2)"}, + {"SELECT COS(0);", true, "SELECT COS(0)"}, + {"SELECT COS(1);", true, "SELECT COS(1)"}, + {"SELECT COS(1, 2);", true, "SELECT COS(1, 2)"}, + {"SELECT COT();", true, "SELECT COT()"}, + {"SELECT COT(1);", true, "SELECT COT(1)"}, + {"SELECT COT(1, 2);", true, "SELECT COT(1, 2)"}, + {"SELECT DEGREES();", true, "SELECT DEGREES()"}, + {"SELECT DEGREES(0);", true, "SELECT DEGREES(0)"}, + {"SELECT EXP();", true, "SELECT EXP()"}, + {"SELECT EXP(1);", true, "SELECT EXP(1)"}, + {"SELECT PI();", true, "SELECT PI()"}, + {"SELECT PI(1);", true, "SELECT PI(1)"}, + {"SELECT RADIANS();", true, "SELECT RADIANS()"}, + {"SELECT RADIANS(1);", true, "SELECT RADIANS(1)"}, + {"SELECT SIN();", true, "SELECT SIN()"}, + {"SELECT SIN(1);", true, "SELECT SIN(1)"}, + {"SELECT TAN(1);", true, "SELECT TAN(1)"}, + {"SELECT TAN();", true, "SELECT TAN()"}, + {"SELECT TRUNCATE(1.223,1);", true, "SELECT TRUNCATE(1.223, 1)"}, + {"SELECT TRUNCATE();", true, "SELECT TRUNCATE()"}, + + {"SELECT SUBSTR('Quadratically',5);", true, "SELECT SUBSTR('Quadratically', 5)"}, + {"SELECT SUBSTR('Quadratically',5, 3);", true, "SELECT SUBSTR('Quadratically', 5, 3)"}, + {"SELECT SUBSTR('Quadratically' FROM 5);", true, "SELECT SUBSTR('Quadratically', 5)"}, + {"SELECT SUBSTR('Quadratically' FROM 5 FOR 3);", true, "SELECT SUBSTR('Quadratically', 5, 3)"}, + + {"SELECT SUBSTRING('Quadratically',5);", true, "SELECT SUBSTRING('Quadratically', 5)"}, + {"SELECT SUBSTRING('Quadratically',5, 3);", true, "SELECT SUBSTRING('Quadratically', 5, 3)"}, + {"SELECT SUBSTRING('Quadratically' FROM 5);", true, "SELECT SUBSTRING('Quadratically', 5)"}, + {"SELECT SUBSTRING('Quadratically' FROM 5 FOR 3);", true, "SELECT SUBSTRING('Quadratically', 5, 3)"}, + + {"SELECT CONVERT('111', SIGNED);", true, "SELECT CONVERT('111', SIGNED)"}, + + {"SELECT LEAST(), LEAST(1, 2, 3);", true, "SELECT LEAST(),LEAST(1, 2, 3)"}, + + {"SELECT INTERVAL(1, 0, 1, 2)", true, "SELECT INTERVAL(1, 0, 1, 2)"}, + {"SELECT DATE_ADD('2008-01-02', INTERVAL INTERVAL(1, 0, 1) DAY);", true, "SELECT DATE_ADD('2008-01-02', INTERVAL INTERVAL(1, 0, 1) DAY)"}, // information functions - {"SELECT DATABASE();", true, ""}, - {"SELECT SCHEMA();", true, ""}, - {"SELECT USER();", true, ""}, - {"SELECT USER(1);", true, ""}, - {"SELECT CURRENT_USER();", true, ""}, - {"SELECT CURRENT_USER;", true, ""}, - {"SELECT CONNECTION_ID();", true, ""}, - {"SELECT VERSION();", true, ""}, - {"SELECT BENCHMARK(1000000, AES_ENCRYPT('text',UNHEX('F3229A0B371ED2D9441B830D21A390C3')));", true, ""}, - {"SELECT BENCHMARK(AES_ENCRYPT('text',UNHEX('F3229A0B371ED2D9441B830D21A390C3')));", true, ""}, - {"SELECT CHARSET('abc');", true, ""}, - {"SELECT COERCIBILITY('abc');", true, ""}, - {"SELECT COERCIBILITY('abc', 'a');", true, ""}, - {"SELECT COLLATION('abc');", true, ""}, - {"SELECT ROW_COUNT();", true, ""}, - {"SELECT SESSION_USER();", true, ""}, - {"SELECT SYSTEM_USER();", true, ""}, - - {"SELECT SUBSTRING_INDEX('www.mysql.com', '.', 2);", true, ""}, - {"SELECT SUBSTRING_INDEX('www.mysql.com', '.', -2);", true, ""}, - - {`SELECT ASCII(), ASCII(""), ASCII("A"), ASCII(1);`, true, ""}, - - {`SELECT LOWER("A"), UPPER("a")`, true, ""}, - {`SELECT LCASE("A"), UCASE("a")`, true, ""}, - - {`SELECT REPLACE('www.mysql.com', 'w', 'Ww')`, true, ""}, - - {`SELECT LOCATE('bar', 'foobarbar');`, true, ""}, - {`SELECT LOCATE('bar', 'foobarbar', 5);`, true, ""}, - - {`SELECT tidb_version();`, true, ""}, - {`SELECT tidb_is_ddl_owner();`, true, ""}, + {"SELECT DATABASE();", true, "SELECT DATABASE()"}, + {"SELECT SCHEMA();", true, "SELECT SCHEMA()"}, + {"SELECT USER();", true, "SELECT USER()"}, + {"SELECT USER(1);", true, "SELECT USER(1)"}, + {"SELECT CURRENT_USER();", true, "SELECT CURRENT_USER()"}, + {"SELECT CURRENT_USER;", true, "SELECT CURRENT_USER()"}, + {"SELECT CONNECTION_ID();", true, "SELECT CONNECTION_ID()"}, + {"SELECT VERSION();", true, "SELECT VERSION()"}, + {"SELECT BENCHMARK(1000000, AES_ENCRYPT('text',UNHEX('F3229A0B371ED2D9441B830D21A390C3')));", true, "SELECT BENCHMARK(1000000, AES_ENCRYPT('text', UNHEX('F3229A0B371ED2D9441B830D21A390C3')))"}, + {"SELECT BENCHMARK(AES_ENCRYPT('text',UNHEX('F3229A0B371ED2D9441B830D21A390C3')));", true, "SELECT BENCHMARK(AES_ENCRYPT('text', UNHEX('F3229A0B371ED2D9441B830D21A390C3')))"}, + {"SELECT CHARSET('abc');", true, "SELECT CHARSET('abc')"}, + {"SELECT COERCIBILITY('abc');", true, "SELECT COERCIBILITY('abc')"}, + {"SELECT COERCIBILITY('abc', 'a');", true, "SELECT COERCIBILITY('abc', 'a')"}, + {"SELECT COLLATION('abc');", true, "SELECT COLLATION('abc')"}, + {"SELECT ROW_COUNT();", true, "SELECT ROW_COUNT()"}, + {"SELECT SESSION_USER();", true, "SELECT SESSION_USER()"}, + {"SELECT SYSTEM_USER();", true, "SELECT SYSTEM_USER()"}, + + {"SELECT SUBSTRING_INDEX('www.mysql.com', '.', 2);", true, "SELECT SUBSTRING_INDEX('www.mysql.com', '.', 2)"}, + {"SELECT SUBSTRING_INDEX('www.mysql.com', '.', -2);", true, "SELECT SUBSTRING_INDEX('www.mysql.com', '.', -2)"}, + + {`SELECT ASCII(), ASCII(""), ASCII("A"), ASCII(1);`, true, "SELECT ASCII(),ASCII(''),ASCII('A'),ASCII(1)"}, + + {`SELECT LOWER("A"), UPPER("a")`, true, "SELECT LOWER('A'),UPPER('a')"}, + {`SELECT LCASE("A"), UCASE("a")`, true, "SELECT LCASE('A'),UCASE('a')"}, + + {`SELECT REPLACE('www.mysql.com', 'w', 'Ww')`, true, "SELECT REPLACE('www.mysql.com', 'w', 'Ww')"}, + + {`SELECT LOCATE('bar', 'foobarbar');`, true, "SELECT LOCATE('bar', 'foobarbar')"}, + {`SELECT LOCATE('bar', 'foobarbar', 5);`, true, "SELECT LOCATE('bar', 'foobarbar', 5)"}, + + {`SELECT tidb_version();`, true, "SELECT TIDB_VERSION()"}, + {`SELECT tidb_is_ddl_owner();`, true, "SELECT TIDB_IS_DDL_OWNER()"}, // for time fsp {"CREATE TABLE t( c1 TIME(2), c2 DATETIME(2), c3 TIMESTAMP(2) );", true, ""}, @@ -881,411 +881,411 @@ func (s *testParserSuite) TestBuiltin(c *C) { {"select row(1)", false, ""}, {"select row(1, 1,)", false, ""}, {"select (1, 1,)", false, ""}, - {"select row(1, 1) > row(1, 1), row(1, 1, 1) > row(1, 1, 1)", true, ""}, - {"Select (1, 1) > (1, 1)", true, ""}, + {"select row(1, 1) > row(1, 1), row(1, 1, 1) > row(1, 1, 1)", true, "SELECT ROW(1,1)>ROW(1,1),ROW(1,1,1)>ROW(1,1,1)"}, + {"Select (1, 1) > (1, 1)", true, "SELECT ROW(1,1)>ROW(1,1)"}, {"create table t (`row` int)", true, ""}, {"create table t (row int)", false, ""}, // for cast with charset - {"SELECT *, CAST(data AS CHAR CHARACTER SET utf8) FROM t;", true, ""}, + {"SELECT *, CAST(data AS CHAR CHARACTER SET utf8) FROM t;", true, "SELECT *,CAST(`data` AS CHAR CHARACTER SET utf8) FROM `t`"}, // for cast as JSON - {"SELECT *, CAST(data AS JSON) FROM t;", true, ""}, + {"SELECT *, CAST(data AS JSON) FROM t;", true, "SELECT *,CAST(`data` AS JSON) FROM `t`"}, // for cast as signed int, fix issue #3691. - {"select cast(1 as signed int);", true, ""}, + {"select cast(1 as signed int);", true, "SELECT CAST(1 AS SIGNED)"}, // for last_insert_id - {"SELECT last_insert_id();", true, ""}, - {"SELECT last_insert_id(1);", true, ""}, + {"SELECT last_insert_id();", true, "SELECT LAST_INSERT_ID()"}, + {"SELECT last_insert_id(1);", true, "SELECT LAST_INSERT_ID(1)"}, // for binary operator - {"SELECT binary 'a';", true, ""}, + {"SELECT binary 'a';", true, "SELECT BINARY 'a'"}, // for bit_count - {`SELECT BIT_COUNT(1);`, true, ""}, + {`SELECT BIT_COUNT(1);`, true, "SELECT BIT_COUNT(1)"}, // select time - {"select current_timestamp", true, ""}, - {"select current_timestamp()", true, ""}, - {"select current_timestamp(6)", true, ""}, + {"select current_timestamp", true, "SELECT CURRENT_TIMESTAMP()"}, + {"select current_timestamp()", true, "SELECT CURRENT_TIMESTAMP()"}, + {"select current_timestamp(6)", true, "SELECT CURRENT_TIMESTAMP(6)"}, {"select current_timestamp(null)", false, ""}, {"select current_timestamp(-1)", false, ""}, {"select current_timestamp(1.0)", false, ""}, {"select current_timestamp('2')", false, ""}, - {"select now()", true, ""}, - {"select now(6)", true, ""}, - {"select sysdate(), sysdate(6)", true, ""}, - {"SELECT time('01:02:03');", true, ""}, - {"SELECT time('01:02:03.1')", true, ""}, - {"SELECT time('20.1')", true, ""}, - {"SELECT TIMEDIFF('2000:01:01 00:00:00', '2000:01:01 00:00:00.000001');", true, ""}, - {"SELECT TIMESTAMPDIFF(MONTH,'2003-02-01','2003-05-01');", true, ""}, - {"SELECT TIMESTAMPDIFF(YEAR,'2002-05-01','2001-01-01');", true, ""}, - {"SELECT TIMESTAMPDIFF(MINUTE,'2003-02-01','2003-05-01 12:05:55');", true, ""}, + {"select now()", true, "SELECT NOW()"}, + {"select now(6)", true, "SELECT NOW(6)"}, + {"select sysdate(), sysdate(6)", true, "SELECT SYSDATE(),SYSDATE(6)"}, + {"SELECT time('01:02:03');", true, "SELECT TIME('01:02:03')"}, + {"SELECT time('01:02:03.1')", true, "SELECT TIME('01:02:03.1')"}, + {"SELECT time('20.1')", true, "SELECT TIME('20.1')"}, + {"SELECT TIMEDIFF('2000:01:01 00:00:00', '2000:01:01 00:00:00.000001');", true, "SELECT TIMEDIFF('2000:01:01 00:00:00', '2000:01:01 00:00:00.000001')"}, + {"SELECT TIMESTAMPDIFF(MONTH,'2003-02-01','2003-05-01');", true, "SELECT TIMESTAMPDIFF(MONTH, '2003-02-01', '2003-05-01')"}, + {"SELECT TIMESTAMPDIFF(YEAR,'2002-05-01','2001-01-01');", true, "SELECT TIMESTAMPDIFF(YEAR, '2002-05-01', '2001-01-01')"}, + {"SELECT TIMESTAMPDIFF(MINUTE,'2003-02-01','2003-05-01 12:05:55');", true, "SELECT TIMESTAMPDIFF(MINUTE, '2003-02-01', '2003-05-01 12:05:55')"}, // select current_time - {"select current_time", true, ""}, - {"select current_time()", true, ""}, - {"select current_time(6)", true, ""}, + {"select current_time", true, "SELECT CURRENT_TIME()"}, + {"select current_time()", true, "SELECT CURRENT_TIME()"}, + {"select current_time(6)", true, "SELECT CURRENT_TIME(6)"}, {"select current_time(-1)", false, ""}, {"select current_time(1.0)", false, ""}, {"select current_time('1')", false, ""}, {"select current_time(null)", false, ""}, - {"select curtime()", true, ""}, - {"select curtime(6)", true, ""}, + {"select curtime()", true, "SELECT CURTIME()"}, + {"select curtime(6)", true, "SELECT CURTIME(6)"}, {"select curtime(-1)", false, ""}, {"select curtime(1.0)", false, ""}, {"select curtime('1')", false, ""}, {"select curtime(null)", false, ""}, // select utc_timestamp - {"select utc_timestamp", true, ""}, - {"select utc_timestamp()", true, ""}, - {"select utc_timestamp(6)", true, ""}, + {"select utc_timestamp", true, "SELECT UTC_TIMESTAMP()"}, + {"select utc_timestamp()", true, "SELECT UTC_TIMESTAMP()"}, + {"select utc_timestamp(6)", true, "SELECT UTC_TIMESTAMP(6)"}, {"select utc_timestamp(-1)", false, ""}, {"select utc_timestamp(1.0)", false, ""}, {"select utc_timestamp('1')", false, ""}, {"select utc_timestamp(null)", false, ""}, // select utc_time - {"select utc_time", true, ""}, - {"select utc_time()", true, ""}, - {"select utc_time(6)", true, ""}, + {"select utc_time", true, "SELECT UTC_TIME()"}, + {"select utc_time()", true, "SELECT UTC_TIME()"}, + {"select utc_time(6)", true, "SELECT UTC_TIME(6)"}, {"select utc_time(-1)", false, ""}, {"select utc_time(1.0)", false, ""}, {"select utc_time('1')", false, ""}, {"select utc_time(null)", false, ""}, // for microsecond, second, minute, hour - {"SELECT MICROSECOND('2009-12-31 23:59:59.000010');", true, ""}, - {"SELECT SECOND('10:05:03');", true, ""}, - {"SELECT MINUTE('2008-02-03 10:05:03');", true, ""}, - {"SELECT HOUR(), HOUR('10:05:03');", true, ""}, + {"SELECT MICROSECOND('2009-12-31 23:59:59.000010');", true, "SELECT MICROSECOND('2009-12-31 23:59:59.000010')"}, + {"SELECT SECOND('10:05:03');", true, "SELECT SECOND('10:05:03')"}, + {"SELECT MINUTE('2008-02-03 10:05:03');", true, "SELECT MINUTE('2008-02-03 10:05:03')"}, + {"SELECT HOUR(), HOUR('10:05:03');", true, "SELECT HOUR(),HOUR('10:05:03')"}, // for date, day, weekday - {"SELECT CURRENT_DATE, CURRENT_DATE(), CURDATE()", true, ""}, + {"SELECT CURRENT_DATE, CURRENT_DATE(), CURDATE()", true, "SELECT CURRENT_DATE(),CURRENT_DATE(),CURDATE()"}, {"SELECT CURRENT_DATE, CURRENT_DATE(), CURDATE(1)", false, ""}, - {"SELECT DATEDIFF('2003-12-31', '2003-12-30');", true, ""}, - {"SELECT DATE('2003-12-31 01:02:03');", true, ""}, - {"SELECT DATE();", true, ""}, - {"SELECT DATE('2003-12-31 01:02:03', '');", true, ""}, - {`SELECT DATE_FORMAT('2003-12-31 01:02:03', '%W %M %Y');`, true, ""}, - {"SELECT DAY('2007-02-03');", true, ""}, - {"SELECT DAYOFMONTH('2007-02-03');", true, ""}, - {"SELECT DAYOFWEEK('2007-02-03');", true, ""}, - {"SELECT DAYOFYEAR('2007-02-03');", true, ""}, - {"SELECT DAYNAME('2007-02-03');", true, ""}, - {"SELECT FROM_DAYS(1423);", true, ""}, - {"SELECT WEEKDAY('2007-02-03');", true, ""}, + {"SELECT DATEDIFF('2003-12-31', '2003-12-30');", true, "SELECT DATEDIFF('2003-12-31', '2003-12-30')"}, + {"SELECT DATE('2003-12-31 01:02:03');", true, "SELECT DATE('2003-12-31 01:02:03')"}, + {"SELECT DATE();", true, "SELECT DATE()"}, + {"SELECT DATE('2003-12-31 01:02:03', '');", true, "SELECT DATE('2003-12-31 01:02:03', '')"}, + {`SELECT DATE_FORMAT('2003-12-31 01:02:03', '%W %M %Y');`, true, "SELECT DATE_FORMAT('2003-12-31 01:02:03', '%W %M %Y')"}, + {"SELECT DAY('2007-02-03');", true, "SELECT DAY('2007-02-03')"}, + {"SELECT DAYOFMONTH('2007-02-03');", true, "SELECT DAYOFMONTH('2007-02-03')"}, + {"SELECT DAYOFWEEK('2007-02-03');", true, "SELECT DAYOFWEEK('2007-02-03')"}, + {"SELECT DAYOFYEAR('2007-02-03');", true, "SELECT DAYOFYEAR('2007-02-03')"}, + {"SELECT DAYNAME('2007-02-03');", true, "SELECT DAYNAME('2007-02-03')"}, + {"SELECT FROM_DAYS(1423);", true, "SELECT FROM_DAYS(1423)"}, + {"SELECT WEEKDAY('2007-02-03');", true, "SELECT WEEKDAY('2007-02-03')"}, // for utc_date - {"SELECT UTC_DATE, UTC_DATE();", true, ""}, - {"SELECT UTC_DATE(), UTC_DATE()+0", true, ""}, + {"SELECT UTC_DATE, UTC_DATE();", true, "SELECT UTC_DATE(),UTC_DATE()"}, + {"SELECT UTC_DATE(), UTC_DATE()+0", true, "SELECT UTC_DATE(),UTC_DATE()+0"}, // for week, month, year - {"SELECT WEEK();", true, ""}, - {"SELECT WEEK('2007-02-03');", true, ""}, - {"SELECT WEEK('2007-02-03', 0);", true, ""}, - {"SELECT WEEKOFYEAR('2007-02-03');", true, ""}, - {"SELECT MONTH('2007-02-03');", true, ""}, - {"SELECT MONTHNAME('2007-02-03');", true, ""}, - {"SELECT YEAR('2007-02-03');", true, ""}, - {"SELECT YEARWEEK('2007-02-03');", true, ""}, - {"SELECT YEARWEEK('2007-02-03', 0);", true, ""}, + {"SELECT WEEK();", true, "SELECT WEEK()"}, + {"SELECT WEEK('2007-02-03');", true, "SELECT WEEK('2007-02-03')"}, + {"SELECT WEEK('2007-02-03', 0);", true, "SELECT WEEK('2007-02-03', 0)"}, + {"SELECT WEEKOFYEAR('2007-02-03');", true, "SELECT WEEKOFYEAR('2007-02-03')"}, + {"SELECT MONTH('2007-02-03');", true, "SELECT MONTH('2007-02-03')"}, + {"SELECT MONTHNAME('2007-02-03');", true, "SELECT MONTHNAME('2007-02-03')"}, + {"SELECT YEAR('2007-02-03');", true, "SELECT YEAR('2007-02-03')"}, + {"SELECT YEARWEEK('2007-02-03');", true, "SELECT YEARWEEK('2007-02-03')"}, + {"SELECT YEARWEEK('2007-02-03', 0);", true, "SELECT YEARWEEK('2007-02-03', 0)"}, // for ADDTIME, SUBTIME - {"SELECT ADDTIME('01:00:00.999999', '02:00:00.999998');", true, ""}, - {"SELECT ADDTIME('02:00:00.999998');", true, ""}, - {"SELECT ADDTIME();", true, ""}, - {"SELECT SUBTIME('01:00:00.999999', '02:00:00.999998');", true, ""}, + {"SELECT ADDTIME('01:00:00.999999', '02:00:00.999998');", true, "SELECT ADDTIME('01:00:00.999999', '02:00:00.999998')"}, + {"SELECT ADDTIME('02:00:00.999998');", true, "SELECT ADDTIME('02:00:00.999998')"}, + {"SELECT ADDTIME();", true, "SELECT ADDTIME()"}, + {"SELECT SUBTIME('01:00:00.999999', '02:00:00.999998');", true, "SELECT SUBTIME('01:00:00.999999', '02:00:00.999998')"}, // for CONVERT_TZ - {"SELECT CONVERT_TZ();", true, ""}, - {"SELECT CONVERT_TZ('2004-01-01 12:00:00','+00:00','+10:00');", true, ""}, - {"SELECT CONVERT_TZ('2004-01-01 12:00:00','+00:00','+10:00', '+10:00');", true, ""}, + {"SELECT CONVERT_TZ();", true, "SELECT CONVERT_TZ()"}, + {"SELECT CONVERT_TZ('2004-01-01 12:00:00','+00:00','+10:00');", true, "SELECT CONVERT_TZ('2004-01-01 12:00:00', '+00:00', '+10:00')"}, + {"SELECT CONVERT_TZ('2004-01-01 12:00:00','+00:00','+10:00', '+10:00');", true, "SELECT CONVERT_TZ('2004-01-01 12:00:00', '+00:00', '+10:00', '+10:00')"}, // for GET_FORMAT - {"SELECT GET_FORMAT(DATE, 'USA');", true, ""}, - {"SELECT GET_FORMAT(DATETIME, 'USA');", true, ""}, - {"SELECT GET_FORMAT(TIME, 'USA');", true, ""}, - {"SELECT GET_FORMAT(TIMESTAMP, 'USA');", true, ""}, + {"SELECT GET_FORMAT(DATE, 'USA');", true, "SELECT GET_FORMAT(DATE, 'USA')"}, + {"SELECT GET_FORMAT(DATETIME, 'USA');", true, "SELECT GET_FORMAT(DATETIME, 'USA')"}, + {"SELECT GET_FORMAT(TIME, 'USA');", true, "SELECT GET_FORMAT(TIME, 'USA')"}, + {"SELECT GET_FORMAT(TIMESTAMP, 'USA');", true, "SELECT GET_FORMAT(TIMESTAMP, 'USA')"}, // for LOCALTIME, LOCALTIMESTAMP - {"SELECT LOCALTIME(), LOCALTIME(1)", true, ""}, - {"SELECT LOCALTIMESTAMP(), LOCALTIMESTAMP(2)", true, ""}, + {"SELECT LOCALTIME(), LOCALTIME(1)", true, "SELECT LOCALTIME(),LOCALTIME(1)"}, + {"SELECT LOCALTIMESTAMP(), LOCALTIMESTAMP(2)", true, "SELECT LOCALTIMESTAMP(),LOCALTIMESTAMP(2)"}, // for MAKEDATE, MAKETIME - {"SELECT MAKEDATE(2011,31);", true, ""}, - {"SELECT MAKETIME(12,15,30);", true, ""}, - {"SELECT MAKEDATE();", true, ""}, - {"SELECT MAKETIME();", true, ""}, + {"SELECT MAKEDATE(2011,31);", true, "SELECT MAKEDATE(2011, 31)"}, + {"SELECT MAKETIME(12,15,30);", true, "SELECT MAKETIME(12, 15, 30)"}, + {"SELECT MAKEDATE();", true, "SELECT MAKEDATE()"}, + {"SELECT MAKETIME();", true, "SELECT MAKETIME()"}, // for PERIOD_ADD, PERIOD_DIFF - {"SELECT PERIOD_ADD(200801,2)", true, ""}, - {"SELECT PERIOD_DIFF(200802,200703)", true, ""}, + {"SELECT PERIOD_ADD(200801,2)", true, "SELECT PERIOD_ADD(200801, 2)"}, + {"SELECT PERIOD_DIFF(200802,200703)", true, "SELECT PERIOD_DIFF(200802, 200703)"}, // for QUARTER - {"SELECT QUARTER('2008-04-01');", true, ""}, + {"SELECT QUARTER('2008-04-01');", true, "SELECT QUARTER('2008-04-01')"}, // for SEC_TO_TIME - {"SELECT SEC_TO_TIME(2378)", true, ""}, + {"SELECT SEC_TO_TIME(2378)", true, "SELECT SEC_TO_TIME(2378)"}, // for TIME_FORMAT - {`SELECT TIME_FORMAT('100:00:00', '%H %k %h %I %l')`, true, ""}, + {`SELECT TIME_FORMAT('100:00:00', '%H %k %h %I %l')`, true, "SELECT TIME_FORMAT('100:00:00', '%H %k %h %I %l')"}, // for TIME_TO_SEC - {"SELECT TIME_TO_SEC('22:23:00')", true, ""}, + {"SELECT TIME_TO_SEC('22:23:00')", true, "SELECT TIME_TO_SEC('22:23:00')"}, // for TIMESTAMPADD - {"SELECT TIMESTAMPADD(WEEK,1,'2003-01-02');", true, ""}, + {"SELECT TIMESTAMPADD(WEEK,1,'2003-01-02');", true, "SELECT TIMESTAMPADD(WEEK, 1, '2003-01-02')"}, // for TO_DAYS, TO_SECONDS - {"SELECT TO_DAYS('2007-10-07')", true, ""}, - {"SELECT TO_SECONDS('2009-11-29')", true, ""}, + {"SELECT TO_DAYS('2007-10-07')", true, "SELECT TO_DAYS('2007-10-07')"}, + {"SELECT TO_SECONDS('2009-11-29')", true, "SELECT TO_SECONDS('2009-11-29')"}, // for LAST_DAY - {"SELECT LAST_DAY('2003-02-05');", true, ""}, + {"SELECT LAST_DAY('2003-02-05');", true, "SELECT LAST_DAY('2003-02-05')"}, // for UTC_TIME - {"SELECT UTC_TIME(), UTC_TIME(1)", true, ""}, + {"SELECT UTC_TIME(), UTC_TIME(1)", true, "SELECT UTC_TIME(),UTC_TIME(1)"}, // for time extract - {`select extract(microsecond from "2011-11-11 10:10:10.123456")`, true, ""}, - {`select extract(second from "2011-11-11 10:10:10.123456")`, true, ""}, - {`select extract(minute from "2011-11-11 10:10:10.123456")`, true, ""}, - {`select extract(hour from "2011-11-11 10:10:10.123456")`, true, ""}, - {`select extract(day from "2011-11-11 10:10:10.123456")`, true, ""}, - {`select extract(week from "2011-11-11 10:10:10.123456")`, true, ""}, - {`select extract(month from "2011-11-11 10:10:10.123456")`, true, ""}, - {`select extract(quarter from "2011-11-11 10:10:10.123456")`, true, ""}, - {`select extract(year from "2011-11-11 10:10:10.123456")`, true, ""}, - {`select extract(second_microsecond from "2011-11-11 10:10:10.123456")`, true, ""}, - {`select extract(minute_microsecond from "2011-11-11 10:10:10.123456")`, true, ""}, - {`select extract(minute_second from "2011-11-11 10:10:10.123456")`, true, ""}, - {`select extract(hour_microsecond from "2011-11-11 10:10:10.123456")`, true, ""}, - {`select extract(hour_second from "2011-11-11 10:10:10.123456")`, true, ""}, - {`select extract(hour_minute from "2011-11-11 10:10:10.123456")`, true, ""}, - {`select extract(day_microsecond from "2011-11-11 10:10:10.123456")`, true, ""}, - {`select extract(day_second from "2011-11-11 10:10:10.123456")`, true, ""}, - {`select extract(day_minute from "2011-11-11 10:10:10.123456")`, true, ""}, - {`select extract(day_hour from "2011-11-11 10:10:10.123456")`, true, ""}, - {`select extract(year_month from "2011-11-11 10:10:10.123456")`, true, ""}, + {`select extract(microsecond from "2011-11-11 10:10:10.123456")`, true, "SELECT EXTRACT(MICROSECOND FROM '2011-11-11 10:10:10.123456')"}, + {`select extract(second from "2011-11-11 10:10:10.123456")`, true, "SELECT EXTRACT(SECOND FROM '2011-11-11 10:10:10.123456')"}, + {`select extract(minute from "2011-11-11 10:10:10.123456")`, true, "SELECT EXTRACT(MINUTE FROM '2011-11-11 10:10:10.123456')"}, + {`select extract(hour from "2011-11-11 10:10:10.123456")`, true, "SELECT EXTRACT(HOUR FROM '2011-11-11 10:10:10.123456')"}, + {`select extract(day from "2011-11-11 10:10:10.123456")`, true, "SELECT EXTRACT(DAY FROM '2011-11-11 10:10:10.123456')"}, + {`select extract(week from "2011-11-11 10:10:10.123456")`, true, "SELECT EXTRACT(WEEK FROM '2011-11-11 10:10:10.123456')"}, + {`select extract(month from "2011-11-11 10:10:10.123456")`, true, "SELECT EXTRACT(MONTH FROM '2011-11-11 10:10:10.123456')"}, + {`select extract(quarter from "2011-11-11 10:10:10.123456")`, true, "SELECT EXTRACT(QUARTER FROM '2011-11-11 10:10:10.123456')"}, + {`select extract(year from "2011-11-11 10:10:10.123456")`, true, "SELECT EXTRACT(YEAR FROM '2011-11-11 10:10:10.123456')"}, + {`select extract(second_microsecond from "2011-11-11 10:10:10.123456")`, true, "SELECT EXTRACT(SECOND_MICROSECOND FROM '2011-11-11 10:10:10.123456')"}, + {`select extract(minute_microsecond from "2011-11-11 10:10:10.123456")`, true, "SELECT EXTRACT(MINUTE_MICROSECOND FROM '2011-11-11 10:10:10.123456')"}, + {`select extract(minute_second from "2011-11-11 10:10:10.123456")`, true, "SELECT EXTRACT(MINUTE_SECOND FROM '2011-11-11 10:10:10.123456')"}, + {`select extract(hour_microsecond from "2011-11-11 10:10:10.123456")`, true, "SELECT EXTRACT(HOUR_MICROSECOND FROM '2011-11-11 10:10:10.123456')"}, + {`select extract(hour_second from "2011-11-11 10:10:10.123456")`, true, "SELECT EXTRACT(HOUR_SECOND FROM '2011-11-11 10:10:10.123456')"}, + {`select extract(hour_minute from "2011-11-11 10:10:10.123456")`, true, "SELECT EXTRACT(HOUR_MINUTE FROM '2011-11-11 10:10:10.123456')"}, + {`select extract(day_microsecond from "2011-11-11 10:10:10.123456")`, true, "SELECT EXTRACT(DAY_MICROSECOND FROM '2011-11-11 10:10:10.123456')"}, + {`select extract(day_second from "2011-11-11 10:10:10.123456")`, true, "SELECT EXTRACT(DAY_SECOND FROM '2011-11-11 10:10:10.123456')"}, + {`select extract(day_minute from "2011-11-11 10:10:10.123456")`, true, "SELECT EXTRACT(DAY_MINUTE FROM '2011-11-11 10:10:10.123456')"}, + {`select extract(day_hour from "2011-11-11 10:10:10.123456")`, true, "SELECT EXTRACT(DAY_HOUR FROM '2011-11-11 10:10:10.123456')"}, + {`select extract(year_month from "2011-11-11 10:10:10.123456")`, true, "SELECT EXTRACT(YEAR_MONTH FROM '2011-11-11 10:10:10.123456')"}, // for from_unixtime - {`select from_unixtime(1447430881)`, true, ""}, - {`select from_unixtime(1447430881.123456)`, true, ""}, - {`select from_unixtime(1447430881.1234567)`, true, ""}, - {`select from_unixtime(1447430881.9999999)`, true, ""}, - {`select from_unixtime(1447430881, "%Y %D %M %h:%i:%s %x")`, true, ""}, - {`select from_unixtime(1447430881.123456, "%Y %D %M %h:%i:%s %x")`, true, ""}, - {`select from_unixtime(1447430881.1234567, "%Y %D %M %h:%i:%s %x")`, true, ""}, + {`select from_unixtime(1447430881)`, true, "SELECT FROM_UNIXTIME(1447430881)"}, + {`select from_unixtime(1447430881.123456)`, true, "SELECT FROM_UNIXTIME(1447430881.123456)"}, + {`select from_unixtime(1447430881.1234567)`, true, "SELECT FROM_UNIXTIME(1447430881.1234567)"}, + {`select from_unixtime(1447430881.9999999)`, true, "SELECT FROM_UNIXTIME(1447430881.9999999)"}, + {`select from_unixtime(1447430881, "%Y %D %M %h:%i:%s %x")`, true, "SELECT FROM_UNIXTIME(1447430881, '%Y %D %M %h:%i:%s %x')"}, + {`select from_unixtime(1447430881.123456, "%Y %D %M %h:%i:%s %x")`, true, "SELECT FROM_UNIXTIME(1447430881.123456, '%Y %D %M %h:%i:%s %x')"}, + {`select from_unixtime(1447430881.1234567, "%Y %D %M %h:%i:%s %x")`, true, "SELECT FROM_UNIXTIME(1447430881.1234567, '%Y %D %M %h:%i:%s %x')"}, // for issue 224 - {`SELECT CAST('test collated returns' AS CHAR CHARACTER SET utf8) COLLATE utf8_bin;`, true, ""}, + {`SELECT CAST('test collated returns' AS CHAR CHARACTER SET utf8) COLLATE utf8_bin;`, true, "SELECT CAST('test collated returns' AS CHAR CHARACTER SET utf8)"}, // for string functions // trim - {`SELECT TRIM(' bar ');`, true, ""}, - {`SELECT TRIM(LEADING 'x' FROM 'xxxbarxxx');`, true, ""}, - {`SELECT TRIM(BOTH 'x' FROM 'xxxbarxxx');`, true, ""}, - {`SELECT TRIM(TRAILING 'xyz' FROM 'barxxyz');`, true, ""}, - {`SELECT LTRIM(' foo ');`, true, ""}, - {`SELECT RTRIM(' bar ');`, true, ""}, - - {`SELECT RPAD('hi', 6, 'c');`, true, ""}, - {`SELECT BIT_LENGTH('hi');`, true, ""}, - {`SELECT CHAR(65);`, true, ""}, - {`SELECT CHAR_LENGTH('abc');`, true, ""}, - {`SELECT CHARACTER_LENGTH('abc');`, true, ""}, - {`SELECT FIELD('ej', 'Hej', 'ej', 'Heja', 'hej', 'foo');`, true, ""}, - {`SELECT FIND_IN_SET('foo', 'foo,bar')`, true, ""}, - {`SELECT FIND_IN_SET('foo')`, true, ""}, // illegal number of argument still pass - {`SELECT MAKE_SET(1,'a'), MAKE_SET(1,'a','b','c')`, true, ""}, - {`SELECT MID('Sakila', -5, 3)`, true, ""}, - {`SELECT OCT(12)`, true, ""}, - {`SELECT OCTET_LENGTH('text')`, true, ""}, - {`SELECT ORD('2')`, true, ""}, - {`SELECT POSITION('bar' IN 'foobarbar')`, true, ""}, - {`SELECT QUOTE('Don\'t!')`, true, ""}, - {`SELECT BIN(12)`, true, ""}, - {`SELECT ELT(1, 'ej', 'Heja', 'hej', 'foo')`, true, ""}, - {`SELECT EXPORT_SET(5,'Y','N'), EXPORT_SET(5,'Y','N',','), EXPORT_SET(5,'Y','N',',',4)`, true, ""}, - {`SELECT FORMAT(), FORMAT(12332.2,2,'de_DE'), FORMAT(12332.123456, 4)`, true, ""}, - {`SELECT FROM_BASE64('abc')`, true, ""}, - {`SELECT TO_BASE64('abc')`, true, ""}, - {`SELECT INSERT(), INSERT('Quadratic', 3, 4, 'What'), INSTR('foobarbar', 'bar')`, true, ""}, - {`SELECT LOAD_FILE('/tmp/picture')`, true, ""}, - {`SELECT LPAD('hi',4,'??')`, true, ""}, - {`SELECT LEFT("foobar", 3)`, true, ""}, - {`SELECT RIGHT("foobar", 3)`, true, ""}, + {`SELECT TRIM(' bar ');`, true, "SELECT TRIM(' bar ')"}, + {`SELECT TRIM(LEADING 'x' FROM 'xxxbarxxx');`, true, "SELECT TRIM(LEADING 'x' FROM 'xxxbarxxx')"}, + {`SELECT TRIM(BOTH 'x' FROM 'xxxbarxxx');`, true, "SELECT TRIM(BOTH 'x' FROM 'xxxbarxxx')"}, + {`SELECT TRIM(TRAILING 'xyz' FROM 'barxxyz');`, true, "SELECT TRIM(TRAILING 'xyz' FROM 'barxxyz')"}, + {`SELECT LTRIM(' foo ');`, true, "SELECT LTRIM(' foo ')"}, + {`SELECT RTRIM(' bar ');`, true, "SELECT RTRIM(' bar ')"}, + + {`SELECT RPAD('hi', 6, 'c');`, true, "SELECT RPAD('hi', 6, 'c')"}, + {`SELECT BIT_LENGTH('hi');`, true, "SELECT BIT_LENGTH('hi')"}, + {`SELECT CHAR(65);`, true, "SELECT CHAR_FUNC(65, NULL)"}, + {`SELECT CHAR_LENGTH('abc');`, true, "SELECT CHAR_LENGTH('abc')"}, + {`SELECT CHARACTER_LENGTH('abc');`, true, "SELECT CHARACTER_LENGTH('abc')"}, + {`SELECT FIELD('ej', 'Hej', 'ej', 'Heja', 'hej', 'foo');`, true, "SELECT FIELD('ej', 'Hej', 'ej', 'Heja', 'hej', 'foo')"}, + {`SELECT FIND_IN_SET('foo', 'foo,bar')`, true, "SELECT FIND_IN_SET('foo', 'foo,bar')"}, + {`SELECT FIND_IN_SET('foo')`, true, "SELECT FIND_IN_SET('foo')"}, // illegal number of argument still pass + {`SELECT MAKE_SET(1,'a'), MAKE_SET(1,'a','b','c')`, true, "SELECT MAKE_SET(1, 'a'),MAKE_SET(1, 'a', 'b', 'c')"}, + {`SELECT MID('Sakila', -5, 3)`, true, "SELECT MID('Sakila', -5, 3)"}, + {`SELECT OCT(12)`, true, "SELECT OCT(12)"}, + {`SELECT OCTET_LENGTH('text')`, true, "SELECT OCTET_LENGTH('text')"}, + {`SELECT ORD('2')`, true, "SELECT ORD('2')"}, + {`SELECT POSITION('bar' IN 'foobarbar')`, true, "SELECT POSITION('bar' IN 'foobarbar')"}, + {`SELECT QUOTE('Don\'t!')`, true, "SELECT QUOTE('Don''t!')"}, + {`SELECT BIN(12)`, true, "SELECT BIN(12)"}, + {`SELECT ELT(1, 'ej', 'Heja', 'hej', 'foo')`, true, "SELECT ELT(1, 'ej', 'Heja', 'hej', 'foo')"}, + {`SELECT EXPORT_SET(5,'Y','N'), EXPORT_SET(5,'Y','N',','), EXPORT_SET(5,'Y','N',',',4)`, true, "SELECT EXPORT_SET(5, 'Y', 'N'),EXPORT_SET(5, 'Y', 'N', ','),EXPORT_SET(5, 'Y', 'N', ',', 4)"}, + {`SELECT FORMAT(), FORMAT(12332.2,2,'de_DE'), FORMAT(12332.123456, 4)`, true, "SELECT FORMAT(),FORMAT(12332.2, 2, 'de_DE'),FORMAT(12332.123456, 4)"}, + {`SELECT FROM_BASE64('abc')`, true, "SELECT FROM_BASE64('abc')"}, + {`SELECT TO_BASE64('abc')`, true, "SELECT TO_BASE64('abc')"}, + {`SELECT INSERT(), INSERT('Quadratic', 3, 4, 'What'), INSTR('foobarbar', 'bar')`, true, "SELECT INSERT_FUNC(),INSERT_FUNC('Quadratic', 3, 4, 'What'),INSTR('foobarbar', 'bar')"}, + {`SELECT LOAD_FILE('/tmp/picture')`, true, "SELECT LOAD_FILE('/tmp/picture')"}, + {`SELECT LPAD('hi',4,'??')`, true, "SELECT LPAD('hi', 4, '??')"}, + {`SELECT LEFT("foobar", 3)`, true, "SELECT LEFT('foobar', 3)"}, + {`SELECT RIGHT("foobar", 3)`, true, "SELECT RIGHT('foobar', 3)"}, // repeat - {`SELECT REPEAT("a", 10);`, true, ""}, + {`SELECT REPEAT("a", 10);`, true, "SELECT REPEAT('a', 10)"}, // for miscellaneous functions - {`SELECT SLEEP(10);`, true, ""}, - {`SELECT ANY_VALUE(@arg);`, true, ""}, - {`SELECT INET_ATON('10.0.5.9');`, true, ""}, - {`SELECT INET_NTOA(167773449);`, true, ""}, - {`SELECT INET6_ATON('fdfe::5a55:caff:fefa:9089');`, true, ""}, - {`SELECT INET6_NTOA(INET_NTOA(167773449));`, true, ""}, - {`SELECT IS_FREE_LOCK(@str);`, true, ""}, - {`SELECT IS_IPV4('10.0.5.9');`, true, ""}, - {`SELECT IS_IPV4_COMPAT(INET6_ATON('::10.0.5.9'));`, true, ""}, - {`SELECT IS_IPV4_MAPPED(INET6_ATON('::10.0.5.9'));`, true, ""}, - {`SELECT IS_IPV6('10.0.5.9');`, true, ""}, - {`SELECT IS_USED_LOCK(@str);`, true, ""}, - {`SELECT MASTER_POS_WAIT(@log_name, @log_pos), MASTER_POS_WAIT(@log_name, @log_pos, @timeout), MASTER_POS_WAIT(@log_name, @log_pos, @timeout, @channel_name);`, true, ""}, - {`SELECT NAME_CONST('myname', 14);`, true, ""}, - {`SELECT RELEASE_ALL_LOCKS();`, true, ""}, - {`SELECT UUID();`, true, ""}, - {`SELECT UUID_SHORT()`, true, ""}, + {`SELECT SLEEP(10);`, true, "SELECT SLEEP(10)"}, + {`SELECT ANY_VALUE(@arg);`, true, "SELECT ANY_VALUE(@`arg`)"}, + {`SELECT INET_ATON('10.0.5.9');`, true, "SELECT INET_ATON('10.0.5.9')"}, + {`SELECT INET_NTOA(167773449);`, true, "SELECT INET_NTOA(167773449)"}, + {`SELECT INET6_ATON('fdfe::5a55:caff:fefa:9089');`, true, "SELECT INET6_ATON('fdfe::5a55:caff:fefa:9089')"}, + {`SELECT INET6_NTOA(INET_NTOA(167773449));`, true, "SELECT INET6_NTOA(INET_NTOA(167773449))"}, + {`SELECT IS_FREE_LOCK(@str);`, true, "SELECT IS_FREE_LOCK(@`str`)"}, + {`SELECT IS_IPV4('10.0.5.9');`, true, "SELECT IS_IPV4('10.0.5.9')"}, + {`SELECT IS_IPV4_COMPAT(INET6_ATON('::10.0.5.9'));`, true, "SELECT IS_IPV4_COMPAT(INET6_ATON('::10.0.5.9'))"}, + {`SELECT IS_IPV4_MAPPED(INET6_ATON('::10.0.5.9'));`, true, "SELECT IS_IPV4_MAPPED(INET6_ATON('::10.0.5.9'))"}, + {`SELECT IS_IPV6('10.0.5.9');`, true, "SELECT IS_IPV6('10.0.5.9')"}, + {`SELECT IS_USED_LOCK(@str);`, true, "SELECT IS_USED_LOCK(@`str`)"}, + {`SELECT MASTER_POS_WAIT(@log_name, @log_pos), MASTER_POS_WAIT(@log_name, @log_pos, @timeout), MASTER_POS_WAIT(@log_name, @log_pos, @timeout, @channel_name);`, true, "SELECT MASTER_POS_WAIT(@`log_name`, @`log_pos`),MASTER_POS_WAIT(@`log_name`, @`log_pos`, @`timeout`),MASTER_POS_WAIT(@`log_name`, @`log_pos`, @`timeout`, @`channel_name`)"}, + {`SELECT NAME_CONST('myname', 14);`, true, "SELECT NAME_CONST('myname', 14)"}, + {`SELECT RELEASE_ALL_LOCKS();`, true, "SELECT RELEASE_ALL_LOCKS()"}, + {`SELECT UUID();`, true, "SELECT UUID()"}, + {`SELECT UUID_SHORT()`, true, "SELECT UUID_SHORT()"}, // test illegal arguments - {`SELECT SLEEP();`, true, ""}, - {`SELECT ANY_VALUE();`, true, ""}, - {`SELECT INET_ATON();`, true, ""}, - {`SELECT INET_NTOA();`, true, ""}, - {`SELECT INET6_ATON();`, true, ""}, - {`SELECT INET6_NTOA(INET_NTOA());`, true, ""}, - {`SELECT IS_FREE_LOCK();`, true, ""}, - {`SELECT IS_IPV4();`, true, ""}, - {`SELECT IS_IPV4_COMPAT(INET6_ATON());`, true, ""}, - {`SELECT IS_IPV4_MAPPED(INET6_ATON());`, true, ""}, - {`SELECT IS_IPV6()`, true, ""}, - {`SELECT IS_USED_LOCK();`, true, ""}, - {`SELECT MASTER_POS_WAIT();`, true, ""}, - {`SELECT NAME_CONST();`, true, ""}, - {`SELECT RELEASE_ALL_LOCKS(1);`, true, ""}, - {`SELECT UUID(1);`, true, ""}, - {`SELECT UUID_SHORT(1)`, true, ""}, + {`SELECT SLEEP();`, true, "SELECT SLEEP()"}, + {`SELECT ANY_VALUE();`, true, "SELECT ANY_VALUE()"}, + {`SELECT INET_ATON();`, true, "SELECT INET_ATON()"}, + {`SELECT INET_NTOA();`, true, "SELECT INET_NTOA()"}, + {`SELECT INET6_ATON();`, true, "SELECT INET6_ATON()"}, + {`SELECT INET6_NTOA(INET_NTOA());`, true, "SELECT INET6_NTOA(INET_NTOA())"}, + {`SELECT IS_FREE_LOCK();`, true, "SELECT IS_FREE_LOCK()"}, + {`SELECT IS_IPV4();`, true, "SELECT IS_IPV4()"}, + {`SELECT IS_IPV4_COMPAT(INET6_ATON());`, true, "SELECT IS_IPV4_COMPAT(INET6_ATON())"}, + {`SELECT IS_IPV4_MAPPED(INET6_ATON());`, true, "SELECT IS_IPV4_MAPPED(INET6_ATON())"}, + {`SELECT IS_IPV6()`, true, "SELECT IS_IPV6()"}, + {`SELECT IS_USED_LOCK();`, true, "SELECT IS_USED_LOCK()"}, + {`SELECT MASTER_POS_WAIT();`, true, "SELECT MASTER_POS_WAIT()"}, + {`SELECT NAME_CONST();`, true, "SELECT NAME_CONST()"}, + {`SELECT RELEASE_ALL_LOCKS(1);`, true, "SELECT RELEASE_ALL_LOCKS(1)"}, + {`SELECT UUID(1);`, true, "SELECT UUID(1)"}, + {`SELECT UUID_SHORT(1)`, true, "SELECT UUID_SHORT(1)"}, // interval - {`select "2011-11-11 10:10:10.123456" + interval 10 second`, true, ""}, - {`select "2011-11-11 10:10:10.123456" - interval 10 second`, true, ""}, + {`select "2011-11-11 10:10:10.123456" + interval 10 second`, true, "SELECT DATE_ADD('2011-11-11 10:10:10.123456', INTERVAL 10 SECOND)"}, + {`select "2011-11-11 10:10:10.123456" - interval 10 second`, true, "SELECT DATE_SUB('2011-11-11 10:10:10.123456', INTERVAL 10 SECOND)"}, // for date_add - {`select date_add("2011-11-11 10:10:10.123456", interval 10 microsecond)`, true, ""}, - {`select date_add("2011-11-11 10:10:10.123456", interval 10 second)`, true, ""}, - {`select date_add("2011-11-11 10:10:10.123456", interval 10 minute)`, true, ""}, - {`select date_add("2011-11-11 10:10:10.123456", interval 10 hour)`, true, ""}, - {`select date_add("2011-11-11 10:10:10.123456", interval 10 day)`, true, ""}, - {`select date_add("2011-11-11 10:10:10.123456", interval 1 week)`, true, ""}, - {`select date_add("2011-11-11 10:10:10.123456", interval 1 month)`, true, ""}, - {`select date_add("2011-11-11 10:10:10.123456", interval 1 quarter)`, true, ""}, - {`select date_add("2011-11-11 10:10:10.123456", interval 1 year)`, true, ""}, - {`select date_add("2011-11-11 10:10:10.123456", interval "10.10" second_microsecond)`, true, ""}, - {`select date_add("2011-11-11 10:10:10.123456", interval "10:10.10" minute_microsecond)`, true, ""}, - {`select date_add("2011-11-11 10:10:10.123456", interval "10:10" minute_second)`, true, ""}, - {`select date_add("2011-11-11 10:10:10.123456", interval "10:10:10.10" hour_microsecond)`, true, ""}, - {`select date_add("2011-11-11 10:10:10.123456", interval "10:10:10" hour_second)`, true, ""}, - {`select date_add("2011-11-11 10:10:10.123456", interval "10:10" hour_minute)`, true, ""}, - {`select date_add("2011-11-11 10:10:10.123456", interval 10.10 hour_minute)`, true, ""}, - {`select date_add("2011-11-11 10:10:10.123456", interval "11 10:10:10.10" day_microsecond)`, true, ""}, - {`select date_add("2011-11-11 10:10:10.123456", interval "11 10:10:10" day_second)`, true, ""}, - {`select date_add("2011-11-11 10:10:10.123456", interval "11 10:10" day_minute)`, true, ""}, - {`select date_add("2011-11-11 10:10:10.123456", interval "11 10" day_hour)`, true, ""}, - {`select date_add("2011-11-11 10:10:10.123456", interval "11-11" year_month)`, true, ""}, + {`select date_add("2011-11-11 10:10:10.123456", interval 10 microsecond)`, true, "SELECT DATE_ADD('2011-11-11 10:10:10.123456', INTERVAL 10 MICROSECOND)"}, + {`select date_add("2011-11-11 10:10:10.123456", interval 10 second)`, true, "SELECT DATE_ADD('2011-11-11 10:10:10.123456', INTERVAL 10 SECOND)"}, + {`select date_add("2011-11-11 10:10:10.123456", interval 10 minute)`, true, "SELECT DATE_ADD('2011-11-11 10:10:10.123456', INTERVAL 10 MINUTE)"}, + {`select date_add("2011-11-11 10:10:10.123456", interval 10 hour)`, true, "SELECT DATE_ADD('2011-11-11 10:10:10.123456', INTERVAL 10 HOUR)"}, + {`select date_add("2011-11-11 10:10:10.123456", interval 10 day)`, true, "SELECT DATE_ADD('2011-11-11 10:10:10.123456', INTERVAL 10 DAY)"}, + {`select date_add("2011-11-11 10:10:10.123456", interval 1 week)`, true, "SELECT DATE_ADD('2011-11-11 10:10:10.123456', INTERVAL 1 WEEK)"}, + {`select date_add("2011-11-11 10:10:10.123456", interval 1 month)`, true, "SELECT DATE_ADD('2011-11-11 10:10:10.123456', INTERVAL 1 MONTH)"}, + {`select date_add("2011-11-11 10:10:10.123456", interval 1 quarter)`, true, "SELECT DATE_ADD('2011-11-11 10:10:10.123456', INTERVAL 1 QUARTER)"}, + {`select date_add("2011-11-11 10:10:10.123456", interval 1 year)`, true, "SELECT DATE_ADD('2011-11-11 10:10:10.123456', INTERVAL 1 YEAR)"}, + {`select date_add("2011-11-11 10:10:10.123456", interval "10.10" second_microsecond)`, true, "SELECT DATE_ADD('2011-11-11 10:10:10.123456', INTERVAL '10.10' SECOND_MICROSECOND)"}, + {`select date_add("2011-11-11 10:10:10.123456", interval "10:10.10" minute_microsecond)`, true, "SELECT DATE_ADD('2011-11-11 10:10:10.123456', INTERVAL '10:10.10' MINUTE_MICROSECOND)"}, + {`select date_add("2011-11-11 10:10:10.123456", interval "10:10" minute_second)`, true, "SELECT DATE_ADD('2011-11-11 10:10:10.123456', INTERVAL '10:10' MINUTE_SECOND)"}, + {`select date_add("2011-11-11 10:10:10.123456", interval "10:10:10.10" hour_microsecond)`, true, "SELECT DATE_ADD('2011-11-11 10:10:10.123456', INTERVAL '10:10:10.10' HOUR_MICROSECOND)"}, + {`select date_add("2011-11-11 10:10:10.123456", interval "10:10:10" hour_second)`, true, "SELECT DATE_ADD('2011-11-11 10:10:10.123456', INTERVAL '10:10:10' HOUR_SECOND)"}, + {`select date_add("2011-11-11 10:10:10.123456", interval "10:10" hour_minute)`, true, "SELECT DATE_ADD('2011-11-11 10:10:10.123456', INTERVAL '10:10' HOUR_MINUTE)"}, + {`select date_add("2011-11-11 10:10:10.123456", interval 10.10 hour_minute)`, true, "SELECT DATE_ADD('2011-11-11 10:10:10.123456', INTERVAL 10.10 HOUR_MINUTE)"}, + {`select date_add("2011-11-11 10:10:10.123456", interval "11 10:10:10.10" day_microsecond)`, true, "SELECT DATE_ADD('2011-11-11 10:10:10.123456', INTERVAL '11 10:10:10.10' DAY_MICROSECOND)"}, + {`select date_add("2011-11-11 10:10:10.123456", interval "11 10:10:10" day_second)`, true, "SELECT DATE_ADD('2011-11-11 10:10:10.123456', INTERVAL '11 10:10:10' DAY_SECOND)"}, + {`select date_add("2011-11-11 10:10:10.123456", interval "11 10:10" day_minute)`, true, "SELECT DATE_ADD('2011-11-11 10:10:10.123456', INTERVAL '11 10:10' DAY_MINUTE)"}, + {`select date_add("2011-11-11 10:10:10.123456", interval "11 10" day_hour)`, true, "SELECT DATE_ADD('2011-11-11 10:10:10.123456', INTERVAL '11 10' DAY_HOUR)"}, + {`select date_add("2011-11-11 10:10:10.123456", interval "11-11" year_month)`, true, "SELECT DATE_ADD('2011-11-11 10:10:10.123456', INTERVAL '11-11' YEAR_MONTH)"}, {`select date_add("2011-11-11 10:10:10.123456", 10)`, false, ""}, {`select date_add("2011-11-11 10:10:10.123456", 0.10)`, false, ""}, {`select date_add("2011-11-11 10:10:10.123456", "11,11")`, false, ""}, // for strcmp - {`select strcmp('abc', 'def')`, true, ""}, + {`select strcmp('abc', 'def')`, true, "SELECT STRCMP('abc', 'def')"}, // for adddate - {`select adddate("2011-11-11 10:10:10.123456", interval 10 microsecond)`, true, ""}, - {`select adddate("2011-11-11 10:10:10.123456", interval 10 second)`, true, ""}, - {`select adddate("2011-11-11 10:10:10.123456", interval 10 minute)`, true, ""}, - {`select adddate("2011-11-11 10:10:10.123456", interval 10 hour)`, true, ""}, - {`select adddate("2011-11-11 10:10:10.123456", interval 10 day)`, true, ""}, - {`select adddate("2011-11-11 10:10:10.123456", interval 1 week)`, true, ""}, - {`select adddate("2011-11-11 10:10:10.123456", interval 1 month)`, true, ""}, - {`select adddate("2011-11-11 10:10:10.123456", interval 1 quarter)`, true, ""}, - {`select adddate("2011-11-11 10:10:10.123456", interval 1 year)`, true, ""}, - {`select adddate("2011-11-11 10:10:10.123456", interval "10.10" second_microsecond)`, true, ""}, - {`select adddate("2011-11-11 10:10:10.123456", interval "10:10.10" minute_microsecond)`, true, ""}, - {`select adddate("2011-11-11 10:10:10.123456", interval "10:10" minute_second)`, true, ""}, - {`select adddate("2011-11-11 10:10:10.123456", interval "10:10:10.10" hour_microsecond)`, true, ""}, - {`select adddate("2011-11-11 10:10:10.123456", interval "10:10:10" hour_second)`, true, ""}, - {`select adddate("2011-11-11 10:10:10.123456", interval "10:10" hour_minute)`, true, ""}, - {`select adddate("2011-11-11 10:10:10.123456", interval 10.10 hour_minute)`, true, ""}, - {`select adddate("2011-11-11 10:10:10.123456", interval "11 10:10:10.10" day_microsecond)`, true, ""}, - {`select adddate("2011-11-11 10:10:10.123456", interval "11 10:10:10" day_second)`, true, ""}, - {`select adddate("2011-11-11 10:10:10.123456", interval "11 10:10" day_minute)`, true, ""}, - {`select adddate("2011-11-11 10:10:10.123456", interval "11 10" day_hour)`, true, ""}, - {`select adddate("2011-11-11 10:10:10.123456", interval "11-11" year_month)`, true, ""}, - {`select adddate("2011-11-11 10:10:10.123456", 10)`, true, ""}, - {`select adddate("2011-11-11 10:10:10.123456", 0.10)`, true, ""}, - {`select adddate("2011-11-11 10:10:10.123456", "11,11")`, true, ""}, + {`select adddate("2011-11-11 10:10:10.123456", interval 10 microsecond)`, true, "SELECT ADDDATE('2011-11-11 10:10:10.123456', INTERVAL 10 MICROSECOND)"}, + {`select adddate("2011-11-11 10:10:10.123456", interval 10 second)`, true, "SELECT ADDDATE('2011-11-11 10:10:10.123456', INTERVAL 10 SECOND)"}, + {`select adddate("2011-11-11 10:10:10.123456", interval 10 minute)`, true, "SELECT ADDDATE('2011-11-11 10:10:10.123456', INTERVAL 10 MINUTE)"}, + {`select adddate("2011-11-11 10:10:10.123456", interval 10 hour)`, true, "SELECT ADDDATE('2011-11-11 10:10:10.123456', INTERVAL 10 HOUR)"}, + {`select adddate("2011-11-11 10:10:10.123456", interval 10 day)`, true, "SELECT ADDDATE('2011-11-11 10:10:10.123456', INTERVAL 10 DAY)"}, + {`select adddate("2011-11-11 10:10:10.123456", interval 1 week)`, true, "SELECT ADDDATE('2011-11-11 10:10:10.123456', INTERVAL 1 WEEK)"}, + {`select adddate("2011-11-11 10:10:10.123456", interval 1 month)`, true, "SELECT ADDDATE('2011-11-11 10:10:10.123456', INTERVAL 1 MONTH)"}, + {`select adddate("2011-11-11 10:10:10.123456", interval 1 quarter)`, true, "SELECT ADDDATE('2011-11-11 10:10:10.123456', INTERVAL 1 QUARTER)"}, + {`select adddate("2011-11-11 10:10:10.123456", interval 1 year)`, true, "SELECT ADDDATE('2011-11-11 10:10:10.123456', INTERVAL 1 YEAR)"}, + {`select adddate("2011-11-11 10:10:10.123456", interval "10.10" second_microsecond)`, true, "SELECT ADDDATE('2011-11-11 10:10:10.123456', INTERVAL '10.10' SECOND_MICROSECOND)"}, + {`select adddate("2011-11-11 10:10:10.123456", interval "10:10.10" minute_microsecond)`, true, "SELECT ADDDATE('2011-11-11 10:10:10.123456', INTERVAL '10:10.10' MINUTE_MICROSECOND)"}, + {`select adddate("2011-11-11 10:10:10.123456", interval "10:10" minute_second)`, true, "SELECT ADDDATE('2011-11-11 10:10:10.123456', INTERVAL '10:10' MINUTE_SECOND)"}, + {`select adddate("2011-11-11 10:10:10.123456", interval "10:10:10.10" hour_microsecond)`, true, "SELECT ADDDATE('2011-11-11 10:10:10.123456', INTERVAL '10:10:10.10' HOUR_MICROSECOND)"}, + {`select adddate("2011-11-11 10:10:10.123456", interval "10:10:10" hour_second)`, true, "SELECT ADDDATE('2011-11-11 10:10:10.123456', INTERVAL '10:10:10' HOUR_SECOND)"}, + {`select adddate("2011-11-11 10:10:10.123456", interval "10:10" hour_minute)`, true, "SELECT ADDDATE('2011-11-11 10:10:10.123456', INTERVAL '10:10' HOUR_MINUTE)"}, + {`select adddate("2011-11-11 10:10:10.123456", interval 10.10 hour_minute)`, true, "SELECT ADDDATE('2011-11-11 10:10:10.123456', INTERVAL 10.10 HOUR_MINUTE)"}, + {`select adddate("2011-11-11 10:10:10.123456", interval "11 10:10:10.10" day_microsecond)`, true, "SELECT ADDDATE('2011-11-11 10:10:10.123456', INTERVAL '11 10:10:10.10' DAY_MICROSECOND)"}, + {`select adddate("2011-11-11 10:10:10.123456", interval "11 10:10:10" day_second)`, true, "SELECT ADDDATE('2011-11-11 10:10:10.123456', INTERVAL '11 10:10:10' DAY_SECOND)"}, + {`select adddate("2011-11-11 10:10:10.123456", interval "11 10:10" day_minute)`, true, "SELECT ADDDATE('2011-11-11 10:10:10.123456', INTERVAL '11 10:10' DAY_MINUTE)"}, + {`select adddate("2011-11-11 10:10:10.123456", interval "11 10" day_hour)`, true, "SELECT ADDDATE('2011-11-11 10:10:10.123456', INTERVAL '11 10' DAY_HOUR)"}, + {`select adddate("2011-11-11 10:10:10.123456", interval "11-11" year_month)`, true, "SELECT ADDDATE('2011-11-11 10:10:10.123456', INTERVAL '11-11' YEAR_MONTH)"}, + {`select adddate("2011-11-11 10:10:10.123456", 10)`, true, "SELECT ADDDATE('2011-11-11 10:10:10.123456', INTERVAL 10 DAY)"}, + {`select adddate("2011-11-11 10:10:10.123456", 0.10)`, true, "SELECT ADDDATE('2011-11-11 10:10:10.123456', INTERVAL 0.10 DAY)"}, + {`select adddate("2011-11-11 10:10:10.123456", "11,11")`, true, "SELECT ADDDATE('2011-11-11 10:10:10.123456', INTERVAL '11,11' DAY)"}, // for date_sub - {`select date_sub("2011-11-11 10:10:10.123456", interval 10 microsecond)`, true, ""}, - {`select date_sub("2011-11-11 10:10:10.123456", interval 10 second)`, true, ""}, - {`select date_sub("2011-11-11 10:10:10.123456", interval 10 minute)`, true, ""}, - {`select date_sub("2011-11-11 10:10:10.123456", interval 10 hour)`, true, ""}, - {`select date_sub("2011-11-11 10:10:10.123456", interval 10 day)`, true, ""}, - {`select date_sub("2011-11-11 10:10:10.123456", interval 1 week)`, true, ""}, - {`select date_sub("2011-11-11 10:10:10.123456", interval 1 month)`, true, ""}, - {`select date_sub("2011-11-11 10:10:10.123456", interval 1 quarter)`, true, ""}, - {`select date_sub("2011-11-11 10:10:10.123456", interval 1 year)`, true, ""}, - {`select date_sub("2011-11-11 10:10:10.123456", interval "10.10" second_microsecond)`, true, ""}, - {`select date_sub("2011-11-11 10:10:10.123456", interval "10:10.10" minute_microsecond)`, true, ""}, - {`select date_sub("2011-11-11 10:10:10.123456", interval "10:10" minute_second)`, true, ""}, - {`select date_sub("2011-11-11 10:10:10.123456", interval "10:10:10.10" hour_microsecond)`, true, ""}, - {`select date_sub("2011-11-11 10:10:10.123456", interval "10:10:10" hour_second)`, true, ""}, - {`select date_sub("2011-11-11 10:10:10.123456", interval "10:10" hour_minute)`, true, ""}, - {`select date_sub("2011-11-11 10:10:10.123456", interval 10.10 hour_minute)`, true, ""}, - {`select date_sub("2011-11-11 10:10:10.123456", interval "11 10:10:10.10" day_microsecond)`, true, ""}, - {`select date_sub("2011-11-11 10:10:10.123456", interval "11 10:10:10" day_second)`, true, ""}, - {`select date_sub("2011-11-11 10:10:10.123456", interval "11 10:10" day_minute)`, true, ""}, - {`select date_sub("2011-11-11 10:10:10.123456", interval "11 10" day_hour)`, true, ""}, - {`select date_sub("2011-11-11 10:10:10.123456", interval "11-11" year_month)`, true, ""}, + {`select date_sub("2011-11-11 10:10:10.123456", interval 10 microsecond)`, true, "SELECT DATE_SUB('2011-11-11 10:10:10.123456', INTERVAL 10 MICROSECOND)"}, + {`select date_sub("2011-11-11 10:10:10.123456", interval 10 second)`, true, "SELECT DATE_SUB('2011-11-11 10:10:10.123456', INTERVAL 10 SECOND)"}, + {`select date_sub("2011-11-11 10:10:10.123456", interval 10 minute)`, true, "SELECT DATE_SUB('2011-11-11 10:10:10.123456', INTERVAL 10 MINUTE)"}, + {`select date_sub("2011-11-11 10:10:10.123456", interval 10 hour)`, true, "SELECT DATE_SUB('2011-11-11 10:10:10.123456', INTERVAL 10 HOUR)"}, + {`select date_sub("2011-11-11 10:10:10.123456", interval 10 day)`, true, "SELECT DATE_SUB('2011-11-11 10:10:10.123456', INTERVAL 10 DAY)"}, + {`select date_sub("2011-11-11 10:10:10.123456", interval 1 week)`, true, "SELECT DATE_SUB('2011-11-11 10:10:10.123456', INTERVAL 1 WEEK)"}, + {`select date_sub("2011-11-11 10:10:10.123456", interval 1 month)`, true, "SELECT DATE_SUB('2011-11-11 10:10:10.123456', INTERVAL 1 MONTH)"}, + {`select date_sub("2011-11-11 10:10:10.123456", interval 1 quarter)`, true, "SELECT DATE_SUB('2011-11-11 10:10:10.123456', INTERVAL 1 QUARTER)"}, + {`select date_sub("2011-11-11 10:10:10.123456", interval 1 year)`, true, "SELECT DATE_SUB('2011-11-11 10:10:10.123456', INTERVAL 1 YEAR)"}, + {`select date_sub("2011-11-11 10:10:10.123456", interval "10.10" second_microsecond)`, true, "SELECT DATE_SUB('2011-11-11 10:10:10.123456', INTERVAL '10.10' SECOND_MICROSECOND)"}, + {`select date_sub("2011-11-11 10:10:10.123456", interval "10:10.10" minute_microsecond)`, true, "SELECT DATE_SUB('2011-11-11 10:10:10.123456', INTERVAL '10:10.10' MINUTE_MICROSECOND)"}, + {`select date_sub("2011-11-11 10:10:10.123456", interval "10:10" minute_second)`, true, "SELECT DATE_SUB('2011-11-11 10:10:10.123456', INTERVAL '10:10' MINUTE_SECOND)"}, + {`select date_sub("2011-11-11 10:10:10.123456", interval "10:10:10.10" hour_microsecond)`, true, "SELECT DATE_SUB('2011-11-11 10:10:10.123456', INTERVAL '10:10:10.10' HOUR_MICROSECOND)"}, + {`select date_sub("2011-11-11 10:10:10.123456", interval "10:10:10" hour_second)`, true, "SELECT DATE_SUB('2011-11-11 10:10:10.123456', INTERVAL '10:10:10' HOUR_SECOND)"}, + {`select date_sub("2011-11-11 10:10:10.123456", interval "10:10" hour_minute)`, true, "SELECT DATE_SUB('2011-11-11 10:10:10.123456', INTERVAL '10:10' HOUR_MINUTE)"}, + {`select date_sub("2011-11-11 10:10:10.123456", interval 10.10 hour_minute)`, true, "SELECT DATE_SUB('2011-11-11 10:10:10.123456', INTERVAL 10.10 HOUR_MINUTE)"}, + {`select date_sub("2011-11-11 10:10:10.123456", interval "11 10:10:10.10" day_microsecond)`, true, "SELECT DATE_SUB('2011-11-11 10:10:10.123456', INTERVAL '11 10:10:10.10' DAY_MICROSECOND)"}, + {`select date_sub("2011-11-11 10:10:10.123456", interval "11 10:10:10" day_second)`, true, "SELECT DATE_SUB('2011-11-11 10:10:10.123456', INTERVAL '11 10:10:10' DAY_SECOND)"}, + {`select date_sub("2011-11-11 10:10:10.123456", interval "11 10:10" day_minute)`, true, "SELECT DATE_SUB('2011-11-11 10:10:10.123456', INTERVAL '11 10:10' DAY_MINUTE)"}, + {`select date_sub("2011-11-11 10:10:10.123456", interval "11 10" day_hour)`, true, "SELECT DATE_SUB('2011-11-11 10:10:10.123456', INTERVAL '11 10' DAY_HOUR)"}, + {`select date_sub("2011-11-11 10:10:10.123456", interval "11-11" year_month)`, true, "SELECT DATE_SUB('2011-11-11 10:10:10.123456', INTERVAL '11-11' YEAR_MONTH)"}, {`select date_sub("2011-11-11 10:10:10.123456", 10)`, false, ""}, {`select date_sub("2011-11-11 10:10:10.123456", 0.10)`, false, ""}, {`select date_sub("2011-11-11 10:10:10.123456", "11,11")`, false, ""}, // for subdate - {`select subdate("2011-11-11 10:10:10.123456", interval 10 microsecond)`, true, ""}, - {`select subdate("2011-11-11 10:10:10.123456", interval 10 second)`, true, ""}, - {`select subdate("2011-11-11 10:10:10.123456", interval 10 minute)`, true, ""}, - {`select subdate("2011-11-11 10:10:10.123456", interval 10 hour)`, true, ""}, - {`select subdate("2011-11-11 10:10:10.123456", interval 10 day)`, true, ""}, - {`select subdate("2011-11-11 10:10:10.123456", interval 1 week)`, true, ""}, - {`select subdate("2011-11-11 10:10:10.123456", interval 1 month)`, true, ""}, - {`select subdate("2011-11-11 10:10:10.123456", interval 1 quarter)`, true, ""}, - {`select subdate("2011-11-11 10:10:10.123456", interval 1 year)`, true, ""}, - {`select subdate("2011-11-11 10:10:10.123456", interval "10.10" second_microsecond)`, true, ""}, - {`select subdate("2011-11-11 10:10:10.123456", interval "10:10.10" minute_microsecond)`, true, ""}, - {`select subdate("2011-11-11 10:10:10.123456", interval "10:10" minute_second)`, true, ""}, - {`select subdate("2011-11-11 10:10:10.123456", interval "10:10:10.10" hour_microsecond)`, true, ""}, - {`select subdate("2011-11-11 10:10:10.123456", interval "10:10:10" hour_second)`, true, ""}, - {`select subdate("2011-11-11 10:10:10.123456", interval "10:10" hour_minute)`, true, ""}, - {`select subdate("2011-11-11 10:10:10.123456", interval 10.10 hour_minute)`, true, ""}, - {`select subdate("2011-11-11 10:10:10.123456", interval "11 10:10:10.10" day_microsecond)`, true, ""}, - {`select subdate("2011-11-11 10:10:10.123456", interval "11 10:10:10" day_second)`, true, ""}, - {`select subdate("2011-11-11 10:10:10.123456", interval "11 10:10" day_minute)`, true, ""}, - {`select subdate("2011-11-11 10:10:10.123456", interval "11 10" day_hour)`, true, ""}, - {`select subdate("2011-11-11 10:10:10.123456", interval "11-11" year_month)`, true, ""}, - {`select subdate("2011-11-11 10:10:10.123456", 10)`, true, ""}, - {`select subdate("2011-11-11 10:10:10.123456", 0.10)`, true, ""}, - {`select subdate("2011-11-11 10:10:10.123456", "11,11")`, true, ""}, + {`select subdate("2011-11-11 10:10:10.123456", interval 10 microsecond)`, true, "SELECT SUBDATE('2011-11-11 10:10:10.123456', INTERVAL 10 MICROSECOND)"}, + {`select subdate("2011-11-11 10:10:10.123456", interval 10 second)`, true, "SELECT SUBDATE('2011-11-11 10:10:10.123456', INTERVAL 10 SECOND)"}, + {`select subdate("2011-11-11 10:10:10.123456", interval 10 minute)`, true, "SELECT SUBDATE('2011-11-11 10:10:10.123456', INTERVAL 10 MINUTE)"}, + {`select subdate("2011-11-11 10:10:10.123456", interval 10 hour)`, true, "SELECT SUBDATE('2011-11-11 10:10:10.123456', INTERVAL 10 HOUR)"}, + {`select subdate("2011-11-11 10:10:10.123456", interval 10 day)`, true, "SELECT SUBDATE('2011-11-11 10:10:10.123456', INTERVAL 10 DAY)"}, + {`select subdate("2011-11-11 10:10:10.123456", interval 1 week)`, true, "SELECT SUBDATE('2011-11-11 10:10:10.123456', INTERVAL 1 WEEK)"}, + {`select subdate("2011-11-11 10:10:10.123456", interval 1 month)`, true, "SELECT SUBDATE('2011-11-11 10:10:10.123456', INTERVAL 1 MONTH)"}, + {`select subdate("2011-11-11 10:10:10.123456", interval 1 quarter)`, true, "SELECT SUBDATE('2011-11-11 10:10:10.123456', INTERVAL 1 QUARTER)"}, + {`select subdate("2011-11-11 10:10:10.123456", interval 1 year)`, true, "SELECT SUBDATE('2011-11-11 10:10:10.123456', INTERVAL 1 YEAR)"}, + {`select subdate("2011-11-11 10:10:10.123456", interval "10.10" second_microsecond)`, true, "SELECT SUBDATE('2011-11-11 10:10:10.123456', INTERVAL '10.10' SECOND_MICROSECOND)"}, + {`select subdate("2011-11-11 10:10:10.123456", interval "10:10.10" minute_microsecond)`, true, "SELECT SUBDATE('2011-11-11 10:10:10.123456', INTERVAL '10:10.10' MINUTE_MICROSECOND)"}, + {`select subdate("2011-11-11 10:10:10.123456", interval "10:10" minute_second)`, true, "SELECT SUBDATE('2011-11-11 10:10:10.123456', INTERVAL '10:10' MINUTE_SECOND)"}, + {`select subdate("2011-11-11 10:10:10.123456", interval "10:10:10.10" hour_microsecond)`, true, "SELECT SUBDATE('2011-11-11 10:10:10.123456', INTERVAL '10:10:10.10' HOUR_MICROSECOND)"}, + {`select subdate("2011-11-11 10:10:10.123456", interval "10:10:10" hour_second)`, true, "SELECT SUBDATE('2011-11-11 10:10:10.123456', INTERVAL '10:10:10' HOUR_SECOND)"}, + {`select subdate("2011-11-11 10:10:10.123456", interval "10:10" hour_minute)`, true, "SELECT SUBDATE('2011-11-11 10:10:10.123456', INTERVAL '10:10' HOUR_MINUTE)"}, + {`select subdate("2011-11-11 10:10:10.123456", interval 10.10 hour_minute)`, true, "SELECT SUBDATE('2011-11-11 10:10:10.123456', INTERVAL 10.10 HOUR_MINUTE)"}, + {`select subdate("2011-11-11 10:10:10.123456", interval "11 10:10:10.10" day_microsecond)`, true, "SELECT SUBDATE('2011-11-11 10:10:10.123456', INTERVAL '11 10:10:10.10' DAY_MICROSECOND)"}, + {`select subdate("2011-11-11 10:10:10.123456", interval "11 10:10:10" day_second)`, true, "SELECT SUBDATE('2011-11-11 10:10:10.123456', INTERVAL '11 10:10:10' DAY_SECOND)"}, + {`select subdate("2011-11-11 10:10:10.123456", interval "11 10:10" day_minute)`, true, "SELECT SUBDATE('2011-11-11 10:10:10.123456', INTERVAL '11 10:10' DAY_MINUTE)"}, + {`select subdate("2011-11-11 10:10:10.123456", interval "11 10" day_hour)`, true, "SELECT SUBDATE('2011-11-11 10:10:10.123456', INTERVAL '11 10' DAY_HOUR)"}, + {`select subdate("2011-11-11 10:10:10.123456", interval "11-11" year_month)`, true, "SELECT SUBDATE('2011-11-11 10:10:10.123456', INTERVAL '11-11' YEAR_MONTH)"}, + {`select subdate("2011-11-11 10:10:10.123456", 10)`, true, "SELECT SUBDATE('2011-11-11 10:10:10.123456', INTERVAL 10 DAY)"}, + {`select subdate("2011-11-11 10:10:10.123456", 0.10)`, true, "SELECT SUBDATE('2011-11-11 10:10:10.123456', INTERVAL 0.10 DAY)"}, + {`select subdate("2011-11-11 10:10:10.123456", "11,11")`, true, "SELECT SUBDATE('2011-11-11 10:10:10.123456', INTERVAL '11,11' DAY)"}, // for unix_timestamp - {`select unix_timestamp()`, true, ""}, - {`select unix_timestamp('2015-11-13 10:20:19.012')`, true, ""}, + {`select unix_timestamp()`, true, "SELECT UNIX_TIMESTAMP()"}, + {`select unix_timestamp('2015-11-13 10:20:19.012')`, true, "SELECT UNIX_TIMESTAMP('2015-11-13 10:20:19.012')"}, // for misc functions - {`SELECT GET_LOCK('lock1',10);`, true, ""}, - {`SELECT RELEASE_LOCK('lock1');`, true, ""}, + {`SELECT GET_LOCK('lock1',10);`, true, "SELECT GET_LOCK('lock1', 10)"}, + {`SELECT RELEASE_LOCK('lock1');`, true, "SELECT RELEASE_LOCK('lock1')"}, // for aggregate functions - {`select avg(), avg(c1,c2) from t;`, false, ""}, - {`select avg(distinct c1) from t;`, true, ""}, - {`select avg(distinctrow c1) from t;`, true, ""}, - {`select avg(distinct all c1) from t;`, true, ""}, - {`select avg(distinctrow all c1) from t;`, true, ""}, - {`select avg(c2) from t;`, true, ""}, - {`select bit_and(c1) from t;`, true, ""}, - {`select bit_and(all c1) from t;`, true, ""}, + {`select avg(), avg(c1,c2) from t;`, false, "SELECT AVG(),AVG(`c1`, `c2`) FROM `t`"}, + {`select avg(distinct c1) from t;`, true, "SELECT AVG(DISTINCT `c1`) FROM `t`"}, + {`select avg(distinctrow c1) from t;`, true, "SELECT AVG(DISTINCT `c1`) FROM `t`"}, + {`select avg(distinct all c1) from t;`, true, "SELECT AVG(DISTINCT `c1`) FROM `t`"}, + {`select avg(distinctrow all c1) from t;`, true, "SELECT AVG(DISTINCT `c1`) FROM `t`"}, + {`select avg(c2) from t;`, true, "SELECT AVG(`c2`) FROM `t`"}, + {`select bit_and(c1) from t;`, true, "SELECT BIT_AND(`c1`) FROM `t`"}, + {`select bit_and(all c1) from t;`, true, "SELECT BIT_AND(`c1`) FROM `t`"}, {`select bit_and(distinct c1) from t;`, false, ""}, {`select bit_and(distinctrow c1) from t;`, false, ""}, {`select bit_and(distinctrow all c1) from t;`, false, ""}, @@ -1293,8 +1293,8 @@ func (s *testParserSuite) TestBuiltin(c *C) { {`select bit_and(), bit_and(distinct c1) from t;`, false, ""}, {`select bit_and(), bit_and(distinctrow c1) from t;`, false, ""}, {`select bit_and(), bit_and(all c1) from t;`, false, ""}, - {`select bit_or(c1) from t;`, true, ""}, - {`select bit_or(all c1) from t;`, true, ""}, + {`select bit_or(c1) from t;`, true, "SELECT BIT_OR(`c1`) FROM `t`"}, + {`select bit_or(all c1) from t;`, true, "SELECT BIT_OR(`c1`) FROM `t`"}, {`select bit_or(distinct c1) from t;`, false, ""}, {`select bit_or(distinctrow c1) from t;`, false, ""}, {`select bit_or(distinctrow all c1) from t;`, false, ""}, @@ -1302,8 +1302,8 @@ func (s *testParserSuite) TestBuiltin(c *C) { {`select bit_or(), bit_or(distinct c1) from t;`, false, ""}, {`select bit_or(), bit_or(distinctrow c1) from t;`, false, ""}, {`select bit_or(), bit_or(all c1) from t;`, false, ""}, - {`select bit_xor(c1) from t;`, true, ""}, - {`select bit_xor(all c1) from t;`, true, ""}, + {`select bit_xor(c1) from t;`, true, "SELECT BIT_XOR(`c1`) FROM `t`"}, + {`select bit_xor(all c1) from t;`, true, "SELECT BIT_XOR(`c1`) FROM `t`"}, {`select bit_xor(distinct c1) from t;`, false, ""}, {`select bit_xor(distinctrow c1) from t;`, false, ""}, {`select bit_xor(distinctrow all c1) from t;`, false, ""}, @@ -1311,90 +1311,90 @@ func (s *testParserSuite) TestBuiltin(c *C) { {`select bit_xor(), bit_xor(distinctrow c1) from t;`, false, ""}, {`select bit_xor(), bit_xor(all c1) from t;`, false, ""}, {`select max(c1,c2) from t;`, false, ""}, - {`select max(distinct c1) from t;`, true, ""}, - {`select max(distinctrow c1) from t;`, true, ""}, - {`select max(distinct all c1) from t;`, true, ""}, - {`select max(distinctrow all c1) from t;`, true, ""}, - {`select max(c2) from t;`, true, ""}, + {`select max(distinct c1) from t;`, true, "SELECT MAX(DISTINCT `c1`) FROM `t`"}, + {`select max(distinctrow c1) from t;`, true, "SELECT MAX(DISTINCT `c1`) FROM `t`"}, + {`select max(distinct all c1) from t;`, true, "SELECT MAX(DISTINCT `c1`) FROM `t`"}, + {`select max(distinctrow all c1) from t;`, true, "SELECT MAX(DISTINCT `c1`) FROM `t`"}, + {`select max(c2) from t;`, true, "SELECT MAX(`c2`) FROM `t`"}, {`select min(c1,c2) from t;`, false, ""}, - {`select min(distinct c1) from t;`, true, ""}, - {`select min(distinctrow c1) from t;`, true, ""}, - {`select min(distinct all c1) from t;`, true, ""}, - {`select min(distinctrow all c1) from t;`, true, ""}, - {`select min(c2) from t;`, true, ""}, + {`select min(distinct c1) from t;`, true, "SELECT MIN(DISTINCT `c1`) FROM `t`"}, + {`select min(distinctrow c1) from t;`, true, "SELECT MIN(DISTINCT `c1`) FROM `t`"}, + {`select min(distinct all c1) from t;`, true, "SELECT MIN(DISTINCT `c1`) FROM `t`"}, + {`select min(distinctrow all c1) from t;`, true, "SELECT MIN(DISTINCT `c1`) FROM `t`"}, + {`select min(c2) from t;`, true, "SELECT MIN(`c2`) FROM `t`"}, {`select sum(c1,c2) from t;`, false, ""}, - {`select sum(distinct c1) from t;`, true, ""}, - {`select sum(distinctrow c1) from t;`, true, ""}, - {`select sum(distinct all c1) from t;`, true, ""}, - {`select sum(distinctrow all c1) from t;`, true, ""}, - {`select sum(c2) from t;`, true, ""}, - {`select count(c1) from t;`, true, ""}, + {`select sum(distinct c1) from t;`, true, "SELECT SUM(DISTINCT `c1`) FROM `t`"}, + {`select sum(distinctrow c1) from t;`, true, "SELECT SUM(DISTINCT `c1`) FROM `t`"}, + {`select sum(distinct all c1) from t;`, true, "SELECT SUM(DISTINCT `c1`) FROM `t`"}, + {`select sum(distinctrow all c1) from t;`, true, "SELECT SUM(DISTINCT `c1`) FROM `t`"}, + {`select sum(c2) from t;`, true, "SELECT SUM(`c2`) FROM `t`"}, + {`select count(c1) from t;`, true, "SELECT COUNT(`c1`) FROM `t`"}, {`select count(distinct *) from t;`, false, ""}, {`select count(distinctrow *) from t;`, false, ""}, - {`select count(*) from t;`, true, ""}, - {`select count(distinct c1, c2) from t;`, true, ""}, - {`select count(distinctrow c1, c2) from t;`, true, ""}, + {`select count(*) from t;`, true, "SELECT COUNT(1) FROM `t`"}, + {`select count(distinct c1, c2) from t;`, true, "SELECT COUNT(DISTINCT `c1`, `c2`) FROM `t`"}, + {`select count(distinctrow c1, c2) from t;`, true, "SELECT COUNT(DISTINCT `c1`, `c2`) FROM `t`"}, {`select count(c1, c2) from t;`, false, ""}, - {`select count(all c1) from t;`, true, ""}, + {`select count(all c1) from t;`, true, "SELECT COUNT(`c1`) FROM `t`"}, {`select count(distinct all c1) from t;`, false, ""}, {`select count(distinctrow all c1) from t;`, false, ""}, - {`select group_concat(c2,c1) from t group by c1;`, true, ""}, - {`select group_concat(c2,c1 SEPARATOR ';') from t group by c1;`, true, ""}, - {`select group_concat(distinct c2,c1) from t group by c1;`, true, ""}, - {`select group_concat(distinctrow c2,c1) from t group by c1;`, true, ""}, - {`SELECT student_name, GROUP_CONCAT(DISTINCT test_score ORDER BY test_score DESC SEPARATOR ' ') FROM student GROUP BY student_name;`, true, ""}, - {`select std(c1), std(all c1), std(distinct c1) from t`, true, ""}, + {`select group_concat(c2,c1) from t group by c1;`, true, "SELECT GROUP_CONCAT(`c2`, `c1` SEPARATOR ',') FROM `t` GROUP BY `c1`"}, + {`select group_concat(c2,c1 SEPARATOR ';') from t group by c1;`, true, "SELECT GROUP_CONCAT(`c2`, `c1` SEPARATOR ';') FROM `t` GROUP BY `c1`"}, + {`select group_concat(distinct c2,c1) from t group by c1;`, true, "SELECT GROUP_CONCAT(DISTINCT `c2`, `c1` SEPARATOR ',') FROM `t` GROUP BY `c1`"}, + {`select group_concat(distinctrow c2,c1) from t group by c1;`, true, "SELECT GROUP_CONCAT(DISTINCT `c2`, `c1` SEPARATOR ',') FROM `t` GROUP BY `c1`"}, + {`SELECT student_name, GROUP_CONCAT(DISTINCT test_score ORDER BY test_score DESC SEPARATOR ' ') FROM student GROUP BY student_name;`, true, "SELECT `student_name`,GROUP_CONCAT(DISTINCT `test_score` SEPARATOR ' ') FROM `student` GROUP BY `student_name`"}, + {`select std(c1), std(all c1), std(distinct c1) from t`, true, "SELECT STD(`c1`),STD(`c1`),STD(DISTINCT `c1`) FROM `t`"}, {`select std(c1, c2) from t`, false, ""}, - {`select stddev(c1), stddev(all c1), stddev(distinct c1) from t`, true, ""}, + {`select stddev(c1), stddev(all c1), stddev(distinct c1) from t`, true, "SELECT STDDEV(`c1`),STDDEV(`c1`),STDDEV(DISTINCT `c1`) FROM `t`"}, {`select stddev(c1, c2) from t`, false, ""}, - {`select stddev_pop(c1), stddev_pop(all c1), stddev_pop(distinct c1) from t`, true, ""}, + {`select stddev_pop(c1), stddev_pop(all c1), stddev_pop(distinct c1) from t`, true, "SELECT STDDEV_POP(`c1`),STDDEV_POP(`c1`),STDDEV_POP(DISTINCT `c1`) FROM `t`"}, {`select stddev_pop(c1, c2) from t`, false, ""}, - {`select stddev_samp(c1), stddev_samp(all c1), stddev_samp(distinct c1) from t`, true, ""}, + {`select stddev_samp(c1), stddev_samp(all c1), stddev_samp(distinct c1) from t`, true, "SELECT STDDEV_SAMP(`c1`),STDDEV_SAMP(`c1`),STDDEV_SAMP(DISTINCT `c1`) FROM `t`"}, {`select stddev_samp(c1, c2) from t`, false, ""}, - {`select variance(c1), variance(all c1), variance(distinct c1) from t`, true, ""}, + {`select variance(c1), variance(all c1), variance(distinct c1) from t`, true, "SELECT VAR_POP(`c1`),VAR_POP(`c1`),VAR_POP(DISTINCT `c1`) FROM `t`"}, {`select variance(c1, c2) from t`, false, ""}, - {`select var_pop(c1), var_pop(all c1), var_pop(distinct c1) from t`, true, ""}, + {`select var_pop(c1), var_pop(all c1), var_pop(distinct c1) from t`, true, "SELECT VAR_POP(`c1`),VAR_POP(`c1`),VAR_POP(DISTINCT `c1`) FROM `t`"}, {`select var_pop(c1, c2) from t`, false, ""}, - {`select var_samp(c1), var_samp(all c1), var_samp(distinct c1) from t`, true, ""}, + {`select var_samp(c1), var_samp(all c1), var_samp(distinct c1) from t`, true, "SELECT VAR_SAMP(`c1`),VAR_SAMP(`c1`),VAR_SAMP(DISTINCT `c1`) FROM `t`"}, {`select var_samp(c1, c2) from t`, false, ""}, // for encryption and compression functions - {`select AES_ENCRYPT('text',UNHEX('F3229A0B371ED2D9441B830D21A390C3'))`, true, ""}, - {`select AES_DECRYPT(@crypt_str,@key_str)`, true, ""}, - {`select AES_DECRYPT(@crypt_str,@key_str,@init_vector);`, true, ""}, - {`SELECT COMPRESS('');`, true, ""}, - {`SELECT DECODE(@crypt_str, @pass_str);`, true, ""}, - {`SELECT DES_DECRYPT(@crypt_str), DES_DECRYPT(@crypt_str, @key_str);`, true, ""}, - {`SELECT DES_ENCRYPT(@str), DES_ENCRYPT(@key_num);`, true, ""}, - {`SELECT ENCODE('cleartext', CONCAT('my_random_salt','my_secret_password'));`, true, ""}, - {`SELECT ENCRYPT('hello'), ENCRYPT('hello', @salt);`, true, ""}, - {`SELECT MD5('testing');`, true, ""}, - {`SELECT OLD_PASSWORD(@str);`, true, ""}, - {`SELECT PASSWORD(@str);`, true, ""}, - {`SELECT RANDOM_BYTES(@len);`, true, ""}, - {`SELECT SHA1('abc');`, true, ""}, - {`SELECT SHA('abc');`, true, ""}, - {`SELECT SHA2('abc', 224);`, true, ""}, - {`SELECT UNCOMPRESS('any string');`, true, ""}, - {`SELECT UNCOMPRESSED_LENGTH(@compressed_string);`, true, ""}, - {`SELECT VALIDATE_PASSWORD_STRENGTH(@str);`, true, ""}, + {`select AES_ENCRYPT('text',UNHEX('F3229A0B371ED2D9441B830D21A390C3'))`, true, "SELECT AES_ENCRYPT('text', UNHEX('F3229A0B371ED2D9441B830D21A390C3'))"}, + {`select AES_DECRYPT(@crypt_str,@key_str)`, true, "SELECT AES_DECRYPT(@`crypt_str`, @`key_str`)"}, + {`select AES_DECRYPT(@crypt_str,@key_str,@init_vector);`, true, "SELECT AES_DECRYPT(@`crypt_str`, @`key_str`, @`init_vector`)"}, + {`SELECT COMPRESS('');`, true, "SELECT COMPRESS('')"}, + {`SELECT DECODE(@crypt_str, @pass_str);`, true, "SELECT DECODE(@`crypt_str`, @`pass_str`)"}, + {`SELECT DES_DECRYPT(@crypt_str), DES_DECRYPT(@crypt_str, @key_str);`, true, "SELECT DES_DECRYPT(@`crypt_str`),DES_DECRYPT(@`crypt_str`, @`key_str`)"}, + {`SELECT DES_ENCRYPT(@str), DES_ENCRYPT(@key_num);`, true, "SELECT DES_ENCRYPT(@`str`),DES_ENCRYPT(@`key_num`)"}, + {`SELECT ENCODE('cleartext', CONCAT('my_random_salt','my_secret_password'));`, true, "SELECT ENCODE('cleartext', CONCAT('my_random_salt', 'my_secret_password'))"}, + {`SELECT ENCRYPT('hello'), ENCRYPT('hello', @salt);`, true, "SELECT ENCRYPT('hello'),ENCRYPT('hello', @`salt`)"}, + {`SELECT MD5('testing');`, true, "SELECT MD5('testing')"}, + {`SELECT OLD_PASSWORD(@str);`, true, "SELECT OLD_PASSWORD(@`str`)"}, + {`SELECT PASSWORD(@str);`, true, "SELECT PASSWORD_FUNC(@`str`)"}, + {`SELECT RANDOM_BYTES(@len);`, true, "SELECT RANDOM_BYTES(@`len`)"}, + {`SELECT SHA1('abc');`, true, "SELECT SHA1('abc')"}, + {`SELECT SHA('abc');`, true, "SELECT SHA('abc')"}, + {`SELECT SHA2('abc', 224);`, true, "SELECT SHA2('abc', 224)"}, + {`SELECT UNCOMPRESS('any string');`, true, "SELECT UNCOMPRESS('any string')"}, + {`SELECT UNCOMPRESSED_LENGTH(@compressed_string);`, true, "SELECT UNCOMPRESSED_LENGTH(@`compressed_string`)"}, + {`SELECT VALIDATE_PASSWORD_STRENGTH(@str);`, true, "SELECT VALIDATE_PASSWORD_STRENGTH(@`str`)"}, // For JSON functions. - {`SELECT JSON_EXTRACT();`, true, ""}, - {`SELECT JSON_UNQUOTE();`, true, ""}, - {`SELECT JSON_TYPE('[123]');`, true, ""}, - {`SELECT JSON_TYPE();`, true, ""}, + {`SELECT JSON_EXTRACT();`, true, "SELECT JSON_EXTRACT()"}, + {`SELECT JSON_UNQUOTE();`, true, "SELECT JSON_UNQUOTE()"}, + {`SELECT JSON_TYPE('[123]');`, true, "SELECT JSON_TYPE('[123]')"}, + {`SELECT JSON_TYPE();`, true, "SELECT JSON_TYPE()"}, // For two json grammar sugar. - {`SELECT a->'$.a' FROM t`, true, ""}, - {`SELECT a->>'$.a' FROM t`, true, ""}, + {`SELECT a->'$.a' FROM t`, true, "SELECT JSON_EXTRACT(`a`, '$.a') FROM `t`"}, + {`SELECT a->>'$.a' FROM t`, true, "SELECT JSON_UNQUOTE(JSON_EXTRACT(`a`, '$.a')) FROM `t`"}, {`SELECT '{}'->'$.a' FROM t`, false, ""}, {`SELECT '{}'->>'$.a' FROM t`, false, ""}, {`SELECT a->3 FROM t`, false, ""}, {`SELECT a->>3 FROM t`, false, ""}, // Test that quoted identifier can be a function name. - {"SELECT `uuid`()", true, ""}, + {"SELECT `uuid`()", true, "SELECT UUID()"}, } s.RunTest(c, table) } @@ -1402,26 +1402,26 @@ func (s *testParserSuite) TestBuiltin(c *C) { func (s *testParserSuite) TestIdentifier(c *C) { table := []testCase{ // for quote identifier - {"select `a`, `a.b`, `a b` from t", true, ""}, + {"select `a`, `a.b`, `a b` from t", true, "SELECT `a`,`a.b`,`a b` FROM `t`"}, // for unquoted identifier {"create table MergeContextTest$Simple (value integer not null, primary key (value))", true, ""}, // for as - {"select 1 as a, 1 as `a`, 1 as \"a\", 1 as 'a'", true, ""}, - {`select 1 as a, 1 as "a", 1 as 'a'`, true, ""}, - {`select 1 a, 1 "a", 1 'a'`, true, ""}, + {"select 1 as a, 1 as `a`, 1 as \"a\", 1 as 'a'", true, "SELECT 1 AS `a`,1 AS `a`,1 AS `a`,1 AS `a`"}, + {`select 1 as a, 1 as "a", 1 as 'a'`, true, "SELECT 1 AS `a`,1 AS `a`,1 AS `a`"}, + {`select 1 a, 1 "a", 1 'a'`, true, "SELECT 1 AS `a`,1 AS `a`,1 AS `a`"}, {`select * from t as "a"`, false, ""}, - {`select * from t a`, true, ""}, + {`select * from t a`, true, "SELECT * FROM `t` AS `a`"}, // reserved keyword can't be used as identifier directly, but A.B pattern is an exception {`select COUNT from DESC`, false, ""}, - {`select COUNT from SELECT.DESC`, true, ""}, + {`select COUNT from SELECT.DESC`, true, "SELECT `COUNT` FROM `SELECT`.`DESC`"}, {"use `select`", true, "USE `select`"}, {"use `sel``ect`", true, "USE `sel``ect`"}, {"use select", false, "USE `select`"}, - {`select * from t as a`, true, ""}, + {`select * from t as a`, true, "SELECT * FROM `t` AS `a`"}, {"select 1 full, 1 row, 1 abs", false, ""}, - {"select 1 full, 1 `row`, 1 abs", true, ""}, + {"select 1 full, 1 `row`, 1 abs", true, "SELECT 1 AS `full`,1 AS `row`,1 AS `abs`"}, {"select * from t full, t1 row, t2 abs", false, ""}, - {"select * from t full, t1 `row`, t2 abs", true, ""}, + {"select * from t full, t1 `row`, t2 abs", true, "SELECT * FROM ((`t` AS `full`) JOIN `t1` AS `row`) JOIN `t2` AS `abs`"}, // for issue 1878, identifiers may begin with digit. {"create database 123test", true, "CREATE DATABASE `123test`"}, {"create database 123", false, "CREATE DATABASE `123`"}, @@ -1928,14 +1928,14 @@ func (s *testParserSuite) TestType(c *C) { {"CREATE TABLE t( c1 TIME(2), c2 DATETIME(2), c3 TIMESTAMP(2) );", true, ""}, // for hexadecimal - {"select x'0a', X'11', 0x11", true, ""}, - {"select x'13181C76734725455A'", true, ""}, + {"select x'0a', X'11', 0x11", true, "SELECT x'0a',x'11',x'11'"}, + {"select x'13181C76734725455A'", true, "SELECT x'13181c76734725455a'"}, {"select x'0xaa'", false, ""}, {"select 0X11", false, ""}, - {"select 0x4920616D2061206C6F6E672068657820737472696E67", true, ""}, + {"select 0x4920616D2061206C6F6E672068657820737472696E67", true, "SELECT x'4920616d2061206c6f6e672068657820737472696e67'"}, // for bit - {"select 0b01, 0b0, b'11', B'11'", true, ""}, + {"select 0b01, 0b0, b'11', B'11'", true, "SELECT b'1',b'0',b'11',b'11'"}, {"select 0B01", false, ""}, {"select 0b21", false, ""}, @@ -2077,10 +2077,10 @@ func (sc *subqueryChecker) Leave(inNode ast.Node) (node ast.Node, ok bool) { func (s *testParserSuite) TestSubquery(c *C) { table := []testCase{ // for compare subquery - {"SELECT 1 > (select 1)", true, ""}, - {"SELECT 1 > ANY (select 1)", true, ""}, - {"SELECT 1 > ALL (select 1)", true, ""}, - {"SELECT 1 > SOME (select 1)", true, ""}, + {"SELECT 1 > (select 1)", true, "SELECT 1>(SELECT 1)"}, + {"SELECT 1 > ANY (select 1)", true, "SELECT 1>ANY (SELECT 1)"}, + {"SELECT 1 > ALL (select 1)", true, "SELECT 1>ALL (SELECT 1)"}, + {"SELECT 1 > SOME (select 1)", true, "SELECT 1>ANY (SELECT 1)"}, // for exists subquery {"SELECT EXISTS select 1", false, ""}, @@ -2112,26 +2112,26 @@ func (s *testParserSuite) TestSubquery(c *C) { } func (s *testParserSuite) TestUnion(c *C) { table := []testCase{ - {"select c1 from t1 union select c2 from t2", true, ""}, - {"select c1 from t1 union (select c2 from t2)", true, ""}, - {"select c1 from t1 union (select c2 from t2) order by c1", true, ""}, - {"select c1 from t1 union select c2 from t2 order by c2", true, ""}, - {"select c1 from t1 union (select c2 from t2) limit 1", true, ""}, - {"select c1 from t1 union (select c2 from t2) limit 1, 1", true, ""}, - {"select c1 from t1 union (select c2 from t2) order by c1 limit 1", true, ""}, - {"(select c1 from t1) union distinct select c2 from t2", true, ""}, - {"(select c1 from t1) union distinctrow select c2 from t2", true, ""}, - {"(select c1 from t1) union all select c2 from t2", true, ""}, + {"select c1 from t1 union select c2 from t2", true, "SELECT `c1` FROM `t1` UNION SELECT `c2` FROM `t2`"}, + {"select c1 from t1 union (select c2 from t2)", true, "SELECT `c1` FROM `t1` UNION (SELECT `c2` FROM `t2`)"}, + {"select c1 from t1 union (select c2 from t2) order by c1", true, "SELECT `c1` FROM `t1` UNION (SELECT `c2` FROM `t2`) ORDER BY `c1`"}, + {"select c1 from t1 union select c2 from t2 order by c2", true, "SELECT `c1` FROM `t1` UNION SELECT `c2` FROM `t2` ORDER BY `c2`"}, + {"select c1 from t1 union (select c2 from t2) limit 1", true, "SELECT `c1` FROM `t1` UNION (SELECT `c2` FROM `t2`) LIMIT 1"}, + {"select c1 from t1 union (select c2 from t2) limit 1, 1", true, "SELECT `c1` FROM `t1` UNION (SELECT `c2` FROM `t2`) LIMIT 1,1"}, + {"select c1 from t1 union (select c2 from t2) order by c1 limit 1", true, "SELECT `c1` FROM `t1` UNION (SELECT `c2` FROM `t2`) ORDER BY `c1` LIMIT 1"}, + {"(select c1 from t1) union distinct select c2 from t2", true, "(SELECT `c1` FROM `t1`) UNION SELECT `c2` FROM `t2`"}, + {"(select c1 from t1) union distinctrow select c2 from t2", true, "(SELECT `c1` FROM `t1`) UNION SELECT `c2` FROM `t2`"}, + {"(select c1 from t1) union all select c2 from t2", true, "(SELECT `c1` FROM `t1`) UNION ALL SELECT `c2` FROM `t2`"}, {"(select c1 from t1) union distinct all select c2 from t2", false, ""}, {"(select c1 from t1) union distinctrow all select c2 from t2", false, ""}, {"(select c1 from t1) union (select c2 from t2) order by c1 union select c3 from t3", false, ""}, {"(select c1 from t1) union (select c2 from t2) limit 1 union select c3 from t3", false, ""}, - {"(select c1 from t1) union select c2 from t2 union (select c3 from t3) order by c1 limit 1", true, ""}, - {"select (select 1 union select 1) as a", true, ""}, - {"select * from (select 1 union select 2) as a", true, ""}, + {"(select c1 from t1) union select c2 from t2 union (select c3 from t3) order by c1 limit 1", true, "(SELECT `c1` FROM `t1`) UNION SELECT `c2` FROM `t2` UNION (SELECT `c3` FROM `t3`) ORDER BY `c1` LIMIT 1"}, + {"select (select 1 union select 1) as a", true, "SELECT (SELECT 1 UNION SELECT 1) AS `a`"}, + {"select * from (select 1 union select 2) as a", true, "SELECT * FROM (SELECT 1 UNION SELECT 2) AS `a`"}, {"insert into t select c1 from t1 union select c2 from t2", true, ""}, {"insert into t (c) select c1 from t1 union select c2 from t2", true, ""}, - {"select 2 as a from dual union select 1 as b from dual order by a", true, ""}, + {"select 2 as a from dual union select 1 as b from dual order by a", true, "SELECT 2 AS `a` UNION SELECT 1 AS `b` ORDER BY `a`"}, } s.RunTest(c, table) } @@ -2173,10 +2173,10 @@ func (s *testParserSuite) TestUnionOrderBy(c *C) { func (s *testParserSuite) TestLikeEscape(c *C) { table := []testCase{ // for like escape - {`select "abc_" like "abc\\_" escape ''`, true, ""}, - {`select "abc_" like "abc\\_" escape '\\'`, true, ""}, + {`select "abc_" like "abc\\_" escape ''`, true, "SELECT 'abc_' LIKE 'abc\\_'"}, + {`select "abc_" like "abc\\_" escape '\\'`, true, "SELECT 'abc_' LIKE 'abc\\_'"}, {`select "abc_" like "abc\\_" escape '||'`, false, ""}, - {`select "abc" like "escape" escape '+'`, true, ""}, + {`select "abc" like "escape" escape '+'`, true, "SELECT 'abc' LIKE 'escape' ESCAPE '+'"}, } s.RunTest(c, table) @@ -2202,25 +2202,25 @@ func (s *testParserSuite) TestMysqlDump(c *C) { func (s *testParserSuite) TestIndexHint(c *C) { table := []testCase{ - {`select * from t use index (primary)`, true, ""}, - {"select * from t use index (`primary`)", true, ""}, - {`select * from t use index ();`, true, ""}, - {`select * from t use index (idx);`, true, ""}, - {`select * from t use index (idx1, idx2);`, true, ""}, - {`select * from t ignore key (idx1)`, true, ""}, - {`select * from t force index for join (idx1)`, true, ""}, - {`select * from t use index for order by (idx1)`, true, ""}, - {`select * from t force index for group by (idx1)`, true, ""}, - {`select * from t use index for group by (idx1) use index for order by (idx2), t2`, true, ""}, + {`select * from t use index (primary)`, true, "SELECT * FROM `t` USE INDEX (`primary`)"}, + {"select * from t use index (`primary`)", true, "SELECT * FROM `t` USE INDEX (`primary`)"}, + {`select * from t use index ();`, true, "SELECT * FROM `t` USE INDEX ()"}, + {`select * from t use index (idx);`, true, "SELECT * FROM `t` USE INDEX (`idx`)"}, + {`select * from t use index (idx1, idx2);`, true, "SELECT * FROM `t` USE INDEX (`idx1`, `idx2`)"}, + {`select * from t ignore key (idx1)`, true, "SELECT * FROM `t` IGNORE INDEX (`idx1`)"}, + {`select * from t force index for join (idx1)`, true, "SELECT * FROM `t` FORCE INDEX FOR JOIN (`idx1`)"}, + {`select * from t use index for order by (idx1)`, true, "SELECT * FROM `t` USE INDEX FOR ORDER BY (`idx1`)"}, + {`select * from t force index for group by (idx1)`, true, "SELECT * FROM `t` FORCE INDEX FOR GROUP BY (`idx1`)"}, + {`select * from t use index for group by (idx1) use index for order by (idx2), t2`, true, "SELECT * FROM (`t` USE INDEX FOR GROUP BY (`idx1`) USE INDEX FOR ORDER BY (`idx2`)) JOIN `t2`"}, } s.RunTest(c, table) } func (s *testParserSuite) TestPriority(c *C) { table := []testCase{ - {`select high_priority * from t`, true, ""}, - {`select low_priority * from t`, true, ""}, - {`select delayed * from t`, true, ""}, + {`select high_priority * from t`, true, "SELECT HIGH_PRIORITY * FROM `t`"}, + {`select low_priority * from t`, true, "SELECT LOW_PRIORITY * FROM `t`"}, + {`select delayed * from t`, true, "SELECT DELAYED * FROM `t`"}, {`insert high_priority into t values (1)`, true, "INSERT HIGH_PRIORITY INTO `t` VALUES (1)"}, {`insert LOW_PRIORITY into t values (1)`, true, "INSERT LOW_PRIORITY INTO `t` VALUES (1)"}, {`insert delayed into t values (1)`, true, "INSERT DELAYED INTO `t` VALUES (1)"}, @@ -2246,8 +2246,8 @@ func (s *testParserSuite) TestPriority(c *C) { func (s *testParserSuite) TestSQLNoCache(c *C) { table := []testCase{ {`select SQL_NO_CACHE * from t`, false, ""}, - {`select SQL_CACHE * from t`, true, ""}, - {`select * from t`, true, ""}, + {`select SQL_CACHE * from t`, true, "SELECT * FROM `t`"}, + {`select * from t`, true, "SELECT * FROM `t`"}, } parser := New() @@ -2263,12 +2263,12 @@ func (s *testParserSuite) TestSQLNoCache(c *C) { func (s *testParserSuite) TestEscape(c *C) { table := []testCase{ {`select """;`, false, ""}, - {`select """";`, true, ""}, - {`select "汉字";`, true, ""}, - {`select 'abc"def';`, true, ""}, - {`select 'a\r\n';`, true, ""}, - {`select "\a\r\n"`, true, ""}, - {`select "\xFF"`, true, ""}, + {`select """";`, true, "SELECT '\"'"}, + {`select "汉字";`, true, "SELECT '汉字'"}, + {`select 'abc"def';`, true, "SELECT 'abc\"def'"}, + {`select 'a\r\n';`, true, "SELECT 'a\r\n'"}, + {`select "\a\r\n"`, true, "SELECT 'a\r\n'"}, + {`select "\xFF"`, true, "SELECT 'xFF'"}, } s.RunTest(c, table) } @@ -2627,66 +2627,66 @@ func (s *testParserSuite) TestWindowFunctions(c *C) { table := []testCase{ // For window function descriptions. // See https://dev.mysql.com/doc/refman/8.0/en/window-function-descriptions.html - {`SELECT CUME_DIST() OVER w FROM t;`, true, ""}, - {`SELECT DENSE_RANK() OVER w FROM t;`, true, ""}, - {`SELECT FIRST_VALUE(val) OVER w FROM t;`, true, ""}, - {`SELECT FIRST_VALUE(val) RESPECT NULLS OVER w FROM t;`, true, ""}, - {`SELECT FIRST_VALUE(val) IGNORE NULLS OVER w FROM t;`, true, ""}, - {`SELECT LAG(val) OVER w FROM t;`, true, ""}, - {`SELECT LAG(val, 1) OVER w FROM t;`, true, ""}, - {`SELECT LAG(val, 1, def) OVER w FROM t;`, true, ""}, - {`SELECT LAST_VALUE(val) OVER w FROM t;`, true, ""}, - {`SELECT LEAD(val) OVER w FROM t;`, true, ""}, - {`SELECT LEAD(val, 1) OVER w FROM t;`, true, ""}, - {`SELECT LEAD(val, 1, def) OVER w FROM t;`, true, ""}, - {`SELECT NTH_VALUE(val, 233) OVER w FROM t;`, true, ""}, - {`SELECT NTH_VALUE(val, 233) FROM FIRST OVER w FROM t;`, true, ""}, - {`SELECT NTH_VALUE(val, 233) FROM LAST OVER w FROM t;`, true, ""}, - {`SELECT NTH_VALUE(val, 233) FROM LAST IGNORE NULLS OVER w FROM t;`, true, ""}, + {`SELECT CUME_DIST() OVER w FROM t;`, true, "SELECT CUME_DIST() OVER (`w`) FROM `t`"}, + {`SELECT DENSE_RANK() OVER w FROM t;`, true, "SELECT DENSE_RANK() OVER (`w`) FROM `t`"}, + {`SELECT FIRST_VALUE(val) OVER w FROM t;`, true, "SELECT FIRST_VALUE(`val`) OVER (`w`) FROM `t`"}, + {`SELECT FIRST_VALUE(val) RESPECT NULLS OVER w FROM t;`, true, "SELECT FIRST_VALUE(`val`) OVER (`w`) FROM `t`"}, + {`SELECT FIRST_VALUE(val) IGNORE NULLS OVER w FROM t;`, true, "SELECT FIRST_VALUE(`val`) IGNORE NULLS OVER (`w`) FROM `t`"}, + {`SELECT LAG(val) OVER w FROM t;`, true, "SELECT LAG(`val`) OVER (`w`) FROM `t`"}, + {`SELECT LAG(val, 1) OVER w FROM t;`, true, "SELECT LAG(`val`, 1) OVER (`w`) FROM `t`"}, + {`SELECT LAG(val, 1, def) OVER w FROM t;`, true, "SELECT LAG(`val`, 1, `def`) OVER (`w`) FROM `t`"}, + {`SELECT LAST_VALUE(val) OVER w FROM t;`, true, "SELECT LAST_VALUE(`val`) OVER (`w`) FROM `t`"}, + {`SELECT LEAD(val) OVER w FROM t;`, true, "SELECT LEAD(`val`) OVER (`w`) FROM `t`"}, + {`SELECT LEAD(val, 1) OVER w FROM t;`, true, "SELECT LEAD(`val`, 1) OVER (`w`) FROM `t`"}, + {`SELECT LEAD(val, 1, def) OVER w FROM t;`, true, "SELECT LEAD(`val`, 1, `def`) OVER (`w`) FROM `t`"}, + {`SELECT NTH_VALUE(val, 233) OVER w FROM t;`, true, "SELECT NTH_VALUE(`val`, 233) OVER (`w`) FROM `t`"}, + {`SELECT NTH_VALUE(val, 233) FROM FIRST OVER w FROM t;`, true, "SELECT NTH_VALUE(`val`, 233) OVER (`w`) FROM `t`"}, + {`SELECT NTH_VALUE(val, 233) FROM LAST OVER w FROM t;`, true, "SELECT NTH_VALUE(`val`, 233) FROM LAST OVER (`w`) FROM `t`"}, + {`SELECT NTH_VALUE(val, 233) FROM LAST IGNORE NULLS OVER w FROM t;`, true, "SELECT NTH_VALUE(`val`, 233) FROM LAST IGNORE NULLS OVER (`w`) FROM `t`"}, {`SELECT NTH_VALUE(val) OVER w FROM t;`, false, ""}, - {`SELECT NTILE(233) OVER w FROM t;`, true, ""}, - {`SELECT PERCENT_RANK() OVER w FROM t;`, true, ""}, - {`SELECT RANK() OVER w FROM t;`, true, ""}, - {`SELECT ROW_NUMBER() OVER w FROM t;`, true, ""}, - {`SELECT n, LAG(n, 1, 0) OVER w, LEAD(n, 1, 0) OVER w, n + LAG(n, 1, 0) OVER w FROM fib;`, true, ""}, + {`SELECT NTILE(233) OVER w FROM t;`, true, "SELECT NTILE(233) OVER (`w`) FROM `t`"}, + {`SELECT PERCENT_RANK() OVER w FROM t;`, true, "SELECT PERCENT_RANK() OVER (`w`) FROM `t`"}, + {`SELECT RANK() OVER w FROM t;`, true, "SELECT RANK() OVER (`w`) FROM `t`"}, + {`SELECT ROW_NUMBER() OVER w FROM t;`, true, "SELECT ROW_NUMBER() OVER (`w`) FROM `t`"}, + {`SELECT n, LAG(n, 1, 0) OVER w, LEAD(n, 1, 0) OVER w, n + LAG(n, 1, 0) OVER w FROM fib;`, true, "SELECT `n`,LAG(`n`, 1, 0) OVER (`w`),LEAD(`n`, 1, 0) OVER (`w`),`n`+LAG(`n`, 1, 0) OVER (`w`) FROM `fib`"}, // For window function concepts and syntax. // See https://dev.mysql.com/doc/refman/8.0/en/window-functions-usage.html - {`SELECT SUM(profit) OVER(PARTITION BY country) AS country_profit FROM sales;`, true, ""}, - {`SELECT SUM(profit) OVER() AS country_profit FROM sales;`, true, ""}, - {`SELECT AVG(profit) OVER() AS country_profit FROM sales;`, true, ""}, - {`SELECT BIT_XOR(profit) OVER() AS country_profit FROM sales;`, true, ""}, - {`SELECT COUNT(profit) OVER() AS country_profit FROM sales;`, true, ""}, - {`SELECT COUNT(ALL profit) OVER() AS country_profit FROM sales;`, true, ""}, - {`SELECT COUNT(*) OVER() AS country_profit FROM sales;`, true, ""}, - {`SELECT MAX(profit) OVER() AS country_profit FROM sales;`, true, ""}, - {`SELECT MIN(profit) OVER() AS country_profit FROM sales;`, true, ""}, - {`SELECT SUM(profit) OVER() AS country_profit FROM sales;`, true, ""}, - {`SELECT ROW_NUMBER() OVER(PARTITION BY country) AS row_num1 FROM sales;`, true, ""}, - {`SELECT ROW_NUMBER() OVER(PARTITION BY country, d ORDER BY year, product) AS row_num2 FROM sales;`, true, ""}, + {`SELECT SUM(profit) OVER(PARTITION BY country) AS country_profit FROM sales;`, true, "SELECT SUM(`profit`) OVER (PARTITION BY `country`) AS `country_profit` FROM `sales`"}, + {`SELECT SUM(profit) OVER() AS country_profit FROM sales;`, true, "SELECT SUM(`profit`) OVER () AS `country_profit` FROM `sales`"}, + {`SELECT AVG(profit) OVER() AS country_profit FROM sales;`, true, "SELECT AVG(`profit`) OVER () AS `country_profit` FROM `sales`"}, + {`SELECT BIT_XOR(profit) OVER() AS country_profit FROM sales;`, true, "SELECT BIT_XOR(`profit`) OVER () AS `country_profit` FROM `sales`"}, + {`SELECT COUNT(profit) OVER() AS country_profit FROM sales;`, true, "SELECT COUNT(`profit`) OVER () AS `country_profit` FROM `sales`"}, + {`SELECT COUNT(ALL profit) OVER() AS country_profit FROM sales;`, true, "SELECT COUNT(`profit`) OVER () AS `country_profit` FROM `sales`"}, + {`SELECT COUNT(*) OVER() AS country_profit FROM sales;`, true, "SELECT COUNT(1) OVER () AS `country_profit` FROM `sales`"}, + {`SELECT MAX(profit) OVER() AS country_profit FROM sales;`, true, "SELECT MAX(`profit`) OVER () AS `country_profit` FROM `sales`"}, + {`SELECT MIN(profit) OVER() AS country_profit FROM sales;`, true, "SELECT MIN(`profit`) OVER () AS `country_profit` FROM `sales`"}, + {`SELECT SUM(profit) OVER() AS country_profit FROM sales;`, true, "SELECT SUM(`profit`) OVER () AS `country_profit` FROM `sales`"}, + {`SELECT ROW_NUMBER() OVER(PARTITION BY country) AS row_num1 FROM sales;`, true, "SELECT ROW_NUMBER() OVER (PARTITION BY `country`) AS `row_num1` FROM `sales`"}, + {`SELECT ROW_NUMBER() OVER(PARTITION BY country, d ORDER BY year, product) AS row_num2 FROM sales;`, true, "SELECT ROW_NUMBER() OVER (PARTITION BY `country`, `d` ORDER BY `year`,`product`) AS `row_num2` FROM `sales`"}, // For window function frame specification. // See https://dev.mysql.com/doc/refman/8.0/en/window-functions-frames.html - {`SELECT SUM(val) OVER (PARTITION BY subject ORDER BY time ROWS UNBOUNDED PRECEDING) FROM t;`, true, ""}, - {`SELECT AVG(val) OVER (PARTITION BY subject ORDER BY time ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) FROM t;`, true, ""}, - {`SELECT AVG(val) OVER (ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) FROM t;`, true, ""}, - {`SELECT AVG(val) OVER (ROWS BETWEEN 1 PRECEDING AND UNBOUNDED FOLLOWING) FROM t;`, true, ""}, - {`SELECT AVG(val) OVER (RANGE BETWEEN INTERVAL 5 DAY PRECEDING AND INTERVAL '2:30' MINUTE_SECOND FOLLOWING) FROM t;`, true, ""}, - {`SELECT AVG(val) OVER (RANGE BETWEEN CURRENT ROW AND CURRENT ROW) FROM t;`, true, ""}, - {`SELECT AVG(val) OVER (RANGE CURRENT ROW) FROM t;`, true, ""}, + {`SELECT SUM(val) OVER (PARTITION BY subject ORDER BY time ROWS UNBOUNDED PRECEDING) FROM t;`, true, "SELECT SUM(`val`) OVER (PARTITION BY `subject` ORDER BY `time` ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM `t`"}, + {`SELECT AVG(val) OVER (PARTITION BY subject ORDER BY time ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) FROM t;`, true, "SELECT AVG(`val`) OVER (PARTITION BY `subject` ORDER BY `time` ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) FROM `t`"}, + {`SELECT AVG(val) OVER (ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) FROM t;`, true, "SELECT AVG(`val`) OVER (ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) FROM `t`"}, + {`SELECT AVG(val) OVER (ROWS BETWEEN 1 PRECEDING AND UNBOUNDED FOLLOWING) FROM t;`, true, "SELECT AVG(`val`) OVER (ROWS BETWEEN 1 PRECEDING AND UNBOUNDED FOLLOWING) FROM `t`"}, + {`SELECT AVG(val) OVER (RANGE BETWEEN INTERVAL 5 DAY PRECEDING AND INTERVAL '2:30' MINUTE_SECOND FOLLOWING) FROM t;`, true, "SELECT AVG(`val`) OVER (RANGE BETWEEN INTERVAL 5 DAY PRECEDING AND INTERVAL '2:30' MINUTE_SECOND FOLLOWING) FROM `t`"}, + {`SELECT AVG(val) OVER (RANGE BETWEEN CURRENT ROW AND CURRENT ROW) FROM t;`, true, "SELECT AVG(`val`) OVER (RANGE BETWEEN CURRENT ROW AND CURRENT ROW) FROM `t`"}, + {`SELECT AVG(val) OVER (RANGE CURRENT ROW) FROM t;`, true, "SELECT AVG(`val`) OVER (RANGE BETWEEN CURRENT ROW AND CURRENT ROW) FROM `t`"}, // For named windows. // See https://dev.mysql.com/doc/refman/8.0/en/window-functions-named-windows.html - {`SELECT RANK() OVER w FROM t WINDOW w AS (ORDER BY val);`, true, ""}, - {`SELECT RANK() OVER w FROM t WINDOW w AS ();`, true, ""}, - {`SELECT FIRST_VALUE(year) OVER (w ORDER BY year ASC) AS first FROM sales WINDOW w AS (PARTITION BY country);`, true, ""}, - {`SELECT RANK() OVER w1 FROM t WINDOW w1 AS (w2), w2 AS (), w3 AS (w1);`, true, ""}, - {`SELECT RANK() OVER w1 FROM t WINDOW w1 AS (w2), w2 AS (w3), w3 AS (w1);`, true, ""}, + {`SELECT RANK() OVER w FROM t WINDOW w AS (ORDER BY val);`, true, "SELECT RANK() OVER (`w`) FROM `t` WINDOW `w` AS (ORDER BY `val`)"}, + {`SELECT RANK() OVER w FROM t WINDOW w AS ();`, true, "SELECT RANK() OVER (`w`) FROM `t` WINDOW `w` AS ()"}, + {`SELECT FIRST_VALUE(year) OVER (w ORDER BY year ASC) AS first FROM sales WINDOW w AS (PARTITION BY country);`, true, "SELECT FIRST_VALUE(`year`) OVER (`w` ORDER BY `year`) AS `first` FROM `sales` WINDOW `w` AS (PARTITION BY `country`)"}, + {`SELECT RANK() OVER w1 FROM t WINDOW w1 AS (w2), w2 AS (), w3 AS (w1);`, true, "SELECT RANK() OVER (`w1`) FROM `t` WINDOW `w1` AS (`w2`),`w2` AS (),`w3` AS (`w1`)"}, + {`SELECT RANK() OVER w1 FROM t WINDOW w1 AS (w2), w2 AS (w3), w3 AS (w1);`, true, "SELECT RANK() OVER (`w1`) FROM `t` WINDOW `w1` AS (`w2`),`w2` AS (`w3`),`w3` AS (`w1`)"}, // For tidb_parse_tso - {`select tidb_parse_tso(1)`, true, ""}, - {`select from_unixtime(404411537129996288)`, true, ""}, - {`select from_unixtime(404411537129996288.22)`, true, ""}, + {`select tidb_parse_tso(1)`, true, "SELECT TIDB_PARSE_TSO(1)"}, + {`select from_unixtime(404411537129996288)`, true, "SELECT FROM_UNIXTIME(404411537129996288)"}, + {`select from_unixtime(404411537129996288.22)`, true, "SELECT FROM_UNIXTIME(404411537129996288.22)"}, } s.enableWindowFunc = true s.RunTest(c, table) @@ -2874,6 +2874,16 @@ type nodeTextCleaner struct { // Enter implements Visitor interface. func (checker *nodeTextCleaner) Enter(in ast.Node) (out ast.Node, skipChildren bool) { in.SetText("") + switch node := in.(type) { + case *ast.FuncCallExpr: + node.FnName.O = strings.ToLower(node.FnName.O) + case *ast.AggregateFuncExpr: + node.F = strings.ToLower(node.F) + case *ast.FieldList: + for _, f := range node.Fields { + f.Offset = 0 + } + } return in, false } From b9ad546e47759f18211898db5ec94102486e5902 Mon Sep 17 00:00:00 2001 From: AndrewDi Date: Sun, 6 Jan 2019 16:57:38 +0800 Subject: [PATCH 2/8] complete all select test --- ast/dml_test.go | 5 ++--- parser_test.go | 54 +++++++++++++++++++++++++++++++++---------------- 2 files changed, 39 insertions(+), 20 deletions(-) diff --git a/ast/dml_test.go b/ast/dml_test.go index 70b85b18a..ed1555036 100644 --- a/ast/dml_test.go +++ b/ast/dml_test.go @@ -183,9 +183,8 @@ func (tc *testDMLSuite) TestTableSourceRestore(c *C) { testCases := []NodeRestoreTestCase{ {"tbl", "`tbl`"}, {"tbl as t", "`tbl` AS `t`"}, - // TODO: Once `Restore` of SelectStmt or UnionStmt is implemented, add the following test cases - // {"(select * from tbl) as t", "(SELECT * FROM `tbl`) AS `t`"}, - // {"(select * from a union select * from b) as t", "(SELECT * FROM `a` UNION SELECT * FROM `b`) AS `t`"}, + {"(select * from tbl) as t", "(SELECT * FROM `tbl`) AS `t`"}, + {"(select * from a union select * from b) as t", "(SELECT * FROM `a` UNION SELECT * FROM `b`) AS `t`"}, } extractNodeFunc := func(node Node) Node { return node.(*SelectStmt).From.TableRefs.Left diff --git a/parser_test.go b/parser_test.go index 063624294..fad6850a1 100755 --- a/parser_test.go +++ b/parser_test.go @@ -26,7 +26,8 @@ import ( "github.com/pingcap/parser/model" "github.com/pingcap/parser/mysql" "github.com/pingcap/parser/terror" - _ "github.com/pingcap/tidb/types/parser_driver" + "github.com/pingcap/tidb/types" + "github.com/pingcap/tidb/types/parser_driver" ) func TestT(t *testing.T) { @@ -1431,24 +1432,24 @@ func (s *testParserSuite) TestIdentifier(c *C) { {"create table 123 (123a1 int)", false, ""}, {fmt.Sprintf("select * from t%cble", 0), false, ""}, // for issue 3954, should NOT be recognized as identifiers. - {`select .78+123`, true, ""}, - {`select .78+.21`, true, ""}, - {`select .78-123`, true, ""}, - {`select .78-.21`, true, ""}, - {`select .78--123`, true, ""}, - {`select .78*123`, true, ""}, - {`select .78*.21`, true, ""}, - {`select .78/123`, true, ""}, - {`select .78/.21`, true, ""}, - {`select .78,123`, true, ""}, - {`select .78,.21`, true, ""}, - {`select .78 , 123`, true, ""}, + {`select .78+123`, true, "SELECT 0.78+123"}, + {`select .78+.21`, true, "SELECT 0.78+0.21"}, + {`select .78-123`, true, "SELECT 0.78-123"}, + {`select .78-.21`, true, "SELECT 0.78-0.21"}, + {`select .78--123`, true, "SELECT 0.78--123"}, + {`select .78*123`, true, "SELECT 0.78*123"}, + {`select .78*.21`, true, "SELECT 0.78*0.21"}, + {`select .78/123`, true, "SELECT 0.78/123"}, + {`select .78/.21`, true, "SELECT 0.78/0.21"}, + {`select .78,123`, true, "SELECT 0.78,123"}, + {`select .78,.21`, true, "SELECT 0.78,0.21"}, + {`select .78 , 123`, true, "SELECT 0.78,123"}, {`select .78.123`, false, ""}, - {`select .78#123`, true, ""}, // select .78 + {`select .78#123`, true, "SELECT 0.78"}, // select .78 {`insert float_test values(.67, 'string');`, true, ""}, - {`select .78'123'`, true, ""}, // select .78 as '123' - {"select .78`123`", true, ""}, // select .78 as `123` - {`select .78"123"`, true, ""}, // select .78 as "123" + {`select .78'123'`, true, "SELECT 0.78 AS `123`"}, // select .78 as '123' + {"select .78`123`", true, "SELECT 0.78 AS `123`"}, // select .78 as `123` + {`select .78"123"`, true, "SELECT 0.78 AS `123`"}, // select .78 as "123" } s.RunTest(c, table) } @@ -2879,9 +2880,28 @@ func (checker *nodeTextCleaner) Enter(in ast.Node) (out ast.Node, skipChildren b node.FnName.O = strings.ToLower(node.FnName.O) case *ast.AggregateFuncExpr: node.F = strings.ToLower(node.F) + case *ast.BinaryOperationExpr: + if v, ok := node.L.(*driver.ValueExpr); ok { + switch v.Kind() { + case types.KindMysqlDecimal: + v.GetMysqlDecimal().FromString(v.GetMysqlDecimal().ToString()) + } + } + if v, ok := node.R.(*driver.ValueExpr); ok { + switch v.Kind() { + case types.KindMysqlDecimal: + v.GetMysqlDecimal().FromString(v.GetMysqlDecimal().ToString()) + } + } case *ast.FieldList: for _, f := range node.Fields { f.Offset = 0 + if v, ok := f.Expr.(*driver.ValueExpr); ok { + switch v.Kind() { + case types.KindMysqlDecimal: + v.GetMysqlDecimal().FromString(v.GetMysqlDecimal().ToString()) + } + } } } return in, false From 91ac1b9619370dcc22da5e36f28f98ee53eb8d4a Mon Sep 17 00:00:00 2001 From: AndrewDi Date: Sat, 12 Jan 2019 11:38:25 +0800 Subject: [PATCH 3/8] fix ci --- parser_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/parser_test.go b/parser_test.go index fad6850a1..bf9fd9640 100755 --- a/parser_test.go +++ b/parser_test.go @@ -2219,9 +2219,9 @@ func (s *testParserSuite) TestIndexHint(c *C) { func (s *testParserSuite) TestPriority(c *C) { table := []testCase{ - {`select high_priority * from t`, true, "SELECT HIGH_PRIORITY * FROM `t`"}, - {`select low_priority * from t`, true, "SELECT LOW_PRIORITY * FROM `t`"}, - {`select delayed * from t`, true, "SELECT DELAYED * FROM `t`"}, + {`select high_priority * from t`, true, "SELECT HIGH_PRIORITY * FROM `t`"}, + {`select low_priority * from t`, true, "SELECT LOW_PRIORITY * FROM `t`"}, + {`select delayed * from t`, true, "SELECT DELAYED * FROM `t`"}, {`insert high_priority into t values (1)`, true, "INSERT HIGH_PRIORITY INTO `t` VALUES (1)"}, {`insert LOW_PRIORITY into t values (1)`, true, "INSERT LOW_PRIORITY INTO `t` VALUES (1)"}, {`insert delayed into t values (1)`, true, "INSERT DELAYED INTO `t` VALUES (1)"}, From bd6d8d6e82a9ff5a53279c3b6d2519e127ef25a8 Mon Sep 17 00:00:00 2001 From: AndrewDi Date: Sat, 12 Jan 2019 11:45:41 +0800 Subject: [PATCH 4/8] fix ci test --- ast/expressions.go | 2 +- parser_test.go | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/ast/expressions.go b/ast/expressions.go index cc78e69be..42f58c762 100755 --- a/ast/expressions.go +++ b/ast/expressions.go @@ -396,7 +396,7 @@ func (n *CompareSubqueryExpr) Restore(ctx *RestoreCtx) error { if err := n.L.Restore(ctx); err != nil { return errors.Annotate(err, "An error occurred while restore CompareSubqueryExpr.L") } - if err := n.Op.Restore(ctx.In); err != nil { + if err := n.Op.Restore(ctx); err != nil { return errors.Annotate(err, "An error occurred while restore CompareSubqueryExpr.Op") } if n.All { diff --git a/parser_test.go b/parser_test.go index bf9fd9640..231dad4e8 100755 --- a/parser_test.go +++ b/parser_test.go @@ -23,6 +23,7 @@ import ( "github.com/pingcap/errors" "github.com/pingcap/parser/ast" "github.com/pingcap/parser/charset" + . "github.com/pingcap/parser/format" "github.com/pingcap/parser/model" "github.com/pingcap/parser/mysql" "github.com/pingcap/parser/terror" @@ -319,9 +320,9 @@ func (s *testParserSuite) TestDMLStmt(c *C) { {"INSERT INTO foo VALUES (1234, 5678)", true, "INSERT INTO `foo` VALUES (1234,5678)"}, {"INSERT INTO t1 (SELECT * FROM t2)", true, ""}, // 15 - {"INSERT INTO foo VALUES (1 || 2)", true, "INSERT INTO `foo` VALUES (1||2)"}, + {"INSERT INTO foo VALUES (1 || 2)", true, "INSERT INTO `foo` VALUES (1 OR 2)"}, {"INSERT INTO foo VALUES (1 | 2)", true, "INSERT INTO `foo` VALUES (1|2)"}, - {"INSERT INTO foo VALUES (false || true)", true, "INSERT INTO `foo` VALUES (FALSE||TRUE)"}, + {"INSERT INTO foo VALUES (false || true)", true, "INSERT INTO `foo` VALUES (FALSE OR TRUE)"}, {"INSERT INTO foo VALUES (bar(5678))", true, ""}, // 20 {"INSERT INTO foo VALUES ()", true, "INSERT INTO `foo` VALUES ()"}, @@ -353,9 +354,9 @@ func (s *testParserSuite) TestDMLStmt(c *C) { {"INSERT INTO tt VALUES (01000001783);", true, "INSERT INTO `tt` VALUES (1000001783)"}, {"INSERT INTO tt VALUES (default);", true, "INSERT INTO `tt` VALUES (DEFAULT)"}, - {"REPLACE INTO foo VALUES (1 || 2)", true, "REPLACE INTO `foo` VALUES (1||2)"}, + {"REPLACE INTO foo VALUES (1 || 2)", true, "REPLACE INTO `foo` VALUES (1 OR 2)"}, {"REPLACE INTO foo VALUES (1 | 2)", true, "REPLACE INTO `foo` VALUES (1|2)"}, - {"REPLACE INTO foo VALUES (false || true)", true, "REPLACE INTO `foo` VALUES (FALSE||TRUE)"}, + {"REPLACE INTO foo VALUES (false || true)", true, "REPLACE INTO `foo` VALUES (FALSE OR TRUE)"}, {"REPLACE INTO foo VALUES (bar(5678))", true, ""}, {"REPLACE INTO foo VALUES ()", true, "REPLACE INTO `foo` VALUES ()"}, {"REPLACE INTO foo (a,b) VALUES (42,314)", true, "REPLACE INTO `foo` (`a`,`b`) VALUES (42,314)"}, From 901d58ba56bf45cfdf25f5a1db0e2179ca929254 Mon Sep 17 00:00:00 2001 From: AndrewDi Date: Sat, 12 Jan 2019 17:14:59 +0800 Subject: [PATCH 5/8] fix CI --- ast/util_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ast/util_test.go b/ast/util_test.go index 2e2489698..3931ea872 100755 --- a/ast/util_test.go +++ b/ast/util_test.go @@ -77,7 +77,7 @@ func (checker *nodeTextCleaner) Enter(in Node) (out Node, skipChildren bool) { case *FieldList: for _, f := range node.Fields { f.Offset = 0 - } + } case *AlterTableSpec: for _, opt := range node.Options { opt.StrValue = strings.ToLower(opt.StrValue) From 66aad529c6dabe4a7719903adcf786b74d0ac61e Mon Sep 17 00:00:00 2001 From: AndrewDi Date: Sun, 13 Jan 2019 09:17:11 +0800 Subject: [PATCH 6/8] fix some [] --- ast/dml.go | 6 +++--- ast/functions.go | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/ast/dml.go b/ast/dml.go index c894545f9..9712156af 100755 --- a/ast/dml.go +++ b/ast/dml.go @@ -771,7 +771,7 @@ func (n *SelectStmt) Restore(ctx *RestoreCtx) error { ctx.WritePlain("/*+ ") for _, tableHint := range n.TableHints { if err := tableHint.Restore(ctx); err != nil { - errors.Annotate(err, "An error occurred while restore SelectStmt.TableHints") + errors.Annotatef(err, "An error occurred while restore SelectStmt.TableHints[%d]",i) } } ctx.WritePlain("*/ ") @@ -789,7 +789,7 @@ func (n *SelectStmt) Restore(ctx *RestoreCtx) error { ctx.WritePlain(",") } if err := field.Restore(ctx); err != nil { - errors.Annotate(err, "An error occurred while restore SelectStmt.Field") + errors.Annotatef(err, "An error occurred while restore SelectStmt.Fields[%i]",i) } } } @@ -832,7 +832,7 @@ func (n *SelectStmt) Restore(ctx *RestoreCtx) error { ctx.WritePlain(",") } if err := windowsSpec.Restore(ctx); err != nil { - errors.Annotate(err, "An error occurred while restore SelectStmt.WindowSpec") + errors.Annotatef(err, "An error occurred while restore SelectStmt.WindowSpec[%d]",i) } } } diff --git a/ast/functions.go b/ast/functions.go index 3df6bb3fa..e805174cf 100755 --- a/ast/functions.go +++ b/ast/functions.go @@ -653,12 +653,12 @@ func (n *AggregateFuncExpr) Restore(ctx *RestoreCtx) error { ctx.WritePlain(", ") } if err := n.Args[i].Restore(ctx); err != nil { - return errors.Annotatef(err, "An error occurred while restore AggregateFuncExpr.Args %d", i) + return errors.Annotatef(err, "An error occurred while restore AggregateFuncExpr.Args[%d]", i) } } ctx.WriteKeyWord(" SEPARATOR ") if err := n.Args[len(n.Args)-1].Restore(ctx); err != nil { - return errors.Annotatef(err, "An error occurred while restore AggregateFuncExpr.Args SEPARATOR") + return errors.Annotate(err, "An error occurred while restore AggregateFuncExpr.Args SEPARATOR") } default: for i, argv := range n.Args { @@ -666,7 +666,7 @@ func (n *AggregateFuncExpr) Restore(ctx *RestoreCtx) error { ctx.WritePlain(", ") } if err := argv.Restore(ctx); err != nil { - return errors.Annotatef(err, "An error occurred while restore AggregateFuncExpr.Args %d", i) + return errors.Annotatef(err, "An error occurred while restore AggregateFuncExpr.Args[%d]", i) } } } From e6fea090f05bf98cccdb7fa205d736f9f6ddf673 Mon Sep 17 00:00:00 2001 From: AndrewDi Date: Sun, 13 Jan 2019 09:20:16 +0800 Subject: [PATCH 7/8] fix some code --- ast/dml.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ast/dml.go b/ast/dml.go index 07476a4cc..8f2db99df 100755 --- a/ast/dml.go +++ b/ast/dml.go @@ -769,9 +769,9 @@ func (n *SelectStmt) Restore(ctx *RestoreCtx) error { if n.TableHints != nil && len(n.TableHints) != 0 { ctx.WritePlain("/*+ ") - for _, tableHint := range n.TableHints { + for i, tableHint := range n.TableHints { if err := tableHint.Restore(ctx); err != nil { - errors.Annotatef(err, "An error occurred while restore SelectStmt.TableHints[%d]",i) + errors.Annotatef(err, "An error occurred while restore SelectStmt.TableHints[%d]", i) } } ctx.WritePlain("*/ ") @@ -789,7 +789,7 @@ func (n *SelectStmt) Restore(ctx *RestoreCtx) error { ctx.WritePlain(",") } if err := field.Restore(ctx); err != nil { - errors.Annotatef(err, "An error occurred while restore SelectStmt.Fields[%i]",i) + errors.Annotatef(err, "An error occurred while restore SelectStmt.Fields[%d]", i) } } } @@ -832,7 +832,7 @@ func (n *SelectStmt) Restore(ctx *RestoreCtx) error { ctx.WritePlain(",") } if err := windowsSpec.Restore(ctx); err != nil { - errors.Annotatef(err, "An error occurred while restore SelectStmt.WindowSpec[%d]",i) + errors.Annotatef(err, "An error occurred while restore SelectStmt.WindowSpec[%d]", i) } } } From 3e6ed33ed588af292a509a8168b2e3184abb1fcf Mon Sep 17 00:00:00 2001 From: AndrewDi Date: Sun, 13 Jan 2019 18:28:48 +0800 Subject: [PATCH 8/8] fix some code --- ast/expressions.go | 2 +- ast/misc.go | 2 +- parser_test.go | 7 ++++--- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/ast/expressions.go b/ast/expressions.go index 42f58c762..261fac89f 100755 --- a/ast/expressions.go +++ b/ast/expressions.go @@ -839,7 +839,7 @@ func (n *PatternLikeExpr) Restore(ctx *RestoreCtx) error { escape := string(n.Escape) if escape != "\\" { ctx.WriteKeyWord(" ESCAPE ") - ctx.WritePlainf("'%s'", escape) + ctx.WriteString(escape) } return nil diff --git a/ast/misc.go b/ast/misc.go index b8f43552b..20a413969 100755 --- a/ast/misc.go +++ b/ast/misc.go @@ -1047,7 +1047,7 @@ type TableOptimizerHint struct { func (n *TableOptimizerHint) Restore(ctx *RestoreCtx) error { ctx.WriteKeyWord(n.HintName.String()) ctx.WritePlain("(") - if n.HintName.O == "MAX_EXECUTION_TIME" { + if n.HintName.L == "max_execution_time" { ctx.WritePlainf("%d", n.MaxExecutionTime) } else { for i, table := range n.Tables { diff --git a/parser_test.go b/parser_test.go index 2067a7902..289ad7767 100755 --- a/parser_test.go +++ b/parser_test.go @@ -2179,6 +2179,7 @@ func (s *testParserSuite) TestLikeEscape(c *C) { {`select "abc_" like "abc\\_" escape '\\'`, true, "SELECT 'abc_' LIKE 'abc\\_'"}, {`select "abc_" like "abc\\_" escape '||'`, false, ""}, {`select "abc" like "escape" escape '+'`, true, "SELECT 'abc' LIKE 'escape' ESCAPE '+'"}, + {"select '''_' like '''_' escape ''''", true, "SELECT '''_' LIKE '''_' ESCAPE ''''"}, } s.RunTest(c, table) @@ -2375,9 +2376,9 @@ func (s *testParserSuite) TestView(c *C) { c.Assert(v.Algorithm, Equals, model.AlgorithmUndefined) c.Assert(v.Definer.Username, Equals, "root") c.Assert(v.Definer.Hostname, Equals, "localhost") - c.Assert(v.Cols[0], Equals, model.CIStr{"a", "a"}) - c.Assert(v.Cols[1], Equals, model.CIStr{"b", "b"}) - c.Assert(v.Cols[2], Equals, model.CIStr{"c", "c"}) + c.Assert(v.Cols[0], Equals, model.NewCIStr("a")) + c.Assert(v.Cols[1], Equals, model.NewCIStr("b")) + c.Assert(v.Cols[2], Equals, model.NewCIStr("c")) c.Assert(v.Select.Text(), Equals, "select c,d,e from t") c.Assert(v.Security, Equals, model.SecurityDefiner) c.Assert(v.CheckOption, Equals, model.CheckOptionCascaded)