[fix](nereids) having with no group by is not parsed correctly (#14883)
SQL: SELECT * FROM tbl HAVING c1 > 10;
This commit is contained in:
@ -1076,11 +1076,29 @@ public class LogicalPlanBuilder extends DorisParserBaseVisitor<Object> {
|
||||
// from -> where -> group by -> having -> select
|
||||
|
||||
LogicalPlan filter = withFilter(inputRelation, whereClause);
|
||||
SelectColumnClauseContext columnCtx = selectClause.selectColumnClause();
|
||||
LogicalPlan aggregate = withAggregate(filter, columnCtx, aggClause);
|
||||
SelectColumnClauseContext selectColumnCtx = selectClause.selectColumnClause();
|
||||
LogicalPlan aggregate = withAggregate(filter, selectColumnCtx, aggClause);
|
||||
// TODO: replace and process having at this position
|
||||
LogicalPlan having = withHaving(aggregate, havingClause);
|
||||
return withProjection(having, selectClause.selectColumnClause(), aggClause);
|
||||
if (!(aggregate instanceof Aggregate) && havingClause.isPresent()) {
|
||||
// create a project node for pattern match of ProjectToGlobalAggregate rule
|
||||
// then ProjectToGlobalAggregate rule can insert agg node as LogicalHaving node's child
|
||||
LogicalPlan project;
|
||||
if (selectColumnCtx.EXCEPT() != null) {
|
||||
List<NamedExpression> expressions = getNamedExpressions(selectColumnCtx.namedExpressionSeq());
|
||||
if (!expressions.stream().allMatch(UnboundSlot.class::isInstance)) {
|
||||
throw new ParseException("only column name is supported in except clause", selectColumnCtx);
|
||||
}
|
||||
project = new LogicalProject<>(ImmutableList.of(new UnboundStar(Collections.emptyList())),
|
||||
expressions, aggregate);
|
||||
} else {
|
||||
List<NamedExpression> projects = getNamedExpressions(selectColumnCtx.namedExpressionSeq());
|
||||
project = new LogicalProject<>(projects, Collections.emptyList(), aggregate);
|
||||
}
|
||||
return new LogicalHaving<>(getExpression((havingClause.get().booleanExpression())), project);
|
||||
} else {
|
||||
LogicalPlan having = withHaving(aggregate, havingClause);
|
||||
return withProjection(having, selectColumnCtx, aggClause);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -54,6 +54,7 @@ public enum RuleType {
|
||||
REPLACE_SORT_EXPRESSION_BY_CHILD_OUTPUT(RuleTypeClass.REWRITE),
|
||||
|
||||
FILL_UP_HAVING_AGGREGATE(RuleTypeClass.REWRITE),
|
||||
FILL_UP_HAVING_PROJECT(RuleTypeClass.REWRITE),
|
||||
FILL_UP_SORT_AGGREGATE(RuleTypeClass.REWRITE),
|
||||
FILL_UP_SORT_HAVING_AGGREGATE(RuleTypeClass.REWRITE),
|
||||
FILL_UP_SORT_PROJECT(RuleTypeClass.REWRITE),
|
||||
|
||||
@ -246,12 +246,12 @@ public class BindSlotReference implements AnalysisRuleFactory {
|
||||
})
|
||||
),
|
||||
RuleType.BINDING_HAVING_SLOT.build(
|
||||
logicalHaving(aggregate()).when(Plan::canBind).thenApply(ctx -> {
|
||||
LogicalHaving<Aggregate<GroupPlan>> having = ctx.root;
|
||||
Aggregate<GroupPlan> aggregate = having.child();
|
||||
logicalHaving(any()).when(Plan::canBind).thenApply(ctx -> {
|
||||
LogicalHaving<Plan> having = ctx.root;
|
||||
Plan childPlan = having.child();
|
||||
// We should deduplicate the slots, otherwise the binding process will fail due to the
|
||||
// ambiguous slots exist.
|
||||
Set<Slot> boundSlots = Stream.concat(Stream.of(aggregate), aggregate.children().stream())
|
||||
Set<Slot> boundSlots = Stream.concat(Stream.of(childPlan), childPlan.children().stream())
|
||||
.flatMap(plan -> plan.getOutput().stream())
|
||||
.collect(Collectors.toSet());
|
||||
Expression boundPredicates = new SlotBinder(
|
||||
|
||||
@ -120,7 +120,10 @@ public class FillUpMissingSlots implements AnalysisRuleFactory {
|
||||
having.getPredicates(), r.getSubstitution());
|
||||
return new LogicalFilter<>(newPredicates, a);
|
||||
});
|
||||
})
|
||||
})),
|
||||
RuleType.FILL_UP_HAVING_PROJECT.build(
|
||||
logicalHaving(logicalProject()).then(having -> new LogicalFilter<>(having.getPredicates(),
|
||||
having.child()))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@ -54,3 +54,49 @@
|
||||
2
|
||||
3
|
||||
|
||||
-- !select --
|
||||
9
|
||||
|
||||
-- !select --
|
||||
1
|
||||
1
|
||||
1
|
||||
2
|
||||
2
|
||||
2
|
||||
3
|
||||
3
|
||||
3
|
||||
|
||||
-- !select --
|
||||
1
|
||||
1
|
||||
1
|
||||
2
|
||||
2
|
||||
2
|
||||
3
|
||||
3
|
||||
3
|
||||
|
||||
-- !select --
|
||||
36
|
||||
|
||||
-- !select --
|
||||
36
|
||||
|
||||
-- !select --
|
||||
36
|
||||
|
||||
-- !select --
|
||||
36
|
||||
|
||||
-- !select --
|
||||
54
|
||||
|
||||
-- !select --
|
||||
54
|
||||
|
||||
-- !select --
|
||||
9
|
||||
|
||||
|
||||
@ -18,6 +18,7 @@
|
||||
suite("test_nereids_having") {
|
||||
|
||||
sql "SET enable_nereids_planner=true"
|
||||
sql "SET enable_fallback_to_original_planner=true"
|
||||
sql "SET enable_vectorized_engine=true"
|
||||
|
||||
sql "DROP TABLE IF EXISTS test_nereids_having_tbl"
|
||||
@ -57,4 +58,15 @@ suite("test_nereids_having") {
|
||||
order_qt_select "SELECT a1, SUM(a1 + a2) FROM test_nereids_having_tbl GROUP BY a1 HAVING SUM(a1 + a2) > 0";
|
||||
order_qt_select "SELECT a1, SUM(a1 + a2) FROM test_nereids_having_tbl GROUP BY a1 HAVING SUM(a1 + a2 + 3) > 0";
|
||||
order_qt_select "SELECT a1 FROM test_nereids_having_tbl GROUP BY a1 HAVING COUNT(*) > 0";
|
||||
order_qt_select "SELECT COUNT(*) FROM test_nereids_having_tbl HAVING COUNT(*) > 0";
|
||||
|
||||
order_qt_select "SELECT a1 as value FROM test_nereids_having_tbl HAVING a1 > 0";
|
||||
order_qt_select "SELECT a1 as value FROM test_nereids_having_tbl HAVING value > 0";
|
||||
order_qt_select "SELECT SUM(a2) FROM test_nereids_having_tbl HAVING SUM(a2) > 0";
|
||||
order_qt_select "SELECT SUM(a2) as value FROM test_nereids_having_tbl HAVING SUM(a2) > 0";
|
||||
order_qt_select "SELECT SUM(a2) as value FROM test_nereids_having_tbl HAVING value > 0";
|
||||
order_qt_select "SELECT SUM(a2) FROM test_nereids_having_tbl HAVING MIN(pk) > 0";
|
||||
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";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user