Skip to content

Commit

Permalink
GH-45005 [C++] Support for fixed-size list in conversion of range tup…
Browse files Browse the repository at this point in the history
…le (#45008)

### What changes are included in this PR?
This PR introduces support for fixed-size lists in Apache Arrow's STL conversion.  Added specializations for arrow::stl::ConversionTraits<T> and arrow::CTypeTraits<T> to handle std::array as a fixed-size list and also Unit Test.

### Are these changes tested?
Yes, new type is tested.

### Are there any user-facing changes?

* GitHub Issue: #45005

Lead-authored-by: kamilt <kamil.tokarek@secom.com.pl>
Co-authored-by: Rossi Sun <zanmato1984@gmail.com>
Signed-off-by: Rossi Sun <zanmato1984@gmail.com>
  • Loading branch information
mroz45 and zanmato1984 authored Dec 18, 2024
1 parent 51d380c commit 37eb3b5
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 0 deletions.
29 changes: 29 additions & 0 deletions cpp/src/arrow/stl.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,35 @@ struct ConversionTraits<std::vector<ValueCType>>
}
};

template <class ValueCType, std::size_t N>
struct ConversionTraits<std::array<ValueCType, N>>
: public CTypeTraits<std::array<ValueCType, N>> {
static arrow::Status AppendRow(FixedSizeListBuilder& builder,
const std::array<ValueCType, N>& values) {
auto vb =
::arrow::internal::checked_cast<typename CTypeTraits<ValueCType>::BuilderType*>(
builder.value_builder());
ARROW_RETURN_NOT_OK(builder.Append());
return vb->AppendValues(values.data(), N);
}

static std::array<ValueCType, N> GetEntry(const ::arrow::FixedSizeListArray& array,
size_t j) {
using ElementArrayType = typename TypeTraits<
typename stl::ConversionTraits<ValueCType>::ArrowType>::ArrayType;

const ElementArrayType& value_array =
::arrow::internal::checked_cast<const ElementArrayType&>(*array.values());

std::array<ValueCType, N> arr;
for (size_t i = 0; i < N; i++) {
arr[i] = stl::ConversionTraits<ValueCType>::GetEntry(value_array,
array.value_offset(j) + i);
}
return arr;
}
};

template <typename Optional>
struct ConversionTraits<Optional, enable_if_optional_like<Optional>>
: public CTypeTraits<typename std::decay<decltype(*std::declval<Optional>())>::type> {
Expand Down
40 changes: 40 additions & 0 deletions cpp/src/arrow/stl_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,26 @@ TEST(TestTableFromTupleVector, ListType) {
ASSERT_TRUE(expected_table->Equals(*table));
}

TEST(TestTableFromTupleVector, FixedSizeListType) {
using tuple_type = std::tuple<std::array<int64_t, 4>>;

auto expected_schema = std::make_shared<Schema>(
FieldVector{field("column1", fixed_size_list(int64(), 4), false)});
std::shared_ptr<Array> expected_array =
ArrayFromJSON(fixed_size_list(int64(), 4), "[[1, 1, 2, 34], [2, -4, 1, 1]]");
std::shared_ptr<Table> expected_table = Table::Make(expected_schema, {expected_array});

std::vector<tuple_type> rows{tuple_type(std::array<int64_t, 4>{1, 1, 2, 34}),
tuple_type(std::array<int64_t, 4>{2, -4, 1, 1})};
std::vector<std::string> names{"column1"};

std::shared_ptr<Table> table;
ASSERT_OK(TableFromTupleRange(default_memory_pool(), rows, names, &table));
ASSERT_OK(table->ValidateFull());

AssertTablesEqual(*expected_table, *table);
}

TEST(TestTableFromTupleVector, ReferenceTuple) {
std::vector<std::string> names{"column1", "column2", "column3", "column4", "column5",
"column6", "column7", "column8", "column9", "column10"};
Expand Down Expand Up @@ -468,6 +488,26 @@ TEST(TestTupleVectorFromTable, ListType) {
ASSERT_EQ(rows, expected_rows);
}

TEST(TestTupleVectorFromTable, FixedSizeListType) {
using tuple_type = std::tuple<std::array<int64_t, 4>>;

compute::ExecContext ctx;
compute::CastOptions cast_options;
auto expected_schema = std::make_shared<Schema>(
FieldVector{field("column1", fixed_size_list(int64(), 4), false)});
std::shared_ptr<Array> expected_array =
ArrayFromJSON(fixed_size_list(int64(), 4), "[[1, 1, 2, 34], [2, -4, 1, 1]]");
std::shared_ptr<Table> table = Table::Make(expected_schema, {expected_array});
ASSERT_OK(table->ValidateFull());

std::vector<tuple_type> expected_rows{tuple_type(std::array<int64_t, 4>{1, 1, 2, 34}),
tuple_type(std::array<int64_t, 4>{2, -4, 1, 1})};

std::vector<tuple_type> rows(2);
ASSERT_OK(TupleRangeFromTable(*table, cast_options, &ctx, &rows));
ASSERT_EQ(rows, expected_rows);
}

TEST(TestTupleVectorFromTable, CastingNeeded) {
using tuple_type = std::tuple<std::vector<int64_t>>;

Expand Down
10 changes: 10 additions & 0 deletions cpp/src/arrow/type_traits.h
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,16 @@ struct CTypeTraits<std::vector<CType>> : public TypeTraits<ListType> {
}
};

/// \addtogroup c-type-traits
template <typename CType, std::size_t N>
struct CTypeTraits<std::array<CType, N>> : public TypeTraits<FixedSizeListType> {
using ArrowType = FixedSizeListType;

static auto type_singleton() {
return fixed_size_list(CTypeTraits<CType>::type_singleton(), N);
}
};

/// \addtogroup type-traits
/// @{
template <>
Expand Down

0 comments on commit 37eb3b5

Please sign in to comment.