Skip to content

Commit 6d73282

Browse files
committed
MDEV-25468 DELETE HISTORY may delete current data on system-versioned table
Item_func_history (is_history()) is a bool function that checks if the row is the history row by checking row_end->is_max(). The argument to this function must be row_end system field. Added the above function to conjunction with SYSTEM_TIME_BEFORE versioning condition.
1 parent 29b2f3d commit 6d73282

File tree

5 files changed

+105
-2
lines changed

5 files changed

+105
-2
lines changed

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

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,3 +129,36 @@ select * from t1;
129129
a
130130
1
131131
drop table t1;
132+
#
133+
# MDEV-25468 DELETE HISTORY may delete current data on system-versioned table
134+
#
135+
create or replace table t1 (x int) with system versioning;
136+
insert into t1 values (1);
137+
delete history from t1 before system_time '2039-01-01 23:00';
138+
select * from t1;
139+
x
140+
1
141+
explain extended delete history from t1 before system_time '2039-01-01 23:00';
142+
id select_type table type possible_keys key key_len ref rows filtered Extra
143+
1 SIMPLE t1 ALL NULL NULL NULL NULL 1 100.00 Using where
144+
create or replace procedure p() delete history from t1 before system_time '2039-01-01 23:00';
145+
call p;
146+
select * from t1;
147+
x
148+
1
149+
call p;
150+
select * from t1;
151+
x
152+
1
153+
drop procedure p;
154+
prepare stmt from "delete history from t1 before system_time '2039-01-01 23:00'";
155+
execute stmt;
156+
select * from t1;
157+
x
158+
1
159+
execute stmt;
160+
select * from t1;
161+
x
162+
1
163+
drop prepare stmt;
164+
drop table t1;

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,4 +141,26 @@ insert into t1 values (1);
141141
select * from t1;
142142
drop table t1;
143143

144+
--echo #
145+
--echo # MDEV-25468 DELETE HISTORY may delete current data on system-versioned table
146+
--echo #
147+
create or replace table t1 (x int) with system versioning;
148+
insert into t1 values (1);
149+
delete history from t1 before system_time '2039-01-01 23:00';
150+
select * from t1;
151+
explain extended delete history from t1 before system_time '2039-01-01 23:00';
152+
create or replace procedure p() delete history from t1 before system_time '2039-01-01 23:00';
153+
call p;
154+
select * from t1;
155+
call p;
156+
select * from t1;
157+
drop procedure p;
158+
prepare stmt from "delete history from t1 before system_time '2039-01-01 23:00'";
159+
execute stmt;
160+
select * from t1;
161+
execute stmt;
162+
select * from t1;
163+
drop prepare stmt;
164+
drop table t1;
165+
144166
--source suite/versioning/common_finish.inc

sql/item_vers.cc

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,22 @@
2626
#include "tztime.h"
2727
#include "item.h"
2828

29+
bool Item_func_history::val_bool()
30+
{
31+
Item_field *f= static_cast<Item_field *>(args[0]);
32+
DBUG_ASSERT(f->fixed);
33+
DBUG_ASSERT(f->field->flags & VERS_SYS_END_FLAG);
34+
return !f->field->is_max();
35+
}
36+
37+
void Item_func_history::print(String *str, enum_query_type query_type)
38+
{
39+
str->append(func_name());
40+
str->append('(');
41+
args[0]->print(str, query_type);
42+
str->append(')');
43+
}
44+
2945
Item_func_trt_ts::Item_func_trt_ts(THD *thd, Item* a, TR_table::field_id_t _trt_field) :
3046
Item_datetimefunc(thd, a),
3147
trt_field(_trt_field)

sql/item_vers.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,36 @@
2222
#pragma interface /* gcc class implementation */
2323
#endif
2424

25+
class Item_func_history: public Item_bool_func
26+
{
27+
public:
28+
/*
29+
@param a Item_field for row_end system field
30+
*/
31+
Item_func_history(THD *thd, Item *a): Item_bool_func(thd, a)
32+
{
33+
DBUG_ASSERT(a->type() == Item::FIELD_ITEM);
34+
}
35+
36+
virtual bool val_bool();
37+
virtual longlong val_int()
38+
{
39+
return (val_bool() ? 1 : 0);
40+
}
41+
bool fix_length_and_dec()
42+
{
43+
maybe_null= 0;
44+
null_value= 0;
45+
decimals= 0;
46+
max_length= 1;
47+
return FALSE;
48+
}
49+
virtual const char* func_name() const { return "is_history"; }
50+
virtual void print(String *str, enum_query_type query_type);
51+
Item *get_copy(THD *thd)
52+
{ return get_item_copy<Item_func_history>(thd, this); }
53+
};
54+
2555
class Item_func_trt_ts: public Item_datetimefunc
2656
{
2757
TR_table::field_id_t trt_field;

sql/sql_select.cc

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -928,7 +928,8 @@ int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables)
928928
cond3= newx Item_func_le(thd, point_in_time1, point_in_time2);
929929
break;
930930
case SYSTEM_TIME_BEFORE:
931-
cond1= newx Item_func_lt(thd, row_end, point_in_time1);
931+
cond1= newx Item_func_history(thd, row_end);
932+
cond2= newx Item_func_lt(thd, row_end, point_in_time1);
932933
break;
933934
default:
934935
DBUG_ASSERT(0);
@@ -978,7 +979,8 @@ int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables)
978979
trx_id0= vers_conditions.start.unit == VERS_TIMESTAMP
979980
? newx Item_func_trt_id(thd, point_in_time1, TR_table::FLD_TRX_ID, true)
980981
: point_in_time1;
981-
cond1= newx Item_func_trt_trx_sees(thd, trx_id0, row_end);
982+
cond1= newx Item_func_history(thd, row_end);
983+
cond2= newx Item_func_trt_trx_sees(thd, trx_id0, row_end);
982984
break;
983985
default:
984986
DBUG_ASSERT(0);

0 commit comments

Comments
 (0)