Skip to content

Commit

Permalink
[Fix](Nereids) fix leading hint should have all tables in one query b…
Browse files Browse the repository at this point in the history
…lock (#33517) (#35272)
  • Loading branch information
LiBinfeng-01 authored May 23, 2024
1 parent a30ded0 commit 24d8481
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 31 deletions.
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 @@ -191,14 +190,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 @@ -252,24 +251,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 @@ -565,27 +587,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 @@ -46,7 +46,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
50 changes: 50 additions & 0 deletions regression-test/data/nereids_p0/hint/fix_leading.out
Original file line number Diff line number Diff line change
Expand Up @@ -226,3 +226,53 @@ SyntaxError:

-- !select4_2 --
1000

-- !select4_3 --
PhysicalResultSink
--hashAgg[GLOBAL]
----hashAgg[LOCAL]
------PhysicalProject
--------NestedLoopJoin[RIGHT_OUTER_JOIN](t3.c3 > 500)
----------PhysicalDistribute[DistributionSpecGather]
------------PhysicalProject
--------------NestedLoopJoin[LEFT_OUTER_JOIN](t1.c1 < 200)(t1.c1 > 500)
----------------PhysicalProject
------------------PhysicalOlapScan[t1]
----------------PhysicalDistribute[DistributionSpecReplicated]
------------------PhysicalProject
--------------------filter((t2.c2 > 500))
----------------------PhysicalOlapScan[t2]
----------PhysicalDistribute[DistributionSpecGather]
------------PhysicalProject
--------------PhysicalOlapScan[t3]

Hint log:
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

5 changes: 5 additions & 0 deletions regression-test/suites/nereids_p0/hint/fix_leading.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -166,4 +166,9 @@ suite("fix_leading") {
// check left right join result
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;"""

}

0 comments on commit 24d8481

Please sign in to comment.