Skip to content

Commit

Permalink
planner: outer merge join cannot keep the prop of its inner child (#3…
Browse files Browse the repository at this point in the history
  • Loading branch information
ti-srebot authored Apr 27, 2022
1 parent 9687ea4 commit 2a86e88
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 4 deletions.
11 changes: 10 additions & 1 deletion planner/core/exhaust_physical_plans.go
Original file line number Diff line number Diff line change
Expand Up @@ -287,14 +287,16 @@ func (p *LogicalJoin) getEnforcedMergeJoin(prop *property.PhysicalProperty, sche
return nil
}
for _, item := range prop.SortItems {
isExist := false
isExist, hasLeftColInProp, hasRightColInProp := false, false, false
for joinKeyPos := 0; joinKeyPos < len(leftJoinKeys); joinKeyPos++ {
var key *expression.Column
if item.Col.Equal(p.ctx, leftJoinKeys[joinKeyPos]) {
key = leftJoinKeys[joinKeyPos]
hasLeftColInProp = true
}
if item.Col.Equal(p.ctx, rightJoinKeys[joinKeyPos]) {
key = rightJoinKeys[joinKeyPos]
hasRightColInProp = true
}
if key == nil {
continue
Expand All @@ -314,6 +316,13 @@ func (p *LogicalJoin) getEnforcedMergeJoin(prop *property.PhysicalProperty, sche
if !isExist {
return nil
}
// If the output wants the order of the inner side. We should reject it since we might add null-extend rows of that side.
if p.JoinType == LeftOuterJoin && hasRightColInProp {
return nil
}
if p.JoinType == RightOuterJoin && hasLeftColInProp {
return nil
}
}
// Generate the enforced sort merge join
leftKeys := getNewJoinKeysByOffsets(leftJoinKeys, offsets)
Expand Down
19 changes: 19 additions & 0 deletions planner/core/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5227,6 +5227,25 @@ func (s *testIntegrationSuite) TestIssue31202(c *C) {
tk.MustExec("drop table if exists t31202")
}

func (s *testIntegrationSuite) TestIssue33042(c *C) {
tk := testkit.NewTestKit(c, s.store)

tk.MustExec("use test")
tk.MustExec("create table t1(id int primary key, col1 int)")
tk.MustExec("create table t2(id int primary key, col1 int)")
tk.MustQuery("explain format='brief' SELECT /*+ merge_join(t1, t2)*/ * FROM (t1 LEFT JOIN t2 ON t1.col1=t2.id) order by t2.id;").Check(
testkit.Rows(
"Sort 12500.00 root test.t2.id",
"└─MergeJoin 12500.00 root left outer join, left key:test.t1.col1, right key:test.t2.id",
" ├─TableReader(Build) 10000.00 root data:TableFullScan",
" │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:true, stats:pseudo",
" └─Sort(Probe) 10000.00 root test.t1.col1",
" └─TableReader 10000.00 root data:TableFullScan",
" └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
),
)
}

// TestDNFCondSelectivityWithConst test selectivity calculation with DNF conditions with one is const.
// Close https://github.com/pingcap/tidb/issues/31096
func (s *testIntegrationSuite) TestDNFCondSelectivityWithConst(c *C) {
Expand Down
4 changes: 2 additions & 2 deletions planner/core/testdata/integration_suite_out.json
Original file line number Diff line number Diff line change
Expand Up @@ -1332,7 +1332,7 @@
"└─IndexRangeScan 20.00 cop[tikv] table:tt, index:a(a) range:[10,10], [20,20], keep order:false, stats:pseudo"
],
"Warnings": [
"Warning 1105 IndexMerge is inapplicable."
"Warning 1105 IndexMerge is inapplicable"
]
},
{
Expand All @@ -1342,7 +1342,7 @@
"└─IndexRangeScan 6666.67 cop[tikv] table:tt, index:a(a) range:[-inf,10), [15,15], (20,+inf], keep order:false, stats:pseudo"
],
"Warnings": [
"Warning 1105 IndexMerge is inapplicable."
"Warning 1105 IndexMerge is inapplicable"
]
}
]
Expand Down
2 changes: 1 addition & 1 deletion planner/core/testdata/plan_suite_out.json
Original file line number Diff line number Diff line change
Expand Up @@ -566,7 +566,7 @@
},
{
"SQL": "select /*+ TIDB_SMJ(t1,t2,t3)*/ * from t t1 left outer join t t2 on t1.a = t2.a left outer join t t3 on t2.a = t3.a",
"Best": "MergeLeftOuterJoin{MergeLeftOuterJoin{TableReader(Table(t))->TableReader(Table(t))}(test.t.a,test.t.a)->TableReader(Table(t))}(test.t.a,test.t.a)"
"Best": "MergeLeftOuterJoin{MergeLeftOuterJoin{TableReader(Table(t))->TableReader(Table(t))}(test.t.a,test.t.a)->Sort->TableReader(Table(t))}(test.t.a,test.t.a)"
},
{
"SQL": "select /*+ TIDB_SMJ(t1,t2,t3)*/ * from t t1 left outer join t t2 on t1.a = t2.a left outer join t t3 on t1.a = t3.a",
Expand Down

0 comments on commit 2a86e88

Please sign in to comment.