aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVitaly Stoyan <vitstn@gmail.com>2022-06-09 13:53:44 +0300
committerVitaly Stoyan <vitstn@gmail.com>2022-06-09 13:53:44 +0300
commit1a0a79084f0aa2254c3eeb466e47596b9c258140 (patch)
tree7cf76d0d344aa18bbc56a0491e461344d3b96f91
parentf4140decee7d6d469b837db2a2886af748132ba7 (diff)
downloadydb-1a0a79084f0aa2254c3eeb466e47596b9c258140.tar.gz
YQL-14728 support of aliases, including sublinks
ref:b7f00fe95aba6398bd425b5f708c7566eedeaa2d
-rw-r--r--ydb/library/yql/core/common_opt/yql_co_pgselect.cpp128
-rw-r--r--ydb/library/yql/core/common_opt/yql_co_pgselect.h3
-rw-r--r--ydb/library/yql/core/common_opt/yql_co_simple1.cpp8
-rw-r--r--ydb/library/yql/core/type_ann/type_ann_pg.cpp163
-rw-r--r--ydb/library/yql/core/type_ann/type_ann_pg.h6
5 files changed, 215 insertions, 93 deletions
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 b86e44bbf4..3766acc17a 100644
--- a/ydb/library/yql/core/common_opt/yql_co_pgselect.cpp
+++ b/ydb/library/yql/core/common_opt/yql_co_pgselect.cpp
@@ -1,5 +1,7 @@
#include "yql_co_pgselect.h"
+#include <ydb/library/yql/core/type_ann/type_ann_pg.h>
+
#include <ydb/library/yql/core/yql_expr_optimize.h>
#include <ydb/library/yql/core/yql_opt_utils.h>
@@ -32,7 +34,7 @@ TSet<TString> ExtractExternalColumns(const TExprNode& select) {
for (const auto& input : extTypes->Tail().Children()) {
auto type = input->Tail().GetTypeAnn()->Cast<TTypeExprType>()->GetType()->Cast<TStructExprType>();
for (const auto& i : type->GetItems()) {
- res.insert(TString(i->GetName()));
+ res.insert(NTypeAnnImpl::MakeAliasedColumn(input->Head().Content(), i->GetName()));
}
}
}
@@ -41,7 +43,7 @@ TSet<TString> ExtractExternalColumns(const TExprNode& select) {
}
TExprNode::TPtr JoinColumns(TPositionHandle pos, const TExprNode::TPtr& list1, const TExprNode::TPtr& list2,
- TExprNode::TPtr leftJoinColumns, TExprContext& ctx) {
+ TExprNode::TPtr leftJoinColumns, ui32 subLinkId, TExprContext& ctx) {
auto join = ctx.Builder(pos)
.Callable("EquiJoin")
.List(0)
@@ -73,7 +75,8 @@ TExprNode::TPtr JoinColumns(TPositionHandle pos, const TExprNode::TPtr& list1, c
if (leftJoinColumns) {
for (ui32 i = 0; i < leftJoinColumns->ChildrenSize(); ++i) {
parent.Atom(2 * i, "b");
- parent.Atom(2 * i + 1, TString("_yql_join_sublink_") + leftJoinColumns->Child(i)->Content() );
+ parent.Atom(2 * i + 1, TString("_yql_join_sublink_") + ToString(subLinkId) +
+ "_" + leftJoinColumns->Child(i)->Content() );
}
}
@@ -84,6 +87,20 @@ TExprNode::TPtr JoinColumns(TPositionHandle pos, const TExprNode::TPtr& list1, c
.Seal()
.Seal()
.List(3)
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder & {
+ if (leftJoinColumns) {
+ for (ui32 i = 0; i < leftJoinColumns->ChildrenSize(); ++i) {
+ parent.List(i)
+ .Atom(0, "rename")
+ .Atom(1, TString("b._yql_join_sublink_") + ToString(subLinkId) +
+ "_" + leftJoinColumns->Child(i)->Content())
+ .Atom(2, "")
+ .Seal();
+ }
+ }
+
+ return parent;
+ })
.Seal()
.Seal()
.Build();
@@ -108,7 +125,6 @@ TExprNode::TPtr JoinColumns(TPositionHandle pos, const TExprNode::TPtr& list1, c
std::pair<TExprNode::TPtr, TExprNode::TPtr> RewriteSubLinks(TPositionHandle pos,
const TExprNode::TPtr& list, const TExprNode::TPtr& lambda,
const TNodeMap<ui32>& subLinks, const TExprNode::TPtr& joins, TExprContext& ctx, TOptimizeContext& optCtx) {
- ui32 sublinkColumnIndex = 0;
auto newList = list;
auto originalRow = lambda->Head().HeadPtr();
auto arg = ctx.NewArgument(pos, "row");
@@ -121,7 +137,7 @@ std::pair<TExprNode::TPtr, TExprNode::TPtr> RewriteSubLinks(TPositionHandle pos,
auto linkType = node->Head().Content();
TSet<TString> extColumns = ExtractExternalColumns(node->Tail());
if (extColumns.empty()) {
- auto select = ExpandPgSelectSublink(node->TailPtr(), ctx, optCtx, nullptr);
+ auto select = ExpandPgSelectSublink(node->TailPtr(), ctx, optCtx, it->second, nullptr);
if (linkType == "exists") {
return ctx.Builder(node->Pos())
.Callable("ToPg")
@@ -264,7 +280,7 @@ std::pair<TExprNode::TPtr, TExprNode::TPtr> RewriteSubLinks(TPositionHandle pos,
.Seal()
.Build();
- auto select = ExpandPgSelectSublink(node->TailPtr(), ctx, optCtx, uniqueOuterList);
+ auto select = ExpandPgSelectSublink(node->TailPtr(), ctx, optCtx, it->second, uniqueOuterList);
auto exportsPtr = optCtx.Types->Modules->GetModule("/lib/yql/aggregate.yql");
YQL_ENSURE(exportsPtr);
@@ -365,7 +381,7 @@ std::pair<TExprNode::TPtr, TExprNode::TPtr> RewriteSubLinks(TPositionHandle pos,
}
}
- auto columnName = "_yql_sublink_" + ToString(sublinkColumnIndex++);
+ auto columnName = "_yql_sublink_" + ToString(it->second);
TExprNode::TListType aggregateItems;
if (linkType == "exists") {
aggregateItems.push_back(ctx.Builder(node->Pos())
@@ -403,7 +419,8 @@ std::pair<TExprNode::TPtr, TExprNode::TPtr> RewriteSubLinks(TPositionHandle pos,
.List(1)
.Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder & {
for (ui32 i = 0; i < colList->ChildrenSize(); ++i) {
- parent.Atom(i, TString("_yql_join_sublink_") + colList->Child(i)->Content());
+ parent.Atom(i, TString("_yql_join_sublink_") + ToString(it->second) +
+ "_" + colList->Child(i)->Content());
}
return parent;
@@ -413,7 +430,7 @@ std::pair<TExprNode::TPtr, TExprNode::TPtr> RewriteSubLinks(TPositionHandle pos,
.Seal()
.Build();
- newList = JoinColumns(pos, newList, groupedSublink, colList, ctx);
+ newList = JoinColumns(pos, newList, groupedSublink, colList, it->second, ctx);
if (linkType == "exists") {
return ctx.Builder(node->Pos())
@@ -607,27 +624,13 @@ TExprNode::TPtr BuildValues(TPositionHandle pos, const TExprNode::TPtr& values,
.Build();
}
-std::tuple<TExprNode::TPtr, TExprNode::TPtr> BuildOneRow(TPositionHandle pos, const TExprNode::TPtr& result, TExprContext& ctx) {
- auto arg = ctx.NewArgument(pos, "row");
- auto arguments = ctx.NewArguments(pos, { arg });
-
- TExprNode::TListType rowItems;
- for (const auto& x : result->Tail().Children()) {
- auto value = ctx.ReplaceNode(x->Tail().TailPtr(), x->Tail().Head().Head(), arg);
- rowItems.push_back(ctx.NewList(x->Pos(), { x->HeadPtr(), value }));
- }
-
- auto row = ctx.NewCallable(pos, "AsStruct", std::move(rowItems));
- auto projectionLambda = ctx.NewLambda(pos, std::move(arguments), std::move(row));
-
- auto list = ctx.Builder(pos)
+TExprNode::TPtr BuildOneRow(TPositionHandle pos, TExprContext& ctx) {
+ return ctx.Builder(pos)
.Callable("AsList")
.Callable(0, "AsStruct")
.Seal()
.Seal()
.Build();
-
- return { list, projectionLambda };
}
using TUsedColumns = TMap<TString, std::pair<ui32, TString>>;
@@ -690,23 +693,31 @@ TUsedColumns GatherUsedColumns(const TExprNode::TPtr& result, const TExprNode::T
void FillInputIndices(const TExprNode::TPtr& from, const TExprNode::TPtr& finalExtTypes,
TUsedColumns& usedColumns, TOptimizeContext& optCtx) {
for (auto& x : usedColumns) {
+ TStringBuf alias;
+ TStringBuf column = NTypeAnnImpl::RemoveAlias(x.first, alias);
+
bool foundColumn = false;
ui32 inputIndex = 0;
for (; inputIndex < from->Tail().ChildrenSize(); ++inputIndex) {
+ const auto& inputAlias = from->Tail().Child(inputIndex)->Child(1)->Content();
const auto& read = from->Tail().Child(inputIndex)->Head();
const auto& columns = from->Tail().Child(inputIndex)->Tail();
if (read.IsCallable("PgResolvedCall")) {
- const auto& alias = from->Tail().Child(inputIndex)->Child(1)->Content();
- Y_ENSURE(!alias.empty());
+ Y_ENSURE(!inputAlias.empty());
Y_ENSURE(columns.ChildrenSize() == 0 || columns.ChildrenSize() == 1);
- auto memberName = (columns.ChildrenSize() == 1) ? columns.Head().Content() : alias;
+ auto memberName = NTypeAnnImpl::MakeAliasedColumn(inputAlias,
+ (columns.ChildrenSize() == 1) ? columns.Head().Content() : inputAlias);
foundColumn = (memberName == x.first);
} else {
+ if (alias && alias != inputAlias) {
+ continue;
+ }
+
if (columns.ChildrenSize() > 0) {
auto readOrder = optCtx.Types->LookupColumnOrder(read);
YQL_ENSURE(readOrder);
for (ui32 i = 0; i < columns.ChildrenSize(); ++i) {
- if (columns.Child(i)->Content() == x.first) {
+ if (columns.Child(i)->Content() == column) {
foundColumn = true;
x.second.second = (*readOrder)[i];
break;
@@ -715,7 +726,7 @@ void FillInputIndices(const TExprNode::TPtr& from, const TExprNode::TPtr& finalE
} else {
auto type = read.GetTypeAnn()->
Cast<TListExprType>()->GetItemType()->Cast<TStructExprType>();
- auto pos = type->FindItem(x.first);
+ auto pos = type->FindItem(column);
foundColumn = pos.Defined();
}
}
@@ -728,9 +739,14 @@ void FillInputIndices(const TExprNode::TPtr& from, const TExprNode::TPtr& finalE
if (!foundColumn && finalExtTypes) {
for (const auto& input : finalExtTypes->Tail().Children()) {
+ const auto& inputAlias = input->Head().Content();
+ if (alias && alias != inputAlias) {
+ continue;
+ }
+
auto type = input->Tail().GetTypeAnn()->
Cast<TTypeExprType>()->GetType()->Cast<TStructExprType>();
- auto pos = type->FindItem(x.first);
+ auto pos = type->FindItem(column);
foundColumn = pos.Defined();
if (foundColumn) {
x.second.first = inputIndex;
@@ -749,12 +765,12 @@ TExprNode::TListType BuildCleanedColumns(TPositionHandle pos, const TExprNode::T
TExprNode::TListType cleanedInputs;
for (ui32 i = 0; i < from->Tail().ChildrenSize(); ++i) {
auto list = from->Tail().Child(i)->HeadPtr();
+ const auto& inputAlias = from->Tail().Child(i)->Child(1)->Content();
if (list->IsCallable("PgResolvedCall")) {
- const auto& alias = from->Tail().Child(i)->Child(1)->Content();
const auto& columns = from->Tail().Child(i)->Tail();
- Y_ENSURE(!alias.empty());
+ Y_ENSURE(!inputAlias.empty());
Y_ENSURE(columns.ChildrenSize() == 0 || columns.ChildrenSize() == 1);
- auto memberName = (columns.ChildrenSize() == 1) ? columns.Head().Content() : alias;
+ auto memberName = (columns.ChildrenSize() == 1) ? columns.Head().Content() : inputAlias;
if (list->GetTypeAnn()->GetKind() == ETypeAnnotationKind::List) {
list = ctx.Builder(pos)
.Callable("OrderedMap")
@@ -801,7 +817,7 @@ TExprNode::TListType BuildCleanedColumns(TPositionHandle pos, const TExprNode::T
listBuilder.Atom(0, x.first);
listBuilder.Callable(1, "Member")
.Arg(0, "row")
- .Atom(1, x.second.second ? x.second.second : x.first)
+ .Atom(1, x.second.second ? x.second.second : NTypeAnnImpl::RemoveAlias(x.first))
.Seal();
listBuilder.Seal();
}
@@ -1012,7 +1028,7 @@ TExprNode::TPtr BuildCrossJoinsBetweenGroups(TPositionHandle pos, const TExprNod
return ctx.NewCallable(pos, "EquiJoin", std::move(args));
}
-TExprNode::TPtr BuildProjectionLambda(TPositionHandle pos, const TExprNode::TPtr& result, TExprContext& ctx) {
+TExprNode::TPtr BuildProjectionLambda(TPositionHandle pos, const TExprNode::TPtr& result, bool subLink, TExprContext& ctx) {
return ctx.Builder(pos)
.Lambda()
.Param("row")
@@ -1028,12 +1044,14 @@ TExprNode::TPtr BuildProjectionLambda(TPositionHandle pos, const TExprNode::TPtr
.Seal();
listBuilder.Seal();
} else {
- for (ui32 i = 0; i < x->Head().ChildrenSize(); ++i) {
+ auto type = x->Child(1)->GetTypeAnn()->Cast<TTypeExprType>()->GetType()->Cast<TStructExprType>();
+ for (ui32 i = 0; i < type->GetSize(); ++i) {
+ auto column = type->GetItems()[i]->GetName();
auto listBuilder = parent.List(index++);
- listBuilder.Add(0, x->Head().ChildPtr(i));
+ listBuilder.Atom(0, subLink ? column : NTypeAnnImpl::RemoveAlias(column));
listBuilder.Callable(1, "Member")
.Arg(0, "row")
- .Add(1, x->Head().ChildPtr(i));
+ .Atom(1, column);
listBuilder.Seal();
}
}
@@ -1651,7 +1669,7 @@ TExprNode::TPtr BuildLimit(TPositionHandle pos, const TExprNode::TPtr& limit, co
}
TExprNode::TPtr AddExtColumns(const TExprNode::TPtr& lambda, const TExprNode::TPtr& finalExtTypes,
- TExprNode::TListType& columns, TExprContext& ctx) {
+ TExprNode::TListType& columns, ui32 subLinkId, TExprContext& ctx) {
return ctx.Builder(lambda->Pos())
.Lambda()
.Param("row")
@@ -1663,17 +1681,20 @@ TExprNode::TPtr AddExtColumns(const TExprNode::TPtr& lambda, const TExprNode::TP
.Seal()
.Seal()
.List(1)
- .Atom(0, "_yql_join_sublink_")
+ .Atom(0, "_yql_join_sublink_" + ToString(subLinkId) + "_")
.Callable(1, "SelectMembers")
.Arg(0, "row")
.List(1)
.Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder & {
ui32 i = 0;
for (const auto& x : finalExtTypes->Children()) {
+ auto alias = x->Head().Content();
auto type = x->Tail().GetTypeAnn()->Cast<TTypeExprType>()->GetType()->Cast<TStructExprType>();
for (const auto& item : type->GetItems()) {
- parent.Atom(i++, item->GetName());
- columns.push_back(ctx.NewAtom(lambda->Pos(), TString("_yql_join_sublink_") + item->GetName()));
+ auto withAlias = NTypeAnnImpl::MakeAliasedColumn(alias, item->GetName());
+ parent.Atom(i++, withAlias);
+ columns.push_back(ctx.NewAtom(lambda->Pos(), TString("_yql_join_sublink_") +
+ ToString(subLinkId) + "_" + withAlias));
}
}
@@ -1687,7 +1708,8 @@ TExprNode::TPtr AddExtColumns(const TExprNode::TPtr& lambda, const TExprNode::TP
.Build();
}
-TExprNode::TPtr ExpandPgSelectImpl(const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& optCtx, bool subLink, const TExprNode::TPtr& outer) {
+TExprNode::TPtr ExpandPgSelectImpl(const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& optCtx,
+ TMaybe<ui32> subLinkId, const TExprNode::TPtr& outer) {
auto order = optCtx.Types->LookupColumnOrder(*node);
YQL_ENSURE(order);
TExprNode::TListType columnsItems;
@@ -1703,7 +1725,7 @@ TExprNode::TPtr ExpandPgSelectImpl(const TExprNode::TPtr& node, TExprContext& ct
YQL_ENSURE(*childOrder);
columnOrders.push_back(*childOrder);
auto finalExtTypes = GetSetting(setItem->Tail(), "final_ext_types");
- if (finalExtTypes && !subLink) {
+ if (finalExtTypes && !subLinkId) {
return node;
}
@@ -1722,9 +1744,9 @@ TExprNode::TPtr ExpandPgSelectImpl(const TExprNode::TPtr& node, TExprContext& ct
list = BuildValues(node->Pos(), values, ctx);
} else {
YQL_ENSURE(result);
- TExprNode::TPtr projectionLambda;
+ TExprNode::TPtr projectionLambda = BuildProjectionLambda(node->Pos(), result, subLinkId.Defined(), ctx);
if (oneRow) {
- std::tie(list, projectionLambda) = BuildOneRow(node->Pos(), result, ctx);
+ list = BuildOneRow(node->Pos(), ctx);
} else {
// extract all used columns
auto usedColumns = GatherUsedColumns(result, joinOps, filter, having);
@@ -1745,12 +1767,10 @@ TExprNode::TPtr ExpandPgSelectImpl(const TExprNode::TPtr& node, TExprContext& ct
list = BuildCrossJoinsBetweenGroups(node->Pos(), joinGroups, usedColumns, groupForIndex, ctx);
}
}
-
- projectionLambda = BuildProjectionLambda(node->Pos(), result, ctx);
}
if (outer) {
- list = JoinColumns(node->Pos(), list, outer, nullptr, ctx);
+ list = JoinColumns(node->Pos(), list, outer, nullptr, 0, ctx);
}
auto joins = list;
@@ -1774,7 +1794,7 @@ TExprNode::TPtr ExpandPgSelectImpl(const TExprNode::TPtr& node, TExprContext& ct
}
if (finalExtTypes) {
- projectionLambda = AddExtColumns(projectionLambda, finalExtTypes->TailPtr(), columnsItems, ctx);
+ projectionLambda = AddExtColumns(projectionLambda, finalExtTypes->TailPtr(), columnsItems, *subLinkId, ctx);
}
list = ctx.Builder(node->Pos())
@@ -1821,11 +1841,11 @@ TExprNode::TPtr ExpandPgSelectImpl(const TExprNode::TPtr& node, TExprContext& ct
}
TExprNode::TPtr ExpandPgSelect(const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& optCtx) {
- return ExpandPgSelectImpl(node, ctx, optCtx, false, nullptr);
+ return ExpandPgSelectImpl(node, ctx, optCtx, Nothing(), nullptr);
}
-TExprNode::TPtr ExpandPgSelectSublink(const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& optCtx, const TExprNode::TPtr& outer) {
- return ExpandPgSelectImpl(node, ctx, optCtx, true, outer);
+TExprNode::TPtr ExpandPgSelectSublink(const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& optCtx, ui32 subLinkId, const TExprNode::TPtr& outer) {
+ return ExpandPgSelectImpl(node, ctx, optCtx, subLinkId, outer);
}
TExprNode::TPtr ExpandPgLike(const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& optCtx) {
diff --git a/ydb/library/yql/core/common_opt/yql_co_pgselect.h b/ydb/library/yql/core/common_opt/yql_co_pgselect.h
index 10a1c2f63a..be7ee143a7 100644
--- a/ydb/library/yql/core/common_opt/yql_co_pgselect.h
+++ b/ydb/library/yql/core/common_opt/yql_co_pgselect.h
@@ -6,7 +6,8 @@ namespace NYql {
TExprNode::TPtr ExpandPgSelect(const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& optCtx);
-TExprNode::TPtr ExpandPgSelectSublink(const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& optCtx, const TExprNode::TPtr& outer);
+TExprNode::TPtr ExpandPgSelectSublink(const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& optCtx,
+ ui32 subLinkId, const TExprNode::TPtr& outer);
TExprNode::TPtr ExpandPositionalUnionAll(const TExprNode& node, const TVector<TColumnOrder>& columnOrders,
TExprNode::TListType children, TExprContext& ctx, TOptimizeContext& optCtx);
diff --git a/ydb/library/yql/core/common_opt/yql_co_simple1.cpp b/ydb/library/yql/core/common_opt/yql_co_simple1.cpp
index 4e9ef778fc..dd8467c669 100644
--- a/ydb/library/yql/core/common_opt/yql_co_simple1.cpp
+++ b/ydb/library/yql/core/common_opt/yql_co_simple1.cpp
@@ -5292,6 +5292,14 @@ void RegisterCoSimpleCallables1(TCallableOptimizerMap& map) {
return HasNullOverStruct(node, ctx);
case ETypeAnnotationKind::Variant:
return HasNullOverVariant(node, ctx);
+ case ETypeAnnotationKind::Pg:
+ return ctx.Builder(node->Pos())
+ .Callable("Not")
+ .Callable(0, "Exists")
+ .Add(0, value)
+ .Seal()
+ .Seal()
+ .Build();
default:
YQL_ENSURE(false, "Value type " << *valueType << " is not supported!");
}
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 0a7c565ed5..4315a945f0 100644
--- a/ydb/library/yql/core/type_ann/type_ann_pg.cpp
+++ b/ydb/library/yql/core/type_ann/type_ann_pg.cpp
@@ -1492,6 +1492,7 @@ bool ScanColumns(TExprNode::TPtr root, TInputs& inputs, const THashSet<TString>&
return false;
}
+ TString foundAlias;
for (ui32 pass = 0; pass < 2; ++pass) {
ui32 matches = 0;
for (auto& x : inputs) {
@@ -1507,6 +1508,7 @@ bool ScanColumns(TExprNode::TPtr root, TInputs& inputs, const THashSet<TString>&
auto pos = x.Type->FindItem(node->Tail().Content());
if (pos) {
+ foundAlias = x.Alias;
++matches;
if (matches > 1) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(node->Pos()),
@@ -1533,7 +1535,11 @@ bool ScanColumns(TExprNode::TPtr root, TInputs& inputs, const THashSet<TString>&
}
}
- refs.insert(TString(node->Tail().Content()));
+ if (foundAlias && qualifiedRefs) {
+ (*qualifiedRefs)[foundAlias].insert(TString(node->Tail().Content()));
+ } else {
+ refs.insert(TString(node->Tail().Content()));
+ }
}
return true;
@@ -1617,9 +1623,53 @@ bool ValidateWindowRefs(const TExprNode::TPtr& root, const TExprNode* windows, T
return !isError;
}
+TString MakeAliasedColumn(TStringBuf alias, TStringBuf column) {
+ if (!alias) {
+ return TString(column);
+ }
+
+ return TStringBuilder() << "_alias_" << alias << "." << column;
+}
+
+const TItemExprType* AddAlias(const TString& alias, const TItemExprType* item, TExprContext& ctx) {
+ if (!alias) {
+ return item;
+ }
+
+ return ctx.MakeType<TItemExprType>(MakeAliasedColumn(alias, item->GetName()), item->GetItemType());
+}
+
+TStringBuf RemoveAlias(TStringBuf column) {
+ TStringBuf tmp;
+ return RemoveAlias(column, tmp);
+}
+
+TStringBuf RemoveAlias(TStringBuf column, TStringBuf& alias) {
+ if (!column.StartsWith("_alias_")) {
+ alias = "";
+ return column;
+ }
+
+ auto columnPos = column.find('.', 7);
+ YQL_ENSURE(columnPos != TString::npos);
+ columnPos += 1;
+ YQL_ENSURE(columnPos != column.size());
+ alias = column.substr(7, columnPos - 7 - 1);
+ return column.substr(columnPos);
+}
+
+const TItemExprType* RemoveAlias(const TItemExprType* item, TExprContext& ctx) {
+ auto name = item->GetName();
+ if (!name.StartsWith("_alias_")) {
+ return item;
+ }
+
+ return ctx.MakeType<TItemExprType>(RemoveAlias(name), item->GetItemType());
+}
+
void AddColumns(const TInputs& inputs, const bool* hasStar, const THashSet<TString>& refs,
const THashMap<TString, THashSet<TString>>* qualifiedRefs,
- TVector<const TItemExprType*>& items) {
+ TVector<const TItemExprType*>& items, TExprContext& ctx) {
THashSet<TString> usedRefs;
THashSet<TString> usedAliases;
for (ui32 pass = 0; pass < 2; ++pass) {
@@ -1632,6 +1682,7 @@ void AddColumns(const TInputs& inputs, const bool* hasStar, const THashSet<TStri
for (ui32 i = 0; i < x.Type->GetSize(); ++i) {
auto item = x.Type->GetItems()[i];
if (!item->GetName().StartsWith("_yql_")) {
+ item = AddAlias(x.Alias, item, ctx);
items.push_back(item);
}
}
@@ -1646,7 +1697,9 @@ void AddColumns(const TInputs& inputs, const bool* hasStar, const THashSet<TStri
auto pos = x.Type->FindItem(ref);
if (pos) {
- items.push_back(x.Type->GetItems()[*pos]);
+ auto item = x.Type->GetItems()[*pos];
+ item = AddAlias(x.Alias, item, ctx);
+ items.push_back(item);
usedRefs.insert(ref);
}
}
@@ -1659,7 +1712,9 @@ void AddColumns(const TInputs& inputs, const bool* hasStar, const THashSet<TStri
for (const auto& ref : qualifiedRefs->find(x.Alias)->second) {
auto pos = x.Type->FindItem(ref);
if (pos) {
- items.push_back(x.Type->GetItems()[*pos]);
+ auto item = x.Type->GetItems()[*pos];
+ item = AddAlias(x.Alias, item, ctx);
+ items.push_back(item);
}
}
@@ -1671,6 +1726,14 @@ void AddColumns(const TInputs& inputs, const bool* hasStar, const THashSet<TStri
IGraphTransformer::TStatus RebuildLambdaColumns(const TExprNode::TPtr& root, const TExprNode::TPtr& argNode,
TExprNode::TPtr& newRoot, const TInputs& inputs, TExprNode::TPtr* expandedColumns, TExtContext& ctx) {
+ bool hasExternalInput = false;
+ for (const auto& i : inputs) {
+ if (i.External) {
+ hasExternalInput = true;
+ break;
+ }
+ }
+
TOptimizeExprSettings optSettings(nullptr);
optSettings.VisitChecker = [](const TExprNode& node) {
if (node.IsCallable("PgSubLink")) {
@@ -1693,7 +1756,8 @@ IGraphTransformer::TStatus RebuildLambdaColumns(const TExprNode::TPtr& root, con
for (const auto& item : x.Type->GetItems()) {
if (!item->GetName().StartsWith("_yql_")) {
if (!order) {
- orderAtoms.push_back(ctx.Expr.NewAtom(node->Pos(), item->GetName()));
+ orderAtoms.push_back(ctx.Expr.NewAtom(node->Pos(),
+ NTypeAnnImpl::MakeAliasedColumn(hasExternalInput ? x.Alias : "", item->GetName())));
}
}
}
@@ -1701,7 +1765,8 @@ IGraphTransformer::TStatus RebuildLambdaColumns(const TExprNode::TPtr& root, con
if (order) {
for (const auto& o : *order) {
if (!o.StartsWith("_yql_")) {
- orderAtoms.push_back(ctx.Expr.NewAtom(node->Pos(), o));
+ orderAtoms.push_back(ctx.Expr.NewAtom(node->Pos(),
+ NTypeAnnImpl::MakeAliasedColumn(hasExternalInput ? x.Alias : "", o)));
}
}
}
@@ -1716,12 +1781,31 @@ IGraphTransformer::TStatus RebuildLambdaColumns(const TExprNode::TPtr& root, con
}
if (node->IsCallable("PgColumnRef")) {
- return ctx.Expr.Builder(node->Pos())
- .Callable("Member")
- .Add(0, argNode)
- .Atom(1, node->Tail().Content())
- .Seal()
- .Build();
+ for (ui32 pass = 0; pass < 2; ++pass) {
+ for (const auto& x : inputs) {
+ if (!pass == x.External) {
+ continue;
+ }
+
+ if (node->ChildrenSize() == 2) {
+ if (x.Alias.empty() || node->Head().Content() != x.Alias) {
+ continue;
+ }
+ }
+
+ auto pos = x.Type->FindItem(node->Tail().Content());
+ if (pos) {
+ return ctx.Expr.Builder(node->Pos())
+ .Callable("Member")
+ .Add(0, argNode)
+ .Atom(1, MakeAliasedColumn(x.Alias, node->Tail().Content()))
+ .Seal()
+ .Build();
+ }
+ }
+ }
+
+ YQL_ENSURE(false, "Missing input");
}
if (node->IsCallable("PgQualifiedStar")) {
@@ -1741,15 +1825,16 @@ IGraphTransformer::TStatus RebuildLambdaColumns(const TExprNode::TPtr& root, con
for (const auto& item : x.Type->GetItems()) {
if (!item->GetName().StartsWith("_yql_")) {
if (!order) {
- orderAtoms.push_back(ctx.Expr.NewAtom(node->Pos(), item->GetName()));
+ orderAtoms.push_back(ctx.Expr.NewAtom(node->Pos(),
+ NTypeAnnImpl::MakeAliasedColumn(hasExternalInput ? x.Alias : "", item->GetName())));
}
members.push_back(ctx.Expr.Builder(node->Pos())
.List()
- .Atom(0, item->GetName())
+ .Atom(0, NTypeAnnImpl::MakeAliasedColumn(hasExternalInput ? x.Alias : "", item->GetName()))
.Callable(1, "Member")
.Add(0, argNode)
- .Atom(1, item->GetName())
+ .Atom(1, MakeAliasedColumn(x.Alias, item->GetName()))
.Seal()
.Seal()
.Build());
@@ -1759,7 +1844,8 @@ IGraphTransformer::TStatus RebuildLambdaColumns(const TExprNode::TPtr& root, con
if (order) {
for (const auto& o : *order) {
if (!o.StartsWith("_yql_")) {
- orderAtoms.push_back(ctx.Expr.NewAtom(node->Pos(), o));
+ orderAtoms.push_back(ctx.Expr.NewAtom(node->Pos(),
+ NTypeAnnImpl::MakeAliasedColumn(hasExternalInput ? x.Alias : "", o)));
}
}
}
@@ -1869,7 +1955,7 @@ bool ValidateGroups(TInputs& inputs, const THashSet<TString>& possibleAliases,
}
TVector<const TItemExprType*> items;
- AddColumns(inputs, nullptr, refs, &qualifiedRefs, items);
+ AddColumns(inputs, nullptr, refs, &qualifiedRefs, items, ctx.Expr);
auto effectiveType = ctx.Expr.MakeType<TStructExprType>(items);
if (!effectiveType->Validate(group->Pos(), ctx.Expr)) {
return false;
@@ -1911,7 +1997,7 @@ bool ValidateSort(TInputs& inputs, const THashSet<TString>& possibleAliases,
}
TVector<const TItemExprType*> items;
- AddColumns(inputs, nullptr, refs, &qualifiedRefs, items);
+ AddColumns(inputs, nullptr, refs, &qualifiedRefs, items, ctx.Expr);
auto effectiveType = ctx.Expr.MakeType<TStructExprType>(items);
if (!effectiveType->Validate(oneSort->Pos(), ctx.Expr)) {
return false;
@@ -2082,23 +2168,23 @@ IGraphTransformer::TStatus PgSetItemWrapper(const TExprNode::TPtr& input, TExprN
THashMap<TString, THashSet<TString>> qualifiedRefs;
if (column->Child(1)->IsCallable("Void")) {
// no effective type yet, scan lambda body
- TNodeSet sublinks;
- ScanSublinks(column->Tail().TailPtr(), sublinks);
+ TNodeSet sublinks;
+ ScanSublinks(column->Tail().TailPtr(), sublinks);
if (!ScanColumns(column->Tail().TailPtr(), joinInputs, possibleAliases, &hasStar, hasColumnRef,
refs, &qualifiedRefs, ctx)) {
return IGraphTransformer::TStatus::Error;
}
- bool needRebuildSubLinks;
+ bool needRebuildSubLinks;
if (!ScanColumnsForSublinks(needRebuildSubLinks, sublinks, joinInputs, possibleAliases,
- hasColumnRef, refs, &qualifiedRefs, ctx)) {
- return IGraphTransformer::TStatus::Error;
+ hasColumnRef, refs, &qualifiedRefs, ctx)) {
+ return IGraphTransformer::TStatus::Error;
}
if (!scanColumnsOnly) {
TVector<const TItemExprType*> items;
- AddColumns(joinInputs, &hasStar, refs, &qualifiedRefs, items);
+ AddColumns(joinInputs, &hasStar, refs, &qualifiedRefs, items, ctx.Expr);
auto effectiveType = ctx.Expr.MakeType<TStructExprType>(items);
if (!effectiveType->Validate(column->Pos(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
@@ -2110,12 +2196,12 @@ IGraphTransformer::TStatus PgSetItemWrapper(const TExprNode::TPtr& input, TExprN
if (needRebuildSubLinks) {
auto arguments = ctx.Expr.NewArguments(column->Pos(), { });
- TExprNode::TPtr newRoot;
- auto status = RebuildSubLinks(column->Tail().TailPtr(), newRoot, sublinks, joinInputs, typeNode, ctx);
- if (status == IGraphTransformer::TStatus::Error) {
- return IGraphTransformer::TStatus::Error;
- }
-
+ TExprNode::TPtr newRoot;
+ auto status = RebuildSubLinks(column->Tail().TailPtr(), newRoot, sublinks, joinInputs, typeNode, ctx);
+ if (status == IGraphTransformer::TStatus::Error) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
auto newLambda = ctx.Expr.NewLambda(column->Pos(), std::move(arguments), std::move(newRoot));
newColumnChildren[2] = newLambda;
} else {
@@ -2142,11 +2228,10 @@ IGraphTransformer::TStatus PgSetItemWrapper(const TExprNode::TPtr& input, TExprN
else {
if (column->Head().IsAtom()) {
outputItems.push_back(ctx.Expr.MakeType<TItemExprType>(column->Head().Content(), column->Tail().GetTypeAnn()));
- }
- else {
+ } else {
// star or qualified star
for (const auto& item : column->Tail().GetTypeAnn()->Cast<TStructExprType>()->GetItems()) {
- outputItems.push_back(item);
+ outputItems.push_back(hasExtTypes ? item : RemoveAlias(item, ctx.Expr));
}
}
@@ -2320,20 +2405,21 @@ IGraphTransformer::TStatus PgSetItemWrapper(const TExprNode::TPtr& input, TExprN
bool hasColumnRef;
THashSet<TString> refs;
+ THashMap<TString, THashSet<TString>> qualifiedRefs;
if (!ScanColumns(data.Child(1)->TailPtr(), joinInputs, possibleAliases, nullptr, hasColumnRef,
- refs, nullptr, ctx)) {
+ refs, &qualifiedRefs, ctx)) {
return IGraphTransformer::TStatus::Error;
}
bool needRebuildSubLinks;
if (!ScanColumnsForSublinks(needRebuildSubLinks, sublinks, joinInputs, possibleAliases, hasColumnRef,
- refs, nullptr, ctx)) {
+ refs, &qualifiedRefs, ctx)) {
return IGraphTransformer::TStatus::Error;
}
if (!scanColumnsOnly) {
TVector<const TItemExprType*> items;
- AddColumns(joinInputs, nullptr, refs, nullptr, items);
+ AddColumns(joinInputs, nullptr, refs, &qualifiedRefs, items, ctx.Expr);
auto effectiveType = ctx.Expr.MakeType<TStructExprType>(items);
if (!effectiveType->Validate(data.Pos(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
@@ -2531,14 +2617,15 @@ IGraphTransformer::TStatus PgSetItemWrapper(const TExprNode::TPtr& input, TExprN
const auto& quals = child->Tail();
bool hasColumnRef;
THashSet<TString> refs;
+ THashMap<TString, THashSet<TString>> qualifiedRefs;
if (!ScanColumns(quals.Child(1)->TailPtr(), groupInputs, groupPossibleAliases, nullptr, hasColumnRef,
- refs, nullptr, ctx)) {
+ refs, &qualifiedRefs, ctx)) {
return IGraphTransformer::TStatus::Error;
}
if (!scanColumnsOnly) {
TVector<const TItemExprType*> items;
- AddColumns(groupInputs, nullptr, refs, nullptr, items);
+ AddColumns(groupInputs, nullptr, refs, &qualifiedRefs, items, ctx.Expr);
auto effectiveType = ctx.Expr.MakeType<TStructExprType>(items);
if (!effectiveType->Validate(quals.Pos(), ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
diff --git a/ydb/library/yql/core/type_ann/type_ann_pg.h b/ydb/library/yql/core/type_ann/type_ann_pg.h
index 7543801f9b..8d985e3ec5 100644
--- a/ydb/library/yql/core/type_ann/type_ann_pg.h
+++ b/ydb/library/yql/core/type_ann/type_ann_pg.h
@@ -8,6 +8,12 @@
namespace NYql {
namespace NTypeAnnImpl {
+TString MakeAliasedColumn(TStringBuf alias, TStringBuf column);
+const TItemExprType* AddAlias(const TString& alias, const TItemExprType* item, TExprContext& ctx);
+TStringBuf RemoveAlias(TStringBuf column);
+TStringBuf RemoveAlias(TStringBuf column, TStringBuf& alias);
+const TItemExprType* RemoveAlias(const TItemExprType* item, TExprContext& ctx);
+
IGraphTransformer::TStatus PgStarWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
IGraphTransformer::TStatus PgCallWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx);
IGraphTransformer::TStatus PgBoolOpWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);