MDEV-34046 Parameterized PS converts error to warning, causes
replication problems DELETE HISTORY did not process parameterized PS properly as the history expression was checked on prepare stage when the parameters was not yet substituted. In that case check_units() succeeded as there is no invalid type: Item_param has type_handler_null which is inherited from string type and this is valid type for history expression. The warning was thrown when the expression was evaluated for comparison on delete execution (when the parameter was already substituted). The fix postpones check_units() until the first PS execution. We have to postpone where conditions processing until the first execution and update select_lex.where on every execution as it is reset to the state after prepare.
This commit is contained in:
parent
bff9b1e472
commit
f1f9284181
@ -251,3 +251,216 @@ t CREATE TABLE `t` (
|
|||||||
PARTITIONS 2
|
PARTITIONS 2
|
||||||
drop table t;
|
drop table t;
|
||||||
# End of 10.9 tests
|
# End of 10.9 tests
|
||||||
|
#
|
||||||
|
# MDEV-34046 Parameterized PS converts error to warning, causes replication problems
|
||||||
|
#
|
||||||
|
create table t (a int) with system versioning;
|
||||||
|
set timestamp= unix_timestamp('2000-01-01 00:00:00');
|
||||||
|
insert into t values (1), (100);
|
||||||
|
delete history from t before system_time @@timestamp;
|
||||||
|
ERROR HY000: Illegal parameter data type double for operation 'FOR SYSTEM_TIME'
|
||||||
|
execute immediate "delete history from t before system_time @@timestamp";
|
||||||
|
ERROR HY000: Illegal parameter data type double for operation 'FOR SYSTEM_TIME'
|
||||||
|
execute immediate "delete history from t before system_time ?" using @@timestamp;
|
||||||
|
ERROR HY000: Illegal parameter data type double for operation 'FOR SYSTEM_TIME'
|
||||||
|
set @ts1= '2000-01-01 00:00:01';
|
||||||
|
set timestamp= unix_timestamp(@ts1);
|
||||||
|
update t set a= a + 1 where a < 100;
|
||||||
|
set @ts2= '2000-01-01 00:00:02';
|
||||||
|
set timestamp= unix_timestamp(@ts2);
|
||||||
|
update t set a= a + 1 where a < 100;
|
||||||
|
set @ts3= '2000-01-01 00:00:03';
|
||||||
|
set timestamp= unix_timestamp(@ts3);
|
||||||
|
select *, row_start, row_end from t for system_time all order by a;
|
||||||
|
a row_start row_end
|
||||||
|
1 2000-01-01 00:00:00.000000 2000-01-01 00:00:01.000000
|
||||||
|
2 2000-01-01 00:00:01.000000 2000-01-01 00:00:02.000000
|
||||||
|
3 2000-01-01 00:00:02.000000 2038-01-19 03:14:07.999999
|
||||||
|
100 2000-01-01 00:00:00.000000 2038-01-19 03:14:07.999999
|
||||||
|
execute immediate "delete history from t before system_time @ts1";
|
||||||
|
select *, row_start, row_end from t for system_time all order by a;
|
||||||
|
a row_start row_end
|
||||||
|
1 2000-01-01 00:00:00.000000 2000-01-01 00:00:01.000000
|
||||||
|
2 2000-01-01 00:00:01.000000 2000-01-01 00:00:02.000000
|
||||||
|
3 2000-01-01 00:00:02.000000 2038-01-19 03:14:07.999999
|
||||||
|
100 2000-01-01 00:00:00.000000 2038-01-19 03:14:07.999999
|
||||||
|
execute immediate "delete history from t before system_time @ts2";
|
||||||
|
select *, row_start, row_end from t for system_time all order by a;
|
||||||
|
a row_start row_end
|
||||||
|
2 2000-01-01 00:00:01.000000 2000-01-01 00:00:02.000000
|
||||||
|
3 2000-01-01 00:00:02.000000 2038-01-19 03:14:07.999999
|
||||||
|
100 2000-01-01 00:00:00.000000 2038-01-19 03:14:07.999999
|
||||||
|
execute immediate "delete history from t before system_time ?" using @ts3;
|
||||||
|
select *, row_start, row_end from t for system_time all order by a;
|
||||||
|
a row_start row_end
|
||||||
|
3 2000-01-01 00:00:02.000000 2038-01-19 03:14:07.999999
|
||||||
|
100 2000-01-01 00:00:00.000000 2038-01-19 03:14:07.999999
|
||||||
|
execute immediate "delete history from t before system_time ?" using @ts3;
|
||||||
|
select *, row_start, row_end from t for system_time all order by a;
|
||||||
|
a row_start row_end
|
||||||
|
3 2000-01-01 00:00:02.000000 2038-01-19 03:14:07.999999
|
||||||
|
100 2000-01-01 00:00:00.000000 2038-01-19 03:14:07.999999
|
||||||
|
update t set a= a + 1 where a < 100;
|
||||||
|
set @ts4= '2000-01-01 00:00:04';
|
||||||
|
set timestamp= unix_timestamp(@ts4);
|
||||||
|
update t set a= a + 1 where a < 100;
|
||||||
|
select *, row_start, row_end from t for system_time all order by a;
|
||||||
|
a row_start row_end
|
||||||
|
3 2000-01-01 00:00:02.000000 2000-01-01 00:00:03.000000
|
||||||
|
4 2000-01-01 00:00:03.000000 2000-01-01 00:00:04.000000
|
||||||
|
5 2000-01-01 00:00:04.000000 2038-01-19 03:14:07.999999
|
||||||
|
100 2000-01-01 00:00:00.000000 2038-01-19 03:14:07.999999
|
||||||
|
execute immediate "delete history from t before system_time ?" using '2000-01-01 00:00:04';
|
||||||
|
select *, row_start, row_end from t for system_time all order by a;
|
||||||
|
a row_start row_end
|
||||||
|
4 2000-01-01 00:00:03.000000 2000-01-01 00:00:04.000000
|
||||||
|
5 2000-01-01 00:00:04.000000 2038-01-19 03:14:07.999999
|
||||||
|
100 2000-01-01 00:00:00.000000 2038-01-19 03:14:07.999999
|
||||||
|
set @ts5= '2000-01-01 00:00:05';
|
||||||
|
set timestamp= unix_timestamp(@ts5);
|
||||||
|
update t set a= a + 1 where a < 100;
|
||||||
|
set @ts6= '2000-01-01 00:00:06';
|
||||||
|
set timestamp= unix_timestamp(@ts6);
|
||||||
|
update t set a= a + 1 where a < 100;
|
||||||
|
set @ts7= '2000-01-01 00:00:07';
|
||||||
|
set timestamp= unix_timestamp(@ts7);
|
||||||
|
update t set a= a + 1 where a < 100;
|
||||||
|
select *, row_start, row_end from t for system_time all order by a;
|
||||||
|
a row_start row_end
|
||||||
|
4 2000-01-01 00:00:03.000000 2000-01-01 00:00:04.000000
|
||||||
|
5 2000-01-01 00:00:04.000000 2000-01-01 00:00:05.000000
|
||||||
|
6 2000-01-01 00:00:05.000000 2000-01-01 00:00:06.000000
|
||||||
|
7 2000-01-01 00:00:06.000000 2000-01-01 00:00:07.000000
|
||||||
|
8 2000-01-01 00:00:07.000000 2038-01-19 03:14:07.999999
|
||||||
|
100 2000-01-01 00:00:00.000000 2038-01-19 03:14:07.999999
|
||||||
|
prepare stmt from 'delete history from t before system_time ?';
|
||||||
|
execute stmt using @ts4;
|
||||||
|
select *, row_start, row_end from t for system_time all order by a;
|
||||||
|
a row_start row_end
|
||||||
|
4 2000-01-01 00:00:03.000000 2000-01-01 00:00:04.000000
|
||||||
|
5 2000-01-01 00:00:04.000000 2000-01-01 00:00:05.000000
|
||||||
|
6 2000-01-01 00:00:05.000000 2000-01-01 00:00:06.000000
|
||||||
|
7 2000-01-01 00:00:06.000000 2000-01-01 00:00:07.000000
|
||||||
|
8 2000-01-01 00:00:07.000000 2038-01-19 03:14:07.999999
|
||||||
|
100 2000-01-01 00:00:00.000000 2038-01-19 03:14:07.999999
|
||||||
|
execute stmt using @ts5;
|
||||||
|
select *, row_start, row_end from t for system_time all order by a;
|
||||||
|
a row_start row_end
|
||||||
|
5 2000-01-01 00:00:04.000000 2000-01-01 00:00:05.000000
|
||||||
|
6 2000-01-01 00:00:05.000000 2000-01-01 00:00:06.000000
|
||||||
|
7 2000-01-01 00:00:06.000000 2000-01-01 00:00:07.000000
|
||||||
|
8 2000-01-01 00:00:07.000000 2038-01-19 03:14:07.999999
|
||||||
|
100 2000-01-01 00:00:00.000000 2038-01-19 03:14:07.999999
|
||||||
|
execute stmt using @ts6;
|
||||||
|
select *, row_start, row_end from t for system_time all order by a;
|
||||||
|
a row_start row_end
|
||||||
|
6 2000-01-01 00:00:05.000000 2000-01-01 00:00:06.000000
|
||||||
|
7 2000-01-01 00:00:06.000000 2000-01-01 00:00:07.000000
|
||||||
|
8 2000-01-01 00:00:07.000000 2038-01-19 03:14:07.999999
|
||||||
|
100 2000-01-01 00:00:00.000000 2038-01-19 03:14:07.999999
|
||||||
|
execute stmt using '2000-01-01 00:00:06';
|
||||||
|
select *, row_start, row_end from t for system_time all order by a;
|
||||||
|
a row_start row_end
|
||||||
|
6 2000-01-01 00:00:05.000000 2000-01-01 00:00:06.000000
|
||||||
|
7 2000-01-01 00:00:06.000000 2000-01-01 00:00:07.000000
|
||||||
|
8 2000-01-01 00:00:07.000000 2038-01-19 03:14:07.999999
|
||||||
|
100 2000-01-01 00:00:00.000000 2038-01-19 03:14:07.999999
|
||||||
|
execute stmt using '2000-01-01 00:00:06.000001';
|
||||||
|
select *, row_start, row_end from t for system_time all order by a;
|
||||||
|
a row_start row_end
|
||||||
|
7 2000-01-01 00:00:06.000000 2000-01-01 00:00:07.000000
|
||||||
|
8 2000-01-01 00:00:07.000000 2038-01-19 03:14:07.999999
|
||||||
|
100 2000-01-01 00:00:00.000000 2038-01-19 03:14:07.999999
|
||||||
|
set @ts8= '2000-01-01 00:00:08';
|
||||||
|
set timestamp= unix_timestamp(@ts8);
|
||||||
|
delete from t;
|
||||||
|
select *, row_start, row_end from t for system_time all order by a;
|
||||||
|
a row_start row_end
|
||||||
|
7 2000-01-01 00:00:06.000000 2000-01-01 00:00:07.000000
|
||||||
|
8 2000-01-01 00:00:07.000000 2000-01-01 00:00:08.000000
|
||||||
|
100 2000-01-01 00:00:00.000000 2000-01-01 00:00:08.000000
|
||||||
|
execute immediate "delete history from t before system_time from_unixtime(?)" using @@timestamp;
|
||||||
|
select *, row_start, row_end from t for system_time all order by a;
|
||||||
|
a row_start row_end
|
||||||
|
8 2000-01-01 00:00:07.000000 2000-01-01 00:00:08.000000
|
||||||
|
100 2000-01-01 00:00:00.000000 2000-01-01 00:00:08.000000
|
||||||
|
execute stmt using '2020-01-01';
|
||||||
|
select *, row_start, row_end from t for system_time all order by a;
|
||||||
|
a row_start row_end
|
||||||
|
drop prepare stmt;
|
||||||
|
set timestamp= unix_timestamp('2000-01-01 00:00:00');
|
||||||
|
insert into t values (1), (100);
|
||||||
|
set @ts1= '2000-01-01 00:00:01';
|
||||||
|
set timestamp= unix_timestamp(@ts1);
|
||||||
|
update t set a= a + 1 where a < 100;
|
||||||
|
set timestamp= @@timestamp + 1;
|
||||||
|
set @ts2= @@timestamp;
|
||||||
|
update t set a= a + 1 where a < 100;
|
||||||
|
set timestamp= @@timestamp + 1;
|
||||||
|
update t set a= a + 1 where a < 100;
|
||||||
|
prepare stmt from 'delete history from t before system_time from_unixtime(? + ?)';
|
||||||
|
select *, row_start, row_end from t for system_time all order by a;
|
||||||
|
a row_start row_end
|
||||||
|
1 2000-01-01 00:00:00.000000 2000-01-01 00:00:01.000000
|
||||||
|
2 2000-01-01 00:00:01.000000 2000-01-01 00:00:02.000000
|
||||||
|
3 2000-01-01 00:00:02.000000 2000-01-01 00:00:03.000000
|
||||||
|
4 2000-01-01 00:00:03.000000 2038-01-19 03:14:07.999999
|
||||||
|
100 2000-01-01 00:00:00.000000 2038-01-19 03:14:07.999999
|
||||||
|
execute stmt using @ts1, 0;
|
||||||
|
Warnings:
|
||||||
|
Warning 1292 Truncated incorrect DOUBLE value: '2000-01-01 00:00:01'
|
||||||
|
Warning 1292 Truncated incorrect DOUBLE value: '2000-01-01 00:00:01'
|
||||||
|
Warning 1292 Truncated incorrect DOUBLE value: '2000-01-01 00:00:01'
|
||||||
|
Warning 1292 Truncated incorrect DOUBLE value: '2000-01-01 00:00:01'
|
||||||
|
Warning 1292 Truncated incorrect DOUBLE value: '2000-01-01 00:00:01'
|
||||||
|
select *, row_start, row_end from t for system_time all order by a;
|
||||||
|
a row_start row_end
|
||||||
|
1 2000-01-01 00:00:00.000000 2000-01-01 00:00:01.000000
|
||||||
|
2 2000-01-01 00:00:01.000000 2000-01-01 00:00:02.000000
|
||||||
|
3 2000-01-01 00:00:02.000000 2000-01-01 00:00:03.000000
|
||||||
|
4 2000-01-01 00:00:03.000000 2038-01-19 03:14:07.999999
|
||||||
|
100 2000-01-01 00:00:00.000000 2038-01-19 03:14:07.999999
|
||||||
|
execute stmt using @ts2, 0;
|
||||||
|
select *, row_start, row_end from t for system_time all order by a;
|
||||||
|
a row_start row_end
|
||||||
|
2 2000-01-01 00:00:01.000000 2000-01-01 00:00:02.000000
|
||||||
|
3 2000-01-01 00:00:02.000000 2000-01-01 00:00:03.000000
|
||||||
|
4 2000-01-01 00:00:03.000000 2038-01-19 03:14:07.999999
|
||||||
|
100 2000-01-01 00:00:00.000000 2038-01-19 03:14:07.999999
|
||||||
|
execute stmt using @@timestamp, NULL;
|
||||||
|
select *, row_start, row_end from t for system_time all order by a;
|
||||||
|
a row_start row_end
|
||||||
|
2 2000-01-01 00:00:01.000000 2000-01-01 00:00:02.000000
|
||||||
|
3 2000-01-01 00:00:02.000000 2000-01-01 00:00:03.000000
|
||||||
|
4 2000-01-01 00:00:03.000000 2038-01-19 03:14:07.999999
|
||||||
|
100 2000-01-01 00:00:00.000000 2038-01-19 03:14:07.999999
|
||||||
|
execute stmt using NULL, NULL;
|
||||||
|
select *, row_start, row_end from t for system_time all order by a;
|
||||||
|
a row_start row_end
|
||||||
|
2 2000-01-01 00:00:01.000000 2000-01-01 00:00:02.000000
|
||||||
|
3 2000-01-01 00:00:02.000000 2000-01-01 00:00:03.000000
|
||||||
|
4 2000-01-01 00:00:03.000000 2038-01-19 03:14:07.999999
|
||||||
|
100 2000-01-01 00:00:00.000000 2038-01-19 03:14:07.999999
|
||||||
|
execute stmt using @ts2, 1;
|
||||||
|
select *, row_start, row_end from t for system_time all order by a;
|
||||||
|
a row_start row_end
|
||||||
|
3 2000-01-01 00:00:02.000000 2000-01-01 00:00:03.000000
|
||||||
|
4 2000-01-01 00:00:03.000000 2038-01-19 03:14:07.999999
|
||||||
|
100 2000-01-01 00:00:00.000000 2038-01-19 03:14:07.999999
|
||||||
|
execute stmt using @ts2, @ts2;
|
||||||
|
select *, row_start, row_end from t for system_time all order by a;
|
||||||
|
a row_start row_end
|
||||||
|
4 2000-01-01 00:00:03.000000 2038-01-19 03:14:07.999999
|
||||||
|
100 2000-01-01 00:00:00.000000 2038-01-19 03:14:07.999999
|
||||||
|
delete from t;
|
||||||
|
select *, row_start, row_end from t for system_time all order by a;
|
||||||
|
a row_start row_end
|
||||||
|
4 2000-01-01 00:00:03.000000 2000-01-01 00:00:03.000000
|
||||||
|
100 2000-01-01 00:00:00.000000 2000-01-01 00:00:03.000000
|
||||||
|
execute stmt using @ts2, @ts2;
|
||||||
|
select *, row_start, row_end from t for system_time all order by a;
|
||||||
|
a row_start row_end
|
||||||
|
drop prepare stmt;
|
||||||
|
drop table t;
|
||||||
|
set timestamp= default;
|
||||||
|
# End of 10.11 tests
|
||||||
|
@ -256,4 +256,102 @@ drop table t;
|
|||||||
|
|
||||||
--echo # End of 10.9 tests
|
--echo # End of 10.9 tests
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-34046 Parameterized PS converts error to warning, causes replication problems
|
||||||
|
--echo #
|
||||||
|
create table t (a int) with system versioning;
|
||||||
|
set timestamp= unix_timestamp('2000-01-01 00:00:00');
|
||||||
|
insert into t values (1), (100);
|
||||||
|
|
||||||
|
--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
|
||||||
|
delete history from t before system_time @@timestamp;
|
||||||
|
--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
|
||||||
|
execute immediate "delete history from t before system_time @@timestamp";
|
||||||
|
--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
|
||||||
|
execute immediate "delete history from t before system_time ?" using @@timestamp;
|
||||||
|
|
||||||
|
set @ts1= '2000-01-01 00:00:01'; set timestamp= unix_timestamp(@ts1);
|
||||||
|
update t set a= a + 1 where a < 100;
|
||||||
|
set @ts2= '2000-01-01 00:00:02'; set timestamp= unix_timestamp(@ts2);
|
||||||
|
update t set a= a + 1 where a < 100;
|
||||||
|
set @ts3= '2000-01-01 00:00:03'; set timestamp= unix_timestamp(@ts3);
|
||||||
|
select *, row_start, row_end from t for system_time all order by a;
|
||||||
|
execute immediate "delete history from t before system_time @ts1";
|
||||||
|
select *, row_start, row_end from t for system_time all order by a;
|
||||||
|
execute immediate "delete history from t before system_time @ts2";
|
||||||
|
select *, row_start, row_end from t for system_time all order by a;
|
||||||
|
execute immediate "delete history from t before system_time ?" using @ts3;
|
||||||
|
select *, row_start, row_end from t for system_time all order by a;
|
||||||
|
execute immediate "delete history from t before system_time ?" using @ts3;
|
||||||
|
select *, row_start, row_end from t for system_time all order by a;
|
||||||
|
update t set a= a + 1 where a < 100;
|
||||||
|
set @ts4= '2000-01-01 00:00:04'; set timestamp= unix_timestamp(@ts4);
|
||||||
|
update t set a= a + 1 where a < 100;
|
||||||
|
select *, row_start, row_end from t for system_time all order by a;
|
||||||
|
execute immediate "delete history from t before system_time ?" using '2000-01-01 00:00:04';
|
||||||
|
select *, row_start, row_end from t for system_time all order by a;
|
||||||
|
set @ts5= '2000-01-01 00:00:05'; set timestamp= unix_timestamp(@ts5);
|
||||||
|
update t set a= a + 1 where a < 100;
|
||||||
|
set @ts6= '2000-01-01 00:00:06'; set timestamp= unix_timestamp(@ts6);
|
||||||
|
update t set a= a + 1 where a < 100;
|
||||||
|
set @ts7= '2000-01-01 00:00:07'; set timestamp= unix_timestamp(@ts7);
|
||||||
|
update t set a= a + 1 where a < 100;
|
||||||
|
select *, row_start, row_end from t for system_time all order by a;
|
||||||
|
prepare stmt from 'delete history from t before system_time ?';
|
||||||
|
execute stmt using @ts4;
|
||||||
|
select *, row_start, row_end from t for system_time all order by a;
|
||||||
|
execute stmt using @ts5;
|
||||||
|
select *, row_start, row_end from t for system_time all order by a;
|
||||||
|
execute stmt using @ts6;
|
||||||
|
select *, row_start, row_end from t for system_time all order by a;
|
||||||
|
execute stmt using '2000-01-01 00:00:06';
|
||||||
|
select *, row_start, row_end from t for system_time all order by a;
|
||||||
|
execute stmt using '2000-01-01 00:00:06.000001';
|
||||||
|
select *, row_start, row_end from t for system_time all order by a;
|
||||||
|
set @ts8= '2000-01-01 00:00:08'; set timestamp= unix_timestamp(@ts8);
|
||||||
|
delete from t;
|
||||||
|
select *, row_start, row_end from t for system_time all order by a;
|
||||||
|
execute immediate "delete history from t before system_time from_unixtime(?)" using @@timestamp;
|
||||||
|
select *, row_start, row_end from t for system_time all order by a;
|
||||||
|
execute stmt using '2020-01-01';
|
||||||
|
select *, row_start, row_end from t for system_time all order by a;
|
||||||
|
drop prepare stmt;
|
||||||
|
|
||||||
|
# Check expression
|
||||||
|
set timestamp= unix_timestamp('2000-01-01 00:00:00');
|
||||||
|
insert into t values (1), (100);
|
||||||
|
set @ts1= '2000-01-01 00:00:01'; set timestamp= unix_timestamp(@ts1);
|
||||||
|
update t set a= a + 1 where a < 100;
|
||||||
|
set timestamp= @@timestamp + 1;
|
||||||
|
set @ts2= @@timestamp;
|
||||||
|
update t set a= a + 1 where a < 100;
|
||||||
|
set timestamp= @@timestamp + 1;
|
||||||
|
update t set a= a + 1 where a < 100;
|
||||||
|
|
||||||
|
prepare stmt from 'delete history from t before system_time from_unixtime(? + ?)';
|
||||||
|
select *, row_start, row_end from t for system_time all order by a;
|
||||||
|
execute stmt using @ts1, 0;
|
||||||
|
select *, row_start, row_end from t for system_time all order by a;
|
||||||
|
execute stmt using @ts2, 0;
|
||||||
|
select *, row_start, row_end from t for system_time all order by a;
|
||||||
|
execute stmt using @@timestamp, NULL;
|
||||||
|
select *, row_start, row_end from t for system_time all order by a;
|
||||||
|
execute stmt using NULL, NULL;
|
||||||
|
select *, row_start, row_end from t for system_time all order by a;
|
||||||
|
execute stmt using @ts2, 1;
|
||||||
|
select *, row_start, row_end from t for system_time all order by a;
|
||||||
|
execute stmt using @ts2, @ts2;
|
||||||
|
select *, row_start, row_end from t for system_time all order by a;
|
||||||
|
delete from t;
|
||||||
|
select *, row_start, row_end from t for system_time all order by a;
|
||||||
|
execute stmt using @ts2, @ts2;
|
||||||
|
select *, row_start, row_end from t for system_time all order by a;
|
||||||
|
|
||||||
|
drop prepare stmt;
|
||||||
|
|
||||||
|
drop table t;
|
||||||
|
set timestamp= default;
|
||||||
|
|
||||||
|
--echo # End of 10.11 tests
|
||||||
|
|
||||||
--source suite/versioning/common_finish.inc
|
--source suite/versioning/common_finish.inc
|
||||||
|
@ -393,7 +393,10 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (delete_history)
|
if (delete_history)
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(conds);
|
||||||
table->vers_write= false;
|
table->vers_write= false;
|
||||||
|
}
|
||||||
|
|
||||||
if (returning)
|
if (returning)
|
||||||
(void) result->prepare(returning->item_list, NULL);
|
(void) result->prepare(returning->item_list, NULL);
|
||||||
|
@ -1279,10 +1279,25 @@ int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (vers_conditions.type == SYSTEM_TIME_ALL)
|
if (vers_conditions.type == SYSTEM_TIME_ALL)
|
||||||
|
{
|
||||||
|
if (vers_conditions.has_param)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Parameter substitution (set_params_from_actual_params()) works
|
||||||
|
on existing items so we don't have to reevaluate table->where
|
||||||
|
(in update_this below), we just update SELECT_LEX WHERE expression
|
||||||
|
from existing table conditions.
|
||||||
|
*/
|
||||||
|
DBUG_ASSERT(vers_conditions.delete_history);
|
||||||
|
DBUG_ASSERT(thd->stmt_arena->is_stmt_execute());
|
||||||
|
where= and_items(thd, where, table->where);
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool timestamps_only= table->table->versioned(VERS_TIMESTAMP);
|
bool timestamps_only= table->table->versioned(VERS_TIMESTAMP);
|
||||||
|
bool update_this= update_conds;
|
||||||
|
|
||||||
if (vers_conditions.is_set() && vers_conditions.type != SYSTEM_TIME_HISTORY)
|
if (vers_conditions.is_set() && vers_conditions.type != SYSTEM_TIME_HISTORY)
|
||||||
{
|
{
|
||||||
@ -1299,9 +1314,23 @@ int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables)
|
|||||||
my_error(ER_VERS_ENGINE_UNSUPPORTED, MYF(0), table->table_name.str);
|
my_error(ER_VERS_ENGINE_UNSUPPORTED, MYF(0), table->table_name.str);
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
}
|
}
|
||||||
|
if (vers_conditions.has_param)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
PS parameter in history expression requires processing at execution
|
||||||
|
stage when parameters has values substituted. So at prepare continue
|
||||||
|
the loop, but at execution enter update_this. The second execution
|
||||||
|
is skipped on vers_conditions.type == SYSTEM_TIME_ALL condition.
|
||||||
|
*/
|
||||||
|
DBUG_ASSERT(vers_conditions.delete_history);
|
||||||
|
if (thd->stmt_arena->is_stmt_prepare())
|
||||||
|
continue;
|
||||||
|
DBUG_ASSERT(thd->stmt_arena->is_stmt_execute());
|
||||||
|
update_this= true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (update_conds)
|
if (update_this)
|
||||||
{
|
{
|
||||||
vers_conditions.period = &table->table->s->vers;
|
vers_conditions.period = &table->table->s->vers;
|
||||||
Item *cond= period_get_condition(thd, table, this, &vers_conditions,
|
Item *cond= period_get_condition(thd, table, this, &vers_conditions,
|
||||||
|
@ -10519,8 +10519,8 @@ bool vers_select_conds_t::check_units(THD *thd)
|
|||||||
{
|
{
|
||||||
DBUG_ASSERT(type != SYSTEM_TIME_UNSPECIFIED);
|
DBUG_ASSERT(type != SYSTEM_TIME_UNSPECIFIED);
|
||||||
DBUG_ASSERT(start.item);
|
DBUG_ASSERT(start.item);
|
||||||
return start.check_unit(thd) ||
|
return start.check_unit(thd, this) ||
|
||||||
end.check_unit(thd);
|
end.check_unit(thd, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool vers_select_conds_t::eq(const vers_select_conds_t &conds) const
|
bool vers_select_conds_t::eq(const vers_select_conds_t &conds) const
|
||||||
@ -10546,7 +10546,7 @@ bool vers_select_conds_t::eq(const vers_select_conds_t &conds) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Vers_history_point::check_unit(THD *thd)
|
bool Vers_history_point::check_unit(THD *thd, vers_select_conds_t *vers_conds)
|
||||||
{
|
{
|
||||||
if (!item)
|
if (!item)
|
||||||
return false;
|
return false;
|
||||||
@ -10556,6 +10556,9 @@ bool Vers_history_point::check_unit(THD *thd)
|
|||||||
item->full_name(), "FOR SYSTEM_TIME");
|
item->full_name(), "FOR SYSTEM_TIME");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
else if (item->with_param())
|
||||||
|
vers_conds->has_param= true;
|
||||||
|
|
||||||
if (item->fix_fields_if_needed(thd, &item))
|
if (item->fix_fields_if_needed(thd, &item))
|
||||||
return true;
|
return true;
|
||||||
const Type_handler *t= item->this_item()->real_type_handler();
|
const Type_handler *t= item->this_item()->real_type_handler();
|
||||||
|
@ -2140,6 +2140,8 @@ struct vers_history_point_t
|
|||||||
Item *item;
|
Item *item;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct vers_select_conds_t;
|
||||||
|
|
||||||
class Vers_history_point : public vers_history_point_t
|
class Vers_history_point : public vers_history_point_t
|
||||||
{
|
{
|
||||||
void fix_item();
|
void fix_item();
|
||||||
@ -2160,7 +2162,8 @@ public:
|
|||||||
}
|
}
|
||||||
void empty() { unit= VERS_TIMESTAMP; item= NULL; }
|
void empty() { unit= VERS_TIMESTAMP; item= NULL; }
|
||||||
void print(String *str, enum_query_type, const char *prefix, size_t plen) const;
|
void print(String *str, enum_query_type, const char *prefix, size_t plen) const;
|
||||||
bool check_unit(THD *thd);
|
bool check_unit(THD *thd, vers_select_conds_t *vers_conds);
|
||||||
|
bool has_param() const;
|
||||||
bool eq(const vers_history_point_t &point) const;
|
bool eq(const vers_history_point_t &point) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2170,6 +2173,7 @@ struct vers_select_conds_t
|
|||||||
vers_system_time_t orig_type;
|
vers_system_time_t orig_type;
|
||||||
bool used:1;
|
bool used:1;
|
||||||
bool delete_history:1;
|
bool delete_history:1;
|
||||||
|
bool has_param:1;
|
||||||
Vers_history_point start;
|
Vers_history_point start;
|
||||||
Vers_history_point end;
|
Vers_history_point end;
|
||||||
Lex_ident name;
|
Lex_ident name;
|
||||||
@ -2185,6 +2189,7 @@ struct vers_select_conds_t
|
|||||||
orig_type= SYSTEM_TIME_UNSPECIFIED;
|
orig_type= SYSTEM_TIME_UNSPECIFIED;
|
||||||
used= false;
|
used= false;
|
||||||
delete_history= false;
|
delete_history= false;
|
||||||
|
has_param= false;
|
||||||
start.empty();
|
start.empty();
|
||||||
end.empty();
|
end.empty();
|
||||||
}
|
}
|
||||||
@ -2199,6 +2204,7 @@ struct vers_select_conds_t
|
|||||||
used= false;
|
used= false;
|
||||||
delete_history= (type == SYSTEM_TIME_HISTORY ||
|
delete_history= (type == SYSTEM_TIME_HISTORY ||
|
||||||
type == SYSTEM_TIME_BEFORE);
|
type == SYSTEM_TIME_BEFORE);
|
||||||
|
has_param= false;
|
||||||
start= _start;
|
start= _start;
|
||||||
end= _end;
|
end= _end;
|
||||||
name= _name;
|
name= _name;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user