diff options
author | Vitaly Stoyan <vitstn@gmail.com> | 2022-06-27 20:21:27 +0300 |
---|---|---|
committer | Vitaly Stoyan <vitstn@gmail.com> | 2022-06-27 20:21:27 +0300 |
commit | fd933a69ffe80751f2c260055db51b4462405266 (patch) | |
tree | a0def9486db0e626f399e221f2cb8f37799cf066 | |
parent | b90fe24b6d1352185510ba49a0828ce8a5b2a13d (diff) | |
download | ydb-fd933a69ffe80751f2c260055db51b4462405266.tar.gz |
YQL-13966 const predicate, equijoin for cartesian part
ref:62ff302cfdf97a1b8d24a6e4f3aafc4647e4cded
-rw-r--r-- | ydb/library/yql/core/common_opt/yql_co_pgselect.cpp | 273 |
1 files changed, 162 insertions, 111 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 c81feb38890..f509664b4a0 100644 --- a/ydb/library/yql/core/common_opt/yql_co_pgselect.cpp +++ b/ydb/library/yql/core/common_opt/yql_co_pgselect.cpp @@ -296,18 +296,18 @@ std::pair<TExprNode::TPtr, TExprNode::TPtr> RewriteSubLinks(TPositionHandle pos, .Build(); } } else { - auto fullColList = ctx.Builder(node->Pos())
- .List()
- .Do([&](TExprNodeBuilder &parent) -> TExprNodeBuilder & {
- ui32 i = 0;
- for (const auto& c : extColumns) {
- parent.Atom(i++, c);
- }
-
- return parent;
- })
- .Seal()
- .Build();
+ auto fullColList = ctx.Builder(node->Pos()) + .List() + .Do([&](TExprNodeBuilder &parent) -> TExprNodeBuilder & { + ui32 i = 0; + for (const auto& c : extColumns) { + parent.Atom(i++, c); + } + + return parent; + }) + .Seal() + .Build(); auto select = ExpandPgSelectSublink(node->TailPtr(), ctx, optCtx, it->second, cleanedInputs, inputAliases); @@ -869,6 +869,72 @@ TExprNode::TListType BuildCleanedColumns(TPositionHandle pos, const TExprNode::T return cleanedInputs; } +TExprNode::TPtr BuildMinus(TPositionHandle pos, const TExprNode::TPtr& left, const TExprNode::TPtr& right, const TExprNode::TPtr& predicate, TExprContext& ctx) { + return ctx.Builder(pos) + .Callable("Filter") + .Add(0, left) + .Lambda(1) + .Param("x") + .Callable(0, "Not") + .Callable(0, "HasItems") + .Callable(0, "Filter") + .Add(0, right) + .Lambda(1) + .Param("y") + .Callable("Coalesce") + .Callable(0, "FromPg") + .Apply(0, predicate) + .With(0) + .Callable("FlattenMembers") + .List(0) + .Atom(0, "") + .Arg(1,"x") + .Seal() + .List(1) + .Atom(0, "") + .Arg(1, "y") + .Seal() + .Seal() + .Done() + .Seal() + .Seal() + .Callable(1, "Bool") + .Atom(0, "0") + .Seal() + .Seal() + .Seal() + .Seal() + .Seal() + .Seal() + .Seal() + .Seal() + .Build(); +} + +TExprNode::TPtr BuildScalarMinus(TPositionHandle pos, const TExprNode::TPtr& left, const TExprNode::TPtr& right, + const TExprNode::TPtr& coalescedPredicate, TExprContext& ctx) { + return ctx.Builder(pos) + .Callable("If") + .Callable(0, "Or") + .Callable(0, "Not") + .Add(0, coalescedPredicate) + .Seal() + .Callable(1, "==") + .Callable(0, "Length") + .Add(0, right) + .Seal() + .Callable(1, "Uint64") + .Atom(0, "0") + .Seal() + .Seal() + .Seal() + .Add(1, left) + .Callable(2, "EmptyList") + .Seal() + .Seal() + .Build(); +} + std::tuple<TVector<ui32>, TExprNode::TListType> BuildJoinGroups(TPositionHandle pos, const TExprNode::TListType& cleanedInputs, const TExprNode::TPtr& joinOps, TExprContext& ctx, TOptimizeContext& optCtx) { TVector<ui32> groupForIndex; @@ -890,94 +956,79 @@ std::tuple<TVector<ui32>, TExprNode::TListType> BuildJoinGroups(TPositionHandle // current = join current & with auto join = groupTuple->Child(i); auto joinType = join->Child(0)->Content(); - auto cartesian = ctx.Builder(pos) - .Callable("FlatMap") - .Add(0, current) - .Lambda(1) - .Param("x") - .Callable("Map") - .Add(0, with) - .Lambda(1) - .Param("y") - .Callable("FlattenMembers") - .List(0) - .Atom(0, "") - .Arg(1,"x") - .Seal() - .List(1) - .Atom(0, "") - .Arg(1, "y") - .Seal() - .Seal() - .Seal() - .Seal() + auto cartesian = JoinColumns(pos, current, with, nullptr, 0, ctx); + if (joinType == "cross") { + current = cartesian; + continue; + } + + auto predicate = join->Tail().TailPtr(); + if (!IsDepended(predicate->Tail(), predicate->Head().Head())) { + auto coalescedPredicate = ctx.Builder(pos) + .Callable("Coalesce") + .Callable(0, "FromPg") + .Add(0, predicate->TailPtr()) + .Seal() + .Callable(1, "Bool") + .Atom(0, "0") .Seal() .Seal() .Build(); - auto buildMinus = [&](auto left, auto right) { - return ctx.Builder(pos) - .Callable("Filter") - .Add(0, left) - .Lambda(1) - .Param("x") - .Callable(0, "Not") - .Callable(0, "HasItems") - .Callable(0, "Filter") - .Add(0, right) - .Lambda(1) - .Param("y") - .Callable("Coalesce") - .Callable(0, "FromPg") - .Apply(0, join->Tail().TailPtr()) - .With(0) - .Callable("FlattenMembers") - .List(0) - .Atom(0, "") - .Arg(1,"x") - .Seal() - .List(1) - .Atom(0, "") - .Arg(1, "y") - .Seal() - .Seal() - .Done() - .Seal() - .Seal() - .Callable(1, "Bool") - .Atom(0, "0") - .Seal() - .Seal() - .Seal() - .Seal() - .Seal() - .Seal() + auto main = ctx.Builder(pos) + .Callable("If") + .Add(0, coalescedPredicate) + .Add(1, cartesian) + .Callable(2, "EmptyList") .Seal() .Seal() .Build(); - }; - TExprNode::TPtr filteredCartesian; - if (joinType != "cross") { - filteredCartesian = BuildFilter(pos, cartesian, join->Tail().TailPtr(), {}, {}, ctx, optCtx); + if (joinType == "inner") { + current = main; + } else if (joinType == "left") { + current = ctx.Builder(pos) + .Callable("UnionAll") + .Add(0, main) + .Add(1, BuildScalarMinus(pos, current, with, coalescedPredicate, ctx)) + .Seal() + .Build(); + } else if (joinType == "right") { + current = ctx.Builder(pos) + .Callable("UnionAll") + .Add(0, main) + .Add(1, BuildScalarMinus(pos, with, current, coalescedPredicate, ctx)) + .Seal() + .Build(); + } else { + YQL_ENSURE(joinType == "full"); + current = ctx.Builder(pos) + .Callable("UnionAll") + .Add(0, main) + .Add(1, BuildScalarMinus(pos, current, with, coalescedPredicate, ctx)) + .Add(2, BuildScalarMinus(pos, with, current, coalescedPredicate, ctx)) + .Seal() + .Build(); + } + + continue; } - if (joinType == "cross") { - current = cartesian; - } else if (joinType == "inner") { + auto filteredCartesian = BuildFilter(pos, cartesian, predicate, {}, {}, ctx, optCtx); + if (joinType == "inner") { current = filteredCartesian; } else if (joinType == "left") { current = ctx.Builder(pos) .Callable("UnionAll") .Add(0, filteredCartesian) - .Add(1, buildMinus(current, with)) + .Add(1, BuildMinus(pos, current, with, predicate, ctx)) .Seal() .Build(); } else if (joinType == "right") { current = ctx.Builder(pos) .Callable("UnionAll") .Add(0, filteredCartesian) - .Add(1, buildMinus(with, current)) + .Add(1, BuildMinus(pos, with, current, predicate, ctx)) .Seal() .Build(); } else { @@ -985,8 +1036,8 @@ std::tuple<TVector<ui32>, TExprNode::TListType> BuildJoinGroups(TPositionHandle current = ctx.Builder(pos) .Callable("UnionAll") .Add(0, filteredCartesian) - .Add(1, buildMinus(current, with)) - .Add(2, buildMinus(with, current)) + .Add(1, BuildMinus(pos, current, with, predicate, ctx)) + .Add(2, BuildMinus(pos, with, current, predicate, ctx)) .Seal() .Build(); } @@ -1715,42 +1766,42 @@ TExprNode::TPtr JoinOuter(TPositionHandle pos, TExprNode::TPtr list, const auto& inputAlias = input->Head().Content(); YQL_ENSURE(inputAlias == outerInputAliases[index]); inputAliases.push_back(TString(inputAlias)); - cleanedInputs.push_back(outerInputs[index]);
+ cleanedInputs.push_back(outerInputs[index]); auto type = input->Tail().GetTypeAnn()->Cast<TTypeExprType>()->GetType()->Cast<TStructExprType>(); if (type->GetSize() == 0) { continue; } - auto colList = ctx.Builder(pos)
- .List()
- .Do([&](TExprNodeBuilder &parent) -> TExprNodeBuilder & {
- ui32 i = 0;
- for (const auto& item : type->GetItems()) {
- parent.Atom(i++, NTypeAnnImpl::MakeAliasedColumn(inputAlias, item->GetName()));
- }
-
- return parent;
- })
- .Seal()
- .Build();
-
- auto outerInput = ctx.Builder(pos)
- .Callable("ExtractMembers")
- .Add(0, outerInputs[index])
- .Add(1, colList)
- .Seal()
- .Build();
-
- auto uniqueOuterInput = ctx.Builder(pos)
- .Callable("Aggregate")
- .Add(0, outerInput)
- .Add(1, colList)
- .List(2)
- .Seal()
- .Seal()
- .Build();
-
+ auto colList = ctx.Builder(pos) + .List() + .Do([&](TExprNodeBuilder &parent) -> TExprNodeBuilder & { + ui32 i = 0; + for (const auto& item : type->GetItems()) { + parent.Atom(i++, NTypeAnnImpl::MakeAliasedColumn(inputAlias, item->GetName())); + } + + return parent; + }) + .Seal() + .Build(); + + auto outerInput = ctx.Builder(pos) + .Callable("ExtractMembers") + .Add(0, outerInputs[index]) + .Add(1, colList) + .Seal() + .Build(); + + auto uniqueOuterInput = ctx.Builder(pos) + .Callable("Aggregate") + .Add(0, outerInput) + .Add(1, colList) + .List(2) + .Seal() + .Seal() + .Build(); + list = JoinColumns(pos, list, uniqueOuterInput, nullptr, 0, ctx); } |