github.com/XiaoMi/Gaea@v1.2.5/parser/ast/format_test.go (about) 1 package ast_test 2 3 import ( 4 "bytes" 5 "fmt" 6 7 . "github.com/pingcap/check" 8 9 "github.com/XiaoMi/Gaea/parser" 10 "github.com/XiaoMi/Gaea/parser/ast" 11 ) 12 13 var _ = Suite(&testAstFormatSuite{}) 14 15 type testAstFormatSuite struct { 16 } 17 18 func getDefaultCharsetAndCollate() (string, string) { 19 return "utf8", "utf8_bin" 20 } 21 22 func (ts *testAstFormatSuite) TestAstFormat(c *C) { 23 var testcases = []struct { 24 input string 25 output string 26 }{ 27 // Literals. 28 {`null`, `NULL`}, 29 {`true`, `TRUE`}, 30 {`350`, `350`}, 31 {`001e-12`, `1e-12`}, // Float. 32 {`345.678`, `345.678`}, 33 {`00.0001000`, `0.0001000`}, // Decimal. 34 {`null`, `NULL`}, 35 {`"Hello, world"`, `"Hello, world"`}, 36 {`'Hello, world'`, `"Hello, world"`}, 37 {`'Hello, "world"'`, `"Hello, \"world\""`}, 38 {`_utf8'你好'`, `"你好"`}, 39 {`x'bcde'`, "x'bcde'"}, 40 {`x''`, "x''"}, 41 {`x'0035'`, "x'0035'"}, // Shouldn't trim leading zero. 42 {`b'00111111'`, `b'111111'`}, 43 {`time'10:10:10.123'`, `timeliteral("10:10:10.123")`}, 44 {`timestamp'1999-01-01 10:0:0.123'`, `timestampliteral("1999-01-01 10:0:0.123")`}, 45 {`date '1700-01-01'`, `dateliteral("1700-01-01")`}, 46 47 // Expressions. 48 {`f between 30 and 50`, "`f` BETWEEN 30 AND 50"}, 49 {`f not between 30 and 50`, "`f` NOT BETWEEN 30 AND 50"}, 50 {`345 + " hello "`, `345 + " hello "`}, 51 {`"hello world" >= 'hello world'`, `"hello world" >= "hello world"`}, 52 {`case 3 when 1 then false else true end`, `CASE 3 WHEN 1 THEN FALSE ELSE TRUE END`}, 53 {`database.table.column`, "`database`.`table`.`column`"}, // ColumnNameExpr 54 {`3 is null`, `3 IS NULL`}, 55 {`3 is not null`, `3 IS NOT NULL`}, 56 {`3 is true`, `3 IS TRUE`}, 57 {`3 is not true`, `3 IS NOT TRUE`}, 58 {`3 is false`, `3 IS FALSE`}, 59 {` ( x is false )`, "(`x` IS FALSE)"}, 60 {`3 in ( a,b,"h",6 )`, "3 IN (`a`,`b`,\"h\",6)"}, 61 {`3 not in ( a,b,"h",6 )`, "3 NOT IN (`a`,`b`,\"h\",6)"}, 62 {`"abc" like '%b%'`, `"abc" LIKE "%b%"`}, 63 {`"abc" not like '%b%'`, `"abc" NOT LIKE "%b%"`}, 64 {`"abc" like '%b%' escape '_'`, `"abc" LIKE "%b%" ESCAPE '_'`}, 65 {`"abc" regexp '.*bc?'`, `"abc" REGEXP ".*bc?"`}, 66 {`"abc" not regexp '.*bc?'`, `"abc" NOT REGEXP ".*bc?"`}, 67 {`- 4`, `-4`}, 68 {`- ( - 4 ) `, `-(-4)`}, 69 {`a%b`, "`a` % `b`"}, 70 {`a%b+6`, "`a` % `b` + 6"}, 71 {`a%(b+6)`, "`a` % (`b` + 6)"}, 72 // Functions. 73 {` json_extract ( a,'$.b',"$.\"c d\"" ) `, "json_extract(`a`, \"$.b\", \"$.\\\"c d\\\"\")"}, 74 {` length ( a )`, "length(`a`)"}, 75 {`a -> '$.a'`, "json_extract(`a`, \"$.a\")"}, 76 {`a.b ->> '$.a'`, "json_unquote(json_extract(`a`.`b`, \"$.a\"))"}, 77 {`DATE_ADD('1970-01-01', interval 3 second)`, `date_add("1970-01-01", INTERVAL 3 SECOND)`}, 78 {`TIMESTAMPDIFF(month, '2001-01-01', '2001-02-02 12:03:05.123')`, `timestampdiff(MONTH, "2001-01-01", "2001-02-02 12:03:05.123")`}, 79 // Cast, Convert and Binary. 80 // There should not be spaces between 'cast' and '(' unless 'IGNORE_SPACE' mode is set. 81 // see: https://dev.mysql.com/doc/refman/5.7/en/function-resolution.html 82 {` cast( a as signed ) `, "CAST(`a` AS SIGNED)"}, 83 {` cast( a as unsigned integer) `, "CAST(`a` AS UNSIGNED)"}, 84 {` cast( a as char(3) binary) `, "CAST(`a` AS CHAR(3) BINARY)"}, 85 {` cast( a as decimal ) `, "CAST(`a` AS DECIMAL(11))"}, 86 {` cast( a as decimal (3) ) `, "CAST(`a` AS DECIMAL(3))"}, 87 {` cast( a as decimal (3,3) ) `, "CAST(`a` AS DECIMAL(3, 3))"}, 88 {` convert (a, signed) `, "CONVERT(`a`, SIGNED)"}, 89 {` binary "hello"`, `BINARY "hello"`}, 90 } 91 for _, tt := range testcases { 92 expr := fmt.Sprintf("select %s", tt.input) 93 charset, collation := getDefaultCharsetAndCollate() 94 stmts, _, err := parser.New().Parse(expr, charset, collation) 95 node := stmts[0].(*ast.SelectStmt).Fields.Fields[0].Expr 96 c.Assert(err, IsNil) 97 98 writer := bytes.NewBufferString("") 99 node.Format(writer) 100 c.Assert(writer.String(), Equals, tt.output) 101 } 102 }