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

gabriellee pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/master by this push:
     new 1d0fdff98a [Bug](sort) disable 2phase read for sort by expressions 
exclude slotref (#16460)
1d0fdff98a is described below

commit 1d0fdff98a2a31e113059ae98b056b5add036cd5
Author: lihangyu <15605149...@163.com>
AuthorDate: Tue Feb 7 19:42:54 2023 +0800

    [Bug](sort) disable 2phase read for sort by expressions exclude slotref 
(#16460)
    
    ```
    create table tbl1 (k1 varchar(100), k2 string) distributed by hash(k1) 
buckets 1 properties("replication_num" = "1");
    
    insert into tbl1 values(1, "alice");
    
    select cast(k1 as INT) as id from tbl1 order by id limit 2;
    ```
    
    The above query could pass `checkEnableTwoPhaseRead` since the order by 
element is SlotRef but actually it's an function call expr
---
 .../java/org/apache/doris/analysis/SelectStmt.java | 18 ++++++++++--
 .../org/apache/doris/planner/OriginalPlanner.java  |  4 +--
 regression-test/data/query_p0/sort/sort.out        | 32 ++++++++++++++++++++++
 regression-test/suites/query_p0/sort/sort.groovy   | 13 +++++++++
 4 files changed, 63 insertions(+), 4 deletions(-)

diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/SelectStmt.java 
b/fe/fe-core/src/main/java/org/apache/doris/analysis/SelectStmt.java
index 034717f886..bfb6286b43 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/SelectStmt.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/SelectStmt.java
@@ -128,6 +128,8 @@ public class SelectStmt extends QueryStmt {
     // For quick get condition for point query
     private Map<SlotRef, Expr> eqPredicates;
 
+    boolean isTwoPhaseOptEnabled = false;
+
     public SelectStmt(ValueList valueList, ArrayList<OrderByElement> 
orderByElement, LimitElement limitElement) {
         super(orderByElement, limitElement);
         this.valueList = valueList;
@@ -603,6 +605,7 @@ public class SelectStmt extends QueryStmt {
             // rest of resultExprs will be marked as `INVALID`, such columns 
will
             // be prevent from reading from ScanNode.Those columns will be 
finally
             // read by the second fetch phase
+            isTwoPhaseOptEnabled = true;
             LOG.debug("two phase read optimize enabled");
             // Expr.analyze(resultExprs, analyzer);
             Set<SlotRef> resultSlots = Sets.newHashSet();
@@ -620,10 +623,12 @@ public class SelectStmt extends QueryStmt {
                 // invalid slots will be pruned from reading from ScanNode
                 slot.setInvalid();
             }
+
             LOG.debug("resultsSlots {}", resultSlots);
             LOG.debug("orderingSlots {}", orderingSlots);
             LOG.debug("conjuntSlots {}", conjuntSlots);
         }
+        checkAndSetPointQuery();
         if (evaluateOrderBy) {
             createSortTupleInfo(analyzer);
         }
@@ -648,6 +653,10 @@ public class SelectStmt extends QueryStmt {
         }
     }
 
+    public boolean isTwoPhaseReadOptEnabled() {
+        return isTwoPhaseOptEnabled;
+    }
+
     // Check whether enable two phase read optimize, if enabled query will be 
devieded into two phase read:
     // 1. read conjuncts columns and order by columns along with an extra 
RowId column from ScanNode
     // 2. sort and filter data, and get final RowId column, spawn RPC to other 
BE to fetch final data
@@ -707,11 +716,12 @@ public class SelectStmt extends QueryStmt {
         // Rethink? implement more generic to support all exprs
         LOG.debug("getOrderingExprs {}", sortInfo.getOrderingExprs());
         LOG.debug("getOrderByElements {}", getOrderByElements());
-        for (OrderByElement orderby : getOrderByElements()) {
-            if (!(orderby.getExpr() instanceof SlotRef)) {
+        for (Expr sortExpr : sortInfo.getOrderingExprs()) {
+            if (!(sortExpr instanceof SlotRef)) {
                 return false;
             }
         }
+        isTwoPhaseOptEnabled = true;
         return true;
     }
 
@@ -2376,6 +2386,10 @@ public class SelectStmt extends QueryStmt {
         return eqPredicates;
     }
 
+    public boolean isPointQueryShortCircuit() {
+        return isPointQuery;
+    }
+
     // Check if it is a point query and set EQUAL predicates
     public boolean checkAndSetPointQuery() {
         if (isPointQuery) {
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/planner/OriginalPlanner.java 
b/fe/fe-core/src/main/java/org/apache/doris/planner/OriginalPlanner.java
index 21d5b18dbe..5f0abd125d 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/planner/OriginalPlanner.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/planner/OriginalPlanner.java
@@ -263,7 +263,7 @@ public class OriginalPlanner extends Planner {
                 LOG.debug("this isn't block query");
             }
             // Check SelectStatement if optimization condition satisfied
-            if (selectStmt.checkAndSetPointQuery()) {
+            if (selectStmt.isPointQueryShortCircuit()) {
                 // Optimize for point query like: SELECT * FROM t1 WHERE pk1 = 
1 and pk2 = 2
                 // such query will use direct RPC to do point query
                 LOG.debug("it's a point query");
@@ -276,7 +276,7 @@ public class OriginalPlanner extends Planner {
                     
analyzer.getPrepareStmt().cacheSerializedDescriptorTable(olapScanNode.getDescTable());
                     
analyzer.getPrepareStmt().cacheSerializedOutputExprs(rootFragment.getOutputExprs());
                 }
-            } else if (selectStmt.checkEnableTwoPhaseRead(analyzer)) {
+            } else if (selectStmt.isTwoPhaseReadOptEnabled()) {
                 // Optimize query like `SELECT ... FROM <tbl> WHERE ... ORDER 
BY ... LIMIT ...`
                 injectRowIdColumnSlot();
             }
diff --git a/regression-test/data/query_p0/sort/sort.out 
b/regression-test/data/query_p0/sort/sort.out
index 3d778981cc..c13b777bb9 100644
--- a/regression-test/data/query_p0/sort/sort.out
+++ b/regression-test/data/query_p0/sort/sort.out
@@ -12,3 +12,35 @@ true
 
 -- !sql --
 
+-- !sql --
+1
+2
+3
+4
+
+-- !sql --
+0
+0
+1
+1
+
+-- !sql --
+1
+2
+3
+4
+
+-- !sql --
+1
+2
+3
+4
+
+-- !sql --
+1
+2
+
+-- !sql --
+1
+2
+
diff --git a/regression-test/suites/query_p0/sort/sort.groovy 
b/regression-test/suites/query_p0/sort/sort.groovy
index 025ec3f198..016ef37dce 100644
--- a/regression-test/suites/query_p0/sort/sort.groovy
+++ b/regression-test/suites/query_p0/sort/sort.groovy
@@ -41,4 +41,17 @@ suite("sort") {
     LIMIT 110
     OFFSET 130
     """
+
+    sql """drop table if exists tbl1"""
+    sql """create table tbl1 (k1 varchar(100), k2 string) distributed by 
hash(k1) buckets 1 properties("replication_num" = "1");"""
+    sql """insert into tbl1 values(1, "alice");"""
+    sql """insert into tbl1 values(2, "bob");"""
+    sql """insert into tbl1 values(3, "mark");"""
+    sql """insert into tbl1 values(4, "thor");"""
+    qt_sql """select cast(k1 as INT) as id from tbl1 order by id;"""
+    qt_sql """select cast(k1 as INT) % 2 as id from tbl1 order by id;"""
+    qt_sql """select cast(k1 as BIGINT) as id from tbl1 order by id;"""
+    qt_sql """select cast(k1 as STRING) as id from tbl1 order by id;"""
+    qt_sql """select cast(k1 as INT) as id from tbl1 order by id limit 2"""
+    qt_sql """select cast(k1 as STRING) as id from tbl1 order by id limit 2"""
 }


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

Reply via email to