-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[BugFix] Fix incorrect execution plan when generated column rewrite in join relation if left table and right table has the same column name #52584
Conversation
…relation if left table and right table has the same column name Why I'm doing: This problem is introduced by pr StarRocks#50398. In this pr, we introduce some new rule for generated column rewriting. The basic idea is following: 1. Collect the rewriting relation in every SELECT scope in query. (Expr -> ColumnRef) 2. Translate the expression relation into Operator mapping: ScalarOperator -> ColumnRefOperator 3. Introduce new rule says ReplaceScalarOperatorRule, use this new rule to replace the ScalarOperator into ColumnRefOperator when generating the logical plan in optimizer. This problem is that, ReplaceScalarOperatorRule use ScalarOperator.isEquivalent to check if a ScalarOperator is hit the rule instead of using ScalarOperator.equals. ScalarOperator.isEquivalent does not check the operator id but this id will be used to indentify the column with the same column name but come from different table in JOIN relation. (e.g column xx in TABLE A and column xx in TABLE B has same name but different id, in this case, ScalarOperator.isEquivalent return true but ScalarOperator.equals return false). So in this case, we will get the wrong mapping and generated a incorrent plan for generated column rewrite. What I'm doing: 1. Using ScalarOperator.equals instead 2. Introduce session variables disable_generated_column_rewrite for disable the generated column rewrite if we want. Signed-off-by: srlch <[email protected]>
public void setDisableGeneratedColumnRewrite(boolean disableGeneratedColumnRewrite) { | ||
this.disableGeneratedColumnRewrite = disableGeneratedColumnRewrite; | ||
} | ||
|
||
public int getConnectorIncrementalScanRangeNumber() { | ||
return connectorIncrementalScanRangeSize; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The most risky bug in this code is:
The DISABLE_GENERATED_COLUMN_REWRITE
variable may not be accounted for in the method that applies rewrites. If other flags interact with rewrite behavior, this oversight could cause unexpected issues.
You can modify the code like this:
// Assuming there is a method where rewrite decisions are applied.
// We need to ensure DISABLE_GENERATED_COLUMN_REWRITE is checked and used to control logic,
// particularly in any code path that performs or skips rewrites.
public void applyRewriteRules() {
if (isDisableGeneratedColumnRewrite()) {
// Add logic to skip generated column rewrite here
} else {
// Existing rewrite logic
}
}
Ensure that wherever rewrite rules are applied, you include logic to handle the disableGeneratedColumnRewrite
flag.
@@ -30,7 +30,7 @@ public ReplaceScalarOperatorRule(Map<ScalarOperator, ColumnRefOperator> translat | |||
@Override | |||
public ScalarOperator visit(ScalarOperator scalarOperator, ScalarOperatorRewriteContext context) { | |||
for (Map.Entry<ScalarOperator, ColumnRefOperator> m : translateMap.entrySet()) { | |||
if (ScalarOperator.isEquivalent(m.getKey(), scalarOperator)) { | |||
if (m.getKey().equals(scalarOperator)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not use Map.contains
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated
Signed-off-by: srlch <[email protected]>
Signed-off-by: srlch <[email protected]>
Signed-off-by: srlch <[email protected]>
Signed-off-by: srlch <[email protected]>
Signed-off-by: srlch <[email protected]>
Quality Gate passedIssues Measures |
[Java-Extensions Incremental Coverage Report]✅ pass : 0 / 0 (0%) |
[BE Incremental Coverage Report]✅ pass : 0 / 0 (0%) |
[FE Incremental Coverage Report]✅ pass : 6 / 6 (100.00%) file detail
|
@Mergifyio backport branch-3.3 |
@Mergifyio backport branch-3.2 |
✅ Backports have been created
|
✅ Backports have been created
|
…n join relation if left table and right table has the same column name (#52584) Signed-off-by: srlch <[email protected]> (cherry picked from commit af20339) # Conflicts: # fe/fe-core/src/main/java/com/starrocks/qe/SessionVariable.java
…n join relation if left table and right table has the same column name (#52584) Signed-off-by: srlch <[email protected]> (cherry picked from commit af20339) # Conflicts: # fe/fe-core/src/main/java/com/starrocks/qe/SessionVariable.java
…n join relation if left table and right table has the same column name (StarRocks#52584) Signed-off-by: srlch <[email protected]>
…n join relation if left table and right table has the same column name (StarRocks#52584) Signed-off-by: srlch <[email protected]>
…n join relation if left table and right table has the same column name (backport #52584) (#52643) Signed-off-by: srlch <[email protected]>
…n join relation if left table and right table has the same column name (backport #52584) (#52644) Signed-off-by: srlch <[email protected]>
…n join relation if left table and right table has the same column name (StarRocks#52584) Signed-off-by: srlch <[email protected]> Signed-off-by: zhiminr.ren <[email protected]>
Why I'm doing:
This problem is introduced by pr #50398. In this pr, we introduce some new rule for generated column rewriting. The basic idea is following:
SELECT
scope in query. (Expr
->SlotRef
)ScalarOperator
->ColumnRefOperator
ReplaceScalarOperatorRule
, use this new rule to replace theScalarOperator
byColumnRefOperator
when generating the logical plan in optimizer.This problem is that,
ReplaceScalarOperatorRule
useScalarOperator.isEquivalent
to check if aScalarOperator
hit the rule instead of usingScalarOperator.equals
.ScalarOperator.isEquivalent
does not check the operator id but this id will be used to identify the column with the same column name but come from different table in JOIN relation. (e.g column xx inTABLE A
and column xx inTABLE B
has same name but different id, in this case,ScalarOperator.isEquivalent
return true butScalarOperator.equals
return false). So in this case, we will get the wrong mapping and generated a incorrect plan for generated column rewrite.What I'm doing:
ScalarOperator.equals
insteadFixes #issue
What type of PR is this:
Does this PR entail a change in behavior?
If yes, please specify the type of change:
Checklist:
Bugfix cherry-pick branch check: