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

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

commit f62cdecc08bdc6cd3ec691f885034adcaa0706fd
Author: minghong <engle...@gmail.com>
AuthorDate: Fri Mar 22 20:53:30 2024 +0800

    [fix](Nereids) do not push down topn-filter through right/full outer join 
if the first orderkey is nulls first (#32633)
    
    * do not push down topn-filter through right/full outer join if the first 
order key is nulls first
---
 .../apache/doris/nereids/processor/post/TopNScanOpt.java | 16 +++++++++++++---
 .../suites/nereids_tpch_p0/tpch/topn-filter.groovy       | 15 +++++++++++++++
 2 files changed, 28 insertions(+), 3 deletions(-)

diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/processor/post/TopNScanOpt.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/processor/post/TopNScanOpt.java
index a9425cb715b..63754afe4df 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/processor/post/TopNScanOpt.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/processor/post/TopNScanOpt.java
@@ -22,6 +22,7 @@ import org.apache.doris.nereids.trees.expressions.Expression;
 import org.apache.doris.nereids.trees.expressions.SlotReference;
 import org.apache.doris.nereids.trees.plans.Plan;
 import org.apache.doris.nereids.trees.plans.SortPhase;
+import org.apache.doris.nereids.trees.plans.algebra.Join;
 import org.apache.doris.nereids.trees.plans.algebra.OlapScan;
 import org.apache.doris.nereids.trees.plans.physical.PhysicalCatalogRelation;
 import 
org.apache.doris.nereids.trees.plans.physical.PhysicalDeferMaterializeTopN;
@@ -89,7 +90,9 @@ public class TopNScanOpt extends PlanPostProcessor {
         if (! (firstKey instanceof SlotReference)) {
             return Optional.empty();
         }
-        OlapScan olapScan = findScanNodeBySlotReference(topN, (SlotReference) 
firstKey);
+
+        boolean nullsFirst = topN.getOrderKeys().get(0).isNullFirst();
+        OlapScan olapScan = findScanNodeBySlotReference(topN, (SlotReference) 
firstKey, nullsFirst);
         if (olapScan != null
                 && olapScan.getTable().isDupKeysOrMergeOnWrite()
                 && olapScan instanceof PhysicalCatalogRelation) {
@@ -99,7 +102,14 @@ public class TopNScanOpt extends PlanPostProcessor {
         return Optional.empty();
     }
 
-    private OlapScan findScanNodeBySlotReference(Plan root, SlotReference 
slot) {
+    private OlapScan findScanNodeBySlotReference(Plan root, SlotReference 
slot, boolean nullsFirst) {
+        // topn-filter cannot be pushed through right/full outer join if the 
first orderKey is nulls first
+        if (nullsFirst && root instanceof Join) {
+            Join join = (Join) root;
+            if (join.getJoinType().isRightOuterJoin() || 
join.getJoinType().isFullOuterJoin()) {
+                return null;
+            }
+        }
         OlapScan target = null;
         if (root instanceof OlapScan && root.getOutputSet().contains(slot)) {
             return (OlapScan) root;
@@ -109,7 +119,7 @@ public class TopNScanOpt extends PlanPostProcessor {
                 // TODO for union, topn-filter can be pushed down to all of 
its children.
                 Plan child = root.child(0);
                 if (!(child instanceof PhysicalWindow) && 
child.getOutputSet().contains(slot)) {
-                    target = findScanNodeBySlotReference(child, slot);
+                    target = findScanNodeBySlotReference(child, slot, 
nullsFirst);
                     if (target != null) {
                         return target;
                     }
diff --git a/regression-test/suites/nereids_tpch_p0/tpch/topn-filter.groovy 
b/regression-test/suites/nereids_tpch_p0/tpch/topn-filter.groovy
index 14733d1303f..3a29274a2fe 100644
--- a/regression-test/suites/nereids_tpch_p0/tpch/topn-filter.groovy
+++ b/regression-test/suites/nereids_tpch_p0/tpch/topn-filter.groovy
@@ -116,6 +116,21 @@ suite("topn-filter") {
     }
 
     qt_groupingsets "select n_regionkey, sum(n_nationkey) from nation group by 
grouping sets((n_regionkey)) order by n_regionkey limit 2;"
+    
+    explain {
+        sql "select * from nation right outer join region on r_regionkey = 
n_regionkey order by n_regionkey nulls first limit 1; "
+        notContains "TOPN OPT:"
+    }
+
+    explain {
+        sql "select * from nation right outer join region on r_regionkey = 
n_regionkey order by n_regionkey nulls last limit 1; "
+        contains "TOPN OPT:"
+    }
+
+    explain {
+        sql "select * from nation right outer join region on r_regionkey = 
n_regionkey order by n_regionkey nulls last, n_name nulls first limit 1; "
+        contains "TOPN OPT:"
+    }
 
     sql "set enable_pipeline_engine=false;"
     sql "set enable_pipeline_x_engine=false;"


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org
For additional commands, e-mail: commits-h...@doris.apache.org

Reply via email to