Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -226,14 +225,14 @@ public RelationId findRelationIdAndTableName(String name) {
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() {
Expand Down Expand Up @@ -287,24 +286,47 @@ public Long getTotalBitmap() {
/**
* 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) {
this.setStatus(HintStatus.SYNTAX_ERROR);
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
Expand Down Expand Up @@ -612,27 +634,4 @@ private Long getBitmap(LogicalPlan root) {
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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public List<Rule> buildRules() {
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()) {
Expand Down
25 changes: 25 additions & 0 deletions regression-test/data/nereids_p0/hint/fix_leading.out
Original file line number Diff line number Diff line change
Expand Up @@ -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

4 changes: 2 additions & 2 deletions regression-test/data/nereids_p0/hint/multi_leading.out
Original file line number Diff line number Diff line change
Expand Up @@ -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:

Expand Down Expand Up @@ -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:

Expand Down
4 changes: 4 additions & 0 deletions regression-test/suites/nereids_p0/hint/fix_leading.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -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;"""

}
8 changes: 4 additions & 4 deletions regression-test/suites/nereids_p0/hint/multi_leading.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -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;"""
Expand Down