lidavidm commented on a change in pull request #10557: URL: https://github.com/apache/arrow/pull/10557#discussion_r661699184
########## File path: cpp/src/arrow/compute/kernels/scalar_if_else.cc ########## @@ -676,7 +677,351 @@ void AddPrimitiveIfElseKernels(const std::shared_ptr<ScalarFunction>& scalar_fun } } -} // namespace +// Helper to copy or broadcast fixed-width values between buffers. +template <typename Type, typename Enable = void> +struct CopyFixedWidth {}; +template <> +struct CopyFixedWidth<BooleanType> { + static void CopyScalar(const Scalar& scalar, uint8_t* out_values, const int64_t offset, + const int64_t length) { + const bool value = UnboxScalar<BooleanType>::Unbox(scalar); + BitUtil::SetBitsTo(out_values, offset, length, value); + } + static void CopyArray(const ArrayData& array, uint8_t* out_values, const int64_t offset, + const int64_t length) { + arrow::internal::CopyBitmap(array.buffers[1]->data(), array.offset + offset, length, + out_values, offset); + } +}; +template <typename Type> +struct CopyFixedWidth<Type, enable_if_number<Type>> { + using CType = typename TypeTraits<Type>::CType; + static void CopyScalar(const Scalar& values, uint8_t* raw_out_values, + const int64_t offset, const int64_t length) { + CType* out_values = reinterpret_cast<CType*>(raw_out_values); + const CType value = UnboxScalar<Type>::Unbox(values); + std::fill(out_values + offset, out_values + offset + length, value); + } + static void CopyArray(const ArrayData& array, uint8_t* raw_out_values, + const int64_t offset, const int64_t length) { + CType* out_values = reinterpret_cast<CType*>(raw_out_values); + const CType* in_values = array.GetValues<CType>(1); + std::copy(in_values + offset, in_values + offset + length, out_values + offset); + } +}; +template <typename Type> +struct CopyFixedWidth<Type, enable_if_same<Type, FixedSizeBinaryType>> { + static void CopyScalar(const Scalar& values, uint8_t* out_values, const int64_t offset, + const int64_t length) { + const int32_t width = + checked_cast<const FixedSizeBinaryType&>(*values.type).byte_width(); + uint8_t* next = out_values + (width * offset); + const auto& scalar = checked_cast<const FixedSizeBinaryScalar&>(values); + // Scalar may have null value buffer + if (!scalar.value) return; Review comment: It looks like this is because the various binary scalars have constructors that take only a DataType - for the non-fixed-size scalars, we can construct an empty buffer, but for the fixed-size scalar, doing this would require allocation. And just removing that constructor for FixedSizeBinaryScalar just pushes the problem around (e.g. now MakeNullScalar needs to do allocation, and it complicates the overloading it does). -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: github-unsubscr...@arrow.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org