MDEV-16026 MDEV-16481 refactor Sys_var_vers_asof
MDEV-16026: Forbid global system_versioning_asof in non-default time zone * store `system_versioning_asof` in unix time; * both session and global vars are processed in session timezone; * setting `default` does not copy global variable anymore. Instead, it sets system_time to SYSTEM_TIME_UNSPECIFIED, which means that no 'AS OF' time is applied and `now()` can be assumed As a regression, we cannot assign values below 1970 (UTC) anymore MDEV-16481: set global system_versioning_asof=sf() crashes in specific case * sys_vars.h: add `MYSQL_TIME` field to `set_var::save_result` * sys_vars.ic: get rid of calling `var->value->get_date()` from `Sys_var_vers_asof::update()` * versioning.sysvars: add test; remove double warning refactor Sys_var_vers_asof * inherit from sys_var rather than Sys_var_enum * remove junk "DEFAULT" keyword. There is DEFAULT in SQL grammar for it. * make all conversions in check() to avoid possible errors * avoid double var->value evaluation, which could consequence in undefined behavior
This commit is contained in:
parent
f50eb0d398
commit
c6bff46958
@ -3959,7 +3959,7 @@ VARIABLE_COMMENT Default value for the FOR SYSTEM_TIME AS OF clause
|
|||||||
NUMERIC_MIN_VALUE NULL
|
NUMERIC_MIN_VALUE NULL
|
||||||
NUMERIC_MAX_VALUE NULL
|
NUMERIC_MAX_VALUE NULL
|
||||||
NUMERIC_BLOCK_SIZE NULL
|
NUMERIC_BLOCK_SIZE NULL
|
||||||
ENUM_VALUE_LIST DEFAULT
|
ENUM_VALUE_LIST NULL
|
||||||
READ_ONLY NO
|
READ_ONLY NO
|
||||||
COMMAND_LINE_ARGUMENT NULL
|
COMMAND_LINE_ARGUMENT NULL
|
||||||
VARIABLE_NAME TABLE_DEFINITION_CACHE
|
VARIABLE_NAME TABLE_DEFINITION_CACHE
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
create table t (a int) with system versioning;
|
create table t (a int) with system versioning;
|
||||||
|
set @before= UNIX_TIMESTAMP(now(6));
|
||||||
insert into t values (1);
|
insert into t values (1);
|
||||||
|
set @after= UNIX_TIMESTAMP(now(6));
|
||||||
update t set a= 2;
|
update t set a= 2;
|
||||||
show global variables like 'system_versioning_asof';
|
show global variables like 'system_versioning_asof';
|
||||||
Variable_name Value
|
Variable_name Value
|
||||||
@ -56,65 +58,71 @@ ERROR 42000: Variable 'system_versioning_asof' can't be set to the value of '201
|
|||||||
set system_versioning_asof= '0000-00-00 00:00';
|
set system_versioning_asof= '0000-00-00 00:00';
|
||||||
ERROR 42000: Variable 'system_versioning_asof' can't be set to the value of '0000-00-00 00:00'
|
ERROR 42000: Variable 'system_versioning_asof' can't be set to the value of '0000-00-00 00:00'
|
||||||
# GLOBAL @@system_versioning_asof
|
# GLOBAL @@system_versioning_asof
|
||||||
set global system_versioning_asof= '1911-11-11 11:11:11.1111119';
|
set global system_versioning_asof= '1991-11-11 11:11:11.1111119';
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1292 Truncated incorrect datetime value: '1911-11-11 11:11:11.1111119'
|
Note 1292 Truncated incorrect datetime value: '1991-11-11 11:11:11.1111119'
|
||||||
Note 1292 Truncated incorrect datetime value: '1911-11-11 11:11:11.1111119'
|
|
||||||
show global variables like 'system_versioning_asof';
|
show global variables like 'system_versioning_asof';
|
||||||
Variable_name Value
|
Variable_name Value
|
||||||
system_versioning_asof 1911-11-11 11:11:11.111111
|
system_versioning_asof 1991-11-11 11:11:11.111111
|
||||||
set global system_versioning_asof= '1900-01-01 00:00:00';
|
set global system_versioning_asof= '1990-01-01 00:00:00';
|
||||||
show global variables like 'system_versioning_asof';
|
show global variables like 'system_versioning_asof';
|
||||||
Variable_name Value
|
Variable_name Value
|
||||||
system_versioning_asof 1900-01-01 00:00:00.000000
|
system_versioning_asof 1990-01-01 00:00:00.000000
|
||||||
set global system_versioning_asof= timestamp'1911-11-11 11:11:11.1111119';
|
set global system_versioning_asof= timestamp'1991-11-11 11:11:11.1111119';
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1292 Truncated incorrect datetime value: '1911-11-11 11:11:11.1111119'
|
Note 1292 Truncated incorrect datetime value: '1991-11-11 11:11:11.1111119'
|
||||||
show global variables like 'system_versioning_asof';
|
show global variables like 'system_versioning_asof';
|
||||||
Variable_name Value
|
Variable_name Value
|
||||||
system_versioning_asof 1911-11-11 11:11:11.111111
|
system_versioning_asof 1991-11-11 11:11:11.111111
|
||||||
set @ts= timestamp'1900-01-01 00:00:00';
|
set @ts= timestamp'1990-01-01 00:00:00';
|
||||||
set global system_versioning_asof= @ts;
|
set global system_versioning_asof= @ts;
|
||||||
show global variables like 'system_versioning_asof';
|
show global variables like 'system_versioning_asof';
|
||||||
Variable_name Value
|
Variable_name Value
|
||||||
system_versioning_asof 1900-01-01 00:00:00.000000
|
system_versioning_asof 1990-01-01 00:00:00.000000
|
||||||
set global system_versioning_asof= default;
|
set global system_versioning_asof= default;
|
||||||
select @@global.system_versioning_asof;
|
select @@global.system_versioning_asof;
|
||||||
@@global.system_versioning_asof
|
@@global.system_versioning_asof
|
||||||
DEFAULT
|
DEFAULT
|
||||||
# SESSION @@system_versioning_asof
|
# SESSION @@system_versioning_asof
|
||||||
set system_versioning_asof= '1911-11-11 11:11:11.1111119';
|
set system_versioning_asof= '1991-11-11 11:11:11.1111119';
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1292 Truncated incorrect datetime value: '1911-11-11 11:11:11.1111119'
|
Note 1292 Truncated incorrect datetime value: '1991-11-11 11:11:11.1111119'
|
||||||
Note 1292 Truncated incorrect datetime value: '1911-11-11 11:11:11.1111119'
|
|
||||||
show variables like 'system_versioning_asof';
|
show variables like 'system_versioning_asof';
|
||||||
Variable_name Value
|
Variable_name Value
|
||||||
system_versioning_asof 1911-11-11 11:11:11.111111
|
system_versioning_asof 1991-11-11 11:11:11.111111
|
||||||
set system_versioning_asof= '1900-01-01 00:00:00';
|
set system_versioning_asof= '1990-01-01 00:00:00';
|
||||||
show variables like 'system_versioning_asof';
|
show variables like 'system_versioning_asof';
|
||||||
Variable_name Value
|
Variable_name Value
|
||||||
system_versioning_asof 1900-01-01 00:00:00.000000
|
system_versioning_asof 1990-01-01 00:00:00.000000
|
||||||
set system_versioning_asof= timestamp'1911-11-11 11:11:11.1111119';
|
set system_versioning_asof= timestamp'1991-11-11 11:11:11.1111119';
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1292 Truncated incorrect datetime value: '1911-11-11 11:11:11.1111119'
|
Note 1292 Truncated incorrect datetime value: '1991-11-11 11:11:11.1111119'
|
||||||
show variables like 'system_versioning_asof';
|
show variables like 'system_versioning_asof';
|
||||||
Variable_name Value
|
Variable_name Value
|
||||||
system_versioning_asof 1911-11-11 11:11:11.111111
|
system_versioning_asof 1991-11-11 11:11:11.111111
|
||||||
set @ts= timestamp'1900-01-01 00:00:00';
|
set @ts= timestamp'1990-01-01 00:00:00';
|
||||||
set system_versioning_asof= @ts;
|
set system_versioning_asof= @ts;
|
||||||
show variables like 'system_versioning_asof';
|
show variables like 'system_versioning_asof';
|
||||||
Variable_name Value
|
Variable_name Value
|
||||||
system_versioning_asof 1900-01-01 00:00:00.000000
|
system_versioning_asof 1990-01-01 00:00:00.000000
|
||||||
# DEFAULT: value is copied from GLOBAL to SESSION
|
# DEFAULT: value is copied from GLOBAL to SESSION
|
||||||
set global system_versioning_asof= timestamp'1911-11-11 11:11:11.111111';
|
set global time_zone= "+03:00";
|
||||||
set system_versioning_asof= '1900-01-01 00:00:00';
|
set time_zone= "+10:00";
|
||||||
|
set global system_versioning_asof= timestamp'1991-11-11 11:11:11.111111';
|
||||||
|
set system_versioning_asof= '1990-01-01 00:00:00';
|
||||||
select @@global.system_versioning_asof != @@system_versioning_asof as different;
|
select @@global.system_versioning_asof != @@system_versioning_asof as different;
|
||||||
different
|
different
|
||||||
1
|
1
|
||||||
set system_versioning_asof= default;
|
set system_versioning_asof= default;
|
||||||
|
select @@global.system_versioning_asof != @@system_versioning_asof as different;
|
||||||
|
different
|
||||||
|
1
|
||||||
|
set global system_versioning_asof= default;
|
||||||
select @@global.system_versioning_asof = @@system_versioning_asof as equal;
|
select @@global.system_versioning_asof = @@system_versioning_asof as equal;
|
||||||
equal
|
equal
|
||||||
1
|
1
|
||||||
|
set global time_zone= DEFAULT;
|
||||||
|
set time_zone= DEFAULT;
|
||||||
set global system_versioning_asof= DEFAULT;
|
set global system_versioning_asof= DEFAULT;
|
||||||
set system_versioning_asof= DEFAULT;
|
set system_versioning_asof= DEFAULT;
|
||||||
select @@global.system_versioning_asof, @@system_versioning_asof;
|
select @@global.system_versioning_asof, @@system_versioning_asof;
|
||||||
@ -142,6 +150,77 @@ select * from t for system_time between '1970-01-01 00:00' and current_timestamp
|
|||||||
a
|
a
|
||||||
2
|
2
|
||||||
1
|
1
|
||||||
|
# MDEV-16026: Global system_versioning_asof must not be used if client sessions can have non-default time zone
|
||||||
|
# changing time zone should not abuse `system_versioning_asof`
|
||||||
|
set session time_zone = '+10:00';
|
||||||
|
set global system_versioning_asof = '1999-09-08 00:00:00.000000';
|
||||||
|
show global variables like 'system_versioning_asof';
|
||||||
|
Variable_name Value
|
||||||
|
system_versioning_asof 1999-09-08 00:00:00.000000
|
||||||
|
set session time_zone = '+03:00';
|
||||||
|
show global variables like 'system_versioning_asof';
|
||||||
|
Variable_name Value
|
||||||
|
system_versioning_asof 1999-09-07 17:00:00.000000
|
||||||
|
set session time_zone = '+03:00';
|
||||||
|
set session system_versioning_asof = '2000-09-08 00:00:00.000000';
|
||||||
|
show session variables like 'system_versioning_asof';
|
||||||
|
Variable_name Value
|
||||||
|
system_versioning_asof 2000-09-08 00:00:00.000000
|
||||||
|
set session time_zone = '+10:00';
|
||||||
|
show session variables like 'system_versioning_asof';
|
||||||
|
Variable_name Value
|
||||||
|
system_versioning_asof 2000-09-08 07:00:00.000000
|
||||||
|
# global and local time zones should not interfere
|
||||||
|
show global variables like 'system_versioning_asof';
|
||||||
|
Variable_name Value
|
||||||
|
system_versioning_asof 1999-09-08 00:00:00.000000
|
||||||
|
set time_zone= "+10:00";
|
||||||
|
set system_versioning_asof= FROM_UNIXTIME(@before);
|
||||||
|
select * from t as empty;
|
||||||
|
a
|
||||||
|
set system_versioning_asof= FROM_UNIXTIME(@after);
|
||||||
|
select * from t as nonempty;
|
||||||
|
a
|
||||||
|
1
|
||||||
|
set time_zone= "+03:00";
|
||||||
|
set system_versioning_asof= FROM_UNIXTIME(@before);
|
||||||
|
select * from t as empty;
|
||||||
|
a
|
||||||
|
set system_versioning_asof= FROM_UNIXTIME(@after);
|
||||||
|
select * from t as nonempty;
|
||||||
|
a
|
||||||
|
1
|
||||||
|
set global system_versioning_asof= FROM_UNIXTIME(@after);
|
||||||
|
select * from t as nonempty;
|
||||||
|
a
|
||||||
|
1
|
||||||
|
connect subcon,127.0.0.1,root,,,$SERVER_MYPORT_1;
|
||||||
|
connection subcon;
|
||||||
|
select * from t as nonempty;
|
||||||
|
a
|
||||||
|
1
|
||||||
|
disconnect subcon;
|
||||||
|
connection default;
|
||||||
|
set global system_versioning_asof= FROM_UNIXTIME(@before);
|
||||||
|
select * from t as nonempty;
|
||||||
|
a
|
||||||
|
1
|
||||||
|
connect subcon,127.0.0.1,root,,,$SERVER_MYPORT_1;
|
||||||
|
connection subcon;
|
||||||
|
select * from t as empty;
|
||||||
|
a
|
||||||
|
disconnect subcon;
|
||||||
|
connection default;
|
||||||
|
# MDEV-16481: set global system_versioning_asof=sf() crashes in specific case
|
||||||
|
# Using global variable inside a stored function should not crash
|
||||||
|
create or replace function now_global() returns timestamp
|
||||||
|
return CONVERT_TZ(now(), @@session.time_zone, @@global.time_zone);
|
||||||
|
set global system_versioning_asof= now_global();
|
||||||
|
drop function now_global;
|
||||||
|
set global time_zone= "SYSTEM";
|
||||||
|
set time_zone= "SYSTEM";
|
||||||
|
set global system_versioning_asof= default;
|
||||||
|
set system_versioning_asof= default;
|
||||||
show status like "Feature_system_versioning";
|
show status like "Feature_system_versioning";
|
||||||
Variable_name Value
|
Variable_name Value
|
||||||
Feature_system_versioning 2
|
Feature_system_versioning 2
|
||||||
@ -153,7 +232,7 @@ create or replace table t1 (x int) with system versioning;
|
|||||||
create or replace table t2 (y int);
|
create or replace table t2 (y int);
|
||||||
insert into t1 values (1);
|
insert into t1 values (1);
|
||||||
insert into t2 values (1);
|
insert into t2 values (1);
|
||||||
set system_versioning_asof= '1970-01-01 00:00:00';
|
set system_versioning_asof= '1970-01-02 00:00:00';
|
||||||
delete t1, t2 from t1 join t2 where t1.x = t2.y;
|
delete t1, t2 from t1 join t2 where t1.x = t2.y;
|
||||||
select * from t1 for system_time as of timestamp now(6);
|
select * from t1 for system_time as of timestamp now(6);
|
||||||
x
|
x
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
create table t (a int) with system versioning;
|
create table t (a int) with system versioning;
|
||||||
|
set @before= UNIX_TIMESTAMP(now(6));
|
||||||
insert into t values (1);
|
insert into t values (1);
|
||||||
|
set @after= UNIX_TIMESTAMP(now(6));
|
||||||
update t set a= 2;
|
update t set a= 2;
|
||||||
|
|
||||||
show global variables like 'system_versioning_asof';
|
show global variables like 'system_versioning_asof';
|
||||||
@ -51,16 +53,16 @@ set system_versioning_asof= '2011-00-28 00:00';
|
|||||||
set system_versioning_asof= '0000-00-00 00:00';
|
set system_versioning_asof= '0000-00-00 00:00';
|
||||||
|
|
||||||
--echo # GLOBAL @@system_versioning_asof
|
--echo # GLOBAL @@system_versioning_asof
|
||||||
set global system_versioning_asof= '1911-11-11 11:11:11.1111119';
|
set global system_versioning_asof= '1991-11-11 11:11:11.1111119';
|
||||||
show global variables like 'system_versioning_asof';
|
show global variables like 'system_versioning_asof';
|
||||||
|
|
||||||
set global system_versioning_asof= '1900-01-01 00:00:00';
|
set global system_versioning_asof= '1990-01-01 00:00:00';
|
||||||
show global variables like 'system_versioning_asof';
|
show global variables like 'system_versioning_asof';
|
||||||
|
|
||||||
set global system_versioning_asof= timestamp'1911-11-11 11:11:11.1111119';
|
set global system_versioning_asof= timestamp'1991-11-11 11:11:11.1111119';
|
||||||
show global variables like 'system_versioning_asof';
|
show global variables like 'system_versioning_asof';
|
||||||
|
|
||||||
set @ts= timestamp'1900-01-01 00:00:00';
|
set @ts= timestamp'1990-01-01 00:00:00';
|
||||||
set global system_versioning_asof= @ts;
|
set global system_versioning_asof= @ts;
|
||||||
show global variables like 'system_versioning_asof';
|
show global variables like 'system_versioning_asof';
|
||||||
|
|
||||||
@ -68,26 +70,32 @@ set global system_versioning_asof= default;
|
|||||||
select @@global.system_versioning_asof;
|
select @@global.system_versioning_asof;
|
||||||
|
|
||||||
--echo # SESSION @@system_versioning_asof
|
--echo # SESSION @@system_versioning_asof
|
||||||
set system_versioning_asof= '1911-11-11 11:11:11.1111119';
|
set system_versioning_asof= '1991-11-11 11:11:11.1111119';
|
||||||
show variables like 'system_versioning_asof';
|
show variables like 'system_versioning_asof';
|
||||||
|
|
||||||
set system_versioning_asof= '1900-01-01 00:00:00';
|
set system_versioning_asof= '1990-01-01 00:00:00';
|
||||||
show variables like 'system_versioning_asof';
|
show variables like 'system_versioning_asof';
|
||||||
|
|
||||||
set system_versioning_asof= timestamp'1911-11-11 11:11:11.1111119';
|
set system_versioning_asof= timestamp'1991-11-11 11:11:11.1111119';
|
||||||
show variables like 'system_versioning_asof';
|
show variables like 'system_versioning_asof';
|
||||||
|
|
||||||
set @ts= timestamp'1900-01-01 00:00:00';
|
set @ts= timestamp'1990-01-01 00:00:00';
|
||||||
set system_versioning_asof= @ts;
|
set system_versioning_asof= @ts;
|
||||||
show variables like 'system_versioning_asof';
|
show variables like 'system_versioning_asof';
|
||||||
|
|
||||||
--echo # DEFAULT: value is copied from GLOBAL to SESSION
|
--echo # DEFAULT: value is copied from GLOBAL to SESSION
|
||||||
set global system_versioning_asof= timestamp'1911-11-11 11:11:11.111111';
|
set global time_zone= "+03:00";
|
||||||
set system_versioning_asof= '1900-01-01 00:00:00';
|
set time_zone= "+10:00";
|
||||||
|
set global system_versioning_asof= timestamp'1991-11-11 11:11:11.111111';
|
||||||
|
set system_versioning_asof= '1990-01-01 00:00:00';
|
||||||
select @@global.system_versioning_asof != @@system_versioning_asof as different;
|
select @@global.system_versioning_asof != @@system_versioning_asof as different;
|
||||||
set system_versioning_asof= default;
|
set system_versioning_asof= default;
|
||||||
|
select @@global.system_versioning_asof != @@system_versioning_asof as different;
|
||||||
|
set global system_versioning_asof= default;
|
||||||
select @@global.system_versioning_asof = @@system_versioning_asof as equal;
|
select @@global.system_versioning_asof = @@system_versioning_asof as equal;
|
||||||
|
|
||||||
|
set global time_zone= DEFAULT;
|
||||||
|
set time_zone= DEFAULT;
|
||||||
set global system_versioning_asof= DEFAULT;
|
set global system_versioning_asof= DEFAULT;
|
||||||
set system_versioning_asof= DEFAULT;
|
set system_versioning_asof= DEFAULT;
|
||||||
select @@global.system_versioning_asof, @@system_versioning_asof;
|
select @@global.system_versioning_asof, @@system_versioning_asof;
|
||||||
@ -100,6 +108,65 @@ select * from t for system_time all;
|
|||||||
select * from t for system_time from '1970-01-01 00:00' to current_timestamp(6);
|
select * from t for system_time from '1970-01-01 00:00' to current_timestamp(6);
|
||||||
select * from t for system_time between '1970-01-01 00:00' and current_timestamp(6);
|
select * from t for system_time between '1970-01-01 00:00' and current_timestamp(6);
|
||||||
|
|
||||||
|
-- echo # MDEV-16026: Global system_versioning_asof must not be used if client sessions can have non-default time zone
|
||||||
|
-- echo # changing time zone should not abuse `system_versioning_asof`
|
||||||
|
|
||||||
|
set session time_zone = '+10:00';
|
||||||
|
set global system_versioning_asof = '1999-09-08 00:00:00.000000';
|
||||||
|
show global variables like 'system_versioning_asof';
|
||||||
|
set session time_zone = '+03:00';
|
||||||
|
show global variables like 'system_versioning_asof';
|
||||||
|
|
||||||
|
set session time_zone = '+03:00';
|
||||||
|
set session system_versioning_asof = '2000-09-08 00:00:00.000000';
|
||||||
|
show session variables like 'system_versioning_asof';
|
||||||
|
set session time_zone = '+10:00';
|
||||||
|
show session variables like 'system_versioning_asof';
|
||||||
|
-- echo # global and local time zones should not interfere
|
||||||
|
show global variables like 'system_versioning_asof';
|
||||||
|
|
||||||
|
set time_zone= "+10:00";
|
||||||
|
set system_versioning_asof= FROM_UNIXTIME(@before);
|
||||||
|
select * from t as empty;
|
||||||
|
set system_versioning_asof= FROM_UNIXTIME(@after);
|
||||||
|
select * from t as nonempty;
|
||||||
|
|
||||||
|
set time_zone= "+03:00";
|
||||||
|
set system_versioning_asof= FROM_UNIXTIME(@before);
|
||||||
|
select * from t as empty;
|
||||||
|
set system_versioning_asof= FROM_UNIXTIME(@after);
|
||||||
|
select * from t as nonempty;
|
||||||
|
|
||||||
|
set global system_versioning_asof= FROM_UNIXTIME(@after);
|
||||||
|
select * from t as nonempty;
|
||||||
|
|
||||||
|
--connect (subcon,127.0.0.1,root,,,$SERVER_MYPORT_1)
|
||||||
|
--connection subcon
|
||||||
|
select * from t as nonempty;
|
||||||
|
--disconnect subcon
|
||||||
|
--connection default
|
||||||
|
|
||||||
|
set global system_versioning_asof= FROM_UNIXTIME(@before);
|
||||||
|
select * from t as nonempty;
|
||||||
|
|
||||||
|
--connect (subcon,127.0.0.1,root,,,$SERVER_MYPORT_1)
|
||||||
|
--connection subcon
|
||||||
|
select * from t as empty;
|
||||||
|
--disconnect subcon
|
||||||
|
--connection default
|
||||||
|
|
||||||
|
--echo # MDEV-16481: set global system_versioning_asof=sf() crashes in specific case
|
||||||
|
--echo # Using global variable inside a stored function should not crash
|
||||||
|
create or replace function now_global() returns timestamp
|
||||||
|
return CONVERT_TZ(now(), @@session.time_zone, @@global.time_zone);
|
||||||
|
set global system_versioning_asof= now_global();
|
||||||
|
drop function now_global;
|
||||||
|
|
||||||
|
set global time_zone= "SYSTEM";
|
||||||
|
set time_zone= "SYSTEM";
|
||||||
|
set global system_versioning_asof= default;
|
||||||
|
set system_versioning_asof= default;
|
||||||
|
|
||||||
show status like "Feature_system_versioning";
|
show status like "Feature_system_versioning";
|
||||||
|
|
||||||
drop table t;
|
drop table t;
|
||||||
@ -111,7 +178,7 @@ create or replace table t1 (x int) with system versioning;
|
|||||||
create or replace table t2 (y int);
|
create or replace table t2 (y int);
|
||||||
insert into t1 values (1);
|
insert into t1 values (1);
|
||||||
insert into t2 values (1);
|
insert into t2 values (1);
|
||||||
set system_versioning_asof= '1970-01-01 00:00:00';
|
set system_versioning_asof= '1970-01-02 00:00:00';
|
||||||
delete t1, t2 from t1 join t2 where t1.x = t2.y;
|
delete t1, t2 from t1 join t2 where t1.x = t2.y;
|
||||||
select * from t1 for system_time as of timestamp now(6);
|
select * from t1 for system_time as of timestamp now(6);
|
||||||
|
|
||||||
|
@ -197,7 +197,8 @@ enum vers_system_time_t
|
|||||||
struct vers_asof_timestamp_t
|
struct vers_asof_timestamp_t
|
||||||
{
|
{
|
||||||
ulong type;
|
ulong type;
|
||||||
MYSQL_TIME ltime;
|
my_time_t unix_time;
|
||||||
|
ulong second_part;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum vers_alter_history_enum
|
enum vers_alter_history_enum
|
||||||
|
@ -278,6 +278,16 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Structure for holding unix timestamp and high precision second part.
|
||||||
|
*/
|
||||||
|
typedef struct my_time_t_hires
|
||||||
|
{
|
||||||
|
my_time_t unix_time;
|
||||||
|
ulong second_part;
|
||||||
|
} my_time_t_hires;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
set_var_base descendant for assignments to the system variables.
|
set_var_base descendant for assignments to the system variables.
|
||||||
*/
|
*/
|
||||||
@ -296,6 +306,7 @@ public:
|
|||||||
plugin_ref *plugins; ///< for Sys_var_pluginlist
|
plugin_ref *plugins; ///< for Sys_var_pluginlist
|
||||||
Time_zone *time_zone; ///< for Sys_var_tz
|
Time_zone *time_zone; ///< for Sys_var_tz
|
||||||
LEX_STRING string_value; ///< for Sys_var_charptr and others
|
LEX_STRING string_value; ///< for Sys_var_charptr and others
|
||||||
|
my_time_t_hires timestamp; ///< for Sys_var_vers_asof
|
||||||
const void *ptr; ///< for Sys_var_struct
|
const void *ptr; ///< for Sys_var_struct
|
||||||
} save_result;
|
} save_result;
|
||||||
LEX_CSTRING base; /**< for structured variables, like keycache_name.variable_name */
|
LEX_CSTRING base; /**< for structured variables, like keycache_name.variable_name */
|
||||||
|
@ -696,8 +696,12 @@ bool vers_select_conds_t::init_from_sysvar(THD *thd)
|
|||||||
if (type != SYSTEM_TIME_UNSPECIFIED && type != SYSTEM_TIME_ALL)
|
if (type != SYSTEM_TIME_UNSPECIFIED && type != SYSTEM_TIME_ALL)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(type == SYSTEM_TIME_AS_OF);
|
DBUG_ASSERT(type == SYSTEM_TIME_AS_OF);
|
||||||
|
MYSQL_TIME ltime;
|
||||||
|
thd->variables.time_zone->gmt_sec_to_TIME(<ime, in.unix_time);
|
||||||
|
ltime.second_part = in.second_part;
|
||||||
|
|
||||||
start.item= new (thd->mem_root)
|
start.item= new (thd->mem_root)
|
||||||
Item_datetime_literal(thd, &in.ltime, TIME_SECOND_PART_DIGITS);
|
Item_datetime_literal(thd, <ime, TIME_SECOND_PART_DIGITS);
|
||||||
if (!start.item)
|
if (!start.item)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -438,11 +438,10 @@ static Sys_var_charptr Sys_my_bind_addr(
|
|||||||
READ_ONLY GLOBAL_VAR(my_bind_addr_str), CMD_LINE(REQUIRED_ARG),
|
READ_ONLY GLOBAL_VAR(my_bind_addr_str), CMD_LINE(REQUIRED_ARG),
|
||||||
IN_FS_CHARSET, DEFAULT(0));
|
IN_FS_CHARSET, DEFAULT(0));
|
||||||
|
|
||||||
const char *Sys_var_vers_asof::asof_keywords[]= {"DEFAULT", NULL};
|
|
||||||
static Sys_var_vers_asof Sys_vers_asof_timestamp(
|
static Sys_var_vers_asof Sys_vers_asof_timestamp(
|
||||||
"system_versioning_asof", "Default value for the FOR SYSTEM_TIME AS OF clause",
|
"system_versioning_asof", "Default value for the FOR SYSTEM_TIME AS OF clause",
|
||||||
SESSION_VAR(vers_asof_timestamp.type), NO_CMD_LINE,
|
SESSION_VAR(vers_asof_timestamp.type), NO_CMD_LINE,
|
||||||
Sys_var_vers_asof::asof_keywords, DEFAULT(SYSTEM_TIME_UNSPECIFIED));
|
DEFAULT(SYSTEM_TIME_UNSPECIFIED));
|
||||||
|
|
||||||
static const char *vers_alter_history_keywords[]= {"ERROR", "KEEP", NullS};
|
static const char *vers_alter_history_keywords[]= {"ERROR", "KEEP", NullS};
|
||||||
static Sys_var_enum Sys_vers_alter_history(
|
static Sys_var_enum Sys_vers_alter_history(
|
||||||
|
@ -2631,63 +2631,82 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class Sys_var_vers_asof: public Sys_var_enum
|
class Sys_var_vers_asof: public sys_var
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
static const char *asof_keywords[];
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Sys_var_vers_asof(const char *name_arg,
|
Sys_var_vers_asof(const char *name_arg,
|
||||||
const char *comment, int flag_args, ptrdiff_t off, size_t size,
|
const char *comment, int flag_args, ptrdiff_t off, size_t size,
|
||||||
CMD_LINE getopt, const char *values[],
|
CMD_LINE getopt, uint def_val,
|
||||||
uint def_val)
|
PolyLock *lock= NO_MUTEX_GUARD,
|
||||||
: Sys_var_enum(name_arg, comment, flag_args, off, size,
|
binlog_status_enum binlog_status_arg= VARIABLE_NOT_IN_BINLOG,
|
||||||
getopt, values, def_val)
|
on_check_function on_check_func= NULL,
|
||||||
|
on_update_function on_update_func= NULL,
|
||||||
|
const char *substitute= NULL)
|
||||||
|
: sys_var(&all_sys_vars, name_arg, comment, flag_args, off,
|
||||||
|
getopt.id, getopt.arg_type, SHOW_CHAR, def_val, lock,
|
||||||
|
binlog_status_arg, on_check_func, on_update_func, substitute)
|
||||||
{
|
{
|
||||||
// setval() accepts string rather enum
|
|
||||||
option.var_type= GET_STR;
|
option.var_type= GET_STR;
|
||||||
}
|
}
|
||||||
virtual bool do_check(THD *thd, set_var *var)
|
virtual bool do_check(THD *thd, set_var *var)
|
||||||
{
|
{
|
||||||
if (!Sys_var_enum::do_check(thd, var))
|
if (!var->value)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
MYSQL_TIME ltime;
|
MYSQL_TIME ltime;
|
||||||
bool res= var->value->get_date(<ime, TIME_NO_ZERO_IN_DATE|TIME_NO_ZERO_DATE);
|
bool res= var->value->get_date(<ime,
|
||||||
|
TIME_NO_ZERO_IN_DATE | TIME_NO_ZERO_DATE);
|
||||||
if (!res)
|
if (!res)
|
||||||
{
|
{
|
||||||
var->save_result.ulonglong_value= SYSTEM_TIME_AS_OF;
|
uint error;
|
||||||
|
var->save_result.timestamp.unix_time=
|
||||||
|
thd->variables.time_zone->TIME_to_gmt_sec(<ime, &error);
|
||||||
|
var->save_result.timestamp.second_part= ltime.second_part;
|
||||||
|
res= error != 0;
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool update(set_var *var, vers_asof_timestamp_t &out)
|
static bool update(THD *thd, set_var *var, vers_asof_timestamp_t *out)
|
||||||
{
|
{
|
||||||
bool res= false;
|
if (var->value)
|
||||||
out.type= static_cast<enum_var_type>(var->save_result.ulonglong_value);
|
|
||||||
if (out.type == SYSTEM_TIME_AS_OF)
|
|
||||||
{
|
{
|
||||||
if (var->value)
|
out->type = SYSTEM_TIME_AS_OF;
|
||||||
{
|
out->unix_time = var->save_result.timestamp.unix_time;
|
||||||
res= var->value->get_date(&out.ltime, TIME_NO_ZERO_IN_DATE|TIME_NO_ZERO_DATE);
|
out->second_part= var->save_result.timestamp.second_part;
|
||||||
}
|
|
||||||
else // set DEFAULT from global var
|
|
||||||
{
|
|
||||||
out= global_var(vers_asof_timestamp_t);
|
|
||||||
res= false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return res;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void save_default(set_var *var, vers_asof_timestamp_t *out)
|
||||||
|
{
|
||||||
|
out->type= SYSTEM_TIME_UNSPECIFIED;
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual bool global_update(THD *thd, set_var *var)
|
virtual bool global_update(THD *thd, set_var *var)
|
||||||
{
|
{
|
||||||
return update(var, global_var(vers_asof_timestamp_t));
|
return update(thd, var, &global_var(vers_asof_timestamp_t));
|
||||||
}
|
}
|
||||||
virtual bool session_update(THD *thd, set_var *var)
|
virtual bool session_update(THD *thd, set_var *var)
|
||||||
{
|
{
|
||||||
return update(var, session_var(thd, vers_asof_timestamp_t));
|
return update(thd, var, &session_var(thd, vers_asof_timestamp_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool session_is_default(THD *thd)
|
||||||
|
{
|
||||||
|
const vers_asof_timestamp_t &var= session_var(thd, vers_asof_timestamp_t);
|
||||||
|
return var.type == SYSTEM_TIME_UNSPECIFIED;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void session_save_default(THD *thd, set_var *var)
|
||||||
|
{
|
||||||
|
save_default(var, &session_var(thd, vers_asof_timestamp_t));
|
||||||
|
}
|
||||||
|
virtual void global_save_default(THD *thd, set_var *var)
|
||||||
|
{
|
||||||
|
save_default(var, &global_var(vers_asof_timestamp_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -2696,15 +2715,19 @@ private:
|
|||||||
switch (val.type)
|
switch (val.type)
|
||||||
{
|
{
|
||||||
case SYSTEM_TIME_UNSPECIFIED:
|
case SYSTEM_TIME_UNSPECIFIED:
|
||||||
case SYSTEM_TIME_ALL:
|
return (uchar*)"DEFAULT";
|
||||||
return (uchar*) thd->strdup(asof_keywords[val.type]);
|
break;
|
||||||
case SYSTEM_TIME_AS_OF:
|
case SYSTEM_TIME_AS_OF:
|
||||||
{
|
{
|
||||||
uchar *buf= (uchar*) thd->alloc(MAX_DATE_STRING_REP_LENGTH);
|
uchar *buf= (uchar*) thd->alloc(MAX_DATE_STRING_REP_LENGTH);
|
||||||
if (buf &&!my_datetime_to_str(&val.ltime, (char*) buf, 6))
|
MYSQL_TIME ltime;
|
||||||
|
|
||||||
|
thd->variables.time_zone->gmt_sec_to_TIME(<ime, val.unix_time);
|
||||||
|
ltime.second_part= val.second_part;
|
||||||
|
|
||||||
|
if (buf && !my_datetime_to_str(<ime, (char*) buf, 6))
|
||||||
{
|
{
|
||||||
// TODO: figure out variable name
|
my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name.str, "NULL (wrong datetime)");
|
||||||
my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), "system_versioning_asof_timestamp", "NULL (wrong datetime)");
|
|
||||||
return (uchar*) thd->strdup("Error: wrong datetime");
|
return (uchar*) thd->strdup("Error: wrong datetime");
|
||||||
}
|
}
|
||||||
return buf;
|
return buf;
|
||||||
@ -2712,7 +2735,7 @@ private:
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), "system_versioning_asof_timestamp", "NULL (wrong range type)");
|
my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name.str, "NULL (wrong range type)");
|
||||||
return (uchar*) thd->strdup("Error: wrong range type");
|
return (uchar*) thd->strdup("Error: wrong range type");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user