This is an automated email from the ASF dual-hosted git repository.

yiguolei pushed a commit to branch branch-1.2-lts
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/branch-1.2-lts by this push:
     new f0ee563cff [fix](planner)runtime filter shouldn't be pushed through 
window function node (#22506)
f0ee563cff is described below

commit f0ee563cff2b4f10594e59054ea9aabc429097bc
Author: starocean999 <[email protected]>
AuthorDate: Wed Aug 2 20:18:02 2023 +0800

    [fix](planner)runtime filter shouldn't be pushed through window function 
node (#22506)
---
 .../org/apache/doris/planner/RuntimeFilter.java    | 41 +++++++++++++++++++---
 1 file changed, 37 insertions(+), 4 deletions(-)

diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/planner/RuntimeFilter.java 
b/fe/fe-core/src/main/java/org/apache/doris/planner/RuntimeFilter.java
index ad92f2245f..0c4ab7ff20 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/planner/RuntimeFilter.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/planner/RuntimeFilter.java
@@ -32,6 +32,7 @@ import org.apache.doris.catalog.ScalarType;
 import org.apache.doris.catalog.Type;
 import org.apache.doris.common.FeConstants;
 import org.apache.doris.common.IdGenerator;
+import org.apache.doris.common.Pair;
 import org.apache.doris.qe.ConnectContext;
 import org.apache.doris.thrift.TRuntimeFilterDesc;
 import org.apache.doris.thrift.TRuntimeFilterType;
@@ -282,7 +283,7 @@ public final class RuntimeFilter {
         }
 
         targetExpr = targetExpr.getRealSlotRef();
-        Map<TupleId, List<SlotId>> targetSlots = getTargetSlots(analyzer, 
targetExpr);
+        Map<TupleId, List<SlotId>> targetSlots = getTargetSlots(analyzer, 
targetExpr, filterSrcNode.getChild(0));
         Preconditions.checkNotNull(targetSlots);
         if (targetSlots.isEmpty()) {
             return null;
@@ -332,7 +333,7 @@ public final class RuntimeFilter {
                 return null;
             }
 
-            Map<TupleId, List<SlotId>> targetSlots = getTargetSlots(analyzer, 
targetExpr);
+            Map<TupleId, List<SlotId>> targetSlots = getTargetSlots(analyzer, 
targetExpr, filterSrcNode.getChild(0));
             Preconditions.checkNotNull(targetSlots);
             if (targetSlots.isEmpty()) {
                 return null;
@@ -358,7 +359,7 @@ public final class RuntimeFilter {
      * or if applying the filter might lead to incorrect results.
      * Returns the slot id of the base table expected to use this target expr.
      */
-    private static Map<TupleId, List<SlotId>> getTargetSlots(Analyzer 
analyzer, Expr expr) {
+    private static Map<TupleId, List<SlotId>> getTargetSlots(Analyzer 
analyzer, Expr expr, PlanNode root) {
         // 'expr' is not a SlotRef and may contain multiple SlotRefs
         List<TupleId> tids = new ArrayList<>();
         List<SlotId> sids = new ArrayList<>();
@@ -460,7 +461,39 @@ public final class RuntimeFilter {
                 return Collections.emptyMap();
             }
         }
-        return slotsByTid;
+
+        // rf shouldn't push down through any analytic node
+        // remove the slots if there is any analytic node in the middle
+        Map<TupleId, List<SlotId>> result = new HashMap<>();
+        for (Map.Entry<TupleId, List<SlotId>> entry : slotsByTid.entrySet()) {
+            Pair<Boolean, Boolean> isValid =
+                    hasAnalyticNodeInSearchPath(entry.getKey(), root, false);
+            if (isValid.first && !isValid.second) {
+                result.put(entry.getKey(), entry.getValue());
+            }
+        }
+        return result;
+    }
+
+    /**
+     * deep first search the child having the corresponding tupleId
+     * and record if meets any analytic node during the search
+     * Returns Pair.first -> find a child's tupleId is id, Pair.second -> if 
met any analytic node during the search
+     */
+    private static Pair<Boolean, Boolean> hasAnalyticNodeInSearchPath(TupleId 
id, PlanNode parent,
+            boolean hasAnalyticParent) {
+        if (parent.getTupleIds().contains(id)) {
+            return Pair.of(true, hasAnalyticParent);
+        } else {
+            for (PlanNode child : parent.getChildren()) {
+                Pair<Boolean, Boolean> result = 
hasAnalyticNodeInSearchPath(id, child,
+                        hasAnalyticParent || parent instanceof 
AnalyticEvalNode);
+                if (result.first) {
+                    return result;
+                }
+            }
+        }
+        return Pair.of(false, false);
     }
 
     /**


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to