github.com/XiaoMi/Gaea@v1.2.5/parser/ast/expressions_test.go (about) 1 // Copyright 2017 PingCAP, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package ast_test 15 16 import ( 17 . "github.com/pingcap/check" 18 19 . "github.com/XiaoMi/Gaea/parser/ast" 20 _ "github.com/XiaoMi/Gaea/parser/tidb-types/parser_driver" 21 ) 22 23 var _ = Suite(&testExpressionsSuite{}) 24 25 type testExpressionsSuite struct { 26 } 27 28 type checkVisitor struct{} 29 30 func (v checkVisitor) Enter(in Node) (Node, bool) { 31 if e, ok := in.(*checkExpr); ok { 32 e.enterCnt++ 33 return in, true 34 } 35 return in, false 36 } 37 38 func (v checkVisitor) Leave(in Node) (Node, bool) { 39 if e, ok := in.(*checkExpr); ok { 40 e.leaveCnt++ 41 } 42 return in, true 43 } 44 45 type checkExpr struct { 46 ValueExpr 47 48 enterCnt int 49 leaveCnt int 50 } 51 52 func (n *checkExpr) Accept(v Visitor) (Node, bool) { 53 newNode, skipChildren := v.Enter(n) 54 if skipChildren { 55 return v.Leave(newNode) 56 } 57 n = newNode.(*checkExpr) 58 return v.Leave(n) 59 } 60 61 func (n *checkExpr) reset() { 62 n.enterCnt = 0 63 n.leaveCnt = 0 64 } 65 66 func (tc *testExpressionsSuite) TestExpresionsVisitorCover(c *C) { 67 ce := &checkExpr{} 68 stmts := 69 []struct { 70 node Node 71 expectedEnterCnt int 72 expectedLeaveCnt int 73 }{ 74 {&BetweenExpr{Expr: ce, Left: ce, Right: ce}, 3, 3}, 75 {&BinaryOperationExpr{L: ce, R: ce}, 2, 2}, 76 {&CaseExpr{Value: ce, WhenClauses: []*WhenClause{{Expr: ce, Result: ce}, 77 {Expr: ce, Result: ce}}, ElseClause: ce}, 6, 6}, 78 {&ColumnNameExpr{Name: &ColumnName{}}, 0, 0}, 79 {&CompareSubqueryExpr{L: ce, R: ce}, 2, 2}, 80 {&DefaultExpr{Name: &ColumnName{}}, 0, 0}, 81 {&ExistsSubqueryExpr{Sel: ce}, 1, 1}, 82 {&IsNullExpr{Expr: ce}, 1, 1}, 83 {&IsTruthExpr{Expr: ce}, 1, 1}, 84 {NewParamMarkerExpr(0), 0, 0}, 85 {&ParenthesesExpr{Expr: ce}, 1, 1}, 86 {&PatternInExpr{Expr: ce, List: []ExprNode{ce, ce, ce}, Sel: ce}, 5, 5}, 87 {&PatternLikeExpr{Expr: ce, Pattern: ce}, 2, 2}, 88 {&PatternRegexpExpr{Expr: ce, Pattern: ce}, 2, 2}, 89 {&PositionExpr{}, 0, 0}, 90 {&RowExpr{Values: []ExprNode{ce, ce}}, 2, 2}, 91 {&UnaryOperationExpr{V: ce}, 1, 1}, 92 {NewValueExpr(0), 0, 0}, 93 {&ValuesExpr{Column: &ColumnNameExpr{Name: &ColumnName{}}}, 0, 0}, 94 {&VariableExpr{Value: ce}, 1, 1}, 95 } 96 97 for _, v := range stmts { 98 ce.reset() 99 v.node.Accept(checkVisitor{}) 100 c.Check(ce.enterCnt, Equals, v.expectedEnterCnt) 101 c.Check(ce.leaveCnt, Equals, v.expectedLeaveCnt) 102 v.node.Accept(visitor1{}) 103 } 104 } 105 106 func (tc *testExpressionsSuite) TestUnaryOperationExprRestore(c *C) { 107 testCases := []NodeRestoreTestCase{ 108 {"++1", "++1"}, 109 {"--1", "--1"}, 110 {"-+1", "-+1"}, 111 {"-1", "-1"}, 112 } 113 extractNodeFunc := func(node Node) Node { 114 return node.(*SelectStmt).Fields.Fields[0].Expr 115 } 116 RunNodeRestoreTest(c, testCases, "select %s", extractNodeFunc) 117 } 118 119 func (tc *testExpressionsSuite) TestColumnNameExprRestore(c *C) { 120 testCases := []NodeRestoreTestCase{ 121 {"abc", "`abc`"}, 122 {"`abc`", "`abc`"}, 123 {"`ab``c`", "`ab``c`"}, 124 {"sabc.tABC", "`sabc`.`tABC`"}, 125 {"dabc.sabc.tabc", "`dabc`.`sabc`.`tabc`"}, 126 {"dabc.`sabc`.tabc", "`dabc`.`sabc`.`tabc`"}, 127 {"`dABC`.`sabc`.tabc", "`dABC`.`sabc`.`tabc`"}, 128 } 129 extractNodeFunc := func(node Node) Node { 130 return node.(*SelectStmt).Fields.Fields[0].Expr 131 } 132 RunNodeRestoreTest(c, testCases, "select %s", extractNodeFunc) 133 } 134 135 func (tc *testExpressionsSuite) TestIsNullExprRestore(c *C) { 136 testCases := []NodeRestoreTestCase{ 137 {"a is null", "`a` IS NULL"}, 138 {"a is not null", "`a` IS NOT NULL"}, 139 } 140 extractNodeFunc := func(node Node) Node { 141 return node.(*SelectStmt).Fields.Fields[0].Expr 142 } 143 RunNodeRestoreTest(c, testCases, "select %s", extractNodeFunc) 144 } 145 146 func (tc *testExpressionsSuite) TestIsTruthRestore(c *C) { 147 testCases := []NodeRestoreTestCase{ 148 {"a is true", "`a` IS TRUE"}, 149 {"a is not true", "`a` IS NOT TRUE"}, 150 {"a is FALSE", "`a` IS FALSE"}, 151 {"a is not false", "`a` IS NOT FALSE"}, 152 } 153 extractNodeFunc := func(node Node) Node { 154 return node.(*SelectStmt).Fields.Fields[0].Expr 155 } 156 RunNodeRestoreTest(c, testCases, "select %s", extractNodeFunc) 157 } 158 159 func (tc *testExpressionsSuite) TestBetweenExprRestore(c *C) { 160 testCases := []NodeRestoreTestCase{ 161 {"b between 1 and 2", "`b` BETWEEN 1 AND 2"}, 162 {"b not between 1 and 2", "`b` NOT BETWEEN 1 AND 2"}, 163 {"b between a and b", "`b` BETWEEN `a` AND `b`"}, 164 {"b between '' and 'b'", "`b` BETWEEN '' AND 'b'"}, 165 {"b between '2018-11-01' and '2018-11-02'", "`b` BETWEEN '2018-11-01' AND '2018-11-02'"}, 166 } 167 extractNodeFunc := func(node Node) Node { 168 return node.(*SelectStmt).Fields.Fields[0].Expr 169 } 170 RunNodeRestoreTest(c, testCases, "select %s", extractNodeFunc) 171 } 172 173 func (tc *testExpressionsSuite) TestCaseExpr(c *C) { 174 testCases := []NodeRestoreTestCase{ 175 {"case when 1 then 2 end", "CASE WHEN 1 THEN 2 END"}, 176 {"case when 1 then 'a' when 2 then 'b' end", "CASE WHEN 1 THEN 'a' WHEN 2 THEN 'b' END"}, 177 {"case when 1 then 'a' when 2 then 'b' else 'c' end", "CASE WHEN 1 THEN 'a' WHEN 2 THEN 'b' ELSE 'c' END"}, 178 {"case when 'a'!=1 then true else false end", "CASE WHEN 'a'!=1 THEN TRUE ELSE FALSE END"}, 179 {"case a when 'a' then true else false end", "CASE `a` WHEN 'a' THEN TRUE ELSE FALSE END"}, 180 } 181 extractNodeFunc := func(node Node) Node { 182 return node.(*SelectStmt).Fields.Fields[0].Expr 183 } 184 RunNodeRestoreTest(c, testCases, "select %s", extractNodeFunc) 185 } 186 187 func (tc *testExpressionsSuite) TestBinaryOperationExpr(c *C) { 188 testCases := []NodeRestoreTestCase{ 189 {"'a'!=1", "'a'!=1"}, 190 {"a!=1", "`a`!=1"}, 191 {"3<5", "3<5"}, 192 {"10>5", "10>5"}, 193 {"3+5", "3+5"}, 194 {"3-5", "3-5"}, 195 {"a<>5", "`a`!=5"}, 196 {"a=1", "`a`=1"}, 197 } 198 extractNodeFunc := func(node Node) Node { 199 return node.(*SelectStmt).Fields.Fields[0].Expr 200 } 201 RunNodeRestoreTest(c, testCases, "select %s", extractNodeFunc) 202 } 203 204 func (tc *testExpressionsSuite) TestParenthesesExpr(c *C) { 205 testCases := []NodeRestoreTestCase{ 206 {"(1+2)*3", "(1+2)*3"}, 207 {"1+2*3", "1+2*3"}, 208 } 209 extractNodeFunc := func(node Node) Node { 210 return node.(*SelectStmt).Fields.Fields[0].Expr 211 } 212 RunNodeRestoreTest(c, testCases, "select %s", extractNodeFunc) 213 } 214 215 func (tc *testExpressionsSuite) TestWhenClause(c *C) { 216 testCases := []NodeRestoreTestCase{ 217 {"when 1 then 2", "WHEN 1 THEN 2"}, 218 {"when 1 then 'a'", "WHEN 1 THEN 'a'"}, 219 {"when 'a'!=1 then true", "WHEN 'a'!=1 THEN TRUE"}, 220 } 221 extractNodeFunc := func(node Node) Node { 222 return node.(*SelectStmt).Fields.Fields[0].Expr.(*CaseExpr).WhenClauses[0] 223 } 224 RunNodeRestoreTest(c, testCases, "select case %s end", extractNodeFunc) 225 } 226 227 func (tc *testExpressionsSuite) TestDefaultExpr(c *C) { 228 testCases := []NodeRestoreTestCase{ 229 {"default", "DEFAULT"}, 230 {"default(i)", "DEFAULT(`i`)"}, 231 } 232 extractNodeFunc := func(node Node) Node { 233 return node.(*InsertStmt).Lists[0][0] 234 } 235 RunNodeRestoreTest(c, testCases, "insert into t values(%s)", extractNodeFunc) 236 } 237 238 func (tc *testExpressionsSuite) TestPatternInExprRestore(c *C) { 239 testCases := []NodeRestoreTestCase{ 240 {"'a' in ('b')", "'a' IN ('b')"}, 241 {"2 in (0,3,7)", "2 IN (0,3,7)"}, 242 {"2 not in (0,3,7)", "2 NOT IN (0,3,7)"}, 243 {"2 in (select 2)", "2 IN (SELECT 2)"}, 244 {"2 not in (select 2)", "2 NOT IN (SELECT 2)"}, 245 } 246 extractNodeFunc := func(node Node) Node { 247 return node.(*SelectStmt).Fields.Fields[0].Expr 248 } 249 RunNodeRestoreTest(c, testCases, "select %s", extractNodeFunc) 250 } 251 252 func (tc *testExpressionsSuite) TestPatternLikeExprRestore(c *C) { 253 testCases := []NodeRestoreTestCase{ 254 {"a like 't1'", "`a` LIKE 't1'"}, 255 {"a like 't1%'", "`a` LIKE 't1%'"}, 256 {"a like '%t1%'", "`a` LIKE '%t1%'"}, 257 {"a like '%t1_|'", "`a` LIKE '%t1_|'"}, 258 {"a not like 't1'", "`a` NOT LIKE 't1'"}, 259 {"a not like 't1%'", "`a` NOT LIKE 't1%'"}, 260 {"a not like '%D%v%'", "`a` NOT LIKE '%D%v%'"}, 261 {"a not like '%t1_|'", "`a` NOT LIKE '%t1_|'"}, 262 } 263 extractNodeFunc := func(node Node) Node { 264 return node.(*SelectStmt).Fields.Fields[0].Expr 265 } 266 RunNodeRestoreTest(c, testCases, "select %s", extractNodeFunc) 267 } 268 269 func (tc *testExpressionsSuite) TestValuesExpr(c *C) { 270 testCases := []NodeRestoreTestCase{ 271 {"values(a)", "VALUES(`a`)"}, 272 {"values(a)+values(b)", "VALUES(`a`)+VALUES(`b`)"}, 273 } 274 extractNodeFunc := func(node Node) Node { 275 return node.(*InsertStmt).OnDuplicate[0].Expr 276 } 277 RunNodeRestoreTest(c, testCases, "insert into t values (1,2,3) on duplicate key update c=%s", extractNodeFunc) 278 } 279 280 func (tc *testExpressionsSuite) TestPatternRegexpExprRestore(c *C) { 281 testCases := []NodeRestoreTestCase{ 282 {"a regexp 't1'", "`a` REGEXP 't1'"}, 283 {"a regexp '^[abc][0-9]{11}|ok$'", "`a` REGEXP '^[abc][0-9]{11}|ok$'"}, 284 {"a rlike 't1'", "`a` REGEXP 't1'"}, 285 {"a rlike '^[abc][0-9]{11}|ok$'", "`a` REGEXP '^[abc][0-9]{11}|ok$'"}, 286 {"a not regexp 't1'", "`a` NOT REGEXP 't1'"}, 287 {"a not regexp '^[abc][0-9]{11}|ok$'", "`a` NOT REGEXP '^[abc][0-9]{11}|ok$'"}, 288 {"a not rlike 't1'", "`a` NOT REGEXP 't1'"}, 289 {"a not rlike '^[abc][0-9]{11}|ok$'", "`a` NOT REGEXP '^[abc][0-9]{11}|ok$'"}, 290 } 291 extractNodeFunc := func(node Node) Node { 292 return node.(*SelectStmt).Fields.Fields[0].Expr 293 } 294 RunNodeRestoreTest(c, testCases, "select %s", extractNodeFunc) 295 } 296 297 func (tc *testExpressionsSuite) TestRowExprRestore(c *C) { 298 testCases := []NodeRestoreTestCase{ 299 {"(1,2)", "ROW(1,2)"}, 300 {"(col1,col2)", "ROW(`col1`,`col2`)"}, 301 {"row(1,2)", "ROW(1,2)"}, 302 {"row(col1,col2)", "ROW(`col1`,`col2`)"}, 303 } 304 extractNodeFunc := func(node Node) Node { 305 return node.(*SelectStmt).Where.(*BinaryOperationExpr).L 306 } 307 RunNodeRestoreTest(c, testCases, "select 1 from t1 where %s = row(1,2)", extractNodeFunc) 308 } 309 310 func (tc *testExpressionsSuite) TestMaxValueExprRestore(c *C) { 311 testCases := []NodeRestoreTestCase{ 312 {"maxvalue", "MAXVALUE"}, 313 } 314 extractNodeFunc := func(node Node) Node { 315 return node.(*AlterTableStmt).Specs[0].PartDefinitions[0].LessThan[0] 316 } 317 RunNodeRestoreTest(c, testCases, "alter table posts add partition ( partition p1 values less than %s)", extractNodeFunc) 318 } 319 320 func (tc *testExpressionsSuite) TestPositionExprRestore(c *C) { 321 testCases := []NodeRestoreTestCase{ 322 {"1", "1"}, 323 } 324 extractNodeFunc := func(node Node) Node { 325 return node.(*SelectStmt).OrderBy.Items[0] 326 } 327 RunNodeRestoreTest(c, testCases, "select * from t order by %s", extractNodeFunc) 328 329 } 330 331 func (tc *testExpressionsSuite) TestExistsSubqueryExprRestore(c *C) { 332 testCases := []NodeRestoreTestCase{ 333 {"EXISTS (SELECT 2)", "EXISTS (SELECT 2)"}, 334 {"NOT EXISTS (SELECT 2)", "NOT EXISTS (SELECT 2)"}, 335 } 336 extractNodeFunc := func(node Node) Node { 337 return node.(*SelectStmt).Where 338 } 339 RunNodeRestoreTest(c, testCases, "select 1 from t1 where %s", extractNodeFunc) 340 } 341 342 func (tc *testExpressionsSuite) TestVariableExpr(c *C) { 343 testCases := []NodeRestoreTestCase{ 344 {"@a>1", "@`a`>1"}, 345 {"@`aB`+1", "@`aB`+1"}, 346 {"@'a':=1", "@`a`:=1"}, 347 {"@`a``b`=4", "@`a``b`=4"}, 348 {`@"aBC">1`, "@`aBC`>1"}, 349 {"@`a`+1", "@`a`+1"}, 350 {"@``", "@``"}, 351 {"@", "@``"}, 352 {"@@``", "@@``"}, 353 {"@@", "@@``"}, 354 {"@@var", "@@`var`"}, 355 {"@@global.b='foo'", "@@GLOBAL.`b`='foo'"}, 356 {"@@session.'C'", "@@SESSION.`c`"}, 357 {`@@local."aBc"`, "@@SESSION.`abc`"}, 358 } 359 extractNodeFunc := func(node Node) Node { 360 return node.(*SelectStmt).Fields.Fields[0].Expr 361 } 362 RunNodeRestoreTest(c, testCases, "select %s", extractNodeFunc) 363 }