Skip to content

GH-54907: [C++] Fix SparseUnionArray::Make for sliced type_ids arrays - #54938

Open
JonSnow1807 wants to merge 1 commit into
apache:mainfrom
JonSnow1807:gh-54907-sparse-union-sliced-type-ids
Open

JonSnow1807 wants to merge 1 commit into
apache:mainfrom
JonSnow1807:gh-54907-sparse-union-sliced-type-ids

Conversation

@JonSnow1807

@JonSnow1807 JonSnow1807 commented Oct 22, 2026 •

Copy link
Copy Markdown

Rationale for this change

SparseUnionArray::Make used type_ids.offset() as the offset of the union array. The offset of a sparse union also applies to its children, so with a sliced type_ids array the union referred to child positions shifted by that offset, while Make still required the children to have the same length as type_ids. As reported in GH-54907, this made it impossible to build a valid sparse union from a sliced type_ids array: children of length len(type_ids) produce an invalid array, children of length offset + len(type_ids) are rejected.

What changes are included in this PR?

When type_ids is sliced, its type ids buffer is sliced (zero-copy) to the logical window of type_ids and the union is built with offset 0, so the children keep corresponding to the logical positions of type_ids as the existing length check requires. Unsliced inputs keep using the original buffer, so nothing changes for them.

Are these changes tested?

Yes. TestSparseUnionArray.MakeFromSlicedTypeIds builds a union from a sliced type_ids array (with plain and with sliced children) and checks the values; on main it fails with Sparse union child array #0 has length smaller than expected for union array (3 < 4). arrow-array-test, arrow-scalar-test, arrow-ipc-read-write-test and arrow-compute-scalar-type-test pass locally (Debug, ASan/UBSan).

Are there any user-facing changes?

A sparse union built from a sliced type_ids array is now valid and has offset 0 instead of type_ids.offset().

AI usage disclosure: Claude Code assisted with investigating the root cause, preparing the implementation, and developing the regression test. I reviewed the changes and am responsible for their correctness.

…arrays

SparseUnionArray::Make used type_ids.offset() as the offset of the union
array. The offset of a sparse union also applies to its children, so with a
sliced type_ids array the union referred to child positions shifted by that
offset, while Make still required the children to have the same length as
type_ids. This made it impossible to build a valid sparse union from a sliced
type_ids array.

Slice the type ids buffer to the logical window of type_ids (zero-copy) and
build the union with offset 0, so children keep corresponding to the logical
positions of type_ids. Unsliced inputs keep using the original buffer.
@github-actions github-actions Bot added the awaiting review Awaiting review label Oct 22, 2026
@github-actions

Copy link
Copy Markdown

⚠️ GitHub issue #54907 has been automatically assigned in GitHub to PR creator.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant