Skip to content

Commit 1ef8605

Browse files
qw4990ti-chi-bot
authored andcommitted
This is an automated cherry-pick of #45587
Signed-off-by: ti-chi-bot <[email protected]>
1 parent 5a5cad1 commit 1ef8605

File tree

2 files changed

+73
-49
lines changed

2 files changed

+73
-49
lines changed

planner/core/exhaust_physical_plans.go

Lines changed: 70 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1845,40 +1845,77 @@ func filterIndexJoinBySessionVars(sc sessionctx.Context, indexJoins []PhysicalPl
18451845
return indexJoins
18461846
}
18471847

1848-
// tryToGetIndexJoin will get index join by hints. If we can generate a valid index join by hint, the second return value
1849-
// will be true, which means we force to choose this index join. Otherwise we will select a join algorithm with min-cost.
1850-
func (p *LogicalJoin) tryToGetIndexJoin(prop *property.PhysicalProperty) (indexJoins []PhysicalPlan, canForced bool) {
1851-
inljRightOuter := (p.preferJoinType & preferLeftAsINLJInner) > 0
1852-
inljLeftOuter := (p.preferJoinType & preferRightAsINLJInner) > 0
1853-
hasINLJHint := inljLeftOuter || inljRightOuter
1848+
func (p *LogicalJoin) preferAny(joinFlags ...uint) bool {
1849+
for _, flag := range joinFlags {
1850+
if p.preferJoinType&flag > 0 {
1851+
return true
1852+
}
1853+
}
1854+
return false
1855+
}
18541856

1855-
inlhjRightOuter := (p.preferJoinType & preferLeftAsINLHJInner) > 0
1856-
inlhjLeftOuter := (p.preferJoinType & preferRightAsINLHJInner) > 0
1857-
hasINLHJHint := inlhjLeftOuter || inlhjRightOuter
1857+
// satisfyIndexJoinHint returns whether this join plan can satisfy current index join hints.
1858+
func (p *LogicalJoin) satisfyIndexJoinHint(join PhysicalPlan) bool {
1859+
const left, right = 0, 1
1860+
const indexJoin, indexHashJoin, indexMergeJoin = 0, 1, 2
1861+
var innerSide, innerIdx, joinMethod int
1862+
switch ij := join.(type) {
1863+
case *PhysicalIndexJoin:
1864+
innerIdx = ij.getInnerChildIdx()
1865+
joinMethod = indexJoin
1866+
case *PhysicalIndexHashJoin:
1867+
innerIdx = ij.getInnerChildIdx()
1868+
joinMethod = indexHashJoin
1869+
case *PhysicalIndexMergeJoin:
1870+
innerIdx = ij.getInnerChildIdx()
1871+
joinMethod = indexMergeJoin
1872+
default:
1873+
return false
1874+
}
1875+
innerSide = left
1876+
if innerIdx == 1 {
1877+
innerSide = right
1878+
}
18581879

1859-
inlmjRightOuter := (p.preferJoinType & preferLeftAsINLMJInner) > 0
1860-
inlmjLeftOuter := (p.preferJoinType & preferRightAsINLMJInner) > 0
1861-
hasINLMJHint := inlmjLeftOuter || inlmjRightOuter
1880+
if (p.preferAny(preferLeftAsINLJInner) && innerSide == left && joinMethod == indexJoin) ||
1881+
(p.preferAny(preferRightAsINLJInner) && innerSide == right && joinMethod == indexJoin) ||
1882+
(p.preferAny(preferLeftAsINLHJInner) && innerSide == left && joinMethod == indexHashJoin) ||
1883+
(p.preferAny(preferRightAsINLHJInner) && innerSide == right && joinMethod == indexHashJoin) ||
1884+
(p.preferAny(preferLeftAsINLMJInner) && innerSide == left && joinMethod == indexMergeJoin) ||
1885+
(p.preferAny(preferRightAsINLMJInner) && innerSide == right && joinMethod == indexMergeJoin) {
1886+
return true
1887+
}
1888+
return false
1889+
}
18621890

1863-
forceLeftOuter := inljLeftOuter || inlhjLeftOuter || inlmjLeftOuter
1864-
forceRightOuter := inljRightOuter || inlhjRightOuter || inlmjRightOuter
1891+
// tryToGetIndexJoin will get index join by hints. If we can generate a valid index join by hint, the second return value
1892+
// will be true, which means we force to choose this index join. Otherwise we will select a join algorithm with min-cost.
1893+
func (p *LogicalJoin) tryToGetIndexJoin(prop *property.PhysicalProperty) (indexJoins []PhysicalPlan, canForced bool) {
1894+
forceLeftOuter := p.preferAny(preferRightAsINLJInner, preferRightAsINLHJInner, preferRightAsINLMJInner) // left as outer == right as inner
1895+
forceRightOuter := p.preferAny(preferLeftAsINLJInner, preferLeftAsINLHJInner, preferLeftAsINLMJInner) // right as outer == left as inner
18651896
needForced := forceLeftOuter || forceRightOuter
18661897

18671898
defer func() {
1868-
// refine error message
1899+
// Print warning message if any hints cannot work.
18691900
// If the required property is not empty, we will enforce it and try the hint again.
18701901
// So we only need to generate warning message when the property is empty.
18711902
if !canForced && needForced && prop.IsSortItemEmpty() {
18721903
// Construct warning message prefix.
1904+
var indexJoinTables, indexHashJoinTables, indexMergeJoinTables []hintTableInfo
1905+
if p.hintInfo != nil {
1906+
t := p.hintInfo.indexNestedLoopJoinTables
1907+
indexJoinTables, indexHashJoinTables, indexMergeJoinTables = t.inljTables, t.inlhjTables, t.inlmjTables
1908+
}
18731909
var errMsg string
18741910
switch {
1875-
case hasINLJHint:
1876-
errMsg = "Optimizer Hint INL_JOIN or TIDB_INLJ is inapplicable"
1877-
case hasINLHJHint:
1878-
errMsg = "Optimizer Hint INL_HASH_JOIN is inapplicable"
1879-
case hasINLMJHint:
1880-
errMsg = "Optimizer Hint INL_MERGE_JOIN is inapplicable"
1881-
}
1911+
case p.preferAny(preferLeftAsINLJInner, preferRightAsINLJInner): // prefer index join
1912+
errMsg = fmt.Sprintf("Optimizer Hint %s or %s is inapplicable", restore2JoinHint(HintINLJ, indexJoinTables), restore2JoinHint(TiDBIndexNestedLoopJoin, indexJoinTables))
1913+
case p.preferAny(preferLeftAsINLHJInner, preferRightAsINLHJInner): // prefer index hash join
1914+
errMsg = fmt.Sprintf("Optimizer Hint %s is inapplicable", restore2JoinHint(HintINLHJ, indexHashJoinTables))
1915+
case p.preferAny(preferLeftAsINLMJInner, preferRightAsINLMJInner): // prefer index merge join
1916+
errMsg = fmt.Sprintf("Optimizer Hint %s is inapplicable", restore2JoinHint(HintINLMJ, indexMergeJoinTables))
1917+
}
1918+
<<<<<<< HEAD
18821919
if p.hintInfo != nil && p.preferJoinType > 0 {
18831920
t := p.hintInfo.indexNestedLoopJoinTables
18841921
switch {
@@ -1892,14 +1929,19 @@ func (p *LogicalJoin) tryToGetIndexJoin(prop *property.PhysicalProperty) (indexJ
18921929
}
18931930
}
18941931

1932+
=======
1933+
>>>>>>> 64be9ec4c0c (planner: refine `tryToGetIndexJoin` (#45587))
18951934
// Append inapplicable reason.
18961935
if len(p.EqualConditions) == 0 {
18971936
errMsg += " without column equal ON condition"
18981937
}
1899-
19001938
// Generate warning message to client.
1939+
<<<<<<< HEAD
19011940
warning := ErrInternal.GenWithStack(errMsg)
19021941
p.ctx.GetSessionVars().StmtCtx.AppendWarning(warning)
1942+
=======
1943+
p.SCtx().GetSessionVars().StmtCtx.AppendWarning(ErrInternal.GenWithStack(errMsg))
1944+
>>>>>>> 64be9ec4c0c (planner: refine `tryToGetIndexJoin` (#45587))
19031945
}
19041946
}()
19051947

@@ -1920,19 +1962,8 @@ func (p *LogicalJoin) tryToGetIndexJoin(prop *property.PhysicalProperty) (indexJ
19201962
allLeftOuterJoins = p.getIndexJoinByOuterIdx(prop, 0)
19211963
forcedLeftOuterJoins = make([]PhysicalPlan, 0, len(allLeftOuterJoins))
19221964
for _, j := range allLeftOuterJoins {
1923-
switch j.(type) {
1924-
case *PhysicalIndexJoin:
1925-
if inljLeftOuter {
1926-
forcedLeftOuterJoins = append(forcedLeftOuterJoins, j)
1927-
}
1928-
case *PhysicalIndexHashJoin:
1929-
if inlhjLeftOuter {
1930-
forcedLeftOuterJoins = append(forcedLeftOuterJoins, j)
1931-
}
1932-
case *PhysicalIndexMergeJoin:
1933-
if inlmjLeftOuter {
1934-
forcedLeftOuterJoins = append(forcedLeftOuterJoins, j)
1935-
}
1965+
if p.satisfyIndexJoinHint(j) {
1966+
forcedLeftOuterJoins = append(forcedLeftOuterJoins, j)
19361967
}
19371968
}
19381969
switch {
@@ -1942,23 +1973,13 @@ func (p *LogicalJoin) tryToGetIndexJoin(prop *property.PhysicalProperty) (indexJ
19421973
return forcedLeftOuterJoins, true
19431974
}
19441975
}
1976+
19451977
if supportRightOuter {
19461978
allRightOuterJoins = p.getIndexJoinByOuterIdx(prop, 1)
19471979
forcedRightOuterJoins = make([]PhysicalPlan, 0, len(allRightOuterJoins))
19481980
for _, j := range allRightOuterJoins {
1949-
switch j.(type) {
1950-
case *PhysicalIndexJoin:
1951-
if inljRightOuter {
1952-
forcedRightOuterJoins = append(forcedRightOuterJoins, j)
1953-
}
1954-
case *PhysicalIndexHashJoin:
1955-
if inlhjRightOuter {
1956-
forcedRightOuterJoins = append(forcedRightOuterJoins, j)
1957-
}
1958-
case *PhysicalIndexMergeJoin:
1959-
if inlmjRightOuter {
1960-
forcedRightOuterJoins = append(forcedRightOuterJoins, j)
1961-
}
1981+
if p.satisfyIndexJoinHint(j) {
1982+
forcedRightOuterJoins = append(forcedRightOuterJoins, j)
19621983
}
19631984
}
19641985
switch {

planner/core/planbuilder.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,9 @@ func restore2TableHint(hintTables ...hintTableInfo) string {
330330
}
331331

332332
func restore2JoinHint(hintType string, hintTables []hintTableInfo) string {
333+
if len(hintTables) == 0 {
334+
return strings.ToUpper(hintType)
335+
}
333336
buffer := bytes.NewBufferString("/*+ ")
334337
buffer.WriteString(strings.ToUpper(hintType))
335338
buffer.WriteString("(")

0 commit comments

Comments
 (0)