Zhen Chen created CALCITE-7645:
----------------------------------
Summary: AggregateUnionTransposeRule drops aggregate FILTER when
rebuilding child aggregate calls
Key: CALCITE-7645
URL: https://issues.apache.org/jira/browse/CALCITE-7645
Project: Calcite
Issue Type: Bug
Components: core
Affects Versions: 1.42.0
Reporter: Zhen Chen
Assignee: Zhen Chen
Fix For: 1.43.0
AggregateUnionTransposeRule accepts aggregate calls with FILTER, but in the
child aggregate rebuild path it does not preserve the original
AggregateCall.filterArg.
The normal path copies aggRel.getAggCallList(), so filtered aggregate calls are
preserved. However, when the nullability of an aggregate argument differs
between the UNION output type and a specific UNION input type, the rule
recreates the child AggregateCall to re-evaluate nullability. That recreated
call currently passes filterArg = -1, which drops the aggregate FILTER
predicate.
Reproducer:
select min(v) filter (where p)
from (
select * from (values (10, false), (100, true)) as t(v, p)
union all
select * from (values (cast(null as integer), true), (200, true)) as t(v, p)
)
Expected result:
100
After applying AggregateUnionTransposeRule, the first pushed-down aggregate
becomes MIN($0) instead of MIN($0) FILTER $1. That branch returns 10, and the
top MIN therefore returns 10, which is incorrect.
Observed rewritten plan:
LogicalAggregate(group=[{}], EXPR$0=[MIN($0)])
LogicalUnion(all=[true])
LogicalAggregate(group=[{}], EXPR$0=[MIN($0)])
LogicalProject(V=[$0], P=[$1])
LogicalValues(tuples=[[\{ 10, false }, \{ 100, true }]])
LogicalAggregate(group=[{}], EXPR$0=[MIN($0) FILTER $1])
LogicalProject(V=[$0], P=[$1])
LogicalValues(tuples=[[\{ null, true }, \{ 200, true }]])
--
This message was sent by Atlassian Jira
(v8.20.10#820010)