|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#pragma once |
|
|
|
#include <iosfwd> |
|
#include <memory> |
|
#include <ratio> |
|
#include <string> |
|
#include <string_view> |
|
#include <utility> |
|
#include <vector> |
|
|
|
#include "arrow/compare.h" |
|
#include "arrow/extension_type.h" |
|
#include "arrow/result.h" |
|
#include "arrow/status.h" |
|
#include "arrow/type.h" |
|
#include "arrow/type_fwd.h" |
|
#include "arrow/type_traits.h" |
|
#include "arrow/util/compare.h" |
|
#include "arrow/util/decimal.h" |
|
#include "arrow/util/visibility.h" |
|
#include "arrow/visit_type_inline.h" |
|
|
|
namespace arrow { |
|
|
|
class Array; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct ARROW_EXPORT Scalar : public std::enable_shared_from_this<Scalar>, |
|
public util::EqualityComparable<Scalar> { |
|
virtual ~Scalar() = default; |
|
|
|
|
|
std::shared_ptr<DataType> type; |
|
|
|
|
|
bool is_valid = false; |
|
|
|
bool Equals(const Scalar& other, |
|
const EqualOptions& options = EqualOptions::Defaults()) const; |
|
|
|
bool ApproxEquals(const Scalar& other, |
|
const EqualOptions& options = EqualOptions::Defaults()) const; |
|
|
|
struct ARROW_EXPORT Hash { |
|
size_t operator()(const Scalar& scalar) const { return scalar.hash(); } |
|
|
|
size_t operator()(const std::shared_ptr<Scalar>& scalar) const { |
|
return scalar->hash(); |
|
} |
|
}; |
|
|
|
size_t hash() const; |
|
|
|
std::string ToString() const; |
|
|
|
|
|
|
|
|
|
|
|
|
|
Status Validate() const; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Status ValidateFull() const; |
|
|
|
static Result<std::shared_ptr<Scalar>> Parse(const std::shared_ptr<DataType>& type, |
|
std::string_view repr); |
|
|
|
|
|
Result<std::shared_ptr<Scalar>> CastTo(std::shared_ptr<DataType> to) const; |
|
|
|
|
|
Status Accept(ScalarVisitor* visitor) const; |
|
|
|
|
|
|
|
std::shared_ptr<Scalar> GetSharedPtr() const { |
|
return const_cast<Scalar*>(this)->shared_from_this(); |
|
} |
|
|
|
protected: |
|
Scalar(std::shared_ptr<DataType> type, bool is_valid) |
|
: type(std::move(type)), is_valid(is_valid) {} |
|
}; |
|
|
|
ARROW_EXPORT void PrintTo(const Scalar& scalar, std::ostream* os); |
|
|
|
|
|
|
|
|
|
|
|
|
|
struct ARROW_EXPORT NullScalar : public Scalar { |
|
public: |
|
using TypeClass = NullType; |
|
|
|
NullScalar() : Scalar{null(), false} {} |
|
}; |
|
|
|
|
|
|
|
namespace internal { |
|
|
|
constexpr auto kScalarScratchSpaceSize = sizeof(int64_t) * 2; |
|
|
|
template <typename Impl> |
|
struct ArraySpanFillFromScalarScratchSpace { |
|
|
|
|
|
|
|
alignas(int64_t) mutable uint8_t scratch_space_[kScalarScratchSpaceSize]; |
|
|
|
private: |
|
template <typename... Args> |
|
explicit ArraySpanFillFromScalarScratchSpace(Args&&... args) { |
|
Impl::FillScratchSpace(scratch_space_, std::forward<Args>(args)...); |
|
} |
|
|
|
ArraySpanFillFromScalarScratchSpace() = delete; |
|
|
|
friend Impl; |
|
}; |
|
|
|
struct ARROW_EXPORT PrimitiveScalarBase : public Scalar { |
|
explicit PrimitiveScalarBase(std::shared_ptr<DataType> type) |
|
: Scalar(std::move(type), false) {} |
|
|
|
using Scalar::Scalar; |
|
|
|
virtual const void* data() const = 0; |
|
|
|
virtual std::string_view view() const = 0; |
|
}; |
|
|
|
template <typename T, typename CType = typename T::c_type> |
|
struct PrimitiveScalar : public PrimitiveScalarBase { |
|
using PrimitiveScalarBase::PrimitiveScalarBase; |
|
using TypeClass = T; |
|
using ValueType = CType; |
|
|
|
|
|
PrimitiveScalar(ValueType value, std::shared_ptr<DataType> type) |
|
: PrimitiveScalarBase(std::move(type), true), value(value) {} |
|
|
|
explicit PrimitiveScalar(std::shared_ptr<DataType> type) |
|
: PrimitiveScalarBase(std::move(type), false) {} |
|
|
|
ValueType value{}; |
|
|
|
const void* data() const override { return &value; } |
|
std::string_view view() const override { |
|
return std::string_view(reinterpret_cast<const char*>(&value), sizeof(ValueType)); |
|
}; |
|
}; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
struct ARROW_EXPORT BooleanScalar : public internal::PrimitiveScalar<BooleanType, bool> { |
|
using Base = internal::PrimitiveScalar<BooleanType, bool>; |
|
using Base::Base; |
|
|
|
explicit BooleanScalar(bool value) : Base(value, boolean()) {} |
|
|
|
BooleanScalar() : Base(boolean()) {} |
|
}; |
|
|
|
template <typename T> |
|
struct NumericScalar : public internal::PrimitiveScalar<T> { |
|
using Base = typename internal::PrimitiveScalar<T>; |
|
using Base::Base; |
|
using TypeClass = typename Base::TypeClass; |
|
using ValueType = typename Base::ValueType; |
|
|
|
explicit NumericScalar(ValueType value) |
|
: Base(value, TypeTraits<T>::type_singleton()) {} |
|
|
|
NumericScalar() : Base(TypeTraits<T>::type_singleton()) {} |
|
}; |
|
|
|
struct ARROW_EXPORT Int8Scalar : public NumericScalar<Int8Type> { |
|
using NumericScalar<Int8Type>::NumericScalar; |
|
}; |
|
|
|
struct ARROW_EXPORT Int16Scalar : public NumericScalar<Int16Type> { |
|
using NumericScalar<Int16Type>::NumericScalar; |
|
}; |
|
|
|
struct ARROW_EXPORT Int32Scalar : public NumericScalar<Int32Type> { |
|
using NumericScalar<Int32Type>::NumericScalar; |
|
}; |
|
|
|
struct ARROW_EXPORT Int64Scalar : public NumericScalar<Int64Type> { |
|
using NumericScalar<Int64Type>::NumericScalar; |
|
}; |
|
|
|
struct ARROW_EXPORT UInt8Scalar : public NumericScalar<UInt8Type> { |
|
using NumericScalar<UInt8Type>::NumericScalar; |
|
}; |
|
|
|
struct ARROW_EXPORT UInt16Scalar : public NumericScalar<UInt16Type> { |
|
using NumericScalar<UInt16Type>::NumericScalar; |
|
}; |
|
|
|
struct ARROW_EXPORT UInt32Scalar : public NumericScalar<UInt32Type> { |
|
using NumericScalar<UInt32Type>::NumericScalar; |
|
}; |
|
|
|
struct ARROW_EXPORT UInt64Scalar : public NumericScalar<UInt64Type> { |
|
using NumericScalar<UInt64Type>::NumericScalar; |
|
}; |
|
|
|
struct ARROW_EXPORT HalfFloatScalar : public NumericScalar<HalfFloatType> { |
|
using NumericScalar<HalfFloatType>::NumericScalar; |
|
}; |
|
|
|
struct ARROW_EXPORT FloatScalar : public NumericScalar<FloatType> { |
|
using NumericScalar<FloatType>::NumericScalar; |
|
}; |
|
|
|
struct ARROW_EXPORT DoubleScalar : public NumericScalar<DoubleType> { |
|
using NumericScalar<DoubleType>::NumericScalar; |
|
}; |
|
|
|
struct ARROW_EXPORT BaseBinaryScalar : public internal::PrimitiveScalarBase { |
|
using ValueType = std::shared_ptr<Buffer>; |
|
|
|
|
|
|
|
|
|
|
|
const std::shared_ptr<Buffer> value = NULLPTR; |
|
|
|
const void* data() const override { |
|
return value ? reinterpret_cast<const void*>(value->data()) : NULLPTR; |
|
} |
|
std::string_view view() const override { |
|
return value ? std::string_view(*value) : std::string_view(); |
|
} |
|
|
|
explicit BaseBinaryScalar(std::shared_ptr<DataType> type) |
|
: internal::PrimitiveScalarBase(std::move(type)) {} |
|
|
|
BaseBinaryScalar(std::shared_ptr<Buffer> value, std::shared_ptr<DataType> type) |
|
: internal::PrimitiveScalarBase{std::move(type), true}, value(std::move(value)) {} |
|
|
|
BaseBinaryScalar(std::string s, std::shared_ptr<DataType> type); |
|
}; |
|
|
|
struct ARROW_EXPORT BinaryScalar |
|
: public BaseBinaryScalar, |
|
private internal::ArraySpanFillFromScalarScratchSpace<BinaryScalar> { |
|
using TypeClass = BinaryType; |
|
using ArraySpanFillFromScalarScratchSpace = |
|
internal::ArraySpanFillFromScalarScratchSpace<BinaryScalar>; |
|
|
|
explicit BinaryScalar(std::shared_ptr<DataType> type) |
|
: BaseBinaryScalar(std::move(type)), |
|
ArraySpanFillFromScalarScratchSpace(this->value) {} |
|
|
|
BinaryScalar(std::shared_ptr<Buffer> value, std::shared_ptr<DataType> type) |
|
: BaseBinaryScalar(std::move(value), std::move(type)), |
|
ArraySpanFillFromScalarScratchSpace(this->value) {} |
|
|
|
BinaryScalar(std::string s, std::shared_ptr<DataType> type) |
|
: BaseBinaryScalar(std::move(s), std::move(type)), |
|
ArraySpanFillFromScalarScratchSpace(this->value) {} |
|
|
|
explicit BinaryScalar(std::shared_ptr<Buffer> value) |
|
: BinaryScalar(std::move(value), binary()) {} |
|
|
|
explicit BinaryScalar(std::string s) : BinaryScalar(std::move(s), binary()) {} |
|
|
|
BinaryScalar() : BinaryScalar(binary()) {} |
|
|
|
private: |
|
static void FillScratchSpace(uint8_t* scratch_space, |
|
const std::shared_ptr<Buffer>& value); |
|
|
|
friend ArraySpan; |
|
friend ArraySpanFillFromScalarScratchSpace; |
|
}; |
|
|
|
struct ARROW_EXPORT StringScalar : public BinaryScalar { |
|
using BinaryScalar::BinaryScalar; |
|
using TypeClass = StringType; |
|
|
|
explicit StringScalar(std::shared_ptr<Buffer> value) |
|
: StringScalar(std::move(value), utf8()) {} |
|
|
|
explicit StringScalar(std::string s) : BinaryScalar(std::move(s), utf8()) {} |
|
|
|
StringScalar() : StringScalar(utf8()) {} |
|
}; |
|
|
|
struct ARROW_EXPORT BinaryViewScalar |
|
: public BaseBinaryScalar, |
|
private internal::ArraySpanFillFromScalarScratchSpace<BinaryViewScalar> { |
|
using TypeClass = BinaryViewType; |
|
using ArraySpanFillFromScalarScratchSpace = |
|
internal::ArraySpanFillFromScalarScratchSpace<BinaryViewScalar>; |
|
|
|
explicit BinaryViewScalar(std::shared_ptr<DataType> type) |
|
: BaseBinaryScalar(std::move(type)), |
|
ArraySpanFillFromScalarScratchSpace(this->value) {} |
|
|
|
BinaryViewScalar(std::shared_ptr<Buffer> value, std::shared_ptr<DataType> type) |
|
: BaseBinaryScalar(std::move(value), std::move(type)), |
|
ArraySpanFillFromScalarScratchSpace(this->value) {} |
|
|
|
BinaryViewScalar(std::string s, std::shared_ptr<DataType> type) |
|
: BaseBinaryScalar(std::move(s), std::move(type)), |
|
ArraySpanFillFromScalarScratchSpace(this->value) {} |
|
|
|
explicit BinaryViewScalar(std::shared_ptr<Buffer> value) |
|
: BinaryViewScalar(std::move(value), binary_view()) {} |
|
|
|
explicit BinaryViewScalar(std::string s) |
|
: BinaryViewScalar(std::move(s), binary_view()) {} |
|
|
|
BinaryViewScalar() : BinaryViewScalar(binary_view()) {} |
|
|
|
std::string_view view() const override { return std::string_view(*this->value); } |
|
|
|
private: |
|
static void FillScratchSpace(uint8_t* scratch_space, |
|
const std::shared_ptr<Buffer>& value); |
|
|
|
friend ArraySpan; |
|
friend ArraySpanFillFromScalarScratchSpace; |
|
}; |
|
|
|
struct ARROW_EXPORT StringViewScalar : public BinaryViewScalar { |
|
using BinaryViewScalar::BinaryViewScalar; |
|
using TypeClass = StringViewType; |
|
|
|
explicit StringViewScalar(std::shared_ptr<Buffer> value) |
|
: StringViewScalar(std::move(value), utf8_view()) {} |
|
|
|
explicit StringViewScalar(std::string s) |
|
: BinaryViewScalar(std::move(s), utf8_view()) {} |
|
|
|
StringViewScalar() : StringViewScalar(utf8_view()) {} |
|
}; |
|
|
|
struct ARROW_EXPORT LargeBinaryScalar |
|
: public BaseBinaryScalar, |
|
private internal::ArraySpanFillFromScalarScratchSpace<LargeBinaryScalar> { |
|
using TypeClass = LargeBinaryType; |
|
using ArraySpanFillFromScalarScratchSpace = |
|
internal::ArraySpanFillFromScalarScratchSpace<LargeBinaryScalar>; |
|
|
|
explicit LargeBinaryScalar(std::shared_ptr<DataType> type) |
|
: BaseBinaryScalar(std::move(type)), |
|
ArraySpanFillFromScalarScratchSpace(this->value) {} |
|
|
|
LargeBinaryScalar(std::shared_ptr<Buffer> value, std::shared_ptr<DataType> type) |
|
: BaseBinaryScalar(std::move(value), std::move(type)), |
|
ArraySpanFillFromScalarScratchSpace(this->value) {} |
|
|
|
LargeBinaryScalar(std::string s, std::shared_ptr<DataType> type) |
|
: BaseBinaryScalar(std::move(s), std::move(type)), |
|
ArraySpanFillFromScalarScratchSpace(this->value) {} |
|
|
|
explicit LargeBinaryScalar(std::shared_ptr<Buffer> value) |
|
: LargeBinaryScalar(std::move(value), large_binary()) {} |
|
|
|
explicit LargeBinaryScalar(std::string s) |
|
: LargeBinaryScalar(std::move(s), large_binary()) {} |
|
|
|
LargeBinaryScalar() : LargeBinaryScalar(large_binary()) {} |
|
|
|
private: |
|
static void FillScratchSpace(uint8_t* scratch_space, |
|
const std::shared_ptr<Buffer>& value); |
|
|
|
friend ArraySpan; |
|
friend ArraySpanFillFromScalarScratchSpace; |
|
}; |
|
|
|
struct ARROW_EXPORT LargeStringScalar : public LargeBinaryScalar { |
|
using LargeBinaryScalar::LargeBinaryScalar; |
|
using TypeClass = LargeStringType; |
|
|
|
explicit LargeStringScalar(std::shared_ptr<Buffer> value) |
|
: LargeStringScalar(std::move(value), large_utf8()) {} |
|
|
|
explicit LargeStringScalar(std::string s) |
|
: LargeBinaryScalar(std::move(s), large_utf8()) {} |
|
|
|
LargeStringScalar() : LargeStringScalar(large_utf8()) {} |
|
}; |
|
|
|
struct ARROW_EXPORT FixedSizeBinaryScalar : public BinaryScalar { |
|
using TypeClass = FixedSizeBinaryType; |
|
|
|
FixedSizeBinaryScalar(std::shared_ptr<Buffer> value, std::shared_ptr<DataType> type, |
|
bool is_valid = true); |
|
|
|
explicit FixedSizeBinaryScalar(const std::shared_ptr<Buffer>& value, |
|
bool is_valid = true); |
|
|
|
explicit FixedSizeBinaryScalar(std::string s, bool is_valid = true); |
|
}; |
|
|
|
template <typename T> |
|
struct TemporalScalar : internal::PrimitiveScalar<T> { |
|
using internal::PrimitiveScalar<T>::PrimitiveScalar; |
|
using ValueType = typename internal::PrimitiveScalar<T>::ValueType; |
|
|
|
TemporalScalar(ValueType value, std::shared_ptr<DataType> type) |
|
: internal::PrimitiveScalar<T>(std::move(value), type) {} |
|
}; |
|
|
|
template <typename T> |
|
struct DateScalar : public TemporalScalar<T> { |
|
using TemporalScalar<T>::TemporalScalar; |
|
using ValueType = typename TemporalScalar<T>::ValueType; |
|
|
|
explicit DateScalar(ValueType value) |
|
: TemporalScalar<T>(std::move(value), TypeTraits<T>::type_singleton()) {} |
|
DateScalar() : TemporalScalar<T>(TypeTraits<T>::type_singleton()) {} |
|
}; |
|
|
|
struct ARROW_EXPORT Date32Scalar : public DateScalar<Date32Type> { |
|
using DateScalar<Date32Type>::DateScalar; |
|
}; |
|
|
|
struct ARROW_EXPORT Date64Scalar : public DateScalar<Date64Type> { |
|
using DateScalar<Date64Type>::DateScalar; |
|
}; |
|
|
|
template <typename T> |
|
struct TimeScalar : public TemporalScalar<T> { |
|
using TemporalScalar<T>::TemporalScalar; |
|
|
|
TimeScalar(typename TemporalScalar<T>::ValueType value, TimeUnit::type unit) |
|
: TimeScalar(std::move(value), std::make_shared<T>(unit)) {} |
|
}; |
|
|
|
struct ARROW_EXPORT Time32Scalar : public TimeScalar<Time32Type> { |
|
using TimeScalar<Time32Type>::TimeScalar; |
|
}; |
|
|
|
struct ARROW_EXPORT Time64Scalar : public TimeScalar<Time64Type> { |
|
using TimeScalar<Time64Type>::TimeScalar; |
|
}; |
|
|
|
struct ARROW_EXPORT TimestampScalar : public TemporalScalar<TimestampType> { |
|
using TemporalScalar<TimestampType>::TemporalScalar; |
|
|
|
TimestampScalar(typename TemporalScalar<TimestampType>::ValueType value, |
|
TimeUnit::type unit, std::string tz = "") |
|
: TimestampScalar(std::move(value), timestamp(unit, std::move(tz))) {} |
|
|
|
static Result<TimestampScalar> FromISO8601(std::string_view iso8601, |
|
TimeUnit::type unit); |
|
}; |
|
|
|
template <typename T> |
|
struct IntervalScalar : public TemporalScalar<T> { |
|
using TemporalScalar<T>::TemporalScalar; |
|
using ValueType = typename TemporalScalar<T>::ValueType; |
|
|
|
explicit IntervalScalar(ValueType value) |
|
: TemporalScalar<T>(value, TypeTraits<T>::type_singleton()) {} |
|
IntervalScalar() : TemporalScalar<T>(TypeTraits<T>::type_singleton()) {} |
|
}; |
|
|
|
struct ARROW_EXPORT MonthIntervalScalar : public IntervalScalar<MonthIntervalType> { |
|
using IntervalScalar<MonthIntervalType>::IntervalScalar; |
|
}; |
|
|
|
struct ARROW_EXPORT DayTimeIntervalScalar : public IntervalScalar<DayTimeIntervalType> { |
|
using IntervalScalar<DayTimeIntervalType>::IntervalScalar; |
|
}; |
|
|
|
struct ARROW_EXPORT MonthDayNanoIntervalScalar |
|
: public IntervalScalar<MonthDayNanoIntervalType> { |
|
using IntervalScalar<MonthDayNanoIntervalType>::IntervalScalar; |
|
}; |
|
|
|
struct ARROW_EXPORT DurationScalar : public TemporalScalar<DurationType> { |
|
using TemporalScalar<DurationType>::TemporalScalar; |
|
|
|
DurationScalar(typename TemporalScalar<DurationType>::ValueType value, |
|
TimeUnit::type unit) |
|
: DurationScalar(std::move(value), duration(unit)) {} |
|
|
|
|
|
template <template <typename, typename> class StdDuration, typename Rep> |
|
explicit DurationScalar(StdDuration<Rep, std::nano> d) |
|
: DurationScalar{DurationScalar(d.count(), duration(TimeUnit::NANO))} {} |
|
|
|
|
|
template <template <typename, typename> class StdDuration, typename Rep> |
|
explicit DurationScalar(StdDuration<Rep, std::micro> d) |
|
: DurationScalar{DurationScalar(d.count(), duration(TimeUnit::MICRO))} {} |
|
|
|
|
|
template <template <typename, typename> class StdDuration, typename Rep> |
|
explicit DurationScalar(StdDuration<Rep, std::milli> d) |
|
: DurationScalar{DurationScalar(d.count(), duration(TimeUnit::MILLI))} {} |
|
|
|
|
|
|
|
template <template <typename, typename> class StdDuration, typename Rep, intmax_t Num> |
|
explicit DurationScalar(StdDuration<Rep, std::ratio<Num, 1>> d) |
|
: DurationScalar{DurationScalar(d.count() * Num, duration(TimeUnit::SECOND))} {} |
|
}; |
|
|
|
template <typename TYPE_CLASS, typename VALUE_TYPE> |
|
struct DecimalScalar : public internal::PrimitiveScalarBase { |
|
using internal::PrimitiveScalarBase::PrimitiveScalarBase; |
|
using TypeClass = TYPE_CLASS; |
|
using ValueType = VALUE_TYPE; |
|
|
|
DecimalScalar(ValueType value, std::shared_ptr<DataType> type) |
|
: internal::PrimitiveScalarBase(std::move(type), true), value(value) {} |
|
|
|
const void* data() const override { |
|
return reinterpret_cast<const void*>(value.native_endian_bytes()); |
|
} |
|
|
|
std::string_view view() const override { |
|
return std::string_view(reinterpret_cast<const char*>(value.native_endian_bytes()), |
|
ValueType::kByteWidth); |
|
} |
|
|
|
ValueType value; |
|
}; |
|
|
|
struct ARROW_EXPORT Decimal32Scalar : public DecimalScalar<Decimal32Type, Decimal32> { |
|
using DecimalScalar::DecimalScalar; |
|
}; |
|
|
|
struct ARROW_EXPORT Decimal64Scalar : public DecimalScalar<Decimal64Type, Decimal64> { |
|
using DecimalScalar::DecimalScalar; |
|
}; |
|
|
|
struct ARROW_EXPORT Decimal128Scalar : public DecimalScalar<Decimal128Type, Decimal128> { |
|
using DecimalScalar::DecimalScalar; |
|
}; |
|
|
|
struct ARROW_EXPORT Decimal256Scalar : public DecimalScalar<Decimal256Type, Decimal256> { |
|
using DecimalScalar::DecimalScalar; |
|
}; |
|
|
|
struct ARROW_EXPORT BaseListScalar : public Scalar { |
|
using ValueType = std::shared_ptr<Array>; |
|
|
|
BaseListScalar(std::shared_ptr<Array> value, std::shared_ptr<DataType> type, |
|
bool is_valid = true); |
|
|
|
|
|
|
|
|
|
|
|
const std::shared_ptr<Array> value; |
|
}; |
|
|
|
struct ARROW_EXPORT ListScalar |
|
: public BaseListScalar, |
|
private internal::ArraySpanFillFromScalarScratchSpace<ListScalar> { |
|
using TypeClass = ListType; |
|
using ArraySpanFillFromScalarScratchSpace = |
|
internal::ArraySpanFillFromScalarScratchSpace<ListScalar>; |
|
|
|
ListScalar(std::shared_ptr<Array> value, std::shared_ptr<DataType> type, |
|
bool is_valid = true) |
|
: BaseListScalar(std::move(value), std::move(type), is_valid), |
|
ArraySpanFillFromScalarScratchSpace(this->value) {} |
|
|
|
explicit ListScalar(std::shared_ptr<Array> value, bool is_valid = true); |
|
|
|
private: |
|
static void FillScratchSpace(uint8_t* scratch_space, |
|
const std::shared_ptr<Array>& value); |
|
|
|
friend ArraySpan; |
|
friend ArraySpanFillFromScalarScratchSpace; |
|
}; |
|
|
|
struct ARROW_EXPORT LargeListScalar |
|
: public BaseListScalar, |
|
private internal::ArraySpanFillFromScalarScratchSpace<LargeListScalar> { |
|
using TypeClass = LargeListType; |
|
using ArraySpanFillFromScalarScratchSpace = |
|
internal::ArraySpanFillFromScalarScratchSpace<LargeListScalar>; |
|
|
|
LargeListScalar(std::shared_ptr<Array> value, std::shared_ptr<DataType> type, |
|
bool is_valid = true) |
|
: BaseListScalar(std::move(value), std::move(type), is_valid), |
|
ArraySpanFillFromScalarScratchSpace(this->value) {} |
|
|
|
explicit LargeListScalar(std::shared_ptr<Array> value, bool is_valid = true); |
|
|
|
private: |
|
static void FillScratchSpace(uint8_t* scratch_space, |
|
const std::shared_ptr<Array>& value); |
|
|
|
friend ArraySpan; |
|
friend ArraySpanFillFromScalarScratchSpace; |
|
}; |
|
|
|
struct ARROW_EXPORT ListViewScalar |
|
: public BaseListScalar, |
|
private internal::ArraySpanFillFromScalarScratchSpace<ListViewScalar> { |
|
using TypeClass = ListViewType; |
|
using ArraySpanFillFromScalarScratchSpace = |
|
internal::ArraySpanFillFromScalarScratchSpace<ListViewScalar>; |
|
|
|
ListViewScalar(std::shared_ptr<Array> value, std::shared_ptr<DataType> type, |
|
bool is_valid = true) |
|
: BaseListScalar(std::move(value), std::move(type), is_valid), |
|
ArraySpanFillFromScalarScratchSpace(this->value) {} |
|
|
|
explicit ListViewScalar(std::shared_ptr<Array> value, bool is_valid = true); |
|
|
|
private: |
|
static void FillScratchSpace(uint8_t* scratch_space, |
|
const std::shared_ptr<Array>& value); |
|
|
|
friend ArraySpan; |
|
friend ArraySpanFillFromScalarScratchSpace; |
|
}; |
|
|
|
struct ARROW_EXPORT LargeListViewScalar |
|
: public BaseListScalar, |
|
private internal::ArraySpanFillFromScalarScratchSpace<LargeListViewScalar> { |
|
using TypeClass = LargeListViewType; |
|
using ArraySpanFillFromScalarScratchSpace = |
|
internal::ArraySpanFillFromScalarScratchSpace<LargeListViewScalar>; |
|
|
|
LargeListViewScalar(std::shared_ptr<Array> value, std::shared_ptr<DataType> type, |
|
bool is_valid = true) |
|
: BaseListScalar(std::move(value), std::move(type), is_valid), |
|
ArraySpanFillFromScalarScratchSpace(this->value) {} |
|
|
|
explicit LargeListViewScalar(std::shared_ptr<Array> value, bool is_valid = true); |
|
|
|
private: |
|
static void FillScratchSpace(uint8_t* scratch_space, |
|
const std::shared_ptr<Array>& value); |
|
|
|
friend ArraySpan; |
|
friend ArraySpanFillFromScalarScratchSpace; |
|
}; |
|
|
|
struct ARROW_EXPORT MapScalar |
|
: public BaseListScalar, |
|
private internal::ArraySpanFillFromScalarScratchSpace<MapScalar> { |
|
using TypeClass = MapType; |
|
using ArraySpanFillFromScalarScratchSpace = |
|
internal::ArraySpanFillFromScalarScratchSpace<MapScalar>; |
|
|
|
MapScalar(std::shared_ptr<Array> value, std::shared_ptr<DataType> type, |
|
bool is_valid = true) |
|
: BaseListScalar(std::move(value), std::move(type), is_valid), |
|
ArraySpanFillFromScalarScratchSpace(this->value) {} |
|
|
|
explicit MapScalar(std::shared_ptr<Array> value, bool is_valid = true); |
|
|
|
private: |
|
static void FillScratchSpace(uint8_t* scratch_space, |
|
const std::shared_ptr<Array>& value); |
|
|
|
friend ArraySpan; |
|
friend ArraySpanFillFromScalarScratchSpace; |
|
}; |
|
|
|
struct ARROW_EXPORT FixedSizeListScalar : public BaseListScalar { |
|
using TypeClass = FixedSizeListType; |
|
|
|
FixedSizeListScalar(std::shared_ptr<Array> value, std::shared_ptr<DataType> type, |
|
bool is_valid = true); |
|
|
|
explicit FixedSizeListScalar(std::shared_ptr<Array> value, bool is_valid = true); |
|
}; |
|
|
|
struct ARROW_EXPORT StructScalar : public Scalar { |
|
using TypeClass = StructType; |
|
using ValueType = std::vector<std::shared_ptr<Scalar>>; |
|
|
|
ScalarVector value; |
|
|
|
Result<std::shared_ptr<Scalar>> field(FieldRef ref) const; |
|
|
|
StructScalar(ValueType value, std::shared_ptr<DataType> type, bool is_valid = true) |
|
: Scalar(std::move(type), is_valid), value(std::move(value)) {} |
|
|
|
static Result<std::shared_ptr<StructScalar>> Make(ValueType value, |
|
std::vector<std::string> field_names); |
|
}; |
|
|
|
struct ARROW_EXPORT UnionScalar : public Scalar { |
|
|
|
|
|
const int8_t type_code; |
|
|
|
virtual const std::shared_ptr<Scalar>& child_value() const = 0; |
|
|
|
protected: |
|
UnionScalar(std::shared_ptr<DataType> type, int8_t type_code, bool is_valid) |
|
: Scalar(std::move(type), is_valid), type_code(type_code) {} |
|
|
|
struct UnionScratchSpace { |
|
alignas(int64_t) int8_t type_code; |
|
alignas(int64_t) uint8_t offsets[sizeof(int32_t) * 2]; |
|
}; |
|
static_assert(sizeof(UnionScratchSpace) <= internal::kScalarScratchSpaceSize); |
|
|
|
friend ArraySpan; |
|
}; |
|
|
|
struct ARROW_EXPORT SparseUnionScalar |
|
: public UnionScalar, |
|
private internal::ArraySpanFillFromScalarScratchSpace<SparseUnionScalar> { |
|
using TypeClass = SparseUnionType; |
|
using ArraySpanFillFromScalarScratchSpace = |
|
internal::ArraySpanFillFromScalarScratchSpace<SparseUnionScalar>; |
|
|
|
|
|
|
|
|
|
using ValueType = std::vector<std::shared_ptr<Scalar>>; |
|
|
|
|
|
|
|
|
|
const ValueType value; |
|
|
|
|
|
int child_id; |
|
|
|
SparseUnionScalar(ValueType value, int8_t type_code, std::shared_ptr<DataType> type); |
|
|
|
const std::shared_ptr<Scalar>& child_value() const override { |
|
return this->value[this->child_id]; |
|
} |
|
|
|
|
|
|
|
static std::shared_ptr<Scalar> FromValue(std::shared_ptr<Scalar> value, int field_index, |
|
std::shared_ptr<DataType> type); |
|
|
|
private: |
|
static void FillScratchSpace(uint8_t* scratch_space, int8_t type_code); |
|
|
|
friend ArraySpan; |
|
friend ArraySpanFillFromScalarScratchSpace; |
|
}; |
|
|
|
struct ARROW_EXPORT DenseUnionScalar |
|
: public UnionScalar, |
|
private internal::ArraySpanFillFromScalarScratchSpace<DenseUnionScalar> { |
|
using TypeClass = DenseUnionType; |
|
using ArraySpanFillFromScalarScratchSpace = |
|
internal::ArraySpanFillFromScalarScratchSpace<DenseUnionScalar>; |
|
|
|
|
|
|
|
using ValueType = std::shared_ptr<Scalar>; |
|
|
|
|
|
|
|
|
|
const ValueType value; |
|
|
|
const std::shared_ptr<Scalar>& child_value() const override { return this->value; } |
|
|
|
DenseUnionScalar(ValueType value, int8_t type_code, std::shared_ptr<DataType> type) |
|
: UnionScalar(std::move(type), type_code, value->is_valid), |
|
ArraySpanFillFromScalarScratchSpace(type_code), |
|
value(std::move(value)) {} |
|
|
|
private: |
|
static void FillScratchSpace(uint8_t* scratch_space, int8_t type_code); |
|
|
|
friend ArraySpan; |
|
friend ArraySpanFillFromScalarScratchSpace; |
|
}; |
|
|
|
struct ARROW_EXPORT RunEndEncodedScalar |
|
: public Scalar, |
|
private internal::ArraySpanFillFromScalarScratchSpace<RunEndEncodedScalar> { |
|
using TypeClass = RunEndEncodedType; |
|
using ValueType = std::shared_ptr<Scalar>; |
|
using ArraySpanFillFromScalarScratchSpace = |
|
internal::ArraySpanFillFromScalarScratchSpace<RunEndEncodedScalar>; |
|
|
|
|
|
|
|
|
|
|
|
const ValueType value; |
|
|
|
RunEndEncodedScalar(std::shared_ptr<Scalar> value, std::shared_ptr<DataType> type); |
|
|
|
|
|
explicit RunEndEncodedScalar(const std::shared_ptr<DataType>& type); |
|
|
|
~RunEndEncodedScalar() override; |
|
|
|
const std::shared_ptr<DataType>& run_end_type() const { |
|
return ree_type().run_end_type(); |
|
} |
|
|
|
const std::shared_ptr<DataType>& value_type() const { return ree_type().value_type(); } |
|
|
|
private: |
|
const TypeClass& ree_type() const { return internal::checked_cast<TypeClass&>(*type); } |
|
|
|
static void FillScratchSpace(uint8_t* scratch_space, const DataType& type); |
|
|
|
friend ArraySpan; |
|
friend ArraySpanFillFromScalarScratchSpace; |
|
}; |
|
|
|
|
|
|
|
|
|
|
|
struct ARROW_EXPORT DictionaryScalar : public internal::PrimitiveScalarBase { |
|
using TypeClass = DictionaryType; |
|
struct ValueType { |
|
std::shared_ptr<Scalar> index; |
|
std::shared_ptr<Array> dictionary; |
|
} value; |
|
|
|
explicit DictionaryScalar(std::shared_ptr<DataType> type); |
|
|
|
DictionaryScalar(ValueType value, std::shared_ptr<DataType> type, bool is_valid = true) |
|
: internal::PrimitiveScalarBase(std::move(type), is_valid), |
|
value(std::move(value)) {} |
|
|
|
static std::shared_ptr<DictionaryScalar> Make(std::shared_ptr<Scalar> index, |
|
std::shared_ptr<Array> dict); |
|
|
|
Result<std::shared_ptr<Scalar>> GetEncodedValue() const; |
|
|
|
const void* data() const override { |
|
return internal::checked_cast<internal::PrimitiveScalarBase&>(*value.index).data(); |
|
} |
|
std::string_view view() const override { |
|
return internal::checked_cast<const internal::PrimitiveScalarBase&>(*value.index) |
|
.view(); |
|
} |
|
}; |
|
|
|
|
|
|
|
|
|
|
|
struct ARROW_EXPORT ExtensionScalar : public Scalar { |
|
using TypeClass = ExtensionType; |
|
using ValueType = std::shared_ptr<Scalar>; |
|
|
|
ExtensionScalar(std::shared_ptr<Scalar> storage, std::shared_ptr<DataType> type, |
|
bool is_valid = true) |
|
: Scalar(std::move(type), is_valid), value(std::move(storage)) {} |
|
|
|
template <typename Storage, |
|
typename = enable_if_t<std::is_base_of<Scalar, Storage>::value>> |
|
ExtensionScalar(Storage&& storage, std::shared_ptr<DataType> type, bool is_valid = true) |
|
: ExtensionScalar(std::make_shared<Storage>(std::move(storage)), std::move(type), |
|
is_valid) {} |
|
|
|
std::shared_ptr<Scalar> value; |
|
}; |
|
|
|
|
|
|
|
namespace internal { |
|
|
|
inline Status CheckBufferLength(...) { return Status::OK(); } |
|
|
|
ARROW_EXPORT Status CheckBufferLength(const FixedSizeBinaryType* t, |
|
const std::shared_ptr<Buffer>* b); |
|
|
|
} |
|
|
|
template <typename ValueRef> |
|
struct MakeScalarImpl; |
|
|
|
|
|
|
|
|
|
|
|
|
|
ARROW_EXPORT |
|
std::shared_ptr<Scalar> MakeNullScalar(std::shared_ptr<DataType> type); |
|
|
|
|
|
template <typename Value> |
|
Result<std::shared_ptr<Scalar>> MakeScalar(std::shared_ptr<DataType> type, |
|
Value&& value) { |
|
return MakeScalarImpl<Value&&>{type, std::forward<Value>(value), NULLPTR}.Finish(); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
template <typename Value, typename Traits = CTypeTraits<typename std::decay<Value>::type>, |
|
typename ScalarType = typename Traits::ScalarType, |
|
typename Enable = decltype(ScalarType(std::declval<Value>(), |
|
Traits::type_singleton()))> |
|
std::shared_ptr<Scalar> MakeScalar(Value value) { |
|
return std::make_shared<ScalarType>(std::move(value), Traits::type_singleton()); |
|
} |
|
|
|
inline std::shared_ptr<Scalar> MakeScalar(std::string value) { |
|
return std::make_shared<StringScalar>(std::move(value)); |
|
} |
|
|
|
inline std::shared_ptr<Scalar> MakeScalar(const std::shared_ptr<Scalar>& scalar) { |
|
return scalar; |
|
} |
|
|
|
|
|
template <typename ValueRef> |
|
struct MakeScalarImpl { |
|
template <typename T, typename ScalarType = typename TypeTraits<T>::ScalarType, |
|
typename ValueType = typename ScalarType::ValueType, |
|
typename Enable = typename std::enable_if< |
|
std::is_constructible<ScalarType, ValueType, |
|
std::shared_ptr<DataType>>::value && |
|
std::is_convertible<ValueRef, ValueType>::value>::type> |
|
Status Visit(const T& t) { |
|
ARROW_RETURN_NOT_OK(internal::CheckBufferLength(&t, &value_)); |
|
|
|
out_ = std::make_shared<ScalarType>( |
|
static_cast<ValueType>(static_cast<ValueRef>(value_)), std::move(type_)); |
|
return Status::OK(); |
|
} |
|
|
|
Status Visit(const ExtensionType& t) { |
|
ARROW_ASSIGN_OR_RAISE(auto storage, |
|
MakeScalar(t.storage_type(), static_cast<ValueRef>(value_))); |
|
out_ = std::make_shared<ExtensionScalar>(std::move(storage), type_); |
|
return Status::OK(); |
|
} |
|
|
|
|
|
template <typename T> |
|
enable_if_t< |
|
std::is_same<typename std::remove_reference<ValueRef>::type, std::string>::value && |
|
(is_base_binary_type<T>::value || std::is_same<T, FixedSizeBinaryType>::value), |
|
Status> |
|
Visit(const T& t) { |
|
using ScalarType = typename TypeTraits<T>::ScalarType; |
|
out_ = std::make_shared<ScalarType>(Buffer::FromString(std::move(value_)), |
|
std::move(type_)); |
|
return Status::OK(); |
|
} |
|
|
|
Status Visit(const DataType& t) { |
|
return Status::NotImplemented("constructing scalars of type ", t, |
|
" from unboxed values"); |
|
} |
|
|
|
Result<std::shared_ptr<Scalar>> Finish() && { |
|
ARROW_RETURN_NOT_OK(VisitTypeInline(*type_, this)); |
|
return std::move(out_); |
|
} |
|
|
|
std::shared_ptr<DataType> type_; |
|
ValueRef value_; |
|
std::shared_ptr<Scalar> out_; |
|
}; |
|
|
|
} |
|
|