@@ -1845,40 +1845,77 @@ func filterIndexJoinBySessionVars(sc sessionctx.Context, indexJoins []PhysicalPl
1845
1845
return indexJoins
1846
1846
}
1847
1847
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
+ }
1854
1856
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
+ }
1858
1879
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
+ }
1862
1890
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
1865
1896
needForced := forceLeftOuter || forceRightOuter
1866
1897
1867
1898
defer func () {
1868
- // refine error message
1899
+ // Print warning message if any hints cannot work.
1869
1900
// If the required property is not empty, we will enforce it and try the hint again.
1870
1901
// So we only need to generate warning message when the property is empty.
1871
1902
if ! canForced && needForced && prop .IsSortItemEmpty () {
1872
1903
// 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
+ }
1873
1909
var errMsg string
1874
1910
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
1882
1919
if p .hintInfo != nil && p .preferJoinType > 0 {
1883
1920
t := p .hintInfo .indexNestedLoopJoinTables
1884
1921
switch {
@@ -1892,14 +1929,19 @@ func (p *LogicalJoin) tryToGetIndexJoin(prop *property.PhysicalProperty) (indexJ
1892
1929
}
1893
1930
}
1894
1931
1932
+ == == == =
1933
+ >> >> >> > 64 be9ec4c0c (planner : refine `tryToGetIndexJoin` (#45587 ))
1895
1934
// Append inapplicable reason.
1896
1935
if len (p .EqualConditions ) == 0 {
1897
1936
errMsg += " without column equal ON condition"
1898
1937
}
1899
-
1900
1938
// Generate warning message to client.
1939
+ << << << < HEAD
1901
1940
warning := ErrInternal .GenWithStack (errMsg )
1902
1941
p .ctx .GetSessionVars ().StmtCtx .AppendWarning (warning )
1942
+ == == == =
1943
+ p .SCtx ().GetSessionVars ().StmtCtx .AppendWarning (ErrInternal .GenWithStack (errMsg ))
1944
+ >> >> >> > 64 be9ec4c0c (planner : refine `tryToGetIndexJoin` (#45587 ))
1903
1945
}
1904
1946
}()
1905
1947
@@ -1920,19 +1962,8 @@ func (p *LogicalJoin) tryToGetIndexJoin(prop *property.PhysicalProperty) (indexJ
1920
1962
allLeftOuterJoins = p .getIndexJoinByOuterIdx (prop , 0 )
1921
1963
forcedLeftOuterJoins = make ([]PhysicalPlan , 0 , len (allLeftOuterJoins ))
1922
1964
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 )
1936
1967
}
1937
1968
}
1938
1969
switch {
@@ -1942,23 +1973,13 @@ func (p *LogicalJoin) tryToGetIndexJoin(prop *property.PhysicalProperty) (indexJ
1942
1973
return forcedLeftOuterJoins , true
1943
1974
}
1944
1975
}
1976
+
1945
1977
if supportRightOuter {
1946
1978
allRightOuterJoins = p .getIndexJoinByOuterIdx (prop , 1 )
1947
1979
forcedRightOuterJoins = make ([]PhysicalPlan , 0 , len (allRightOuterJoins ))
1948
1980
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 )
1962
1983
}
1963
1984
}
1964
1985
switch {
0 commit comments