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 90c69b020ad4cf1b7456c5bdfdbcaae3dbec7969
Author: LiBinfeng <46676950+libinfeng...@users.noreply.github.com>
AuthorDate: Fri Apr 12 15:06:02 2024 +0800

    [Fix](Nereids) fix leading hint should have all tables in one query block 
(#33517)
---
 .../org/apache/doris/nereids/hint/LeadingHint.java | 59 +++++++++++-----------
 .../doris/nereids/rules/analysis/LeadingJoin.java  |  2 +-
 .../data/nereids_p0/hint/fix_leading.out           | 25 +++++++++
 .../data/nereids_p0/hint/multi_leading.out         |  4 +-
 .../suites/nereids_p0/hint/fix_leading.groovy      |  4 ++
 .../suites/nereids_p0/hint/multi_leading.groovy    |  8 +--
 6 files changed, 65 insertions(+), 37 deletions(-)

diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/hint/LeadingHint.java 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/hint/LeadingHint.java
index 1f48e4873cb..3ef5217566a 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/hint/LeadingHint.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/hint/LeadingHint.java
@@ -17,7 +17,6 @@
 
 package org.apache.doris.nereids.hint;
 
-import org.apache.doris.catalog.TableIf;
 import org.apache.doris.common.Pair;
 import org.apache.doris.nereids.jobs.joinorder.hypergraph.bitmap.LongBitmap;
 import org.apache.doris.nereids.trees.expressions.ExprId;
@@ -226,14 +225,14 @@ public class LeadingHint extends Hint {
         return null;
     }
 
-    private boolean hasSameName() {
+    private Optional<String> hasSameName() {
         Set<String> tableSet = Sets.newHashSet();
         for (String table : tablelist) {
             if (!tableSet.add(table)) {
-                return true;
+                return Optional.of(table);
             }
         }
-        return false;
+        return Optional.empty();
     }
 
     public Map<ExprId, String> getExprIdToTableNameMap() {
@@ -287,12 +286,14 @@ public class LeadingHint extends Hint {
     /**
      * set total bitmap used in leading before we get into leading join
      */
-    public void setTotalBitmap() {
+    public void setTotalBitmap(Set<RelationId> inputRelationSets) {
         Long totalBitmap = 0L;
-        if (hasSameName()) {
+        Optional<String> duplicateTableName = hasSameName();
+        if (duplicateTableName.isPresent()) {
             this.setStatus(HintStatus.SYNTAX_ERROR);
-            this.setErrorMessage("duplicated table");
+            this.setErrorMessage("duplicated table:" + 
duplicateTableName.get());
         }
+        Set<RelationId> existRelationSets = new HashSet<>();
         for (int index = 0; index < getTablelist().size(); index++) {
             RelationId id = 
findRelationIdAndTableName(getTablelist().get(index));
             if (id == null) {
@@ -300,11 +301,32 @@ public class LeadingHint extends Hint {
                 this.setErrorMessage("can not find table: " + 
getTablelist().get(index));
                 return;
             }
+            existRelationSets.add(id);
             totalBitmap = LongBitmap.set(totalBitmap, id.asInt());
         }
+        if (getTablelist().size() < inputRelationSets.size()) {
+            Set<RelationId> missRelationIds = new HashSet<>();
+            missRelationIds.addAll(inputRelationSets);
+            missRelationIds.removeAll(existRelationSets);
+            String missingTablenames = getMissingTableNames(missRelationIds);
+            this.setStatus(HintStatus.SYNTAX_ERROR);
+            this.setErrorMessage("leading should have all tables in query 
block, missing tables: " + missingTablenames);
+        }
         this.totalBitmap = totalBitmap;
     }
 
+    private String getMissingTableNames(Set<RelationId> missRelationIds) {
+        String missTableNames = "";
+        for (RelationId id : missRelationIds) {
+            for (Pair<RelationId, String> pair : relationIdAndTableName) {
+                if (pair.first.equals(id)) {
+                    missTableNames += pair.second + " ";
+                }
+            }
+        }
+        return missTableNames;
+    }
+
     /**
      * try to get join constraint, if can not get, it means join is inner join,
      * @param joinTableBitmap table bitmap below this join
@@ -612,27 +634,4 @@ public class LeadingHint extends Hint {
             return null;
         }
     }
-
-    /**
-     * get leading containing tables which means leading wants to combine 
tables into joins
-     * @return long value represent tables we included
-     */
-    public Long getLeadingTableBitmap(List<TableIf> tables) {
-        Long totalBitmap = 0L;
-        if (hasSameName()) {
-            this.setStatus(HintStatus.SYNTAX_ERROR);
-            this.setErrorMessage("duplicated table");
-            return totalBitmap;
-        }
-        for (int index = 0; index < getTablelist().size(); index++) {
-            RelationId id = 
findRelationIdAndTableName(getTablelist().get(index));
-            if (id == null) {
-                this.setStatus(HintStatus.SYNTAX_ERROR);
-                this.setErrorMessage("can not find table: " + 
getTablelist().get(index));
-                return totalBitmap;
-            }
-            totalBitmap = LongBitmap.set(totalBitmap, id.asInt());
-        }
-        return totalBitmap;
-    }
 }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/LeadingJoin.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/LeadingJoin.java
index c8b19a1e9d5..9e94c745f77 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/LeadingJoin.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/LeadingJoin.java
@@ -43,7 +43,7 @@ public class LeadingJoin implements RewriteRuleFactory {
                             return ctx.root;
                         }
                         Hint leadingHint = 
ctx.cascadesContext.getHintMap().get("Leading");
-                        ((LeadingHint) leadingHint).setTotalBitmap();
+                        ((LeadingHint) 
leadingHint).setTotalBitmap(ctx.root.getInputRelations());
                         Long currentBitMap = 
LongBitmap.computeTableBitmap(ctx.root.getInputRelations());
                         if (((LeadingHint) 
leadingHint).getTotalBitmap().equals(currentBitMap)
                                 && leadingHint.isSuccess()) {
diff --git a/regression-test/data/nereids_p0/hint/fix_leading.out 
b/regression-test/data/nereids_p0/hint/fix_leading.out
index 2a83ff6eafe..c7bfec92f2d 100644
--- a/regression-test/data/nereids_p0/hint/fix_leading.out
+++ b/regression-test/data/nereids_p0/hint/fix_leading.out
@@ -256,3 +256,28 @@ Used: leading(t1 t2 t3 )
 UnUsed:
 SyntaxError:
 
+-- !select5_1 --
+PhysicalResultSink
+--hashAgg[GLOBAL]
+----PhysicalDistribute[DistributionSpecGather]
+------hashAgg[LOCAL]
+--------PhysicalProject
+----------NestedLoopJoin[LEFT_OUTER_JOIN](t3.c3 > 500)
+------------PhysicalProject
+--------------PhysicalOlapScan[t3]
+------------PhysicalDistribute[DistributionSpecReplicated]
+--------------PhysicalProject
+----------------NestedLoopJoin[LEFT_OUTER_JOIN](t1.c1 > 500)
+------------------PhysicalProject
+--------------------filter((t1.c1 < 200))
+----------------------PhysicalOlapScan[t1]
+------------------PhysicalDistribute[DistributionSpecReplicated]
+--------------------PhysicalProject
+----------------------filter((t2.c2 > 500))
+------------------------PhysicalOlapScan[t2]
+
+Hint log:
+Used:
+UnUsed:
+SyntaxError: leading(t1 t2) Msg:leading should have all tables in query block, 
missing tables: t3 
+
diff --git a/regression-test/data/nereids_p0/hint/multi_leading.out 
b/regression-test/data/nereids_p0/hint/multi_leading.out
index 0efabe2002e..b602e97bcb9 100644
--- a/regression-test/data/nereids_p0/hint/multi_leading.out
+++ b/regression-test/data/nereids_p0/hint/multi_leading.out
@@ -264,7 +264,7 @@ PhysicalResultSink
 ----------------------PhysicalOlapScan[t1]
 
 Hint log:
-Used: leading(t2 t1 ) leading(t3 alias1 )
+Used: leading(t2 t1 ) leading(t3 alias1 cte )
 UnUsed:
 SyntaxError:
 
@@ -330,7 +330,7 @@ PhysicalResultSink
 ----------------------PhysicalOlapScan[t1]
 
 Hint log:
-Used: leading(t2 t1 ) leading(t2 t1 ) leading(t2 t1 ) leading(t3 alias1 )
+Used: leading(t2 t1 ) leading(t2 t1 ) leading(t2 t1 ) leading(t3 alias1 cte )
 UnUsed:
 SyntaxError:
 
diff --git a/regression-test/suites/nereids_p0/hint/fix_leading.groovy 
b/regression-test/suites/nereids_p0/hint/fix_leading.groovy
index 6185789d2ba..49823e97698 100644
--- a/regression-test/suites/nereids_p0/hint/fix_leading.groovy
+++ b/regression-test/suites/nereids_p0/hint/fix_leading.groovy
@@ -170,4 +170,8 @@ suite("fix_leading") {
     qt_select4_1 """select count(*) from t1 left join t2 on c1 > 500 and c2 
>500 right join t3 on c3 > 500 and c1 < 200;"""
     qt_select4_2 """select /*+ leading(t1 t2 t3)*/ count(*) from t1 left join 
t2 on c1 > 500 and c2 >500 right join t3 on c3 > 500 and c1 < 200;"""
     qt_select4_3 """explain shape plan select /*+ leading(t1 t2 t3)*/ count(*) 
from t1 left join t2 on c1 > 500 and c2 >500 right join t3 on c3 > 500 and c1 < 
200;"""
+
+    // check whether we have all tables
+    qt_select5_1 """explain shape plan select /*+ leading(t1 t2)*/ count(*) 
from t1 left join t2 on c1 > 500 and c2 >500 right join t3 on c3 > 500 and c1 < 
200;"""
+
 }
diff --git a/regression-test/suites/nereids_p0/hint/multi_leading.groovy 
b/regression-test/suites/nereids_p0/hint/multi_leading.groovy
index d1f83d15ebb..bd567ecdefa 100644
--- a/regression-test/suites/nereids_p0/hint/multi_leading.groovy
+++ b/regression-test/suites/nereids_p0/hint/multi_leading.groovy
@@ -98,14 +98,14 @@ suite("multi_leading") {
 
     // test subquery + cte
     qt_sql3_1 """explain shape plan with cte as (select c11, c1 from t1 join 
t2 on c1 = c2) select count(*) from (select c1, c11 from t1 join t2 on c1 = c2) 
as alias1 join t3 on alias1.c1 = t3.c3 join cte on alias1.c1 = cte.c11;"""
-    qt_sql3_2 """explain shape plan with cte as (select /*+ leading(t2 t1) */ 
c11, c1 from t1 join t2 on c1 = c2) select /*+ leading(t3 alias1) */ count(*) 
from (select c1, c11 from t1 join t2 on c1 = c2) as alias1 join t3 on alias1.c1 
= t3.c3 join cte on alias1.c1 = cte.c11;;"""
+    qt_sql3_2 """explain shape plan with cte as (select /*+ leading(t2 t1) */ 
c11, c1 from t1 join t2 on c1 = c2) select /*+ leading(t3 alias1 cte) */ 
count(*) from (select c1, c11 from t1 join t2 on c1 = c2) as alias1 join t3 on 
alias1.c1 = t3.c3 join cte on alias1.c1 = cte.c11;;"""
     qt_sql3_3 """explain shape plan with cte as (select c11, c1 from t1 join 
t2 on c1 = c2) select count(*) from (select /*+ leading(t2 t1) */ c1, c11 from 
t1 join t2 on c1 = c2) as alias1 join t3 on alias1.c1 = t3.c3 join cte on 
alias1.c1 = cte.c11;;"""
-    qt_sql3_4 """explain shape plan with cte as (select /*+ leading(t2 t1) */ 
c11, c1 from t1 join t2 on c1 = c2) select /*+ leading(t3 alias1) */ count(*) 
from (select /*+ leading(t2 t1) */ c1, c11 from t1 join t2 on c1 = c2) as 
alias1 join t3 on alias1.c1 = t3.c3 join cte on alias1.c1 = cte.c11;;"""
+    qt_sql3_4 """explain shape plan with cte as (select /*+ leading(t2 t1) */ 
c11, c1 from t1 join t2 on c1 = c2) select /*+ leading(t3 alias1 cte) */ 
count(*) from (select /*+ leading(t2 t1) */ c1, c11 from t1 join t2 on c1 = c2) 
as alias1 join t3 on alias1.c1 = t3.c3 join cte on alias1.c1 = cte.c11;;"""
 
     qt_sql3_res_1 """with cte as (select c11, c1 from t1 join t2 on c1 = c2) 
select count(*) from (select c1, c11 from t1 join t2 on c1 = c2) as alias1 join 
t3 on alias1.c1 = t3.c3 join cte on alias1.c1 = cte.c11;;"""
-    qt_sql3_res_2 """with cte as (select /*+ leading(t2 t1) */ c11, c1 from t1 
join t2 on c1 = c2) select /*+ leading(t3 alias1) */ count(*) from (select c1, 
c11 from t1 join t2 on c1 = c2) as alias1 join t3 on alias1.c1 = t3.c3 join cte 
on alias1.c1 = cte.c11;;"""
+    qt_sql3_res_2 """with cte as (select /*+ leading(t2 t1) */ c11, c1 from t1 
join t2 on c1 = c2) select /*+ leading(t3 alias1 cte) */ count(*) from (select 
c1, c11 from t1 join t2 on c1 = c2) as alias1 join t3 on alias1.c1 = t3.c3 join 
cte on alias1.c1 = cte.c11;;"""
     qt_sql3_res_3 """with cte as (select c11, c1 from t1 join t2 on c1 = c2) 
select count(*) from (select /*+ leading(t2 t1) */ c1, c11 from t1 join t2 on 
c1 = c2) as alias1 join t3 on alias1.c1 = t3.c3 join cte on alias1.c1 = 
cte.c11;;"""
-    qt_sql3_res_4 """with cte as (select /*+ leading(t2 t1) */ c11, c1 from t1 
join t2 on c1 = c2) select /*+ leading(t3 alias1) */ count(*) from (select /*+ 
leading(t2 t1) */ c1, c11 from t1 join t2 on c1 = c2) as alias1 join t3 on 
alias1.c1 = t3.c3 join cte on alias1.c1 = cte.c11;;"""
+    qt_sql3_res_4 """with cte as (select /*+ leading(t2 t1) */ c11, c1 from t1 
join t2 on c1 = c2) select /*+ leading(t3 alias1 cte) */ count(*) from (select 
/*+ leading(t2 t1) */ c1, c11 from t1 join t2 on c1 = c2) as alias1 join t3 on 
alias1.c1 = t3.c3 join cte on alias1.c1 = cte.c11;;"""
 
     // test multi level subqueries
     qt_sql4_0 """explain shape plan select count(*) from (select c1, c11 from 
t1 join (select c2, c22 from t2 join t4 on c2 = c4) as alias2 on c1 = 
alias2.c2) as alias1 join t3 on alias1.c1 = t3.c3;"""


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

Reply via email to