This is an automated email from the ASF dual-hosted git repository. snuyanzin pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/flink.git
commit 5c2e1d0bb9eec48eca3497721bbfca8909c4db21 Author: Sergey Nuyanzin <[email protected]> AuthorDate: Sat Jun 6 10:19:08 2026 +0200 [FLINK-39882][table] Parser can not parse unparsed polymorphic table functions with several table args --- .../src/main/codegen/templates/Parser.jj | 14 +++++++++++ .../plan/stream/sql/ProcessTableFunctionTest.java | 9 ++++++++ .../plan/stream/sql/ProcessTableFunctionTest.xml | 27 ++++++++++++++++++++++ 3 files changed, 50 insertions(+) diff --git a/flink-table/flink-sql-parser/src/main/codegen/templates/Parser.jj b/flink-table/flink-sql-parser/src/main/codegen/templates/Parser.jj index 1f0ae3d455c..5d303e65b09 100644 --- a/flink-table/flink-sql-parser/src/main/codegen/templates/Parser.jj +++ b/flink-table/flink-sql-parser/src/main/codegen/templates/Parser.jj @@ -1055,6 +1055,9 @@ void AddArg(List<SqlNode> list, ExprContext exprContext) : { final SqlIdentifier name; SqlNode e; + final Span s; + SqlNodeList partitionList; + SqlNodeList orderList; } { ( @@ -1068,6 +1071,17 @@ void AddArg(List<SqlNode> list, ExprContext exprContext) : e = LambdaExpression() | e = Expression(exprContext) + // A set-semantics table argument may be a partitioned sub-query, e.g. + // "(SELECT ...) PARTITION BY key [ORDER BY ...]". + [ + { s = span(); } + <PARTITION> <BY> partitionList = SimpleIdentifierOrList() + ( + orderList = OrderByOfSetSemanticsTable() + | { orderList = SqlNodeList.EMPTY; } + ) + { e = CreateSetSemanticsTableIfNeeded(s, e, partitionList, orderList); } + ] | e = TableParam() ) diff --git a/flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/plan/stream/sql/ProcessTableFunctionTest.java b/flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/plan/stream/sql/ProcessTableFunctionTest.java index d68141be11e..118a753556a 100644 --- a/flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/plan/stream/sql/ProcessTableFunctionTest.java +++ b/flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/plan/stream/sql/ProcessTableFunctionTest.java @@ -116,6 +116,15 @@ public class ProcessTableFunctionTest extends TableTestBase { util.verifyRelPlan("SELECT * FROM f(i => 1, b => true)"); } + @Test + void testFunctionWithMultipleTableArgs() { + util.addTemporarySystemFunction("f", MultiInputFunction.class); + util.tableEnv().executeSql("CREATE VIEW v AS SELECT * FROM f(" + + "in1 => TABLE t PARTITION BY name," + + "in2 => TABLE t PARTITION BY name)"); + util.verifyRelPlan("SELECT * FROM v"); + } + @Test void testScalarArgsWithUid() { util.addTemporarySystemFunction("f", ScalarArgsFunction.class); diff --git a/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/stream/sql/ProcessTableFunctionTest.xml b/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/stream/sql/ProcessTableFunctionTest.xml index 36c40cfc695..7cd0f835487 100644 --- a/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/stream/sql/ProcessTableFunctionTest.xml +++ b/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/stream/sql/ProcessTableFunctionTest.xml @@ -68,6 +68,33 @@ LogicalProject(out=[$0]) <![CDATA[ ProcessTableFunction(invocation=[f(DEFAULT(), _UTF-16LE'my-ptf')], uid=[my-ptf], select=[out], rowType=[RecordType(VARCHAR(2147483647) out)]) +- Values(tuples=[[{ }]]) +]]> + </Resource> + </TestCase> + <TestCase name="testFunctionWithMultipleTableArgs"> + <Resource name="sql"> + <![CDATA[SELECT * FROM v]]> + </Resource> + <Resource name="ast"> + <![CDATA[ +LogicalProject(name=[$0], name0=[$1], out=[$2]) ++- LogicalProject(name=[$0], name0=[$1], out=[$2]) + +- LogicalTableFunctionScan(invocation=[f(TABLE(#0) PARTITION BY($0), TABLE(#1) PARTITION BY($0), DEFAULT(), DEFAULT())], rowType=[RecordType(VARCHAR(5) name, VARCHAR(5) name0, VARCHAR(2147483647) out)]) + :- LogicalProject(name=[$0], score=[$1]) + : +- LogicalProject(name=[$0], score=[$1]) + : +- LogicalValues(tuples=[[{ _UTF-16LE'Bob', 12 }, { _UTF-16LE'Alice', 42 }]]) + +- LogicalProject(name=[$0], score=[$1]) + +- LogicalProject(name=[$0], score=[$1]) + +- LogicalValues(tuples=[[{ _UTF-16LE'Bob', 12 }, { _UTF-16LE'Alice', 42 }]]) +]]> + </Resource> + <Resource name="optimized rel plan"> + <![CDATA[ +ProcessTableFunction(invocation=[f(TABLE(#0) PARTITION BY($0), TABLE(#1) PARTITION BY($0), DEFAULT(), DEFAULT())], uid=[f], select=[name,name0,out], rowType=[RecordType(VARCHAR(5) name, VARCHAR(5) name0, VARCHAR(2147483647) out)]) +:- Exchange(distribution=[hash[name]]) +: +- Values(tuples=[[{ _UTF-16LE'Bob', 12 }, { _UTF-16LE'Alice', 42 }]]) ++- Exchange(distribution=[hash[name]]) + +- Values(tuples=[[{ _UTF-16LE'Bob', 12 }, { _UTF-16LE'Alice', 42 }]]) ]]> </Resource> </TestCase>
