Skip to content

Commit

Permalink
planner, CTE, view: Fix default inline CTE which contains orderby/lim…
Browse files Browse the repository at this point in the history
…it/distinct and inside of view | tidb-test=pr/2438 (#56609) (#56695)

close #56582, close #56603
  • Loading branch information
ti-chi-bot authored Dec 4, 2024
1 parent 13e8409 commit a04a55c
Show file tree
Hide file tree
Showing 11 changed files with 343 additions and 39 deletions.
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
24 changes: 15 additions & 9 deletions pkg/planner/core/casetest/hint/testdata/integration_suite_out.json
Original file line number Diff line number Diff line change
Expand Up @@ -796,18 +796,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",
" │ ├─IndexReader(Build) 10000.00 root index:IndexFullScan",
" │ │ └─IndexFullScan 10000.00 cop[tikv] table:t3, index:idx_a(a) keep order:false, stats:pseudo",
" │ └─HashJoin(Probe) 100000000.00 root CARTESIAN inner join",
" │ ├─IndexReader(Build) 10000.00 root index:IndexFullScan",
" │ │ └─IndexFullScan 10000.00 cop[tikv] table:t2, index:idx_a(a) keep order:false, stats:pseudo",
" │ └─TableReader(Probe) 10000.00 root data:TableFullScan",
" │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
" │ ├─TableReader(Build) 10000.00 root data:TableFullScan",
" │ │ └─TableFullScan 10000.00 cop[tikv] table:t1 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
Original file line number Diff line number Diff line change
Expand Up @@ -1209,6 +1209,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 @@ -1225,7 +1226,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
Original file line number Diff line number Diff line change
Expand Up @@ -571,7 +571,18 @@
"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 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
Original file line number Diff line number Diff line change
Expand Up @@ -3390,6 +3390,159 @@
" └─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 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",
"└─TableReader(Seed Part) 10000.00 root data:TableFullScan",
" └─TableFullScan 10000.00 cop[tikv] table:test keep order:false, stats:pseudo"
],
"Warning": null
}
]
},
Expand Down
2 changes: 1 addition & 1 deletion pkg/planner/core/casetest/planstats/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ go_test(
],
data = glob(["testdata/**"]),
flaky = True,
shard_count = 5,
shard_count = 6,
deps = [
"//pkg/config",
"//pkg/domain",
Expand Down
Loading

0 comments on commit a04a55c

Please sign in to comment.