Skip to content

Commit 84b718a

Browse files
committed
SQL: derived SYSTEM_TIME clash detection [closes #371]
1 parent d04063c commit 84b718a

File tree

9 files changed

+145
-75
lines changed

9 files changed

+145
-75
lines changed

mysql-test/suite/versioning/r/cte.result

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,26 @@ from emp for system_time as of timestamp @ts_1 as e,
4242
ancestors as a
4343
where e.mgr = a.emp_id
4444
)
45-
select * from ancestors for system_time as of current_timestamp;
45+
select * from ancestors;
46+
emp_id name mgr salary
47+
1 bill NULL 1000
48+
20 john 1 500
49+
30 jane 1 750
50+
with recursive
51+
ancestors
52+
as
53+
(
54+
select e.emp_id, e.name, e.mgr, e.salary
55+
from emp as e
56+
where name = 'bill'
57+
union
58+
select e.emp_id, e.name, e.mgr, e.salary
59+
from emp as e,
60+
ancestors as a
61+
where e.mgr = a.emp_id
62+
)
63+
select * from ancestors
64+
for system_time as of timestamp @ts_1;
4665
emp_id name mgr salary
4766
1 bill NULL 1000
4867
30 jane 1 750

mysql-test/suite/versioning/r/derived.result

Lines changed: 44 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -133,25 +133,28 @@ create or replace table t1 (x int) with system versioning;
133133
create or replace table t2 (y int) with system versioning;
134134
insert into t1 values (1);
135135
set @t0= now(6);
136+
delete from t1;
136137
insert into t1 values (2);
137-
delete from t1 where x = 1;
138138
insert into t2 values (10);
139139
select * from (select *, t1.sys_trx_end, t1.sys_trx_end as endo from t1) as s0;
140140
ERROR HY000: Derived table is prohibited: multiple end system fields `t1.sys_trx_end`, `t1.sys_trx_end` in query!
141141
select * from (select *, t1.sys_trx_end, t2.sys_trx_start from t1, t2) as s0;
142142
ERROR HY000: Derived table is prohibited: system fields from multiple tables `t1`, `t2` in query!
143+
# SYSTEM_TIME propagation from inner to outer
143144
select * from (select * from t1 for system_time as of timestamp @t0, t2) as s0;
144145
x y
145146
1 10
146147
with s1 as (select * from t1 for system_time as of timestamp @t0, t2) select * from s1;
147148
x y
148149
1 10
150+
# leading table selection
149151
select * from (select *, t1.sys_trx_end from t2, t1 for system_time as of timestamp @t0) as s2;
150152
y x
151153
10 1
152154
with s3 as (select *, t1.sys_trx_end from t2, t1 for system_time as of timestamp @t0) select * from s3;
153155
y x
154156
10 1
157+
# SYSTEM_TIME propagation from outer to inner
155158
select * from (select *, t1.sys_trx_start from t2 for system_time as of current_timestamp, t1) as s4 for system_time as of timestamp @t0;
156159
y x
157160
10 1
@@ -161,21 +164,56 @@ y x
161164
with s6 as (select *, t1.sys_trx_start from t2 for system_time as of current_timestamp, t1) select * from s6 for system_time as of timestamp @t0;
162165
y x
163166
10 1
167+
### VIEW instead of t1
164168
set @q= concat("create view vt1 as select * from t1 for system_time as of timestamp '", @t0, "'");
165169
prepare q from @q;
166170
execute q;
167171
drop prepare q;
172+
create view vt2 as select * from t1;
173+
# SYSTEM_TIME propagation from view
168174
select * from vt1;
169175
x
170176
1
177+
# SYSTEM_TIME propagation from inner to outer
171178
select * from (select * from vt1, t2) as s0;
172179
x y
173180
1 10
181+
# leading table selection
174182
select * from (select *, vt1.sys_trx_end from t2, vt1) as s0;
175183
y x
176184
10 1
177-
select * from (select *, vt1.sys_trx_start from t2 for system_time as of current_timestamp, vt1) as s0 for system_time as of timestamp @t0;
178-
y x
179-
10 1
180-
drop table t1, t2;
181-
drop view vt1;
185+
### SYSTEM_TIME clash
186+
select * from (select * from t1 for system_time all) dt0 for system_time all;
187+
ERROR HY000: SYSTEM_TIME is not allowed outside historical `dt0`
188+
select * from vt1 for system_time all;
189+
ERROR HY000: SYSTEM_TIME is not allowed outside historical `vt1`
190+
with dt1 as (select * from t1 for system_time all)
191+
select * from dt1 for system_time all;
192+
ERROR HY000: SYSTEM_TIME is not allowed outside historical `dt1`
193+
### UNION
194+
set @t1= now(6);
195+
delete from t2;
196+
insert into t2 values (3);
197+
# SYSTEM_TIME is not propagated
198+
select x from t1 union
199+
select y from t2;
200+
x
201+
2
202+
3
203+
select x from t1 for system_time as of @t0 union
204+
select y from t2;
205+
x
206+
1
207+
3
208+
select x from t1 union
209+
select y from t2 for system_time as of @t1;
210+
x
211+
2
212+
10
213+
select x from t1 for system_time as of @t0 union
214+
select y from t2 for system_time as of @t1;
215+
x
216+
1
217+
10
218+
drop database test;
219+
create database test;

