diff --git a/src/nanoarrow/ipc/decoder.c b/src/nanoarrow/ipc/decoder.c index e02390745..e47a652e4 100644 --- a/src/nanoarrow/ipc/decoder.c +++ b/src/nanoarrow/ipc/decoder.c @@ -1203,6 +1203,22 @@ static int ArrowIpcDecoderSetTypeUnion(struct ArrowSchema* schema, return ArrowIpcDecoderSetTypeSimpleNested(schema, union_types_str, error); } +static int ArrowIpcDecoderSetTypeRunEndEncoded(struct ArrowSchema* schema, + int64_t n_children, + struct ArrowError* error) { + // The RunEndEncoded type table has no parameters: the run ends and values + // types are carried by its two children (run_ends, then values) + if (n_children != 2) { + ArrowErrorSet(error, + "Expected RunEndEncoded field to have exactly two children but found " + "%" PRId64, + n_children); + return EINVAL; + } + + return ArrowIpcDecoderSetTypeSimpleNested(schema, "+r", error); +} + static int ArrowIpcDecoderSetType(struct ArrowSchema* schema, ns(Field_table_t) field, int64_t n_children, struct ArrowError* error) { ns(Type_union_type_t) type_type = ns(Field_type_type(field)); @@ -1266,8 +1282,7 @@ static int ArrowIpcDecoderSetType(struct ArrowSchema* schema, ns(Field_table_t) case ns(Type_Union): return ArrowIpcDecoderSetTypeUnion(schema, type, n_children, error); case ns(Type_RunEndEncoded): - ArrowErrorSet(error, "RunEndEncoded not yet supported in IPC reader"); - return ENOTSUP; + return ArrowIpcDecoderSetTypeRunEndEncoded(schema, n_children, error); default: ArrowErrorSet(error, "Unrecognized Field type with value %d", type_type); return EINVAL; diff --git a/src/nanoarrow/ipc/decoder_test.cc b/src/nanoarrow/ipc/decoder_test.cc index 8f89acc6f..17de84d44 100644 --- a/src/nanoarrow/ipc/decoder_test.cc +++ b/src/nanoarrow/ipc/decoder_test.cc @@ -2039,6 +2039,10 @@ INSTANTIATE_TEST_SUITE_P( arrow::dense_union({arrow::field("col1", arrow::int32()), arrow::field("col2", arrow::utf8())}, {126, 127}), + // Run-end encoded + arrow::run_end_encoded(arrow::int16(), arrow::utf8()), + arrow::run_end_encoded(arrow::int32(), arrow::int64()), + arrow::run_end_encoded(arrow::int64(), arrow::float64()), // Type with nested metadata arrow::list(arrow::field("some_custom_name", arrow::int32(), diff --git a/src/nanoarrow/ipc/files_test.cc b/src/nanoarrow/ipc/files_test.cc index cc15a5251..501b92495 100644 --- a/src/nanoarrow/ipc/files_test.cc +++ b/src/nanoarrow/ipc/files_test.cc @@ -620,7 +620,7 @@ INSTANTIATE_TEST_SUITE_P( TestFile::OK("cpp-21.0.0/generated_nested_dictionary.stream"), TestFile::NotSupported("cpp-21.0.0/generated_list_view.stream"), TestFile::NotSupported("cpp-21.0.0/generated_binary_view.stream"), - TestFile::NotSupported("cpp-21.0.0/generated_run_end_encoded.stream") + TestFile::OK("cpp-21.0.0/generated_run_end_encoded.stream") // Comment to keep line from wrapping ));