Skip to content

Commit a04d89b

Browse files
author
kinash-varvara
authored
add WriteNanAsString option in Yson::SerializeJson (#1871)
1 parent b92e8dc commit a04d89b

File tree

7 files changed

+105
-4
lines changed

7 files changed

+105
-4
lines changed

ydb/library/yql/minikql/dom/json.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -323,10 +323,13 @@ TUnboxedValue TryParseJsonDom(const TStringBuf json, const IValueBuilder* valueB
323323
}
324324
}
325325

326-
TString SerializeJsonDom(const NUdf::TUnboxedValuePod dom, bool skipMapEntity, bool encodeUtf8) {
326+
TString SerializeJsonDom(const NUdf::TUnboxedValuePod dom, bool skipMapEntity, bool encodeUtf8, bool writeNanAsString) {
327327
TStringStream output;
328328
TJsonWriterConfig config;
329+
329330
config.SetFormatOutput(false);
331+
config.WriteNanAsString = writeNanAsString;
332+
330333
config.FloatToStringMode = EFloatToStringMode::PREC_AUTO;
331334
TJsonWriter writer(&output, config);
332335
if (skipMapEntity)

ydb/library/yql/minikql/dom/json.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,6 @@ bool IsValidJson(const TStringBuf json);
99

1010
NUdf::TUnboxedValue TryParseJsonDom(const TStringBuf json, const NUdf::IValueBuilder* valueBuilder, bool decodeUtf8 = false);
1111

12-
TString SerializeJsonDom(const NUdf::TUnboxedValuePod dom, bool skipMapEntity = false, bool encodeUtf8 = false);
12+
TString SerializeJsonDom(const NUdf::TUnboxedValuePod dom, bool skipMapEntity = false, bool encodeUtf8 = false, bool writeNanAsString = false);
1313

1414
}

ydb/library/yql/minikql/dom/ut/yson_ut.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#include <ydb/library/yql/minikql/dom/yson.h>
22

3+
#include <ydb/library/yql/minikql/dom/json.h>
4+
35
#include <library/cpp/testing/unittest/registar.h>
46
#include <ydb/library/yql/minikql/mkql_alloc.h>
57
#include <ydb/library/yql/minikql/computation/mkql_computation_node_holders.h>
@@ -2059,4 +2061,27 @@ Y_UNIT_TEST_SUITE(TYsonTests) {
20592061
const auto time = TInstant::Now() - t;
20602062
Cerr << "Time is " << time << Endl;
20612063
}
2064+
2065+
Y_UNIT_TEST(TestSerializeJsonNanInf) {
2066+
NMiniKQL::TScopedAlloc alloc(__LOCATION__);
2067+
NMiniKQL::TMemoryUsageInfo memInfo("Memory");
2068+
NMiniKQL::THolderFactory holderFactory(alloc.Ref(), memInfo, nullptr);
2069+
NMiniKQL::TDefaultValueBuilder builder(holderFactory);
2070+
2071+
constexpr char yson[] =
2072+
R"(
2073+
{
2074+
"Nan" = %nan;
2075+
"Inf" = %inf;
2076+
"NegInf" = %-inf
2077+
}
2078+
)";
2079+
2080+
TString expected(R"({"Inf":"inf","Nan":"nan","NegInf":"-inf"})");
2081+
2082+
const auto dom = TryParseYsonDom(yson, &builder);
2083+
TString res = SerializeJsonDom(dom, false, true, true);
2084+
2085+
UNIT_ASSERT_EQUAL(expected, res);
2086+
}
20622087
}

ydb/library/yql/udfs/common/yson2/test/canondata/result.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,11 @@
114114
"uri": "file://test.test_JsonWithUtf8_/results.txt"
115115
}
116116
],
117+
"test.test[JsonWithNanAsString]": [
118+
{
119+
"uri": "file://test.test_JsonWithNanAsString_/results.txt"
120+
}
121+
],
117122
"test.test[Lists]": [
118123
{
119124
"uri": "file://test.test_Lists_/results.txt"
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
[
2+
{
3+
"Write" = [
4+
{
5+
"Type" = [
6+
"ListType";
7+
[
8+
"StructType";
9+
[
10+
[
11+
"column0";
12+
[
13+
"OptionalType";
14+
[
15+
"DataType";
16+
"Json"
17+
]
18+
]
19+
];
20+
[
21+
"column1";
22+
[
23+
"OptionalType";
24+
[
25+
"DataType";
26+
"Json"
27+
]
28+
]
29+
];
30+
[
31+
"column2";
32+
[
33+
"OptionalType";
34+
[
35+
"DataType";
36+
"Json"
37+
]
38+
]
39+
]
40+
]
41+
]
42+
];
43+
"Data" = [
44+
[
45+
[
46+
"\"nan\""
47+
];
48+
[
49+
"\"inf\""
50+
];
51+
[
52+
"\"-inf\""
53+
]
54+
]
55+
]
56+
}
57+
]
58+
}
59+
]
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
$src = Yson::From(0./0.); -- nan
2+
$src1 = Yson::From(1./0.); -- inf
3+
$src2 = Yson::From(-1./0.); -- -inf
4+
5+
SELECT
6+
Yson::SerializeJson($src, true AS WriteNanAsString),
7+
Yson::SerializeJson($src1, true AS WriteNanAsString),
8+
Yson::SerializeJson($src2, true AS WriteNanAsString)

ydb/library/yql/udfs/common/yson2/yson2_udf.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -670,9 +670,10 @@ SIMPLE_STRICT_UDF(TSerializePretty, TYson(TAutoMap<TNodeResource>)) {
670670

671671
constexpr char SkipMapEntity[] = "SkipMapEntity";
672672
constexpr char EncodeUtf8[] = "EncodeUtf8";
673+
constexpr char WriteNanAsString[] = "WriteNanAsString";
673674

674-
SIMPLE_UDF_WITH_OPTIONAL_ARGS(TSerializeJson, TOptional<TJson>(TAutoMap<TNodeResource>, TOptional<TOptionsResource>, TNamedArg<bool, SkipMapEntity>, TNamedArg<bool, EncodeUtf8>), 3) try {
675-
return valueBuilder->NewString(SerializeJsonDom(args[0], args[2].GetOrDefault(false), args[3].GetOrDefault(false)));
675+
SIMPLE_UDF_WITH_OPTIONAL_ARGS(TSerializeJson, TOptional<TJson>(TAutoMap<TNodeResource>, TOptional<TOptionsResource>, TNamedArg<bool, SkipMapEntity>, TNamedArg<bool, EncodeUtf8>, TNamedArg<bool, WriteNanAsString>), 4) try {
676+
return valueBuilder->NewString(SerializeJsonDom(args[0], args[2].GetOrDefault(false), args[3].GetOrDefault(false), args[4].GetOrDefault(false)));
676677
} catch (const std::exception& e) {
677678
if (ParseOptions(args[1]).Strict) {
678679
UdfTerminate((::TStringBuilder() << valueBuilder->WithCalleePosition(GetPos()) << " " << e.what()).data());

0 commit comments

Comments
 (0)