This is an automated email from the ASF dual-hosted git repository.
rongr pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/pinot.git
The following commit(s) were added to refs/heads/master by this push:
new 86735ce1cc [multistage][bugfix] eliminate multiple exchanges (#11882)
86735ce1cc is described below
commit 86735ce1cc6eca1d988e0c950f313b51b541fa02
Author: Rong Rong <[email protected]>
AuthorDate: Mon Oct 30 08:03:38 2023 -0700
[multistage][bugfix] eliminate multiple exchanges (#11882)
* [bugfix] eliminate multiple exchanges
---------
Co-authored-by: Rong Rong <[email protected]>
---
.../rel/rules/PinotExchangeEliminationRule.java | 52 ++++++++++++++++++++++
.../calcite/rel/rules/PinotQueryRuleSets.java | 5 ++-
.../src/test/resources/queries/JoinPlans.json | 21 +++++++++
3 files changed, 77 insertions(+), 1 deletion(-)
diff --git
a/pinot-query-planner/src/main/java/org/apache/calcite/rel/rules/PinotExchangeEliminationRule.java
b/pinot-query-planner/src/main/java/org/apache/calcite/rel/rules/PinotExchangeEliminationRule.java
new file mode 100644
index 0000000000..308eb83e62
--- /dev/null
+++
b/pinot-query-planner/src/main/java/org/apache/calcite/rel/rules/PinotExchangeEliminationRule.java
@@ -0,0 +1,52 @@
+/**
+ * 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.calcite.rel.rules;
+
+import java.util.Collections;
+import org.apache.calcite.plan.RelOptRule;
+import org.apache.calcite.plan.RelOptRuleCall;
+import org.apache.calcite.rel.RelDistribution;
+import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.logical.PinotLogicalExchange;
+import org.apache.calcite.tools.RelBuilderFactory;
+
+
+/**
+ * Special rule for Pinot, this rule eliminates {@link PinotLogicalExchange}
when {@link RelDistribution} traits
+ * are the same at this exchange node and at the node prior to this exchange
node.
+ */
+public class PinotExchangeEliminationRule extends RelOptRule {
+ public static final PinotExchangeEliminationRule INSTANCE =
+ new PinotExchangeEliminationRule(PinotRuleUtils.PINOT_REL_FACTORY);
+
+ public PinotExchangeEliminationRule(RelBuilderFactory factory) {
+ super(operand(PinotLogicalExchange.class,
+ some(operand(PinotLogicalExchange.class, some(operand(RelNode.class,
any()))))), factory, null);
+ }
+
+ @Override
+ public void onMatch(RelOptRuleCall call) {
+ PinotLogicalExchange exchange0 = call.rel(0);
+ PinotLogicalExchange exchange1 = call.rel(1);
+ RelNode input = call.rel(2);
+ // convert the call to skip the exchange.
+ RelNode rel = exchange0.copy(input.getTraitSet(),
Collections.singletonList(input));
+ call.transformTo(rel);
+ }
+}
diff --git
a/pinot-query-planner/src/main/java/org/apache/calcite/rel/rules/PinotQueryRuleSets.java
b/pinot-query-planner/src/main/java/org/apache/calcite/rel/rules/PinotQueryRuleSets.java
index 581fd7e8e5..ff3aca3012 100644
---
a/pinot-query-planner/src/main/java/org/apache/calcite/rel/rules/PinotQueryRuleSets.java
+++
b/pinot-query-planner/src/main/java/org/apache/calcite/rel/rules/PinotQueryRuleSets.java
@@ -134,6 +134,9 @@ public class PinotQueryRuleSets {
PinotSetOpExchangeNodeInsertRule.INSTANCE,
// apply dynamic broadcast rule after exchange is inserted/
- PinotJoinToDynamicBroadcastRule.INSTANCE
+ PinotJoinToDynamicBroadcastRule.INSTANCE,
+
+ // remove exchanges when there's duplicates
+ PinotExchangeEliminationRule.INSTANCE
);
}
diff --git a/pinot-query-planner/src/test/resources/queries/JoinPlans.json
b/pinot-query-planner/src/test/resources/queries/JoinPlans.json
index b3c1504565..6f655ec6e4 100644
--- a/pinot-query-planner/src/test/resources/queries/JoinPlans.json
+++ b/pinot-query-planner/src/test/resources/queries/JoinPlans.json
@@ -421,6 +421,27 @@
"\n LogicalTableScan(table=[[b]])",
"\n"
]
+ },
+ {
+ "description": "nexted reused tmp table SEMI JOINs",
+ "sql": "EXPLAIN PLAN FOR WITH tmp1 AS ( SELECT * FROM a WHERE col2 NOT
IN ('foo', 'bar') ), tmp2 AS ( SELECT * FROM b WHERE col1 IN (SELECT col1 FROM
tmp1) AND col3 < 100 ) SELECT * FROM tmp2 WHERE col3 IN (SELECT col3 from
tmp1)",
+ "output": [
+ "Execution Plan",
+ "\nLogicalJoin(condition=[=($2, $8)], joinType=[semi])",
+ "\n PinotLogicalExchange(distribution=[hash[2]])",
+ "\n LogicalJoin(condition=[=($0, $7)], joinType=[semi])",
+ "\n LogicalFilter(condition=[<($2, 100)])",
+ "\n LogicalTableScan(table=[[b]])",
+ "\n PinotLogicalExchange(distribution=[broadcast],
relExchangeType=[PIPELINE_BREAKER])",
+ "\n LogicalProject(col1=[$0], col2=[$1])",
+ "\n LogicalFilter(condition=[AND(<>($1, 'bar'), <>($1,
'foo'))])",
+ "\n LogicalTableScan(table=[[a]])",
+ "\n PinotLogicalExchange(distribution=[hash[1]])",
+ "\n LogicalProject(col2=[$1], col3=[$2])",
+ "\n LogicalFilter(condition=[AND(<>($1, 'bar'), <>($1,
'foo'))])",
+ "\n LogicalTableScan(table=[[a]])",
+ "\n"
+ ]
}
]
},
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]