1
0
mirror of https://github.com/MariaDB/server.git synced 2025-05-08 15:01:49 +03:00

SQL: derived SYSTEM_TIME clash detection [closes #371]

This commit is contained in:
Aleksey Midenkov 2017-12-06 06:14:22 +03:00
parent d04063c5b9
commit 84b718ae70
9 changed files with 145 additions and 75 deletions

View File

@ -42,7 +42,26 @@ from emp for system_time as of timestamp @ts_1 as e,
ancestors as a
where e.mgr = a.emp_id
)
select * from ancestors for system_time as of current_timestamp;
select * from ancestors;
emp_id name mgr salary
1 bill NULL 1000
20 john 1 500
30 jane 1 750
with recursive
ancestors
as
(
select e.emp_id, e.name, e.mgr, e.salary
from emp as e
where name = 'bill'
union
select e.emp_id, e.name, e.mgr, e.salary
from emp as e,
ancestors as a
where e.mgr = a.emp_id
)
select * from ancestors
for system_time as of timestamp @ts_1;
emp_id name mgr salary
1 bill NULL 1000
30 jane 1 750

View File

@ -133,25 +133,28 @@ create or replace table t1 (x int) with system versioning;
create or replace table t2 (y int) with system versioning;
insert into t1 values (1);
set @t0= now(6);
delete from t1;
insert into t1 values (2);
delete from t1 where x = 1;
insert into t2 values (10);
select * from (select *, t1.sys_trx_end, t1.sys_trx_end as endo from t1) as s0;
ERROR HY000: Derived table is prohibited: multiple end system fields `t1.sys_trx_end`, `t1.sys_trx_end` in query!
select * from (select *, t1.sys_trx_end, t2.sys_trx_start from t1, t2) as s0;
ERROR HY000: Derived table is prohibited: system fields from multiple tables `t1`, `t2` in query!
# SYSTEM_TIME propagation from inner to outer
select * from (select * from t1 for system_time as of timestamp @t0, t2) as s0;
x y
1 10
with s1 as (select * from t1 for system_time as of timestamp @t0, t2) select * from s1;
x y
1 10
# leading table selection
select * from (select *, t1.sys_trx_end from t2, t1 for system_time as of timestamp @t0) as s2;
y x
10 1
with s3 as (select *, t1.sys_trx_end from t2, t1 for system_time as of timestamp @t0) select * from s3;
y x
10 1
# SYSTEM_TIME propagation from outer to inner
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;
y x
10 1
@ -161,21 +164,56 @@ y x
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;
y x
10 1
### VIEW instead of t1
set @q= concat("create view vt1 as select * from t1 for system_time as of timestamp '", @t0, "'");
prepare q from @q;
execute q;
drop prepare q;
create view vt2 as select * from t1;
# SYSTEM_TIME propagation from view
select * from vt1;
x
1
# SYSTEM_TIME propagation from inner to outer
select * from (select * from vt1, t2) as s0;
x y
1 10
# leading table selection
select * from (select *, vt1.sys_trx_end from t2, vt1) as s0;
y x
10 1
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;
y x
10 1
drop table t1, t2;
drop view vt1;
### SYSTEM_TIME clash
select * from (select * from t1 for system_time all) dt0 for system_time all;
ERROR HY000: SYSTEM_TIME is not allowed outside historical `dt0`
select * from vt1 for system_time all;
ERROR HY000: SYSTEM_TIME is not allowed outside historical `vt1`
with dt1 as (select * from t1 for system_time all)
select * from dt1 for system_time all;
ERROR HY000: SYSTEM_TIME is not allowed outside historical `dt1`
### UNION
set @t1= now(6);
delete from t2;
insert into t2 values (3);
# SYSTEM_TIME is not propagated
select x from t1 union
select y from t2;
x
2
3
select x from t1 for system_time as of @t0 union
select y from t2;
x
1
3
select x from t1 union
select y from t2 for system_time as of @t1;
x
2
10
select x from t1 for system_time as of @t0 union
select y from t2 for system_time as of @t1;
x
1
10
drop database test;
create database test;

View File

