-
Notifications
You must be signed in to change notification settings - Fork 5.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor outer to inner join optimization rule
- Loading branch information
1 parent
3292909
commit fca7854
Showing
14 changed files
with
715 additions
and
64 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
// Copyright 2024 PingCAP, Inc. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package rule | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/pingcap/tidb/pkg/testkit" | ||
"github.com/pingcap/tidb/pkg/testkit/testdata" | ||
) | ||
|
||
func TestOuter2Inner(t *testing.T) { | ||
store := testkit.CreateMockStore(t) | ||
tk := testkit.NewTestKit(t, store) | ||
|
||
tk.MustExec("use test") | ||
tk.MustExec("drop table if exists t") | ||
tk.MustExec("create table t1(a1 int, b1 int, c1 int)") | ||
tk.MustExec("create table t2(a2 int, b2 int, c2 int)") | ||
tk.MustExec("create table t3(a3 int, b3 int, c3 int)") | ||
tk.MustExec("create table t4(a4 int, b4 int, c4 int)") | ||
var input Input | ||
var output []struct { | ||
SQL string | ||
Plan []string | ||
} | ||
suiteData := GetOuter2InnerSuiteData() | ||
suiteData.LoadTestCases(t, &input, &output) | ||
for i, sql := range input { | ||
plan := tk.MustQuery("explain format = 'brief' " + sql) | ||
testdata.OnRecord(func() { | ||
output[i].SQL = sql | ||
output[i].Plan = testdata.ConvertRowsToStrings(plan.Rows()) | ||
}) | ||
plan.Check(testkit.Rows(output[i].Plan...)) | ||
} | ||
} |
35 changes: 35 additions & 0 deletions
35
pkg/planner/core/casetest/rule/testdata/outer2inner_in.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
[ | ||
{ | ||
"name": "TestOuter2Inner", | ||
"cases": [ | ||
"select * from t1 left outer join t2 on a1=a2 where b2 < 1 -- basic case of outer to inner join conversion", | ||
"select * from t1 left outer join t2 on a1=a2 where b2 is not null -- basic case of not null", | ||
"select * from t1 left outer join t2 on a1=a2 where not(b2 is null) -- another form of basic case of not null", | ||
"select * from t1 left outer join t2 on a1=a2 where c2 = 5 OR b2 < 55 -- case with A OR B (Both A and B are null filtering)", | ||
"select * from t1 left outer join t2 on a1=a2 where c2 = 5 AND b2 is null -- case with A AND B (A is null filtering and B is not)", | ||
"select * from t2 left outer join t1 on a1=a2 where b1+b1 > 2; -- expression evaluates to UNKNOWN/FALSE", | ||
"select * from t2 left outer join t1 on a1=a2 where coalesce(b1,2) > 2; -- false condition for b1=NULL", | ||
"select * from t2 left outer join t1 on a1=a2 where true and b1 = 5; -- AND with one branch is null filtering", | ||
"select * from t2 left outer join t1 on a1=a2 where false OR b1 = 5; -- OR with both branches are null filtering", | ||
"select * from t3 as t1 left join t3 as t2 on t1.c3 = t2.c3 where t2.b3 != NULL; -- self join", | ||
"select * from t1 ta left outer join (t1 tb left outer join t1 tc on tb.b1 = tc.b1) on ta.a1=tc.a1; -- nested join. On clause is null filtering on tc.", | ||
"select * from t1 ta left outer join (t1 tb left outer join t1 tc on tb.b1 = tc.b1) on ta.a1=tc.a1 where tb.a1 > 5; -- nested join. On clause and WHERE clause are filters", | ||
"select * from (t2 left join t1 on a1=a2) join t3 on b1=b3 -- on clause applied nested join", | ||
"select * from ((t1 left join t2 on a1=a2) left join t3 on b2=b3) join t4 on b3=b4 -- nested and propagation of null filtering", | ||
"select * from t1 right join t2 on a1=a2 where exists (select 1 from t3 where b1=b3) -- semi join is null filtering on the outer join", | ||
"select * from t1 left outer join t2 on a1=a2 where b2 is null -- negative case with single predicate which is not null filtering", | ||
"select * from t1 left outer join t2 on a1=a2 where c2 = 5 OR b2 is null -- negative case with A OR B (A is null filtering and B is not)", | ||
"select * from t1 left outer join t2 on a1=a2 where not(b2 is not null) -- nested 'not' negative case", | ||
"select * from t1 left outer join t2 on a1=a2 where not(not(b2 is null)) -- nested 'not' negative case", | ||
"select * from t1 left outer join t2 on a1=a2 where b1 is not null -- negative case with condition on outer table.", | ||
"select * from t2 left outer join t1 on a1=a2 where coalesce(b1,2) = 2; -- true condition for b1=NULL", | ||
"select * from t2 left outer join t1 on a1=a2 where true OR b1 = 5; -- negative case with OR and one branch is TRUE", | ||
"select * from t3 as t1 left join t3 as t2 on t1.c3 = t2.c3 where t1.b3 != NULL -- negative case with self join", | ||
"select * from (t1 left outer join t2 on a1=a2) left outer join t3 on a2=a3 and b2 = 5 -- negative case. inner side is not a join", | ||
"select * from t1 ta right outer join (t1 tb right outer join t1 tc on tb.b1 = tc.b1) on ta.a1=tc.a1; -- negative case. inner side is not a join", | ||
"select * from t1 ta right outer join (t1 tb right outer join t1 tc on tb.b1 = tc.b1) on ta.a1=tc.a1 where tc.a1 > 5; -- negative case. inner side is not a join and WHERE clause on outer table", | ||
"select * from (t2 left join t1 on a1=a2) join t3 on b2=b3 -- negative case, on clause on outer table in nested join", | ||
"select t1.c1 in (select count(s.b1) from t1 s where s.a1 = t1.a1) from t1 -- subquery test that generates outer join and not converted" | ||
] | ||
} | ||
] |
Oops, something went wrong.