uncomment old LIMIT tests, make them pass

We forward-ported a handful of tests from the previous parser
which relied on LIMIT clauses, but then we didn't support that.
Now that we do, we uncomment most of these tests, and actually
give them the correct data structures to compare with.

We leave two tests commented out. One was using `limit 10, 5` to
express a limit plus offset, and the other is using `not fld = 1`
as a WHERE clause, but we don't support unary-not to negate
other expressions.

In the process, we discover that converting a SELECT with a
LIMIT clause back to a string has a missing space, and fix that.
This commit is contained in:
Seebs 2023-04-05 12:23:57 -05:00 committed by seebs
parent 875999e30d
commit c66d392c87
2 changed files with 101 additions and 11 deletions

View file

@ -4037,7 +4037,7 @@ func (s *SelectStatement) String() string {
}
if s.Limit.IsValid() {
fmt.Fprintf(&buf, "LIMIT %s", s.LimitExpr.String())
fmt.Fprintf(&buf, " LIMIT %s", s.LimitExpr.String())
}
return buf.String()

View file

@ -3347,16 +3347,106 @@ func TestParser_ParseStatement(t *testing.T) {
},
},
})
if false {
// not working because we don't support limit(x), we support top(x), i think?
AssertParseStatement(t, `SELECT fld1, fld2, COUNT(*) FROM tbl where fld1 = 1 group by fld1, fld2 limit 1`, nil) // 1:73: expected semicolon or EOF, found limit
AssertParseStatement(t, `SELECT DISTINCT score FROM grouper order by score asc limit 5`, nil) // 1:55: expected semicolon or EOF, found limit
AssertParseStatement(t, `SELECT DISTINCT score FROM grouper order by score desc limit 5`, nil) // 1:56: expected semicolon or EOF, found limit
AssertParseStatement(t, `SELECT fld FROM tbl limit 10`, nil) // 1:27: expected semicolon or EOF, found 10
AssertParseStatement(t, `SELECT fld FROM tbl limit 10, 5`, nil) // 1:27: expected semicolon or EOF, found 10
AssertParseStatement(t, `SELECT _id FROM tbl where not fld = 1 limit 10`, nil) // 1:31: expected EXISTS, found fld
}
AssertParseStatement(t, `SELECT fld1, fld2, COUNT(*) FROM tbl where fld1 = 1 group by fld1, fld2 limit 1`, &parser.SelectStatement{
Select: pos(0),
Columns: []*parser.ResultColumn{
{Expr: &parser.Ident{NamePos: pos(7), Name: "fld1"}},
{Expr: &parser.Ident{NamePos: pos(13), Name: "fld2"}},
{
Expr: &parser.Call{
Name: &parser.Ident{NamePos: pos(19), Name: "COUNT"},
Lparen: pos(24),
Star: pos(25),
Rparen: pos(26),
},
},
},
From: pos(28),
Source: &parser.QualifiedTableName{Name: &parser.Ident{NamePos: pos(33), Name: "tbl"}},
Where: pos(37),
WhereExpr: &parser.BinaryExpr{
X: &parser.Ident{NamePos: pos(43), Name: "fld1"},
OpPos: pos(48),
Op: parser.EQ,
Y: &parser.IntegerLit{
ValuePos: pos(50),
Value: "1",
},
},
Group: pos(52),
GroupBy: pos(58),
GroupByExprs: []parser.Expr{
&parser.Ident{NamePos: pos(61), Name: "fld1"},
&parser.Ident{NamePos: pos(67), Name: "fld2"},
},
Limit: pos(72),
LimitExpr: &parser.IntegerLit{
ValuePos: pos(78),
Value: "1",
},
})
AssertParseStatement(t, `SELECT DISTINCT score FROM grouper order by score asc limit 5`, &parser.SelectStatement{
Select: pos(0),
Distinct: pos(7),
Columns: []*parser.ResultColumn{
{Expr: &parser.Ident{NamePos: pos(16), Name: "score"}},
},
From: pos(22),
Source: &parser.QualifiedTableName{Name: &parser.Ident{NamePos: pos(27), Name: "grouper"}},
Order: pos(35),
OrderBy: pos(41),
OrderingTerms: []*parser.OrderingTerm{
{
X: &parser.Ident{NamePos: pos(44), Name: "score"},
Asc: pos(50),
},
},
Limit: pos(54),
LimitExpr: &parser.IntegerLit{
ValuePos: pos(60),
Value: "5",
},
})
AssertParseStatement(t, `SELECT DISTINCT score FROM grouper order by score desc limit 5`, &parser.SelectStatement{
Select: pos(0),
Distinct: pos(7),
Columns: []*parser.ResultColumn{
{Expr: &parser.Ident{NamePos: pos(16), Name: "score"}},
},
From: pos(22),
Source: &parser.QualifiedTableName{Name: &parser.Ident{NamePos: pos(27), Name: "grouper"}},
Order: pos(35),
OrderBy: pos(41),
OrderingTerms: []*parser.OrderingTerm{
{
X: &parser.Ident{NamePos: pos(44), Name: "score"},
Desc: pos(50),
},
},
Limit: pos(55),
LimitExpr: &parser.IntegerLit{
ValuePos: pos(61),
Value: "5",
},
})
AssertParseStatement(t, `SELECT fld FROM tbl limit 10`, &parser.SelectStatement{
Select: pos(0),
Columns: []*parser.ResultColumn{
{Expr: &parser.Ident{NamePos: pos(7), Name: "fld"}},
},
From: pos(11),
Source: &parser.QualifiedTableName{Name: &parser.Ident{NamePos: pos(16), Name: "tbl"}},
Limit: pos(20),
LimitExpr: &parser.IntegerLit{
ValuePos: pos(26),
Value: "10",
},
})
// our previous SQL implementation supported "limit 10, 5" to mean a limit of 10 items,
// starting from the 5th item. The new implementation does not support this feature yet.
// AssertParseStatement(t, `SELECT fld FROM tbl limit 10, 5`, nil) // 1:27: expected semicolon or EOF, found 10
// the previous SQL implementation allowed `where not [condition]` but we don't currently.
// AssertParseStatement(t, `SELECT _id FROM tbl where not fld = 1 limit 10`, nil) // 1:31: expected EXISTS, found fld
/*AssertParseStatementError(t, `WITH `, `1:5: expected table name, found 'EOF'`)
AssertParseStatementError(t, `WITH cte`, `1:8: expected AS, found 'EOF'`)
AssertParseStatementError(t, `WITH cte (`, `1:10: expected column name, found 'EOF'`)