Skip to content

test: end-to-end reproducer for aggregating batches with stricter nested nullability than the declared schema - #24278

Draft
alamb wants to merge 1 commit into
apache:mainfrom
alamb:repro-24069-nested-nullability
Draft

test: end-to-end reproducer for aggregating batches with stricter nested nullability than the declared schema#24278
alamb wants to merge 1 commit into
apache:mainfrom
alamb:repro-24069-nested-nullability

Conversation

@alamb

@alamb alamb commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Which issue does this PR close?

Rationale for this change

get a reproducer so we can tell when the error happened

What changes are included in this PR?

An end-to-end reproducer as a basis for working out a root-cause fix.

Are these changes tested?

The tests are the change. They currently fail (and one panics) on main, demonstrating the bug.

cargo test --test core_integration -- nested_nullability

And it fails like this

thread 'sql::aggregates::nested_nullability::array_agg_struct_from_stricter_batches' (14311250) panicked at /Users/andrewlamb/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/arrow-array-59.2.0/src/array/list_array.rs:272:54:
called `Result::unwrap()` on an `Err` value: InvalidArgumentError("ListArray expected data type Struct(\"colA\": Boolean) got Struct(\"colA\": non-null Boolean) for \"item\"")
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Error: Context("Join Error", External(JoinError::Panic(Id(65), "called `Result::unwrap()` on an `Err` value: InvalidArgumentError(\"ListArray expected data type Struct(\\\"colA\\\": Boolean) got Struct(\\\"colA\\\": non-null Boolean) for \\\"item\\\"\")", ...)))

---- sql::aggregates::nested_nullability::array_agg_struct_from_stricter_batches_with_spilling stdout ----

I also ran the same test on the 54.1.0 branch:

andrewlamb@Andrews-MacBook-Pro-3:/tmp/54.1.0$ git cherry-pick 6a5d04fead7fb6ecf8c53ad3a725c176794d3aef
Auto-merging datafusion/core/tests/sql/aggregates/mod.rs
[detached HEAD 782a17c405] Add end-to-end reproducer for aggregating batches stricter than the declared schema
 Date: Mon Aug 10 19:14:37 2026 -0400
 2 files changed, 180 insertions(+)
 create mode 100644 datafusion/core/tests/sql/aggregates/nested_nullability.rs
andrewlamb@Andrews-MacBook-Pro-3:/tmp/54.1.0$ cargo test --test core_integration -- nested_nullability

And it fails the same way

...
thread 'sql::aggregates::nested_nullability::array_agg_struct_from_stricter_batches' (14314739) panicked at /Users/andrewlamb/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/arrow-array-58.3.0/src/array/list_array.rs:272:54:
called `Result::unwrap()` on an `Err` value: InvalidArgumentError("ListArray expected data type Struct(\"colA\": Boolean) got Struct(\"colA\": non-null Boolean) for \"item\"")
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Error: Context("Join Error", External(JoinError::Panic(Id(65), "called `Result::unwrap()` on an `Err` value: InvalidArgumentError(\"ListArray expected data type Struct(\\\"colA\\\": Boolean) got Struct(\\\"colA\\\": non-null Boolean) for \\\"item\\\"\")", ...)))
...

Are there any user-facing changes?

No.

@github-actions github-actions Bot added the core Core DataFusion crate label Aug 11, 2026
…eclared schema

DataFusion accepts batches whose data types are stricter than the
declared schema (`MemTable::try_new` validates with `Schema::contains`,
which permits a non-nullable field where the schema declares a nullable
one, including nested fields). Aggregating a struct column from such
batches fails in several independent places; see apache#24069.

The new tests register a `MemTable` whose declared schema marks a
nested struct field nullable while the batches carry a non-nullable
one, and run `array_agg` / `array_agg(DISTINCT)` over it via SQL, with
and without a memory limit that forces spilling. They currently fail
(this commit is the reproducer only):

* `array_agg`, with and without spilling: panic in `ListArray::new`
  (`ArrayAggGroupsAccumulator::evaluate` builds the list item field
  from the planner-declared type, the values from the actual data)
* `array_agg(DISTINCT)` without spilling: `RowConverter column schema
  mismatch` (the `single_distinct_to_groupby` rewrite turns the struct
  into a GROUP BY key; `GroupValues`' row converter is built from the
  declared schema but fed the stricter runtime arrays)
* `array_agg(DISTINCT)` with spilling passes on current main, showing
  how configuration-dependent the failures are

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

core Core DataFusion crate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant