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  }