mysql-test/suite/versioning/r/view.result

Lines changed: 8 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,6 @@ set @vt2= concat("create or replace view vt2 as select *, sys_trx_end from t1 fo
1212
prepare stmt from @vt2;
1313
execute stmt;
1414
drop prepare stmt;
15-
select * from vt1 for system_time all;
16-
x
17-
1
18-
select * from vt2 for system_time all;
19-
x
20-
2
2115
select * from t1;
2216
x
2317
create or replace view vt1 as select * from t1;
@@ -26,17 +20,7 @@ View Create View character_set_client collation_connection
2620
vt1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `vt1` AS select `t1`.`x` AS `x`,`t1`.`sys_trx_start` AS `sys_trx_start`,`t1`.`sys_trx_end` AS `sys_trx_end` from `t1` FOR SYSTEM_TIME ALL where `t1`.`sys_trx_end` = MAX_RESULT latin1 latin1_swedish_ci
2721
drop view vt1;
2822
drop view vt2;
29-
create view vt1 as select * from t1 for system_time all;
30-
select * from vt1 for system_time all;
31-
x
32-
2
33-
1
34-
prepare stmt from 'select * from vt1 for system_time all';
35-
execute stmt;
36-
x
37-
2
38-
1
39-
drop prepare stmt;
23+
create or replace view vt1 as select * from t1 for system_time all;
4024
select * from vt1;
4125
x
4226
2
@@ -47,39 +31,24 @@ x
4731
2
4832
1
4933
drop prepare stmt;
34+
set @str= concat('create or replace view vt1 as
35+
select * from t1 for system_time as of timestamp "', @t1, '"');
36+
prepare stmt from @str;
37+
execute stmt;
38+
drop prepare stmt;
5039
select * from t1 for system_time as of timestamp @t1;
5140
x
5241
1
53-
select * from vt1 for system_time as of timestamp @t1;
54-
x
55-
1
56-
prepare stmt from 'select * from vt1 for system_time as of timestamp @t1';
57-
execute stmt;
42+
select * from vt1;
5843
x
5944
1
60-
drop prepare stmt;
61-
create or replace view vt1 as select * from t1;
62-
select * from vt1 for system_time all;
63-
x
64-
prepare stmt from 'select * from vt1 for system_time all';
65-
execute stmt;
66-
x
67-
drop prepare stmt;
6845
insert into vt1 values (3);
6946
select * from t1;
7047
x
7148
3
7249
select * from vt1;
7350
x
74-
3
75-
select * from t1 for system_time all;
76-
x
77-
2
7851
1
79-
3
80-
select * from vt1 for system_time all;
81-
x
82-
3
8352
create or replace table t1 (x int) with system versioning;
8453
insert into t1 values (1), (2);
8554
set @t1=now(6);
@@ -91,7 +60,7 @@ set @tmp= concat("create or replace view vt1 as select * from t1 for system_time
9160
prepare stmt from @tmp;
9261
execute stmt;
9362
drop prepare stmt;
94-
select * from vt1 for system_time all;
63+
select * from vt1;
9564
x
9665
1
9766
2

mysql-test/suite/versioning/t/cte.test

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,23 @@ as
4949
ancestors as a
5050
where e.mgr = a.emp_id
5151
)
52-
select * from ancestors for system_time as of current_timestamp;
52+
select * from ancestors;
53+
54+
with recursive
55+
ancestors
56+
as
57+
(
58+
select e.emp_id, e.name, e.mgr, e.salary
59+
from emp as e
60+
where name = 'bill'
61+
union
62+
select e.emp_id, e.name, e.mgr, e.salary
63+
from emp as e,
64+
ancestors as a
65+
where e.mgr = a.emp_id
66+
)
67+
select * from ancestors
68+
for system_time as of timestamp @ts_1;
5369

5470
/* Expected 3 rows */
5571
with recursive

mysql-test/suite/versioning/t/derived.test

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -96,38 +96,60 @@ create or replace table t1 (x int) with system versioning;
9696
create or replace table t2 (y int) with system versioning;
9797
insert into t1 values (1);
9898
set @t0= now(6);
99+
delete from t1;
99100
insert into t1 values (2);
100-
delete from t1 where x = 1;
101101
insert into t2 values (10);
102102

103103
--error ER_VERS_DERIVED_PROHIBITED
104104
select * from (select *, t1.sys_trx_end, t1.sys_trx_end as endo from t1) as s0;
105105
--error ER_VERS_DERIVED_PROHIBITED
106106
select * from (select *, t1.sys_trx_end, t2.sys_trx_start from t1, t2) as s0;
107107

108-
# system_time propagation from inner to outer
108+
--echo # SYSTEM_TIME propagation from inner to outer
109109
select * from (select * from t1 for system_time as of timestamp @t0, t2) as s0;
110110
with s1 as (select * from t1 for system_time as of timestamp @t0, t2) select * from s1;
111-
# leading table selection
111+
--echo # leading table selection
112112
select * from (select *, t1.sys_trx_end from t2, t1 for system_time as of timestamp @t0) as s2;
113113
with s3 as (select *, t1.sys_trx_end from t2, t1 for system_time as of timestamp @t0) select * from s3;
114-
# system_time propagation from outer to inner
114+
--echo # SYSTEM_TIME propagation from outer to inner
115115
select * from (select *, t1.sys_trx_start from t2 for system_time as of current_timestamp, t1) as s4 for system_time as of timestamp @t0;
116116
with s5 as (select *, t1.sys_trx_start from t2 for system_time as of current_timestamp, t1) select * from s5 for system_time as of timestamp @t0;
117117
with s6 as (select *, t1.sys_trx_start from t2 for system_time as of current_timestamp, t1) select * from s6 for system_time as of timestamp @t0;
118118

119-
# VIEW instead of t1
119+
--echo ### VIEW instead of t1
120120
set @q= concat("create view vt1 as select * from t1 for system_time as of timestamp '", @t0, "'");
121121
prepare q from @q; execute q; drop prepare q;
122+
create view vt2 as select * from t1;
122123

123-
# system_time propagation from view
124+
--echo # SYSTEM_TIME propagation from view
124125
select * from vt1;
125-
# system_time propagation from inner to outer
126+
--echo # SYSTEM_TIME propagation from inner to outer
126127
select * from (select * from vt1, t2) as s0;
127-
# leading table selection
128+
--echo # leading table selection
128129
select * from (select *, vt1.sys_trx_end from t2, vt1) as s0;
129-
# system_time propagation from outer to inner
130-
select * from (select *, vt1.sys_trx_start from t2 for system_time as of current_timestamp, vt1) as s0 for system_time as of timestamp @t0;
131130

132-
drop table t1, t2;
133-
drop view vt1;
131+
--echo ### SYSTEM_TIME clash
132+
--error ER_VERS_SYSTEM_TIME_CLASH
133+
select * from (select * from t1 for system_time all) dt0 for system_time all;
134+
--error ER_VERS_SYSTEM_TIME_CLASH
135+
select * from vt1 for system_time all;
136+
--error ER_VERS_SYSTEM_TIME_CLASH
137+
with dt1 as (select * from t1 for system_time all)
138+
select * from dt1 for system_time all;
139+
140+
--echo ### UNION
141+
set @t1= now(6);
142+
delete from t2;
143+
insert into t2 values (3);
144+
--echo # SYSTEM_TIME is not propagated
145+
select x from t1 union
146+
select y from t2;
147+
select x from t1 for system_time as of @t0 union
148+
select y from t2;
149+
select x from t1 union
150+
select y from t2 for system_time as of @t1;
151+
select x from t1 for system_time as of @t0 union
152+
select y from t2 for system_time as of @t1;
153+
154+
drop database test;
155+
create database test;

mysql-test/suite/versioning/t/view.test

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@ prepare stmt from @vt1; execute stmt; drop prepare stmt;
1616
set @vt2= concat("create or replace view vt2 as select *, sys_trx_end from t1 for system_time as of timestamp '", @t2, "'");
1717
prepare stmt from @vt2; execute stmt; drop prepare stmt;
1818

19-
select * from vt1 for system_time all;
20-
select * from vt2 for system_time all;
2119
select * from t1;
2220

2321
create or replace view vt1 as select * from t1;
@@ -27,26 +25,19 @@ show create view vt1;
2725
drop view vt1;
2826
drop view vt2;
2927

30-
create view vt1 as select * from t1 for system_time all;
31-
select * from vt1 for system_time all;
32-
prepare stmt from 'select * from vt1 for system_time all'; execute stmt; drop prepare stmt;
33-
28+
create or replace view vt1 as select * from t1 for system_time all;
3429
select * from vt1;
3530
prepare stmt from 'select * from vt1'; execute stmt; drop prepare stmt;
3631

32+
set @str= concat('create or replace view vt1 as
33+
select * from t1 for system_time as of timestamp "', @t1, '"');
34+
prepare stmt from @str; execute stmt; drop prepare stmt;
3735
select * from t1 for system_time as of timestamp @t1;
38-
select * from vt1 for system_time as of timestamp @t1;
39-
prepare stmt from 'select * from vt1 for system_time as of timestamp @t1'; execute stmt; drop prepare stmt;
40-
41-
create or replace view vt1 as select * from t1;
42-
select * from vt1 for system_time all;
43-
prepare stmt from 'select * from vt1 for system_time all'; execute stmt; drop prepare stmt;
36+
select * from vt1;
4437

4538
insert into vt1 values (3);
4639
select * from t1;
4740
select * from vt1;
48-
select * from t1 for system_time all;
49-
select * from vt1 for system_time all;
5041

5142
create or replace table t1 (x int) with system versioning;
5243
insert into t1 values (1), (2);
@@ -59,7 +50,7 @@ set @t3=now(6);
5950
set @tmp= concat("create or replace view vt1 as select * from t1 for system_time as of timestamp '", @t1, "'");
6051
prepare stmt from @tmp; execute stmt; drop prepare stmt;
6152

62-
select * from vt1 for system_time all;
53+
select * from vt1;
6354

6455
--echo # VIEW with parameters [#151]
6556
create or replace table t1 (x int) with system versioning;

sql/share/errmsg-utf8.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7857,6 +7857,9 @@ ER_VERS_VIEW_PROHIBITED
78577857
ER_VERS_DERIVED_PROHIBITED
78587858
eng "Derived table is prohibited!"
78597859

7860+
ER_VERS_SYSTEM_TIME_CLASH
7861+
eng "SYSTEM_TIME is not allowed outside historical %`s"
7862+
78607863
ER_VERS_UNUSED_CLAUSE
78617864
eng "Unused clause: '%s'"
78627865

sql/sql_lex.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -575,6 +575,10 @@ class st_select_lex_node {
575575
*/
576576
uint8 uncacheable;
577577
enum sub_select_type linkage;
578+
bool is_linkage_set() const
579+
{
580+
return linkage == UNION_TYPE || linkage == INTERSECT_TYPE || linkage == EXCEPT_TYPE;
581+
}
578582
bool no_table_names_allowed; /* used for global order by */
579583

580584
static void *operator new(size_t size, MEM_ROOT *mem_root) throw ()

sql/sql_select.cc

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -773,7 +773,15 @@ int vers_setup_select(THD *thd, TABLE_LIST *tables, COND **where_expr,
773773
{
774774
for (table= outer_slex->table_list.first; table; table= table->next_local)
775775
{
776-
if (!table->vers_conditions)
776+
if (table->vers_conditions)
777+
{
778+
if (!slex->is_linkage_set() && !table->vers_conditions.from_inner)
779+
{
780+
my_error(ER_VERS_SYSTEM_TIME_CLASH, MYF(0), table->alias);
781+
DBUG_RETURN(-1);
782+
}
783+
}
784+
else
777785
{
778786
table->vers_conditions= slex->vers_export_outer;
779787
table->vers_conditions.from_inner= true;

0 commit comments

Comments
 (0)