This is an automated email from the ASF dual-hosted git repository.
morrysnow 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 7e485874495 [Fix](Nereids) fix leading hint should have all tables in
one query block (#33517)
7e485874495 is described below
commit 7e485874495810c844d69e4b27f01091577ff231
Author: LiBinfeng <[email protected]>
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: [email protected]
For additional commands, e-mail: [email protected]