Skip to content

arrow: don't swallow the child type error when building a list array - #2174

Draft
rootkiller6788 wants to merge 2 commits into
tensorflow:masterfrom
rootkiller6788:fix-arrow-list-child-status
Draft

rootkiller6788 wants to merge 2 commits into
tensorflow:masterfrom
rootkiller6788:fix-arrow-list-child-status

Conversation

@rootkiller6788

Copy link
Copy Markdown

Fixes #1759.

ArrowMakeArrayDataImpl::Visit(const arrow::ListType&) called the child type's Accept() and dropped the status it returned. That's the line the issue points at, and it's the only such call in arrow_util.cc that isn't checked (the ones at 153 and 276 both keep the result).

The visible symptom is worse than a missing diagnostic. The primitive visitors only cover bool, the int/uint widths and the floats, so for something like a list<string> column the child visit returns NotImplemented without ever assigning *out_data_. The caller in arrow_kernels.cc passes a default-constructed std::shared_ptr<arrow::ArrayData>, so the list ArrayData it builds has a null child. arrow::MakeArray then constructs a ListArray, and Arrow 7.0.0 (the vendored version) does ARROW_CHECK_EQ(self->list_type_->value_type()->id(), data->child_data[0]->type->id()) in BaseListArray::SetData - null dereference, so tfio.IOTensor.from_arrow(table) on such a table takes down the process instead of telling you the type isn't supported.

I went with propagating the error rather than adding the missing child types to the visitor: the read path does handle string/binary arrays, so supporting list<string> here would probably work, but I have no way to build the extension locally and I'd rather not guess at buffer layout. Happy to follow up on that separately if you want it.

The test is in ArrowIOTensorTest. The existing list coverage is int32/int64/float32/float64, all of which are in the primitive visitor list, which is why this path was never exercised.

Visit(ListType) called the child type's Accept() and threw the returned
status away. If the child type isn't one of the primitive visitors the
status is NotImplemented, *out_data_ never gets assigned, and the caller
ends up with a list ArrayData whose child is a null shared_ptr. Arrow
then dereferences it in BaseListArray::SetData, so a plain
list<string> column takes the process down instead of reporting the
unsupported type.
Covers the path that used to segfault: the column goes through
ArrowIOTensor, the array builder bails out on the string child, and we
should get an OpError naming the child type.

This branch has not been deployed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Error ignored from DataType::Accept()

1 participant