aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVitaly Stoyan <vitstn@gmail.com>2022-06-27 20:21:27 +0300
committerVitaly Stoyan <vitstn@gmail.com>2022-06-27 20:21:27 +0300
commitfd933a69ffe80751f2c260055db51b4462405266 (patch)
treea0def9486db0e626f399e221f2cb8f37799cf066
parentb90fe24b6d1352185510ba49a0828ce8a5b2a13d (diff)
downloadydb-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.cpp273
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);
}