Browse Source

YQL-19571 fix FilterPushdownOverJoinOptionalSide
commit_hash:0de01a92df5a19ee8b6d1e1057a1b023e1fccbe9

lucius 2 days ago
parent
commit
611f446619

+ 16 - 5
yql/essentials/core/common_opt/yql_flatmap_over_join.cpp

@@ -128,7 +128,7 @@ bool IsRequiredAndFilteredSide(const TExprNode::TPtr& joinTree, const TJoinLabel
 TExprNode::TPtr ApplyJoinPredicate(const TExprNode::TPtr& predicate, const TExprNode::TPtr& filterInput,
 TExprNode::TPtr ApplyJoinPredicate(const TExprNode::TPtr& predicate, const TExprNode::TPtr& filterInput,
     const TExprNode::TPtr& args, const TJoinLabels& labels, const THashMap<ui32, THashMap<TString, TString>>& aliasedKeys,
     const TExprNode::TPtr& args, const TJoinLabels& labels, const THashMap<ui32, THashMap<TString, TString>>& aliasedKeys,
     const TMap<TStringBuf, TVector<TStringBuf>>& renameMap, bool onlyKeys,
     const TMap<TStringBuf, TVector<TStringBuf>>& renameMap, bool onlyKeys,
-    ui32 firstCandidate, ui32 inputIndex, bool ordered, bool substituteWithNulls, TExprContext& ctx
+    ui32 firstCandidate, ui32 inputIndex, bool ordered, bool substituteWithNulls, bool forceOptional, TExprContext& ctx
 ) {
 ) {
     return ctx.Builder(predicate->Pos())
     return ctx.Builder(predicate->Pos())
     .Callable(ordered ? "OrderedFilter" : "Filter")
     .Callable(ordered ? "OrderedFilter" : "Filter")
@@ -157,7 +157,8 @@ TExprNode::TPtr ApplyJoinPredicate(const TExprNode::TPtr& predicate, const TExpr
                             auto memberName = label.MemberName(part1, part2);
                             auto memberName = label.MemberName(part1, part2);
                             auto memberType = label.FindColumn(part1, part2);
                             auto memberType = label.FindColumn(part1, part2);
                             Y_ENSURE(memberType);
                             Y_ENSURE(memberType);
-                            const TTypeAnnotationNode* optMemberType = ((*memberType)->IsOptionalOrNull()) ? *memberType : ctx.MakeType<TOptionalExprType>(*memberType);
+                            const bool memberIsOptional = (*memberType)->IsOptionalOrNull();
+                            const TTypeAnnotationNode* optMemberType = memberIsOptional ? *memberType : ctx.MakeType<TOptionalExprType>(*memberType);
 
 
                             if (auto renamed = renameMap.FindPtr(targetColumns[0])) {
                             if (auto renamed = renameMap.FindPtr(targetColumns[0])) {
                                 if (renamed->empty()) {
                                 if (renamed->empty()) {
@@ -179,6 +180,16 @@ TExprNode::TPtr ApplyJoinPredicate(const TExprNode::TPtr& predicate, const TExpr
                                             .Add(0, typeNode)
                                             .Add(0, typeNode)
                                         .Seal()
                                         .Seal()
                                     .Seal();
                                     .Seal();
+                                } else if (forceOptional && !memberIsOptional) {
+                                    parent.List(index++)
+                                        .Atom(0, targetColumn)
+                                        .Callable(1, "Just")
+                                            .Callable(0, "Member")
+                                                .Arg(0, "row")
+                                                .Atom(1, memberName)
+                                            .Seal()
+                                        .Seal()
+                                    .Seal();
                                 } else {
                                 } else {
                                     parent.List(index++)
                                     parent.List(index++)
                                         .Atom(0, targetColumn)
                                         .Atom(0, targetColumn)
@@ -286,7 +297,7 @@ TExprNode::TPtr SingleInputPredicatePushdownOverEquiJoin(TExprNode::TPtr equiJoi
         // then apply predicate
         // then apply predicate
         newInput = ApplyJoinPredicate(
         newInput = ApplyJoinPredicate(
             predicate, /*filterInput=*/newInput, args, labels, aliasedKeys, renameMap, onlyKeys,
             predicate, /*filterInput=*/newInput, args, labels, aliasedKeys, renameMap, onlyKeys,
-            firstCandidate, inputIndex, ordered, /*substituteWithNulls=*/false, ctx
+            firstCandidate, inputIndex, ordered, /*substituteWithNulls=*/false, /*forceOptional=*/false, ctx
         );
         );
 
 
         // then return reassembled join
         // then return reassembled join
@@ -415,7 +426,7 @@ TExprNode::TPtr FilterPushdownOverJoinOptionalSide(TExprNode::TPtr equiJoin, TEx
     // then apply predicate
     // then apply predicate
     auto filteredInput = ApplyJoinPredicate(
     auto filteredInput = ApplyJoinPredicate(
         predicate, /*filterInput=*/rightSideInput, args, labels, {}, renameMap, onlyKeys,
         predicate, /*filterInput=*/rightSideInput, args, labels, {}, renameMap, onlyKeys,
-        inputIndex, inputIndex, ordered, /*substituteWithNulls=*/false, ctx
+        inputIndex, inputIndex, ordered, /*substituteWithNulls=*/false, /*forceOptional=*/true, ctx
     );
     );
 
 
     // then create unionall of two joins.
     // then create unionall of two joins.
@@ -469,7 +480,7 @@ TExprNode::TPtr FilterPushdownOverJoinOptionalSide(TExprNode::TPtr equiJoin, TEx
     //extend left only join with nulls as left part and apply same predicate
     //extend left only join with nulls as left part and apply same predicate
     auto nullPredicateFilter = ApplyJoinPredicate(
     auto nullPredicateFilter = ApplyJoinPredicate(
         predicate, /*filterInput=*/leftOnlyJoin, args, labels, {}, renameMap, onlyKeys,
         predicate, /*filterInput=*/leftOnlyJoin, args, labels, {}, renameMap, onlyKeys,
-        inputIndex, inputIndex, ordered, /*substituteWithNulls=*/true, ctx
+        inputIndex, inputIndex, ordered, /*substituteWithNulls=*/true, /*forceOptional=*/false, ctx
     );
     );
 
 
     //then unite the results;
     //then unite the results;

+ 2 - 0
yt/yql/tests/sql/suites/join/left_join_right_pushdown_optional.cfg

@@ -0,0 +1,2 @@
+in Input1 left_join_input1.txt
+in Input2 left_join_input2.txt

+ 12 - 0
yt/yql/tests/sql/suites/join/left_join_right_pushdown_optional.sql

@@ -0,0 +1,12 @@
+PRAGMA FilterPushdownOverJoinOptionalSide;
+
+use plato;
+
+SELECT a.Key AS Key, a.Value AS Value, b.y AS RightValue
+FROM Input2 AS a
+LEFT JOIN (
+    SELECT Fk1 AS x, Value AS y
+    FROM Input1
+) AS b
+ON a.Key == b.x
+WHERE b.x >= "Name2";