diff --git a/cpp/src/arrow/stl.h b/cpp/src/arrow/stl.h index b542ee5c34868..ae5462c661a8c 100644 --- a/cpp/src/arrow/stl.h +++ b/cpp/src/arrow/stl.h @@ -187,6 +187,35 @@ struct ConversionTraits> } }; +template +struct ConversionTraits> + : public CTypeTraits> { + static arrow::Status AppendRow(FixedSizeListBuilder& builder, + const std::array& values) { + auto vb = + ::arrow::internal::checked_cast::BuilderType*>( + builder.value_builder()); + ARROW_RETURN_NOT_OK(builder.Append()); + return vb->AppendValues(values.data(), N); + } + + static std::array GetEntry(const ::arrow::FixedSizeListArray& array, + size_t j) { + using ElementArrayType = typename TypeTraits< + typename stl::ConversionTraits::ArrowType>::ArrayType; + + const ElementArrayType& value_array = + ::arrow::internal::checked_cast(*array.values()); + + std::array arr; + for (size_t i = 0; i < N; i++) { + arr[i] = stl::ConversionTraits::GetEntry(value_array, + array.value_offset(j) + i); + } + return arr; + } +}; + template struct ConversionTraits> : public CTypeTraits())>::type> { diff --git a/cpp/src/arrow/stl_test.cc b/cpp/src/arrow/stl_test.cc index 48e6f8014c923..ce5adf0c0e268 100644 --- a/cpp/src/arrow/stl_test.cc +++ b/cpp/src/arrow/stl_test.cc @@ -245,6 +245,26 @@ TEST(TestTableFromTupleVector, ListType) { ASSERT_TRUE(expected_table->Equals(*table)); } +TEST(TestTableFromTupleVector, FixedSizeListType) { + using tuple_type = std::tuple>; + + auto expected_schema = std::make_shared( + FieldVector{field("column1", fixed_size_list(int64(), 4), false)}); + std::shared_ptr expected_array = + ArrayFromJSON(fixed_size_list(int64(), 4), "[[1, 1, 2, 34], [2, -4, 1, 1]]"); + std::shared_ptr expected_table = Table::Make(expected_schema, {expected_array}); + + std::vector rows{tuple_type(std::array{1, 1, 2, 34}), + tuple_type(std::array{2, -4, 1, 1})}; + std::vector names{"column1"}; + + std::shared_ptr
table; + ASSERT_OK(TableFromTupleRange(default_memory_pool(), rows, names, &table)); + ASSERT_OK(table->ValidateFull()); + + AssertTablesEqual(*expected_table, *table); +} + TEST(TestTableFromTupleVector, ReferenceTuple) { std::vector names{"column1", "column2", "column3", "column4", "column5", "column6", "column7", "column8", "column9", "column10"}; @@ -468,6 +488,26 @@ TEST(TestTupleVectorFromTable, ListType) { ASSERT_EQ(rows, expected_rows); } +TEST(TestTupleVectorFromTable, FixedSizeListType) { + using tuple_type = std::tuple>; + + compute::ExecContext ctx; + compute::CastOptions cast_options; + auto expected_schema = std::make_shared( + FieldVector{field("column1", fixed_size_list(int64(), 4), false)}); + std::shared_ptr expected_array = + ArrayFromJSON(fixed_size_list(int64(), 4), "[[1, 1, 2, 34], [2, -4, 1, 1]]"); + std::shared_ptr
table = Table::Make(expected_schema, {expected_array}); + ASSERT_OK(table->ValidateFull()); + + std::vector expected_rows{tuple_type(std::array{1, 1, 2, 34}), + tuple_type(std::array{2, -4, 1, 1})}; + + std::vector rows(2); + ASSERT_OK(TupleRangeFromTable(*table, cast_options, &ctx, &rows)); + ASSERT_EQ(rows, expected_rows); +} + TEST(TestTupleVectorFromTable, CastingNeeded) { using tuple_type = std::tuple>; diff --git a/cpp/src/arrow/type_traits.h b/cpp/src/arrow/type_traits.h index 6da05bd8f1435..92009c8560c4e 100644 --- a/cpp/src/arrow/type_traits.h +++ b/cpp/src/arrow/type_traits.h @@ -540,6 +540,16 @@ struct CTypeTraits> : public TypeTraits { } }; +/// \addtogroup c-type-traits +template +struct CTypeTraits> : public TypeTraits { + using ArrowType = FixedSizeListType; + + static auto type_singleton() { + return fixed_size_list(CTypeTraits::type_singleton(), N); + } +}; + /// \addtogroup type-traits /// @{ template <>