Skip to content

Commit 00d3dc9

Browse files
MDEV-32294 fix_fields() problem with inconsistent outer context paths
As part of optimization, we can simplify queries by merging a derived table into it's parent instead of materializing it. When this happens the context paths, describing how each SELECT_LEX is positioned in our query needs updating. The best place to do this is in the call to SELECT_LEX::exclude_level(). We follow MySQLs example here. Approved by Sanja Byelkin (sanja@mariadb.com)
1 parent 21bb6a3 commit 00d3dc9

File tree

3 files changed

+329
-0
lines changed

3 files changed

+329
-0
lines changed
Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
#
2+
# MDEV-32294 2nd execution problem with inconsistent outer context paths
3+
#
4+
SELECT
5+
(
6+
WITH x AS
7+
(
8+
WITH RECURSIVE x ( x ) AS
9+
(
10+
SELECT 1 UNION SELECT x FROM x
11+
)
12+
SELECT * FROM x WHERE x IN
13+
(
14+
SELECT x FROM x WHERE
15+
(
16+
SELECT 1 GROUP BY x HAVING ( x )
17+
)
18+
)
19+
)
20+
SELECT * FROM x
21+
) AS R;
22+
R
23+
1
24+
SELECT * FROM (
25+
WITH RECURSIVE x ( a ) AS ( SELECT 1 UNION SELECT a FROM x )
26+
SELECT * FROM x
27+
WHERE a IN (
28+
SELECT a FROM x WHERE ( SELECT 1 GROUP BY a HAVING ( a ) )
29+
)
30+
) as dt ;
31+
a
32+
1
33+
create table t1 (a int) engine=myisam;
34+
insert into t1 values (1), (2);
35+
create table t2 (b int) engine=myisam;
36+
insert into t2 values (3), (1);
37+
create table t3 (c int) select a as c from t1;
38+
select * from
39+
(
40+
with recursive x as ( select a from t1 union select a+1 from x where a < 4 )
41+
select * from x where a in
42+
(
43+
select a from x where
44+
(
45+
select b from t2 where b < 3 group by a having a > 0
46+
) <> 0
47+
)
48+
) dt;
49+
a
50+
1
51+
2
52+
3
53+
4
54+
select * from
55+
(
56+
with x as ( select distinct a from t1 )
57+
select * from x where a in
58+
(
59+
select a from x where
60+
(
61+
select b from t2 where b < 3 group by a having a > 0
62+
) <> 0
63+
)
64+
) dt;
65+
a
66+
1
67+
2
68+
select * from
69+
(
70+
select * from t1 where a in
71+
(
72+
select a from t1 where
73+
(
74+
select b from t2 where b < 3 group by a having a > 0
75+
) <> 0
76+
)
77+
) dt;
78+
a
79+
1
80+
2
81+
select * from
82+
(
83+
select * from t1 where a in
84+
(
85+
select a from t1 where
86+
(
87+
select b from t2 where b < 3 group by a
88+
) <> 0
89+
)
90+
) dt;
91+
a
92+
1
93+
2
94+
select * from
95+
(
96+
select * from t3 where c in
97+
(
98+
select a from t1 where
99+
(
100+
select b from t2 where b < 3 group by a
101+
) <> 0
102+
)
103+
) dt;
104+
c
105+
1
106+
2
107+
select * from
108+
(
109+
select * from t3 where c in
110+
(
111+
select a from t1 where
112+
(
113+
select b from t2 where a > 0 and b < 3
114+
) <> 0
115+
)
116+
) dt;
117+
c
118+
1
119+
2
120+
select * from
121+
(
122+
select * from t3 where c in
123+
(
124+
select a from t1 where
125+
(
126+
select b from t2 where a > 0 and b < 3
127+
) <> 0
128+
)
129+
) dt
130+
where dt.c > 1;
131+
c
132+
2
133+
select * from
134+
(
135+
select * from t3 where c in
136+
(
137+
select a from t1 where
138+
(
139+
select b from t2
140+
where a > 0 and b < 3
141+
) <> 0
142+
)
143+
) dt;
144+
c
145+
1
146+
2
147+
prepare stmt from "with cte as
148+
( select * from t3 where c in
149+
(
150+
select a from t1 where
151+
(
152+
select b from t2 where a > 0 and b < 3
153+
) <> 0
154+
)
155+
)
156+
select * from cte";
157+
execute stmt;
158+
c
159+
1
160+
2
161+
execute stmt;
162+
c
163+
1
164+
2
165+
deallocate prepare stmt;
166+
drop table t1, t2, t3;
167+
#
168+
# End of 10.11 tests
169+
#
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
--echo #
2+
--echo # MDEV-32294 2nd execution problem with inconsistent outer context paths
3+
--echo #
4+
5+
SELECT
6+
(
7+
WITH x AS
8+
(
9+
WITH RECURSIVE x ( x ) AS
10+
(
11+
SELECT 1 UNION SELECT x FROM x
12+
)
13+
SELECT * FROM x WHERE x IN
14+
(
15+
SELECT x FROM x WHERE
16+
(
17+
SELECT 1 GROUP BY x HAVING ( x )
18+
)
19+
)
20+
)
21+
SELECT * FROM x
22+
) AS R;
23+
24+
SELECT * FROM (
25+
WITH RECURSIVE x ( a ) AS ( SELECT 1 UNION SELECT a FROM x )
26+
SELECT * FROM x
27+
WHERE a IN (
28+
SELECT a FROM x WHERE ( SELECT 1 GROUP BY a HAVING ( a ) )
29+
)
30+
) as dt ;
31+
32+
create table t1 (a int) engine=myisam;
33+
insert into t1 values (1), (2);
34+
create table t2 (b int) engine=myisam;
35+
insert into t2 values (3), (1);
36+
create table t3 (c int) select a as c from t1;
37+
38+
select * from
39+
(
40+
with recursive x as ( select a from t1 union select a+1 from x where a < 4 )
41+
select * from x where a in
42+
(
43+
select a from x where
44+
(
45+
select b from t2 where b < 3 group by a having a > 0
46+
) <> 0
47+
)
48+
) dt;
49+
50+
select * from
51+
(
52+
with x as ( select distinct a from t1 )
53+
select * from x where a in
54+
(
55+
select a from x where
56+
(
57+
select b from t2 where b < 3 group by a having a > 0
58+
) <> 0
59+
)
60+
) dt;
61+
62+
select * from
63+
(
64+
select * from t1 where a in
65+
(
66+
select a from t1 where
67+
(
68+
select b from t2 where b < 3 group by a having a > 0
69+
) <> 0
70+
)
71+
) dt;
72+
73+
select * from
74+
(
75+
select * from t1 where a in
76+
(
77+
select a from t1 where
78+
(
79+
select b from t2 where b < 3 group by a
80+
) <> 0
81+
)
82+
) dt;
83+
84+
select * from
85+
(
86+
select * from t3 where c in
87+
(
88+
select a from t1 where
89+
(
90+
select b from t2 where b < 3 group by a
91+
) <> 0
92+
)
93+
) dt;
94+
95+
select * from
96+
(
97+
select * from t3 where c in
98+
(
99+
select a from t1 where
100+
(
101+
select b from t2 where a > 0 and b < 3
102+
) <> 0
103+
)
104+
) dt;
105+
106+
select * from
107+
(
108+
select * from t3 where c in
109+
(
110+
select a from t1 where
111+
(
112+
select b from t2 where a > 0 and b < 3
113+
) <> 0
114+
)
115+
) dt
116+
where dt.c > 1;
117+
118+
select * from
119+
(
120+
select * from t3 where c in
121+
(
122+
select a from t1 where
123+
(
124+
select b from t2
125+
where a > 0 and b < 3
126+
) <> 0
127+
)
128+
) dt;
129+
130+
let $q=
131+
with cte as
132+
( select * from t3 where c in
133+
(
134+
select a from t1 where
135+
(
136+
select b from t2 where a > 0 and b < 3
137+
) <> 0
138+
)
139+
)
140+
select * from cte;
141+
142+
eval prepare stmt from "$q";
143+
execute stmt;
144+
execute stmt;
145+
deallocate prepare stmt;
146+
147+
drop table t1, t2, t3;
148+
149+
--echo #
150+
--echo # End of 10.11 tests
151+
--echo #

sql/sql_lex.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3348,6 +3348,15 @@ void st_select_lex_unit::exclude_level()
33483348
SELECT_LEX_UNIT **last= 0;
33493349
for (SELECT_LEX_UNIT *u= sl->first_inner_unit(); u; u= u->next_unit())
33503350
{
3351+
for (SELECT_LEX *inner_sel= u->first_select();
3352+
inner_sel; inner_sel= inner_sel->next_select())
3353+
{
3354+
if (&sl->context == inner_sel->context.outer_context)
3355+
inner_sel->context.outer_context = &sl->outer_select()->context;
3356+
}
3357+
if (u->fake_select_lex &&
3358+
u->fake_select_lex->context.outer_context == &sl->context)
3359+
u->fake_select_lex->context.outer_context= &sl->outer_select()->context;
33513360
u->master= master;
33523361
last= (SELECT_LEX_UNIT**)&(u->next);
33533362
}

0 commit comments

Comments
 (0)