Skip to content

Commit 1a0c84b

Browse files
elsa0520ti-chi-bot
authored andcommitted
This is an automated cherry-pick of pingcap#56609
Signed-off-by: ti-chi-bot <[email protected]>
1 parent 21d2679 commit 1a0c84b

File tree

14 files changed

+1637
-24
lines changed

14 files changed

+1637
-24
lines changed

pkg/planner/core/casetest/flatplan/testdata/flat_plan_suite_out.json

Lines changed: 70 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -212,8 +212,8 @@
212212
{
213213
"Depth": 2,
214214
"Label": 0,
215-
"IsRoot": false,
216-
"StoreType": 0,
215+
"IsRoot": true,
216+
"StoreType": 2,
217217
"ReqType": 0,
218218
"IsPhysicalPlan": true,
219219
"TextTreeIndent": "│ │ ",
@@ -232,15 +232,80 @@
232232
{
233233
"Depth": 2,
234234
"Label": 0,
235-
"IsRoot": false,
236-
"StoreType": 0,
235+
"IsRoot": true,
236+
"StoreType": 2,
237237
"ReqType": 0,
238238
"IsPhysicalPlan": true,
239239
"TextTreeIndent": "",
240240
"IsLastChild": true
241241
}
242242
],
243-
"CTEs": null
243+
"CTEs": [
244+
[
245+
{
246+
"Depth": 0,
247+
"Label": 0,
248+
"IsRoot": true,
249+
"StoreType": 2,
250+
"ReqType": 0,
251+
"IsPhysicalPlan": true,
252+
"TextTreeIndent": "",
253+
"IsLastChild": true
254+
},
255+
{
256+
"Depth": 1,
257+
"Label": 3,
258+
"IsRoot": true,
259+
"StoreType": 2,
260+
"ReqType": 0,
261+
"IsPhysicalPlan": true,
262+
"TextTreeIndent": "",
263+
"IsLastChild": true
264+
},
265+
{
266+
"Depth": 2,
267+
"Label": 0,
268+
"IsRoot": false,
269+
"StoreType": 0,
270+
"ReqType": 0,
271+
"IsPhysicalPlan": true,
272+
"TextTreeIndent": "",
273+
"IsLastChild": true
274+
}
275+
],
276+
[
277+
{
278+
"Depth": 0,
279+
"Label": 0,
280+
"IsRoot": true,
281+
"StoreType": 2,
282+
"ReqType": 0,
283+
"IsPhysicalPlan": true,
284+
"TextTreeIndent": "",
285+
"IsLastChild": true
286+
},
287+
{
288+
"Depth": 1,
289+
"Label": 3,
290+
"IsRoot": true,
291+
"StoreType": 2,
292+
"ReqType": 0,
293+
"IsPhysicalPlan": true,
294+
"TextTreeIndent": "",
295+
"IsLastChild": true
296+
},
297+
{
298+
"Depth": 2,
299+
"Label": 0,
300+
"IsRoot": false,
301+
"StoreType": 0,
302+
"ReqType": 0,
303+
"IsPhysicalPlan": true,
304+
"TextTreeIndent": "",
305+
"IsLastChild": true
306+
}
307+
]
308+
]
244309
},
245310
{
246311
"SQL": "WITH RECURSIVE cte (n) AS( SELECT 1 UNION ALL SELECT n + 1 FROM cte WHERE n < 5)SELECT * FROM cte;",

pkg/planner/core/casetest/hint/testdata/integration_suite_out.json

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -796,18 +796,24 @@
796796
{
797797
"SQL": "explain format = 'brief' select /*+ qb_name(qb_v8, v8), merge(@qb_v8) */ * from v8;",
798798
"Plan": [
799-
"HashAgg 16000.00 root group by:Column#41, funcs:firstrow(Column#41)->Column#41",
799+
"HashAgg 16000.00 root group by:Column#21, funcs:firstrow(Column#21)->Column#21",
800800
"└─Union 1000000010000.00 root ",
801801
" ├─HashJoin 1000000000000.00 root CARTESIAN inner join",
802-
" │ ├─IndexReader(Build) 10000.00 root index:IndexFullScan",
803-
" │ │ └─IndexFullScan 10000.00 cop[tikv] table:t3, index:idx_a(a) keep order:false, stats:pseudo",
804-
" │ └─HashJoin(Probe) 100000000.00 root CARTESIAN inner join",
805-
" │ ├─IndexReader(Build) 10000.00 root index:IndexFullScan",
806-
" │ │ └─IndexFullScan 10000.00 cop[tikv] table:t2, index:idx_a(a) keep order:false, stats:pseudo",
807-
" │ └─TableReader(Probe) 10000.00 root data:TableFullScan",
808-
" │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
802+
" │ ├─TableReader(Build) 10000.00 root data:TableFullScan",
803+
" │ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
804+
" │ └─CTEFullScan(Probe) 100000000.00 root CTE:cte2 data:CTE_1",
809805
" └─TableReader 10000.00 root data:TableFullScan",
810-
" └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo"
806+
" └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
807+
"CTE_1 100000000.00 root Non-Recursive CTE",
808+
"└─HashJoin(Seed Part) 100000000.00 root CARTESIAN inner join",
809+
" ├─CTEFullScan(Build) 10000.00 root CTE:cte4 data:CTE_3",
810+
" └─CTEFullScan(Probe) 10000.00 root CTE:cte3 data:CTE_2",
811+
"CTE_3 10000.00 root Non-Recursive CTE",
812+
"└─IndexReader(Seed Part) 10000.00 root index:IndexFullScan",
813+
" └─IndexFullScan 10000.00 cop[tikv] table:t3, index:idx_a(a) keep order:false, stats:pseudo",
814+
"CTE_2 10000.00 root Non-Recursive CTE",
815+
"└─IndexReader(Seed Part) 10000.00 root index:IndexFullScan",
816+
" └─IndexFullScan 10000.00 cop[tikv] table:t2, index:idx_a(a) keep order:false, stats:pseudo"
811817
],
812818
"Warn": null
813819
},

pkg/planner/core/casetest/planstats/BUILD.bazel

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ go_test(
99
],
1010
data = glob(["testdata/**"]),
1111
flaky = True,
12-
shard_count = 5,
12+
shard_count = 6,
1313
deps = [
1414
"//pkg/config",
1515
"//pkg/domain",

pkg/planner/core/casetest/planstats/plan_stats_test.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ func TestPlanStatsLoad(t *testing.T) {
163163
require.Greater(t, countFullStats(ptr.StatsInfo().HistColl, tableInfo.Columns[2].ID), 0)
164164
},
165165
},
166+
<<<<<<< HEAD
166167
{ // CTE
167168
sql: "with cte(x, y) as (select d + 1, b from t where c > 1) select * from cte where x < 3",
168169
check: func(p plannercore.Plan, tableInfo *model.TableInfo) {
@@ -177,6 +178,8 @@ func TestPlanStatsLoad(t *testing.T) {
177178
require.Greater(t, countFullStats(reader.StatsInfo().HistColl, tableInfo.Columns[2].ID), 0)
178179
},
179180
},
181+
=======
182+
>>>>>>> fa723c3bd54 (planner, CTE, view: Fix default inline CTE which contains orderby/limit/distinct and inside of view (#56609))
180183
{ // recursive CTE
181184
sql: "with recursive cte(x, y) as (select a, b from t where c > 1 union select x + 1, y from cte where x < 5) select * from cte",
182185
check: func(p plannercore.Plan, tableInfo *model.TableInfo) {
@@ -220,6 +223,47 @@ func TestPlanStatsLoad(t *testing.T) {
220223
}
221224
}
222225

226+
func TestPlanStatsLoadForCTE(t *testing.T) {
227+
store, dom := testkit.CreateMockStoreAndDomain(t)
228+
229+
tk := testkit.NewTestKit(t, store)
230+
tk.MustExec("use test")
231+
tk.MustExec("drop table if exists t")
232+
tk.MustExec("set @@session.tidb_analyze_version=2")
233+
tk.MustExec("set @@session.tidb_partition_prune_mode = 'static'")
234+
tk.MustExec("set @@session.tidb_stats_load_sync_wait = 60000")
235+
tk.MustExec("set tidb_opt_projection_push_down = 0")
236+
tk.MustExec("create table t(a int, b int, c int, d int, primary key(a), key idx(b))")
237+
tk.MustExec("insert into t values (1,1,1,1),(2,2,2,2),(3,3,3,3)")
238+
tk.MustExec("create table pt(a int, b int, c int) partition by range(a) (partition p0 values less than (10), partition p1 values less than (20), partition p2 values less than maxvalue)")
239+
tk.MustExec("insert into pt values (1,1,1),(2,2,2),(13,13,13),(14,14,14),(25,25,25),(36,36,36)")
240+
241+
oriLease := dom.StatsHandle().Lease()
242+
dom.StatsHandle().SetLease(1)
243+
defer func() {
244+
dom.StatsHandle().SetLease(oriLease)
245+
}()
246+
tk.MustExec("analyze table t all columns")
247+
tk.MustExec("analyze table pt all columns")
248+
249+
var (
250+
input []string
251+
output []struct {
252+
Query string
253+
Result []string
254+
}
255+
)
256+
testData := GetPlanStatsData()
257+
testData.LoadTestCases(t, &input, &output)
258+
for i, sql := range input {
259+
testdata.OnRecord(func() {
260+
output[i].Query = input[i]
261+
output[i].Result = testdata.ConvertRowsToStrings(tk.MustQuery(sql).Rows())
262+
})
263+
tk.MustQuery(sql).Check(testkit.Rows(output[i].Result...))
264+
}
265+
}
266+
223267
func countFullStats(stats *statistics.HistColl, colID int64) int {
224268
for _, col := range stats.Columns {
225269
if col.Info.ID == colID {

pkg/planner/core/casetest/planstats/testdata/plan_stats_suite_in.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,5 +70,11 @@
7070
"explain format = brief select * from t join tp where tp.a = 10 and t.b = tp.c",
7171
"explain format = brief select * from t join tp partition (p0) join t2 where t.a < 10 and t.b = tp.c and t2.a > 10 and t2.a = tp.c"
7272
]
73+
},
74+
{
75+
"name": "TestPlanStatsLoadForCTE",
76+
"cases": [
77+
"explain format= brief with cte(x, y) as (select d + 1, b from t where c > 1) select * from cte where x < 3"
78+
]
7379
}
7480
]

pkg/planner/core/casetest/planstats/testdata/plan_stats_suite_out.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,5 +143,19 @@
143143
]
144144
}
145145
]
146+
},
147+
{
148+
"Name": "TestPlanStatsLoadForCTE",
149+
"Cases": [
150+
{
151+
"Query": "explain format= brief with cte(x, y) as (select d + 1, b from t where c > 1) select * from cte where x < 3",
152+
"Result": [
153+
"Projection 1.60 root plus(test.t.d, 1)->Column#12, test.t.b",
154+
"└─TableReader 1.60 root data:Selection",
155+
" └─Selection 1.60 cop[tikv] gt(test.t.c, 1), lt(plus(test.t.d, 1), 3)",
156+
" └─TableFullScan 3.00 cop[tikv] table:t keep order:false"
157+
]
158+
}
159+
]
146160
}
147161
]
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
[
2+
{
3+
"name": "TestOuter2Inner",
4+
"cases": [
5+
"select * from t1 left outer join t2 on a1=a2 where b2 < 1 -- basic case of outer to inner join conversion",
6+
"select * from t1 left outer join t2 on a1=a2 where b2 is not null -- basic case of not null",
7+
"select * from t1 left outer join t2 on a1=a2 where not(b2 is null) -- another form of basic case of not null",
8+
"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)",
9+
"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)",
10+
"select * from t1 left outer join t2 on a1=a2 where b2 is NULL AND c2 = 5 -- case with A AND B (A is null filtering and B is not)",
11+
"select * from t1 left outer join t2 on a1=a2 where not (b2 is NULL OR c2 = 5) -- NOT case ",
12+
"select * from t1 left outer join t2 on a1=a2 where not (b2 is NULL AND c2 = 5) -- NOT case ",
13+
"select * from t2 left outer join t1 on a1=a2 where b1+b1 > 2; -- expression evaluates to UNKNOWN/FALSE",
14+
"select * from t2 left outer join t1 on a1=a2 where coalesce(b1,2) > 2; -- false condition for b1=NULL",
15+
"select * from t2 left outer join t1 on a1=a2 where true and b1 = 5; -- AND with one branch is null filtering",
16+
"select * from t2 left outer join t1 on a1=a2 where false OR b1 = 5; -- OR with both branches are null filtering",
17+
"select * from t3 as t1 left join t3 as t2 on t1.c3 = t2.c3 where t2.b3 != NULL; -- self join",
18+
"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.",
19+
"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",
20+
"select * from (t2 left join t1 on a1=a2) join t3 on b1=b3 -- on clause applied nested join",
21+
"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",
22+
"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",
23+
"select sum(l_extendedprice) / 7.0 as avg_yearly from lineitem, part where p_partkey = l_partkey and p_brand = 'Brand#44' and p_container = 'WRAP PKG' and l_quantity < ( select 0.2 * avg(l_quantity) from lineitem where l_partkey = p_partkey) -- Q17 in TPCH. null filter on derived outer join",
24+
"WITH cte AS ( SELECT alias1.col_date AS field1 FROM d AS alias1 LEFT JOIN dd AS alias2 ON alias1.col_blob_key=alias2.col_blob_key WHERE alias1.col_varchar_key IS NULL OR alias1.col_blob_key >= 'a') SELECT * FROM d AS outr1 LEFT OUTER JOIN dd AS outr2 ON (outr1.col_date=outr2.col_date) JOIN cte AS outrcte ON outr2.col_blob_key=outrcte.field1 -- nested complex case",
25+
"with cte as (select count(a2) as cnt,b2-5 as b3 from t1 left outer join t2 on a1=a2 group by b3) select * from cte where b3 > 1 -- aggregate case.",
26+
"select * from dd as outr1 WHERE outr1.col_blob IN (SELECT DISTINCT innr1.col_blob_key AS y FROM d AS innrcte left outer join dd AS innr1 ON innr1.pk = innrcte.col_date WHERE outr1.col_int_key > 6)",
27+
"select * from t0 left outer join t11 on a0=a1 where t0.b0 in (t11.b1, t11.c1) -- each = in the in list is null filtering",
28+
"select * from t1 left outer join t2 on a1=a2 where b2 is null -- negative case with single predicate which is not null filtering",
29+
"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)",
30+
"select * from t1 left outer join t2 on a1=a2 where not(b2 is not null) -- nested 'not' negative case",
31+
"select * from t1 left outer join t2 on a1=a2 where not(not(b2 is null)) -- nested 'not' negative case",
32+
"select * from t1 left outer join t2 on a1=a2 where b1 is not null -- negative case with condition on outer table.",
33+
"select * from t2 left outer join t1 on a1=a2 where coalesce(b1,2) = 2; -- true condition for b1=NULL",
34+
"select * from t2 left outer join t1 on a1=a2 where true OR b1 = 5; -- negative case with OR and one branch is TRUE",
35+
"select * from t3 as t1 left join t3 as t2 on t1.c3 = t2.c3 where t1.b3 != NULL -- negative case with self join",
36+
"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",
37+
"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",
38+
"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",
39+
"select * from (t2 left join t1 on a1=a2) join t3 on b2=b3 -- negative case, on clause on outer table in nested join",
40+
"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",
41+
"SELECT * FROM ti LEFT JOIN (SELECT i FROM ti WHERE FALSE) AS d1 ON ti.i = d1.i WHERE NOT EXISTS (SELECT 1 FROM ti AS inner_t1 WHERE i = d1.i) -- anti semi join",
42+
"select count(*) from t1 where t1.a1+100 > ( select count(*) from t2 where t1.a1=t2.a2 and t1.b1=t2.b2) group by t1.b1 -- filter not filtering over derived outer join",
43+
"with cte as (select count(a2) as cnt,ifnull(b2,5) as b2 from t1 left outer join t2 on a1=a2 group by b2) select * from cte where b2 > 1 -- non null filter on group by",
44+
"with cte as (select count(a2) as cnt,ifnull(b2,5) as b2 from t1 left outer join t2 on a1=a2 group by b2) select * from cte where cnt > 1 -- filter on aggregates not applicable",
45+
"select * from t0 left outer join t11 on a0=a1 where t0.b0 in (t0.b0, t11.b1)",
46+
"select * from t0 left outer join t11 on a0=a1 where '5' not in (t0.b0, t11.b1)",
47+
"select * from t0 left outer join t11 on a0=a1 where '1' in (t0.b0, t11.b1)",
48+
"select * from t0 left outer join t11 on a0=a1 where t0.b0 in ('5', t11.b1) -- some = in the in list is not null filtering",
49+
"select * from t0 left outer join t11 on a0=a1 where '5' in (t0.b0, t11.b1) -- some = in the in list is not null filtering",
50+
"select * from t1 left outer join t2 on a1=a2 where not (b2 is NOT NULL AND c2 = 5) -- NOT case "
51+
]
52+
}
53+
]

0 commit comments

Comments
 (0)