Skip to content

Commit

Permalink
[BugFix] Fix eliminate join lose predicate (#52273)
Browse files Browse the repository at this point in the history
Signed-off-by: Seaven <seaven_7@qq.com>
(cherry picked from commit aeafef0)
  • Loading branch information
Seaven authored and mergify[bot] committed Oct 24, 2024
1 parent 4933c4e commit d123b86
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ private EliminateJoinWithConstantRule(int index) {
@Override
public boolean check(OptExpression input, OptimizerContext context) {
if (OperatorType.LOGICAL_PROJECT.equals(input.inputAt(constantIndex).getOp().getOpType())) {
LogicalProjectOperator project = input.inputAt(constantIndex).getOp().cast();
if (!project.getColumnRefMap().values().stream().allMatch(ScalarOperator::isConstant)) {
return false;
}
OptExpression optExpression = input.inputAt(constantIndex);
OptExpression valuesOpt = optExpression.inputAt(0);
return checkValuesOptExpression(valuesOpt);
Expand Down Expand Up @@ -106,35 +110,38 @@ public List<OptExpression> onMatch(OptExpression joinOpt,
OptExpression otherOpt,
OptExpression constantOpt,
OptimizerContext context) {
Map<ColumnRefOperator, ScalarOperator> outputs = Maps.newHashMap();

LogicalJoinOperator joinOperator = (LogicalJoinOperator) joinOpt.getOp();
JoinOperator joinType = joinOperator.getJoinType();
LogicalProjectOperator projectOperator = (LogicalProjectOperator) constantOpt.getOp();

ScalarOperator condition = joinOperator.getOnPredicate();
ScalarOperator predicate = otherOpt.getOp().getPredicate();
ScalarOperator predicate = joinOperator.getPredicate();

// rewrite join's on-predicate with constant column values
LogicalProjectOperator projectOperator = (LogicalProjectOperator) constantOpt.getOp();
ReplaceColumnRefRewriter rewriter = new ReplaceColumnRefRewriter(projectOperator.getColumnRefMap());
ScalarOperator rewrittenCondition = rewriter.rewrite(condition);
ScalarOperator rewrittenPredicate = rewriter.rewrite(predicate);

// output join and constant opt's output columns
Map<ColumnRefOperator, ScalarOperator> outputs = Maps.newHashMap();
joinOpt.getOutputColumns().getStream().map(context.getColumnRefFactory()::getColumnRef)
.forEach(ref -> outputs.put(ref, rewriter.rewrite(ref)));
if (joinOperator.getJoinType().isOuterJoin()) {
// transform join's on-predicate with case-when operator
constantOpt.getRowOutputInfo().getColumnRefMap().entrySet().stream()
.forEach(entry -> {
ScalarOperator transformed = transformOuterJoinOnPredicate(
joinOperator, entry.getValue(), rewrittenCondition);
outputs.put(entry.getKey(), transformed);
});
constantOpt.getRowOutputInfo().getColumnRefMap().forEach((key, value) -> {
ScalarOperator t = transformOuterJoinOnPredicate(joinOperator, value, rewrittenCondition);
outputs.put(key, t);
});
} else {
predicate = Utils.compoundAnd(predicate, rewrittenCondition);
rewrittenPredicate = Utils.compoundAnd(rewrittenPredicate, rewrittenCondition);
}

LogicalProjectOperator project = new LogicalProjectOperator(outputs);
OptExpression result = OptExpression.create(project, otherOpt);

// save predicate
if (predicate != null) {
result = OptExpression.create(new LogicalFilterOperator(predicate), result);
if (rewrittenPredicate != null) {
result = OptExpression.create(new LogicalFilterOperator(rewrittenPredicate), result);
}
return Lists.newArrayList(result);
}
Expand Down
12 changes: 12 additions & 0 deletions fe/fe-core/src/test/java/com/starrocks/sql/plan/JoinTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -3290,4 +3290,16 @@ public void testOuterJoinOnConstValue() throws Exception {
" | join op: RIGHT OUTER JOIN\n" +
" | colocate: false, reason:");
}

@Test
public void testJoinOnConstValue() throws Exception {
String query = "select coalesce(b.v1, a.v1) as v1, a.v2 \n" +
"from t0 a left join (select 'cccc' as v1, 'dddd' as v2) b on a.v1 = b.v1 \n" +
"where coalesce(b.v1, a.v1) = '1';";
String plan = getFragmentPlan(query);
assertContainsIgnoreColRefs(plan, " 0:OlapScanNode\n" +
" TABLE: t0\n" +
" PREAGGREGATION: ON\n" +
" PREDICATES: coalesce('cccc', CAST(1: v1 AS VARCHAR)) = '1'");
}
}

0 comments on commit d123b86

Please sign in to comment.