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>

Reply via email to