@ -12,12 +12,6 @@ set @vt2= concat("create or replace view vt2 as select *, sys_trx_end from t1 fo
prepare stmt from @vt2;
execute stmt;
drop prepare stmt;
select * from vt1 for system_time all;
x
1
select * from vt2 for system_time all;
x
2
select * from t1;
x
create or replace view vt1 as select * from t1;
@ -26,17 +20,7 @@ View Create View character_set_client collation_connection
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
drop view vt1;
drop view vt2;
create view vt1 as select * from t1 for system_time all;
select * from vt1 for system_time all;
x
2
1
prepare stmt from 'select * from vt1 for system_time all';
execute stmt;
x
2
1
drop prepare stmt;
create or replace view vt1 as select * from t1 for system_time all;
select * from vt1;
x
2
@ -47,39 +31,24 @@ x
2
1
drop prepare stmt;
set @str= concat('create or replace view vt1 as
select * from t1 for system_time as of timestamp "', @t1, '"');
prepare stmt from @str;
execute stmt;
drop prepare stmt;
select * from t1 for system_time as of timestamp @t1;
x
1
select * from vt1 for system_time as of timestamp @t1;
select * from vt1;
x
1
prepare stmt from 'select * from vt1 for system_time as of timestamp @t1';
execute stmt;
x
1
drop prepare stmt;
create or replace view vt1 as select * from t1;
select * from vt1 for system_time all;
x
prepare stmt from 'select * from vt1 for system_time all';
execute stmt;
x
drop prepare stmt;
insert into vt1 values (3);
select * from t1;
x
3
select * from vt1;
x
3
select * from t1 for system_time all;
x
2
1
3
select * from vt1 for system_time all;
x
3
create or replace table t1 (x int) with system versioning;
insert into t1 values (1), (2);
set @t1=now(6);
@ -91,7 +60,7 @@ set @tmp= concat("create or replace view vt1 as select * from t1 for system_time
prepare stmt from @tmp;
execute stmt;
drop prepare stmt;
select * from vt1 for system_time all;
select * from vt1;
x
1
2

View File

@ -49,7 +49,23 @@ as
ancestors as a
where e.mgr = a.emp_id
)
select * from ancestors for system_time as of current_timestamp;
select * from ancestors;
with recursive
ancestors
as
(
select e.emp_id, e.name, e.mgr, e.salary
from emp as e
where name = 'bill'
union
select e.emp_id, e.name, e.mgr, e.salary
from emp as e,
ancestors as a
where e.mgr = a.emp_id
)
select * from ancestors
for system_time as of timestamp @ts_1;
/* Expected 3 rows */
with recursive

View File

@ -96,8 +96,8 @@ create or replace table t1 (x int) with system versioning;
create or replace table t2 (y int) with system versioning;
insert into t1 values (1);
set @t0= now(6);
delete from t1;
insert into t1 values (2);
delete from t1 where x = 1;
insert into t2 values (10);
--error ER_VERS_DERIVED_PROHIBITED
@ -105,29 +105,51 @@ select * from (select *, t1.sys_trx_end, t1.sys_trx_end as endo from t1) as s0;
--error ER_VERS_DERIVED_PROHIBITED
select * from (select *, t1.sys_trx_end, t2.sys_trx_start from t1, t2) as s0;
# system_time propagation from inner to outer
--echo # SYSTEM_TIME propagation from inner to outer
select * from (select * from t1 for system_time as of timestamp @t0, t2) as s0;
with s1 as (select * from t1 for system_time as of timestamp @t0, t2) select * from s1;
# leading table selection
--echo # leading table selection
select * from (select *, t1.sys_trx_end from t2, t1 for system_time as of timestamp @t0) as s2;
with s3 as (select *, t1.sys_trx_end from t2, t1 for system_time as of timestamp @t0) select * from s3;
# system_time propagation from outer to inner
--echo # SYSTEM_TIME propagation from outer to inner
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;
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;
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;
# VIEW instead of t1
--echo ### VIEW instead of t1
set @q= concat("create view vt1 as select * from t1 for system_time as of timestamp '", @t0, "'");
prepare q from @q; execute q; drop prepare q;
create view vt2 as select * from t1;
# system_time propagation from view
--echo # SYSTEM_TIME propagation from view
select * from vt1;
# system_time propagation from inner to outer
--echo # SYSTEM_TIME propagation from inner to outer
select * from (select * from vt1, t2) as s0;
# leading table selection
--echo # leading table selection
select * from (select *, vt1.sys_trx_end from t2, vt1) as s0;
# system_time propagation from outer to inner
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;
drop table t1, t2;
drop view vt1;
--echo ### SYSTEM_TIME clash
--error ER_VERS_SYSTEM_TIME_CLASH
select * from (select * from t1 for system_time all) dt0 for system_time all;
--error ER_VERS_SYSTEM_TIME_CLASH
select * from vt1 for system_time all;
--error ER_VERS_SYSTEM_TIME_CLASH
with dt1 as (select * from t1 for system_time all)
select * from dt1 for system_time all;
--echo ### UNION
set @t1= now(6);
delete from t2;
insert into t2 values (3);
--echo # SYSTEM_TIME is not propagated
select x from t1 union
select y from t2;
select x from t1 for system_time as of @t0 union
select y from t2;
select x from t1 union
select y from t2 for system_time as of @t1;
select x from t1 for system_time as of @t0 union
select y from t2 for system_time as of @t1;
drop database test;
create database test;

View File

@ -16,8 +16,6 @@ prepare stmt from @vt1; execute stmt; drop prepare stmt;
set @vt2= concat("create or replace view vt2 as select *, sys_trx_end from t1 for system_time as of timestamp '", @t2, "'");
prepare stmt from @vt2; execute stmt; drop prepare stmt;
select * from vt1 for system_time all;
select * from vt2 for system_time all;
select * from t1;
create or replace view vt1 as select * from t1;
@ -27,26 +25,19 @@ show create view vt1;
drop view vt1;
drop view vt2;
create view vt1 as select * from t1 for system_time all;
select * from vt1 for system_time all;
prepare stmt from 'select * from vt1 for system_time all'; execute stmt; drop prepare stmt;
create or replace view vt1 as select * from t1 for system_time all;
select * from vt1;
prepare stmt from 'select * from vt1'; execute stmt; drop prepare stmt;
set @str= concat('create or replace view vt1 as
select * from t1 for system_time as of timestamp "', @t1, '"');
prepare stmt from @str; execute stmt; drop prepare stmt;
select * from t1 for system_time as of timestamp @t1;
select * from vt1 for system_time as of timestamp @t1;
prepare stmt from 'select * from vt1 for system_time as of timestamp @t1'; execute stmt; drop prepare stmt;
create or replace view vt1 as select * from t1;
select * from vt1 for system_time all;
prepare stmt from 'select * from vt1 for system_time all'; execute stmt; drop prepare stmt;
select * from vt1;
insert into vt1 values (3);
select * from t1;
select * from vt1;
select * from t1 for system_time all;
select * from vt1 for system_time all;
create or replace table t1 (x int) with system versioning;
insert into t1 values (1), (2);
@ -59,7 +50,7 @@ set @t3=now(6);
set @tmp= concat("create or replace view vt1 as select * from t1 for system_time as of timestamp '", @t1, "'");
prepare stmt from @tmp; execute stmt; drop prepare stmt;
select * from vt1 for system_time all;
select * from vt1;
--echo # VIEW with parameters [#151]
create or replace table t1 (x int) with system versioning;

View File

@ -7857,6 +7857,9 @@ ER_VERS_VIEW_PROHIBITED
ER_VERS_DERIVED_PROHIBITED
eng "Derived table is prohibited!"
ER_VERS_SYSTEM_TIME_CLASH
eng "SYSTEM_TIME is not allowed outside historical %`s"
ER_VERS_UNUSED_CLAUSE
eng "Unused clause: '%s'"

View File

@ -575,6 +575,10 @@ public:
*/
uint8 uncacheable;
enum sub_select_type linkage;
bool is_linkage_set() const
{
return linkage == UNION_TYPE || linkage == INTERSECT_TYPE || linkage == EXCEPT_TYPE;
}
bool no_table_names_allowed; /* used for global order by */
static void *operator new(size_t size, MEM_ROOT *mem_root) throw ()

View File

@ -773,7 +773,15 @@ int vers_setup_select(THD *thd, TABLE_LIST *tables, COND **where_expr,
{
for (table= outer_slex->table_list.first; table; table= table->next_local)
{
if (!table->vers_conditions)
if (table->vers_conditions)
{
if (!slex->is_linkage_set() && !table->vers_conditions.from_inner)
{
my_error(ER_VERS_SYSTEM_TIME_CLASH, MYF(0), table->alias);
DBUG_RETURN(-1);
}
}
else
{
table->vers_conditions= slex->vers_export_outer;
table->vers_conditions.from_inner= true;