Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions cpp/src/arrow/compute/kernel.h
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,9 @@ class ARROW_EXPORT OutputType {
this->resolver_ = other.resolver_;
}

OutputType& operator=(const OutputType&) = default;
OutputType& operator=(OutputType&&) = default;

/// \brief Return the shape and type of the expected output value of the
/// kernel given the value descriptors (shapes and types) of the input
/// arguments. The resolver may make use of state information kept in the
Expand Down
46 changes: 46 additions & 0 deletions cpp/src/arrow/compute/kernels/codegen_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,8 @@ struct GetViewType<Decimal128Type> {
static T LogicalValue(PhysicalType value) {
return Decimal128(reinterpret_cast<const uint8_t*>(value.data()));
}

static T LogicalValue(T value) { return value; }
};

template <>
Expand All @@ -159,6 +161,8 @@ struct GetViewType<Decimal256Type> {
static T LogicalValue(PhysicalType value) {
return Decimal256(reinterpret_cast<const uint8_t*>(value.data()));
}

static T LogicalValue(T value) { return value; }
};

template <typename Type, typename Enable = void>
Expand Down Expand Up @@ -243,6 +247,18 @@ struct ArrayIterator<Type, enable_if_base_binary<Type>> {
}
};

template <typename Type>
struct ArrayIterator<Type, enable_if_decimal<Type>> {
using T = typename TypeTraits<Type>::ScalarType::ValueType;
using endian_agnostic = std::array<uint8_t, sizeof(T)>;
const endian_agnostic* values;

explicit ArrayIterator(const ArrayData& data)
: values(data.GetValues<endian_agnostic>(1)) {}

T operator()() { return T{values++->data()}; }
};

// Iterator over various output array types, taking a GetOutputType<Type>

template <typename Type, typename Enable = void>
Expand All @@ -262,6 +278,20 @@ struct OutputArrayWriter<Type, enable_if_has_c_type_not_boolean<Type>> {
void WriteNull() { *values++ = T{}; }
};

template <typename Type>
struct OutputArrayWriter<Type, enable_if_decimal<Type>> {
using T = typename TypeTraits<Type>::ScalarType::ValueType;
using endian_agnostic = std::array<uint8_t, sizeof(T)>;
endian_agnostic* values;

explicit OutputArrayWriter(ArrayData* data)
: values(data->GetMutableValues<endian_agnostic>(1)) {}

void Write(T value) { value.ToBytes(values++->data()); }

void WriteNull() { T{}.ToBytes(values++->data()); }
};

// (Un)box Scalar to / from C++ value

template <typename Type, typename Enable = void>
Expand Down Expand Up @@ -538,6 +568,22 @@ struct OutputAdapter<Type, enable_if_base_binary<Type>> {
}
};

template <typename Type>
struct OutputAdapter<Type, enable_if_decimal<Type>> {
using T = typename TypeTraits<Type>::ScalarType::ValueType;
using endian_agnostic = std::array<uint8_t, sizeof(T)>;

template <typename Generator>
static Status Write(KernelContext*, Datum* out, Generator&& generator) {
ArrayData* out_arr = out->mutable_array();
auto out_data = out_arr->GetMutableValues<endian_agnostic>(1);
for (int64_t i = 0; i < out_arr->length; ++i) {
generator().ToBytes(out_data++->data());
}
return Status::OK();
}
};

// A kernel exec generator for unary functions that addresses both array and
// scalar inputs and dispatches input iteration and output writing to other
// templates
Expand Down
Loading