-
Notifications
You must be signed in to change notification settings - Fork 3.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support table functions with pushdown to connector #11336
Conversation
Sadly, not all jdbc-based connectors want to cooperate. Testing all to see what they need. |
append(indent, ""); | ||
} | ||
Node value = argument.getValue(); | ||
if (value instanceof TableArgument) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ideally, the formatting of each argument should be done by a recursive call to format each element, instead of switching on the specific concrete classes here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done for all except Expression arguments. I order to be processed recursively, they would require wrapping in another AST node, which I considered too much overhead.
if (context.qualifiedName() != null) { | ||
table = new Table(getLocation(context.TABLE()), getQualifiedName(context.qualifiedName())); | ||
} | ||
else { | ||
table = new TableSubquery(getLocation(context.TABLE()), (Query) visit(context.query())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It'd be better to model these as sub-rules so that the construction occurs naturally by the recursive tree traversal instead of switching on whether qualifiedName is present or not
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
8c3cdc9
to
a05ddd6
Compare
149971a
to
b8aa8f0
Compare
34b3d71
to
907158e
Compare
catalogTableFunctions.remove(catalogName); | ||
} | ||
|
||
public TableFunction resolve(List<CatalogSchemaRoutineName> names) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is the argument a list of names?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Refactored so that the list is implementation detail in table function resolution.
core/trino-main/src/main/java/io/trino/sql/analyzer/StatementAnalyzer.java
Outdated
Show resolved
Hide resolved
core/trino-main/src/main/java/io/trino/metadata/TableFunctionRegistry.java
Outdated
Show resolved
Hide resolved
core/trino-main/src/main/java/io/trino/sql/analyzer/StatementAnalyzer.java
Outdated
Show resolved
Hide resolved
core/trino-main/src/main/java/io/trino/sql/analyzer/StatementAnalyzer.java
Outdated
Show resolved
Hide resolved
for (Argument argument : arguments) { | ||
ArgumentDeclaration declaration = declarationsByName.remove(argument.getName().get().getCanonicalValue()); | ||
if (declaration == null) { | ||
throw semanticException(INVALID_FUNCTION_ARGUMENT, argument, "Unexpected argument name: ", argument.getName().get().getCanonicalValue()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There should be explicit validation to make sure the arguments provided to the function are not duplicated. This will catch that condition, but with an unclear error message.
@Override | ||
public Result apply(TableFunctionNode tableFunctionNode, Captures captures, Context context) | ||
{ | ||
Optional<TableHandle> result = plannerContext.getMetadata().applyTableFunction(context.getSession(), tableFunctionNode.getName(), tableFunctionNode.getHandle()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
applyFunction should return a TableHandle and a list of ColumnHandle for that TH corresponding to the columns coming out of the original table function. This optimizer should not have to derive that from the table metadata, which may not actually exist for a "virtual" table.
public class TableFunctionNode | ||
extends PlanNode | ||
{ | ||
private final QualifiedObjectName name; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does this hold a name?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Refactored. Now the TableFunctionHandle holds the catalog name.
3325323
to
0acafc1
Compare
@martint Applied comments |
core/trino-main/src/main/java/io/trino/metadata/TableFunctionRegistry.java
Show resolved
Hide resolved
core/trino-main/src/main/java/io/trino/metadata/TableFunctionHandle.java
Outdated
Show resolved
Hide resolved
core/trino-main/src/main/java/io/trino/sql/analyzer/StatementAnalyzer.java
Show resolved
Hide resolved
core/trino-main/src/main/java/io/trino/sql/analyzer/StatementAnalyzer.java
Show resolved
Hide resolved
core/trino-spi/src/main/java/io/trino/spi/ptf/ConnectorTableFunction.java
Outdated
Show resolved
Hide resolved
core/trino-spi/src/main/java/io/trino/spi/ptf/ConnectorTableFunction.java
Outdated
Show resolved
Hide resolved
} | ||
} | ||
|
||
static String checkNotNullOrEmpty(String value, String name) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As a follow up - can we extract it to a common util method ?
7ddb7ae
to
45cb337
Compare
eec1b22
to
a2139f7
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great job. Let's merge everything in except for the functions added to the jdbc and elasticsearch connectors. We need to come up with a good name for them and make sure they have reasonable semantics -- I haven't had a chance to review them yet.
core/trino-main/src/main/java/io/trino/metadata/TableFunctionHandle.java
Outdated
Show resolved
Hide resolved
Preparatory commit for supporting table functions in JDBC connectors
Woah, nice job @kasiafi! |
I am going to assume this needs to release notes entry or docs at this stage. Going forward can you maybe use the PR template to indicate that @kasiafi .. thanks |
@mosabua this does need a release notes entry and docs. I'll add the proposed release notes entry in the relnotes issue. I'm currently working on the documentation -- it's likely we'll have to wait for it until the next release. |
#1839
This PR introduces partial support for Table Functions (including Polymorphic Table Functions).
Temporarily, only constant scalar arguments are supported (no Table or Descriptor arguments).
The supported execution path for a Table Function is to be pushed down into connector, and replaced with a TableHandle.
Later, Descriptor and Table arguments will be supported, and operator-based execution will be enabled for Table Functions.