[fix](nereids) Bind slot in having to its direct child instead of grand child (#16047)

For example, in this case, the `date` in having clause should be bind to alias which has same name, instead of `date` field of the relation

SELECT date_format(date, '%x%v') AS `date` FROM `tb_holiday` WHERE `date` between 20221111 AND 20221116 HAVING date = 202245 ORDER BY date;
This commit is contained in:
AKIRA
2023-01-19 13:19:16 +08:00
committed by GitHub
parent abdf56bfa5
commit c5beab39c0
3 changed files with 45 additions and 12 deletions

View File

@ -427,8 +427,8 @@ public class BindSlotReference implements AnalysisRuleFactory {
})
),
RuleType.BINDING_HAVING_SLOT.build(
logicalHaving(any()).when(Plan::canBind).thenApply(ctx -> {
LogicalHaving<Plan> having = ctx.root;
logicalHaving(aggregate()).when(Plan::canBind).thenApply(ctx -> {
LogicalHaving<Aggregate<GroupPlan>> having = ctx.root;
Plan childPlan = having.child();
// We should deduplicate the slots, otherwise the binding process will fail due to the
// ambiguous slots exist.
@ -450,6 +450,30 @@ public class BindSlotReference implements AnalysisRuleFactory {
return new LogicalHaving<>(boundConjuncts, having.child());
})
),
RuleType.BINDING_HAVING_SLOT.build(
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.
List<Slot> childChildSlots = childPlan.children().stream()
.flatMap(plan -> plan.getOutputSet().stream())
.collect(Collectors.toList());
SlotBinder childChildBinder = new SlotBinder(toScope(childChildSlots),
ctx.cascadesContext);
List<Slot> childSlots = childPlan.getOutputSet().stream()
.collect(Collectors.toList());
SlotBinder childBinder = new SlotBinder(toScope(childSlots),
ctx.cascadesContext);
Set<Expression> boundConjuncts = having.getConjuncts().stream().map(
expr -> {
expr = childBinder.bind(expr);
return childChildBinder.bind(expr);
})
.collect(Collectors.toSet());
return new LogicalHaving<>(boundConjuncts, having.child());
})
),
RuleType.BINDING_ONE_ROW_RELATION_SLOT.build(
// we should bind UnboundAlias in the UnboundOneRowRelation
unboundOneRowRelation().thenApply(ctx -> {

View File

@ -26,3 +26,8 @@
-- !case5 --
2 3
-- !case6 --
202245
202245
202245

View File

@ -16,10 +16,10 @@
// under the License.
suite("test_group_having_alias") {
sql """
DROP TABLE IF EXISTS `tb_holiday`;
"""
sql """DROP TABLE IF EXISTS `test_having_alias_tb`; """
sql """DROP TABLE IF EXISTS `tb_holiday`;"""
sql """DROP TABLE IF EXISTS `test_having_alias_tb`; """
sql """
CREATE TABLE `tb_holiday` (
`date` bigint(20) NOT NULL ,
@ -71,11 +71,6 @@
ORDER BY date;
"""
sql """
DROP TABLE IF EXISTS `tb_holiday`;
"""
sql """ DROP TABLE IF EXISTS `test_having_alias_tb`; """
sql """
CREATE TABLE `test_having_alias_tb` (
`id` int(11) NULL,
@ -98,5 +93,14 @@
qt_case3 """ SELECT id, v1-2 as v, sum(v2) v2 FROM test_having_alias_tb GROUP BY id,v having(v>0 AND sum(v2)>1) ORDER BY id,v; """
qt_case4 """ SELECT id, v1-2 as v, sum(v2) vsum FROM test_having_alias_tb GROUP BY id,v having(v>0 AND vsum>1) ORDER BY id,v; """
qt_case5 """ SELECT id, max(v1) v1 FROM test_having_alias_tb GROUP BY 1 having count(distinct v1)>1 ORDER BY id; """
sql """ DROP TABLE IF EXISTS `test_having_alias_tb`; """
}
sql """set enable_nereids_planner=true"""
sql """set enable_fallback_to_original_planner=false"""
qt_case6 """
SELECT date_format(date, '%x%v') AS `date` FROM `tb_holiday` WHERE `date` between 20221111 AND 20221116 HAVING date = 202245 ORDER BY date;
"""
sql """DROP TABLE IF EXISTS `test_having_alias_tb`; """
sql """DROP TABLE IF EXISTS `tb_holiday`;"""
sql """DROP TABLE IF EXISTS `test_having_alias_tb`; """
}