Commit e069de7d authored by kevg's avatar kevg Committed by Aleksey Midenkov

SQL: TRUNCATE FOR SYSTEM_TIME BEFORE [closes #111]

parent 3a64d55a
......@@ -111,5 +111,53 @@ select * from t for system_time all;
a
9
8
create or replace table t (a int) with system versioning;
insert into t values (1), (2);
update t set a=11 where a=1;
set @ts1=now(6);
update t set a=22 where a=2;
select * from t for system_time all;
a
11
22
1
2
truncate t for system_time before timestamp @ts1;
select * from t for system_time all;
a
11
22
2
truncate t for system_time before timestamp now(6);
select * from t for system_time all;
a
11
22
create or replace table t (a int) with system versioning engine=innodb;
insert into t values (1), (2);
update t set a=11 where a=1;
set @ts1=now(6);
update t set a=22 where a=2;
select * from t for system_time all;
a
11
22
1
2
truncate t for system_time before timestamp @ts1;
select * from t for system_time all;
a
11
22
1
2
truncate t for system_time before timestamp now(6);
select * from t for system_time all;
a
11
22
2
select * from t for system_time before timestamp now();
ERROR HY000: `FOR SYSTEM_TIME BEFORE` works only with `TRUNCATE` query type
drop table t;
drop procedure truncate_history_of_t;
......@@ -90,5 +90,30 @@ update t set a=9;
truncate t for system_time timestamp between '1-1-1' and @ts2;
select * from t for system_time all;
create or replace table t (a int) with system versioning;
insert into t values (1), (2);
update t set a=11 where a=1;
set @ts1=now(6);
update t set a=22 where a=2;
select * from t for system_time all;
truncate t for system_time before timestamp @ts1;
select * from t for system_time all;
truncate t for system_time before timestamp now(6);
select * from t for system_time all;
create or replace table t (a int) with system versioning engine=innodb;
insert into t values (1), (2);
update t set a=11 where a=1;
set @ts1=now(6);
update t set a=22 where a=2;
select * from t for system_time all;
truncate t for system_time before timestamp @ts1;
select * from t for system_time all;
truncate t for system_time before timestamp now(6);
select * from t for system_time all;
--error ER_VERS_WRONG_QUERY_TYPE
select * from t for system_time before timestamp now();
drop table t;
drop procedure truncate_history_of_t;
......@@ -7525,3 +7525,6 @@ WARN_VERS_PART_ROTATION
ER_VERS_NOT_ALLOWED
eng "%`s is not allowed for versioned table"
ER_VERS_WRONG_QUERY_TYPE
eng "%`s works only with %`s query type"
......@@ -283,12 +283,17 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
DBUG_RETURN(TRUE);
// trx_sees() in InnoDB reads sys_trx_start
if (!table->versioned_by_sql() &&
(select_lex->vers_conditions.type == FOR_SYSTEM_TIME_BETWEEN ||
select_lex->vers_conditions.type == FOR_SYSTEM_TIME_FROM_TO))
if (!table->versioned_by_sql()) {
if (select_lex->vers_conditions.type == FOR_SYSTEM_TIME_BETWEEN ||
select_lex->vers_conditions.type == FOR_SYSTEM_TIME_FROM_TO)
{
bitmap_set_bit(table->read_set, table->vers_start_field()->field_index);
}
else if (select_lex->vers_conditions.type == FOR_SYSTEM_TIME_BEFORE)
{
bitmap_set_bit(table->read_set, table->vers_end_field()->field_index);
}
}
}
if (mysql_handle_list_of_derived(thd->lex, table_list, DT_MERGE_FOR_INSERT))
......
......@@ -762,6 +762,14 @@ int vers_setup_select(THD *thd, TABLE_LIST *tables, COND **where_expr,
table->vers_conditions.type == FOR_SYSTEM_TIME_UNSPECIFIED ?
slex->vers_conditions : table->vers_conditions;
if (vers_conditions.type == FOR_SYSTEM_TIME_BEFORE &&
thd->lex->sql_command != SQLCOM_TRUNCATE)
{
my_error(ER_VERS_WRONG_QUERY_TYPE, MYF(0), "FOR SYSTEM_TIME BEFORE",
"TRUNCATE");
DBUG_RETURN(-1);
}
if (vers_conditions.type != FOR_SYSTEM_TIME_UNSPECIFIED)
{
switch (slex->lock_type)
......@@ -869,6 +877,10 @@ int vers_setup_select(THD *thd, TABLE_LIST *tables, COND **where_expr,
cond2= newx Item_func_ge(thd, row_end,
vers_conditions.start);
break;
case FOR_SYSTEM_TIME_BEFORE:
cond1= newx Item_func_lt(thd, row_end,
vers_conditions.start);
break;
default:
DBUG_ASSERT(0);
}
......@@ -912,6 +924,12 @@ int vers_setup_select(THD *thd, TABLE_LIST *tables, COND **where_expr,
newx Item_func_vtq_trx_sees_eq(thd, trx_id1, row_start);
cond2= newx Item_func_vtq_trx_sees_eq(thd, row_end, trx_id0);
break;
case FOR_SYSTEM_TIME_BEFORE:
trx_id0= vers_conditions.unit == UNIT_TIMESTAMP ?
newx Item_func_vtq_id(thd, vers_conditions.start, VTQ_TRX_ID) :
vers_conditions.start;
cond1= newx Item_func_lt(thd, row_end, trx_id0);
break;
default:
DBUG_ASSERT(0);
}
......
......@@ -8880,6 +8880,12 @@ for_system_time_expr:
{
Lex->vers_conditions.init(FOR_SYSTEM_TIME_BETWEEN, $1, $3, $5);
}
| BEFORE_SYM
trans_or_timestamp
simple_expr
{
Lex->vers_conditions.init(FOR_SYSTEM_TIME_BEFORE, $2, $3);
}
;
select_option_list:
......
......@@ -1847,7 +1847,8 @@ enum vers_range_type_t
FOR_SYSTEM_TIME_AS_OF,
FOR_SYSTEM_TIME_FROM_TO,
FOR_SYSTEM_TIME_BETWEEN,
FOR_SYSTEM_TIME_ALL
FOR_SYSTEM_TIME_ALL,
FOR_SYSTEM_TIME_BEFORE
};
enum vers_range_unit_t
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment