summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrobot-piglet <[email protected]>2025-01-09 20:55:43 +0300
committerrobot-piglet <[email protected]>2025-01-09 21:09:19 +0300
commit667707fa06732f2943922d08ef77a2c9a52cbd47 (patch)
tree87eb9978b23ed47f105c5efba3a91cc35330be3a
parent7740c9ef0cd954624d51f1fc8c8ff4426edcc9ab (diff)
Intermediate changes
commit_hash:c97917e5fe0a2f094b8f7a50cf183357e8d07096
-rw-r--r--contrib/libs/libunwind/.yandex_meta/__init__.py2
-rw-r--r--library/cpp/protobuf/yql/descriptor.cpp22
-rw-r--r--library/cpp/protobuf/yql/descriptor.h5
-rw-r--r--yql/essentials/udfs/common/protobuf/test/canondata/result.json5
-rw-r--r--yql/essentials/udfs/common/protobuf/test/canondata/test.test_YQL-19040_/results.txt28
-rw-r--r--yql/essentials/udfs/common/protobuf/test/cases/YQL-19040.sql62
6 files changed, 121 insertions, 3 deletions
diff --git a/contrib/libs/libunwind/.yandex_meta/__init__.py b/contrib/libs/libunwind/.yandex_meta/__init__.py
index d1a5b082d63..803baf46fbd 100644
--- a/contrib/libs/libunwind/.yandex_meta/__init__.py
+++ b/contrib/libs/libunwind/.yandex_meta/__init__.py
@@ -9,7 +9,7 @@ def post_install(self):
libunwind.NO_RUNTIME = True
libunwind.NO_SANITIZE = True
libunwind.NO_SANITIZE_COVERAGE = True
- # original build uses -f options heavily, keep only necessary subset
+ # original build uses -f options heavily, keep only necessary subset
libunwind.CFLAGS += ["-fno-exceptions", "-fno-rtti", "-funwind-tables"]
libunwind.after("CFLAGS", Switch({"SANITIZER_TYPE == memory": "CFLAGS(-fPIC)"}))
libunwind.PEERDIR.add("library/cpp/sanitizer/include")
diff --git a/library/cpp/protobuf/yql/descriptor.cpp b/library/cpp/protobuf/yql/descriptor.cpp
index 2d5a154fc17..e5e1c8e28bd 100644
--- a/library/cpp/protobuf/yql/descriptor.cpp
+++ b/library/cpp/protobuf/yql/descriptor.cpp
@@ -19,6 +19,7 @@
#include <google/protobuf/text_format.h>
#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
+#include <google/protobuf/io/coded_stream.h>
using namespace NProtoBuf;
@@ -73,6 +74,7 @@ TDynamicInfoRef TDynamicInfo::Create(const TStringBuf& typeConfig) {
info->SkipBytes_ = data.SkipBytes;
info->OptionalLists_ = data.OptionalLists;
info->SyntaxAware_ = data.SyntaxAware;
+ info->Deterministic_ = data.Deterministic;
return info;
}
@@ -146,7 +148,16 @@ TString TDynamicInfo::Serialize(const Message& proto) {
switch (ProtoFormat_) {
case PF_PROTOBIN: {
result.ReserveAndResize(proto.ByteSize());
- if (!proto.SerializeToArray(result.begin(), result.size())) {
+ bool success = false;
+ if (Deterministic_) {
+ io::ArrayOutputStream arrOut(result.begin(), result.size());
+ io::CodedOutputStream codedOut(&arrOut);
+ codedOut.SetSerializationDeterministic(true);
+ success = proto.SerializeToCodedStream(&codedOut);
+ } else {
+ success = proto.SerializeToArray(result.begin(), result.size());
+ }
+ if (!success) {
ythrow yexception() << "can't serialize protobin message";
}
break;
@@ -159,7 +170,9 @@ TString TDynamicInfo::Serialize(const Message& proto) {
}
case PF_JSON: {
NJson::TJsonValue value;
- NProtobufJson::Proto2Json(proto, value);
+ NProtobufJson::TProto2JsonConfig config;
+ config.SetSortMapKeys(Deterministic_);
+ NProtobufJson::Proto2Json(proto, value, config);
result = NJson::WriteJson(value);
break;
}
@@ -225,6 +238,10 @@ TString GenerateProtobufTypeConfig(
ret["view"]["yt_mode"] = true;
}
+ if (options.Deterministic) {
+ ret["view"]["deterministic"] = true;
+ }
+
return NJson::WriteJson(ret, false);
}
@@ -268,6 +285,7 @@ TProtoTypeConfig ParseTypeConfig(const TStringBuf& config) {
result.OptionalLists = value["lists"]["optional"].GetBooleanSafe(true);
result.SyntaxAware = value["syntax"]["aware"].GetBooleanSafe(false);
result.YtMode = value["view"]["yt_mode"].GetBooleanSafe(false);
+ result.Deterministic = value["view"]["deterministic"].GetBooleanSafe(false);
if (protoFormat == "protobin") {
result.ProtoFormat = PF_PROTOBIN;
diff --git a/library/cpp/protobuf/yql/descriptor.h b/library/cpp/protobuf/yql/descriptor.h
index bbed6850ec1..f5f51add0bc 100644
--- a/library/cpp/protobuf/yql/descriptor.h
+++ b/library/cpp/protobuf/yql/descriptor.h
@@ -50,6 +50,8 @@ struct TProtoTypeConfig {
bool OptionalLists = false;
//! Заполнять ли пустые Optional типы дефолтным значением (только для proto3).
bool SyntaxAware = false;
+ //! Использовать ли детерминированную сериализацию
+ bool Deterministic = false;
};
struct TProtoTypeConfigOptions {
@@ -69,6 +71,8 @@ struct TProtoTypeConfigOptions {
bool OptionalLists = false;
//! Заполнять ли пустые Optional типы дефолтным значением (только для proto3).
bool SyntaxAware = false;
+ //! Использовать ли детерминированную сериализацию
+ bool Deterministic = false;
TProtoTypeConfigOptions& SetProtoFormat(EProtoFormat value) {
ProtoFormat = value;
@@ -158,4 +162,5 @@ private:
ui32 SkipBytes_;
bool OptionalLists_;
bool SyntaxAware_;
+ bool Deterministic_;
};
diff --git a/yql/essentials/udfs/common/protobuf/test/canondata/result.json b/yql/essentials/udfs/common/protobuf/test/canondata/result.json
index ac534cee58f..be8251f2ae0 100644
--- a/yql/essentials/udfs/common/protobuf/test/canondata/result.json
+++ b/yql/essentials/udfs/common/protobuf/test/canondata/result.json
@@ -13,6 +13,11 @@
"uri": "https://storage.yandex-team.ru/get-devtools/1781765/c2a453956382e0fdfc958f3c4e32ed7740f03d4b/resource.tar.gz#test.test_YQL-16111_/results.txt"
}
],
+ "test.test[YQL-19040]": [
+ {
+ "uri": "file://test.test_YQL-19040_/results.txt"
+ }
+ ],
"test.test[YQL-3381]": [
{
"checksum": "c098af301d5dc8d85071a47455f0f592",
diff --git a/yql/essentials/udfs/common/protobuf/test/canondata/test.test_YQL-19040_/results.txt b/yql/essentials/udfs/common/protobuf/test/canondata/test.test_YQL-19040_/results.txt
new file mode 100644
index 00000000000..67f6ba046e3
--- /dev/null
+++ b/yql/essentials/udfs/common/protobuf/test/canondata/test.test_YQL-19040_/results.txt
@@ -0,0 +1,28 @@
+[
+ {
+ "Write" = [
+ {
+ "Type" = [
+ "ListType";
+ [
+ "StructType";
+ [
+ [
+ "column0";
+ [
+ "DataType";
+ "String"
+ ]
+ ]
+ ]
+ ]
+ ];
+ "Data" = [
+ [
+ "Success"
+ ]
+ ]
+ }
+ ]
+ }
+] \ No newline at end of file
diff --git a/yql/essentials/udfs/common/protobuf/test/cases/YQL-19040.sql b/yql/essentials/udfs/common/protobuf/test/cases/YQL-19040.sql
new file mode 100644
index 00000000000..895929c06c9
--- /dev/null
+++ b/yql/essentials/udfs/common/protobuf/test/cases/YQL-19040.sql
@@ -0,0 +1,62 @@
+/*
+syntax='proto3';
+
+import "yt/yt_proto/yt/formats/extension.proto";
+
+message Test {
+ option (NYT.default_field_flags) = SERIALIZATION_YT;
+
+ message Inner {
+ string a = 1;
+ }
+ map<string, Inner> dict1 = 1 [(NYT.flags) = MAP_AS_DICT];
+ map<string, Inner> dict2 = 2 [(NYT.flags) = MAP_AS_OPTIONAL_DICT];
+ map<string, Inner> dict3 = 3 [(NYT.flags) = MAP_AS_LIST_OF_STRUCTS_LEGACY];
+ map<string, Inner> dict4 = 4 [(NYT.flags) = MAP_AS_LIST_OF_STRUCTS];
+ map<string, string> dict5 = 5 [(NYT.flags) = MAP_AS_DICT];
+ map<string, string> dict6 = 6 [(NYT.flags) = MAP_AS_OPTIONAL_DICT];
+ map<string, string> dict7 = 7 [(NYT.flags) = MAP_AS_LIST_OF_STRUCTS_LEGACY];
+ map<string, string> dict8 = 8 [(NYT.flags) = MAP_AS_LIST_OF_STRUCTS];
+}
+*/
+
+$config_json = @@{
+ "name": "Test",
+ "format": "json",
+ "skip": 0,
+ "lists": {
+ "optional": false
+ },
+ "meta": "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",
+ "view": {
+ "recursion": "bytes",
+ "enum": "number",
+ "yt_mode": true,
+ "deterministic": true
+ }
+}
+@@;
+
+$config_bin = @@{
+ "name": "Test",
+ "skip": 0,
+ "lists": {
+ "optional": false
+ },
+ "meta": "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",
+ "view": {
+ "recursion": "bytes",
+ "enum": "number",
+ "yt_mode": true,
+ "deterministic": true
+ }
+}
+@@;
+
+$dat = "{\"dict1\":[{\"key\":\"k1\",\"value\":{\"a\":\"1\"}},{\"key\":\"k2\",\"value\":{\"a\":\"0\"}}],\"dict2\":[{\"key\":\"k2\",\"value\":{\"a\":\"2\"}}],\"dict3\":[{\"key\":\"k3\",\"value\":{\"a\":\"3\"}}],\"dict4\":[{\"key\":\"k4\",\"value\":{\"a\":\"4\"}}],\"dict5\":[{\"key\":\"k5\",\"value\":\"v5\"}],\"dict6\":[{\"key\":\"k6\",\"value\":\"v6\"}],\"dict7\":[{\"key\":\"k7\",\"value\":\"v7\"}],\"dict8\":[{\"key\":\"k8\",\"value\":\"v8\"}]}";
+
+$udfParseJson = Udf(Protobuf::Parse, $config_json as TypeConfig);
+$udfParseBin = Udf(Protobuf::Parse, $config_bin as TypeConfig);
+$udfSerializeBin = Udf(Protobuf::Serialize, $config_bin as TypeConfig);
+
+SELECT Ensure("Success", $udfParseJson($dat) == $udfParseBin($udfSerializeBin($udfParseJson($dat))), "Fail"); \ No newline at end of file