diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/FillUpMissingSlots.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/FillUpMissingSlots.java index afee320f6f591f..127003f8f6707c 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/FillUpMissingSlots.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/FillUpMissingSlots.java @@ -156,6 +156,24 @@ public List buildRules() { }); }) ), + RuleType.FILL_UP_HAVING_PROJECT.build( + logicalHaving(logicalProject()).then(having -> { + LogicalProject project = having.child(); + Set projectOutputSet = project.getOutputSet(); + Set notExistedInProject = having.getExpressions().stream() + .map(Expression::getInputSlots) + .flatMap(Set::stream) + .filter(s -> !projectOutputSet.contains(s)) + .collect(Collectors.toSet()); + if (notExistedInProject.size() == 0) { + return null; + } + List projects = ImmutableList.builder() + .addAll(project.getProjects()).addAll(notExistedInProject).build(); + return new LogicalProject<>(ImmutableList.copyOf(project.getOutput()), + having.withChildren(new LogicalProject<>(projects, project.child()))); + }) + ), // Convert having to filter RuleType.FILL_UP_HAVING_PROJECT.build( logicalHaving().then(having -> new LogicalFilter<>(having.getConjuncts(), having.child())) diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/ReorderJoin.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/ReorderJoin.java index a9e685b1c89219..9a5c7d833c6748 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/ReorderJoin.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/ReorderJoin.java @@ -328,10 +328,12 @@ private static boolean canCombine(Plan input, boolean changeChildren) { Set joinFilter, Set usedPlansIndex, Map planToHintType) { List otherJoinConditions = Lists.newArrayList(); Set leftOutputExprIdSet = left.getOutputExprIdSet(); + int candidateIndex = 0; for (int i = 0; i < candidates.size(); i++) { if (usedPlansIndex.contains(i)) { continue; } + candidateIndex = i; Plan candidate = candidates.get(i); Set rightOutputExprIdSet = candidate.getOutputExprIdSet(); @@ -361,21 +363,14 @@ private static boolean canCombine(Plan input, boolean changeChildren) { } // All { left -> one in [candidates] } is CrossJoin // Generate a CrossJoin - for (int i = 0; i < candidates.size(); i++) { - if (usedPlansIndex.contains(i)) { - continue; - } - usedPlansIndex.add(i); - Plan right = candidates.get(i); - return new LogicalJoin<>(JoinType.CROSS_JOIN, - ExpressionUtils.EMPTY_CONDITION, - otherJoinConditions, - JoinHint.fromRightPlanHintType(planToHintType.getOrDefault(right, JoinHintType.NONE)), - Optional.empty(), - left, right); - } - - throw new RuntimeException("findInnerJoin: can't reach here"); + usedPlansIndex.add(candidateIndex); + Plan right = candidates.get(candidateIndex); + return new LogicalJoin<>(JoinType.CROSS_JOIN, + ExpressionUtils.EMPTY_CONDITION, + otherJoinConditions, + JoinHint.fromRightPlanHintType(planToHintType.getOrDefault(right, JoinHintType.NONE)), + Optional.empty(), + left, right); } private boolean nonJoinAndNonFilter(Plan plan) { diff --git a/regression-test/suites/nereids_syntax_p0/having.groovy b/regression-test/suites/nereids_syntax_p0/having.groovy index a9a4b3ae25379f..0caa0c9a78d300 100644 --- a/regression-test/suites/nereids_syntax_p0/having.groovy +++ b/regression-test/suites/nereids_syntax_p0/having.groovy @@ -68,4 +68,12 @@ suite("test_nereids_having") { order_qt_select "SELECT SUM(a1 + a2) FROM test_nereids_having_tbl HAVING SUM(a1 + a2) > 0"; order_qt_select "SELECT SUM(a1 + a2) FROM test_nereids_having_tbl HAVING SUM(a1 + a2 + 3) > 0"; order_qt_select "SELECT COUNT(*) FROM test_nereids_having_tbl HAVING COUNT(*) > 0"; + sql """SELECT alias2.`pk` AS field4 + FROM + (SELECT pk + FROM test_nereids_having_tbl AS SQ1_alias1 ) AS alias2 + HAVING alias2.`pk` <> + (SELECT * + FROM + (SELECT "xAbfcUSAOy") __DORIS_DUAL__ );""" }