Skip to content

Commit 3872173

Browse files
committed
fix(MXP-4112): EnumerableBatchNestedLoopJoin causes infinit plan optimization for single sourced JDBC queries
1 parent 7f13bd7 commit 3872173

File tree

1 file changed

+35
-2
lines changed

1 file changed

+35
-2
lines changed

core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableBatchNestedLoopJoinRule.java

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,14 @@
1616
*/
1717
package org.apache.calcite.adapter.enumerable;
1818

19+
import java.util.concurrent.atomic.AtomicReference;
20+
21+
import org.apache.calcite.adapter.jdbc.JdbcConvention;
1922
import org.apache.calcite.plan.RelOptCluster;
2023
import org.apache.calcite.plan.RelOptRuleCall;
2124
import org.apache.calcite.plan.RelRule;
25+
import org.apache.calcite.plan.RelTrait;
26+
import org.apache.calcite.plan.RelTraitSet;
2227
import org.apache.calcite.rel.RelNode;
2328
import org.apache.calcite.rel.core.CorrelationId;
2429
import org.apache.calcite.rel.core.Join;
@@ -80,10 +85,38 @@ public EnumerableBatchNestedLoopJoinRule(RelBuilderFactory relBuilderFactory,
8085
@Override public boolean matches(RelOptRuleCall call) {
8186
Join join = call.rel(0);
8287
JoinRelType joinType = join.getJoinType();
83-
return joinType == JoinRelType.INNER
88+
return (joinType == JoinRelType.INNER
8489
|| joinType == JoinRelType.LEFT
8590
|| joinType == JoinRelType.ANTI
86-
|| joinType == JoinRelType.SEMI;
91+
|| joinType == JoinRelType.SEMI )
92+
&& !containsSingleJdbcSource(join, new AtomicReference<>());
93+
}
94+
95+
private boolean containsSingleJdbcSource(RelNode node, AtomicReference<JdbcConvention> jdbcConvention) {
96+
List<RelNode> inputs = node.getInputs();
97+
if ( inputs.isEmpty()) {
98+
RelTraitSet traitSet = node.getTraitSet();
99+
for ( int i = 0; i < traitSet.size(); i++) {
100+
RelTrait trait = traitSet.get(i);
101+
if ( trait instanceof JdbcConvention ) {
102+
JdbcConvention jdbcTrait = (JdbcConvention) trait;
103+
if ( jdbcConvention.get() == null){
104+
jdbcConvention.set(jdbcTrait);
105+
return true;
106+
} else {
107+
return jdbcConvention.get() == jdbcTrait;
108+
}
109+
}
110+
}
111+
return false;
112+
} else {
113+
for ( RelNode input : inputs) {
114+
if ( !containsSingleJdbcSource(input.stripped(), jdbcConvention)) {
115+
return false;
116+
}
117+
}
118+
}
119+
return true;
87120
}
88121

89122
@Override public void onMatch(RelOptRuleCall call) {

0 commit comments

Comments
 (0)