mirror of https://github.com/AMT-Cheif/drift.git
Start implementing SELECT statements for parser
This commit is contained in:
parent
b442d32a87
commit
d125a844da
|
@ -1,5 +1,12 @@
|
|||
import 'package:sqlparser/src/ast/expressions/literals.dart';
|
||||
import 'package:sqlparser/src/ast/expressions/simple.dart';
|
||||
import 'package:sqlparser/src/reader/tokenizer/token.dart';
|
||||
|
||||
part 'clauses/limit.dart';
|
||||
|
||||
part 'expressions/expressions.dart';
|
||||
part 'expressions/literals.dart';
|
||||
part 'expressions/simple.dart';
|
||||
|
||||
part 'statements/select.dart';
|
||||
|
||||
abstract class AstNode {
|
||||
Iterable<AstNode> get childNodes;
|
||||
|
@ -7,6 +14,10 @@ abstract class AstNode {
|
|||
}
|
||||
|
||||
abstract class AstVisitor<T> {
|
||||
T visitSelectStatement(SelectStatement e);
|
||||
|
||||
T visitLimit(Limit e);
|
||||
|
||||
T visitBinaryExpression(BinaryExpression e);
|
||||
T visitUnaryExpression(UnaryExpression e);
|
||||
T visitIsExpression(IsExpression e);
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
part of '../ast.dart';
|
||||
|
||||
class Limit extends AstNode {
|
||||
Expression count;
|
||||
Token offsetSeparator; // can either be OFFSET or just a comma
|
||||
Expression offset;
|
||||
|
||||
Limit({this.count, this.offsetSeparator, this.offset});
|
||||
|
||||
@override
|
||||
T accept<T>(AstVisitor<T> visitor) {
|
||||
return visitor.visitLimit(this);
|
||||
}
|
||||
|
||||
@override
|
||||
Iterable<AstNode> get childNodes => [count, if (offset != null) offset];
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
import 'package:sqlparser/src/ast/ast.dart';
|
||||
part of '../ast.dart';
|
||||
|
||||
abstract class Expression implements AstNode {
|
||||
const Expression();
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
import 'package:sqlparser/src/ast/ast.dart';
|
||||
import 'package:sqlparser/src/reader/tokenizer/token.dart';
|
||||
|
||||
import 'expressions.dart';
|
||||
|
||||
part of '../ast.dart';
|
||||
// https://www.sqlite.org/syntax/literal-value.html
|
||||
|
||||
abstract class Literal extends Expression {
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
import 'package:sqlparser/src/ast/ast.dart';
|
||||
import 'package:sqlparser/src/reader/tokenizer/token.dart';
|
||||
|
||||
import 'expressions.dart';
|
||||
part of '../ast.dart';
|
||||
|
||||
class UnaryExpression extends Expression {
|
||||
final Token operator;
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
part of '../ast.dart';
|
||||
|
||||
class SelectStatement extends AstNode {
|
||||
final Expression where;
|
||||
final Limit limit;
|
||||
|
||||
SelectStatement({this.where, this.limit});
|
||||
|
||||
@override
|
||||
T accept<T>(AstVisitor<T> visitor) {
|
||||
return visitor.visitSelectStatement(this);
|
||||
}
|
||||
|
||||
@override
|
||||
Iterable<AstNode> get childNodes => null;
|
||||
}
|
|
@ -1,7 +1,5 @@
|
|||
import 'package:meta/meta.dart';
|
||||
import 'package:sqlparser/src/ast/expressions/expressions.dart';
|
||||
import 'package:sqlparser/src/ast/expressions/literals.dart';
|
||||
import 'package:sqlparser/src/ast/expressions/simple.dart';
|
||||
import 'package:sqlparser/src/ast/ast.dart';
|
||||
import 'package:sqlparser/src/reader/tokenizer/token.dart';
|
||||
|
||||
const _comparisonOperators = [
|
||||
|
@ -72,6 +70,44 @@ class Parser {
|
|||
_error(message);
|
||||
}
|
||||
|
||||
/// Parses a [SelectStatement], or returns null if there is no select token
|
||||
/// after the current position.
|
||||
SelectStatement select() {
|
||||
if (!_match(const [TokenType.select])) return null;
|
||||
|
||||
// todo parse result column
|
||||
|
||||
final where = _where();
|
||||
final limit = _limit();
|
||||
|
||||
return SelectStatement(where: where, limit: limit);
|
||||
}
|
||||
|
||||
/// Parses a where clause if there is one at the current position
|
||||
Expression _where() {
|
||||
if (_match(const [TokenType.where])) {
|
||||
return expression();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Parses a [Limit] clause, or returns null if there is no limit token after
|
||||
/// the current position.
|
||||
Limit _limit() {
|
||||
if (!_match(const [TokenType.limit])) return null;
|
||||
|
||||
final count = expression();
|
||||
Token offsetSep;
|
||||
Expression offset;
|
||||
|
||||
if (_match(const [TokenType.comma, TokenType.offset])) {
|
||||
offsetSep = _previous;
|
||||
offset = expression();
|
||||
}
|
||||
|
||||
return Limit(count: count, offsetSeparator: offsetSep, offset: offset);
|
||||
}
|
||||
|
||||
/* We parse expressions here.
|
||||
* Operators have the following precedence:
|
||||
* - + ~ NOT (unary)
|
||||
|
|
|
@ -45,9 +45,13 @@ enum TokenType {
|
|||
identifier,
|
||||
|
||||
select,
|
||||
|
||||
from,
|
||||
where,
|
||||
|
||||
limit,
|
||||
offset,
|
||||
|
||||
eof,
|
||||
}
|
||||
|
||||
|
@ -55,6 +59,8 @@ const Map<String, TokenType> keywords = {
|
|||
'SELECT': TokenType.select,
|
||||
'FROM': TokenType.from,
|
||||
'WHERE': TokenType.where,
|
||||
'LIMIT': TokenType.limit,
|
||||
'OFFSET': TokenType.offset,
|
||||
'IS': TokenType.$is,
|
||||
'IN': TokenType.$in,
|
||||
'LIKE': TokenType.like,
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import 'package:sqlparser/src/ast/ast.dart';
|
||||
import 'package:sqlparser/src/ast/expressions/simple.dart';
|
||||
|
||||
/// Checks whether [a] and [b] are equal. If they aren't, throws an exception.
|
||||
void enforceEqual(AstNode a, AstNode b) {
|
||||
|
|
|
@ -7,7 +7,7 @@ issue_tracker: https://github.com/simolus3/moor/issues
|
|||
author: Simon Binder <oss@simonbinder.eu>
|
||||
|
||||
environment:
|
||||
sdk: '>=2.2.0 <3.0.0'
|
||||
sdk: '>=2.2.2 <3.0.0'
|
||||
|
||||
dev_dependencies:
|
||||
test: ^1.0.0
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import 'package:sqlparser/src/ast/expressions/literals.dart';
|
||||
import 'package:sqlparser/src/ast/expressions/simple.dart';
|
||||
import 'package:sqlparser/src/ast/ast.dart';
|
||||
import 'package:sqlparser/src/reader/parser/parser.dart';
|
||||
import 'package:sqlparser/src/reader/tokenizer/scanner.dart';
|
||||
import 'package:sqlparser/src/reader/tokenizer/token.dart';
|
||||
|
|
Loading…
Reference in New Issue