[
https://issues.apache.org/jira/browse/CALCITE-7863?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18128854#comment-18128854
]
Mihai Budiu commented on CALCITE-7863:
--------------------------------------
I think that the JavaDoc being wrong is a bug which needs to be fixed as well.
> AggregateReduceFunctionsOnGroupKeysRule fails for constant aggregates on
> empty input
> ------------------------------------------------------------------------------------
>
> Key: CALCITE-7863
> URL: https://issues.apache.org/jira/browse/CALCITE-7863
> Project: Calcite
> Issue Type: Bug
> Components: core
> Affects Versions: 1.42.0
> Reporter: Zhen Chen
> Assignee: Zhen Chen
> Priority: Major
> Labels: pull-request-available
>
> {{AggregateReduceFunctionsOnGroupKeysRule}} incorrectly replaces constant
> aggregate calls with their arguments when the aggregate has no grouping keys.
> For a global aggregate, an empty input must still produce one row. {{MIN(1)}}
> and {{MAX(1)}} must return {{NULL}} in that row. Replacing these calls with
> the constant {{1}} does not preserve this behavior.
> The issue requires explicitly applying this rule. The query returns the
> correct result with the default planner configuration.
> To reproduce in a Quidem test, enable this rule:
> {code:java}
> !set hep-rules "
> +CoreRules.AGGREGATE_REDUCE_FUNCTIONS_ON_GROUP_KEYS"
> {code}
> Then execute:
> {code:java}
> SELECT
> MIN(1) AS min_v,
> MAX(1) AS max_v
> FROM (VALUES (7)) AS t(x)
> WHERE x < 0; {code}
> *Expected result:* One row containing two {{NULL}} values.
> {code:java}
> +-------+-------+
> | MIN_V | MAX_V |
> +-------+-------+
> | | |
> +-------+-------+
> (1 row) {code}
> *Actual behavior before the fix:* Query preparation fails with an
> {{{}AssertionError{}}}:
>
> {{java.lang.AssertionError: Cannot add expression of different type to set:
> set type is RecordType(INTEGER MIN_V, INTEGER MAX_V) NOT NULL
> expression type is RecordType(INTEGER NOT NULL MIN_V, INTEGER NOT NULL MAX_V)
> NOT NULL
> expression is LogicalValues(tuples=[[\{ 1, 1 }]])
> Type mismatch:
> rowtype of original rel: RecordType(INTEGER MIN_V, INTEGER MAX_V) NOT NULL
> rowtype of new rel: RecordType(INTEGER NOT NULL MIN_V, INTEGER NOT NULL
> MAX_V) NOT NULL
> Difference:
> MIN_V: INTEGER -> INTEGER NOT NULL
> MAX_V: INTEGER -> INTEGER NOT NULL}}
> The rule generates a constant row {{{}(1, 1){}}}. Its non-nullable output
> types differ from the nullable aggregate output types, so the planner rejects
> the transformation. The incorrect row is not returned to the user.
> *Cause and proposed fix:*
> The rule checks that an expression references only grouping keys. A literal
> references no columns, so it passes this check even when the grouping set is
> empty. The rule then replaces the aggregate call without accounting for
> empty-input semantics.
> Skip aggregates with no grouping keys in this rule. Add a regression test in
> {{hep.iq}} that explicitly enables only
> {{AGGREGATE_REDUCE_FUNCTIONS_ON_GROUP_KEYS}} and verifies both the expected
> {{NULL}} results and the execution plan.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)