Search before asking
Version
8.0.90-v1.2.925-patch-10-1abb4b1e29 (rust nightly 2026-08-25) — the latest patch release as of 2026-08-25. Reproduced with the minimized form 4/4 runs (the original, more complex predicate shape reproduced nondeterministically).
What's Wrong?
When an ARRAY column is used as a GROUP BY key of a super-aggregate grouping (CUBE / ROLLUP),
and the HAVING predicate evaluates an array lambda (ARRAY_FILTER) over that same column, the query
fails with an internal downcast panic instead of evaluating the lambda with NULL propagation:
ERROR 1105 (HY000): UnwindError. Code: 1104, Text = called `Result::unwrap()` on an `Err` value:
BadDataValueType. Code: 1010, Text = failed to downcast column
NullableColumn { column: ArrayColumn { values: NullableColumn { column: Int32([19]),
validity: [0b_______1] }, offsets: [0, 1] }, validity: [0b_______1] }
into databend_common_expression::types::array::ArrayType<...::generic::GenericType<0>>.
The failing value is the NULL-filled group key of a super-aggregate (sub-total) row — CUBE/ROLLUP
fill the rolled-up grouping levels with NULL, and the array-lambda evaluation attempts to downcast the
NULL-containing ArrayColumn into a concrete ArrayType and unwraps the Err.
How to Reproduce?
CREATE TABLE t1(c0array ARRAY(INT) NOT NULL);
INSERT INTO t1(c0array) VALUES ([17, 27]), ([46, 14, 34]), ([-23, 37, 9, -20]), ([19]);
The two queries below are logically equivalent: the second is the standard predicate-relocation
rewrite of the first — the HAVING predicate is materialized as a projection column of a derived table
and filtered by an outer WHERE (π(σ(π(R))) ≡ π(σ(R)), the same equivalence every
predicate-pushdown optimizer relies on). A correct engine must return the same rows from both forms.
-- Base form (predicate in HAVING): fails
SELECT COALESCE(CAST(CAST(t1.c0array AS VARIANT) AS VARCHAR), '__NULL__') FROM t1
GROUP BY CUBE (t1.c0array)
HAVING (ARRAY_LENGTH(ARRAY_FILTER(t1.c0array, x -> x <> -42)) >= 0);
-- ERROR 1105 (HY000): UnwindError. Code: 1104, ... failed to downcast column ...
-- Relocated form (same predicate materialized into the derived-table projection, filtered outside):
-- fails with the SAME error
SELECT ref0 FROM (
SELECT COALESCE(CAST(CAST(t1.c0array AS VARIANT) AS VARCHAR) AS ref0,
(ARRAY_LENGTH(ARRAY_FILTER(t1.c0array, x -> x <> -42)) >= 0) AS ref1
FROM t1 GROUP BY CUBE (t1.c0array)
) AS s WHERE ref1;
-- ERROR 1105 (HY000): UnwindError. Code: 1104, ... failed to downcast column ...
Both members of the equivalent pair crash identically, which localizes the defect to the scalar
array-lambda evaluation over the super-aggregate NULL key — independent of where the predicate
sits (HAVING vs. materialized projection). That positional independence is itself the diagnostic
value of presenting the pair: a filter-path-only failure would instead point at predicate
pushdown/planning.
Isolation matrix (same table, same grouping, only the HAVING predicate varies):
| HAVING predicate |
Result |
constant (1 = 1) |
OK (5 groups) |
GROUPING(c0array) = 0 |
OK (4 groups) |
ARRAY_LENGTH(ARRAY_FILTER(c0array, x -> x <> -42)) >= 0 |
UnwindError, stable |
Additional contrasts that pin the trigger on the super-aggregate NULL key:
-- Same lambda predicate, plain GROUP BY (no CUBE/ROLLUP): succeeds, returns the 4 groups
SELECT t1.c0array FROM t1
GROUP BY t1.c0array
HAVING (ARRAY_LENGTH(ARRAY_FILTER(t1.c0array, x -> x <> -42)) >= 0);
-- Same CUBE grouping without the lambda: succeeds, returns the 4 non-total groups
SELECT t1.c0array FROM t1
GROUP BY CUBE (t1.c0array)
HAVING (GROUPING(t1.c0array) = 0);
-- ROLLUP triggers it as well:
SELECT t1.c0array FROM t1
GROUP BY ROLLUP (t1.c0array)
HAVING (ARRAY_LENGTH(ARRAY_FILTER(t1.c0array, x -> x <> -42)) >= 0);
-- ERROR 1105 (HY000): UnwindError. Code: 1104, ...
Are you willing to submit PR?
Search before asking
Version
8.0.90-v1.2.925-patch-10-1abb4b1e29(rust nightly 2026-08-25) — the latest patch release as of 2026-08-25. Reproduced with the minimized form 4/4 runs (the original, more complex predicate shape reproduced nondeterministically).What's Wrong?
When an
ARRAYcolumn is used as aGROUP BYkey of a super-aggregate grouping (CUBE/ROLLUP),and the
HAVINGpredicate evaluates an array lambda (ARRAY_FILTER) over that same column, the queryfails with an internal downcast panic instead of evaluating the lambda with NULL propagation:
The failing value is the NULL-filled group key of a super-aggregate (sub-total) row —
CUBE/ROLLUPfill the rolled-up grouping levels with NULL, and the array-lambda evaluation attempts to downcast the
NULL-containing
ArrayColumninto a concreteArrayTypeand unwraps theErr.How to Reproduce?
The two queries below are logically equivalent: the second is the standard predicate-relocation
rewrite of the first — the HAVING predicate is materialized as a projection column of a derived table
and filtered by an outer
WHERE(π(σ(π(R)))≡π(σ(R)), the same equivalence everypredicate-pushdown optimizer relies on). A correct engine must return the same rows from both forms.
Both members of the equivalent pair crash identically, which localizes the defect to the scalar
array-lambda evaluation over the super-aggregate NULL key — independent of where the predicate
sits (HAVING vs. materialized projection). That positional independence is itself the diagnostic
value of presenting the pair: a filter-path-only failure would instead point at predicate
pushdown/planning.
Isolation matrix (same table, same grouping, only the HAVING predicate varies):
1 = 1)GROUPING(c0array) = 0ARRAY_LENGTH(ARRAY_FILTER(c0array, x -> x <> -42)) >= 0Additional contrasts that pin the trigger on the super-aggregate NULL key:
Are you willing to submit PR?