File indexing completed on 2025-08-27 08:47:20
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021 #pragma once
0022
0023 #include <iosfwd>
0024 #include <memory>
0025 #include <ratio>
0026 #include <string>
0027 #include <string_view>
0028 #include <utility>
0029 #include <vector>
0030
0031 #include "arrow/compare.h"
0032 #include "arrow/extension_type.h"
0033 #include "arrow/result.h"
0034 #include "arrow/status.h"
0035 #include "arrow/type.h"
0036 #include "arrow/type_fwd.h"
0037 #include "arrow/type_traits.h"
0038 #include "arrow/util/compare.h"
0039 #include "arrow/util/decimal.h"
0040 #include "arrow/util/visibility.h"
0041 #include "arrow/visit_type_inline.h"
0042
0043 namespace arrow {
0044
0045 class Array;
0046
0047
0048
0049
0050
0051
0052
0053 struct ARROW_EXPORT Scalar : public std::enable_shared_from_this<Scalar>,
0054 public util::EqualityComparable<Scalar> {
0055 virtual ~Scalar() = default;
0056
0057
0058 std::shared_ptr<DataType> type;
0059
0060
0061 bool is_valid = false;
0062
0063 bool Equals(const Scalar& other,
0064 const EqualOptions& options = EqualOptions::Defaults()) const;
0065
0066 bool ApproxEquals(const Scalar& other,
0067 const EqualOptions& options = EqualOptions::Defaults()) const;
0068
0069 struct ARROW_EXPORT Hash {
0070 size_t operator()(const Scalar& scalar) const { return scalar.hash(); }
0071
0072 size_t operator()(const std::shared_ptr<Scalar>& scalar) const {
0073 return scalar->hash();
0074 }
0075 };
0076
0077 size_t hash() const;
0078
0079 std::string ToString() const;
0080
0081
0082
0083
0084
0085
0086 Status Validate() const;
0087
0088
0089
0090
0091
0092
0093
0094 Status ValidateFull() const;
0095
0096 static Result<std::shared_ptr<Scalar>> Parse(const std::shared_ptr<DataType>& type,
0097 std::string_view repr);
0098
0099
0100 Result<std::shared_ptr<Scalar>> CastTo(std::shared_ptr<DataType> to) const;
0101
0102
0103 Status Accept(ScalarVisitor* visitor) const;
0104
0105
0106
0107 std::shared_ptr<Scalar> GetSharedPtr() const {
0108 return const_cast<Scalar*>(this)->shared_from_this();
0109 }
0110
0111 protected:
0112 Scalar(std::shared_ptr<DataType> type, bool is_valid)
0113 : type(std::move(type)), is_valid(is_valid) {}
0114 };
0115
0116 ARROW_EXPORT void PrintTo(const Scalar& scalar, std::ostream* os);
0117
0118
0119
0120
0121
0122
0123 struct ARROW_EXPORT NullScalar : public Scalar {
0124 public:
0125 using TypeClass = NullType;
0126
0127 NullScalar() : Scalar{null(), false} {}
0128 };
0129
0130
0131
0132 namespace internal {
0133
0134 constexpr auto kScalarScratchSpaceSize = sizeof(int64_t) * 2;
0135
0136 template <typename Impl>
0137 struct ArraySpanFillFromScalarScratchSpace {
0138
0139
0140
0141 alignas(int64_t) mutable uint8_t scratch_space_[kScalarScratchSpaceSize];
0142
0143 private:
0144 template <typename... Args>
0145 explicit ArraySpanFillFromScalarScratchSpace(Args&&... args) {
0146 Impl::FillScratchSpace(scratch_space_, std::forward<Args>(args)...);
0147 }
0148
0149 ArraySpanFillFromScalarScratchSpace() = delete;
0150
0151 friend Impl;
0152 };
0153
0154 struct ARROW_EXPORT PrimitiveScalarBase : public Scalar {
0155 explicit PrimitiveScalarBase(std::shared_ptr<DataType> type)
0156 : Scalar(std::move(type), false) {}
0157
0158 using Scalar::Scalar;
0159
0160 virtual const void* data() const = 0;
0161
0162 virtual std::string_view view() const = 0;
0163 };
0164
0165 template <typename T, typename CType = typename T::c_type>
0166 struct PrimitiveScalar : public PrimitiveScalarBase {
0167 using PrimitiveScalarBase::PrimitiveScalarBase;
0168 using TypeClass = T;
0169 using ValueType = CType;
0170
0171
0172 PrimitiveScalar(ValueType value, std::shared_ptr<DataType> type)
0173 : PrimitiveScalarBase(std::move(type), true), value(value) {}
0174
0175 explicit PrimitiveScalar(std::shared_ptr<DataType> type)
0176 : PrimitiveScalarBase(std::move(type), false) {}
0177
0178 ValueType value{};
0179
0180 const void* data() const override { return &value; }
0181 std::string_view view() const override {
0182 return std::string_view(reinterpret_cast<const char*>(&value), sizeof(ValueType));
0183 };
0184 };
0185
0186 }
0187
0188
0189
0190
0191
0192 struct ARROW_EXPORT BooleanScalar : public internal::PrimitiveScalar<BooleanType, bool> {
0193 using Base = internal::PrimitiveScalar<BooleanType, bool>;
0194 using Base::Base;
0195
0196 explicit BooleanScalar(bool value) : Base(value, boolean()) {}
0197
0198 BooleanScalar() : Base(boolean()) {}
0199 };
0200
0201 template <typename T>
0202 struct NumericScalar : public internal::PrimitiveScalar<T> {
0203 using Base = typename internal::PrimitiveScalar<T>;
0204 using Base::Base;
0205 using TypeClass = typename Base::TypeClass;
0206 using ValueType = typename Base::ValueType;
0207
0208 explicit NumericScalar(ValueType value)
0209 : Base(value, TypeTraits<T>::type_singleton()) {}
0210
0211 NumericScalar() : Base(TypeTraits<T>::type_singleton()) {}
0212 };
0213
0214 struct ARROW_EXPORT Int8Scalar : public NumericScalar<Int8Type> {
0215 using NumericScalar<Int8Type>::NumericScalar;
0216 };
0217
0218 struct ARROW_EXPORT Int16Scalar : public NumericScalar<Int16Type> {
0219 using NumericScalar<Int16Type>::NumericScalar;
0220 };
0221
0222 struct ARROW_EXPORT Int32Scalar : public NumericScalar<Int32Type> {
0223 using NumericScalar<Int32Type>::NumericScalar;
0224 };
0225
0226 struct ARROW_EXPORT Int64Scalar : public NumericScalar<Int64Type> {
0227 using NumericScalar<Int64Type>::NumericScalar;
0228 };
0229
0230 struct ARROW_EXPORT UInt8Scalar : public NumericScalar<UInt8Type> {
0231 using NumericScalar<UInt8Type>::NumericScalar;
0232 };
0233
0234 struct ARROW_EXPORT UInt16Scalar : public NumericScalar<UInt16Type> {
0235 using NumericScalar<UInt16Type>::NumericScalar;
0236 };
0237
0238 struct ARROW_EXPORT UInt32Scalar : public NumericScalar<UInt32Type> {
0239 using NumericScalar<UInt32Type>::NumericScalar;
0240 };
0241
0242 struct ARROW_EXPORT UInt64Scalar : public NumericScalar<UInt64Type> {
0243 using NumericScalar<UInt64Type>::NumericScalar;
0244 };
0245
0246 struct ARROW_EXPORT HalfFloatScalar : public NumericScalar<HalfFloatType> {
0247 using NumericScalar<HalfFloatType>::NumericScalar;
0248 };
0249
0250 struct ARROW_EXPORT FloatScalar : public NumericScalar<FloatType> {
0251 using NumericScalar<FloatType>::NumericScalar;
0252 };
0253
0254 struct ARROW_EXPORT DoubleScalar : public NumericScalar<DoubleType> {
0255 using NumericScalar<DoubleType>::NumericScalar;
0256 };
0257
0258 struct ARROW_EXPORT BaseBinaryScalar : public internal::PrimitiveScalarBase {
0259 using ValueType = std::shared_ptr<Buffer>;
0260
0261
0262
0263
0264
0265 const std::shared_ptr<Buffer> value = NULLPTR;
0266
0267 const void* data() const override {
0268 return value ? reinterpret_cast<const void*>(value->data()) : NULLPTR;
0269 }
0270 std::string_view view() const override {
0271 return value ? std::string_view(*value) : std::string_view();
0272 }
0273
0274 explicit BaseBinaryScalar(std::shared_ptr<DataType> type)
0275 : internal::PrimitiveScalarBase(std::move(type)) {}
0276
0277 BaseBinaryScalar(std::shared_ptr<Buffer> value, std::shared_ptr<DataType> type)
0278 : internal::PrimitiveScalarBase{std::move(type), true}, value(std::move(value)) {}
0279
0280 BaseBinaryScalar(std::string s, std::shared_ptr<DataType> type);
0281 };
0282
0283 struct ARROW_EXPORT BinaryScalar
0284 : public BaseBinaryScalar,
0285 private internal::ArraySpanFillFromScalarScratchSpace<BinaryScalar> {
0286 using TypeClass = BinaryType;
0287 using ArraySpanFillFromScalarScratchSpace =
0288 internal::ArraySpanFillFromScalarScratchSpace<BinaryScalar>;
0289
0290 explicit BinaryScalar(std::shared_ptr<DataType> type)
0291 : BaseBinaryScalar(std::move(type)),
0292 ArraySpanFillFromScalarScratchSpace(this->value) {}
0293
0294 BinaryScalar(std::shared_ptr<Buffer> value, std::shared_ptr<DataType> type)
0295 : BaseBinaryScalar(std::move(value), std::move(type)),
0296 ArraySpanFillFromScalarScratchSpace(this->value) {}
0297
0298 BinaryScalar(std::string s, std::shared_ptr<DataType> type)
0299 : BaseBinaryScalar(std::move(s), std::move(type)),
0300 ArraySpanFillFromScalarScratchSpace(this->value) {}
0301
0302 explicit BinaryScalar(std::shared_ptr<Buffer> value)
0303 : BinaryScalar(std::move(value), binary()) {}
0304
0305 explicit BinaryScalar(std::string s) : BinaryScalar(std::move(s), binary()) {}
0306
0307 BinaryScalar() : BinaryScalar(binary()) {}
0308
0309 private:
0310 static void FillScratchSpace(uint8_t* scratch_space,
0311 const std::shared_ptr<Buffer>& value);
0312
0313 friend ArraySpan;
0314 friend ArraySpanFillFromScalarScratchSpace;
0315 };
0316
0317 struct ARROW_EXPORT StringScalar : public BinaryScalar {
0318 using BinaryScalar::BinaryScalar;
0319 using TypeClass = StringType;
0320
0321 explicit StringScalar(std::shared_ptr<Buffer> value)
0322 : StringScalar(std::move(value), utf8()) {}
0323
0324 explicit StringScalar(std::string s) : BinaryScalar(std::move(s), utf8()) {}
0325
0326 StringScalar() : StringScalar(utf8()) {}
0327 };
0328
0329 struct ARROW_EXPORT BinaryViewScalar
0330 : public BaseBinaryScalar,
0331 private internal::ArraySpanFillFromScalarScratchSpace<BinaryViewScalar> {
0332 using TypeClass = BinaryViewType;
0333 using ArraySpanFillFromScalarScratchSpace =
0334 internal::ArraySpanFillFromScalarScratchSpace<BinaryViewScalar>;
0335
0336 explicit BinaryViewScalar(std::shared_ptr<DataType> type)
0337 : BaseBinaryScalar(std::move(type)),
0338 ArraySpanFillFromScalarScratchSpace(this->value) {}
0339
0340 BinaryViewScalar(std::shared_ptr<Buffer> value, std::shared_ptr<DataType> type)
0341 : BaseBinaryScalar(std::move(value), std::move(type)),
0342 ArraySpanFillFromScalarScratchSpace(this->value) {}
0343
0344 BinaryViewScalar(std::string s, std::shared_ptr<DataType> type)
0345 : BaseBinaryScalar(std::move(s), std::move(type)),
0346 ArraySpanFillFromScalarScratchSpace(this->value) {}
0347
0348 explicit BinaryViewScalar(std::shared_ptr<Buffer> value)
0349 : BinaryViewScalar(std::move(value), binary_view()) {}
0350
0351 explicit BinaryViewScalar(std::string s)
0352 : BinaryViewScalar(std::move(s), binary_view()) {}
0353
0354 BinaryViewScalar() : BinaryViewScalar(binary_view()) {}
0355
0356 std::string_view view() const override { return std::string_view(*this->value); }
0357
0358 private:
0359 static void FillScratchSpace(uint8_t* scratch_space,
0360 const std::shared_ptr<Buffer>& value);
0361
0362 friend ArraySpan;
0363 friend ArraySpanFillFromScalarScratchSpace;
0364 };
0365
0366 struct ARROW_EXPORT StringViewScalar : public BinaryViewScalar {
0367 using BinaryViewScalar::BinaryViewScalar;
0368 using TypeClass = StringViewType;
0369
0370 explicit StringViewScalar(std::shared_ptr<Buffer> value)
0371 : StringViewScalar(std::move(value), utf8_view()) {}
0372
0373 explicit StringViewScalar(std::string s)
0374 : BinaryViewScalar(std::move(s), utf8_view()) {}
0375
0376 StringViewScalar() : StringViewScalar(utf8_view()) {}
0377 };
0378
0379 struct ARROW_EXPORT LargeBinaryScalar
0380 : public BaseBinaryScalar,
0381 private internal::ArraySpanFillFromScalarScratchSpace<LargeBinaryScalar> {
0382 using TypeClass = LargeBinaryType;
0383 using ArraySpanFillFromScalarScratchSpace =
0384 internal::ArraySpanFillFromScalarScratchSpace<LargeBinaryScalar>;
0385
0386 explicit LargeBinaryScalar(std::shared_ptr<DataType> type)
0387 : BaseBinaryScalar(std::move(type)),
0388 ArraySpanFillFromScalarScratchSpace(this->value) {}
0389
0390 LargeBinaryScalar(std::shared_ptr<Buffer> value, std::shared_ptr<DataType> type)
0391 : BaseBinaryScalar(std::move(value), std::move(type)),
0392 ArraySpanFillFromScalarScratchSpace(this->value) {}
0393
0394 LargeBinaryScalar(std::string s, std::shared_ptr<DataType> type)
0395 : BaseBinaryScalar(std::move(s), std::move(type)),
0396 ArraySpanFillFromScalarScratchSpace(this->value) {}
0397
0398 explicit LargeBinaryScalar(std::shared_ptr<Buffer> value)
0399 : LargeBinaryScalar(std::move(value), large_binary()) {}
0400
0401 explicit LargeBinaryScalar(std::string s)
0402 : LargeBinaryScalar(std::move(s), large_binary()) {}
0403
0404 LargeBinaryScalar() : LargeBinaryScalar(large_binary()) {}
0405
0406 private:
0407 static void FillScratchSpace(uint8_t* scratch_space,
0408 const std::shared_ptr<Buffer>& value);
0409
0410 friend ArraySpan;
0411 friend ArraySpanFillFromScalarScratchSpace;
0412 };
0413
0414 struct ARROW_EXPORT LargeStringScalar : public LargeBinaryScalar {
0415 using LargeBinaryScalar::LargeBinaryScalar;
0416 using TypeClass = LargeStringType;
0417
0418 explicit LargeStringScalar(std::shared_ptr<Buffer> value)
0419 : LargeStringScalar(std::move(value), large_utf8()) {}
0420
0421 explicit LargeStringScalar(std::string s)
0422 : LargeBinaryScalar(std::move(s), large_utf8()) {}
0423
0424 LargeStringScalar() : LargeStringScalar(large_utf8()) {}
0425 };
0426
0427 struct ARROW_EXPORT FixedSizeBinaryScalar : public BinaryScalar {
0428 using TypeClass = FixedSizeBinaryType;
0429
0430 FixedSizeBinaryScalar(std::shared_ptr<Buffer> value, std::shared_ptr<DataType> type,
0431 bool is_valid = true);
0432
0433 explicit FixedSizeBinaryScalar(const std::shared_ptr<Buffer>& value,
0434 bool is_valid = true);
0435
0436 explicit FixedSizeBinaryScalar(std::string s, bool is_valid = true);
0437 };
0438
0439 template <typename T>
0440 struct TemporalScalar : internal::PrimitiveScalar<T> {
0441 using internal::PrimitiveScalar<T>::PrimitiveScalar;
0442 using ValueType = typename internal::PrimitiveScalar<T>::ValueType;
0443
0444 TemporalScalar(ValueType value, std::shared_ptr<DataType> type)
0445 : internal::PrimitiveScalar<T>(std::move(value), type) {}
0446 };
0447
0448 template <typename T>
0449 struct DateScalar : public TemporalScalar<T> {
0450 using TemporalScalar<T>::TemporalScalar;
0451 using ValueType = typename TemporalScalar<T>::ValueType;
0452
0453 explicit DateScalar(ValueType value)
0454 : TemporalScalar<T>(std::move(value), TypeTraits<T>::type_singleton()) {}
0455 DateScalar() : TemporalScalar<T>(TypeTraits<T>::type_singleton()) {}
0456 };
0457
0458 struct ARROW_EXPORT Date32Scalar : public DateScalar<Date32Type> {
0459 using DateScalar<Date32Type>::DateScalar;
0460 };
0461
0462 struct ARROW_EXPORT Date64Scalar : public DateScalar<Date64Type> {
0463 using DateScalar<Date64Type>::DateScalar;
0464 };
0465
0466 template <typename T>
0467 struct TimeScalar : public TemporalScalar<T> {
0468 using TemporalScalar<T>::TemporalScalar;
0469
0470 TimeScalar(typename TemporalScalar<T>::ValueType value, TimeUnit::type unit)
0471 : TimeScalar(std::move(value), std::make_shared<T>(unit)) {}
0472 };
0473
0474 struct ARROW_EXPORT Time32Scalar : public TimeScalar<Time32Type> {
0475 using TimeScalar<Time32Type>::TimeScalar;
0476 };
0477
0478 struct ARROW_EXPORT Time64Scalar : public TimeScalar<Time64Type> {
0479 using TimeScalar<Time64Type>::TimeScalar;
0480 };
0481
0482 struct ARROW_EXPORT TimestampScalar : public TemporalScalar<TimestampType> {
0483 using TemporalScalar<TimestampType>::TemporalScalar;
0484
0485 TimestampScalar(typename TemporalScalar<TimestampType>::ValueType value,
0486 TimeUnit::type unit, std::string tz = "")
0487 : TimestampScalar(std::move(value), timestamp(unit, std::move(tz))) {}
0488
0489 static Result<TimestampScalar> FromISO8601(std::string_view iso8601,
0490 TimeUnit::type unit);
0491 };
0492
0493 template <typename T>
0494 struct IntervalScalar : public TemporalScalar<T> {
0495 using TemporalScalar<T>::TemporalScalar;
0496 using ValueType = typename TemporalScalar<T>::ValueType;
0497
0498 explicit IntervalScalar(ValueType value)
0499 : TemporalScalar<T>(value, TypeTraits<T>::type_singleton()) {}
0500 IntervalScalar() : TemporalScalar<T>(TypeTraits<T>::type_singleton()) {}
0501 };
0502
0503 struct ARROW_EXPORT MonthIntervalScalar : public IntervalScalar<MonthIntervalType> {
0504 using IntervalScalar<MonthIntervalType>::IntervalScalar;
0505 };
0506
0507 struct ARROW_EXPORT DayTimeIntervalScalar : public IntervalScalar<DayTimeIntervalType> {
0508 using IntervalScalar<DayTimeIntervalType>::IntervalScalar;
0509 };
0510
0511 struct ARROW_EXPORT MonthDayNanoIntervalScalar
0512 : public IntervalScalar<MonthDayNanoIntervalType> {
0513 using IntervalScalar<MonthDayNanoIntervalType>::IntervalScalar;
0514 };
0515
0516 struct ARROW_EXPORT DurationScalar : public TemporalScalar<DurationType> {
0517 using TemporalScalar<DurationType>::TemporalScalar;
0518
0519 DurationScalar(typename TemporalScalar<DurationType>::ValueType value,
0520 TimeUnit::type unit)
0521 : DurationScalar(std::move(value), duration(unit)) {}
0522
0523
0524 template <template <typename, typename> class StdDuration, typename Rep>
0525 explicit DurationScalar(StdDuration<Rep, std::nano> d)
0526 : DurationScalar{DurationScalar(d.count(), duration(TimeUnit::NANO))} {}
0527
0528
0529 template <template <typename, typename> class StdDuration, typename Rep>
0530 explicit DurationScalar(StdDuration<Rep, std::micro> d)
0531 : DurationScalar{DurationScalar(d.count(), duration(TimeUnit::MICRO))} {}
0532
0533
0534 template <template <typename, typename> class StdDuration, typename Rep>
0535 explicit DurationScalar(StdDuration<Rep, std::milli> d)
0536 : DurationScalar{DurationScalar(d.count(), duration(TimeUnit::MILLI))} {}
0537
0538
0539
0540 template <template <typename, typename> class StdDuration, typename Rep, intmax_t Num>
0541 explicit DurationScalar(StdDuration<Rep, std::ratio<Num, 1>> d)
0542 : DurationScalar{DurationScalar(d.count() * Num, duration(TimeUnit::SECOND))} {}
0543 };
0544
0545 template <typename TYPE_CLASS, typename VALUE_TYPE>
0546 struct DecimalScalar : public internal::PrimitiveScalarBase {
0547 using internal::PrimitiveScalarBase::PrimitiveScalarBase;
0548 using TypeClass = TYPE_CLASS;
0549 using ValueType = VALUE_TYPE;
0550
0551 DecimalScalar(ValueType value, std::shared_ptr<DataType> type)
0552 : internal::PrimitiveScalarBase(std::move(type), true), value(value) {}
0553
0554 const void* data() const override {
0555 return reinterpret_cast<const void*>(value.native_endian_bytes());
0556 }
0557
0558 std::string_view view() const override {
0559 return std::string_view(reinterpret_cast<const char*>(value.native_endian_bytes()),
0560 ValueType::kByteWidth);
0561 }
0562
0563 ValueType value;
0564 };
0565
0566 struct ARROW_EXPORT Decimal32Scalar : public DecimalScalar<Decimal32Type, Decimal32> {
0567 using DecimalScalar::DecimalScalar;
0568 };
0569
0570 struct ARROW_EXPORT Decimal64Scalar : public DecimalScalar<Decimal64Type, Decimal64> {
0571 using DecimalScalar::DecimalScalar;
0572 };
0573
0574 struct ARROW_EXPORT Decimal128Scalar : public DecimalScalar<Decimal128Type, Decimal128> {
0575 using DecimalScalar::DecimalScalar;
0576 };
0577
0578 struct ARROW_EXPORT Decimal256Scalar : public DecimalScalar<Decimal256Type, Decimal256> {
0579 using DecimalScalar::DecimalScalar;
0580 };
0581
0582 struct ARROW_EXPORT BaseListScalar : public Scalar {
0583 using ValueType = std::shared_ptr<Array>;
0584
0585 BaseListScalar(std::shared_ptr<Array> value, std::shared_ptr<DataType> type,
0586 bool is_valid = true);
0587
0588
0589
0590
0591
0592 const std::shared_ptr<Array> value;
0593 };
0594
0595 struct ARROW_EXPORT ListScalar
0596 : public BaseListScalar,
0597 private internal::ArraySpanFillFromScalarScratchSpace<ListScalar> {
0598 using TypeClass = ListType;
0599 using ArraySpanFillFromScalarScratchSpace =
0600 internal::ArraySpanFillFromScalarScratchSpace<ListScalar>;
0601
0602 ListScalar(std::shared_ptr<Array> value, std::shared_ptr<DataType> type,
0603 bool is_valid = true)
0604 : BaseListScalar(std::move(value), std::move(type), is_valid),
0605 ArraySpanFillFromScalarScratchSpace(this->value) {}
0606
0607 explicit ListScalar(std::shared_ptr<Array> value, bool is_valid = true);
0608
0609 private:
0610 static void FillScratchSpace(uint8_t* scratch_space,
0611 const std::shared_ptr<Array>& value);
0612
0613 friend ArraySpan;
0614 friend ArraySpanFillFromScalarScratchSpace;
0615 };
0616
0617 struct ARROW_EXPORT LargeListScalar
0618 : public BaseListScalar,
0619 private internal::ArraySpanFillFromScalarScratchSpace<LargeListScalar> {
0620 using TypeClass = LargeListType;
0621 using ArraySpanFillFromScalarScratchSpace =
0622 internal::ArraySpanFillFromScalarScratchSpace<LargeListScalar>;
0623
0624 LargeListScalar(std::shared_ptr<Array> value, std::shared_ptr<DataType> type,
0625 bool is_valid = true)
0626 : BaseListScalar(std::move(value), std::move(type), is_valid),
0627 ArraySpanFillFromScalarScratchSpace(this->value) {}
0628
0629 explicit LargeListScalar(std::shared_ptr<Array> value, bool is_valid = true);
0630
0631 private:
0632 static void FillScratchSpace(uint8_t* scratch_space,
0633 const std::shared_ptr<Array>& value);
0634
0635 friend ArraySpan;
0636 friend ArraySpanFillFromScalarScratchSpace;
0637 };
0638
0639 struct ARROW_EXPORT ListViewScalar
0640 : public BaseListScalar,
0641 private internal::ArraySpanFillFromScalarScratchSpace<ListViewScalar> {
0642 using TypeClass = ListViewType;
0643 using ArraySpanFillFromScalarScratchSpace =
0644 internal::ArraySpanFillFromScalarScratchSpace<ListViewScalar>;
0645
0646 ListViewScalar(std::shared_ptr<Array> value, std::shared_ptr<DataType> type,
0647 bool is_valid = true)
0648 : BaseListScalar(std::move(value), std::move(type), is_valid),
0649 ArraySpanFillFromScalarScratchSpace(this->value) {}
0650
0651 explicit ListViewScalar(std::shared_ptr<Array> value, bool is_valid = true);
0652
0653 private:
0654 static void FillScratchSpace(uint8_t* scratch_space,
0655 const std::shared_ptr<Array>& value);
0656
0657 friend ArraySpan;
0658 friend ArraySpanFillFromScalarScratchSpace;
0659 };
0660
0661 struct ARROW_EXPORT LargeListViewScalar
0662 : public BaseListScalar,
0663 private internal::ArraySpanFillFromScalarScratchSpace<LargeListViewScalar> {
0664 using TypeClass = LargeListViewType;
0665 using ArraySpanFillFromScalarScratchSpace =
0666 internal::ArraySpanFillFromScalarScratchSpace<LargeListViewScalar>;
0667
0668 LargeListViewScalar(std::shared_ptr<Array> value, std::shared_ptr<DataType> type,
0669 bool is_valid = true)
0670 : BaseListScalar(std::move(value), std::move(type), is_valid),
0671 ArraySpanFillFromScalarScratchSpace(this->value) {}
0672
0673 explicit LargeListViewScalar(std::shared_ptr<Array> value, bool is_valid = true);
0674
0675 private:
0676 static void FillScratchSpace(uint8_t* scratch_space,
0677 const std::shared_ptr<Array>& value);
0678
0679 friend ArraySpan;
0680 friend ArraySpanFillFromScalarScratchSpace;
0681 };
0682
0683 struct ARROW_EXPORT MapScalar
0684 : public BaseListScalar,
0685 private internal::ArraySpanFillFromScalarScratchSpace<MapScalar> {
0686 using TypeClass = MapType;
0687 using ArraySpanFillFromScalarScratchSpace =
0688 internal::ArraySpanFillFromScalarScratchSpace<MapScalar>;
0689
0690 MapScalar(std::shared_ptr<Array> value, std::shared_ptr<DataType> type,
0691 bool is_valid = true)
0692 : BaseListScalar(std::move(value), std::move(type), is_valid),
0693 ArraySpanFillFromScalarScratchSpace(this->value) {}
0694
0695 explicit MapScalar(std::shared_ptr<Array> value, bool is_valid = true);
0696
0697 private:
0698 static void FillScratchSpace(uint8_t* scratch_space,
0699 const std::shared_ptr<Array>& value);
0700
0701 friend ArraySpan;
0702 friend ArraySpanFillFromScalarScratchSpace;
0703 };
0704
0705 struct ARROW_EXPORT FixedSizeListScalar : public BaseListScalar {
0706 using TypeClass = FixedSizeListType;
0707
0708 FixedSizeListScalar(std::shared_ptr<Array> value, std::shared_ptr<DataType> type,
0709 bool is_valid = true);
0710
0711 explicit FixedSizeListScalar(std::shared_ptr<Array> value, bool is_valid = true);
0712 };
0713
0714 struct ARROW_EXPORT StructScalar : public Scalar {
0715 using TypeClass = StructType;
0716 using ValueType = std::vector<std::shared_ptr<Scalar>>;
0717
0718 ScalarVector value;
0719
0720 Result<std::shared_ptr<Scalar>> field(FieldRef ref) const;
0721
0722 StructScalar(ValueType value, std::shared_ptr<DataType> type, bool is_valid = true)
0723 : Scalar(std::move(type), is_valid), value(std::move(value)) {}
0724
0725 static Result<std::shared_ptr<StructScalar>> Make(ValueType value,
0726 std::vector<std::string> field_names);
0727 };
0728
0729 struct ARROW_EXPORT UnionScalar : public Scalar {
0730
0731
0732 const int8_t type_code;
0733
0734 virtual const std::shared_ptr<Scalar>& child_value() const = 0;
0735
0736 protected:
0737 UnionScalar(std::shared_ptr<DataType> type, int8_t type_code, bool is_valid)
0738 : Scalar(std::move(type), is_valid), type_code(type_code) {}
0739
0740 struct UnionScratchSpace {
0741 alignas(int64_t) int8_t type_code;
0742 alignas(int64_t) uint8_t offsets[sizeof(int32_t) * 2];
0743 };
0744 static_assert(sizeof(UnionScratchSpace) <= internal::kScalarScratchSpaceSize);
0745
0746 friend ArraySpan;
0747 };
0748
0749 struct ARROW_EXPORT SparseUnionScalar
0750 : public UnionScalar,
0751 private internal::ArraySpanFillFromScalarScratchSpace<SparseUnionScalar> {
0752 using TypeClass = SparseUnionType;
0753 using ArraySpanFillFromScalarScratchSpace =
0754 internal::ArraySpanFillFromScalarScratchSpace<SparseUnionScalar>;
0755
0756
0757
0758
0759 using ValueType = std::vector<std::shared_ptr<Scalar>>;
0760
0761
0762
0763
0764 const ValueType value;
0765
0766
0767 int child_id;
0768
0769 SparseUnionScalar(ValueType value, int8_t type_code, std::shared_ptr<DataType> type);
0770
0771 const std::shared_ptr<Scalar>& child_value() const override {
0772 return this->value[this->child_id];
0773 }
0774
0775
0776
0777 static std::shared_ptr<Scalar> FromValue(std::shared_ptr<Scalar> value, int field_index,
0778 std::shared_ptr<DataType> type);
0779
0780 private:
0781 static void FillScratchSpace(uint8_t* scratch_space, int8_t type_code);
0782
0783 friend ArraySpan;
0784 friend ArraySpanFillFromScalarScratchSpace;
0785 };
0786
0787 struct ARROW_EXPORT DenseUnionScalar
0788 : public UnionScalar,
0789 private internal::ArraySpanFillFromScalarScratchSpace<DenseUnionScalar> {
0790 using TypeClass = DenseUnionType;
0791 using ArraySpanFillFromScalarScratchSpace =
0792 internal::ArraySpanFillFromScalarScratchSpace<DenseUnionScalar>;
0793
0794
0795
0796 using ValueType = std::shared_ptr<Scalar>;
0797
0798
0799
0800
0801 const ValueType value;
0802
0803 const std::shared_ptr<Scalar>& child_value() const override { return this->value; }
0804
0805 DenseUnionScalar(ValueType value, int8_t type_code, std::shared_ptr<DataType> type)
0806 : UnionScalar(std::move(type), type_code, value->is_valid),
0807 ArraySpanFillFromScalarScratchSpace(type_code),
0808 value(std::move(value)) {}
0809
0810 private:
0811 static void FillScratchSpace(uint8_t* scratch_space, int8_t type_code);
0812
0813 friend ArraySpan;
0814 friend ArraySpanFillFromScalarScratchSpace;
0815 };
0816
0817 struct ARROW_EXPORT RunEndEncodedScalar
0818 : public Scalar,
0819 private internal::ArraySpanFillFromScalarScratchSpace<RunEndEncodedScalar> {
0820 using TypeClass = RunEndEncodedType;
0821 using ValueType = std::shared_ptr<Scalar>;
0822 using ArraySpanFillFromScalarScratchSpace =
0823 internal::ArraySpanFillFromScalarScratchSpace<RunEndEncodedScalar>;
0824
0825
0826
0827
0828
0829 const ValueType value;
0830
0831 RunEndEncodedScalar(std::shared_ptr<Scalar> value, std::shared_ptr<DataType> type);
0832
0833
0834 explicit RunEndEncodedScalar(const std::shared_ptr<DataType>& type);
0835
0836 ~RunEndEncodedScalar() override;
0837
0838 const std::shared_ptr<DataType>& run_end_type() const {
0839 return ree_type().run_end_type();
0840 }
0841
0842 const std::shared_ptr<DataType>& value_type() const { return ree_type().value_type(); }
0843
0844 private:
0845 const TypeClass& ree_type() const { return internal::checked_cast<TypeClass&>(*type); }
0846
0847 static void FillScratchSpace(uint8_t* scratch_space, const DataType& type);
0848
0849 friend ArraySpan;
0850 friend ArraySpanFillFromScalarScratchSpace;
0851 };
0852
0853
0854
0855
0856
0857 struct ARROW_EXPORT DictionaryScalar : public internal::PrimitiveScalarBase {
0858 using TypeClass = DictionaryType;
0859 struct ValueType {
0860 std::shared_ptr<Scalar> index;
0861 std::shared_ptr<Array> dictionary;
0862 } value;
0863
0864 explicit DictionaryScalar(std::shared_ptr<DataType> type);
0865
0866 DictionaryScalar(ValueType value, std::shared_ptr<DataType> type, bool is_valid = true)
0867 : internal::PrimitiveScalarBase(std::move(type), is_valid),
0868 value(std::move(value)) {}
0869
0870 static std::shared_ptr<DictionaryScalar> Make(std::shared_ptr<Scalar> index,
0871 std::shared_ptr<Array> dict);
0872
0873 Result<std::shared_ptr<Scalar>> GetEncodedValue() const;
0874
0875 const void* data() const override {
0876 return internal::checked_cast<internal::PrimitiveScalarBase&>(*value.index).data();
0877 }
0878 std::string_view view() const override {
0879 return internal::checked_cast<const internal::PrimitiveScalarBase&>(*value.index)
0880 .view();
0881 }
0882 };
0883
0884
0885
0886
0887
0888 struct ARROW_EXPORT ExtensionScalar : public Scalar {
0889 using TypeClass = ExtensionType;
0890 using ValueType = std::shared_ptr<Scalar>;
0891
0892 ExtensionScalar(std::shared_ptr<Scalar> storage, std::shared_ptr<DataType> type,
0893 bool is_valid = true)
0894 : Scalar(std::move(type), is_valid), value(std::move(storage)) {}
0895
0896 template <typename Storage,
0897 typename = enable_if_t<std::is_base_of<Scalar, Storage>::value>>
0898 ExtensionScalar(Storage&& storage, std::shared_ptr<DataType> type, bool is_valid = true)
0899 : ExtensionScalar(std::make_shared<Storage>(std::move(storage)), std::move(type),
0900 is_valid) {}
0901
0902 std::shared_ptr<Scalar> value;
0903 };
0904
0905
0906
0907 namespace internal {
0908
0909 inline Status CheckBufferLength(...) { return Status::OK(); }
0910
0911 ARROW_EXPORT Status CheckBufferLength(const FixedSizeBinaryType* t,
0912 const std::shared_ptr<Buffer>* b);
0913
0914 }
0915
0916 template <typename ValueRef>
0917 struct MakeScalarImpl;
0918
0919
0920
0921
0922
0923
0924 ARROW_EXPORT
0925 std::shared_ptr<Scalar> MakeNullScalar(std::shared_ptr<DataType> type);
0926
0927
0928 template <typename Value>
0929 Result<std::shared_ptr<Scalar>> MakeScalar(std::shared_ptr<DataType> type,
0930 Value&& value) {
0931 return MakeScalarImpl<Value&&>{type, std::forward<Value>(value), NULLPTR}.Finish();
0932 }
0933
0934
0935
0936
0937
0938
0939 template <typename Value, typename Traits = CTypeTraits<typename std::decay<Value>::type>,
0940 typename ScalarType = typename Traits::ScalarType,
0941 typename Enable = decltype(ScalarType(std::declval<Value>(),
0942 Traits::type_singleton()))>
0943 std::shared_ptr<Scalar> MakeScalar(Value value) {
0944 return std::make_shared<ScalarType>(std::move(value), Traits::type_singleton());
0945 }
0946
0947 inline std::shared_ptr<Scalar> MakeScalar(std::string value) {
0948 return std::make_shared<StringScalar>(std::move(value));
0949 }
0950
0951 inline std::shared_ptr<Scalar> MakeScalar(const std::shared_ptr<Scalar>& scalar) {
0952 return scalar;
0953 }
0954
0955
0956 template <typename ValueRef>
0957 struct MakeScalarImpl {
0958 template <typename T, typename ScalarType = typename TypeTraits<T>::ScalarType,
0959 typename ValueType = typename ScalarType::ValueType,
0960 typename Enable = typename std::enable_if<
0961 std::is_constructible<ScalarType, ValueType,
0962 std::shared_ptr<DataType>>::value &&
0963 std::is_convertible<ValueRef, ValueType>::value>::type>
0964 Status Visit(const T& t) {
0965 ARROW_RETURN_NOT_OK(internal::CheckBufferLength(&t, &value_));
0966
0967 out_ = std::make_shared<ScalarType>(
0968 static_cast<ValueType>(static_cast<ValueRef>(value_)), std::move(type_));
0969 return Status::OK();
0970 }
0971
0972 Status Visit(const ExtensionType& t) {
0973 ARROW_ASSIGN_OR_RAISE(auto storage,
0974 MakeScalar(t.storage_type(), static_cast<ValueRef>(value_)));
0975 out_ = std::make_shared<ExtensionScalar>(std::move(storage), type_);
0976 return Status::OK();
0977 }
0978
0979
0980 template <typename T>
0981 enable_if_t<
0982 std::is_same<typename std::remove_reference<ValueRef>::type, std::string>::value &&
0983 (is_base_binary_type<T>::value || std::is_same<T, FixedSizeBinaryType>::value),
0984 Status>
0985 Visit(const T& t) {
0986 using ScalarType = typename TypeTraits<T>::ScalarType;
0987 out_ = std::make_shared<ScalarType>(Buffer::FromString(std::move(value_)),
0988 std::move(type_));
0989 return Status::OK();
0990 }
0991
0992 Status Visit(const DataType& t) {
0993 return Status::NotImplemented("constructing scalars of type ", t,
0994 " from unboxed values");
0995 }
0996
0997 Result<std::shared_ptr<Scalar>> Finish() && {
0998 ARROW_RETURN_NOT_OK(VisitTypeInline(*type_, this));
0999 return std::move(out_);
1000 }
1001
1002 std::shared_ptr<DataType> type_;
1003 ValueRef value_;
1004 std::shared_ptr<Scalar> out_;
1005 };
1006
1007 }