[bugfix](topn) fix topn optimzation wrong result for NULL values (#18121)

1. add PassNullPredicate to fix topn wrong result for NULL values
2. refactor RuntimePredicate to avoid using TCondition
3. refactor using ordering_exprs in fe and vsort_node
This commit is contained in:
Kang
2023-03-31 10:01:34 +08:00
committed by GitHub
parent 8be43857ef
commit 4e1e0ce06d
369 changed files with 3193 additions and 161 deletions

View File

@ -1004,7 +1004,9 @@ public class OlapScanNode extends ScanNode {
// olap order by key: a.b.c.d
// sort key: (a) (a,b) (a,b,c) (a,b,c,d) is ok
// (a,c) (a,c,d), (a,c,b) (a,c,f) (a,b,c,d,e)is NOT ok
List<Expr> sortExprs = sortNode.getSortInfo().getMaterializedOrderingExprs();
List<Expr> sortExprs = sortNode.getSortInfo().getOrigOrderingExprs();
List<Boolean> nullsFirsts = sortNode.getSortInfo().getNullsFirst();
List<Boolean> isAscOrders = sortNode.getSortInfo().getIsAscOrder();
if (sortExprs.size() > olapTable.getDataSortInfo().getColNum()) {
return false;
}
@ -1013,7 +1015,18 @@ public class OlapScanNode extends ScanNode {
Column tableKey = olapTable.getFullSchema().get(i);
// sort slot.
Expr sortExpr = sortExprs.get(i);
if (!(sortExpr instanceof SlotRef) || !tableKey.equals(((SlotRef) sortExpr).getColumn())) {
if (sortExpr instanceof SlotRef) {
SlotRef slotRef = (SlotRef) sortExpr;
if (tableKey.equals(slotRef.getColumn())) {
// ORDER BY DESC NULLS FIRST can not be optimized to only read file tail,
// since NULLS is at file head but data is at tail
if (tableKey.isAllowNull() && nullsFirsts.get(i) && !isAscOrders.get(i)) {
return false;
}
} else {
return false;
}
} else {
return false;
}
}

View File

@ -603,8 +603,8 @@ public class OriginalPlanner extends Planner {
if (child instanceof OlapScanNode && sortNode.getLimit() > 0
&& ConnectContext.get() != null && ConnectContext.get().getSessionVariable() != null
&& sortNode.getLimit() <= ConnectContext.get().getSessionVariable().topnOptLimitThreshold
&& sortNode.getSortInfo().getMaterializedOrderingExprs().size() > 0) {
Expr firstSortExpr = sortNode.getSortInfo().getMaterializedOrderingExprs().get(0);
&& sortNode.getSortInfo().getOrigOrderingExprs().size() > 0) {
Expr firstSortExpr = sortNode.getSortInfo().getOrigOrderingExprs().get(0);
if (firstSortExpr instanceof SlotRef && !firstSortExpr.getType().isStringType()
&& !firstSortExpr.getType().isFloatingPointType()) {
OlapScanNode scanNode = (OlapScanNode) child;