Support LIKE expressions in the new type resolver

This commit is contained in:
Simon Binder 2020-01-04 21:36:06 +01:00
parent a8ffd0a7f3
commit 523eabaa2a
No known key found for this signature in database
GPG Key ID: 7891917E4147B8C0
3 changed files with 35 additions and 0 deletions

View File

@ -2,6 +2,8 @@ part of 'types.dart';
const _expectInt =
ExactTypeExpectation.laxly(ResolvedType(type: BasicType.int));
const _expectString =
ExactTypeExpectation.laxly(ResolvedType(type: BasicType.text));
class TypeResolver extends RecursiveVisitor<TypeExpectation, void> {
final TypeInferenceSession session;
@ -116,16 +118,20 @@ class TypeResolver extends RecursiveVisitor<TypeExpectation, void> {
if (e is NullLiteral) {
type = const ResolvedType(type: BasicType.nullType, nullable: true);
session.hintNullability(e, true);
} else if (e is StringLiteral) {
type = e.isBinary
? const ResolvedType(type: BasicType.blob)
: const ResolvedType(type: BasicType.text);
session.hintNullability(e, false);
} else if (e is BooleanLiteral) {
type = const ResolvedType.bool();
session.hintNullability(e, false);
} else if (e is NumericLiteral) {
type = e.isInt
? const ResolvedType(type: BasicType.int)
: const ResolvedType(type: BasicType.real);
session.hintNullability(e, false);
}
session.checkAndResolve(e, type, arg);
@ -243,6 +249,24 @@ class TypeResolver extends RecursiveVisitor<TypeExpectation, void> {
visit(e.operand, const NoTypeExpectation());
}
@override
void visitStringComparison(
StringComparisonExpression e, TypeExpectation arg) {
session.checkAndResolve(e, const ResolvedType(type: BasicType.text), arg);
session.addRelationship(NullableIfSomeOtherIs(
e,
[
e.left,
e.right,
if (e.escape != null) e.escape,
],
));
visit(e.left, _expectString);
visit(e.right, _expectString);
visitNullable(e.escape, _expectString);
}
@override
void visitReference(Reference e, TypeExpectation arg) {
final resolved = e.resolvedColumn;

View File

@ -57,6 +57,7 @@ class BinaryExpression extends Expression {
}
}
/// A like, glob, match or regexp expression.
class StringComparisonExpression extends Expression {
final bool not;
final Token operator;

View File

@ -127,4 +127,14 @@ void main() {
final offsetType = _resolveFirstVariable('SELECT 0 LIMIT 1, ?');
expect(offsetType, int);
});
test('handles string matching expressions', () {
final type =
_resolveFirstVariable('SELECT * FROM demo WHERE content LIKE ?');
expect(type, const ResolvedType(type: BasicType.text));
final escapedType = _resolveFirstVariable(
"SELECT * FROM demo WHERE content LIKE 'foo' ESCAPE ?");
expect(escapedType, const ResolvedType(type: BasicType.text));
});
}