Skip to content

Commit fd47cea

Browse files
authored
Implement Using (#2544)
1 parent 69bc320 commit fd47cea

File tree

68 files changed

+1817
-143
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+1817
-143
lines changed

ydb/library/yql/core/common_opt/yql_co_pgselect.cpp

Lines changed: 109 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -911,7 +911,7 @@ void GatherUsedWindows(const TExprNode::TPtr& window, const TExprNode::TPtr& pro
911911

912912
TUsedColumns GatherUsedColumns(const TExprNode::TPtr& result, const TExprNode::TPtr& joinOps,
913913
const TExprNode::TPtr& filter, const TExprNode::TPtr& groupExprs, const TExprNode::TPtr& having, const TExprNode::TPtr& extraSortColumns,
914-
const TExprNode::TPtr& window, const TWindowsCtx& winCtx) {
914+
const TExprNode::TPtr& window, const TWindowsCtx& winCtx, TVector<std::pair<TString, TString>>& joinUsingColumns) {
915915
TUsedColumns usedColumns;
916916
for (const auto& x : result->Tail().Children()) {
917917
AddColumnsFromType(x->Child(1)->GetTypeAnn(), usedColumns);
@@ -924,6 +924,21 @@ TUsedColumns GatherUsedColumns(const TExprNode::TPtr& result, const TExprNode::T
924924
for (ui32 i = 0; i < groupTuple->ChildrenSize(); ++i) {
925925
auto join = groupTuple->Child(i);
926926
auto joinType = join->Child(0)->Content();
927+
if (join->ChildrenSize() > 2) {
928+
Y_ENSURE(join->ChildrenSize() > 3, "Excepted at least 4 args there");
929+
Y_ENSURE(join->Child(1)->IsAtom(), "Supported only USING clause there");
930+
Y_ENSURE(join->Child(1)->Content() == "using", "Supported only USING clause there");
931+
for (ui32 col = 0; col < join->Child(3)->ChildrenSize(); ++col) {
932+
auto lr = join->Child(3)->Child(col);
933+
if (lr->Child(0)->IsAtom()) {
934+
usedColumns.insert(std::make_pair(TString(lr->Child(0)->Content()), std::make_pair(Max<ui32>(), TString())));
935+
}
936+
usedColumns.insert(std::make_pair(TString(lr->Child(1)->Content()), std::make_pair(Max<ui32>(), TString())));
937+
usedColumns.erase(TString(join->Child(2)->Child(col)->Content()));
938+
joinUsingColumns.emplace_back(ToString(groupNo), join->Child(2)->Child(col)->Content());
939+
}
940+
continue;
941+
}
927942
if (joinType != "cross") {
928943
AddColumnsFromType(join->Tail().Child(0)->GetTypeAnn(), usedColumns);
929944
}
@@ -1519,6 +1534,85 @@ std::tuple<TVector<ui32>, TExprNode::TListType> BuildJoinGroups(TPositionHandle
15191534
current = cartesian;
15201535
continue;
15211536
}
1537+
if (join->ChildrenSize() > 2) {
1538+
Y_ENSURE(join->Child(1)->IsAtom(), "expected only USING clause when join_ops children size > 2");
1539+
Y_ENSURE(join->Child(1)->Content() == "using", "expected only USING clause when join_ops children size > 2");
1540+
Y_ENSURE(join->ChildrenSize() > 3 && join->Child(3)->IsList(), "Excepted list of aliased columns in USING join");
1541+
auto left = current;
1542+
auto right = with;
1543+
TExprNode::TListType leftColumns;
1544+
TExprNode::TListType rightColumns;
1545+
TExprNode::TListType toRemove;
1546+
for (auto& col: join->Child(3)->ChildrenList()) {
1547+
if (col->Child(0)->IsAtom()) {
1548+
leftColumns.push_back(col->Child(0));
1549+
} else {
1550+
toRemove.push_back(col->Child(0)->Child(0));
1551+
leftColumns.push_back(col->Child(0)->Child(0));
1552+
}
1553+
rightColumns.push_back(col->Child(1));
1554+
}
1555+
current = BuildEquiJoin(pos, joinType, left, right, leftColumns, rightColumns, ctx);
1556+
auto secondStruct = ctx.Builder(pos)
1557+
.Lambda()
1558+
.Param("row")
1559+
.Callable("AsStruct")
1560+
.Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
1561+
for (size_t i = 0; i < leftColumns.size(); ++i) {
1562+
parent.List(i)
1563+
.Add(0, join->Child(2)->Child(i))
1564+
.Callable(1, "Coalesce")
1565+
.Callable(0, "Member")
1566+
.Arg(0, "row")
1567+
.Add(1, leftColumns[i])
1568+
.Seal()
1569+
.Callable(1, "Member")
1570+
.Arg(0, "row")
1571+
.Add(1, rightColumns[i])
1572+
.Seal()
1573+
.Seal()
1574+
.Seal();
1575+
}
1576+
return parent;
1577+
})
1578+
.Seal()
1579+
.Seal()
1580+
.Build();
1581+
auto removeProjection = ctx.Builder(pos)
1582+
.Lambda()
1583+
.Param("row")
1584+
.Arg(0, "row")
1585+
.Seal().Build();
1586+
current = ctx.Builder(pos)
1587+
.Callable("OrderedMap")
1588+
.Add(0, current)
1589+
.Lambda(1)
1590+
.Param("row")
1591+
.Callable("FlattenMembers")
1592+
.List(0)
1593+
.Atom(0, "")
1594+
.Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& {
1595+
if (toRemove.size()) {
1596+
parent.Callable(1, "RemoveMembers")
1597+
.Arg(0, "row")
1598+
.Add(1, ctx.NewList(pos, std::move(toRemove)))
1599+
.Seal();
1600+
} else {
1601+
parent.Arg(1, "row");
1602+
}
1603+
return parent;
1604+
})
1605+
.Seal()
1606+
.List(1)
1607+
.Atom(0, "")
1608+
.Apply(1, secondStruct).With(0, "row").Seal()
1609+
.Seal()
1610+
.Seal()
1611+
.Seal()
1612+
.Seal()
1613+
.Build();
1614+
continue;
1615+
}
15221616

15231617
auto predicate = join->Tail().TailPtr();
15241618
if (!IsDepended(predicate->Tail(), predicate->Head().Head())) {
@@ -1709,7 +1803,7 @@ std::tuple<TVector<ui32>, TExprNode::TListType> BuildJoinGroups(TPositionHandle
17091803
}
17101804

17111805
TExprNode::TPtr BuildCrossJoinsBetweenGroups(TPositionHandle pos, const TExprNode::TListType& joinGroups,
1712-
const TUsedColumns& usedColumns, const TVector<ui32>& groupForIndex, TExprContext& ctx) {
1806+
const TUsedColumns& usedColumns, const TVector<ui32>& groupForIndex, TExprContext& ctx, const TVector<std::pair<TString, TString>>& joinUsingColumns) {
17131807
TExprNode::TListType args;
17141808
for (ui32 i = 0; i < joinGroups.size(); ++i) {
17151809
args.push_back(ctx.Builder(pos)
@@ -1742,6 +1836,16 @@ TExprNode::TPtr BuildCrossJoinsBetweenGroups(TPositionHandle pos, const TExprNod
17421836
.Build());
17431837
}
17441838

1839+
for (const auto& x: joinUsingColumns) {
1840+
settings.push_back(ctx.Builder(pos)
1841+
.List()
1842+
.Atom(0, "rename")
1843+
.Atom(1, x.first + "." + x.second)
1844+
.Atom(2, x.second)
1845+
.Seal()
1846+
.Build());
1847+
}
1848+
17451849
auto settingsNode = ctx.NewList(pos, std::move(settings));
17461850
args.push_back(settingsNode);
17471851
return ctx.NewCallable(pos, "EquiJoin", std::move(args));
@@ -3366,7 +3470,8 @@ TExprNode::TPtr ExpandPgSelectImpl(const TExprNode::TPtr& node, TExprContext& ct
33663470
cleanedInputs.push_back(list);
33673471
} else {
33683472
// extract all used columns
3369-
auto usedColumns = GatherUsedColumns(result, joinOps, filter, groupExprs, having, extraSortColumns, window, winCtx);
3473+
TVector<std::pair<TString, TString>> joinUsingColumns;
3474+
auto usedColumns = GatherUsedColumns(result, joinOps, filter, groupExprs, having, extraSortColumns, window, winCtx, joinUsingColumns);
33703475

33713476
// fill index of input for each column
33723477
FillInputIndices(from, finalExtTypes, usedColumns, optCtx);
@@ -3382,7 +3487,7 @@ TExprNode::TPtr ExpandPgSelectImpl(const TExprNode::TPtr& node, TExprContext& ct
33823487
if (joinGroups.size() == 1) {
33833488
list = joinGroups.front();
33843489
} else {
3385-
list = BuildCrossJoinsBetweenGroups(node->Pos(), joinGroups, usedColumns, groupForIndex, ctx);
3490+
list = BuildCrossJoinsBetweenGroups(node->Pos(), joinGroups, usedColumns, groupForIndex, ctx, joinUsingColumns);
33863491
}
33873492
}
33883493
}

0 commit comments

Comments
 (0)