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

SQL, Tests: FOR SYSTEM_TIME for VIEWs [closes #98]

This commit is contained in:
kevg
2017-01-31 22:41:38 +03:00
committed by Aleksey Midenkov
parent 5853266fab
commit 7aa3ebdd18
8 changed files with 232 additions and 70 deletions

View File

@ -76,16 +76,12 @@ set @str= concat('
engine ', engine);
prepare stmt from @str; execute stmt; drop prepare stmt;
create view vt1_1 as select x, y from t1;
create view vt1_2 as select x, y, sys_end from t1;
insert into t1(x, y) values(8001, 9001);
insert into vt1_1(x, y) values(1001, 2001);
insert into vt1_1 values(1002, 2002);
insert into vt1_2(x, y) values(3001, 4001);
set @str= concat('select x, y, ', fields, ' from t1');
prepare stmt from @str; execute stmt; drop prepare stmt;
select x, y from vt1_1;
set @str= concat('select x, y, ', fields, ' from vt1_2');
prepare stmt from @str; execute stmt; drop prepare stmt;
end~~
create procedure test_04(
sys_type varchar(255),
@ -176,47 +172,23 @@ x y sys_end
8001 9001 2038-01-19 03:14:07.000000
1001 2001 2038-01-19 03:14:07.000000
1002 2002 2038-01-19 03:14:07.000000
3001 4001 2038-01-19 03:14:07.000000
x y
8001 9001
1001 2001
1002 2002
3001 4001
x y sys_end
8001 9001 2038-01-19 03:14:07.000000
1001 2001 2038-01-19 03:14:07.000000
1002 2002 2038-01-19 03:14:07.000000
3001 4001 2038-01-19 03:14:07.000000
insert into t1(x, y, sys_end) values(8001, 9001, '2015-1-1 1:1:1');
ERROR HY000: System field `sys_end` is read-only
insert into vt1_2 values(3002, 4002, '2015-2-2 2:2:2');
ERROR HY000: System field `sys_end` is read-only
drop table t1;
drop view vt1_1;
drop view vt1_2;
call test_03('bigint unsigned', 'innodb', 'vtq_commit_ts(sys_end)');
x y vtq_commit_ts(sys_end)
8001 9001 2038-01-19 03:14:07.000000
1001 2001 2038-01-19 03:14:07.000000
1002 2002 2038-01-19 03:14:07.000000
3001 4001 2038-01-19 03:14:07.000000
x y
8001 9001
1001 2001
1002 2002
3001 4001
x y vtq_commit_ts(sys_end)
8001 9001 2038-01-19 03:14:07.000000
1001 2001 2038-01-19 03:14:07.000000
1002 2002 2038-01-19 03:14:07.000000
3001 4001 2038-01-19 03:14:07.000000
insert into t1(x, y, sys_end) values(8001, 9001, 1111111);
ERROR HY000: System field `sys_end` is read-only
insert into vt1_2 values(3002, 4002, 2222222);
ERROR HY000: System field `sys_end` is read-only
drop table t1;
drop view vt1_1;
drop view vt1_2;
call test_04('timestamp(6)', 'myisam', 'sys_end');
id a b
1 1 1
@ -304,7 +276,6 @@ No A B C D
13 1 1 1 1
14 1 1 1 1
15 1 1 1 1
16 1 1 1 1
create table t1(
x int unsigned,
sys_start bigint unsigned generated always as row start,

View File

@ -12,10 +12,10 @@ set @vt2= concat("create view vt2 as select * from t1 for system_time as of time
prepare stmt from @vt2;
execute stmt;
drop prepare stmt;
select * from vt1;
select * from vt1 for system_time all;
x
1
select * from vt2;
select * from vt2 for system_time all;
x
2
select * from t1;
@ -23,7 +23,94 @@ x
create or replace view vt1 as select * from t1;
show create view vt1;
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` from `t1` where `t1`.`sys_trx_end` = 18446744073709551615 query for system_time all latin1 latin1_swedish_ci
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` = 18446744073709551615 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;
select * from vt1;
x
2
1
prepare stmt from 'select * from vt1';
execute stmt;
x
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;
x
2
1
prepare stmt from 'select * from vt1 for system_time as of timestamp @t1';
execute stmt;
x
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 view error_view as select *, sys_trx_start from t1;
ERROR 42S21: Duplicate column name 'sys_trx_start'
create view error_view as select *, sys_trx_end from t1;
ERROR 42S21: Duplicate column name 'sys_trx_end'
create or replace table t1 (x int) with system versioning;
insert into t1 values (1), (2);
set @t1=now(6);
delete from t1 where x=2;
set @t2=now(6);
delete from t1 where x=1;
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;
set @tmp= concat("create or replace view vvt1 as select * from vt1 for system_time as of timestamp '", @t2, "'");
prepare stmt from @tmp;
execute stmt;
drop prepare stmt;
set @tmp= concat("create or replace view vvvt1 as select * from vvt1 for system_time as of timestamp '", @t3, "'");
prepare stmt from @tmp;
execute stmt;
drop prepare stmt;
select * from vt1 for system_time all;
x
1
2
select * from vvt1 for system_time all;
x
1
select * from vvvt1 for system_time all;
x
drop view vvvt1;
drop view vvt1;
drop view vt1;
drop table t1;

View File

@ -64,16 +64,12 @@ begin
engine ', engine);
prepare stmt from @str; execute stmt; drop prepare stmt;
create view vt1_1 as select x, y from t1;
create view vt1_2 as select x, y, sys_end from t1;
insert into t1(x, y) values(8001, 9001);
insert into vt1_1(x, y) values(1001, 2001);
insert into vt1_1 values(1002, 2002);
insert into vt1_2(x, y) values(3001, 4001);
set @str= concat('select x, y, ', fields, ' from t1');
prepare stmt from @str; execute stmt; drop prepare stmt;
select x, y from vt1_1;
set @str= concat('select x, y, ', fields, ' from vt1_2');
prepare stmt from @str; execute stmt; drop prepare stmt;
end~~
create procedure test_04(
@ -150,22 +146,12 @@ call test_02('timestamp(6)', 'myisam', 'sys_end');
call test_02('bigint unsigned', 'innodb', 'vtq_commit_ts(sys_end)');
call test_03('timestamp(6)', 'myisam', 'sys_end');
--ERROR ER_VERS_READONLY_FIELD
insert into t1(x, y, sys_end) values(8001, 9001, '2015-1-1 1:1:1');
--ERROR ER_VERS_READONLY_FIELD
insert into vt1_2 values(3002, 4002, '2015-2-2 2:2:2');
drop table t1;
drop view vt1_1;
drop view vt1_2;
call test_03('bigint unsigned', 'innodb', 'vtq_commit_ts(sys_end)');
--ERROR ER_VERS_READONLY_FIELD
insert into t1(x, y, sys_end) values(8001, 9001, 1111111);
--ERROR ER_VERS_READONLY_FIELD
insert into vt1_2 values(3002, 4002, 2222222);
drop table t1;
drop view vt1_1;
drop view vt1_2;
call test_04('timestamp(6)', 'myisam', 'sys_end');
call test_04('bigint unsigned', 'innodb', 'vtq_commit_ts(sys_end)');

View File

@ -15,8 +15,8 @@ prepare stmt from @vt1; execute stmt; drop prepare stmt;
set @vt2= concat("create view vt2 as select * from t1 for system_time as of timestamp '", @t2, "'");
prepare stmt from @vt2; execute stmt; drop prepare stmt;
select * from vt1;
select * from vt2;
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;
@ -24,5 +24,53 @@ show create view vt1;
drop view vt1;
drop view vt2;
drop table t1;
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;
select * from vt1;
prepare stmt from 'select * from vt1'; 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;
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;
--error ER_DUP_FIELDNAME
create view error_view as select *, sys_trx_start from t1;
--error ER_DUP_FIELDNAME
create view error_view as select *, sys_trx_end from t1;
create or replace table t1 (x int) with system versioning;
insert into t1 values (1), (2);
set @t1=now(6);
delete from t1 where x=2;
set @t2=now(6);
delete from t1 where x=1;
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;
set @tmp= concat("create or replace view vvt1 as select * from vt1 for system_time as of timestamp '", @t2, "'");
prepare stmt from @tmp; execute stmt; drop prepare stmt;
set @tmp= concat("create or replace view vvvt1 as select * from vvt1 for system_time as of timestamp '", @t3, "'");
prepare stmt from @tmp; execute stmt; drop prepare stmt;
select * from vt1 for system_time all;
select * from vvt1 for system_time all;
select * from vvvt1 for system_time all;
drop view vvvt1;
drop view vvt1;
drop view vt1;
drop table t1;

View File

@ -7576,6 +7576,19 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name,
if (f->field->flags & HIDDEN_FLAG)
continue;
}
if (item->type() == Item::REF_ITEM)
{
Item *i= item;
while (i->type() == Item::REF_ITEM)
i= *((Item_ref *)i)->ref;
if (i->type() == Item::FIELD_ITEM)
{
Item_field *f= (Item_field *)i;
DBUG_ASSERT(f->field);
if (f->field->flags & HIDDEN_FLAG)
continue;
}
}
/* cache the table for the Item_fields inserted by expanding stars */
if (item->type() == Item::FIELD_ITEM && tables->cacheable_table)

View File

@ -684,6 +684,11 @@ int vers_setup_select(THD *thd, TABLE_LIST *tables, COND **where_expr,
DBUG_RETURN(0);
}
while (tables && tables->is_view() && !thd->stmt_arena->is_stmt_prepare())
{
tables= tables->view->select_lex.table_list.first;
}
for (table= tables; table; table= table->next_local)
{
if (table->table && table->table->versioned())
@ -790,10 +795,7 @@ int vers_setup_select(THD *thd, TABLE_LIST *tables, COND **where_expr,
}
if (vers_conditions.type == FOR_SYSTEM_TIME_ALL)
{
vers_conditions.unwrapped= true;
continue;
}
}
COND** dst_cond= where_expr;
@ -954,8 +956,6 @@ int vers_setup_select(THD *thd, TABLE_LIST *tables, COND **where_expr,
if (arena)
thd->restore_active_arena(arena, &backup);
slex->vers_conditions.unwrapped= true;
DBUG_RETURN(0);
#undef newx
}
@ -16728,6 +16728,8 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields,
List_iterator_fast<Item> li(fields);
Item *item;
Field **tmp_from_field=from_field;
Field *sys_trx_start= NULL;
Field *sys_trx_end= NULL;
while ((item=li++))
{
Item::Type type=item->type();
@ -16843,6 +16845,20 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields,
goto err; // Got OOM
continue; // Some kind of const item
}
if (type == Item::FIELD_ITEM)
{
Item_field *item_field= (Item_field *)item;
Field *field= item_field->field;
TABLE_SHARE *s= field->table->s;
if (s->versioned)
{
if (field->flags & VERS_SYS_START_FLAG)
sys_trx_start= new_field;
else if (field->flags & VERS_SYS_END_FLAG)
sys_trx_end= new_field;
}
}
if (type == Item::SUM_FUNC_ITEM)
{
Item_sum *agg_item= (Item_sum *) item;
@ -16923,6 +16939,17 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields,
total_uneven_bit_length= 0;
}
}
if (sys_trx_start && sys_trx_end)
{
sys_trx_start->flags|= VERS_SYS_START_FLAG | HIDDEN_FLAG;
sys_trx_end->flags|= VERS_SYS_END_FLAG | HIDDEN_FLAG;
share->versioned= true;
share->field= table->field;
share->row_start_field= field_count - 2;
share->row_end_field= field_count - 1;
}
DBUG_ASSERT(fieldnr == (uint) (reg_field - table->field));
DBUG_ASSERT(field_count >= (uint) (reg_field - table->field));
field_count= fieldnr;
@ -25416,6 +25443,11 @@ void TABLE_LIST::print(THD *thd, table_map eliminated_tables, String *str,
append_identifier(thd, str, t_alias, strlen(t_alias));
}
if (table && table->versioned())
{
// versioning conditions are already unwrapped to WHERE clause
str->append(" FOR SYSTEM_TIME ALL");
}
if (index_hints)
{
@ -25576,12 +25608,6 @@ void st_select_lex::print(THD *thd, String *str, enum_query_type query_type)
str->append(having_value != Item::COND_FALSE ? "1" : "0");
}
if (vers_conditions.unwrapped)
{
// versioning conditions are already unwrapped to WHERE clause
str->append(STRING_WITH_LEN(" query for system_time all "));
}
if (order_list.elements)
{
str->append(STRING_WITH_LEN(" order by "));

View File

@ -453,6 +453,26 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views,
goto err;
}
/* Implicitly add versioning fields if needed */
{
TABLE_LIST *tl = tables;
while (tl && tl->is_view())
tl = tl->view->select_lex.table_list.first;
if (tl && tl->table)
{
TABLE_SHARE *s= tl->table->s;
if (s->versioned)
{
select_lex->item_list.push_back(new (thd->mem_root) Item_field(
thd, &select_lex->context, NULL, NULL,
s->vers_start_field()->field_name));
select_lex->item_list.push_back(new (thd->mem_root) Item_field(
thd, &select_lex->context, NULL, NULL,
s->vers_end_field()->field_name));
}
}
}
view= lex->unlink_first_table(&link_to_local);
if (check_db_dir_existence(view->db))
@ -605,14 +625,22 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views,
view->table_name, item->name) &
VIEW_ANY_ACL);
if (fld && !fld->field->table->s->tmp_table)
if (!fld)
continue;
TABLE_SHARE *s= fld->field->table->s;
const char *field_name= fld->field->field_name;
if (s->tmp_table ||
(s->versioned &&
(!strcmp(field_name, s->vers_start_field()->field_name) ||
!strcmp(field_name, s->vers_end_field()->field_name))))
{
final_priv&= fld->have_privileges;
if (~fld->have_privileges & priv)
report_item= item;
continue;
}
final_priv&= fld->have_privileges;
if (~fld->have_privileges & priv)
report_item= item;
}
}
@ -2027,7 +2055,14 @@ bool insert_view_fields(THD *thd, List<Item> *list, TABLE_LIST *view)
{
Item_field *fld;
if ((fld= entry->item->field_for_view_update()))
{
TABLE_SHARE *s= fld->context->table_list->table->s;
if (s->versioned &&
(!strcmp(fld->name, s->vers_start_field()->field_name) ||
!strcmp(fld->name, s->vers_end_field()->field_name)))
continue;
list->push_back(fld, thd->mem_root);
}
else
{
my_error(ER_NON_INSERTABLE_TABLE, MYF(0), view->alias, "INSERT");

View File

@ -1864,14 +1864,11 @@ struct vers_select_conds_t
vers_range_unit_t unit;
Item *start, *end;
bool unwrapped;
void empty()
{
type= FOR_SYSTEM_TIME_UNSPECIFIED;
unit= UNIT_TIMESTAMP;
start= end= NULL;
unwrapped= false;
}
void init(
@ -1884,7 +1881,6 @@ struct vers_select_conds_t
unit= u;
start= s;
end= e;
unwrapped= false;
}
};