Skip to content

Commit a0e707d

Browse files
jorisvandenbosscheliujiacheng777
authored andcommitted
apacheGH-31868: [C++] Support concatenating extension arrays (apache#14463)
(still needs a test in C++ and more elaborate tests (eg extension types with nested data)) * Closes: apache#31868 Authored-by: Joris Van den Bossche <jorisvandenbossche@gmail.com> Signed-off-by: Joris Van den Bossche <jorisvandenbossche@gmail.com>
1 parent b6cc238 commit a0e707d

3 files changed

Lines changed: 34 additions & 2 deletions

File tree

cpp/src/arrow/array/concatenate.cc

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -459,8 +459,16 @@ class ConcatenateImpl {
459459
}
460460

461461
Status Visit(const ExtensionType& e) {
462-
// XXX can we just concatenate their storage?
463-
return Status::NotImplemented("concatenation of ", e);
462+
ArrayDataVector storage_data(in_.size());
463+
for (size_t i = 0; i < in_.size(); ++i) {
464+
storage_data[i] = in_[i]->Copy();
465+
storage_data[i]->type = e.storage_type();
466+
}
467+
std::shared_ptr<ArrayData> out_storage;
468+
RETURN_NOT_OK(ConcatenateImpl(storage_data, pool_).Concatenate(&out_storage));
469+
out_storage->type = in_[0]->type;
470+
out_ = std::move(out_storage);
471+
return Status::OK();
464472
}
465473

466474
private:

cpp/src/arrow/array/concatenate_test.cc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include "arrow/buffer.h"
3737
#include "arrow/status.h"
3838
#include "arrow/testing/builder.h"
39+
#include "arrow/testing/extension_type.h"
3940
#include "arrow/testing/random.h"
4041
#include "arrow/testing/util.h"
4142
#include "arrow/type.h"
@@ -529,6 +530,13 @@ TEST_F(ConcatenateTest, DenseUnionType) {
529530
*concat_array_type_codes);
530531
}
531532

533+
TEST_F(ConcatenateTest, ExtensionType) {
534+
Check([this](int32_t size, double null_probability, std::shared_ptr<Array>* out) {
535+
auto storage = this->GeneratePrimitive<Int16Type>(size, null_probability);
536+
*out = ExtensionType::WrapArray(smallint(), storage);
537+
});
538+
}
539+
532540
TEST_F(ConcatenateTest, OffsetOverflow) {
533541
auto fake_long = ArrayFromJSON(utf8(), "[\"\"]");
534542
fake_long->data()->GetMutableValues<int32_t>(1)[1] =

python/pyarrow/tests/test_extension_type.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -630,6 +630,22 @@ def test_casting_dict_array_to_extension_type():
630630
UUID('30313233-3435-3637-3839-616263646566')]
631631

632632

633+
def test_concat():
634+
arr1 = pa.array([1, 2, 3], IntegerType())
635+
arr2 = pa.array([4, 5, 6], IntegerType())
636+
637+
result = pa.concat_arrays([arr1, arr2])
638+
expected = pa.array([1, 2, 3, 4, 5, 6], IntegerType())
639+
assert result.equals(expected)
640+
641+
# nested in a struct
642+
struct_arr1 = pa.StructArray.from_arrays([arr1], names=["a"])
643+
struct_arr2 = pa.StructArray.from_arrays([arr2], names=["a"])
644+
result = pa.concat_arrays([struct_arr1, struct_arr2])
645+
expected = pa.StructArray.from_arrays([expected], names=["a"])
646+
assert result.equals(expected)
647+
648+
633649
def test_null_storage_type():
634650
ext_type = AnnotatedType(pa.null(), {"key": "value"})
635651
storage = pa.array([None] * 10, pa.null())

0 commit comments

Comments
 (0)