ClickHouse
641 строка · 18.4 Кб
1#include <IO/ReadBuffer.h>
2#include <IO/WriteBuffer.h>
3#include <IO/ReadHelpers.h>
4#include <IO/WriteHelpers.h>
5#include <IO/ReadBufferFromString.h>
6#include <IO/readDecimalText.h>
7#include <Core/Field.h>
8#include <Core/DecimalComparison.h>
9#include <Common/FieldVisitorDump.h>
10#include <Common/FieldVisitorToString.h>
11#include <Common/FieldVisitorWriteBinary.h>
12
13
14using namespace std::literals;
15
16namespace DB
17{
18
19namespace ErrorCodes
20{
21extern const int CANNOT_RESTORE_FROM_FIELD_DUMP;
22extern const int DECIMAL_OVERFLOW;
23}
24
25template <is_decimal T>
26T DecimalField<T>::getScaleMultiplier() const
27{
28return DecimalUtils::scaleMultiplier<T>(scale);
29}
30
31inline Field getBinaryValue(UInt8 type, ReadBuffer & buf)
32{
33switch (static_cast<Field::Types::Which>(type))
34{
35case Field::Types::Null:
36{
37return Field();
38}
39case Field::Types::UInt64:
40{
41UInt64 value;
42readVarUInt(value, buf);
43return value;
44}
45case Field::Types::UInt128:
46{
47UInt128 value;
48readBinary(value, buf);
49return value;
50}
51case Field::Types::UInt256:
52{
53UInt256 value;
54readBinary(value, buf);
55return value;
56}
57case Field::Types::UUID:
58{
59UUID value;
60readBinary(value, buf);
61return value;
62}
63case Field::Types::IPv4:
64{
65IPv4 value;
66readBinary(value, buf);
67return value;
68}
69case Field::Types::IPv6:
70{
71IPv6 value;
72readBinary(value.toUnderType(), buf);
73return value;
74}
75case Field::Types::Int64:
76{
77Int64 value;
78readVarInt(value, buf);
79return value;
80}
81case Field::Types::Int128:
82{
83Int128 value;
84readBinary(value, buf);
85return value;
86}
87case Field::Types::Int256:
88{
89Int256 value;
90readBinary(value, buf);
91return value;
92}
93case Field::Types::Float64:
94{
95Float64 value;
96readFloatBinary(value, buf);
97return value;
98}
99case Field::Types::String:
100{
101std::string value;
102readStringBinary(value, buf);
103return value;
104}
105case Field::Types::Array:
106{
107Array value;
108readBinary(value, buf);
109return value;
110}
111case Field::Types::Tuple:
112{
113Tuple value;
114readBinary(value, buf);
115return value;
116}
117case Field::Types::Map:
118{
119Map value;
120readBinary(value, buf);
121return value;
122}
123case Field::Types::Object:
124{
125Object value;
126readBinary(value, buf);
127return value;
128}
129case Field::Types::AggregateFunctionState:
130{
131AggregateFunctionStateData value;
132readStringBinary(value.name, buf);
133readStringBinary(value.data, buf);
134return value;
135}
136case Field::Types::Bool:
137{
138UInt8 value;
139readBinary(value, buf);
140return bool(value);
141}
142case Field::Types::Decimal32:
143case Field::Types::Decimal64:
144case Field::Types::Decimal128:
145case Field::Types::Decimal256:
146case Field::Types::CustomType:
147return Field();
148}
149UNREACHABLE();
150}
151
152void readBinary(Array & x, ReadBuffer & buf)
153{
154size_t size;
155UInt8 type;
156readBinary(type, buf);
157readBinary(size, buf);
158
159for (size_t index = 0; index < size; ++index)
160x.push_back(getBinaryValue(type, buf));
161}
162
163void writeBinary(const Array & x, WriteBuffer & buf)
164{
165UInt8 type = Field::Types::Null;
166size_t size = x.size();
167if (size)
168type = x.front().getType();
169writeBinary(type, buf);
170writeBinary(size, buf);
171
172for (const auto & elem : x)
173Field::dispatch([&buf] (const auto & value) { FieldVisitorWriteBinary()(value, buf); }, elem);
174}
175
176void writeText(const Array & x, WriteBuffer & buf)
177{
178String res = applyVisitor(FieldVisitorToString(), Field(x));
179buf.write(res.data(), res.size());
180}
181
182void readBinary(Tuple & x, ReadBuffer & buf)
183{
184size_t size;
185readBinary(size, buf);
186
187for (size_t index = 0; index < size; ++index)
188{
189UInt8 type;
190readBinary(type, buf);
191x.push_back(getBinaryValue(type, buf));
192}
193}
194
195void writeBinary(const Tuple & x, WriteBuffer & buf)
196{
197const size_t size = x.size();
198writeBinary(size, buf);
199
200for (const auto & elem : x)
201{
202const UInt8 type = elem.getType();
203writeBinary(type, buf);
204Field::dispatch([&buf] (const auto & value) { FieldVisitorWriteBinary()(value, buf); }, elem);
205}
206}
207
208void writeText(const Tuple & x, WriteBuffer & buf)
209{
210writeFieldText(Field(x), buf);
211}
212
213void readBinary(Map & x, ReadBuffer & buf)
214{
215size_t size;
216readBinary(size, buf);
217
218for (size_t index = 0; index < size; ++index)
219{
220UInt8 type;
221readBinary(type, buf);
222x.push_back(getBinaryValue(type, buf));
223}
224}
225
226void writeBinary(const Map & x, WriteBuffer & buf)
227{
228const size_t size = x.size();
229writeBinary(size, buf);
230
231for (const auto & elem : x)
232{
233const UInt8 type = elem.getType();
234writeBinary(type, buf);
235Field::dispatch([&buf] (const auto & value) { FieldVisitorWriteBinary()(value, buf); }, elem);
236}
237}
238
239void writeText(const Map & x, WriteBuffer & buf)
240{
241writeFieldText(Field(x), buf);
242}
243
244void readBinary(Object & x, ReadBuffer & buf)
245{
246size_t size;
247readBinary(size, buf);
248
249for (size_t index = 0; index < size; ++index)
250{
251UInt8 type;
252String key;
253readBinary(type, buf);
254readBinary(key, buf);
255x[key] = getBinaryValue(type, buf);
256}
257}
258
259void writeBinary(const Object & x, WriteBuffer & buf)
260{
261const size_t size = x.size();
262writeBinary(size, buf);
263
264for (const auto & [key, value] : x)
265{
266const UInt8 type = value.getType();
267writeBinary(type, buf);
268writeBinary(key, buf);
269Field::dispatch([&buf] (const auto & val) { FieldVisitorWriteBinary()(val, buf); }, value);
270}
271}
272
273void writeText(const Object & x, WriteBuffer & buf)
274{
275writeFieldText(Field(x), buf);
276}
277
278void writeBinary(const CustomType & x, WriteBuffer & buf)
279{
280writeBinary(std::string_view(x.getTypeName()), buf);
281writeBinary(x.toString(), buf);
282}
283
284void writeText(const CustomType & x, WriteBuffer & buf)
285{
286writeFieldText(Field(x), buf);
287}
288
289template <typename T>
290void readQuoted(DecimalField<T> & x, ReadBuffer & buf)
291{
292assertChar('\'', buf);
293T value;
294UInt32 scale;
295int32_t exponent;
296uint32_t max_digits = static_cast<uint32_t>(-1);
297readDigits<true>(buf, value, max_digits, exponent, true);
298if (exponent > 0)
299{
300scale = 0;
301if (common::mulOverflow(value.value, DecimalUtils::scaleMultiplier<T>(exponent), value.value))
302throw Exception(ErrorCodes::DECIMAL_OVERFLOW, "Decimal math overflow");
303}
304else
305scale = -exponent;
306assertChar('\'', buf);
307x = DecimalField<T>{value, scale};
308}
309
310template void readQuoted<Decimal32>(DecimalField<Decimal32> & x, ReadBuffer & buf);
311template void readQuoted<Decimal64>(DecimalField<Decimal64> & x, ReadBuffer & buf);
312template void readQuoted<Decimal128>(DecimalField<Decimal128> & x, ReadBuffer & buf);
313template void readQuoted<Decimal256>(DecimalField<Decimal256> & x, ReadBuffer & buf);
314
315void writeFieldText(const Field & x, WriteBuffer & buf)
316{
317String res = Field::dispatch(FieldVisitorToString(), x);
318buf.write(res.data(), res.size());
319}
320
321
322String Field::dump() const
323{
324return applyVisitor(FieldVisitorDump(), *this);
325}
326
327Field Field::restoreFromDump(std::string_view dump_)
328{
329auto show_error = [&dump_]
330{
331throw Exception(ErrorCodes::CANNOT_RESTORE_FROM_FIELD_DUMP, "Couldn't restore Field from dump: {}", String{dump_});
332};
333
334std::string_view dump = dump_;
335trim(dump);
336
337if (dump == "NULL")
338return {};
339
340std::string_view prefix = std::string_view{"Int64_"};
341if (dump.starts_with(prefix))
342{
343Int64 value = parseFromString<Int64>(dump.substr(prefix.length()));
344return value;
345}
346
347prefix = std::string_view{"UInt64_"};
348if (dump.starts_with(prefix))
349{
350UInt64 value = parseFromString<UInt64>(dump.substr(prefix.length()));
351return value;
352}
353
354prefix = std::string_view{"Int128_"};
355if (dump.starts_with(prefix))
356{
357Int128 value = parseFromString<Int128>(dump.substr(prefix.length()));
358return value;
359}
360
361prefix = std::string_view{"UInt128_"};
362if (dump.starts_with(prefix))
363{
364UInt128 value = parseFromString<UInt128>(dump.substr(prefix.length()));
365return value;
366}
367
368prefix = std::string_view{"Int256_"};
369if (dump.starts_with(prefix))
370{
371Int256 value = parseFromString<Int256>(dump.substr(prefix.length()));
372return value;
373}
374
375prefix = std::string_view{"UInt256_"};
376if (dump.starts_with(prefix))
377{
378UInt256 value = parseFromString<UInt256>(dump.substr(prefix.length()));
379return value;
380}
381
382prefix = std::string_view{"Float64_"};
383if (dump.starts_with(prefix))
384{
385Float64 value = parseFromString<Float64>(dump.substr(prefix.length()));
386return value;
387}
388
389prefix = std::string_view{"Decimal32_"};
390if (dump_.starts_with(prefix))
391{
392DecimalField<Decimal32> decimal;
393ReadBufferFromString buf{dump.substr(prefix.length())};
394readQuoted(decimal, buf);
395return decimal;
396}
397
398prefix = std::string_view{"Decimal64_"};
399if (dump_.starts_with(prefix))
400{
401DecimalField<Decimal64> decimal;
402ReadBufferFromString buf{dump.substr(prefix.length())};
403readQuoted(decimal, buf);
404return decimal;
405}
406
407prefix = std::string_view{"Decimal128_"};
408if (dump_.starts_with(prefix))
409{
410DecimalField<Decimal128> decimal;
411ReadBufferFromString buf{dump.substr(prefix.length())};
412readQuoted(decimal, buf);
413return decimal;
414}
415
416prefix = std::string_view{"Decimal256_"};
417if (dump_.starts_with(prefix))
418{
419DecimalField<Decimal256> decimal;
420ReadBufferFromString buf{dump.substr(prefix.length())};
421readQuoted(decimal, buf);
422return decimal;
423}
424
425if (dump.starts_with("\'"))
426{
427String str;
428ReadBufferFromString buf{dump};
429readQuoted(str, buf);
430return str;
431}
432
433prefix = std::string_view{"Bool_"};
434if (dump.starts_with(prefix))
435{
436bool value = parseFromString<bool>(dump.substr(prefix.length()));
437return value;
438}
439
440prefix = std::string_view{"Array_["};
441if (dump.starts_with(prefix))
442{
443std::string_view tail = dump.substr(prefix.length());
444trimLeft(tail);
445Array array;
446while (tail != "]")
447{
448size_t separator = tail.find_first_of(",]");
449if (separator == std::string_view::npos)
450show_error();
451bool comma = (tail[separator] == ',');
452std::string_view element = tail.substr(0, separator);
453tail.remove_prefix(separator);
454if (comma)
455tail.remove_prefix(1);
456trimLeft(tail);
457if (!comma && tail != "]")
458show_error();
459array.push_back(Field::restoreFromDump(element));
460}
461return array;
462}
463
464prefix = std::string_view{"Tuple_("};
465if (dump.starts_with(prefix))
466{
467std::string_view tail = dump.substr(prefix.length());
468trimLeft(tail);
469Tuple tuple;
470while (tail != ")")
471{
472size_t separator = tail.find_first_of(",)");
473if (separator == std::string_view::npos)
474show_error();
475bool comma = (tail[separator] == ',');
476std::string_view element = tail.substr(0, separator);
477tail.remove_prefix(separator);
478if (comma)
479tail.remove_prefix(1);
480trimLeft(tail);
481if (!comma && tail != ")")
482show_error();
483tuple.push_back(Field::restoreFromDump(element));
484}
485return tuple;
486}
487
488prefix = std::string_view{"Map_("};
489if (dump.starts_with(prefix))
490{
491std::string_view tail = dump.substr(prefix.length());
492trimLeft(tail);
493Map map;
494while (tail != ")")
495{
496size_t separator = tail.find_first_of(",)");
497if (separator == std::string_view::npos)
498show_error();
499bool comma = (tail[separator] == ',');
500std::string_view element = tail.substr(0, separator);
501tail.remove_prefix(separator);
502if (comma)
503tail.remove_prefix(1);
504trimLeft(tail);
505if (!comma && tail != ")")
506show_error();
507map.push_back(Field::restoreFromDump(element));
508}
509return map;
510}
511
512prefix = std::string_view{"AggregateFunctionState_("};
513if (dump.starts_with(prefix))
514{
515std::string_view after_prefix = dump.substr(prefix.length());
516size_t comma = after_prefix.find(',');
517size_t end = after_prefix.find(')', comma + 1);
518if ((comma == std::string_view::npos) || (end != after_prefix.length() - 1))
519show_error();
520std::string_view name_view = after_prefix.substr(0, comma);
521std::string_view data_view = after_prefix.substr(comma + 1, end - comma - 1);
522trim(name_view);
523trim(data_view);
524ReadBufferFromString name_buf{name_view};
525ReadBufferFromString data_buf{data_view};
526AggregateFunctionStateData res;
527readQuotedString(res.name, name_buf);
528readQuotedString(res.data, data_buf);
529return res;
530}
531
532show_error();
533UNREACHABLE();
534}
535
536
537template <typename T>
538bool decimalEqual(T x, T y, UInt32 x_scale, UInt32 y_scale)
539{
540using Comparator = DecimalComparison<T, T, EqualsOp>;
541return Comparator::compare(x, y, x_scale, y_scale);
542}
543
544template <typename T>
545bool decimalLess(T x, T y, UInt32 x_scale, UInt32 y_scale)
546{
547using Comparator = DecimalComparison<T, T, LessOp>;
548return Comparator::compare(x, y, x_scale, y_scale);
549}
550
551template <typename T>
552bool decimalLessOrEqual(T x, T y, UInt32 x_scale, UInt32 y_scale)
553{
554using Comparator = DecimalComparison<T, T, LessOrEqualsOp>;
555return Comparator::compare(x, y, x_scale, y_scale);
556}
557
558
559template bool decimalEqual<Decimal32>(Decimal32 x, Decimal32 y, UInt32 x_scale, UInt32 y_scale);
560template bool decimalEqual<Decimal64>(Decimal64 x, Decimal64 y, UInt32 x_scale, UInt32 y_scale);
561template bool decimalEqual<Decimal128>(Decimal128 x, Decimal128 y, UInt32 x_scale, UInt32 y_scale);
562template bool decimalEqual<Decimal256>(Decimal256 x, Decimal256 y, UInt32 x_scale, UInt32 y_scale);
563template bool decimalEqual<DateTime64>(DateTime64 x, DateTime64 y, UInt32 x_scale, UInt32 y_scale);
564
565template bool decimalLess<Decimal32>(Decimal32 x, Decimal32 y, UInt32 x_scale, UInt32 y_scale);
566template bool decimalLess<Decimal64>(Decimal64 x, Decimal64 y, UInt32 x_scale, UInt32 y_scale);
567template bool decimalLess<Decimal128>(Decimal128 x, Decimal128 y, UInt32 x_scale, UInt32 y_scale);
568template bool decimalLess<Decimal256>(Decimal256 x, Decimal256 y, UInt32 x_scale, UInt32 y_scale);
569template bool decimalLess<DateTime64>(DateTime64 x, DateTime64 y, UInt32 x_scale, UInt32 y_scale);
570
571template bool decimalLessOrEqual<Decimal32>(Decimal32 x, Decimal32 y, UInt32 x_scale, UInt32 y_scale);
572template bool decimalLessOrEqual<Decimal64>(Decimal64 x, Decimal64 y, UInt32 x_scale, UInt32 y_scale);
573template bool decimalLessOrEqual<Decimal128>(Decimal128 x, Decimal128 y, UInt32 x_scale, UInt32 y_scale);
574template bool decimalLessOrEqual<Decimal256>(Decimal256 x, Decimal256 y, UInt32 x_scale, UInt32 y_scale);
575template bool decimalLessOrEqual<DateTime64>(DateTime64 x, DateTime64 y, UInt32 x_scale, UInt32 y_scale);
576
577
578inline void writeText(const Null & x, WriteBuffer & buf)
579{
580if (x.isNegativeInfinity())
581writeText("-Inf", buf);
582if (x.isPositiveInfinity())
583writeText("+Inf", buf);
584else
585writeText("NULL", buf);
586}
587
588String toString(const Field & x)
589{
590return Field::dispatch(
591[] (const auto & value)
592{
593// Use explicit type to prevent implicit construction of Field and
594// infinite recursion into toString<Field>.
595return toString<decltype(value)>(value);
596},
597x);
598}
599
600std::string_view fieldTypeToString(Field::Types::Which type)
601{
602switch (type)
603{
604case Field::Types::Which::Null: return "Null"sv;
605case Field::Types::Which::Array: return "Array"sv;
606case Field::Types::Which::Tuple: return "Tuple"sv;
607case Field::Types::Which::Map: return "Map"sv;
608case Field::Types::Which::Object: return "Object"sv;
609case Field::Types::Which::AggregateFunctionState: return "AggregateFunctionState"sv;
610case Field::Types::Which::Bool: return "Bool"sv;
611case Field::Types::Which::String: return "String"sv;
612case Field::Types::Which::Decimal32: return "Decimal32"sv;
613case Field::Types::Which::Decimal64: return "Decimal64"sv;
614case Field::Types::Which::Decimal128: return "Decimal128"sv;
615case Field::Types::Which::Decimal256: return "Decimal256"sv;
616case Field::Types::Which::Float64: return "Float64"sv;
617case Field::Types::Which::Int64: return "Int64"sv;
618case Field::Types::Which::Int128: return "Int128"sv;
619case Field::Types::Which::Int256: return "Int256"sv;
620case Field::Types::Which::UInt64: return "UInt64"sv;
621case Field::Types::Which::UInt128: return "UInt128"sv;
622case Field::Types::Which::UInt256: return "UInt256"sv;
623case Field::Types::Which::UUID: return "UUID"sv;
624case Field::Types::Which::IPv4: return "IPv4"sv;
625case Field::Types::Which::IPv6: return "IPv6"sv;
626case Field::Types::Which::CustomType: return "CustomType"sv;
627}
628}
629
630/// Keep in mind, that "magic_enum" is very expensive for compiler, that's why we don't use it.
631std::string_view Field::getTypeName() const
632{
633return fieldTypeToString(which);
634}
635
636template class DecimalField<Decimal32>;
637template class DecimalField<Decimal64>;
638template class DecimalField<Decimal128>;
639template class DecimalField<Decimal256>;
640template class DecimalField<DateTime64>;
641}
642