aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSergey Uzhakov <uzhastik@gmail.com>2022-06-17 20:29:34 +0300
committerSergey Uzhakov <uzhastik@gmail.com>2022-06-17 20:29:34 +0300
commite3b5f78d6131cd2e85971d9147035145bcaeeb0c (patch)
treeb752cd2d1e9cc8fd26cb3d00df4d8bb78eb3d826
parent349bc75358426fc4245611743bf725010472028b (diff)
downloadydb-e3b5f78d6131cd2e85971d9147035145bcaeeb0c.tar.gz
YQ-1154: support NULL in TPgValue
ref:e8fd847c1f45774fe56b5cb5599e7673cfd8d021
-rw-r--r--ydb/core/yq/libs/result_formatter/result_formatter.cpp6
-rw-r--r--ydb/core/yq/libs/result_formatter/result_formatter_ut.cpp7
-rw-r--r--ydb/public/lib/json_value/ydb_json_value.cpp10
-rw-r--r--ydb/public/lib/json_value/ydb_json_value_ut.cpp16
-rw-r--r--ydb/public/lib/yson_value/ydb_yson_value.cpp4
-rw-r--r--ydb/public/sdk/cpp/client/ydb_value/value.cpp21
-rw-r--r--ydb/public/sdk/cpp/client/ydb_value/value.h11
-rw-r--r--ydb/public/sdk/cpp/client/ydb_value/value_ut.cpp38
8 files changed, 88 insertions, 25 deletions
diff --git a/ydb/core/yq/libs/result_formatter/result_formatter.cpp b/ydb/core/yq/libs/result_formatter/result_formatter.cpp
index 00f84cbd49..8e57a5ee75 100644
--- a/ydb/core/yq/libs/result_formatter/result_formatter.cpp
+++ b/ydb/core/yq/libs/result_formatter/result_formatter.cpp
@@ -340,10 +340,10 @@ void FormatColumnValue(
if (type->GetKind() == TType::EKind::Pg) {
NYdb::TValueParser parser(value);
auto pgValue = parser.GetPg();
- /*if (pgValue.IsNull()) {
- root = NJson::TJsonValue();
+ if (pgValue.IsNull()) {
+ root = NJson::TJsonValue(NJson::JSON_NULL);
return;
- }*/
+ }
if (pgValue.IsText()) {
root = NJson::TJsonValue(pgValue.Content_);
diff --git a/ydb/core/yq/libs/result_formatter/result_formatter_ut.cpp b/ydb/core/yq/libs/result_formatter/result_formatter_ut.cpp
index 8105aabd27..3b369ecbd3 100644
--- a/ydb/core/yq/libs/result_formatter/result_formatter_ut.cpp
+++ b/ydb/core/yq/libs/result_formatter/result_formatter_ut.cpp
@@ -377,6 +377,11 @@ Y_UNIT_TEST_SUITE(ResultFormatter) {
auto& cell = *value.add_items();
cell.set_text_value("");
}
+ // null
+ {
+ auto& value = *rs.add_rows();
+ value.add_items();
+ }
NJson::TJsonValue root;
FormatResultSet(root, rs);
@@ -384,7 +389,7 @@ Y_UNIT_TEST_SUITE(ResultFormatter) {
TStringStream stream;
NJson::WriteJson(&stream, &root);
//Cerr << "Stream >> " << stream.Str() << Endl;
- TString expected = R"___({"data":[{"column0":"my_text_value"},{"column0":""}],"columns":[{"name":"column0","type":["PgType","bool"]}]})___";
+ TString expected = R"___({"data":[{"column0":"my_text_value"},{"column0":""},{"column0":null}],"columns":[{"name":"column0","type":["PgType","bool"]}]})___";
UNIT_ASSERT_VALUES_EQUAL(stream.Str(), expected);
}
diff --git a/ydb/public/lib/json_value/ydb_json_value.cpp b/ydb/public/lib/json_value/ydb_json_value.cpp
index 7842e11dd3..172e345c0a 100644
--- a/ydb/public/lib/json_value/ydb_json_value.cpp
+++ b/ydb/public/lib/json_value/ydb_json_value.cpp
@@ -211,7 +211,9 @@ namespace NYdb {
break;
case TTypeParser::ETypeKind::Pg:
- if (Parser.GetPg().IsText()) {
+ if (Parser.GetPg().IsNull()) {
+ Writer.WriteNull();
+ } else if (Parser.GetPg().IsText()) {
Writer.WriteString(Parser.GetPg().Content_);
} else {
Writer.BeginList();
@@ -645,7 +647,9 @@ namespace {
case TTypeParser::ETypeKind::Pg: {
TPgType pgType(0, 0, 0);
if (jsonValue.GetType() == NJson::JSON_STRING) {
- ValueBuilder.Pg(TPgValue(true, jsonValue.GetString(), pgType));
+ ValueBuilder.Pg(TPgValue(TPgValue::VK_TEXT, jsonValue.GetString(), pgType));
+ } else if (jsonValue.GetType() == NJson::JSON_NULL) {
+ ValueBuilder.Pg(TPgValue(TPgValue::VK_NULL, {}, pgType));
} else {
EnsureType(jsonValue, NJson::JSON_ARRAY);
if (jsonValue.GetArray().size() != 1) {
@@ -654,7 +658,7 @@ namespace {
auto& innerJsonValue = jsonValue.GetArray().at(0);
EnsureType(innerJsonValue, NJson::JSON_STRING);
auto binary = JsonStringToBinaryString(innerJsonValue.GetString());
- ValueBuilder.Pg(TPgValue(false, binary, pgType));
+ ValueBuilder.Pg(TPgValue(TPgValue::VK_BINARY, binary, pgType));
}
}
break;
diff --git a/ydb/public/lib/json_value/ydb_json_value_ut.cpp b/ydb/public/lib/json_value/ydb_json_value_ut.cpp
index d6abdee7af..afa9584225 100644
--- a/ydb/public/lib/json_value/ydb_json_value_ut.cpp
+++ b/ydb/public/lib/json_value/ydb_json_value_ut.cpp
@@ -560,10 +560,12 @@ Y_UNIT_TEST_SUITE(JsonValueTest) {
Y_UNIT_TEST(PgValue) {
TPgType pgType(1, 2, 3);
- TPgValue v1(true, "text_value", pgType);
- TPgValue v2(false, "binary_value", pgType);
- TPgValue v3(true, "", pgType);
- TPgValue v4(false, "", pgType);
+ TPgValue v1(TPgValue::VK_TEXT, "text_value", pgType);
+ TPgValue v2(TPgValue::VK_BINARY, "binary_value", pgType);
+ TPgValue v3(TPgValue::VK_TEXT, "", pgType);
+ TPgValue v4(TPgValue::VK_BINARY, "", pgType);
+ TPgValue v5(TPgValue::VK_NULL, "", pgType);
+
TValue value = TValueBuilder()
.BeginList()
.AddListItem()
@@ -574,12 +576,14 @@ Y_UNIT_TEST_SUITE(JsonValueTest) {
.Pg(v3)
.AddListItem()
.Pg(v4)
+ .AddListItem()
+ .Pg(v5)
.EndList()
.Build();
// unicode
const TString jsonString1 = FormatValueJson(value, EBinaryStringEncoding::Unicode);
- UNIT_ASSERT_NO_DIFF(jsonString1, R"(["text_value",["binary_value"],"",[""]])");
+ UNIT_ASSERT_NO_DIFF(jsonString1, R"(["text_value",["binary_value"],"",[""],null])");
TValue resultValue1 = JsonToYdbValue(jsonString1, value.GetType(), EBinaryStringEncoding::Unicode);
UNIT_ASSERT_NO_DIFF(
@@ -589,7 +593,7 @@ Y_UNIT_TEST_SUITE(JsonValueTest) {
// base64
const TString jsonString2 = FormatValueJson(value, EBinaryStringEncoding::Base64);
- UNIT_ASSERT_NO_DIFF(jsonString2, R"(["text_value",["YmluYXJ5X3ZhbHVl"],"",[""]])");
+ UNIT_ASSERT_NO_DIFF(jsonString2, R"(["text_value",["YmluYXJ5X3ZhbHVl"],"",[""],null])");
TValue resultValue2 = JsonToYdbValue(jsonString2, value.GetType(), EBinaryStringEncoding::Base64);
UNIT_ASSERT_NO_DIFF(
diff --git a/ydb/public/lib/yson_value/ydb_yson_value.cpp b/ydb/public/lib/yson_value/ydb_yson_value.cpp
index 922d14ae2b..d73b1c41e7 100644
--- a/ydb/public/lib/yson_value/ydb_yson_value.cpp
+++ b/ydb/public/lib/yson_value/ydb_yson_value.cpp
@@ -99,7 +99,9 @@ static void FormatValueYsonInternal(TValueParser& parser, NYson::TYsonWriter& wr
break;
case TTypeParser::ETypeKind::Pg:
- if (parser.GetPg().IsText()) {
+ if (parser.GetPg().IsNull()) {
+ writer.OnEntity();
+ } else if (parser.GetPg().IsText()) {
writer.OnStringScalar(parser.GetPg().Content_);
} else {
writer.OnBeginList();
diff --git a/ydb/public/sdk/cpp/client/ydb_value/value.cpp b/ydb/public/sdk/cpp/client/ydb_value/value.cpp
index a4396b7bec..25336625a0 100644
--- a/ydb/public/sdk/cpp/client/ydb_value/value.cpp
+++ b/ydb/public/sdk/cpp/client/ydb_value/value.cpp
@@ -918,25 +918,34 @@ TString TDecimalValue::ToString() const {
TPgValue::TPgValue(const Ydb::Value& pgValueProto, const TPgType& pgType)
: PgType_(pgType)
{
- IsText_ = pgValueProto.has_text_value();
- if (IsText_) {
+ if (pgValueProto.has_text_value()) {
+ Kind_ = VK_TEXT;
Content_ = pgValueProto.text_value();
+ return;
}
if (pgValueProto.has_bytes_value()) {
+ Kind_ = VK_BINARY;
Content_ = pgValueProto.bytes_value();
+ return;
}
+
+ Kind_ = VK_NULL;
}
-TPgValue::TPgValue(bool isText, const TString& content, const TPgType& pgType)
+TPgValue::TPgValue(EPgValueKind kind, const TString& content, const TPgType& pgType)
: PgType_(pgType)
- , IsText_(isText)
+ , Kind_(kind)
, Content_(content)
{
}
+bool TPgValue::IsNull() const {
+ return Kind_ == VK_NULL;
+}
+
bool TPgValue::IsText() const {
- return IsText_;
+ return Kind_ == VK_TEXT;
}
////////////////////////////////////////////////////////////////////////////////
@@ -2019,7 +2028,7 @@ public:
FillPgType(value.PgType_);
if (value.IsText()) {
GetValue().set_text_value(value.Content_);
- } else {
+ } else if (!value.IsNull()) {
GetValue().set_bytes_value(value.Content_);
}
}
diff --git a/ydb/public/sdk/cpp/client/ydb_value/value.h b/ydb/public/sdk/cpp/client/ydb_value/value.h
index 363c672285..2a5a96d182 100644
--- a/ydb/public/sdk/cpp/client/ydb_value/value.h
+++ b/ydb/public/sdk/cpp/client/ydb_value/value.h
@@ -221,12 +221,19 @@ struct TDecimalValue {
};
struct TPgValue {
+ enum EPgValueKind {
+ VK_NULL,
+ VK_TEXT,
+ VK_BINARY
+ };
+
TPgValue(const Ydb::Value& pgValueProto, const TPgType& pgType);
- TPgValue(bool isText, const TString& content, const TPgType& pgType);
+ TPgValue(EPgValueKind kind, const TString& content, const TPgType& pgType);
+ bool IsNull() const;
bool IsText() const;
TPgType PgType_;
- bool IsText_;
+ EPgValueKind Kind_ = VK_NULL;
TString Content_;
};
diff --git a/ydb/public/sdk/cpp/client/ydb_value/value_ut.cpp b/ydb/public/sdk/cpp/client/ydb_value/value_ut.cpp
index 82fa017fc5..8f6b8553f9 100644
--- a/ydb/public/sdk/cpp/client/ydb_value/value_ut.cpp
+++ b/ydb/public/sdk/cpp/client/ydb_value/value_ut.cpp
@@ -344,6 +344,36 @@ Y_UNIT_TEST_SUITE(YdbValue) {
}
}
}
+ members {
+ name: "C"
+ type {
+ pg_type {
+ oid: 123
+ typlen: -345
+ typmod: -321
+ }
+ }
+ }
+ members {
+ name: "D"
+ type {
+ pg_type {
+ oid: 123
+ typlen: -1
+ typmod: -1
+ }
+ }
+ }
+ members {
+ name: "E"
+ type {
+ pg_type {
+ oid: 123
+ typlen: -1
+ typmod: -1
+ }
+ }
+ }
}
)";
@@ -360,6 +390,8 @@ Y_UNIT_TEST_SUITE(YdbValue) {
items {
bytes_value: ""
}
+ items {
+ }
)";
Ydb::Type protoType;
@@ -371,11 +403,11 @@ Y_UNIT_TEST_SUITE(YdbValue) {
TValue value(TType(protoType), protoValue);
UNIT_ASSERT_NO_DIFF(FormatValueYson(value),
- R"(["my_text_value";["my_binary_value"]])");
+ R"(["my_text_value";["my_binary_value"];"";[""];#])");
UNIT_ASSERT_NO_DIFF(FormatValueJson(value, EBinaryStringEncoding::Unicode),
- R"({"A":"my_text_value","B":["my_binary_value"]})");
+ R"({"A":"my_text_value","B":["my_binary_value"],"C":"","D":[""],"E":null})");
UNIT_ASSERT_NO_DIFF(FormatValueJson(value, EBinaryStringEncoding::Base64),
- R"({"A":"my_text_value","B":["bXlfYmluYXJ5X3ZhbHVl"]})");
+ R"({"A":"my_text_value","B":["bXlfYmluYXJ5X3ZhbHVl"],"C":"","D":[""],"E":null})");
}
Y_UNIT_TEST(ParseValueMaybe) {