Fix order in limit expressions with comma

Fixes #73
This commit is contained in:
Simon Binder 2019-07-10 17:26:43 +02:00
parent 6c70c947a1
commit d01b5c750f
No known key found for this signature in database
GPG Key ID: 7891917E4147B8C0
4 changed files with 20 additions and 13 deletions

View File

@ -14,7 +14,7 @@ class Limit extends Component {
@override
void writeInto(GenerationContext context) {
if (offset != null) {
context.buffer.write('LIMIT $amount, $offset');
context.buffer.write('LIMIT $amount OFFSET $offset');
} else {
context.buffer.write('LIMIT $amount');
}

View File

@ -36,9 +36,9 @@ void main() {
});
test('with limit statements', () {
(db.select(db.users)..limit(10)).get();
(db.select(db.users)..limit(10, offset: 0)).get();
verify(executor.runSelect(
'SELECT * FROM users LIMIT 10;', argThat(isEmpty)));
'SELECT * FROM users LIMIT 10 OFFSET 0;', argThat(isEmpty)));
});
test('with like expressions', () {

View File

@ -405,16 +405,21 @@ class Parser {
Limit _limit() {
if (!_matchOne(TokenType.limit)) return null;
final count = expression();
Token offsetSep;
Expression offset;
// Unintuitive, it's "$amount OFFSET $offset", but "$offset, $amount"
// the order changes between the separator tokens.
final first = expression();
if (_match(const [TokenType.comma, TokenType.offset])) {
offsetSep = _previous;
offset = expression();
if (_matchOne(TokenType.comma)) {
final separator = _previous;
final count = expression();
return Limit(count: count, offsetSeparator: separator, offset: first);
} else if (_matchOne(TokenType.offset)) {
final separator = _previous;
final offset = expression();
return Limit(count: first, offsetSeparator: separator, offset: offset);
} else {
return Limit(count: first);
}
return Limit(count: count, offsetSeparator: offsetSep, offset: offset);
}
DeleteStatement _deleteStmt() {

View File

@ -40,6 +40,8 @@ void main() {
});
test('with offset as comma', () {
// with the comma notation, the offset comes first.
// https://www.sqlite.org/lang_select.html#limitoffset
final select = SqlEngine()
.parse('SELECT * FROM test LIMIT 10, 2')
.rootNode as SelectStatement;
@ -47,9 +49,9 @@ void main() {
enforceEqual(
select.limit,
Limit(
count: NumericLiteral(10, token(TokenType.numberLiteral)),
count: NumericLiteral(2, token(TokenType.numberLiteral)),
offsetSeparator: token(TokenType.comma),
offset: NumericLiteral(2, token(TokenType.numberLiteral)),
offset: NumericLiteral(10, token(TokenType.numberLiteral)),
),
);
});