Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

planner, CTE, view: Fix default inline CTE which contains orderby/limit/distinct and inside of view | tidb-test=pr/2422 (#56609) #56696

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion planner/core/casetest/physical_plan_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1435,6 +1435,7 @@ func TestSingleConsumerCTE(t *testing.T) {
tk.MustExec("create table t1 (c1 int primary key, c2 int, index c2 (c2));")
tk.MustExec("create table t2 (c1 int unique, c2 int);")
tk.MustExec("insert into t values (1), (5), (10), (15), (20), (30), (50);")
tk.MustExec("create table test(a int);")

var (
input []string
Expand All @@ -1451,7 +1452,7 @@ func TestSingleConsumerCTE(t *testing.T) {
testdata.OnRecord(func() {
output[i].SQL = ts
})
if strings.HasPrefix(ts, "set") {
if strings.HasPrefix(ts, "set") || strings.HasPrefix(ts, "create") {
tk.MustExec(ts)
continue
}
Expand Down
75 changes: 70 additions & 5 deletions planner/core/casetest/testdata/flat_plan_suite_out.json
Original file line number Diff line number Diff line change
Expand Up @@ -212,8 +212,8 @@
{
"Depth": 2,
"Label": 0,
"IsRoot": false,
"StoreType": 0,
"IsRoot": true,
"StoreType": 2,
"ReqType": 0,
"IsPhysicalPlan": true,
"TextTreeIndent": "│ │ ",
Expand All @@ -232,15 +232,80 @@
{
"Depth": 2,
"Label": 0,
"IsRoot": false,
"StoreType": 0,
"IsRoot": true,
"StoreType": 2,
"ReqType": 0,
"IsPhysicalPlan": true,
"TextTreeIndent": " │ ",
"IsLastChild": true
}
],
"CTEs": null
"CTEs": [
[
{
"Depth": 0,
"Label": 0,
"IsRoot": true,
"StoreType": 2,
"ReqType": 0,
"IsPhysicalPlan": true,
"TextTreeIndent": "",
"IsLastChild": true
},
{
"Depth": 1,
"Label": 3,
"IsRoot": true,
"StoreType": 2,
"ReqType": 0,
"IsPhysicalPlan": true,
"TextTreeIndent": "│ ",
"IsLastChild": true
},
{
"Depth": 2,
"Label": 0,
"IsRoot": false,
"StoreType": 0,
"ReqType": 0,
"IsPhysicalPlan": true,
"TextTreeIndent": " │ ",
"IsLastChild": true
}
],
[
{
"Depth": 0,
"Label": 0,
"IsRoot": true,
"StoreType": 2,
"ReqType": 0,
"IsPhysicalPlan": true,
"TextTreeIndent": "",
"IsLastChild": true
},
{
"Depth": 1,
"Label": 3,
"IsRoot": true,
"StoreType": 2,
"ReqType": 0,
"IsPhysicalPlan": true,
"TextTreeIndent": "│ ",
"IsLastChild": true
},
{
"Depth": 2,
"Label": 0,
"IsRoot": false,
"StoreType": 0,
"ReqType": 0,
"IsPhysicalPlan": true,
"TextTreeIndent": " │ ",
"IsLastChild": true
}
]
]
},
{
"SQL": "WITH RECURSIVE cte (n) AS( SELECT 1 UNION ALL SELECT n + 1 FROM cte WHERE n < 5)SELECT * FROM cte;",
Expand Down
23 changes: 13 additions & 10 deletions planner/core/casetest/testdata/integration_suite_out.json
Original file line number Diff line number Diff line change
Expand Up @@ -6593,21 +6593,24 @@
{
"SQL": "explain format = 'brief' select /*+ qb_name(qb_v8, v8), merge(@qb_v8) */ * from v8;",
"Plan": [
"HashAgg 16000.00 root group by:Column#41, funcs:firstrow(Column#41)->Column#41",
"HashAgg 16000.00 root group by:Column#21, funcs:firstrow(Column#21)->Column#21",
"└─Union 1000000010000.00 root ",
" ├─HashJoin 1000000000000.00 root CARTESIAN inner join",
" │ ├─TableReader(Build) 10000.00 root data:TableFullScan",
" │ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
" │ └─Projection(Probe) 100000000.00 root 1->Column#55",
" │ └─HashJoin 100000000.00 root CARTESIAN inner join",
" │ ├─Projection(Build) 10000.00 root 1->Column#54",
" │ │ └─IndexReader 10000.00 root index:IndexFullScan",
" │ │ └─IndexFullScan 10000.00 cop[tikv] table:t3, index:idx_a(a) keep order:false, stats:pseudo",
" │ └─Projection(Probe) 10000.00 root 1->Column#53",
" │ └─IndexReader 10000.00 root index:IndexFullScan",
" │ └─IndexFullScan 10000.00 cop[tikv] table:t2, index:idx_a(a) keep order:false, stats:pseudo",
" │ └─CTEFullScan(Probe) 100000000.00 root CTE:cte2 data:CTE_1",
" └─TableReader 10000.00 root data:TableFullScan",
" └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo"
" └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
"CTE_1 100000000.00 root Non-Recursive CTE",
"└─HashJoin(Seed Part) 100000000.00 root CARTESIAN inner join",
" ├─CTEFullScan(Build) 10000.00 root CTE:cte4 data:CTE_3",
" └─CTEFullScan(Probe) 10000.00 root CTE:cte3 data:CTE_2",
"CTE_3 10000.00 root Non-Recursive CTE",
"└─IndexReader(Seed Part) 10000.00 root index:IndexFullScan",
" └─IndexFullScan 10000.00 cop[tikv] table:t3, index:idx_a(a) keep order:false, stats:pseudo",
"CTE_2 10000.00 root Non-Recursive CTE",
"└─IndexReader(Seed Part) 10000.00 root index:IndexFullScan",
" └─IndexFullScan 10000.00 cop[tikv] table:t2, index:idx_a(a) keep order:false, stats:pseudo"
],
"Warn": null
},
Expand Down
12 changes: 11 additions & 1 deletion planner/core/casetest/testdata/plan_suite_in.json
Original file line number Diff line number Diff line change
Expand Up @@ -817,7 +817,17 @@
"with cte as (select 1) select /*+ MERGE() */ * from cte union select * from cte; -- firstly inline cte, secondly cannot be inlined",
"with a as (select 8 as id from dual),maxa as (select max(id) as max_id from a),b as (with recursive temp as (select 1 as lvl from dual union all select lvl+1 from temp, maxa where lvl < max_id)select * from temp) select * from b; -- issue #47711, maxa cannot be inlined because it contains agg and in the recursive part of cte temp",
"with a as (select count(*) from t1), b as (select 2 as bb from a), c as (with recursive tmp as (select 1 as res from t1 union all select res+1 from tmp,b where res+1 < bb) select * from tmp) select * from c; -- inline a, cannot be inline b because b indirectly contains agg and in the recursive part of cte tmp",
"with a as (select count(*) from t1), b as (select 2 as bb from a), c as (with recursive tmp as (select bb as res from b union all select res+1 from tmp where res +1 < 10) select * from tmp) select * from c; -- inline a, b, cannot be inline tmp, c"
"with a as (select count(*) from t1), b as (select 2 as bb from a), c as (with recursive tmp as (select bb as res from b union all select res+1 from tmp where res +1 < 10) select * from tmp) select * from c; -- inline a, b, cannot be inline tmp, c",
"with a as (select count(*) from t1), b as (select 2 as bb from a), c as (with recursive tmp as (select bb as res from b union all select res+1 from tmp where res +1 < 10) select * from tmp) select * from c; -- inline a, b, cannot be inline tmp, c",
"WITH RECURSIVE CTE (x) AS (SELECT 1 UNION ALL SELECT distinct a FROM test), CTE1 AS (SELECT x FROM CTE UNION ALL select CTE.x from CTE join CTE1 on CTE.x=CTE1.x) SELECT * FROM CTE1; -- CTE contain distinct and ref by CET1 recursive part cannot be inlined;",
"create definer='root'@'localhost' view test_cte(a) as WITH RECURSIVE CTE (x) AS (SELECT 1 UNION ALL SELECT distinct a FROM test) , CTE1 AS (SELECT x FROM CTE UNION ALL select CTE.x from CTE join CTE1 on CTE.x=CTE1.x) SELECT * FROM CTE1;",
"select * from test_cte; -- CTE (inside of view) cannot be inlined by default;",
"create definer='root'@'localhost' view test_inline_cte(a) as with CTE (x) as (select distinct a from test) select * from CTE;",
"select * from test_inline_cte; -- CTE (inside of view) cannot be inlined by default;",
"create definer='root'@'localhost' view test_force_inline_cte(a) as with CTE (x) as (select /*+ merge() */ distinct a from test) select * from CTE;",
"select * from test_force_inline_cte; -- CTE (inside of view) can be inlined by force;" ,
"WITH RECURSIVE CTE (x) AS (SELECT a FROM test limit 1) , CTE1(x) AS (SELECT a FROM test UNION ALL select CTE.x from CTE join CTE1 on CTE.x=CTE1.x) SELECT * FROM CTE1; -- CTE contain limit and ref by CET1 recursive part cannot be inlined;",
"WITH RECURSIVE CTE (x) AS (SELECT a FROM test order by a) , CTE1(x) AS (SELECT a FROM test UNION ALL select CTE.x from CTE join CTE1 on CTE.x=CTE1.x) SELECT * FROM CTE1; -- CTE contain order by and ref by CET1 recursive part cannot be inlined;"
]
},
{
Expand Down
138 changes: 138 additions & 0 deletions planner/core/casetest/testdata/plan_suite_out.json
Original file line number Diff line number Diff line change
Expand Up @@ -4010,6 +4010,144 @@
" └─CTETable 1.00 root Scan on CTE_4"
],
"Warning": null
},
{
"SQL": "with a as (select count(*) from t1), b as (select 2 as bb from a), c as (with recursive tmp as (select bb as res from b union all select res+1 from tmp where res +1 < 10) select * from tmp) select * from c; -- inline a, b, cannot be inline tmp, c",
"Plan": [
"CTEFullScan 1.80 root CTE:tmp data:CTE_4",
"CTE_4 1.80 root Recursive CTE",
"├─Projection(Seed Part) 1.00 root 2->Column#37",
"│ └─HashAgg 1.00 root funcs:count(Column#46)->Column#44",
"│ └─TableReader 1.00 root data:HashAgg",
"│ └─HashAgg 1.00 cop[tikv] funcs:count(1)->Column#46",
"│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
"└─Projection(Recursive Part) 0.80 root cast(plus(Column#38, 1), bigint(1) BINARY)->Column#40",
" └─Selection 0.80 root lt(plus(Column#38, 1), 10)",
" └─CTETable 1.00 root Scan on CTE_4"
],
"Warning": null
},
{
"SQL": "WITH RECURSIVE CTE (x) AS (SELECT 1 UNION ALL SELECT distinct a FROM test), CTE1 AS (SELECT x FROM CTE UNION ALL select CTE.x from CTE join CTE1 on CTE.x=CTE1.x) SELECT * FROM CTE1; -- CTE contain distinct and ref by CET1 recursive part cannot be inlined;",
"Plan": [
"CTEFullScan 14401.80 root CTE:cte1 data:CTE_1",
"CTE_1 14401.80 root Recursive CTE",
"├─CTEFullScan(Seed Part) 8001.00 root CTE:cte data:CTE_0",
"└─HashJoin(Recursive Part) 6400.80 root inner join, equal:[eq(Column#11, Column#12)]",
" ├─Selection(Build) 6400.80 root not(isnull(Column#12))",
" │ └─CTETable 8001.00 root Scan on CTE_1",
" └─Selection(Probe) 6400.80 root not(isnull(Column#11))",
" └─CTEFullScan 8001.00 root CTE:cte data:CTE_0",
"CTE_0 8001.00 root Non-Recursive CTE",
"└─Union(Seed Part) 8001.00 root ",
" ├─Projection 1.00 root 1->Column#7",
" │ └─TableDual 1.00 root rows:1",
" └─Projection 8000.00 root cast(test.test.a, bigint(11) BINARY)->Column#7",
" └─HashAgg 8000.00 root group by:test.test.a, funcs:firstrow(test.test.a)->test.test.a",
" └─TableReader 8000.00 root data:HashAgg",
" └─HashAgg 8000.00 cop[tikv] group by:test.test.a, ",
" └─TableFullScan 10000.00 cop[tikv] table:test keep order:false, stats:pseudo"
],
"Warning": null
},
{
"SQL": "create definer='root'@'localhost' view test_cte(a) as WITH RECURSIVE CTE (x) AS (SELECT 1 UNION ALL SELECT distinct a FROM test) , CTE1 AS (SELECT x FROM CTE UNION ALL select CTE.x from CTE join CTE1 on CTE.x=CTE1.x) SELECT * FROM CTE1;",
"Plan": null,
"Warning": null
},
{
"SQL": "select * from test_cte; -- CTE (inside of view) cannot be inlined by default;",
"Plan": [
"CTEFullScan 14401.80 root CTE:cte1 data:CTE_1",
"CTE_1 14401.80 root Recursive CTE",
"├─CTEFullScan(Seed Part) 8001.00 root CTE:cte data:CTE_0",
"└─HashJoin(Recursive Part) 6400.80 root inner join, equal:[eq(Column#11, Column#12)]",
" ├─Selection(Build) 6400.80 root not(isnull(Column#12))",
" │ └─CTETable 8001.00 root Scan on CTE_1",
" └─Selection(Probe) 6400.80 root not(isnull(Column#11))",
" └─CTEFullScan 8001.00 root CTE:cte data:CTE_0",
"CTE_0 8001.00 root Non-Recursive CTE",
"└─Union(Seed Part) 8001.00 root ",
" ├─Projection 1.00 root 1->Column#7",
" │ └─TableDual 1.00 root rows:1",
" └─Projection 8000.00 root cast(test.test.a, bigint(11) BINARY)->Column#7",
" └─HashAgg 8000.00 root group by:test.test.a, funcs:firstrow(test.test.a)->test.test.a",
" └─TableReader 8000.00 root data:HashAgg",
" └─HashAgg 8000.00 cop[tikv] group by:test.test.a, ",
" └─TableFullScan 10000.00 cop[tikv] table:test keep order:false, stats:pseudo"
],
"Warning": null
},
{
"SQL": "create definer='root'@'localhost' view test_inline_cte(a) as with CTE (x) as (select distinct a from test) select * from CTE;",
"Plan": null,
"Warning": null
},
{
"SQL": "select * from test_inline_cte; -- CTE (inside of view) cannot be inlined by default;",
"Plan": [
"CTEFullScan 8000.00 root CTE:cte data:CTE_0",
"CTE_0 8000.00 root Non-Recursive CTE",
"└─HashAgg(Seed Part) 8000.00 root group by:test.test.a, funcs:firstrow(test.test.a)->test.test.a",
" └─TableReader 8000.00 root data:HashAgg",
" └─HashAgg 8000.00 cop[tikv] group by:test.test.a, ",
" └─TableFullScan 10000.00 cop[tikv] table:test keep order:false, stats:pseudo"
],
"Warning": null
},
{
"SQL": "create definer='root'@'localhost' view test_force_inline_cte(a) as with CTE (x) as (select /*+ merge() */ distinct a from test) select * from CTE;",
"Plan": null,
"Warning": null
},
{
"SQL": "select * from test_force_inline_cte; -- CTE (inside of view) can be inlined by force;",
"Plan": [
"HashAgg 8000.00 root group by:test.test.a, funcs:firstrow(test.test.a)->test.test.a",
"└─TableReader 8000.00 root data:HashAgg",
" └─HashAgg 8000.00 cop[tikv] group by:test.test.a, ",
" └─TableFullScan 10000.00 cop[tikv] table:test keep order:false, stats:pseudo"
],
"Warning": null
},
{
"SQL": "WITH RECURSIVE CTE (x) AS (SELECT a FROM test limit 1) , CTE1(x) AS (SELECT a FROM test UNION ALL select CTE.x from CTE join CTE1 on CTE.x=CTE1.x) SELECT * FROM CTE1; -- CTE contain limit and ref by CET1 recursive part cannot be inlined;",
"Plan": [
"CTEFullScan 16400.00 root CTE:cte1 data:CTE_1",
"CTE_1 16400.00 root Recursive CTE",
"├─TableReader(Seed Part) 10000.00 root data:TableFullScan",
"│ └─TableFullScan 10000.00 cop[tikv] table:test keep order:false, stats:pseudo",
"└─HashJoin(Recursive Part) 6400.00 root inner join, equal:[eq(test.test.a, test.test.a)]",
" ├─Selection(Build) 0.80 root not(isnull(test.test.a))",
" │ └─CTEFullScan 1.00 root CTE:cte data:CTE_0",
" └─Selection(Probe) 8000.00 root not(isnull(test.test.a))",
" └─CTETable 10000.00 root Scan on CTE_1",
"CTE_0 1.00 root Non-Recursive CTE",
"└─Limit(Seed Part) 1.00 root offset:0, count:1",
" └─TableReader 1.00 root data:Limit",
" └─Limit 1.00 cop[tikv] offset:0, count:1",
" └─TableFullScan 1.00 cop[tikv] table:test keep order:false, stats:pseudo"
],
"Warning": null
},
{
"SQL": "WITH RECURSIVE CTE (x) AS (SELECT a FROM test order by a) , CTE1(x) AS (SELECT a FROM test UNION ALL select CTE.x from CTE join CTE1 on CTE.x=CTE1.x) SELECT * FROM CTE1; -- CTE contain order by and ref by CET1 recursive part cannot be inlined;",
"Plan": [
"CTEFullScan 20000.00 root CTE:cte1 data:CTE_1",
"CTE_1 20000.00 root Recursive CTE",
"├─TableReader(Seed Part) 10000.00 root data:TableFullScan",
"│ └─TableFullScan 10000.00 cop[tikv] table:test keep order:false, stats:pseudo",
"└─HashJoin(Recursive Part) 10000.00 root inner join, equal:[eq(test.test.a, test.test.a)]",
" ├─Selection(Build) 8000.00 root not(isnull(test.test.a))",
" │ └─CTEFullScan 10000.00 root CTE:cte data:CTE_0",
" └─Selection(Probe) 8000.00 root not(isnull(test.test.a))",
" └─CTETable 10000.00 root Scan on CTE_1",
"CTE_0 10000.00 root Non-Recursive CTE",
"└─Sort(Seed Part) 10000.00 root test.test.a",
" └─TableReader 10000.00 root data:TableFullScan",
" └─TableFullScan 10000.00 cop[tikv] table:test keep order:false, stats:pseudo"
],
"Warning": null
}
]
},
Expand Down
Loading