@@ -40,6 +40,28 @@ void ThrowOnError(const arrow::Status& status)
40
40
}
41
41
}
42
42
43
+ template <class TUnderlyingValueType >
44
+ TStringBuf SerializeDecimalBinary (const TStringBuf& value, int precision, char * buffer, size_t bufferLength)
45
+ {
46
+ // NB: Arrow wire representation of Decimal128 is little-endian and (obviously) 128 bit,
47
+ // while YT in-memory representation of Decimal is big-endian, variadic-length of either 32 bit, 64 bit or 128 bit,
48
+ // and MSB-flipped to ensure lexical sorting order.
49
+ // Representation of Decimal256 is similar, but the upper limit for a length is 256 bit.
50
+ TUnderlyingValueType decimalValue;
51
+ YT_VERIFY (value.size () == sizeof (decimalValue));
52
+ std::memcpy (&decimalValue, value.data (), value.size ());
53
+
54
+ TStringBuf decimalBinary;
55
+ if constexpr (std::is_same_v<TUnderlyingValueType, TDecimal::TValue128>) {
56
+ decimalBinary = TDecimal::WriteBinary128Variadic (precision, decimalValue, buffer, bufferLength);
57
+ } else if constexpr (std::is_same_v<TUnderlyingValueType, TDecimal::TValue256>) {
58
+ decimalBinary = TDecimal::WriteBinary256Variadic (precision, decimalValue, buffer, bufferLength);
59
+ } else {
60
+ static_assert (std::is_same_v<TUnderlyingValueType, TDecimal::TValue256>, " Unexpected decimal type" );
61
+ }
62
+ return decimalBinary;
63
+ }
64
+
43
65
// //////////////////////////////////////////////////////////////////////////////
44
66
45
67
class TArraySimpleVisitor
@@ -291,28 +313,12 @@ class TArraySimpleVisitor
291
313
}
292
314
293
315
template <class TUnderlyingValueType >
294
- TUnversionedValue MakeDecimalBinaryValue (const TStringBuf& value , i64 columnId, int precision)
316
+ TUnversionedValue MakeDecimalBinaryValue (const TStringBuf& arrowValue , i64 columnId, int precision)
295
317
{
296
- // NB: Arrow wire representation of Decimal128 is little-endian and (obviously) 128 bit,
297
- // while YT in-memory representation of Decimal is big-endian, variadic-length of either 32 bit, 64 bit or 128 bit,
298
- // and MSB-flipped to ensure lexical sorting order.
299
- // Representation of Decimal256 is similar, but only 256 bits.
300
- TUnderlyingValueType decimalValue;
301
- YT_VERIFY (value.size () == sizeof (decimalValue));
302
- std::memcpy (&decimalValue, value.data (), value.size ());
303
-
304
- const auto maxByteCount = sizeof (decimalValue);
318
+ const auto maxByteCount = sizeof (TUnderlyingValueType);
305
319
char * buffer = BufferForStringLikeValues_->Preallocate (maxByteCount);
306
- TStringBuf decimalBinary;
307
- if constexpr (std::is_same_v<TUnderlyingValueType, TDecimal::TValue128>) {
308
- decimalBinary = TDecimal::WriteBinary128Variadic (precision, decimalValue, buffer, maxByteCount);
309
- } else if constexpr (std::is_same_v<TUnderlyingValueType, TDecimal::TValue256>) {
310
- decimalBinary = TDecimal::WriteBinary256 (precision, decimalValue, buffer, maxByteCount);
311
- } else {
312
- static_assert (std::is_same_v<TUnderlyingValueType, TDecimal::TValue256>, " Unexpected decimal type" );
313
- }
320
+ auto decimalBinary = SerializeDecimalBinary<TUnderlyingValueType>(arrowValue, precision, buffer, maxByteCount);
314
321
BufferForStringLikeValues_->Advance (decimalBinary.size ());
315
-
316
322
return MakeUnversionedStringValue (decimalBinary, columnId);
317
323
}
318
324
};
@@ -456,6 +462,20 @@ class TArrayCompositeVisitor
456
462
return ParseStruct ();
457
463
}
458
464
465
+ arrow::Status Visit (const arrow::Decimal128Type& type) override
466
+ {
467
+ return ParseStringLikeArray<arrow::Decimal128Array>([&] (const TStringBuf& value) {
468
+ WriteDecimalBinary<TDecimal::TValue128>(value, type.precision ());
469
+ });
470
+ }
471
+
472
+ arrow::Status Visit (const arrow::Decimal256Type& type) override
473
+ {
474
+ return ParseStringLikeArray<arrow::Decimal256Array>([&] (const TStringBuf& value) {
475
+ WriteDecimalBinary<TDecimal::TValue256>(value, type.precision ());
476
+ });
477
+ }
478
+
459
479
private:
460
480
const int RowIndex_;
461
481
@@ -505,13 +525,21 @@ class TArrayCompositeVisitor
505
525
506
526
template <typename ArrayType>
507
527
arrow::Status ParseStringLikeArray ()
528
+ {
529
+ return ParseStringLikeArray<ArrayType>([&] (const TStringBuf& value) {
530
+ Writer_->WriteBinaryString (value);
531
+ });
532
+ }
533
+
534
+ template <typename ArrayType>
535
+ arrow::Status ParseStringLikeArray (auto writeStringValue)
508
536
{
509
537
auto array = std::static_pointer_cast<ArrayType>(Array_);
510
538
if (array->IsNull (RowIndex_)) {
511
539
Writer_->WriteEntity ();
512
540
} else {
513
541
auto element = array->GetView (RowIndex_);
514
- Writer_-> WriteBinaryString (TStringBuf (element.data (), element.size ()));
542
+ writeStringValue (TStringBuf (element.data (), element.size ()));
515
543
}
516
544
return arrow::Status::OK ();
517
545
}
@@ -610,6 +638,15 @@ class TArrayCompositeVisitor
610
638
}
611
639
return arrow::Status::OK ();
612
640
}
641
+
642
+ template <class TUnderlyingType >
643
+ void WriteDecimalBinary (TStringBuf arrowValue, int precision)
644
+ {
645
+ const auto maxByteCount = sizeof (TUnderlyingType);
646
+ char buffer[maxByteCount];
647
+ auto decimalBinary = SerializeDecimalBinary<TUnderlyingType>(arrowValue, precision, buffer, maxByteCount);
648
+ Writer_->WriteBinaryString (decimalBinary);
649
+ }
613
650
};
614
651
615
652
// //////////////////////////////////////////////////////////////////////////////
0 commit comments