mirror of https://github.com/AMT-Cheif/drift.git
Parse exists expressions
This commit is contained in:
parent
3e910123d2
commit
da07be2da4
|
@ -78,7 +78,10 @@ class TypeResolver {
|
||||||
return resolveColumn(expr.resolved as Column);
|
return resolveColumn(expr.resolved as Column);
|
||||||
} else if (expr is FunctionExpression) {
|
} else if (expr is FunctionExpression) {
|
||||||
return resolveFunctionCall(expr);
|
return resolveFunctionCall(expr);
|
||||||
} else if (expr is IsExpression) {
|
} else if (expr is IsExpression ||
|
||||||
|
expr is StringComparisonExpression ||
|
||||||
|
expr is BetweenExpression ||
|
||||||
|
expr is ExistsExpression) {
|
||||||
return const ResolveResult(ResolvedType.bool());
|
return const ResolveResult(ResolvedType.bool());
|
||||||
} else if (expr is BinaryExpression) {
|
} else if (expr is BinaryExpression) {
|
||||||
final operator = expr.operator.type;
|
final operator = expr.operator.type;
|
||||||
|
@ -89,10 +92,6 @@ class TypeResolver {
|
||||||
[BasicType.int, BasicType.real, BasicType.text, BasicType.blob]);
|
[BasicType.int, BasicType.real, BasicType.text, BasicType.blob]);
|
||||||
return ResolveResult(type);
|
return ResolveResult(type);
|
||||||
}
|
}
|
||||||
} else if (expr is StringComparisonExpression) {
|
|
||||||
return const ResolveResult(ResolvedType.bool());
|
|
||||||
} else if (expr is BetweenExpression) {
|
|
||||||
return const ResolveResult(ResolvedType.bool());
|
|
||||||
} else if (expr is CaseExpression) {
|
} else if (expr is CaseExpression) {
|
||||||
return resolveExpression(expr.whens.first.then);
|
return resolveExpression(expr.whens.first.then);
|
||||||
} else if (expr is SubQuery) {
|
} else if (expr is SubQuery) {
|
||||||
|
|
|
@ -145,6 +145,7 @@ abstract class AstVisitor<T> {
|
||||||
T visitReference(Reference e);
|
T visitReference(Reference e);
|
||||||
T visitFunction(FunctionExpression e);
|
T visitFunction(FunctionExpression e);
|
||||||
T visitSubQuery(SubQuery e);
|
T visitSubQuery(SubQuery e);
|
||||||
|
T visitExists(ExistsExpression e);
|
||||||
T visitCaseExpression(CaseExpression e);
|
T visitCaseExpression(CaseExpression e);
|
||||||
T visitWhen(WhenComponent e);
|
T visitWhen(WhenComponent e);
|
||||||
|
|
||||||
|
@ -181,6 +182,9 @@ class RecursiveVisitor<T> extends AstVisitor<T> {
|
||||||
@override
|
@override
|
||||||
T visitSubQuery(SubQuery e) => visitChildren(e);
|
T visitSubQuery(SubQuery e) => visitChildren(e);
|
||||||
|
|
||||||
|
@override
|
||||||
|
T visitExists(ExistsExpression e) => visitChildren(e);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
T visitSetComponent(SetComponent e) => visitChildren(e);
|
T visitSetComponent(SetComponent e) => visitChildren(e);
|
||||||
|
|
||||||
|
|
|
@ -16,3 +16,18 @@ class SubQuery extends Expression {
|
||||||
@override
|
@override
|
||||||
bool contentEquals(SubQuery other) => true;
|
bool contentEquals(SubQuery other) => true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ExistsExpression extends Expression {
|
||||||
|
final SelectStatement select;
|
||||||
|
|
||||||
|
ExistsExpression({@required this.select});
|
||||||
|
|
||||||
|
@override
|
||||||
|
T accept<T>(AstVisitor<T> visitor) => visitor.visitExists(this);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Iterable<AstNode> get childNodes => [select];
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool contentEquals(ExistsExpression other) => true;
|
||||||
|
}
|
||||||
|
|
|
@ -33,9 +33,9 @@ class SelectStatement extends Statement with ResultSet {
|
||||||
@override
|
@override
|
||||||
Iterable<AstNode> get childNodes {
|
Iterable<AstNode> get childNodes {
|
||||||
return [
|
return [
|
||||||
if (where != null) where,
|
|
||||||
...columns,
|
...columns,
|
||||||
if (from != null) ...from,
|
if (from != null) ...from,
|
||||||
|
if (where != null) where,
|
||||||
if (groupBy != null) groupBy,
|
if (groupBy != null) groupBy,
|
||||||
if (limit != null) limit,
|
if (limit != null) limit,
|
||||||
if (orderBy != null) orderBy,
|
if (orderBy != null) orderBy,
|
||||||
|
|
|
@ -612,6 +612,13 @@ class Parser {
|
||||||
final operator = _previous;
|
final operator = _previous;
|
||||||
final expression = _unary();
|
final expression = _unary();
|
||||||
return UnaryExpression(operator, expression);
|
return UnaryExpression(operator, expression);
|
||||||
|
} else if (_matchOne(TokenType.exists)) {
|
||||||
|
_consume(
|
||||||
|
TokenType.leftParen, 'Expected opening parenthesis after EXISTS');
|
||||||
|
final selectStmt = select();
|
||||||
|
_consume(TokenType.rightParen,
|
||||||
|
'Expected closing paranthesis to finish EXISTS expression');
|
||||||
|
return ExistsExpression(select: selectStmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
return _postfix();
|
return _postfix();
|
||||||
|
|
|
@ -35,6 +35,7 @@ enum TokenType {
|
||||||
or,
|
or,
|
||||||
tilde,
|
tilde,
|
||||||
between,
|
between,
|
||||||
|
exists,
|
||||||
|
|
||||||
questionMark,
|
questionMark,
|
||||||
colon,
|
colon,
|
||||||
|
@ -104,6 +105,7 @@ const Map<String, TokenType> keywords = {
|
||||||
'ALL': TokenType.all,
|
'ALL': TokenType.all,
|
||||||
'AND': TokenType.and,
|
'AND': TokenType.and,
|
||||||
'OR': TokenType.or,
|
'OR': TokenType.or,
|
||||||
|
'EXISTS': TokenType.exists,
|
||||||
'BETWEEN': TokenType.between,
|
'BETWEEN': TokenType.between,
|
||||||
'DELETE': TokenType.delete,
|
'DELETE': TokenType.delete,
|
||||||
'FROM': TokenType.from,
|
'FROM': TokenType.from,
|
||||||
|
|
|
@ -72,6 +72,17 @@ final Map<String, Expression> _testCases = {
|
||||||
right: StringLiteral.from(token(TokenType.stringLiteral), '%A%\$'),
|
right: StringLiteral.from(token(TokenType.stringLiteral), '%A%\$'),
|
||||||
escape: StringLiteral.from(token(TokenType.stringLiteral), '\$'),
|
escape: StringLiteral.from(token(TokenType.stringLiteral), '\$'),
|
||||||
),
|
),
|
||||||
|
'NOT EXISTS (SELECT * FROM demo)': UnaryExpression(
|
||||||
|
token(TokenType.not),
|
||||||
|
ExistsExpression(
|
||||||
|
select: SelectStatement(
|
||||||
|
columns: [StarResultColumn(null)],
|
||||||
|
from: [
|
||||||
|
TableReference('demo', null),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
|
Loading…
Reference in New Issue