Skip to content

Commit ee6b1e3

Browse files
committed
convert large integers to double
1 parent 3b3e4b4 commit ee6b1e3

File tree

3 files changed

+68
-27
lines changed

3 files changed

+68
-27
lines changed

ydb/library/binary_json/ut_benchmark/ya.make

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@ SRCS(
1818
PEERDIR(
1919
library/cpp/testing/unittest
2020
ydb/library/binary_json
21+
ydb/library/yql/minikql/dom
22+
ydb/library/yql/minikql/invoke_builtins/llvm14
2123
ydb/library/yql/public/udf/service/exception_policy
24+
ydb/library/yql/core/issue/protos
25+
ydb/library/yql/sql/pg_dummy
2226
)
2327

2428
YQL_LAST_ABI_VERSION()

ydb/library/binary_json/write.cpp

Lines changed: 18 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -548,10 +548,9 @@ void DomToJsonIndex(const NUdf::TUnboxedValue& value, TBinaryJsonCallbacks& call
548548
}
549549
}
550550

551-
// unused, left for performance comparison
552551
template <typename TOnDemandValue>
553552
requires std::is_same_v<TOnDemandValue, simdjson::ondemand::value> || std::is_same_v<TOnDemandValue, simdjson::ondemand::document>
554-
[[maybe_unused]] [[nodiscard]] simdjson::error_code SimdJsonToJsonIndexImpl(TOnDemandValue& value, TBinaryJsonCallbacks& callbacks) {
553+
[[nodiscard]] simdjson::error_code SimdJsonToJsonIndex(TOnDemandValue& value, TBinaryJsonCallbacks& callbacks) {
555554
#define RETURN_IF_NOT_SUCCESS(error) \
556555
if (Y_UNLIKELY(error != simdjson::SUCCESS)) { \
557556
return error; \
@@ -591,7 +590,10 @@ template <typename TOnDemandValue>
591590
break;
592591
}
593592
case simdjson::fallback::number_type::big_integer:
594-
return simdjson::NUMBER_OUT_OF_RANGE;
593+
double v;
594+
RETURN_IF_NOT_SUCCESS(value.get(v));
595+
callbacks.OnDouble(v);
596+
break;
595597
}
596598
break;
597599
}
@@ -605,7 +607,7 @@ template <typename TOnDemandValue>
605607
RETURN_IF_NOT_SUCCESS(value.get(v));
606608
for (auto item : v) {
607609
RETURN_IF_NOT_SUCCESS(item.error());
608-
RETURN_IF_NOT_SUCCESS(SimdJsonToJsonIndexImpl(item.value_unsafe(), callbacks));
610+
RETURN_IF_NOT_SUCCESS(SimdJsonToJsonIndex(item.value_unsafe(), callbacks));
609611
}
610612

611613
callbacks.OnCloseArray();
@@ -622,7 +624,7 @@ template <typename TOnDemandValue>
622624
const auto key = keyValue.unescaped_key();
623625
RETURN_IF_NOT_SUCCESS(key.error());
624626
callbacks.OnMapKey(key.value_unsafe());
625-
RETURN_IF_NOT_SUCCESS(SimdJsonToJsonIndexImpl(keyValue.value(), callbacks));
627+
RETURN_IF_NOT_SUCCESS(SimdJsonToJsonIndex(keyValue.value(), callbacks));
626628
}
627629

628630
callbacks.OnCloseMap();
@@ -635,7 +637,8 @@ template <typename TOnDemandValue>
635637
#undef RETURN_IF_NOT_SUCCESS
636638
}
637639

