This is an automated email from the ASF dual-hosted git repository.
morrysnow pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push:
new 3414d72e503 [fix](mtmv) Fix set disable join reorder fail when table
row count is -1 when init join order (#55681)
3414d72e503 is described below
commit 3414d72e503cceb1918aac285cb8d467203c9e41
Author: seawinde <[email protected]>
AuthorDate: Wed Sep 10 17:03:20 2025 +0800
[fix](mtmv) Fix set disable join reorder fail when table row count is -1
when init join order (#55681)
---
.../doris/nereids/rules/rewrite/InitJoinOrder.java | 7 +-
.../doris/nereids/stats/StatsCalculatorTest.java | 42 +++++++++++-
.../org/apache/doris/nereids/util/PlanChecker.java | 80 +++++++++++++++++++---
3 files changed, 114 insertions(+), 15 deletions(-)
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/InitJoinOrder.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/InitJoinOrder.java
index 970dc84c787..5129f3fdfd8 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/InitJoinOrder.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/InitJoinOrder.java
@@ -17,6 +17,7 @@
package org.apache.doris.nereids.rules.rewrite;
+import org.apache.doris.nereids.CascadesContext;
import org.apache.doris.nereids.rules.Rule;
import org.apache.doris.nereids.rules.RuleType;
import org.apache.doris.nereids.rules.rewrite.StatsDerive.DeriveContext;
@@ -55,12 +56,12 @@ public class InitJoinOrder extends OneRewriteRuleFactory {
return null;
}
LogicalJoin<? extends Plan, ? extends Plan> join =
(LogicalJoin<?, ?>) ctx.root;
- return swapJoinChildrenIfNeed(join);
+ return swapJoinChildrenIfNeed(join, ctx.cascadesContext);
})
.toRule(RuleType.INIT_JOIN_ORDER);
}
- private Plan swapJoinChildrenIfNeed(LogicalJoin<? extends Plan, ? extends
Plan> join) {
+ private Plan swapJoinChildrenIfNeed(LogicalJoin<? extends Plan, ? extends
Plan> join, CascadesContext context) {
if (join.getJoinType().isLeftSemiOrAntiJoin()) {
// TODO: currently, the transform rules for right semi/anti join
is not complete,
// for example LogicalJoinSemiJoinTransposeProject (tpch 22) only
works for left semi/anti join
@@ -68,7 +69,7 @@ public class InitJoinOrder extends OneRewriteRuleFactory {
return null;
}
List<CatalogRelation> scans =
join.collectToList(CatalogRelation.class::isInstance);
- Optional<String> disableReason =
StatsCalculator.disableJoinReorderIfStatsInvalid(scans, null);
+ Optional<String> disableReason =
StatsCalculator.disableJoinReorderIfStatsInvalid(scans, context);
if (!disableReason.isPresent()) {
JoinType swapType = join.getJoinType().swap();
if (swapType == null) {
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/nereids/stats/StatsCalculatorTest.java
b/fe/fe-core/src/test/java/org/apache/doris/nereids/stats/StatsCalculatorTest.java
index 9f77dfddb55..0590078de22 100644
---
a/fe/fe-core/src/test/java/org/apache/doris/nereids/stats/StatsCalculatorTest.java
+++
b/fe/fe-core/src/test/java/org/apache/doris/nereids/stats/StatsCalculatorTest.java
@@ -21,6 +21,7 @@ import org.apache.doris.catalog.Column;
import org.apache.doris.catalog.OlapTable;
import org.apache.doris.catalog.PrimitiveType;
import org.apache.doris.common.Pair;
+import org.apache.doris.nereids.CascadesContext;
import org.apache.doris.nereids.memo.Group;
import org.apache.doris.nereids.memo.GroupExpression;
import org.apache.doris.nereids.properties.DataTrait;
@@ -47,18 +48,25 @@ import
org.apache.doris.nereids.trees.plans.logical.LogicalOlapScan;
import org.apache.doris.nereids.trees.plans.logical.LogicalTopN;
import org.apache.doris.nereids.trees.plans.logical.LogicalUnion;
import org.apache.doris.nereids.types.IntegerType;
+import org.apache.doris.nereids.util.LogicalPlanBuilder;
+import org.apache.doris.nereids.util.MemoTestUtils;
import org.apache.doris.nereids.util.PlanConstructor;
+import org.apache.doris.qe.SessionVariable;
import org.apache.doris.statistics.ColumnStatistic;
import org.apache.doris.statistics.ColumnStatisticBuilder;
import org.apache.doris.statistics.Statistics;
+import org.apache.doris.statistics.TableStatsMeta;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
+import mockit.Mock;
+import mockit.MockUp;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -67,10 +75,12 @@ import java.util.Map;
import java.util.Optional;
public class StatsCalculatorTest {
- private final LogicalOlapScan scan = PlanConstructor.newLogicalOlapScan(0,
"t1", 0);
+ private final LogicalOlapScan scan1 =
PlanConstructor.newLogicalOlapScan(0, "t1", 0);
+ private final LogicalOlapScan scan2 =
PlanConstructor.newLogicalOlapScan(0, "t1", 0);
+ private final LogicalOlapScan scan3 =
PlanConstructor.newLogicalOlapScan(0, "t1", 0);
private Group newFakeGroup() {
- GroupExpression groupExpression = new GroupExpression(scan);
+ GroupExpression groupExpression = new GroupExpression(scan1);
Group group = new Group(null, groupExpression,
new LogicalProperties(Collections::emptyList, () ->
DataTrait.EMPTY_TRAIT));
group.getLogicalExpressions().remove(0);
@@ -534,4 +544,32 @@ public class StatsCalculatorTest {
Statistics outputStats = calculator.computeLimit(limit, childStats);
Assertions.assertNull(outputStats.findColumnStatistics(ia).getHotValues());
}
+
+ @Test
+ public void testDisableJoinReorderIfStatsInvalid() throws IOException {
+ LogicalJoin<?, ?> join = (LogicalJoin<?, ?>) new
LogicalPlanBuilder(scan1)
+ .join(scan2, JoinType.LEFT_OUTER_JOIN, Pair.of(0, 0))
+ .join(scan3, JoinType.LEFT_OUTER_JOIN, Pair.of(0, 0))
+ .build();
+
+ // mock StatsCalculator to return -1 for getTableRowCount
+ new MockUp<OlapTable>() {
+ @Mock
+ public long getRowCountForIndex(long indexId, boolean strict) {
+ return -1;
+ }
+ };
+ new MockUp<TableStatsMeta>() {
+ @Mock
+ public long getRowCount(long indexId) {
+ return -1;
+ }
+ };
+ CascadesContext cascadesContext =
MemoTestUtils.createCascadesContext(join);
+ cascadesContext.getConnectContext().getSessionVariable()
+ .setVarOnce(SessionVariable.DISABLE_JOIN_REORDER, "false");
+
StatsCalculator.disableJoinReorderIfStatsInvalid(ImmutableList.of(scan1, scan2,
scan3), cascadesContext);
+ // because table row count is -1, so disable join reorder
+
Assertions.assertTrue(cascadesContext.getConnectContext().getSessionVariable().isDisableJoinReorder());
+ }
}
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/nereids/util/PlanChecker.java
b/fe/fe-core/src/test/java/org/apache/doris/nereids/util/PlanChecker.java
index 8c8da655873..2e4361000c9 100644
--- a/fe/fe-core/src/test/java/org/apache/doris/nereids/util/PlanChecker.java
+++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/util/PlanChecker.java
@@ -18,6 +18,7 @@
package org.apache.doris.nereids.util;
import org.apache.doris.analysis.ExplainOptions;
+import org.apache.doris.common.DdlException;
import org.apache.doris.nereids.CTEContext;
import org.apache.doris.nereids.CascadesContext;
import org.apache.doris.nereids.NereidsPlanner;
@@ -68,7 +69,9 @@ import
org.apache.doris.nereids.trees.plans.visitor.CustomRewriter;
import org.apache.doris.planner.PlanFragment;
import org.apache.doris.qe.ConnectContext;
import org.apache.doris.qe.OriginStatement;
+import org.apache.doris.qe.SessionVariable;
import org.apache.doris.qe.StmtExecutor;
+import org.apache.doris.qe.VariableMgr;
import org.apache.doris.thrift.TUniqueId;
import com.google.common.collect.ImmutableList;
@@ -305,13 +308,27 @@ public class PlanChecker {
}
public PlanChecker rewrite() {
- cascadesContext.withPlanProcess(true, () -> {
- Rewriter.getWholeTreeRewriter(cascadesContext).execute();
- cascadesContext.toMemo();
- cascadesContext.getStatementContext().setNeedPreMvRewrite(
-
PreMaterializedViewRewriter.needPreRewrite(cascadesContext));
- collectTableInfoAndInitHook(cascadesContext);
- });
+ SessionVariable sessionVariable =
cascadesContext.getConnectContext().getSessionVariable();
+ try {
+ cascadesContext.withPlanProcess(true, () -> {
+ Rewriter.getWholeTreeRewriter(cascadesContext).execute();
+ cascadesContext.toMemo();
+ cascadesContext.getStatementContext().setNeedPreMvRewrite(
+
PreMaterializedViewRewriter.needPreRewrite(cascadesContext));
+ collectTableInfoAndInitHook(cascadesContext);
+ });
+ } finally {
+ // revert Session Value, because setVarOnceInSql will set some
session variable, this would influence
+ // other test cases
+ try {
+ VariableMgr.revertSessionValue(sessionVariable);
+ // origin value init
+ sessionVariable.setIsSingleSetVar(false);
+ sessionVariable.clearSessionOriginValue();
+ } catch (DdlException e) {
+ Assertions.fail("revert Session Value fail when rewrite");
+ }
+ }
return this;
}
@@ -380,7 +397,22 @@ public class PlanChecker {
LogicalPlan parsedPlan = new NereidsParser().parseSingle(sql);
LogicalPlanAdapter parsedPlanAdaptor = new
LogicalPlanAdapter(parsedPlan, statementContext);
statementContext.setParsedStatement(parsedPlanAdaptor);
- planner.plan(parsedPlanAdaptor);
+
+ SessionVariable sessionVariable = connectContext.getSessionVariable();
+ try {
+ planner.plan(parsedPlanAdaptor);
+ } finally {
+ // revert Session Value, because setVarOnceInSql will set some
session variable, this would influence
+ // other test cases
+ try {
+ VariableMgr.revertSessionValue(sessionVariable);
+ // origin value init
+ sessionVariable.setIsSingleSetVar(false);
+ sessionVariable.clearSessionOriginValue();
+ } catch (DdlException e) {
+ Assertions.fail("revert Session Value fail when explain");
+ }
+ }
return planner;
}
@@ -693,7 +725,21 @@ public class PlanChecker {
connectContext.setStatementContext(statementContext);
LogicalPlanAdapter adapter = LogicalPlanAdapter.of(parsed);
adapter.setIsExplain(new ExplainOptions(ExplainLevel.ALL_PLAN, false));
- nereidsPlanner.plan(adapter);
+ SessionVariable sessionVariable = connectContext.getSessionVariable();
+ try {
+ nereidsPlanner.plan(adapter);
+ } finally {
+ // revert Session Value, because setVarOnceInSql will set some
session variable, this would influence
+ // other test cases
+ try {
+ VariableMgr.revertSessionValue(sessionVariable);
+ // origin value init
+ sessionVariable.setIsSingleSetVar(false);
+ sessionVariable.clearSessionOriginValue();
+ } catch (DdlException e) {
+ Assertions.fail("revert Session Value fail when explain");
+ }
+ }
consumer.accept(nereidsPlanner);
return this;
}
@@ -703,7 +749,21 @@ public class PlanChecker {
StatementContext statementContext = new
StatementContext(connectContext, new OriginStatement(sql, 0));
NereidsPlanner nereidsPlanner = new NereidsPlanner(statementContext);
connectContext.setStatementContext(statementContext);
- nereidsPlanner.plan(LogicalPlanAdapter.of(parsed));
+ SessionVariable sessionVariable = connectContext.getSessionVariable();
+ try {
+ nereidsPlanner.plan(LogicalPlanAdapter.of(parsed));
+ } finally {
+ // revert Session Value, because setVarOnceInSql will set some
session variable, this would influence
+ // other test cases
+ try {
+ VariableMgr.revertSessionValue(sessionVariable);
+ // origin value init
+ sessionVariable.setIsSingleSetVar(false);
+ sessionVariable.clearSessionOriginValue();
+ } catch (DdlException e) {
+ Assertions.fail("revert Session Value fail when plan");
+ }
+ }
consumer.accept(nereidsPlanner);
return this;
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]