aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMars Agliullin <marsaly@ydb.tech>2024-01-18 00:48:17 +0300
committerGitHub <noreply@github.com>2024-01-18 00:48:17 +0300
commit2d2adb6bba1eda1de2f8b590dc8f70984cb69724 (patch)
tree589448861b1cc793be6c6b5e367eebbf367e7bb3
parent09f346fc38ae4a39c6fd1659caea5a183af8ee31 (diff)
downloadydb-2d2adb6bba1eda1de2f8b590dc8f70984cb69724.tar.gz
YQL-17493: Wrap returned YQL-typed columns with ToPg (#1059)
-rw-r--r--ydb/core/kqp/ut/service/kqp_qs_queries_ut.cpp2
-rw-r--r--ydb/library/yql/core/common_opt/yql_co_pgselect.cpp113
-rw-r--r--ydb/library/yql/core/type_ann/type_ann_pg.cpp14
-rw-r--r--ydb/library/yql/tests/sql/dq_file/part5/canondata/result.json22
-rw-r--r--ydb/library/yql/tests/sql/sql2yql/canondata/result.json7
-rw-r--r--ydb/library/yql/tests/sql/suites/pg/select_yql_type.cfg1
-rw-r--r--ydb/library/yql/tests/sql/suites/pg/select_yql_type.sql15
-rw-r--r--ydb/library/yql/tests/sql/yt_native_file/part5/canondata/result.json21
8 files changed, 135 insertions, 60 deletions
diff --git a/ydb/core/kqp/ut/service/kqp_qs_queries_ut.cpp b/ydb/core/kqp/ut/service/kqp_qs_queries_ut.cpp
index 06a5db263a..460fa094be 100644
--- a/ydb/core/kqp/ut/service/kqp_qs_queries_ut.cpp
+++ b/ydb/core/kqp/ut/service/kqp_qs_queries_ut.cpp
@@ -348,7 +348,7 @@ Y_UNIT_TEST_SUITE(KqpQueryService) {
auto db = kikimr.GetTableClient();
auto session = db.CreateSession().GetValueSync().GetSession();
auto result = session.ExecuteSchemeQuery(R"(
- CREATE TABLE test (id int8,PRIMARY KEY (id)))"
+ CREATE TABLE test (id int16,PRIMARY KEY (id)))"
).GetValueSync();
UNIT_ASSERT_C(result.IsSuccess(), result.GetIssues().ToString());
diff --git a/ydb/library/yql/core/common_opt/yql_co_pgselect.cpp b/ydb/library/yql/core/common_opt/yql_co_pgselect.cpp
index 12bd598fe4..154c593790 100644
--- a/ydb/library/yql/core/common_opt/yql_co_pgselect.cpp
+++ b/ydb/library/yql/core/common_opt/yql_co_pgselect.cpp
@@ -1699,53 +1699,74 @@ TExprNode::TPtr BuildProjectionLambda(TPositionHandle pos, const TExprNode::TPtr
.Param("row")
.Callable("AsStruct")
.Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
- ui32 index = 0;
- THashMap<TString, TExprNode*> overrideColumns;
- if (emitPgStar) {
- for (const auto& x : result->Tail().Children()) {
- if (x->HeadPtr()->IsAtom()) {
- overrideColumns.emplace(TString(x->HeadPtr()->Content()), x.Get());
- }
- }
- }
- auto addAtomToList = [] (TExprNodeBuilder& listBuilder, TExprNode* x) -> void {
- listBuilder.Add(0, x->HeadPtr());
- listBuilder.Apply(1, x->TailPtr())
+ auto addResultItem = [] (TExprNodeBuilder& builder, ui32 idx, TExprNode* resultItem) {
+ builder.Apply(idx, resultItem->TailPtr())
.With(0, "row")
.Seal();
- listBuilder.Seal();
};
- auto addAtomToListWithCast = [&addAtomToList] (TExprNodeBuilder& listBuilder, TExprNode* x,
- const TTypeAnnotationNode* expectedTypeNode) -> void {
- auto actualType = x->GetTypeAnn()->Cast<TPgExprType>();
+ auto addStructMember = [] (TExprNodeBuilder& builder, ui32 idx, const TStringBuf& memberName) {
+ builder.Callable(idx, "Member")
+ .Arg(0, "row")
+ .Atom(1, memberName)
+ .Seal();
+ };
+
+ auto addPgCast = [&finalType, &columnNamesMap, &pos, &ctx] (TExprNodeBuilder& builder, ui32 idx, const TStringBuf& columnName,
+ const TTypeAnnotationNode* actualTypeNode, const std::function<void(TExprNodeBuilder&, ui32)>& buildCore) {
+
+ const auto expectedTypeNode = finalType->FindItemType(columnNamesMap[columnName]);
Y_ENSURE(expectedTypeNode);
const auto expectedType = expectedTypeNode->Cast<TPgExprType>();
- if (actualType == expectedType) {
- addAtomToList(listBuilder, x);
- return;
- }
- listBuilder.Add(0, x->HeadPtr());
- listBuilder.Callable(1, "PgCast")
- .Apply(0, x->TailPtr())
- .With(0, "row")
- .Seal()
- .Callable(1, "PgType")
+ ui32 actualPgTypeId;
+ bool convertToPg;
+ Y_ENSURE(ExtractPgType(actualTypeNode, actualPgTypeId, convertToPg, pos, ctx));
+
+ auto needPgCast = (expectedType->GetId() != actualPgTypeId);
+
+ if (convertToPg) {
+ Y_ENSURE(!needPgCast, TStringBuilder()
+ << "Conversion to PG type is different at typization (" << expectedType->GetId()
+ << ") and optimization (" << actualPgTypeId << ") stages.");
+
+ auto wrapBuilder = builder.Callable(idx, "ToPg");
+ buildCore(wrapBuilder, 0);
+ wrapBuilder.Seal();
+ } else if (needPgCast) {
+ auto wrapBuilder = builder.Callable(idx, "PgCast");
+ buildCore(wrapBuilder, 0);
+ wrapBuilder.Callable(1, "PgType")
.Atom(0, NPg::LookupType(expectedType->GetId()).Name)
.Seal();
- listBuilder.Seal();
+ wrapBuilder.Seal();
+ } else {
+ buildCore(builder, idx);
+ }
+ builder.Seal();
};
+ ui32 index = 0;
+ THashMap<TString, TExprNode*> overrideColumns;
+ if (emitPgStar) {
+ for (const auto& x : result->Tail().Children()) {
+ if (x->HeadPtr()->IsAtom()) {
+ overrideColumns.emplace(TString(x->HeadPtr()->Content()), x.Get());
+ }
+ }
+ }
+
for (const auto& x : result->Tail().Children()) {
if (x->HeadPtr()->IsAtom()) {
- if (!emitPgStar) {
- const auto& columnName = x->Child(0)->Content();
- auto listBuilder = parent.List(index++);
- const auto expectedType = finalType->FindItemType(columnNamesMap[columnName]);
- Y_ENSURE(expectedType);
- addAtomToListWithCast(listBuilder, x.Get(), expectedType);
+ if (emitPgStar) {
+ continue;
}
+ const auto& columnName = x->Head().Content();
+
+ auto listBuilder = parent.List(index++);
+ listBuilder.Add(0, x->HeadPtr());
+ addPgCast(listBuilder, 1, columnName, x->GetTypeAnn(),
+ [&addResultItem, &x] (TExprNodeBuilder& builder, ui32 idx) { addResultItem(builder, idx, x.Get()); });
} else {
auto type = x->Child(1)->GetTypeAnn()->Cast<TTypeExprType>()->GetType()->Cast<TStructExprType>();
Y_ENSURE(type);
@@ -1755,31 +1776,15 @@ TExprNode::TPtr BuildProjectionLambda(TPositionHandle pos, const TExprNode::TPtr
auto columnName = subLink ? column : NTypeAnnImpl::RemoveAlias(column);
auto listBuilder = parent.List(index++);
- if (overrideColumns.contains(columnName)) {
+ if (auto* columnNode = overrideColumns.FindPtr(columnName)) {
// we never get here while processing SELECTs,
// so no need to add PgCasts due to query combining with UNION ALL et al
- addAtomToList(listBuilder, overrideColumns[columnName]);
+ listBuilder.Add(0, (*columnNode)->HeadPtr());
+ addResultItem(listBuilder, 1, *columnNode);
} else {
listBuilder.Atom(0, columnName);
-
- const auto expectedType = finalType->FindItemType(columnNamesMap[columnName]);
- Y_ENSURE(expectedType);
- if (item->GetItemType() == expectedType) {
- listBuilder.Callable(1, "Member")
- .Arg(0, "row")
- .Atom(1, column)
- .Seal();
- } else {
- listBuilder.Callable(1, "PgCast")
- .Callable(0, "Member")
- .Arg(0, "row")
- .Atom(1, column)
- .Seal()
- .Callable(1, "PgType")
- .Atom(0, NPg::LookupType(expectedType->Cast<TPgExprType>()->GetId()).Name)
- .Seal()
- .Seal();
- }
+ addPgCast(listBuilder, 1, columnName, item->GetItemType(),
+ [&addStructMember, &column] (TExprNodeBuilder& builder, ui32 idx) { addStructMember(builder, idx, column); });
}
}
}
diff --git a/ydb/library/yql/core/type_ann/type_ann_pg.cpp b/ydb/library/yql/core/type_ann/type_ann_pg.cpp
index 262abe8726..c096043951 100644
--- a/ydb/library/yql/core/type_ann/type_ann_pg.cpp
+++ b/ydb/library/yql/core/type_ann/type_ann_pg.cpp
@@ -153,7 +153,15 @@ IGraphTransformer::TStatus InferPgCommonType(TPositionHandle pos, const TExprNod
for (const auto& col : *childColumnOrder) {
auto itemIdx = structType->FindItem(col);
YQL_ENSURE(itemIdx);
- pgTypes[j].push_back(structType->GetItems()[*itemIdx]->GetItemType()->Cast<TPgExprType>()->GetId());
+
+ const auto* type = structType->GetItems()[*itemIdx]->GetItemType();
+ ui32 pgType;
+ bool convertToPg;
+ if (!ExtractPgType(type, pgType, convertToPg, child->Pos(), ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ pgTypes[j].push_back(pgType);
++j;
}
@@ -4282,7 +4290,6 @@ IGraphTransformer::TStatus PgSelectWrapper(const TExprNode::TPtr& input, TExprNo
return IGraphTransformer::TStatus::Error;
}
- // const TStructExprType* outputRowType = nullptr;
TExprNode* setItems = nullptr;
TExprNode* setOps = nullptr;
bool hasSort = false;
@@ -4343,9 +4350,6 @@ IGraphTransformer::TStatus PgSelectWrapper(const TExprNode::TPtr& input, TExprNo
}
setItems = &option->Tail();
- } else {
- /*outputRowType = */option->Tail().Head().GetTypeAnn()->Cast<TListExprType>()->GetItemType()->
- Cast<TStructExprType>();
}
} else if (optionName == "limit" || optionName == "offset") {
if (pass != 0) {
diff --git a/ydb/library/yql/tests/sql/dq_file/part5/canondata/result.json b/ydb/library/yql/tests/sql/dq_file/part5/canondata/result.json
index 0ac48205a7..fda32009b6 100644
--- a/ydb/library/yql/tests/sql/dq_file/part5/canondata/result.json
+++ b/ydb/library/yql/tests/sql/dq_file/part5/canondata/result.json
@@ -2210,6 +2210,28 @@
}
],
"test.test[pg-select_win_count-default.txt-Results]": [],
+ "test.test[pg-select_yql_type--Analyze]": [
+ {
+ "checksum": "8ff95379719438cd7e637f0c2b6945c5",
+ "size": 7622,
+ "uri": "https://{canondata_backend}/1031349/1e1ff3377d9e6463687741aa3509395b92a00445/resource.tar.gz#test.test_pg-select_yql_type--Analyze_/plan.txt"
+ }
+ ],
+ "test.test[pg-select_yql_type--Debug]": [
+ {
+ "checksum": "3dde0f6689824d0af2cae2e11a23fe80",
+ "size": 2702,
+ "uri": "https://{canondata_backend}/1031349/1e1ff3377d9e6463687741aa3509395b92a00445/resource.tar.gz#test.test_pg-select_yql_type--Debug_/opt.yql_patched"
+ }
+ ],
+ "test.test[pg-select_yql_type--Plan]": [
+ {
+ "checksum": "8ff95379719438cd7e637f0c2b6945c5",
+ "size": 7622,
+ "uri": "https://{canondata_backend}/1031349/1e1ff3377d9e6463687741aa3509395b92a00445/resource.tar.gz#test.test_pg-select_yql_type--Plan_/plan.txt"
+ }
+ ],
+ "test.test[pg-select_yql_type--Results]": [],
"test.test[pg-str_lookup_pg-default.txt-Analyze]": [
{
"checksum": "a48ccc9922567dfee1170d2c2df45b6e",
diff --git a/ydb/library/yql/tests/sql/sql2yql/canondata/result.json b/ydb/library/yql/tests/sql/sql2yql/canondata/result.json
index 349c8228ea..2c89d6b5b9 100644
--- a/ydb/library/yql/tests/sql/sql2yql/canondata/result.json
+++ b/ydb/library/yql/tests/sql/sql2yql/canondata/result.json
@@ -12046,6 +12046,13 @@
"uri": "https://{canondata_backend}/1599023/af9c2f81df0601cf266a0926b5ce73b6101b9115/resource.tar.gz#test_sql2yql.test_pg-select_win_sum_null_/sql.yql"
}
],
+ "test_sql2yql.test[pg-select_yql_type]": [
+ {
+ "checksum": "7447752d11b2fc790e27004b7112fe31",
+ "size": 1975,
+ "uri": "https://{canondata_backend}/1937367/379ba745ff59ebd29c817a5b281c005a67df3be4/resource.tar.gz#test_sql2yql.test_pg-select_yql_type_/sql.yql"
+ }
+ ],
"test_sql2yql.test[pg-set_of_as_records]": [
{
"checksum": "439ee1feaf9750daf11386fe54adbc05",
diff --git a/ydb/library/yql/tests/sql/suites/pg/select_yql_type.cfg b/ydb/library/yql/tests/sql/suites/pg/select_yql_type.cfg
new file mode 100644
index 0000000000..0ca1ef5bf1
--- /dev/null
+++ b/ydb/library/yql/tests/sql/suites/pg/select_yql_type.cfg
@@ -0,0 +1 @@
+in Input input_name.txt
diff --git a/ydb/library/yql/tests/sql/suites/pg/select_yql_type.sql b/ydb/library/yql/tests/sql/suites/pg/select_yql_type.sql
new file mode 100644
index 0000000000..18574a079b
--- /dev/null
+++ b/ydb/library/yql/tests/sql/suites/pg/select_yql_type.sql
@@ -0,0 +1,15 @@
+--!syntax_pg
+SELECT
+ key, index, index + 1
+FROM plato."Input"
+ORDER BY index;
+
+SELECT
+ *
+FROM plato."Input"
+ORDER BY index;
+
+SELECT
+ t.*
+FROM plato."Input" as t
+ORDER BY index;
diff --git a/ydb/library/yql/tests/sql/yt_native_file/part5/canondata/result.json b/ydb/library/yql/tests/sql/yt_native_file/part5/canondata/result.json
index dd17cdc3cd..617b5ee95e 100644
--- a/ydb/library/yql/tests/sql/yt_native_file/part5/canondata/result.json
+++ b/ydb/library/yql/tests/sql/yt_native_file/part5/canondata/result.json
@@ -2075,6 +2075,27 @@
"uri": "https://{canondata_backend}/1773845/f8e51a5dd98665ee7534cca6737c91ce5a753b8e/resource.tar.gz#test.test_pg-select_win_count-default.txt-Results_/results.txt"
}
],
+ "test.test[pg-select_yql_type--Debug]": [
+ {
+ "checksum": "f94603a4a31fd031cd1be6adf9bde1fd",
+ "size": 3816,
+ "uri": "https://{canondata_backend}/1031349/2368626953942b3adafcb76228785c3ee4e852f5/resource.tar.gz#test.test_pg-select_yql_type--Debug_/opt.yql"
+ }
+ ],
+ "test.test[pg-select_yql_type--Plan]": [
+ {
+ "checksum": "5889de5da2fd54b7327aaf12f536e2d9",
+ "size": 6736,
+ "uri": "https://{canondata_backend}/1031349/2368626953942b3adafcb76228785c3ee4e852f5/resource.tar.gz#test.test_pg-select_yql_type--Plan_/plan.txt"
+ }
+ ],
+ "test.test[pg-select_yql_type--Results]": [
+ {
+ "checksum": "aa4c3b838298a4c407b27345733a5fa1",
+ "size": 3812,
+ "uri": "https://{canondata_backend}/1031349/2368626953942b3adafcb76228785c3ee4e852f5/resource.tar.gz#test.test_pg-select_yql_type--Results_/results.txt"
+ }
+ ],
"test.test[pg-str_lookup_pg-default.txt-Debug]": [
{
"checksum": "66a86824b404ec795db5472f15e7ef6d",