bgeng777 commented on code in PR #29652:
URL: https://github.com/apache/flink/pull/29652#discussion_r4438694274


##########
flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/plan/rules/logical/PythonAsyncCalcProjectionTest.java:
##########
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.planner.plan.rules.logical;
+
+import org.apache.flink.table.api.DataTypes;
+import org.apache.flink.table.api.Schema;
+import 
org.apache.flink.table.planner.runtime.utils.JavaUserDefinedScalarFunctions.AsyncPythonScalarFunction;
+import 
org.apache.flink.table.planner.runtime.utils.JavaUserDefinedScalarFunctions.PythonScalarFunction;
+import org.apache.flink.table.planner.utils.JavaTableTestUtil;
+import org.apache.flink.table.planner.utils.TableTestBase;
+
+import org.junit.jupiter.api.Test;
+
+/** Tests projection ordering after splitting Python async calls. */
+class PythonAsyncCalcProjectionTest extends TableTestBase {

Review Comment:
   Could you add plan tests with forwarded fields interleaved with remote 
calls, e.g. `SELECT a, asyncFunc1(a, b), c, pyFunc1(b, c), a FROM MyTable`, and 
one with a `WHERE` clause? These match the shape in the Jira and document that 
conditions are pushed out before the reorder step (I verified locally that they 
are preserved).



##########
flink-table/flink-table-planner/src/main/java/org/apache/flink/table/planner/plan/rules/logical/RemoteCalcReorderProjectionRule.java:
##########
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.planner.plan.rules.logical;
+
+import org.apache.flink.table.planner.plan.nodes.logical.FlinkLogicalCalc;
+
+import org.apache.calcite.plan.RelOptRuleCall;
+import org.apache.calcite.rex.RexCall;
+import org.apache.calcite.rex.RexInputRef;
+import org.apache.calcite.rex.RexNode;
+import org.apache.calcite.rex.RexProgram;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+import scala.Option;
+
+/**
+ * Enforces that {@link RexInputRef} projections precede {@link RexCall} 
projections in a {@link
+ * FlinkLogicalCalc} containing remote calls.
+ *
+ * <p>{@link RemoteCalcRewriteProjectionRule} moves expressions other than 
{@link RexInputRef} and
+ * {@link RexCall} out of the remote calc and also establishes this projection 
order. Subsequent
+ * optimizations, such as async calc splitting, can disrupt that order. This 
rule restores the
+ * required order after those optimizations.
+ */
+public class RemoteCalcReorderProjectionRule extends 
RemoteCalcSplitProjectionRuleBase<Void> {
+
+    public RemoteCalcReorderProjectionRule(RemoteCallFinder callFinder) {
+        super("RemoteCalcReorderProjectionRule", callFinder);
+    }
+
+    @Override
+    public boolean matches(RelOptRuleCall call) {
+        final FlinkLogicalCalc calc = call.rel(0);
+        final RexProgram program = calc.getProgram();
+        final List<RexNode> projects =
+                program.getProjectList().stream()
+                        .map(program::expandLocalRef)
+                        .collect(Collectors.toList());
+        if (projects.stream().noneMatch(callFinder()::containsRemoteCall)) {
+            return false;
+        }
+        boolean seenCall = false;
+        for (RexNode project : projects) {
+            if (project instanceof RexCall) {

Review Comment:
   nit: `matches()` treats any `RexCall` (including non-remote calls such as `a 
+ 1`) as a call when checking the ordering. Would checking 
`callFinder().isRemoteCall(project)` express the intent more precisely?



##########
flink-table/flink-table-planner/src/main/java/org/apache/flink/table/planner/plan/rules/logical/RemoteCalcReorderProjectionRule.java:
##########
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.planner.plan.rules.logical;
+
+import org.apache.flink.table.planner.plan.nodes.logical.FlinkLogicalCalc;
+
+import org.apache.calcite.plan.RelOptRuleCall;
+import org.apache.calcite.rex.RexCall;
+import org.apache.calcite.rex.RexInputRef;
+import org.apache.calcite.rex.RexNode;
+import org.apache.calcite.rex.RexProgram;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+import scala.Option;
+
+/**
+ * Enforces that {@link RexInputRef} projections precede {@link RexCall} 
projections in a {@link
+ * FlinkLogicalCalc} containing remote calls.
+ *
+ * <p>{@link RemoteCalcRewriteProjectionRule} moves expressions other than 
{@link RexInputRef} and
+ * {@link RexCall} out of the remote calc and also establishes this projection 
order. Subsequent
+ * optimizations, such as async calc splitting, can disrupt that order. This 
rule restores the
+ * required order after those optimizations.
+ */
+public class RemoteCalcReorderProjectionRule extends 
RemoteCalcSplitProjectionRuleBase<Void> {

Review Comment:
   Reusing `PythonCalcSplitRule.REWRITE_PROJECT` here doesn't work: 
`FlinkRuleSetProgram.add()` de-duplicates it (same class and call finder), so 
it's silently skipped, while a distinct subclass yields the same plans as this 
PR. Could you note this in the Javadoc, and consider a thin subclass of 
`RemoteCalcRewriteProjectionRule` instead of duplicating its logic?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to