Don't crash when trying to resolve variables

This commit is contained in:
Simon Binder 2019-12-16 13:24:29 +01:00
parent ae91b5d526
commit ffe4bb8c82
No known key found for this signature in database
GPG Key ID: 7891917E4147B8C0
2 changed files with 15 additions and 12 deletions

View File

@ -125,9 +125,8 @@ class TypeResolver {
if (_comparisonOperators.contains(operator)) {
return const ResolveResult(ResolvedType.bool());
} else {
final type = _encapsulate(expr.childNodes.cast(),
return _encapsulate(expr.childNodes.cast(),
[BasicType.int, BasicType.real, BasicType.text, BasicType.blob]);
return ResolveResult(type);
}
} else if (expr is CaseExpression) {
return resolveExpression(expr.whens.first.then);
@ -141,7 +140,7 @@ class TypeResolver {
}
}
throw StateError('Unknown expression $expr');
return const ResolveResult.unknown();
}, expr);
}
@ -265,8 +264,8 @@ class TypeResolver {
return justResolve(parameters.first);
case 'coalesce':
case 'ifnull':
return ResolveResult(_encapsulate(parameters,
[BasicType.int, BasicType.real, BasicType.text, BasicType.blob]));
return _encapsulate(parameters,
[BasicType.int, BasicType.real, BasicType.text, BasicType.blob]);
case 'nullif':
return justResolve(parameters.first).withNullable(true);
case 'first_value':
@ -276,19 +275,19 @@ class TypeResolver {
case 'nth_value':
return justResolve(parameters.first);
case 'max':
return ResolveResult(_encapsulate(parameters, [
return _encapsulate(parameters, [
BasicType.int,
BasicType.real,
BasicType.text,
BasicType.blob
])).withNullable(true);
]).withNullable(true);
case 'min':
return ResolveResult(_encapsulate(parameters, [
return _encapsulate(parameters, [
BasicType.blob,
BasicType.text,
BasicType.int,
BasicType.real
])).withNullable(true);
]).withNullable(true);
}
if (options.enableJson1) {
@ -431,15 +430,18 @@ class TypeResolver {
/// Returns the type of an expression in [expressions] that has the highest
/// order in [types].
ResolvedType _encapsulate(
ResolveResult _encapsulate(
Iterable<Typeable> expressions, List<BasicType> types) {
final argTypes = expressions
.map((expr) => justResolve(expr).type)
.where((t) => t != null);
final type = types.lastWhere((t) => argTypes.any((arg) => arg.type == t));
final type = types.lastWhere((t) => argTypes.any((arg) => arg.type == t),
orElse: () => null);
if (type == null) return const ResolveResult.unknown();
final notNull = argTypes.any((t) => !t.nullable);
return ResolvedType(type: type, nullable: !notNull);
return ResolveResult(ResolvedType(type: type, nullable: !notNull));
}
}

View File

@ -29,6 +29,7 @@ Map<String, ResolveResult> _types = {
ResolvedType(type: BasicType.int, hint: IsDateTime())),
'SELECT row_number() OVER (RANGE ? PRECEDING)':
const ResolveResult(ResolvedType(type: BasicType.int)),
'SELECT ?;': const ResolveResult.unknown(),
};
void main() {