Analysis support for table-valued functions

This commit is contained in:
Simon Binder 2020-01-26 14:04:35 +01:00
parent 5622ed5c43
commit c82bff8c97
No known key found for this signature in database
GPG Key ID: 7891917E4147B8C0
5 changed files with 31 additions and 13 deletions

View File

@ -136,16 +136,9 @@ class ColumnResolver extends RecursiveVisitor<void, void> {
}
},
isTableFunction: (function) {
final functions = context.engineOptions.addedFunctions;
final lowercaseName = function.name.toLowerCase();
ResultSet resolved;
if (functions.containsKey(lowercaseName)) {
final handler = functions[lowercaseName];
if (handler is TableValuedFunctionHandler) {
resolved = handler.resolveTableValued(context, function);
}
}
final handler = context
.engineOptions.addedTableFunctions[function.name.toLowerCase()];
final resolved = handler?.resolveTableValued(context, function);
if (resolved == null) {
context.reportError(AnalysisError(

View File

@ -1,7 +1,11 @@
part of '../ast.dart';
/// Interface for function calls, either a [FunctionExpression] or a
/// [AggregateExpression].
/// Interface for function calls.
///
/// Functions that resolve to an [Expression] are subclasses of
/// [ExpressionInvocation], like [FunctionExpression] or [AggregateExpression].
/// There are invocation that don't resolve to an expression, notably
/// [TableValuedFunction].
abstract class SqlInvocation implements AstNode {
/// The name of the function being called
String get name;

View File

@ -47,7 +47,12 @@ abstract class FunctionHandler {
void reportErrors(SqlInvocation call, AnalysisContext context) {}
}
abstract class TableValuedFunctionHandler implements FunctionHandler {
/// Interface for a handler which can resolve the result set of a table-valued
/// function.
abstract class TableValuedFunctionHandler {
/// The name of the table-valued function implemented by this handler.
String get functionName;
/// Resolve the result set of a table-valued function.
///
/// Should return null when the result set can't be resolved.

View File

@ -16,8 +16,14 @@ class EngineOptions {
final List<Extension> enabledExtensions;
final List<FunctionHandler> _addedFunctionHandlers = [];
/// A map from lowercase function names to the associated handler.
final Map<String, FunctionHandler> addedFunctions = {};
/// A map from lowercase function names (where the function is a table-valued
/// function) to the associated handler.
final Map<String, TableValuedFunctionHandler> addedTableFunctions = {};
EngineOptions({
this.useMoorExtensions = false,
this.enableJson1 = false,
@ -32,4 +38,8 @@ class EngineOptions {
addedFunctions[function.toLowerCase()] = handler;
}
}
void addTableValuedFunctionHandler(TableValuedFunctionHandler handler) {
addedTableFunctions[handler.functionName.toLowerCase()] = handler;
}
}

View File

@ -75,6 +75,12 @@ class SqlEngine {
options.addFunctionHandler(handler);
}
/// Registers the [handler], which can infer result sets for a table-valued
/// function.
void registerTableValuedFunctionHandler(TableValuedFunctionHandler handler) {
options.addTableValuedFunctionHandler(handler);
}
ReferenceScope _constructRootScope({ReferenceScope parent}) {
final scope = parent == null ? ReferenceScope(null) : parent.createChild();
for (final table in knownTables) {