From c677d75fb7148a7e126279ddd0990e5696d2448b Mon Sep 17 00:00:00 2001 From: Evgeny Zverev Date: Fri, 28 Feb 2025 05:59:35 +0000 Subject: [PATCH] regularize coalesce pushdown --- .../opt/physical/kqp_opt_phy_olap_filter.cpp | 120 ++++++++---------- 1 file changed, 55 insertions(+), 65 deletions(-) diff --git a/ydb/core/kqp/opt/physical/kqp_opt_phy_olap_filter.cpp b/ydb/core/kqp/opt/physical/kqp_opt_phy_olap_filter.cpp index 98a90b683045..77e9170c6331 100644 --- a/ydb/core/kqp/opt/physical/kqp_opt_phy_olap_filter.cpp +++ b/ydb/core/kqp/opt/physical/kqp_opt_phy_olap_filter.cpp @@ -139,7 +139,7 @@ std::vector> ExtractComparisonParameters(const T TMaybeNode ComparisonPushdown(const std::vector>& parameters, const TCoCompare& predicate, TExprContext& ctx, TPositionHandle pos); [[maybe_unused]] -TMaybeNode YqlCoalescePushdown(const TCoCoalesce& coalesce, const TExprNode& argument, TExprContext& ctx) { +TMaybeNode CoalescePushdown(const TCoCoalesce& coalesce, const TExprNode& argument, TExprContext& ctx) { if (const auto params = ExtractBinaryFunctionParameters(coalesce, argument, ctx, coalesce.Pos())) { return Build(ctx, coalesce.Pos()) .Operator().Value("??", TNodeFlags::Default).Build() @@ -212,6 +212,53 @@ TMaybeNode JsonExistsPushdown(const TCoJsonExists& jsonExists, TExprC .Path(jsonExists.JsonPath().Cast()) .Done(); } +TMaybeNode SimplePredicatePushdown(const TCoCompare& predicate, const TExprNode& argument, TExprContext& ctx, TPositionHandle pos) +{ + const auto parameters = ExtractComparisonParameters(predicate, argument, ctx, pos); + if (parameters.empty()) { + return NullNode; + } + + return ComparisonPushdown(parameters, predicate, ctx, pos); +} + +TMaybeNode SafeCastPredicatePushdown(const TCoFlatMap& inputFlatmap, const TExprNode& argument, TExprContext& ctx, TPositionHandle pos) +{ + /* + * There are three ways of comparison in following format: + * + * FlatMap (LeftArgument, FlatMap(RightArgument(), Just(Predicate)) + * + * Examples: + * FlatMap (SafeCast(), FlatMap(Member(), Just(Comparison)) + * FlatMap (Member(), FlatMap(SafeCast(), Just(Comparison)) + * FlatMap (SafeCast(), FlatMap(SafeCast(), Just(Comparison)) + */ + auto left = ConvertComparisonNode(inputFlatmap.Input(), argument, ctx, pos); + if (left.empty()) { + return NullNode; + } + + auto flatmap = inputFlatmap.Lambda().Body().Cast(); + auto right = ConvertComparisonNode(flatmap.Input(), argument, ctx, pos); + if (right.empty()) { + return NullNode; + } + + auto predicate = flatmap.Lambda().Body().Cast().Input().Cast(); + + std::vector> parameters; + if (left.size() != right.size()) { + return NullNode; + } + + for (ui32 i = 0; i < left.size(); ++i) { + parameters.emplace_back(std::move(std::make_pair(left[i], right[i]))); + } + + return ComparisonPushdown(parameters, predicate, ctx, pos); +} + std::vector ConvertComparisonNode(const TExprBase& nodeIn, const TExprNode& argument, TExprContext& ctx, TPositionHandle pos) { @@ -299,7 +346,7 @@ std::vector ConvertComparisonNode(const TExprBase& nodeIn, const TExp } if (const auto maybeCoalesce = node.Maybe()) { - return YqlCoalescePushdown(maybeCoalesce.Cast(), argument, ctx); + return CoalescePushdown(maybeCoalesce.Cast(), argument, ctx); } if (const auto maybeCompare = node.Maybe()) { @@ -308,6 +355,11 @@ std::vector ConvertComparisonNode(const TExprBase& nodeIn, const TExp } } + if (const auto maybeFlatmap = node.Maybe()) { + return SafeCastPredicatePushdown(maybeFlatmap.Cast(), argument, ctx, pos); + } else if (auto maybePredicate = node.Maybe()) { + return SimplePredicatePushdown(maybePredicate.Cast(), argument, ctx, pos); + } if constexpr (NKikimr::NSsa::RuntimeVersion >= 5U) { return YqlApplyPushdown(node, argument, ctx); @@ -480,16 +532,6 @@ TMaybeNode ComparisonPushdown(const std::vector SimplePredicatePushdown(const TCoCompare& predicate, const TExprNode& argument, TExprContext& ctx, TPositionHandle pos) -{ - const auto parameters = ExtractComparisonParameters(predicate, argument, ctx, pos); - if (parameters.empty()) { - return NullNode; - } - - return ComparisonPushdown(parameters, predicate, ctx, pos); -} - // TODO: Check how to reduce columns if they are not needed. Unfortunately columnshard need columns list // for every column present in program even if it is not used in result set. //#define ENABLE_COLUMNS_PRUNING @@ -528,62 +570,10 @@ TMaybeNode ExistsPushdown(const TCoExists& exists, TExprContext& ctx, .Done(); } -TMaybeNode SafeCastPredicatePushdown(const TCoFlatMap& inputFlatmap, const TExprNode& argument, TExprContext& ctx, TPositionHandle pos) -{ - /* - * There are three ways of comparison in following format: - * - * FlatMap (LeftArgument, FlatMap(RightArgument(), Just(Predicate)) - * - * Examples: - * FlatMap (SafeCast(), FlatMap(Member(), Just(Comparison)) - * FlatMap (Member(), FlatMap(SafeCast(), Just(Comparison)) - * FlatMap (SafeCast(), FlatMap(SafeCast(), Just(Comparison)) - */ - auto left = ConvertComparisonNode(inputFlatmap.Input(), argument, ctx, pos); - if (left.empty()) { - return NullNode; - } - - auto flatmap = inputFlatmap.Lambda().Body().Cast(); - auto right = ConvertComparisonNode(flatmap.Input(), argument, ctx, pos); - if (right.empty()) { - return NullNode; - } - - auto predicate = flatmap.Lambda().Body().Cast().Input().Cast(); - - std::vector> parameters; - if (left.size() != right.size()) { - return NullNode; - } - - for (ui32 i = 0; i < left.size(); ++i) { - parameters.emplace_back(std::move(std::make_pair(left[i], right[i]))); - } - - return ComparisonPushdown(parameters, predicate, ctx, pos); -} - -TMaybeNode CoalescePushdown(const TCoCoalesce& coalesce, const TExprNode& argument, TExprContext& ctx, TPositionHandle pos) -{ - if (const auto node = YqlCoalescePushdown(coalesce, argument, ctx)) { - return node; - } - - auto predicate = coalesce.Predicate(); - if (const auto maybeFlatmap = predicate.Maybe()) { - return SafeCastPredicatePushdown(maybeFlatmap.Cast(), argument, ctx, pos); - } else if (auto maybePredicate = predicate.Maybe()) { - return SimplePredicatePushdown(maybePredicate.Cast(), argument, ctx, pos); - } - return NullNode; -} - TFilterOpsLevels PredicatePushdown(const TExprBase& predicate, const TExprNode& argument, TExprContext& ctx, TPositionHandle pos) { if (const auto maybeCoalesce = predicate.Maybe()) { - auto coalescePred = CoalescePushdown(maybeCoalesce.Cast(), argument, ctx, pos); + auto coalescePred = CoalescePushdown(maybeCoalesce.Cast(), argument, ctx); return TFilterOpsLevels(coalescePred); }