638-
[[nodiscard]] simdjson::error_code SimdJsonToJsonIndex(const simdjson::dom::element& value, TBinaryJsonCallbacks& callbacks) {
640+
// unused, left for performance comparison
641+
[[maybe_unused]] [[nodiscard]] simdjson::error_code SimdJsonToJsonIndexImpl(const simdjson::dom::element& value, TBinaryJsonCallbacks& callbacks) {
639642
#define RETURN_IF_NOT_SUCCESS(status) \
640643
if (Y_UNLIKELY(status != simdjson::SUCCESS)) { \
641644
return status; \
@@ -681,7 +684,7 @@ template <typename TOnDemandValue>
681684
simdjson::dom::array v;
682685
RETURN_IF_NOT_SUCCESS(value.get(v));
683686
for (const auto& item : v) {
684-
RETURN_IF_NOT_SUCCESS(SimdJsonToJsonIndex(item, callbacks));
687+
RETURN_IF_NOT_SUCCESS(SimdJsonToJsonIndexImpl(item, callbacks));
685688
}
686689

687690
callbacks.OnCloseArray();
@@ -694,7 +697,7 @@ template <typename TOnDemandValue>
694697
RETURN_IF_NOT_SUCCESS(value.get(v));
695698
for (const auto& item : v) {
696699
callbacks.OnMapKey(item.key);
697-
RETURN_IF_NOT_SUCCESS(SimdJsonToJsonIndex(item.value, callbacks));
700+
RETURN_IF_NOT_SUCCESS(SimdJsonToJsonIndexImpl(item.value, callbacks));
698701
}
699702

700703
callbacks.OnCloseMap();
@@ -706,28 +709,17 @@ template <typename TOnDemandValue>
706709
}
707710
}
708711

709-
TMaybe<TBinaryJson> SerializeToBinaryJsonImplRapidjson(const TStringBuf json) {
710-
TMemoryInput input(json.data(), json.size());
711-
TBinaryJsonCallbacks callbacks(/* throwException */ false);
712-
if (!ReadJson(&input, &callbacks)) {
713-
return Nothing();
714-
}
715-
TBinaryJsonSerializer serializer(std::move(callbacks).GetResult());
716-
return std::move(serializer).Serialize();
717-
}
718-
719712
TMaybe<TBinaryJson> SerializeToBinaryJsonImpl(const TStringBuf json) {
720-
thread_local simdjson::dom::parser parser;
721-
auto doc = parser.parse(json);
713+
thread_local simdjson::ondemand::parser parser;
714+
const simdjson::padded_string paddedJson(json);
715+
auto doc = parser.iterate(paddedJson);
722716
if (doc.error() != simdjson::SUCCESS) {
723-
if (doc.error() == simdjson::BIGINT_ERROR) {
724-
return SerializeToBinaryJsonImplRapidjson(json);
725-
}
726-
return Nothing();
717+
Y_ABORT_IF(doc.error() == simdjson::BIGINT_ERROR);
718+
return false;
727719
}
728720
TBinaryJsonCallbacks callbacks(/* throwException */ false);
729-
if (SimdJsonToJsonIndex(doc.value(), callbacks) != simdjson::SUCCESS) {
730-
return Nothing();
721+
if (SimdJsonToJsonIndex(doc.value_unsafe(), callbacks) != simdjson::SUCCESS) {
722+
return false;
731723
}
732724
TBinaryJsonSerializer serializer(std::move(callbacks).GetResult());
733725
return std::move(serializer).Serialize();

ydb/library/yql/minikql/jsonpath/ut/common_ut.cpp

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,52 @@ class TJsonPathCommonTest : public TJsonPathTestBase {
339339
"array": [1, 2, 3, 4]
340340
})", "$.array[+$.range.from to +$.range.to]", {"2", "3"}},
341341
{R"([1, 2, 3])", "-$[*]", {"-1", "-2", "-3"}},
342-
{"10000000000000000000000000", "-$", {"-9.999999999999999e+24"}},
342+
{"30000000000000000000000000", "-$", {"-3e+25"}},
343+
};
344+
345+
for (const auto& testCase : testCases) {
346+
for (const auto mode : ALL_MODES) {
347+
RunTestCase(testCase.Json, mode + testCase.JsonPath, testCase.Result);
348+
}
349+
}
350+
}
351+
352+
void TestBigint() {
353+
const TVector<TMultiOutputTestCase> testCases = {
354+
{R"([])", "-3", {"-3"}},
355+
{R"([])", "+3", {"3"}},
356+
{R"(-1)", "-$", {"1"}},
357+
{R"(-1)", "+$", {"-1"}},
358+
{R"({
359+
"range": {
360+
"from": -1,
361+
"to": -2
362+
},
363+
"array": [1, 2, 3, 4]
364+
})", "$.array[-$.range.from to -$.range.to]", {"2", "3"}},
365+
{R"({
366+
"range": {
367+
"from": 1,
368+
"to": -2
369+
},
370+
"array": [1, 2, 3, 4]
371+
})", "$.array[+$.range.from to -$.range.to]", {"2", "3"}},
372+
{R"({
373+
"range": {
374+
"from": -1,
375+
"to": 2
376+
},
377+
"array": [1, 2, 3, 4]
378+
})", "$.array[-$.range.from to +$.range.to]", {"2", "3"}},
379+
{R"({
380+
"range": {
381+
"from": 1,
382+
"to": 2
383+
},
384+
"array": [1, 2, 3, 4]
385+
})", "$.array[+$.range.from to +$.range.to]", {"2", "3"}},
386+
{R"([1, 2, 3])", "-$[*]", {"-1", "-2", "-3"}},
387+
{"100000000000000000000000000", "-$", {"-1e+26"}},
343388
};
344389

345390
for (const auto& testCase : testCases) {

0 commit comments

Comments
 (0)