12#ifndef O2_FRAMEWORK_TABLEBUILDER_H_
13#define O2_FRAMEWORK_TABLEBUILDER_H_
18#include "arrow/type_traits.h"
23#include <arrow/chunked_array.h>
24#include <arrow/status.h>
25#include <arrow/memory_pool.h>
27#include <arrow/type_traits.h>
28#include <arrow/table.h>
29#include <arrow/builder.h>
45extern template class arrow::NumericBuilder<arrow::UInt8Type>;
46extern template class arrow::NumericBuilder<arrow::UInt32Type>;
47extern template class arrow::NumericBuilder<arrow::FloatType>;
48extern template class arrow::NumericBuilder<arrow::Int32Type>;
49extern template class arrow::NumericBuilder<arrow::Int8Type>;
60template <
typename T,
int N>
65template <
typename T,
int N>
70template <
typename T,
int N>
80#define O2_ARROW_STL_CONVERSION(c_type, ArrowType_) \
82 struct ConversionTraits<c_type> { \
83 using ArrowType = ::arrow::ArrowType_; \
107 template <
typename T>
108 static arrow::Status
appendToList(std::unique_ptr<arrow::FixedSizeListBuilder>& builder,
const T*
data,
int size = 1)
111 using BuilderType =
typename arrow::TypeTraits<ArrowType>::BuilderType;
112 size_t numElements =
static_cast<const arrow::FixedSizeListType*
>(builder->type().get())->list_size();
114 auto status = builder->AppendValues(
size);
115 auto ValueBuilder =
static_cast<BuilderType*
>(builder->value_builder());
116 status &= ValueBuilder->AppendValues(
data, numElements *
size,
nullptr);
121 template <
typename HolderType,
typename T>
124 return static_cast<typename HolderType::Policy&
>(holder).append(holder.builder,
value);
127 template <
typename HolderType>
128 static arrow::Status
flush(HolderType& holder)
130 return static_cast<typename HolderType::Policy&
>(holder).flush(holder.builder);
136 template <
typename HolderType,
typename T>
137 static arrow::Status
append(HolderType& holder,
const T*
data)
139 if constexpr (std::is_same_v<
decltype(holder.builder), std::unique_ptr<arrow::FixedSizeListBuilder>>) {
140 return appendToList<T>(holder.builder,
data);
142 return holder.builder->Append(
reinterpret_cast<const uint8_t*
>(
data));
146 template <
typename HolderType,
typename T,
int N>
147 static arrow::Status
append(HolderType& holder,
const T (&
data)[N])
149 return holder.builder->Append(
reinterpret_cast<const uint8_t*
>(
data));
153 template <
typename HolderType,
typename T,
int N>
154 static arrow::Status
append(HolderType& holder, std::array<const T, N>
const&
data)
156 return holder.builder->Append(
reinterpret_cast<const uint8_t*
>(
data.data()));
160 template <
typename HolderType,
typename T>
161 static arrow::Status
append(HolderType& holder, std::span<const T>
data)
164 using ValueBuilderType =
typename arrow::TypeTraits<ArrowType>::BuilderType;
165 auto status = holder.builder->Reserve(
data.size());
166 status &= holder.builder->Append();
167 auto vbuilder =
static_cast<ValueBuilderType*
>(holder.builder->value_builder());
168 status &= vbuilder->AppendValues(
data.begin(),
data.end());
173 template <
typename HolderType,
typename T>
176 auto status = append(holder,
value);
182 template <
typename HolderType,
typename T>
185 return holder.builder->UnsafeAppend(
value);
188 template <
typename HolderType,
typename T>
191 if constexpr (std::is_same_v<
decltype(holder.builder), std::unique_ptr<arrow::FixedSizeListBuilder>>) {
192 auto status = appendToList<T>(holder.builder,
value);
194 return holder.builder->UnsafeAppend(
reinterpret_cast<const uint8_t*
>(
value));
198 template <
typename HolderType,
typename ITERATOR>
199 static arrow::Status
append(HolderType& holder, std::pair<ITERATOR, ITERATOR> ip)
202 using ValueBuilderType =
typename arrow::TypeTraits<ArrowType>::BuilderType;
204 auto status = holder.builder->Append();
205 auto valueBuilder =
reinterpret_cast<ValueBuilderType*
>(holder.builder->value_builder());
206 return status & valueBuilder->AppendValues(&*ip.first, std::distance(ip.first, ip.second));
210 template <
typename HolderType,
typename ITERATOR>
211 static void unsafeAppend(HolderType& holder, std::pair<ITERATOR, ITERATOR> ip)
214 using ValueBuilderType =
typename arrow::TypeTraits<ArrowType>::BuilderType;
216 auto status = holder.builder->Append();
217 auto valueBuilder =
reinterpret_cast<ValueBuilderType*
>(holder.builder->value_builder());
218 status &= valueBuilder->AppendValues(&*ip.first, std::distance(ip.first, ip.second));
220 throw runtime_error(
"Unable to append values to valueBuilder!");
231 using BuilderType =
typename arrow::TypeTraits<ArrowType>::BuilderType;
233 static std::unique_ptr<BuilderType>
make(arrow::MemoryPool* pool)
235 return std::make_unique<BuilderType>(pool);
240 return arrow::TypeTraits<ArrowType>::type_singleton();
245 return builder.Append(
value);
251 return builder.Append(
value);
260 using BuilderType =
typename arrow::TypeTraits<ArrowType>::BuilderType;
262 static std::unique_ptr<BuilderType>
make(arrow::MemoryPool* pool)
264 return std::make_unique<BuilderType>(pool);
269 return arrow::TypeTraits<ArrowType>::type_singleton();
274 return builder.Append(
value);
283 using BuilderType =
typename arrow::TypeTraits<ArrowType>::BuilderType;
285 static std::unique_ptr<BuilderType>
make(arrow::MemoryPool* pool)
287 return std::make_unique<BuilderType>(pool);
292 return arrow::TypeTraits<ArrowType>::type_singleton();
297 return builder.Append((
char*)
value.data(), (int64_t)
value.size());
301template <
typename ITERATOR>
303 using FillType = std::pair<ITERATOR, ITERATOR>
const&;
308 using ValueBuilder =
typename arrow::TypeTraits<ValueType>::BuilderType;
310 static std::unique_ptr<BuilderType>
make(arrow::MemoryPool* pool)
312 auto valueBuilder = std::make_shared<ValueBuilder>(pool);
313 return std::make_unique<arrow::ListBuilder>(pool, valueBuilder);
318 return arrow::list(arrow::TypeTraits<ValueType>::type_singleton());
322template <
typename T,
int N>
330 static std::unique_ptr<BuilderType>
make(arrow::MemoryPool* pool)
332 std::unique_ptr<arrow::ArrayBuilder> valueBuilder;
334 arrow::MakeBuilder(pool, arrow::TypeTraits<ElementType>::type_singleton(), &valueBuilder);
335 return std::make_unique<BuilderType>(pool, std::move(valueBuilder), N);
340 return arrow::fixed_size_list(arrow::TypeTraits<ElementType>::type_singleton(), N);
344template <
typename T,
int N>
351 static std::unique_ptr<BuilderType>
make(arrow::MemoryPool* pool)
353 std::unique_ptr<arrow::ArrayBuilder> valueBuilder;
355 arrow::MakeBuilder(pool, arrow::TypeTraits<ElementType>::type_singleton(), &valueBuilder);
356 return std::make_unique<BuilderType>(pool, std::move(valueBuilder), N);
361 return arrow::fixed_size_list(arrow::TypeTraits<ElementType>::type_singleton(), N);
365template <
typename T,
int N>
372 static std::unique_ptr<BuilderType>
make(arrow::MemoryPool* pool)
374 std::unique_ptr<arrow::ArrayBuilder> valueBuilder;
376 arrow::MakeBuilder(pool, arrow::TypeTraits<ElementType>::type_singleton(), &valueBuilder);
377 return std::make_unique<BuilderType>(pool, std::move(valueBuilder), N);
382 return arrow::fixed_size_list(arrow::TypeTraits<ElementType>::type_singleton(), N);
393 static std::unique_ptr<BuilderType>
make(arrow::MemoryPool* pool)
395 std::unique_ptr<arrow::ArrayBuilder> valueBuilder;
397 arrow::MakeBuilder(pool, arrow::TypeTraits<ElementType>::type_singleton(), &valueBuilder);
398 return std::make_unique<BuilderType>(pool, std::move(valueBuilder));
403 return arrow::list(arrow::TypeTraits<ElementType>::type_singleton());
407template <
typename... ARGS>
410 return std::make_tuple(std::make_unique<ARGS>()...);
416 using BuilderType =
typename arrow::TypeTraits<ArrowType>::BuilderType;
421template <
typename ITERATOR>
429template <
typename T,
int N>
443 template <
typename BUILDER>
446 return builder->Append(
value);
449 template <
typename BUILDER>
450 requires std::same_as<std::span<std::byte>, T>
453 return builder->Append((
char*)
value.data(), (int64_t)
value.size());
456 template <
typename BUILDER>
459 return arrow::Status::OK();
465 static constexpr int CHUNK_SIZE = 256;
467 template <
typename BUILDER>
472 if (
pos % CHUNK_SIZE == 0) {
473 return builder->AppendValues(cache, CHUNK_SIZE,
nullptr);
475 return arrow::Status::OK();
478 template <
typename BUILDER>
479 arrow::Status
flush(BUILDER& builder)
481 if (
pos % CHUNK_SIZE != 0) {
482 return builder->AppendValues(cache,
pos % CHUNK_SIZE,
nullptr);
484 return arrow::Status::OK();
496template <
size_t I,
typename T>
501 using BuilderType =
typename arrow::TypeTraits<ArrowType>::BuilderType;
507 auto s = builder->Reserve(nRows);
518 template <
typename... ARGS,
size_t NCOLUMNS>
525 template <
typename...
Ts,
typename VALUES>
528 return (BuilderUtils::append(std::get<Ts::index>(holders), std::get<Ts::index>(
values)).ok() && ...);
534 template <
typename...
Ts,
typename VALUES>
537 (BuilderUtils::unsafeAppend(std::get<Ts::index>(holders), std::get<Ts::index>(
values)), ...);
541 template <
typename...
Ts>
542 static bool finalize(std::vector<std::shared_ptr<arrow::Array>>&
arrays, std::tuple<Ts...>& holders)
544 return (finalize(
arrays[Ts::index], std::get<Ts::index>(holders)) && ...);
547 template <
typename HOLDER>
550 return BuilderUtils::flush(holder).ok() && holder.builder->Finish(&
array).ok();
554template <
typename... ARGS>
565 using type = std::decay_t<T>;
568 return std::make_tuple(p0,
p1,
p2, p3);
571 return std::make_tuple(p0,
p1,
p2);
574 return std::make_tuple(p0,
p1);
577 return std::make_tuple(p0);
579 return std::make_tuple();
583template <
typename... ARGS>
586 return []<std::size_t... Is>(std::index_sequence<Is...>) {
588 }(std::make_index_sequence<
sizeof...(ARGS)>{});
591template <
typename... ARGS>
594 return [pool, nRows]<std::size_t... Is>(std::index_sequence<Is...>) {
596 }(std::make_index_sequence<
sizeof...(ARGS)>{});
599template <
typename... ARGS>
603concept ShouldNotDeconstruct = std::is_bounded_array_v<T> || std::is_arithmetic_v<T> || framework::is_base_of_template_v<std::vector, T> || std::same_as<std::span<std::byte>, T>;
612 template <
typename... ARGS>
613 using HoldersTuple =
typename std::tuple<BuilderHolder<0, ARGS>...>;
615 template <
typename... ARGS>
620 template <
typename... ARGS>
623 return (HoldersTupleIndexed<ARGS...>*)mHolders;
626 void validate()
const;
628 template <
typename... ARGS,
size_t I =
sizeof...(ARGS)>
629 auto makeBuilders(std::array<char const*, I>
const& columnNames,
size_t nRows)
631 char const*
const* names_ptr = columnNames.data();
632 mSchema = std::make_shared<arrow::Schema>(
635 mHolders =
makeHolders<ARGS...>(mMemoryPool, nRows);
636 mFinalizer = [](std::vector<std::shared_ptr<arrow::Array>>&
arrays,
void* holders) ->
bool {
637 return TableBuilderHelpers::finalize(
arrays, *(HoldersTupleIndexed<ARGS...>*)holders);
639 mDestructor = [](
void* holders)
mutable ->
void {
640 delete (HoldersTupleIndexed<ARGS...>*)holders;
645 template <
typename ARG0,
typename... ARGS>
649 using argsPack_t =
decltype(
tuple_to_pack(framework::to_tuple(std::declval<ARG0>())));
650 return framework::pack_size(argsPack_t{});
653 template <
typename ARG0,
typename... ARGS>
657 return 1 +
sizeof...(ARGS);
660 void setLabel(
const char*
label);
670 mDestructor(mHolders);
675 template <
typename ARG0,
typename... ARGS>
677 auto persist(std::array<
char const*,
sizeof...(ARGS) + 1>
const& columnNames)
682 persister(slot, std::forward_as_tuple(arg, args...));
688 template <
typename ARG0,
typename... ARGS>
690 auto persist(std::array<
char const*, countColumns<ARG0, ARGS...>()>
const& columnNames)
692 using argsPack_t =
decltype(
tuple_to_pack(framework::to_tuple(std::declval<ARG0>())));
693 auto persister = persistTuple(argsPack_t{}, columnNames);
694 return [persister = persister](
unsigned int slot, ARG0
const& obj) ->
void {
701 template <
typename... ARGS>
704 constexpr int nColumns =
sizeof...(ARGS);
706 mArrays.resize(nColumns);
707 makeBuilders<ARGS...>(columnNames, 10);
710 using FillTuple = std::tuple<typename BuilderMaker<ARGS>::FillType...>;
711 return [holders = mHolders](
unsigned int , FillTuple
const& t) ->
void {
712 auto status = TableBuilderHelpers::append(*(HoldersTupleIndexed<ARGS...>*)holders, t);
713 if (status ==
false) {
721 template <
typename T>
724 return [
this]<
typename... Cs>(
pack<Cs...>) {
725 return this->
template persist<
typename Cs::type...>({Cs::columnLabel()...});
726 }(
typename T::table_t::persistent_columns_t{});
729 template <
typename... Cs>
732 return this->
template persist<
typename Cs::type...>({Cs::columnLabel()...});
735 template <
typename T,
typename E>
738 return [
this]<
typename... Cs>(
pack<Cs...>) {
739 return this->
template persist<E>({Cs::columnLabel()...});
740 }(
typename T::table_t::persistent_columns_t{});
744 template <
typename...
Ts>
747 return (std::get<Ts::index>(holders).builder->Reserve(s).ok() && ...);
750 template <
typename... ARGS>
753 reserveArrays(*(HoldersTupleIndexed<ARGS...>*)mHolders, s);
758 std::shared_ptr<arrow::Table> finalize();
761 bool (*mFinalizer)(std::vector<std::shared_ptr<arrow::Array>>&
arrays,
void* holders);
762 void (*mDestructor)(
void* holders);
764 arrow::MemoryPool* mMemoryPool;
765 std::shared_ptr<arrow::Schema> mSchema;
766 std::vector<std::shared_ptr<arrow::Array>> mArrays;
773 [[maybe_unused]]
auto writer =
b.
cursor<T>();
778template <soa::TableRef R>
783 b.setLabel(aod::label<R>());
787template <
typename... Cs>
791 [[maybe_unused]]
auto writer =
b.
cursor(p);
796std::shared_ptr<arrow::Table>
spawnerHelper(std::shared_ptr<arrow::Table>
const& fullTable, std::shared_ptr<arrow::Schema> newSchema,
size_t nColumns,
800template <aod::is_aod_hash D>
805 if (fullTable->num_rows() == 0) {
808 return spawnerHelper(fullTable, schema, framework::pack_size(placeholders_pack_t{}), projectors,
name, projector);
811template <aod::is_aod_hash D>
816 return spawner<D>(fullTable,
name, projectors, projector, schema);
819template <aod::is_aod_hash D>
821auto spawner(std::shared_ptr<arrow::Table>
const& fullTable,
const char*
name,
expressions::Projector* projectors, std::shared_ptr<gandiva::Projector>& projector, std::shared_ptr<arrow::Schema>
const& schema)
824 if (fullTable->num_rows() == 0) {
827 return spawnerHelper(fullTable, schema, framework::pack_size(expression_pack_t{}), projectors,
name, projector);
830template <aod::is_aod_hash D>
832auto spawner(std::vector<std::shared_ptr<arrow::Table>>&& tables,
const char*
name,
expressions::Projector* projectors, std::shared_ptr<gandiva::Projector>& projector, std::shared_ptr<arrow::Schema>
const& schema)
835 return spawner<D>(fullTable,
name, projectors, projector, schema);
838template <
typename... C>
841 std::array<const char*, 1> labels{
"original"};
842 auto fullTable = soa::ArrowHelpers::joinTables(std::move(tables), std::span<const char* const>{labels});
843 if (fullTable->num_rows() == 0) {
846 return spawnerHelper(fullTable, schema,
sizeof...(C), projectors,
name, projector);
849template <
typename... T>
constexpr int p1()
constexpr to accelerate the coordinates changing
#define O2_ARROW_STL_CONVERSION(c_type, ArrowType_)
auto cursor(framework::pack< Cs... >)
auto persist(std::array< char const *, countColumns< ARG0, ARGS... >()> const &columnNames)
auto persistTuple(framework::pack< ARGS... >, std::array< char const *, sizeof...(ARGS)> const &columnNames)
Same a the above, but use a tuple to persist stuff.
static constexpr int countColumns()
void extracted(bool &status)
Actually creates the arrow::Table from the builders.
static constexpr int countColumns()
auto reserve(o2::framework::pack< ARGS... > &&, int s)
TableBuilder(arrow::MemoryPool *pool=arrow::default_memory_pool())
auto reserveArrays(std::tuple< Ts... > &holders, int s)
Reserve method to expand the columns as needed.
auto persist(std::array< char const *, sizeof...(ARGS)+1 > const &columnNames)
GLuint const GLchar * name
GLboolean GLboolean GLboolean b
GLsizei const GLfloat * value
GLint GLint GLsizei GLint GLenum GLenum type
GLenum GLsizei GLsizei GLint * values
GLuint GLsizei const GLchar * label
typedef void(APIENTRYP PFNGLCULLFACEPROC)(GLenum mode)
Defining PrimaryVertex explicitly as messageable.
void addLabelToSchema(std::shared_ptr< arrow::Schema > &schema, const char *label)
RuntimeErrorRef runtime_error(const char *)
constexpr auto makeHolderTypes()
auto constexpr to_tuple(T &&object) noexcept
auto makeEmptyTable(const char *name)
auto spawner(std::shared_ptr< arrow::Table > const &fullTable, const char *name, o2::framework::expressions::Projector *projectors, std::shared_ptr< gandiva::Projector > &projector, std::shared_ptr< arrow::Schema > const &schema)
Expression-based column generator to materialize columns.
constexpr auto tuple_to_pack(std::tuple< ARGS... > &&)
auto makeHolders(arrow::MemoryPool *pool, size_t nRows)
std::shared_ptr< arrow::Table > spawnerHelper(std::shared_ptr< arrow::Table > const &fullTable, std::shared_ptr< arrow::Schema > newSchema, size_t nColumns, expressions::Projector *projectors, const char *name, std::shared_ptr< gandiva::Projector > &projector)
decltype(makeHolderTypes< ARGS... >()) IndexedHoldersTuple
RuntimeErrorRef runtime_error_f(const char *,...)
std::tuple< typename T::iterator... > iterator_tuple_t
Defining DataPointCompositeObject explicitly as copiable.
typename detail::ConversionTraits< T >::ArrowType ArrowType
std::unique_ptr< BuilderType > builder
typename arrow::TypeTraits< ArrowType >::BuilderType BuilderType
typename InsertionTrait< T >::Policy Policy
BuilderHolder(arrow::MemoryPool *pool, size_t nRows=0)
typename detail::ConversionTraits< T >::ArrowType ElementType
static std::unique_ptr< BuilderType > make(arrow::MemoryPool *pool)
arrow::FixedSizeListBuilder BuilderType
arrow::FixedSizeListType ArrowType
static std::shared_ptr< arrow::DataType > make_datatype()
static std::unique_ptr< BuilderType > make(arrow::MemoryPool *pool)
typename detail::ConversionTraits< T >::ArrowType ElementType
arrow::FixedSizeListType ArrowType
static std::shared_ptr< arrow::DataType > make_datatype()
arrow::FixedSizeListBuilder BuilderType
typename arrow::TypeTraits< ArrowType >::BuilderType BuilderType
static arrow::Status append(BuilderType &builder, bool value)
static std::unique_ptr< BuilderType > make(arrow::MemoryPool *pool)
static std::shared_ptr< arrow::DataType > make_datatype()
typename detail::ConversionTraits< bool >::ArrowType ArrowType
typename detail::ConversionTraits< T >::ArrowType ElementType
static std::unique_ptr< BuilderType > make(arrow::MemoryPool *pool)
arrow::FixedSizeListType ArrowType
arrow::FixedSizeListBuilder BuilderType
static std::shared_ptr< arrow::DataType > make_datatype()
static std::unique_ptr< BuilderType > make(arrow::MemoryPool *pool)
arrow::ListType ArrowType
arrow::ListBuilder BuilderType
typename detail::ConversionTraits< typename ITERATOR::value_type >::ArrowType ValueType
typename ITERATOR::value_type STLValueType
std::pair< ITERATOR, ITERATOR > const & FillType
typename arrow::TypeTraits< ValueType >::BuilderType ValueBuilder
static std::shared_ptr< arrow::DataType > make_datatype()
static arrow::Status append(BuilderType &builder, std::span< std::byte > value)
typename arrow::TypeTraits< ArrowType >::BuilderType BuilderType
std::span< std::byte > STLValueType
typename detail::ConversionTraits< std::span< std::byte > >::ArrowType ArrowType
static std::unique_ptr< BuilderType > make(arrow::MemoryPool *pool)
static std::shared_ptr< arrow::DataType > make_datatype()
std::span< std::byte > FillType
std::span< const T > FillType
arrow::ListType ArrowType
static std::unique_ptr< BuilderType > make(arrow::MemoryPool *pool)
typename detail::ConversionTraits< T >::ArrowType ElementType
arrow::ListBuilder BuilderType
static std::shared_ptr< arrow::DataType > make_datatype()
typename arrow::TypeTraits< ArrowType >::BuilderType BuilderType
static arrow::Status append(BuilderType &builder, std::array< T, N > &value)
static arrow::Status append(BuilderType &builder, T value)
typename detail::ConversionTraits< T >::ArrowType ArrowType
static std::unique_ptr< BuilderType > make(arrow::MemoryPool *pool)
static std::shared_ptr< arrow::DataType > make_datatype()
arrow::FixedSizeListBuilder BuilderType
arrow::FixedSizeListType ArrowType
arrow::ListType ArrowType
arrow::ListBuilder BuilderType
arrow::ListType ArrowType
arrow::ListBuilder BuilderType
typename arrow::TypeTraits< ArrowType >::BuilderType BuilderType
typename detail::ConversionTraits< T >::ArrowType ArrowType
static arrow::Status flush(HolderType &holder)
static arrow::Status appendToList(std::unique_ptr< arrow::FixedSizeListBuilder > &builder, const T *data, int size=1)
static arrow::Status append(HolderType &holder, const T(&data)[N])
Appender for the array case.
static arrow::Status append(HolderType &holder, T value)
static void unsafeAppend(HolderType &holder, std::span< const T > value)
static arrow::Status append(HolderType &holder, std::span< const T > data)
Appender for the vector case.
static arrow::Status append(HolderType &holder, const T *data)
static arrow::Status append(HolderType &holder, std::pair< ITERATOR, ITERATOR > ip)
static arrow::Status append(HolderType &holder, std::array< const T, N > const &data)
Appender for the array case.
static void unsafeAppend(HolderType &holder, T *value)
static void unsafeAppend(HolderType &holder, std::pair< ITERATOR, ITERATOR > ip)
static void unsafeAppend(HolderType &holder, T value)
arrow::Status append(BUILDER &builder, T value)
arrow::Status flush(BUILDER &builder)
arrow::Status append(BUILDER &builder, T value)
arrow::Status append(BUILDER &builder, T value)
arrow::Status flush(BUILDER &)
static consteval DirectInsertion< T > policy()
decltype(policy()) Policy
static bool finalize(std::shared_ptr< arrow::Array > &array, HOLDER &holder)
static bool append(std::tuple< Ts... > &holders, VALUES &&values)
Invokes the append method for each entry in the tuple.
static std::array< arrow::DataType, NCOLUMNS > makeArrowColumnTypes()
static bool finalize(std::vector< std::shared_ptr< arrow::Array > > &arrays, std::tuple< Ts... > &holders)
Invokes the append method for each entry in the tuple.
static void unsafeAppend(std::tuple< Ts... > &holders, VALUES &&values)
::arrow::FixedSizeListType ArrowType
::arrow::FixedSizeListType ArrowType
::arrow::FixedSizeListType ArrowType
::arrow::ListType ArrowType
FIXME: adapt type conversion to new arrow.
A struct, containing the root of the expression tree.