[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
This commit is contained in:
@ -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;
|
||||
}
|
||||
|
||||
@ -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;"
|
||||
|
||||
Reference in New Issue
Block a user