Skip to content

Commit 4388b91

Browse files
stephen-shelbymergify[bot]
authored andcommitted
[Enhancement] Add enable_optimizer_rule_debug session variable for rule failure diagnosis (#63693)
Signed-off-by: stephen <[email protected]> (cherry picked from commit 6a318c2) # Conflicts: # fe/fe-core/src/main/java/com/starrocks/sql/optimizer/QueryOptimizer.java # fe/fe-core/src/main/java/com/starrocks/sql/optimizer/task/RewriteTreeTask.java # fe/fe-core/src/main/java/com/starrocks/sql/optimizer/task/TaskContext.java # fe/fe-core/src/test/java/com/starrocks/sql/plan/GroupingSetsTest.java
1 parent 7f40408 commit 4388b91

File tree

12 files changed

+1384
-17
lines changed

12 files changed

+1384
-17
lines changed

fe/fe-core/src/main/java/com/starrocks/qe/SessionVariable.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -725,6 +725,8 @@ public static MaterializedViewRewriteMode parse(String str) {
725725

726726
public static final String ENABLE_PLAN_VALIDATION = "enable_plan_validation";
727727

728+
public static final String ENABLE_OPTIMIZER_RULE_DEBUG = "enable_optimizer_rule_debug";
729+
728730
public static final String ENABLE_STRICT_TYPE = "enable_strict_type";
729731

730732
public static final String PARTIAL_UPDATE_MODE = "partial_update_mode";
@@ -2195,6 +2197,9 @@ public long getConnectorSinkTargetMaxFileSize() {
21952197
@VarAttr(name = ENABLE_PLAN_VALIDATION, flag = VariableMgr.INVISIBLE)
21962198
private boolean enablePlanValidation = true;
21972199

2200+
@VarAttr(name = ENABLE_OPTIMIZER_RULE_DEBUG)
2201+
private boolean enableOptimizerRuleDebug = false;
2202+
21982203
@VarAttr(name = SCAN_OR_TO_UNION_LIMIT, flag = VariableMgr.INVISIBLE)
21992204
private int scanOrToUnionLimit = 4;
22002205

@@ -4297,6 +4302,14 @@ public void setEnablePlanValidation(boolean val) {
42974302
this.enablePlanValidation = val;
42984303
}
42994304

4305+
public boolean enableOptimizerRuleDebug() {
4306+
return this.enableOptimizerRuleDebug;
4307+
}
4308+
4309+
public void setEnableOptimizerRuleDebug(boolean enableOptimizerRuleDebug) {
4310+
this.enableOptimizerRuleDebug = enableOptimizerRuleDebug;
4311+
}
4312+
43004313
public boolean isCboPruneSubfield() {
43014314
return cboPruneSubfield;
43024315
}

fe/fe-core/src/main/java/com/starrocks/sql/optimizer/QueryOptimizer.java

Lines changed: 1095 additions & 0 deletions
Large diffs are not rendered by default.

fe/fe-core/src/main/java/com/starrocks/sql/optimizer/RowOutputInfo.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ public List<ColumnOutputInfo> getCommonColInfo() {
137137
}
138138

139139
public List<ColumnRefOperator> getOutputColRefs() {
140-
return chooseOutputMap().values().stream().map(e -> e.getColumnRef()).collect(Collectors.toList());
140+
return chooseOutputMap().values().stream().map(ColumnOutputInfo::getColumnRef).collect(Collectors.toList());
141141
}
142142

143143
public Map<ColumnRefOperator, ScalarOperator> getColumnRefMap() {

fe/fe-core/src/main/java/com/starrocks/sql/optimizer/base/ColumnRefSet.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public ColumnRefSet(Collection<ColumnRefOperator> refs) {
4747

4848
public static ColumnRefSet createByIds(Collection<Integer> colIds) {
4949
ColumnRefSet columnRefSet = new ColumnRefSet();
50-
colIds.stream().forEach(columnRefSet::union);
50+
colIds.forEach(columnRefSet::union);
5151
return columnRefSet;
5252
}
5353

fe/fe-core/src/main/java/com/starrocks/sql/optimizer/rule/transformation/PushDownAggregateGroupingSetsRule.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ private OptExpression buildSelectConsume(ColumnRefFactory factory,
247247
/*
248248
* select a, b, c, d, null, sum(x) x from t group by rollup(a, b, c, d)
249249
*/
250-
private OptExpression buildSubRepeatConsume(ColumnRefFactory factory,
250+
public OptExpression buildSubRepeatConsume(ColumnRefFactory factory,
251251
Map<ColumnRefOperator, ColumnRefOperator> outputs,
252252
LogicalAggregationOperator aggregate, LogicalRepeatOperator repeat,
253253
int cteId) {
@@ -357,4 +357,4 @@ private OptExpression buildSubRepeatConsume(ColumnRefFactory factory,
357357
return OptExpression.create(projectOperator,
358358
OptExpression.create(newAggregate, OptExpression.create(newRepeat, OptExpression.create(consume))));
359359
}
360-
}
360+
}

fe/fe-core/src/main/java/com/starrocks/sql/optimizer/task/ApplyRuleTask.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ public void execute() {
9191
extractExpressions.add(extractExpr);
9292
List<OptExpression> targetExpressions;
9393
OptimizerTraceUtil.logApplyRuleBefore(context.getOptimizerContext(), rule, extractExpr);
94+
9495
try (Timer ignore = Tracers.watchScope(Tracers.Module.OPTIMIZER, rule.getClass().getSimpleName())) {
9596
targetExpressions = rule.transform(extractExpr, context.getOptimizerContext());
9697
} catch (StarRocksPlannerException e) {

fe/fe-core/src/main/java/com/starrocks/sql/optimizer/task/RewriteTreeTask.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import com.starrocks.sql.optimizer.operator.OperatorType;
2424
import com.starrocks.sql.optimizer.operator.pattern.Pattern;
2525
import com.starrocks.sql.optimizer.rule.Rule;
26+
import com.starrocks.sql.optimizer.validate.PlanValidator;
2627

2728
import java.util.List;
2829

@@ -54,8 +55,29 @@ public OptExpression getResult() {
5455

5556
@Override
5657
public void execute() {
58+
<<<<<<< HEAD
59+
=======
60+
if (rules.stream().allMatch(rule -> context.getOptimizerContext()
61+
.getOptimizerOptions().isRuleDisable(rule.type()))) {
62+
return;
63+
}
64+
65+
// Save whole tree state before rule group execution for validation
66+
OptExpression wholePlanBefore = null;
67+
if (context.getOptimizerContext().getSessionVariable().enableOptimizerRuleDebug()) {
68+
wholePlanBefore = planTree.getInputs().get(0);
69+
}
70+
71+
>>>>>>> 6a318c2507 ([Enhancement] Add enable_optimizer_rule_debug session variable for rule failure diagnosis (#63693))
5772
// first node must be RewriteAnchorNode
5873
rewrite(planTree, 0, planTree.getInputs().get(0));
74+
75+
// Validate after the entire rule group execution
76+
if (wholePlanBefore != null && change > 0) {
77+
OptExpression wholePlanAfter = planTree.getInputs().get(0);
78+
PlanValidator.validateAfterRule(wholePlanBefore, wholePlanAfter, rules.get(0), context);
79+
}
80+
5981
// pushdownNotNullPredicates should task-bind, reset it before another RewriteTreeTask
6082
// TODO: refactor TaskContext to make it local to support this requirement better?
6183
context.getOptimizerContext().clearNotNullPredicates();
@@ -83,6 +105,7 @@ protected OptExpression applyRules(OptExpression parent, int childIndex, OptExpr
83105
}
84106

85107
OptimizerTraceUtil.logApplyRuleBefore(context.getOptimizerContext(), rule, root);
108+
86109
List<OptExpression> result;
87110
try (Timer ignore = Tracers.watchScope(Tracers.Module.OPTIMIZER, rule.getClass().getSimpleName())) {
88111
result = rule.transform(root, context.getOptimizerContext());

fe/fe-core/src/main/java/com/starrocks/sql/optimizer/task/TaskContext.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,26 @@
1818
import com.starrocks.sql.optimizer.OptimizerContext;
1919
import com.starrocks.sql.optimizer.base.ColumnRefSet;
2020
import com.starrocks.sql.optimizer.base.PhysicalPropertySet;
21+
<<<<<<< HEAD
2122
import com.starrocks.sql.optimizer.operator.physical.PhysicalOlapScanOperator;
2223

2324
import java.util.Collections;
2425
import java.util.List;
26+
=======
27+
import com.starrocks.sql.optimizer.validate.PlanValidator;
28+
>>>>>>> 6a318c2507 ([Enhancement] Add enable_optimizer_rule_debug session variable for rule failure diagnosis (#63693))
2529

2630
// The context for optimizer task
2731
public class TaskContext {
2832
private final OptimizerContext optimizerContext;
2933
private final PhysicalPropertySet requiredProperty;
3034
private ColumnRefSet requiredColumns;
3135
private double upperBoundCost;
36+
<<<<<<< HEAD
3237
private List<PhysicalOlapScanOperator> allPhysicalOlapScanOperators;
38+
=======
39+
private final PlanValidator planValidator;
40+
>>>>>>> 6a318c2507 ([Enhancement] Add enable_optimizer_rule_debug session variable for rule failure diagnosis (#63693))
3341

3442
public TaskContext(OptimizerContext context,
3543
PhysicalPropertySet physicalPropertySet,
@@ -39,7 +47,15 @@ public TaskContext(OptimizerContext context,
3947
this.requiredProperty = physicalPropertySet;
4048
this.requiredColumns = requiredColumns;
4149
this.upperBoundCost = cost;
50+
<<<<<<< HEAD
4251
this.allPhysicalOlapScanOperators = Collections.emptyList();
52+
=======
53+
this.planValidator = new PlanValidator();
54+
}
55+
56+
public PlanValidator getPlanValidator() {
57+
return planValidator;
58+
>>>>>>> 6a318c2507 ([Enhancement] Add enable_optimizer_rule_debug session variable for rule failure diagnosis (#63693))
4359
}
4460

4561
public OptimizerContext getOptimizerContext() {

fe/fe-core/src/main/java/com/starrocks/sql/optimizer/validate/CTEUniqueChecker.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ public static CTEUniqueChecker getInstance() {
4343
return INSTANCE;
4444
}
4545

46-
4746
@Override
4847
public void validate(OptExpression physicalPlan, TaskContext taskContext) {
4948
CTEUniqueChecker.Visitor visitor = new CTEUniqueChecker.Visitor();

fe/fe-core/src/main/java/com/starrocks/sql/optimizer/validate/InputDependenciesChecker.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -199,15 +199,15 @@ private void checkInputCols(ColumnRefSet inputCols, ColumnRefSet usedCols, OptEx
199199
ColumnRefSet missedCols = usedCols.clone();
200200
missedCols.except(inputCols);
201201
if (!missedCols.isEmpty()) {
202-
String message = String.format("Invalid plan:%s%s%s The required cols %s cannot obtain from input cols %s.",
202+
String message = String.format("Invalid plan:%s%s\n%s \nThe required cols %s cannot obtain from input cols %s.",
203203
System.lineSeparator(), optExpr.debugString(), PREFIX, missedCols, inputCols);
204204
throw new StarRocksPlannerException(message, ErrorType.INTERNAL_ERROR);
205205
}
206206
}
207207

208208
private void checkInputType(ColumnRefOperator inputCol, ColumnRefOperator outputCol, OptExpression optExpression) {
209209
if (!outputCol.getType().isFullyCompatible(inputCol.getType())) {
210-
String message = String.format("Invalid plan:%s%s%s Type of output col %s is not fully compatible with " +
210+
String message = String.format("Invalid plan:%s%s\n%s \nType of output col %s is not fully compatible with " +
211211
"type of input col %s.",
212212
System.lineSeparator(), optExpression.debugString(), PREFIX, outputCol, inputCol);
213213
throw new StarRocksPlannerException(message, ErrorType.INTERNAL_ERROR);
@@ -216,7 +216,7 @@ private void checkInputType(ColumnRefOperator inputCol, ColumnRefOperator output
216216

217217
private void checkChildNumberOfSet(int inputSize, int requiredSize, OptExpression optExpression) {
218218
if (inputSize != requiredSize) {
219-
String message = String.format("Invalid plan:%s%s%s. The required number of children is %d but found %d.",
219+
String message = String.format("Invalid plan:%s%s\n%s. \nThe required number of children is %d but found %d.",
220220
System.lineSeparator(), optExpression.debugString(), PREFIX, requiredSize, inputSize);
221221
throw new StarRocksPlannerException(message, ErrorType.INTERNAL_ERROR);
222222
}

0 commit comments

Comments
 (0)