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)

Reply via email to