Skip to content

Commit 4070362

Browse files
committed
[CALCITE-6236] EnumerableBatchNestedLoopJoin::estimateRowCount returns wrong value
1 parent e2e7ce1 commit 4070362

File tree

4 files changed

+38
-5
lines changed

4 files changed

+38
-5
lines changed

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

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
public class EnumerableBatchNestedLoopJoin extends Join implements EnumerableRel {
5656

5757
private final ImmutableBitSet requiredColumns;
58+
private final @Nullable Double originRowCount;
5859
protected EnumerableBatchNestedLoopJoin(
5960
RelOptCluster cluster,
6061
RelTraitSet traits,
@@ -63,18 +64,32 @@ protected EnumerableBatchNestedLoopJoin(
6364
RexNode condition,
6465
Set<CorrelationId> variablesSet,
6566
ImmutableBitSet requiredColumns,
66-
JoinRelType joinType) {
67+
JoinRelType joinType,
68+
@Nullable Double originRowCount) {
6769
super(cluster, traits, ImmutableList.of(), left, right, condition, variablesSet, joinType);
6870
this.requiredColumns = requiredColumns;
71+
this.originRowCount = originRowCount;
6972
}
7073

74+
@Deprecated
7175
public static EnumerableBatchNestedLoopJoin create(
7276
RelNode left,
7377
RelNode right,
7478
RexNode condition,
7579
ImmutableBitSet requiredColumns,
7680
Set<CorrelationId> variablesSet,
7781
JoinRelType joinType) {
82+
return create(left, right, condition, requiredColumns, variablesSet, joinType, null);
83+
}
84+
85+
public static EnumerableBatchNestedLoopJoin create(
86+
RelNode left,
87+
RelNode right,
88+
RexNode condition,
89+
ImmutableBitSet requiredColumns,
90+
Set<CorrelationId> variablesSet,
91+
JoinRelType joinType,
92+
@Nullable Double originRowCount) {
7893
final RelOptCluster cluster = left.getCluster();
7994
final RelMetadataQuery mq = cluster.getMetadataQuery();
8095
final RelTraitSet traitSet =
@@ -89,9 +104,11 @@ public static EnumerableBatchNestedLoopJoin create(
89104
condition,
90105
variablesSet,
91106
requiredColumns,
92-
joinType);
107+
joinType,
108+
originRowCount);
93109
}
94110

111+
95112
@Override public @Nullable Pair<RelTraitSet, List<RelTraitSet>> passThroughTraits(
96113
final RelTraitSet required) {
97114
return EnumerableTraitsUtils.passThroughTraitsForJoin(
@@ -115,8 +132,8 @@ public static EnumerableBatchNestedLoopJoin create(
115132
@Override public EnumerableBatchNestedLoopJoin copy(RelTraitSet traitSet,
116133
RexNode condition, RelNode left, RelNode right, JoinRelType joinType,
117134
boolean semiJoinDone) {
118-
return new EnumerableBatchNestedLoopJoin(getCluster(), traitSet,
119-
left, right, condition, variablesSet, requiredColumns, joinType);
135+
return new EnumerableBatchNestedLoopJoin(getCluster(), traitSet, left, right, condition,
136+
variablesSet, requiredColumns, joinType, originRowCount);
120137
}
121138

122139
@Override public @Nullable RelOptCost computeSelfCost(
@@ -149,6 +166,10 @@ public static EnumerableBatchNestedLoopJoin create(
149166
return pw.item("batchSize", variablesSet.size());
150167
}
151168

169+
public @Nullable Double getOriginRowCount() {
170+
return originRowCount;
171+
}
172+
152173
@Override public Result implement(EnumerableRelImplementor implementor, Prefer pref) {
153174
final BlockBuilder builder = new BlockBuilder();
154175
final Result leftResult =

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import org.apache.calcite.tools.RelBuilder;
3333
import org.apache.calcite.tools.RelBuilderFactory;
3434
import org.apache.calcite.util.ImmutableBitSet;
35+
import org.apache.calcite.util.Util;
3536

3637
import org.immutables.value.Value;
3738

@@ -137,6 +138,8 @@ public EnumerableBatchNestedLoopJoinRule(RelBuilderFactory relBuilderFactory,
137138
// Push a filter with batchSize disjunctions
138139
relBuilder.push(join.getRight()).filter(relBuilder.or(conditionList));
139140
final RelNode right = relBuilder.build();
141+
final double originRowCount =
142+
Util.first(call.getMetadataQuery().getRowCount(join), Double.MAX_VALUE);
140143

141144
call.transformTo(
142145
EnumerableBatchNestedLoopJoin.create(
@@ -147,7 +150,8 @@ public EnumerableBatchNestedLoopJoinRule(RelBuilderFactory relBuilderFactory,
147150
join.getCondition(),
148151
requiredColumns.build(),
149152
correlationIds,
150-
join.getJoinType()));
153+
join.getJoinType(),
154+
originRowCount));
151155
}
152156

153157
/** Rule configuration. */

core/src/main/java/org/apache/calcite/rel/metadata/RelMdRowCount.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
*/
1717
package org.apache.calcite.rel.metadata;
1818

19+
import org.apache.calcite.adapter.enumerable.EnumerableBatchNestedLoopJoin;
1920
import org.apache.calcite.adapter.enumerable.EnumerableLimit;
2021
import org.apache.calcite.plan.RelOptPredicateList;
2122
import org.apache.calcite.plan.volcano.RelSubset;
@@ -183,6 +184,12 @@ public Double getRowCount(Calc rel, RelMetadataQuery mq) {
183184
}
184185

185186
public @Nullable Double getRowCount(Join rel, RelMetadataQuery mq) {
187+
if (rel instanceof EnumerableBatchNestedLoopJoin) {
188+
Double originRowCount = ((EnumerableBatchNestedLoopJoin) rel).getOriginRowCount();
189+
if (originRowCount != null) {
190+
return originRowCount;
191+
}
192+
}
186193
return RelMdUtil.getJoinRowCount(mq, rel, rel.getCondition());
187194
}
188195

core/src/test/java/org/apache/calcite/test/enumerable/EnumerableBatchNestedLoopJoinTest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,7 @@ class EnumerableBatchNestedLoopJoinTest {
226226
+ "join locations l on e.empid <> l.empid and d.deptno = l.empid")
227227
.withHook(Hook.PLANNER, (Consumer<RelOptPlanner>) planner -> {
228228
planner.removeRule(EnumerableRules.ENUMERABLE_CORRELATE_RULE);
229+
planner.removeRule(EnumerableRules.ENUMERABLE_JOIN_RULE);
229230
// Use a small batch size, otherwise we will run into Janino's
230231
// "InternalCompilerException: Code of method grows beyond 64 KB".
231232
planner.addRule(

0 commit comments

Comments
 (0)