github.com/wfusion/gofusion@v1.1.14/common/utils/sqlparser/parser_test.go (about) 1 package sqlparser_test 2 3 import ( 4 "strings" 5 "testing" 6 7 "github.com/go-test/deep" 8 "github.com/wfusion/gofusion/common/utils/sqlparser" 9 ) 10 11 func TestParser_ParseStatement(t *testing.T) { 12 t.Run("ErrNoStatement", func(t *testing.T) { 13 AssertParseStatementError(t, `123`, `1:1: expected statement, found 123`) 14 }) 15 16 t.Run("Select", func(t *testing.T) { 17 AssertParseStatement(t, `SELECT * FROM tbl`, &sqlparser.SelectStatement{ 18 Columns: &sqlparser.OutputNames{&sqlparser.ResultColumn{ 19 Star: true, 20 }}, 21 FromItems: &sqlparser.TableName{ 22 Name: &sqlparser.Ident{Name: "tbl"}, 23 }, 24 }) 25 26 AssertParseStatement(t, `SELECT /* hint */ * FROM tbl`, &sqlparser.SelectStatement{ 27 Columns: &sqlparser.OutputNames{&sqlparser.ResultColumn{ 28 Star: true, 29 }}, 30 FromItems: &sqlparser.TableName{ 31 Name: &sqlparser.Ident{Name: "tbl"}, 32 }, 33 Hint: &sqlparser.Hint{ 34 Value: "hint", 35 }, 36 }) 37 38 AssertParseStatement(t, `SELECT DISTINCT * FROM tbl`, &sqlparser.SelectStatement{ 39 Distinct: true, 40 Columns: &sqlparser.OutputNames{&sqlparser.ResultColumn{ 41 Star: true, 42 }}, 43 FromItems: &sqlparser.TableName{ 44 Name: &sqlparser.Ident{Name: "tbl"}, 45 }, 46 }) 47 48 AssertParseStatement(t, `SELECT ALL * FROM tbl`, &sqlparser.SelectStatement{ 49 All: true, 50 Columns: &sqlparser.OutputNames{&sqlparser.ResultColumn{ 51 Star: true, 52 }}, 53 FromItems: &sqlparser.TableName{ 54 Name: &sqlparser.Ident{Name: "tbl"}, 55 }, 56 }) 57 58 AssertParseStatement(t, `SELECT foo AS FOO, bar baz, tbl.* FROM tbl`, &sqlparser.SelectStatement{ 59 Columns: &sqlparser.OutputNames{ 60 &sqlparser.ResultColumn{ 61 Expr: &sqlparser.Ident{Name: "foo"}, 62 Alias: &sqlparser.Ident{Name: "FOO"}, 63 }, 64 &sqlparser.ResultColumn{ 65 Expr: &sqlparser.Ident{Name: "bar"}, 66 Alias: &sqlparser.Ident{Name: "baz"}, 67 }, 68 &sqlparser.ResultColumn{ 69 Expr: &sqlparser.QualifiedRef{ 70 Table: &sqlparser.Ident{Name: "tbl"}, 71 Star: true, 72 }, 73 }, 74 }, 75 FromItems: &sqlparser.TableName{ 76 Name: &sqlparser.Ident{Name: "tbl"}, 77 }, 78 }) 79 AssertParseStatement(t, `SELECT * FROM tbl tbl2`, &sqlparser.SelectStatement{ 80 Columns: &sqlparser.OutputNames{&sqlparser.ResultColumn{ 81 Star: true, 82 }}, 83 FromItems: &sqlparser.TableName{ 84 Name: &sqlparser.Ident{Name: "tbl"}, 85 Alias: &sqlparser.Ident{Name: "tbl2"}, 86 }, 87 }) 88 AssertParseStatement(t, `SELECT * FROM tbl AS tbl2`, &sqlparser.SelectStatement{ 89 Columns: &sqlparser.OutputNames{&sqlparser.ResultColumn{ 90 Star: true, 91 }}, 92 FromItems: &sqlparser.TableName{ 93 Name: &sqlparser.Ident{Name: "tbl"}, 94 Alias: &sqlparser.Ident{Name: "tbl2"}, 95 }, 96 }) 97 98 AssertParseStatement(t, `SELECT * FROM (SELECT *) AS tbl`, &sqlparser.SelectStatement{ 99 Columns: &sqlparser.OutputNames{&sqlparser.ResultColumn{ 100 Star: true, 101 }}, 102 FromItems: &sqlparser.ParenSource{ 103 X: &sqlparser.SelectStatement{ 104 Columns: &sqlparser.OutputNames{&sqlparser.ResultColumn{ 105 Star: true, 106 }}, 107 }, 108 Alias: &sqlparser.Ident{Name: "tbl"}, 109 }, 110 }) 111 112 AssertParseStatement(t, `SELECT * FROM foo, bar`, &sqlparser.SelectStatement{ 113 Columns: &sqlparser.OutputNames{&sqlparser.ResultColumn{ 114 Star: true, 115 }}, 116 FromItems: &sqlparser.JoinClause{ 117 X: &sqlparser.TableName{ 118 Name: &sqlparser.Ident{Name: "foo"}, 119 }, 120 Operator: &sqlparser.JoinOperator{Comma: true}, 121 Y: &sqlparser.TableName{ 122 Name: &sqlparser.Ident{Name: "bar"}, 123 }, 124 }, 125 }) 126 AssertParseStatement(t, `SELECT * FROM foo JOIN bar`, &sqlparser.SelectStatement{ 127 Columns: &sqlparser.OutputNames{&sqlparser.ResultColumn{ 128 Star: true, 129 }}, 130 FromItems: &sqlparser.JoinClause{ 131 X: &sqlparser.TableName{ 132 Name: &sqlparser.Ident{Name: "foo"}, 133 }, 134 Operator: &sqlparser.JoinOperator{}, 135 Y: &sqlparser.TableName{ 136 Name: &sqlparser.Ident{Name: "bar"}, 137 }, 138 }, 139 }) 140 AssertParseStatement(t, `SELECT * FROM foo NATURAL JOIN bar`, &sqlparser.SelectStatement{ 141 Columns: &sqlparser.OutputNames{&sqlparser.ResultColumn{ 142 Star: true, 143 }}, 144 FromItems: &sqlparser.JoinClause{ 145 X: &sqlparser.TableName{ 146 Name: &sqlparser.Ident{Name: "foo"}, 147 }, 148 Operator: &sqlparser.JoinOperator{Natural: true}, 149 Y: &sqlparser.TableName{ 150 Name: &sqlparser.Ident{Name: "bar"}, 151 }, 152 }, 153 }) 154 AssertParseStatement(t, `SELECT * FROM foo INNER JOIN bar ON true`, &sqlparser.SelectStatement{ 155 Columns: &sqlparser.OutputNames{&sqlparser.ResultColumn{ 156 Star: true, 157 }}, 158 FromItems: &sqlparser.JoinClause{ 159 X: &sqlparser.TableName{ 160 Name: &sqlparser.Ident{Name: "foo"}, 161 }, 162 Operator: &sqlparser.JoinOperator{Inner: true}, 163 Y: &sqlparser.TableName{ 164 Name: &sqlparser.Ident{Name: "bar"}, 165 }, 166 Constraint: &sqlparser.OnConstraint{ 167 X: &sqlparser.BoolLit{Value: true}, 168 }, 169 }, 170 }) 171 AssertParseStatement(t, `SELECT * FROM foo LEFT JOIN bar USING (x, y)`, &sqlparser.SelectStatement{ 172 Columns: &sqlparser.OutputNames{&sqlparser.ResultColumn{ 173 Star: true, 174 }}, 175 FromItems: &sqlparser.JoinClause{ 176 X: &sqlparser.TableName{ 177 Name: &sqlparser.Ident{Name: "foo"}, 178 }, 179 Operator: &sqlparser.JoinOperator{Left: true}, 180 Y: &sqlparser.TableName{ 181 Name: &sqlparser.Ident{Name: "bar"}, 182 }, 183 Constraint: &sqlparser.UsingConstraint{ 184 Columns: []*sqlparser.Ident{ 185 {Name: "x"}, 186 {Name: "y"}, 187 }, 188 }, 189 }, 190 }) 191 AssertParseStatement(t, `SELECT * FROM X INNER JOIN Y ON true INNER JOIN Z ON false`, &sqlparser.SelectStatement{ 192 Columns: &sqlparser.OutputNames{&sqlparser.ResultColumn{ 193 Star: true, 194 }}, 195 FromItems: &sqlparser.JoinClause{ 196 X: &sqlparser.TableName{ 197 Name: &sqlparser.Ident{Name: "X"}, 198 }, 199 Operator: &sqlparser.JoinOperator{Inner: true}, 200 Y: &sqlparser.JoinClause{ 201 X: &sqlparser.TableName{ 202 Name: &sqlparser.Ident{Name: "Y"}, 203 }, 204 Operator: &sqlparser.JoinOperator{Inner: true}, 205 Y: &sqlparser.TableName{ 206 Name: &sqlparser.Ident{Name: "Z"}, 207 }, 208 Constraint: &sqlparser.OnConstraint{ 209 X: &sqlparser.BoolLit{Value: false}, 210 }, 211 }, 212 Constraint: &sqlparser.OnConstraint{ 213 X: &sqlparser.BoolLit{Value: true}, 214 }, 215 }, 216 }) 217 AssertParseStatement(t, `SELECT * FROM foo LEFT OUTER JOIN bar`, &sqlparser.SelectStatement{ 218 Columns: &sqlparser.OutputNames{&sqlparser.ResultColumn{ 219 Star: true, 220 }}, 221 FromItems: &sqlparser.JoinClause{ 222 X: &sqlparser.TableName{ 223 Name: &sqlparser.Ident{Name: "foo"}, 224 }, 225 Operator: &sqlparser.JoinOperator{Left: true, Outer: true}, 226 Y: &sqlparser.TableName{ 227 Name: &sqlparser.Ident{Name: "bar"}, 228 }, 229 }, 230 }) 231 AssertParseStatement(t, `SELECT * FROM foo CROSS JOIN bar`, &sqlparser.SelectStatement{ 232 Columns: &sqlparser.OutputNames{&sqlparser.ResultColumn{ 233 Star: true, 234 }}, 235 FromItems: &sqlparser.JoinClause{ 236 X: &sqlparser.TableName{ 237 Name: &sqlparser.Ident{Name: "foo"}, 238 }, 239 Operator: &sqlparser.JoinOperator{Cross: true}, 240 Y: &sqlparser.TableName{ 241 Name: &sqlparser.Ident{Name: "bar"}, 242 }, 243 }, 244 }) 245 246 AssertParseStatement(t, `SELECT * WHERE true`, &sqlparser.SelectStatement{ 247 Columns: &sqlparser.OutputNames{&sqlparser.ResultColumn{Star: true}}, 248 Condition: &sqlparser.BoolLit{Value: true}, 249 }) 250 251 AssertParseStatement(t, `SELECT * GROUP BY foo, bar`, &sqlparser.SelectStatement{ 252 Columns: &sqlparser.OutputNames{&sqlparser.ResultColumn{Star: true}}, 253 GroupingElements: []sqlparser.Expr{ 254 &sqlparser.Ident{Name: "foo"}, 255 &sqlparser.Ident{Name: "bar"}, 256 }, 257 }) 258 AssertParseStatement(t, `SELECT * GROUP BY foo HAVING true`, &sqlparser.SelectStatement{ 259 Columns: &sqlparser.OutputNames{&sqlparser.ResultColumn{Star: true}}, 260 GroupingElements: []sqlparser.Expr{ 261 &sqlparser.Ident{Name: "foo"}, 262 }, 263 HavingCondition: &sqlparser.BoolLit{Value: true}, 264 }) 265 266 AssertParseStatement(t, `SELECT * ORDER BY foo ASC, bar DESC`, &sqlparser.SelectStatement{ 267 Columns: &sqlparser.OutputNames{&sqlparser.ResultColumn{ 268 Star: true, 269 }}, 270 OrderBy: []*sqlparser.OrderingTerm{ 271 {X: &sqlparser.Ident{Name: "foo"}, Asc: true}, 272 {X: &sqlparser.Ident{Name: "bar"}, Desc: true}, 273 }, 274 }) 275 276 AssertParseStatement(t, `SELECT * LIMIT 1`, &sqlparser.SelectStatement{ 277 Columns: &sqlparser.OutputNames{&sqlparser.ResultColumn{ 278 Star: true, 279 }}, 280 Limit: &sqlparser.NumberLit{Value: "1"}, 281 }) 282 AssertParseStatement(t, `SELECT * LIMIT 1 OFFSET 2`, &sqlparser.SelectStatement{ 283 Columns: &sqlparser.OutputNames{&sqlparser.ResultColumn{ 284 Star: true, 285 }}, 286 Limit: &sqlparser.NumberLit{Value: "1"}, 287 Offset: &sqlparser.NumberLit{Value: "2"}, 288 }) 289 AssertParseStatement(t, `SELECT * LIMIT 1, 2`, &sqlparser.SelectStatement{ 290 Columns: &sqlparser.OutputNames{&sqlparser.ResultColumn{ 291 Star: true, 292 }}, 293 Limit: &sqlparser.NumberLit{Value: "1"}, 294 Offset: &sqlparser.NumberLit{Value: "2"}, 295 }) 296 AssertParseStatement(t, `SELECT * UNION SELECT * ORDER BY foo`, &sqlparser.SelectStatement{ 297 Columns: &sqlparser.OutputNames{&sqlparser.ResultColumn{ 298 Star: true, 299 }}, 300 Union: true, 301 Compound: &sqlparser.SelectStatement{ 302 Columns: &sqlparser.OutputNames{&sqlparser.ResultColumn{ 303 Star: true, 304 }}, 305 }, 306 OrderBy: []*sqlparser.OrderingTerm{ 307 {X: &sqlparser.Ident{Name: "foo"}}, 308 }, 309 }) 310 AssertParseStatement(t, `SELECT * UNION ALL SELECT *`, &sqlparser.SelectStatement{ 311 Columns: &sqlparser.OutputNames{&sqlparser.ResultColumn{ 312 Star: true, 313 }}, 314 Union: true, 315 UnionAll: true, 316 Compound: &sqlparser.SelectStatement{ 317 Columns: &sqlparser.OutputNames{&sqlparser.ResultColumn{ 318 Star: true, 319 }}, 320 }, 321 }) 322 AssertParseStatement(t, `SELECT * INTERSECT SELECT *`, &sqlparser.SelectStatement{ 323 Columns: &sqlparser.OutputNames{&sqlparser.ResultColumn{ 324 Star: true, 325 }}, 326 Intersect: true, 327 Compound: &sqlparser.SelectStatement{ 328 Columns: &sqlparser.OutputNames{&sqlparser.ResultColumn{ 329 Star: true, 330 }}, 331 }, 332 }) 333 AssertParseStatement(t, `SELECT * EXCEPT SELECT *`, &sqlparser.SelectStatement{ 334 Columns: &sqlparser.OutputNames{&sqlparser.ResultColumn{ 335 Star: true, 336 }}, 337 Except: true, 338 Compound: &sqlparser.SelectStatement{ 339 Columns: &sqlparser.OutputNames{&sqlparser.ResultColumn{ 340 Star: true, 341 }}, 342 }, 343 }) 344 345 AssertParseStatementError(t, `SELECT `, `1:7: expected expression, found 'EOF'`) 346 AssertParseStatementError(t, `SELECT 1+`, `1:9: expected expression, found 'EOF'`) 347 AssertParseStatementError(t, `SELECT foo,`, `1:11: expected expression, found 'EOF'`) 348 AssertParseStatementError(t, `SELECT foo AS`, `1:13: expected column alias, found 'EOF'`) 349 AssertParseStatementError(t, `SELECT foo.* AS`, `1:14: expected semicolon or EOF, found 'AS'`) 350 AssertParseStatementError(t, `SELECT foo FROM`, `1:15: expected table name or left paren, found 'EOF'`) 351 AssertParseStatementError(t, `SELECT * FROM foo INNER`, `1:23: expected JOIN, found 'EOF'`) 352 AssertParseStatementError(t, `SELECT * FROM foo CROSS`, `1:23: expected JOIN, found 'EOF'`) 353 AssertParseStatementError(t, `SELECT * FROM foo NATURAL`, `1:25: expected JOIN, found 'EOF'`) 354 AssertParseStatementError(t, `SELECT * FROM foo LEFT`, `1:22: expected JOIN, found 'EOF'`) 355 AssertParseStatementError(t, `SELECT * FROM foo LEFT OUTER`, `1:28: expected JOIN, found 'EOF'`) 356 AssertParseStatementError(t, `SELECT * FROM foo,`, `1:18: expected table name or left paren, found 'EOF'`) 357 AssertParseStatementError(t, `SELECT * FROM foo JOIN bar ON`, `1:29: expected expression, found 'EOF'`) 358 AssertParseStatementError(t, `SELECT * FROM foo JOIN bar USING`, `1:32: expected left paren, found 'EOF'`) 359 AssertParseStatementError(t, `SELECT * FROM foo JOIN bar USING (`, `1:34: expected column name, found 'EOF'`) 360 AssertParseStatementError(t, `SELECT * FROM foo JOIN bar USING (x`, `1:35: expected comma or right paren, found 'EOF'`) 361 AssertParseStatementError(t, `SELECT * FROM foo JOIN bar USING (x,`, `1:36: expected column name, found 'EOF'`) 362 AssertParseStatementError(t, `SELECT * FROM (`, `1:15: expected table name or left paren, found 'EOF'`) 363 AssertParseStatementError(t, `SELECT * FROM ((`, `1:16: expected table name or left paren, found 'EOF'`) 364 AssertParseStatementError(t, `SELECT * FROM (SELECT`, `1:21: expected expression, found 'EOF'`) 365 AssertParseStatementError(t, `SELECT * FROM (tbl`, `1:18: expected right paren, found 'EOF'`) 366 AssertParseStatementError(t, `SELECT * FROM (SELECT *) AS`, `1:27: expected table alias, found 'EOF'`) 367 AssertParseStatementError(t, `SELECT * FROM foo AS`, `1:20: expected table alias, found 'EOF'`) 368 AssertParseStatementError(t, `SELECT foo WHERE`, `1:16: expected expression, found 'EOF'`) 369 AssertParseStatementError(t, `SELECT * GROUP`, `1:14: expected BY, found 'EOF'`) 370 AssertParseStatementError(t, `SELECT * GROUP BY`, `1:17: expected expression, found 'EOF'`) 371 AssertParseStatementError(t, `SELECT * GROUP BY foo bar`, `1:23: expected semicolon or EOF, found bar`) 372 AssertParseStatementError(t, `SELECT * GROUP BY foo HAVING`, `1:28: expected expression, found 'EOF'`) 373 AssertParseStatementError(t, `SELECT * ORDER`, `1:14: expected BY, found 'EOF'`) 374 AssertParseStatementError(t, `SELECT * ORDER BY`, `1:17: expected expression, found 'EOF'`) 375 AssertParseStatementError(t, `SELECT * ORDER BY 1,`, `1:20: expected expression, found 'EOF'`) 376 AssertParseStatementError(t, `SELECT * LIMIT`, `1:14: expected expression, found 'EOF'`) 377 AssertParseStatementError(t, `SELECT * LIMIT 1,`, `1:17: expected expression, found 'EOF'`) 378 AssertParseStatementError(t, `SELECT * LIMIT 1 OFFSET`, `1:23: expected expression, found 'EOF'`) 379 AssertParseStatementError(t, `SELECT * UNION`, `1:14: expected SELECT, found 'EOF'`) 380 }) 381 382 t.Run("Insert", func(t *testing.T) { 383 AssertParseStatement(t, `INSERT INTO tbl (x, y) VALUES (1, 2)`, &sqlparser.InsertStatement{ 384 TableName: &sqlparser.TableName{Name: &sqlparser.Ident{Name: "tbl"}}, 385 ColumnNames: []*sqlparser.Ident{ 386 {Name: "x"}, 387 {Name: "y"}, 388 }, 389 Expressions: []*sqlparser.Exprs{{ 390 Exprs: []sqlparser.Expr{ 391 &sqlparser.NumberLit{Value: "1"}, 392 &sqlparser.NumberLit{Value: "2"}, 393 }, 394 }}, 395 }) 396 397 AssertParseStatement(t, `INSERT INTO tbl (x) SELECT y`, &sqlparser.InsertStatement{ 398 TableName: &sqlparser.TableName{Name: &sqlparser.Ident{Name: "tbl"}}, 399 ColumnNames: []*sqlparser.Ident{{Name: "x"}}, 400 Query: &sqlparser.SelectStatement{ 401 Columns: &sqlparser.OutputNames{&sqlparser.ResultColumn{ 402 Expr: &sqlparser.Ident{Name: "y"}, 403 }}, 404 }, 405 }) 406 407 AssertParseStatement(t, `INSERT INTO tbl (x) DEFAULT VALUES`, &sqlparser.InsertStatement{ 408 TableName: &sqlparser.TableName{Name: &sqlparser.Ident{Name: "tbl"}}, 409 ColumnNames: []*sqlparser.Ident{{Name: "x"}}, 410 DefaultValues: true, 411 }) 412 413 AssertParseStatement(t, `INSERT INTO tbl AS tbl2 (x) DEFAULT VALUES`, &sqlparser.InsertStatement{ 414 TableName: &sqlparser.TableName{ 415 Name: &sqlparser.Ident{Name: "tbl"}, 416 Alias: &sqlparser.Ident{Name: "tbl2"}, 417 }, 418 ColumnNames: []*sqlparser.Ident{{Name: "x"}}, 419 DefaultValues: true, 420 }) 421 422 AssertParseStatement(t, `INSERT INTO tbl (x) VALUES (1) ON CONFLICT (y ASC, z DESC) DO NOTHING`, &sqlparser.InsertStatement{ 423 TableName: &sqlparser.TableName{Name: &sqlparser.Ident{Name: "tbl"}}, 424 ColumnNames: []*sqlparser.Ident{{Name: "x"}}, 425 Expressions: []*sqlparser.Exprs{{ 426 Exprs: []sqlparser.Expr{ 427 &sqlparser.NumberLit{Value: "1"}, 428 }, 429 }}, 430 UpsertClause: &sqlparser.UpsertClause{ 431 Columns: []*sqlparser.IndexedColumn{ 432 {X: &sqlparser.Ident{Name: "y"}, Asc: true}, 433 {X: &sqlparser.Ident{Name: "z"}, Desc: true}, 434 }, 435 DoNothing: true, 436 }, 437 }) 438 AssertParseStatement(t, `INSERT INTO tbl (x) VALUES (1) ON CONFLICT (y) WHERE true DO UPDATE SET foo = 1, (bar, baz) = 2 WHERE false`, &sqlparser.InsertStatement{ 439 TableName: &sqlparser.TableName{Name: &sqlparser.Ident{Name: "tbl"}}, 440 ColumnNames: []*sqlparser.Ident{{Name: "x"}}, 441 Expressions: []*sqlparser.Exprs{{ 442 Exprs: []sqlparser.Expr{ 443 &sqlparser.NumberLit{Value: "1"}, 444 }, 445 }}, 446 UpsertClause: &sqlparser.UpsertClause{ 447 Columns: []*sqlparser.IndexedColumn{ 448 {X: &sqlparser.Ident{Name: "y"}}, 449 }, 450 WhereExpr: &sqlparser.BoolLit{Value: true}, 451 DoUpdate: true, 452 Assignments: []*sqlparser.Assignment{ 453 { 454 Columns: []*sqlparser.Ident{ 455 {Name: "foo"}, 456 }, 457 Expr: &sqlparser.NumberLit{Value: "1"}, 458 }, 459 { 460 Columns: []*sqlparser.Ident{ 461 {Name: "bar"}, 462 {Name: "baz"}, 463 }, 464 Expr: &sqlparser.NumberLit{Value: "2"}, 465 }, 466 }, 467 UpdateWhereExpr: &sqlparser.BoolLit{Value: false}, 468 }, 469 }) 470 471 AssertParseStatementError(t, `INSERT`, `1:6: expected INTO, found 'EOF'`) 472 AssertParseStatementError(t, `INSERT INTO`, `1:11: expected table name, found 'EOF'`) 473 AssertParseStatementError(t, `INSERT INTO tbl AS`, `1:18: expected table alias, found 'EOF'`) 474 AssertParseStatementError(t, `INSERT INTO tbl `, `1:16: expected DEFAULT VALUES, VALUES or SELECT, found 'EOF'`) 475 AssertParseStatementError(t, `INSERT INTO tbl (`, `1:17: expected column name, found 'EOF'`) 476 AssertParseStatementError(t, `INSERT INTO tbl (x`, `1:18: expected comma or right paren, found 'EOF'`) 477 AssertParseStatementError(t, `INSERT INTO tbl (x)`, `1:19: expected DEFAULT VALUES, VALUES or SELECT, found 'EOF'`) 478 AssertParseStatementError(t, `INSERT INTO tbl (x) VALUES`, `1:26: expected left paren, found 'EOF'`) 479 AssertParseStatementError(t, `INSERT INTO tbl (x) VALUES (`, `1:28: expected expression, found 'EOF'`) 480 AssertParseStatementError(t, `INSERT INTO tbl (x) VALUES (1`, `1:29: expected comma or right paren, found 'EOF'`) 481 AssertParseStatementError(t, `INSERT INTO tbl (x) SELECT`, `1:26: expected expression, found 'EOF'`) 482 AssertParseStatementError(t, `INSERT INTO tbl (x) DEFAULT`, `1:27: expected VALUES, found 'EOF'`) 483 AssertParseStatementError(t, `INSERT INTO tbl (x) VALUES (1) ON`, `1:33: expected CONFLICT, found 'EOF'`) 484 AssertParseStatementError(t, `INSERT INTO tbl (x) VALUES (1) ON CONFLICT (`, `1:44: expected expression, found 'EOF'`) 485 AssertParseStatementError(t, `INSERT INTO tbl (x) VALUES (1) ON CONFLICT (x`, `1:45: expected comma or right paren, found 'EOF'`) 486 AssertParseStatementError(t, `INSERT INTO tbl (x) VALUES (1) ON CONFLICT (x) WHERE`, `1:52: expected expression, found 'EOF'`) 487 AssertParseStatementError(t, `INSERT INTO tbl (x) VALUES (1) ON CONFLICT (x)`, `1:46: expected DO, found 'EOF'`) 488 AssertParseStatementError(t, `INSERT INTO tbl (x) VALUES (1) ON CONFLICT (x) DO`, `1:49: expected NOTHING or UPDATE SET, found 'EOF'`) 489 AssertParseStatementError(t, `INSERT INTO tbl (x) VALUES (1) ON CONFLICT (x) DO UPDATE`, `1:56: expected SET, found 'EOF'`) 490 AssertParseStatementError(t, `INSERT INTO tbl (x) VALUES (1) ON CONFLICT (x) DO UPDATE SET foo`, `1:64: expected =, found 'EOF'`) 491 AssertParseStatementError(t, `INSERT INTO tbl (x) VALUES (1) ON CONFLICT (x) DO UPDATE SET foo =`, `1:66: expected expression, found 'EOF'`) 492 AssertParseStatementError(t, `INSERT INTO tbl (x) VALUES (1) ON CONFLICT (x) DO UPDATE SET foo = 1 WHERE`, `1:74: expected expression, found 'EOF'`) 493 AssertParseStatementError(t, `INSERT INTO tbl (x) VALUES (1) ON CONFLICT (x) DO UPDATE SET (`, `1:62: expected column name, found 'EOF'`) 494 AssertParseStatementError(t, `INSERT INTO tbl (x) VALUES (1) ON CONFLICT (x) DO UPDATE SET (foo`, `1:65: expected comma or right paren, found 'EOF'`) 495 AssertParseStatementError(t, `INSERT INTO tbl (x) VALUES (1) RETURNING`, `1:40: expected expression, found 'EOF'`) 496 }) 497 498 t.Run("Update", func(t *testing.T) { 499 AssertParseStatement(t, `UPDATE tbl SET x = 1, y = 2`, &sqlparser.UpdateStatement{ 500 TableName: &sqlparser.TableName{ 501 Name: &sqlparser.Ident{Name: "tbl"}, 502 }, 503 Assignments: []*sqlparser.Assignment{ 504 { 505 Columns: []*sqlparser.Ident{{Name: "x"}}, 506 Expr: &sqlparser.NumberLit{Value: "1"}, 507 }, 508 { 509 Columns: []*sqlparser.Ident{{Name: "y"}}, 510 Expr: &sqlparser.NumberLit{Value: "2"}, 511 }, 512 }, 513 }) 514 AssertParseStatement(t, `UPDATE tbl SET x = 1 WHERE y = 2`, &sqlparser.UpdateStatement{ 515 TableName: &sqlparser.TableName{ 516 Name: &sqlparser.Ident{Name: "tbl"}, 517 }, 518 Assignments: []*sqlparser.Assignment{{ 519 Columns: []*sqlparser.Ident{{Name: "x"}}, 520 Expr: &sqlparser.NumberLit{Value: "1"}, 521 }}, 522 Condition: &sqlparser.BinaryExpr{ 523 X: &sqlparser.Ident{Name: "y"}, 524 Op: sqlparser.EQ, 525 Y: &sqlparser.NumberLit{Value: "2"}, 526 }, 527 }) 528 529 AssertParseStatementError(t, `UPDATE`, `1:6: expected table name, found 'EOF'`) 530 AssertParseStatementError(t, `UPDATE tbl`, `1:10: expected SET, found 'EOF'`) 531 AssertParseStatementError(t, `UPDATE tbl SET`, `1:14: expected column name or column list, found 'EOF'`) 532 AssertParseStatementError(t, `UPDATE tbl SET x = `, `1:19: expected expression, found 'EOF'`) 533 AssertParseStatementError(t, `UPDATE tbl SET x = 1 WHERE`, `1:26: expected expression, found 'EOF'`) 534 AssertParseStatementError(t, `UPDATE tbl SET x = 1 WHERE y =`, `1:30: expected expression, found 'EOF'`) 535 }) 536 537 t.Run("Delete", func(t *testing.T) { 538 AssertParseStatement(t, `DELETE FROM tbl`, &sqlparser.DeleteStatement{ 539 TableName: &sqlparser.TableName{ 540 Name: &sqlparser.Ident{Name: "tbl"}, 541 }, 542 }) 543 AssertParseStatement(t, `DELETE FROM tbl WHERE x = 1`, &sqlparser.DeleteStatement{ 544 TableName: &sqlparser.TableName{ 545 Name: &sqlparser.Ident{Name: "tbl"}, 546 }, 547 Condition: &sqlparser.BinaryExpr{ 548 X: &sqlparser.Ident{Name: "x"}, 549 Op: sqlparser.EQ, 550 Y: &sqlparser.NumberLit{Value: "1"}, 551 }, 552 }) 553 AssertParseStatement(t, `DELETE FROM ONLY tbl`, &sqlparser.DeleteStatement{ 554 Only: true, 555 TableName: &sqlparser.TableName{ 556 Name: &sqlparser.Ident{Name: "tbl"}, 557 }, 558 }) 559 /* 560 AssertParseStatement(t, `DELETE FROM tbl USING tbl2, tbl3`, &sqlparser.DeleteStatement{ 561 TableName: &sqlparser.TableName{ 562 Name: &sqlparser.Ident{Name: "tbl"}, 563 }, 564 UsingList: []*sqlparser.TableName{ 565 &sqlparser.TableName{ 566 Name: &sqlparser.Ident{Name: "tbl"}, 567 }, 568 &sqlparser.TableName{ 569 Name: &sqlparser.Ident{Name: "tbl"}, 570 }, 571 }, 572 })*/ 573 AssertParseStatement(t, `DELETE FROM tbl WHERE CURRENT OF c_tasks`, &sqlparser.DeleteStatement{ 574 TableName: &sqlparser.TableName{ 575 Name: &sqlparser.Ident{Name: "tbl"}, 576 }, 577 CursorName: &sqlparser.Ident{Name: "c_tasks"}, 578 }) 579 580 AssertParseStatementError(t, `DELETE FROM`, `1:11: expected table name, found 'EOF'`) 581 AssertParseStatementError(t, `DELETE FROM tbl WHERE`, `1:21: expected expression, found 'EOF'`) 582 }) 583 } 584 585 func TestParser_ParseExpr(t *testing.T) { 586 t.Run("Ident", func(t *testing.T) { 587 AssertParseExpr(t, `fooBAR_123'`, &sqlparser.Ident{Name: `fooBAR_123`}) 588 }) 589 t.Run("StringLit", func(t *testing.T) { 590 AssertParseExpr(t, `'foo bar'`, &sqlparser.StringLit{Value: `foo bar`}) 591 }) 592 t.Run("BlobLit", func(t *testing.T) { 593 AssertParseExpr(t, `x'0123'`, &sqlparser.BlobLit{Value: `0123`}) 594 }) 595 t.Run("Integer", func(t *testing.T) { 596 AssertParseExpr(t, `123`, &sqlparser.NumberLit{Value: `123`}) 597 }) 598 t.Run("Float", func(t *testing.T) { 599 AssertParseExpr(t, `123.456`, &sqlparser.NumberLit{Value: `123.456`}) 600 }) 601 t.Run("Null", func(t *testing.T) { 602 AssertParseExpr(t, `NULL`, &sqlparser.NullLit{}) 603 }) 604 t.Run("Bool", func(t *testing.T) { 605 AssertParseExpr(t, `true`, &sqlparser.BoolLit{Value: true}) 606 AssertParseExpr(t, `false`, &sqlparser.BoolLit{Value: false}) 607 }) 608 t.Run("Bind", func(t *testing.T) { 609 AssertParseExpr(t, `$bar`, &sqlparser.BindExpr{Name: "$bar"}) 610 }) 611 t.Run("UnaryExpr", func(t *testing.T) { 612 AssertParseExpr(t, `-123`, &sqlparser.UnaryExpr{Op: sqlparser.MINUS, X: &sqlparser.NumberLit{Value: `123`}}) 613 AssertParseExprError(t, `-`, `1:1: expected expression, found 'EOF'`) 614 }) 615 t.Run("QualifiedRef", func(t *testing.T) { 616 AssertParseExpr(t, `tbl.col`, &sqlparser.QualifiedRef{ 617 Table: &sqlparser.Ident{Name: "tbl"}, 618 Column: &sqlparser.Ident{Name: "col"}, 619 }) 620 AssertParseExpr(t, `"tbl"."col"`, &sqlparser.QualifiedRef{ 621 Table: &sqlparser.Ident{Name: "tbl", Quoted: true, QuoteChar: `"`}, 622 Column: &sqlparser.Ident{Name: "col", Quoted: true, QuoteChar: `"`}, 623 }) 624 AssertParseExpr(t, "`tbl`.`col`", &sqlparser.QualifiedRef{ 625 Table: &sqlparser.Ident{Name: "tbl", Quoted: true, QuoteChar: "`"}, 626 Column: &sqlparser.Ident{Name: "col", Quoted: true, QuoteChar: "`"}, 627 }) 628 AssertParseExprError(t, `tbl.`, `1:4: expected column name, found 'EOF'`) 629 }) 630 t.Run("Exists", func(t *testing.T) { 631 AssertParseExpr(t, `EXISTS (SELECT *)`, &sqlparser.Exists{ 632 Select: &sqlparser.SelectStatement{ 633 Columns: &sqlparser.OutputNames{&sqlparser.ResultColumn{ 634 Star: true, 635 }}, 636 }, 637 }) 638 AssertParseExpr(t, `NOT EXISTS (SELECT *)`, &sqlparser.Exists{ 639 Not: true, 640 Select: &sqlparser.SelectStatement{ 641 Columns: &sqlparser.OutputNames{&sqlparser.ResultColumn{ 642 Star: true, 643 }}, 644 }, 645 }) 646 AssertParseExprError(t, `NOT`, `1:3: expected EXISTS, found 'EOF'`) 647 AssertParseExprError(t, `EXISTS`, `1:6: expected left paren, found 'EOF'`) 648 AssertParseExprError(t, `EXISTS (`, `1:8: expected SELECT, found 'EOF'`) 649 AssertParseExprError(t, `EXISTS (SELECT`, `1:14: expected expression, found 'EOF'`) 650 AssertParseExprError(t, `EXISTS (SELECT *`, `1:16: expected right paren, found 'EOF'`) 651 }) 652 t.Run("BinaryExpr", func(t *testing.T) { 653 AssertParseExpr(t, `1 + 2'`, &sqlparser.BinaryExpr{ 654 X: &sqlparser.NumberLit{Value: "1"}, 655 Op: sqlparser.PLUS, 656 Y: &sqlparser.NumberLit{Value: "2"}, 657 }) 658 AssertParseExpr(t, `1 - 2'`, &sqlparser.BinaryExpr{ 659 X: &sqlparser.NumberLit{Value: "1"}, 660 Op: sqlparser.MINUS, 661 Y: &sqlparser.NumberLit{Value: "2"}, 662 }) 663 AssertParseExpr(t, `1 * 2'`, &sqlparser.BinaryExpr{ 664 X: &sqlparser.NumberLit{Value: "1"}, 665 Op: sqlparser.STAR, 666 Y: &sqlparser.NumberLit{Value: "2"}, 667 }) 668 AssertParseExpr(t, `1 / 2'`, &sqlparser.BinaryExpr{ 669 X: &sqlparser.NumberLit{Value: "1"}, 670 Op: sqlparser.SLASH, 671 Y: &sqlparser.NumberLit{Value: "2"}, 672 }) 673 AssertParseExpr(t, `1 % 2'`, &sqlparser.BinaryExpr{ 674 X: &sqlparser.NumberLit{Value: "1"}, 675 Op: sqlparser.REM, 676 Y: &sqlparser.NumberLit{Value: "2"}, 677 }) 678 AssertParseExpr(t, `1 || 2'`, &sqlparser.BinaryExpr{ 679 X: &sqlparser.NumberLit{Value: "1"}, 680 Op: sqlparser.CONCAT, 681 Y: &sqlparser.NumberLit{Value: "2"}, 682 }) 683 AssertParseExpr(t, `1 << 2'`, &sqlparser.BinaryExpr{ 684 X: &sqlparser.NumberLit{Value: "1"}, 685 Op: sqlparser.LSHIFT, 686 Y: &sqlparser.NumberLit{Value: "2"}, 687 }) 688 AssertParseExpr(t, `1 >> 2'`, &sqlparser.BinaryExpr{ 689 X: &sqlparser.NumberLit{Value: "1"}, 690 Op: sqlparser.RSHIFT, 691 Y: &sqlparser.NumberLit{Value: "2"}, 692 }) 693 AssertParseExpr(t, `1 & 2'`, &sqlparser.BinaryExpr{ 694 X: &sqlparser.NumberLit{Value: "1"}, 695 Op: sqlparser.BITAND, 696 Y: &sqlparser.NumberLit{Value: "2"}, 697 }) 698 AssertParseExpr(t, `1 | 2'`, &sqlparser.BinaryExpr{ 699 X: &sqlparser.NumberLit{Value: "1"}, 700 Op: sqlparser.BITOR, 701 Y: &sqlparser.NumberLit{Value: "2"}, 702 }) 703 AssertParseExpr(t, `1 < 2'`, &sqlparser.BinaryExpr{ 704 X: &sqlparser.NumberLit{Value: "1"}, 705 Op: sqlparser.LT, 706 Y: &sqlparser.NumberLit{Value: "2"}, 707 }) 708 AssertParseExpr(t, `1 <= 2'`, &sqlparser.BinaryExpr{ 709 X: &sqlparser.NumberLit{Value: "1"}, 710 Op: sqlparser.LE, 711 Y: &sqlparser.NumberLit{Value: "2"}, 712 }) 713 AssertParseExpr(t, `1 <> 2'`, &sqlparser.BinaryExpr{ 714 X: &sqlparser.NumberLit{Value: "1"}, 715 Op: sqlparser.LG, 716 Y: &sqlparser.NumberLit{Value: "2"}, 717 }) 718 AssertParseExpr(t, `1 > 2'`, &sqlparser.BinaryExpr{ 719 X: &sqlparser.NumberLit{Value: "1"}, 720 Op: sqlparser.GT, 721 Y: &sqlparser.NumberLit{Value: "2"}, 722 }) 723 AssertParseExpr(t, `1 >= 2'`, &sqlparser.BinaryExpr{ 724 X: &sqlparser.NumberLit{Value: "1"}, 725 Op: sqlparser.GE, 726 Y: &sqlparser.NumberLit{Value: "2"}, 727 }) 728 AssertParseExpr(t, `1 = 2'`, &sqlparser.BinaryExpr{ 729 X: &sqlparser.NumberLit{Value: "1"}, 730 Op: sqlparser.EQ, 731 Y: &sqlparser.NumberLit{Value: "2"}, 732 }) 733 AssertParseExpr(t, `1 != 2'`, &sqlparser.BinaryExpr{ 734 X: &sqlparser.NumberLit{Value: "1"}, 735 Op: sqlparser.NE, 736 Y: &sqlparser.NumberLit{Value: "2"}, 737 }) 738 AssertParseExpr(t, `(1 + 2)'`, &sqlparser.ParenExpr{ 739 X: &sqlparser.BinaryExpr{ 740 X: &sqlparser.NumberLit{Value: "1"}, 741 Op: sqlparser.PLUS, 742 Y: &sqlparser.NumberLit{Value: "2"}, 743 }, 744 }) 745 AssertParseExprError(t, `(`, `1:1: expected expression, found 'EOF'`) 746 AssertParseExpr(t, `1 IS 2'`, &sqlparser.BinaryExpr{ 747 X: &sqlparser.NumberLit{Value: "1"}, 748 Op: sqlparser.IS, 749 Y: &sqlparser.NumberLit{Value: "2"}, 750 }) 751 AssertParseExpr(t, `1 IS NOT 2'`, &sqlparser.BinaryExpr{ 752 X: &sqlparser.NumberLit{Value: "1"}, 753 Op: sqlparser.ISNOT, 754 Y: &sqlparser.NumberLit{Value: "2"}, 755 }) 756 AssertParseExpr(t, `1 LIKE 2'`, &sqlparser.BinaryExpr{ 757 X: &sqlparser.NumberLit{Value: "1"}, 758 Op: sqlparser.LIKE, 759 Y: &sqlparser.NumberLit{Value: "2"}, 760 }) 761 AssertParseExpr(t, `1 NOT LIKE 2'`, &sqlparser.BinaryExpr{ 762 X: &sqlparser.NumberLit{Value: "1"}, 763 Op: sqlparser.NOTLIKE, 764 Y: &sqlparser.NumberLit{Value: "2"}, 765 }) 766 AssertParseExpr(t, `1 GLOB 2'`, &sqlparser.BinaryExpr{ 767 X: &sqlparser.NumberLit{Value: "1"}, 768 Op: sqlparser.GLOB, 769 Y: &sqlparser.NumberLit{Value: "2"}, 770 }) 771 AssertParseExpr(t, `1 NOT GLOB 2'`, &sqlparser.BinaryExpr{ 772 X: &sqlparser.NumberLit{Value: "1"}, 773 Op: sqlparser.NOTGLOB, 774 Y: &sqlparser.NumberLit{Value: "2"}, 775 }) 776 AssertParseExpr(t, `1 REGEXP 2'`, &sqlparser.BinaryExpr{ 777 X: &sqlparser.NumberLit{Value: "1"}, 778 Op: sqlparser.REGEXP, 779 Y: &sqlparser.NumberLit{Value: "2"}, 780 }) 781 AssertParseExpr(t, `1 NOT REGEXP 2'`, &sqlparser.BinaryExpr{ 782 X: &sqlparser.NumberLit{Value: "1"}, 783 Op: sqlparser.NOTREGEXP, 784 Y: &sqlparser.NumberLit{Value: "2"}, 785 }) 786 AssertParseExpr(t, `1 MATCH 2'`, &sqlparser.BinaryExpr{ 787 X: &sqlparser.NumberLit{Value: "1"}, 788 Op: sqlparser.MATCH, 789 Y: &sqlparser.NumberLit{Value: "2"}, 790 }) 791 AssertParseExpr(t, `1 NOT MATCH 2'`, &sqlparser.BinaryExpr{ 792 X: &sqlparser.NumberLit{Value: "1"}, 793 Op: sqlparser.NOTMATCH, 794 Y: &sqlparser.NumberLit{Value: "2"}, 795 }) 796 AssertParseExprError(t, `1 NOT TABLE`, `1:7: expected IN, LIKE, GLOB, REGEXP, MATCH, or BETWEEN, found 'TABLE'`) 797 AssertParseExpr(t, `1 IN (2, 3)'`, &sqlparser.BinaryExpr{ 798 X: &sqlparser.NumberLit{Value: "1"}, 799 Op: sqlparser.IN, 800 Y: &sqlparser.Exprs{ 801 Exprs: []sqlparser.Expr{ 802 &sqlparser.NumberLit{Value: "2"}, 803 &sqlparser.NumberLit{Value: "3"}, 804 }, 805 }, 806 }) 807 AssertParseExpr(t, `1 NOT IN (2, 3)'`, &sqlparser.BinaryExpr{ 808 X: &sqlparser.NumberLit{Value: "1"}, 809 Op: sqlparser.NOTIN, 810 Y: &sqlparser.Exprs{ 811 Exprs: []sqlparser.Expr{ 812 &sqlparser.NumberLit{Value: "2"}, 813 &sqlparser.NumberLit{Value: "3"}, 814 }, 815 }, 816 }) 817 AssertParseExprError(t, `1 IN 2`, `1:6: expected left paren, found 2`) 818 AssertParseExprError(t, `1 IN (`, `1:6: expected expression, found 'EOF'`) 819 AssertParseExprError(t, `1 IN (2 3`, `1:9: expected comma or right paren, found 3`) 820 AssertParseExpr(t, `1 BETWEEN 2 AND 3'`, &sqlparser.BinaryExpr{ 821 X: &sqlparser.NumberLit{Value: "1"}, 822 Op: sqlparser.BETWEEN, 823 Y: &sqlparser.Range{ 824 X: &sqlparser.NumberLit{Value: "2"}, 825 Y: &sqlparser.NumberLit{Value: "3"}, 826 }, 827 }) 828 AssertParseExpr(t, `1 NOT BETWEEN 2 AND 3'`, &sqlparser.BinaryExpr{ 829 X: &sqlparser.NumberLit{Value: "1"}, 830 Op: sqlparser.NOTBETWEEN, 831 Y: &sqlparser.Range{ 832 X: &sqlparser.NumberLit{Value: "2"}, 833 Y: &sqlparser.NumberLit{Value: "3"}, 834 }, 835 }) 836 AssertParseExprError(t, `1 BETWEEN`, `1:9: expected expression, found 'EOF'`) 837 AssertParseExprError(t, `1 BETWEEN 2`, `1:11: expected range expression, found 'EOF'`) 838 AssertParseExprError(t, `1 BETWEEN 2 + 3`, `1:15: expected range expression, found 'EOF'`) 839 AssertParseExprError(t, `1 + `, `1:4: expected expression, found 'EOF'`) 840 }) 841 t.Run("Call", func(t *testing.T) { 842 AssertParseExpr(t, `sum()`, &sqlparser.Call{ 843 Name: &sqlparser.Ident{Name: "sum"}, 844 }) 845 AssertParseExpr(t, `sum(*)`, &sqlparser.Call{ 846 Name: &sqlparser.Ident{Name: "sum"}, 847 Star: true, 848 }) 849 AssertParseExpr(t, `sum(foo, 123)`, &sqlparser.Call{ 850 Name: &sqlparser.Ident{Name: "sum"}, 851 Args: []sqlparser.Expr{ 852 &sqlparser.Ident{Name: "foo"}, 853 &sqlparser.NumberLit{Value: "123"}, 854 }, 855 }) 856 AssertParseExpr(t, `sum(distinct 'foo')`, &sqlparser.Call{ 857 Name: &sqlparser.Ident{Name: "sum"}, 858 Distinct: true, 859 Args: []sqlparser.Expr{ 860 &sqlparser.StringLit{Value: "foo"}, 861 }, 862 }) 863 AssertParseExpr(t, `sum() filter (where true)`, &sqlparser.Call{ 864 Name: &sqlparser.Ident{Name: "sum"}, 865 Filter: &sqlparser.FilterClause{ 866 X: &sqlparser.BoolLit{Value: true}, 867 }, 868 }) 869 870 AssertParseExprError(t, `sum(`, `1:4: expected expression, found 'EOF'`) 871 AssertParseExprError(t, `sum(*`, `1:5: expected right paren, found 'EOF'`) 872 AssertParseExprError(t, `sum(foo foo`, `1:9: expected comma or right paren, found foo`) 873 AssertParseExprError(t, `sum() filter`, `1:12: expected left paren, found 'EOF'`) 874 AssertParseExprError(t, `sum() filter (`, `1:14: expected WHERE, found 'EOF'`) 875 AssertParseExprError(t, `sum() filter (where`, `1:19: expected expression, found 'EOF'`) 876 AssertParseExprError(t, `sum() filter (where true`, `1:24: expected right paren, found 'EOF'`) 877 }) 878 879 t.Run("Case", func(t *testing.T) { 880 AssertParseExpr(t, `CASE 1 WHEN 2 THEN 3 WHEN 4 THEN 5 ELSE 6 END`, &sqlparser.CaseExpr{ 881 Operand: &sqlparser.NumberLit{Value: "1"}, 882 Blocks: []*sqlparser.CaseBlock{ 883 { 884 Condition: &sqlparser.NumberLit{Value: "2"}, 885 Body: &sqlparser.NumberLit{Value: "3"}, 886 }, 887 { 888 Condition: &sqlparser.NumberLit{Value: "4"}, 889 Body: &sqlparser.NumberLit{Value: "5"}, 890 }, 891 }, 892 ElseExpr: &sqlparser.NumberLit{Value: "6"}, 893 }) 894 AssertParseExpr(t, `CASE WHEN 1 THEN 2 END`, &sqlparser.CaseExpr{ 895 Blocks: []*sqlparser.CaseBlock{ 896 { 897 Condition: &sqlparser.NumberLit{Value: "1"}, 898 Body: &sqlparser.NumberLit{Value: "2"}, 899 }, 900 }, 901 }) 902 AssertParseExprError(t, `CASE`, `1:4: expected expression, found 'EOF'`) 903 AssertParseExprError(t, `CASE 1`, `1:6: expected WHEN, found 'EOF'`) 904 AssertParseExprError(t, `CASE WHEN`, `1:9: expected expression, found 'EOF'`) 905 AssertParseExprError(t, `CASE WHEN 1`, `1:11: expected THEN, found 'EOF'`) 906 AssertParseExprError(t, `CASE WHEN 1 THEN`, `1:16: expected expression, found 'EOF'`) 907 AssertParseExprError(t, `CASE WHEN 1 THEN 2`, `1:18: expected WHEN, ELSE or END, found 'EOF'`) 908 AssertParseExprError(t, `CASE WHEN 1 THEN 2 ELSE`, `1:23: expected expression, found 'EOF'`) 909 AssertParseExprError(t, `CASE WHEN 1 THEN 2 ELSE 3`, `1:25: expected END, found 'EOF'`) 910 }) 911 } 912 913 func TestError_Error(t *testing.T) { 914 err := &sqlparser.Error{Msg: "test"} 915 if got, want := err.Error(), `test`; got != want { 916 t.Fatalf("Error()=%s, want %s", got, want) 917 } 918 } 919 920 // ParseStatementOrFail parses a statement from s. Fail on error. 921 func ParseStatementOrFail(tb testing.TB, s string) sqlparser.Statement { 922 tb.Helper() 923 stmt, err := sqlparser.NewParser(strings.NewReader(s)).ParseStatement() 924 if err != nil { 925 tb.Fatal(err) 926 } 927 return stmt 928 } 929 930 // AssertParseStatement asserts the value of the first parse of s. 931 func AssertParseStatement(tb testing.TB, s string, want sqlparser.Statement) { 932 tb.Helper() 933 stmt, err := sqlparser.NewParser(strings.NewReader(s)).ParseStatement() 934 if err != nil { 935 tb.Fatal(err) 936 } else if diff := deep.Equal(stmt, want); diff != nil { 937 tb.Fatalf("mismatch:\n%s", strings.Join(diff, "\n")) 938 } 939 } 940 941 // AssertParseStatementError asserts s parses to a given error string. 942 func AssertParseStatementError(tb testing.TB, s string, want string) { 943 tb.Helper() 944 _, err := sqlparser.NewParser(strings.NewReader(s)).ParseStatement() 945 if err == nil || err.Error() != want { 946 tb.Fatalf("ParseStatement()=%q, want %q", err, want) 947 } 948 } 949 950 // ParseExprOrFail parses a expression from s. Fail on error. 951 func ParseExprOrFail(tb testing.TB, s string) sqlparser.Expr { 952 tb.Helper() 953 stmt, err := sqlparser.NewParser(strings.NewReader(s)).ParseExpr() 954 if err != nil { 955 tb.Fatal(err) 956 } 957 return stmt 958 } 959 960 // AssertParseExpr asserts the value of the first parse of s. 961 func AssertParseExpr(tb testing.TB, s string, want sqlparser.Expr) { 962 tb.Helper() 963 stmt, err := sqlparser.NewParser(strings.NewReader(s)).ParseExpr() 964 if err != nil { 965 tb.Fatal(err) 966 } else if diff := deep.Equal(stmt, want); diff != nil { 967 tb.Fatalf("mismatch:\n%s", strings.Join(diff, "\n")) 968 } 969 } 970 971 // AssertParseExprError asserts s parses to a given error string. 972 func AssertParseExprError(tb testing.TB, s string, want string) { 973 tb.Helper() 974 _, err := sqlparser.NewParser(strings.NewReader(s)).ParseExpr() 975 if err == nil || err.Error() != want { 976 tb.Fatalf("ParseExpr()=%q, want %q", err, want) 977 } 978 }