mirror of
https://github.com/MariaDB/server.git
synced 2025-08-07 00:04:31 +03:00
MDEV-16546 post-review fixes
* clarify the help text for --system-versioning-insert-history * move the vers_write=false check from Item_field::fix_fields() next to other vers field checks in find_field_in_table() * move row_start validation from handler::write_row() next to vers_update_fields() * make secure_timestamp check to happen in one place only, extract it into a function is_set_timestamp_vorbidden(). * overwriting vers fields is an error, just like setting @@timestamp * don't run vers_insert_history() for every row
This commit is contained in:
@@ -1386,6 +1386,7 @@ The following specify which files/extra groups are read (specified before remain
|
|||||||
to ALTER
|
to ALTER
|
||||||
--system-versioning-insert-history
|
--system-versioning-insert-history
|
||||||
Allows direct inserts into ROW_START and ROW_END columns
|
Allows direct inserts into ROW_START and ROW_END columns
|
||||||
|
if secure_timestamp allows changing @@timestamp
|
||||||
--table-cache=# Deprecated; use --table-open-cache instead.
|
--table-cache=# Deprecated; use --table-open-cache instead.
|
||||||
--table-definition-cache=#
|
--table-definition-cache=#
|
||||||
The number of cached table definitions
|
The number of cached table definitions
|
||||||
|
@@ -3555,7 +3555,7 @@ COMMAND_LINE_ARGUMENT NULL
|
|||||||
VARIABLE_NAME SYSTEM_VERSIONING_INSERT_HISTORY
|
VARIABLE_NAME SYSTEM_VERSIONING_INSERT_HISTORY
|
||||||
VARIABLE_SCOPE SESSION
|
VARIABLE_SCOPE SESSION
|
||||||
VARIABLE_TYPE BOOLEAN
|
VARIABLE_TYPE BOOLEAN
|
||||||
VARIABLE_COMMENT Allows direct inserts into ROW_START and ROW_END columns
|
VARIABLE_COMMENT Allows direct inserts into ROW_START and ROW_END columns if secure_timestamp allows changing @@timestamp
|
||||||
NUMERIC_MIN_VALUE NULL
|
NUMERIC_MIN_VALUE NULL
|
||||||
NUMERIC_MAX_VALUE NULL
|
NUMERIC_MAX_VALUE NULL
|
||||||
NUMERIC_BLOCK_SIZE NULL
|
NUMERIC_BLOCK_SIZE NULL
|
||||||
|
@@ -4275,7 +4275,7 @@ COMMAND_LINE_ARGUMENT NULL
|
|||||||
VARIABLE_NAME SYSTEM_VERSIONING_INSERT_HISTORY
|
VARIABLE_NAME SYSTEM_VERSIONING_INSERT_HISTORY
|
||||||
VARIABLE_SCOPE SESSION
|
VARIABLE_SCOPE SESSION
|
||||||
VARIABLE_TYPE BOOLEAN
|
VARIABLE_TYPE BOOLEAN
|
||||||
VARIABLE_COMMENT Allows direct inserts into ROW_START and ROW_END columns
|
VARIABLE_COMMENT Allows direct inserts into ROW_START and ROW_END columns if secure_timestamp allows changing @@timestamp
|
||||||
NUMERIC_MIN_VALUE NULL
|
NUMERIC_MIN_VALUE NULL
|
||||||
NUMERIC_MAX_VALUE NULL
|
NUMERIC_MAX_VALUE NULL
|
||||||
NUMERIC_BLOCK_SIZE NULL
|
NUMERIC_BLOCK_SIZE NULL
|
||||||
|
@@ -141,6 +141,8 @@ t1 CREATE TABLE `t1` (
|
|||||||
insert into t1(x, row_start, row_end) values (3, '1980-01-01 00:00:00', '1980-01-01 00:00:01');
|
insert into t1(x, row_start, row_end) values (3, '1980-01-01 00:00:00', '1980-01-01 00:00:01');
|
||||||
insert into t2(y, row_start, row_end) values (4, '1980-01-01 00:00:00', '1980-01-01 00:00:01');
|
insert into t2(y, row_start, row_end) values (4, '1980-01-01 00:00:00', '1980-01-01 00:00:01');
|
||||||
insert into t3 values (5, '1980-01-01 00:00:00', '1980-01-01 00:00:01');
|
insert into t3 values (5, '1980-01-01 00:00:00', '1980-01-01 00:00:01');
|
||||||
|
insert into t3 values (5, '1980-01-02 00:00:00', '1980-01-01 00:00:01');
|
||||||
|
ERROR HY000: Incorrect row_start value: '1980-01-02 00:00:00.000000'
|
||||||
select x, row_start, row_end from t1 for system_time all;
|
select x, row_start, row_end from t1 for system_time all;
|
||||||
x row_start row_end
|
x row_start row_end
|
||||||
3 1980-01-01 00:00:00.000000 1980-01-01 00:00:01.000000
|
3 1980-01-01 00:00:00.000000 1980-01-01 00:00:01.000000
|
||||||
@@ -286,18 +288,19 @@ row_start = '1980-01-01 00:00:00' row_end = '1980-01-01 00:00:01'
|
|||||||
# restart: --secure-timestamp=YES
|
# restart: --secure-timestamp=YES
|
||||||
set @@system_versioning_insert_history= 1;
|
set @@system_versioning_insert_history= 1;
|
||||||
insert into t1(x, row_start, row_end) values (8, '1980-01-01 00:00:00', '1980-01-01 00:00:01');
|
insert into t1(x, row_start, row_end) values (8, '1980-01-01 00:00:00', '1980-01-01 00:00:01');
|
||||||
ERROR 42S22: Unknown column 'row_start' in 'field list'
|
ERROR HY000: The MariaDB server is running with the --secure-timestamp=YES option so it cannot execute this statement
|
||||||
# restart: --secure-timestamp=REPLICATION
|
# restart: --secure-timestamp=REPLICATION
|
||||||
|
create user nobody;
|
||||||
|
grant all privileges on test.* to nobody;
|
||||||
set @@system_versioning_insert_history= 1;
|
set @@system_versioning_insert_history= 1;
|
||||||
insert into t1(x, row_start, row_end) values (9, '1980-01-01 00:00:00', '1980-01-01 00:00:01');
|
insert into test.t1(x, row_start, row_end) values (9, '1980-01-01 00:00:00', '1980-01-01 00:00:01');
|
||||||
ERROR 42S22: Unknown column 'row_start' in 'field list'
|
ERROR 42000: Access denied; you need (at least one of) the BINLOG REPLAY privilege(s) for this operation
|
||||||
# restart: --secure-timestamp=SUPER
|
# restart: --secure-timestamp=SUPER
|
||||||
set @@system_versioning_insert_history= 1;
|
set @@system_versioning_insert_history= 1;
|
||||||
insert into t1(x, row_start, row_end) values (10, '1980-01-01 00:00:00', '1980-01-01 00:00:01');
|
insert into test.t1(x, row_start, row_end) values (10, '1980-01-01 00:00:00', '1980-01-01 00:00:01');
|
||||||
create user nobody;
|
set @@system_versioning_insert_history= 1;
|
||||||
use test;
|
insert into test.t1(x, row_start, row_end) values (7, '1980-01-01 00:00:00', '1980-01-01 00:00:01');
|
||||||
insert into t1(x, row_start, row_end) values (7, '1980-01-01 00:00:00', '1980-01-01 00:00:01');
|
ERROR 42000: Access denied; you need (at least one of) the SUPER, BINLOG REPLAY privilege(s) for this operation
|
||||||
ERROR 42S22: Unknown column 'row_start' in 'field list'
|
|
||||||
use test;
|
use test;
|
||||||
# restart: --secure-timestamp=NO
|
# restart: --secure-timestamp=NO
|
||||||
drop tables t1, t2, t3;
|
drop tables t1, t2, t3;
|
||||||
|
@@ -3257,6 +3257,7 @@ delete from t partition (px);
|
|||||||
ERROR HY000: Unknown partition 'px' in table 't'
|
ERROR HY000: Unknown partition 'px' in table 't'
|
||||||
unlock tables;
|
unlock tables;
|
||||||
drop table t;
|
drop table t;
|
||||||
|
set timestamp= default;
|
||||||
#
|
#
|
||||||
# MDEV-28978 Assertion failure in THD::binlog_query or unexpected
|
# MDEV-28978 Assertion failure in THD::binlog_query or unexpected
|
||||||
# ER_ERROR_ON_WRITE with auto-partitioning
|
# ER_ERROR_ON_WRITE with auto-partitioning
|
||||||
@@ -3266,4 +3267,24 @@ insert into t () values (),(),(),(),(),();
|
|||||||
update t set a = 1;
|
update t set a = 1;
|
||||||
update t set a = 2 limit 0;
|
update t set a = 2 limit 0;
|
||||||
drop table t;
|
drop table t;
|
||||||
|
#
|
||||||
|
# MDEV-16546 System versioning setting to allow history modification
|
||||||
|
#
|
||||||
|
create table t1 (a varchar(100)) with system versioning
|
||||||
|
partition by system_time interval 1 day
|
||||||
|
starts '2021-09-30 00:00:00' partitions 3;
|
||||||
|
set system_versioning_insert_history=1;
|
||||||
|
insert into t1 (a,row_start,row_end) values
|
||||||
|
('p0', '2021-09-30', '2021-09-30 10:00:00'),
|
||||||
|
('p1', '2021-09-30', '2021-10-01 10:00:00'),
|
||||||
|
('overflows, so also p1','2021-09-30', '2021-10-10 10:00:00'),
|
||||||
|
('pn, current', '2021-09-30', '2038-01-19 03:14:07.999999');
|
||||||
|
select table_name,partition_name,partition_ordinal_position,partition_method,partition_description,table_rows
|
||||||
|
from information_schema.partitions where table_schema='test';
|
||||||
|
table_name partition_name partition_ordinal_position partition_method partition_description table_rows
|
||||||
|
t1 p0 1 SYSTEM_TIME 2021-10-01 00:00:00 1
|
||||||
|
t1 p1 2 SYSTEM_TIME 2021-10-02 00:00:00 2
|
||||||
|
t1 pn 3 SYSTEM_TIME CURRENT 1
|
||||||
|
drop table t1;
|
||||||
|
set system_versioning_insert_history=0;
|
||||||
set global innodb_stats_persistent= @save_persistent;
|
set global innodb_stats_persistent= @save_persistent;
|
||||||
|
@@ -434,6 +434,25 @@ x check_row_ts(row_start, row_end)
|
|||||||
select row_start = '1980-01-01 00:00:00', row_end = '1980-01-01 00:00:01' from t3 for system_time all where x = 3;
|
select row_start = '1980-01-01 00:00:00', row_end = '1980-01-01 00:00:01' from t3 for system_time all where x = 3;
|
||||||
row_start = '1980-01-01 00:00:00' row_end = '1980-01-01 00:00:01'
|
row_start = '1980-01-01 00:00:00' row_end = '1980-01-01 00:00:01'
|
||||||
1 1
|
1 1
|
||||||
|
# why a slave cannot have system_versioning_insert_history always on
|
||||||
|
connection master;
|
||||||
|
set @@system_versioning_insert_history= 0;
|
||||||
|
set sql_mode='';
|
||||||
|
create or replace table t1 (a int,
|
||||||
|
rs timestamp(6) as row start, re timestamp(6) as row end,
|
||||||
|
period for system_time (rs,re)) with system versioning;
|
||||||
|
insert t1 values (1, '2000-01-01 02:03:04', '2001-01-01 02:03.04');
|
||||||
|
Warnings:
|
||||||
|
Warning 1906 The value specified for generated column 'rs' in table 't1' has been ignored
|
||||||
|
Warning 1906 The value specified for generated column 're' in table 't1' has been ignored
|
||||||
|
select a,check_row_ts(rs,re) from t1 for system_time all;
|
||||||
|
a check_row_ts(rs,re)
|
||||||
|
1 CURRENT ROW
|
||||||
|
connection slave;
|
||||||
|
select a,check_row_ts(rs,re) from t1 for system_time all;
|
||||||
|
a check_row_ts(rs,re)
|
||||||
|
1 CURRENT ROW
|
||||||
|
set sql_mode=default;
|
||||||
connection master;
|
connection master;
|
||||||
drop tables t1, t2, t3;
|
drop tables t1, t2, t3;
|
||||||
include/rpl_end.inc
|
include/rpl_end.inc
|
||||||
|
@@ -108,6 +108,8 @@ show create table t1;
|
|||||||
insert into t1(x, row_start, row_end) values (3, '1980-01-01 00:00:00', '1980-01-01 00:00:01');
|
insert into t1(x, row_start, row_end) values (3, '1980-01-01 00:00:00', '1980-01-01 00:00:01');
|
||||||
insert into t2(y, row_start, row_end) values (4, '1980-01-01 00:00:00', '1980-01-01 00:00:01');
|
insert into t2(y, row_start, row_end) values (4, '1980-01-01 00:00:00', '1980-01-01 00:00:01');
|
||||||
insert into t3 values (5, '1980-01-01 00:00:00', '1980-01-01 00:00:01');
|
insert into t3 values (5, '1980-01-01 00:00:00', '1980-01-01 00:00:01');
|
||||||
|
--error ER_WRONG_VALUE
|
||||||
|
insert into t3 values (5, '1980-01-02 00:00:00', '1980-01-01 00:00:01');
|
||||||
|
|
||||||
select x, row_start, row_end from t1 for system_time all;
|
select x, row_start, row_end from t1 for system_time all;
|
||||||
select y, row_start, row_end from t2 for system_time all;
|
select y, row_start, row_end from t2 for system_time all;
|
||||||
@@ -215,22 +217,25 @@ select row_start = '1980-01-01 00:00:00', row_end = '1980-01-01 00:00:01' from t
|
|||||||
--let $restart_parameters= --secure-timestamp=YES
|
--let $restart_parameters= --secure-timestamp=YES
|
||||||
--source include/restart_mysqld.inc
|
--source include/restart_mysqld.inc
|
||||||
set @@system_versioning_insert_history= 1;
|
set @@system_versioning_insert_history= 1;
|
||||||
--error ER_BAD_FIELD_ERROR
|
--error ER_OPTION_PREVENTS_STATEMENT
|
||||||
insert into t1(x, row_start, row_end) values (8, '1980-01-01 00:00:00', '1980-01-01 00:00:01');
|
insert into t1(x, row_start, row_end) values (8, '1980-01-01 00:00:00', '1980-01-01 00:00:01');
|
||||||
--let $restart_parameters= --secure-timestamp=REPLICATION
|
--let $restart_parameters= --secure-timestamp=REPLICATION
|
||||||
--source include/restart_mysqld.inc
|
--source include/restart_mysqld.inc
|
||||||
|
create user nobody;
|
||||||
|
grant all privileges on test.* to nobody;
|
||||||
|
change_user nobody;
|
||||||
set @@system_versioning_insert_history= 1;
|
set @@system_versioning_insert_history= 1;
|
||||||
--error ER_BAD_FIELD_ERROR
|
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
|
||||||
insert into t1(x, row_start, row_end) values (9, '1980-01-01 00:00:00', '1980-01-01 00:00:01');
|
insert into test.t1(x, row_start, row_end) values (9, '1980-01-01 00:00:00', '1980-01-01 00:00:01');
|
||||||
|
change_user root;
|
||||||
--let $restart_parameters= --secure-timestamp=SUPER
|
--let $restart_parameters= --secure-timestamp=SUPER
|
||||||
--source include/restart_mysqld.inc
|
--source include/restart_mysqld.inc
|
||||||
set @@system_versioning_insert_history= 1;
|
set @@system_versioning_insert_history= 1;
|
||||||
insert into t1(x, row_start, row_end) values (10, '1980-01-01 00:00:00', '1980-01-01 00:00:01');
|
insert into test.t1(x, row_start, row_end) values (10, '1980-01-01 00:00:00', '1980-01-01 00:00:01');
|
||||||
create user nobody;
|
|
||||||
change_user nobody;
|
change_user nobody;
|
||||||
use test;
|
set @@system_versioning_insert_history= 1;
|
||||||
--error ER_BAD_FIELD_ERROR
|
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
|
||||||
insert into t1(x, row_start, row_end) values (7, '1980-01-01 00:00:00', '1980-01-01 00:00:01');
|
insert into test.t1(x, row_start, row_end) values (7, '1980-01-01 00:00:00', '1980-01-01 00:00:01');
|
||||||
change_user root;
|
change_user root;
|
||||||
use test;
|
use test;
|
||||||
--let $restart_parameters= --secure-timestamp=NO
|
--let $restart_parameters= --secure-timestamp=NO
|
||||||
|
@@ -2494,8 +2494,8 @@ lock tables t write;
|
|||||||
--error ER_UNKNOWN_PARTITION
|
--error ER_UNKNOWN_PARTITION
|
||||||
delete from t partition (px);
|
delete from t partition (px);
|
||||||
unlock tables;
|
unlock tables;
|
||||||
# cleanup
|
|
||||||
drop table t;
|
drop table t;
|
||||||
|
set timestamp= default;
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # MDEV-28978 Assertion failure in THD::binlog_query or unexpected
|
--echo # MDEV-28978 Assertion failure in THD::binlog_query or unexpected
|
||||||
@@ -2508,6 +2508,23 @@ update t set a = 2 limit 0;
|
|||||||
# cleanup
|
# cleanup
|
||||||
drop table t;
|
drop table t;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-16546 System versioning setting to allow history modification
|
||||||
|
--echo #
|
||||||
|
create table t1 (a varchar(100)) with system versioning
|
||||||
|
partition by system_time interval 1 day
|
||||||
|
starts '2021-09-30 00:00:00' partitions 3;
|
||||||
|
set system_versioning_insert_history=1;
|
||||||
|
insert into t1 (a,row_start,row_end) values
|
||||||
|
('p0', '2021-09-30', '2021-09-30 10:00:00'),
|
||||||
|
('p1', '2021-09-30', '2021-10-01 10:00:00'),
|
||||||
|
('overflows, so also p1','2021-09-30', '2021-10-10 10:00:00'),
|
||||||
|
('pn, current', '2021-09-30', '2038-01-19 03:14:07.999999');
|
||||||
|
select table_name,partition_name,partition_ordinal_position,partition_method,partition_description,table_rows
|
||||||
|
from information_schema.partitions where table_schema='test';
|
||||||
|
drop table t1;
|
||||||
|
set system_versioning_insert_history=0;
|
||||||
|
|
||||||
--disable_prepare_warnings
|
--disable_prepare_warnings
|
||||||
set global innodb_stats_persistent= @save_persistent;
|
set global innodb_stats_persistent= @save_persistent;
|
||||||
--source suite/versioning/common_finish.inc
|
--source suite/versioning/common_finish.inc
|
||||||
|
@@ -336,6 +336,19 @@ select x, check_row_ts(row_start, row_end) from t3 for system_time all order by
|
|||||||
select row_start = '1980-01-01 00:00:00', row_end = '1980-01-01 00:00:01' from t3 for system_time all where x = 3;
|
select row_start = '1980-01-01 00:00:00', row_end = '1980-01-01 00:00:01' from t3 for system_time all where x = 3;
|
||||||
--remove_file $DATAFILE
|
--remove_file $DATAFILE
|
||||||
|
|
||||||
|
--echo # why a slave cannot have system_versioning_insert_history always on
|
||||||
|
connection master;
|
||||||
|
set @@system_versioning_insert_history= 0;
|
||||||
|
set sql_mode='';
|
||||||
|
create or replace table t1 (a int,
|
||||||
|
rs timestamp(6) as row start, re timestamp(6) as row end,
|
||||||
|
period for system_time (rs,re)) with system versioning;
|
||||||
|
insert t1 values (1, '2000-01-01 02:03:04', '2001-01-01 02:03.04');
|
||||||
|
select a,check_row_ts(rs,re) from t1 for system_time all;
|
||||||
|
sync_slave_with_master;
|
||||||
|
select a,check_row_ts(rs,re) from t1 for system_time all;
|
||||||
|
set sql_mode=default;
|
||||||
|
|
||||||
connection master;
|
connection master;
|
||||||
drop tables t1, t2, t3;
|
drop tables t1, t2, t3;
|
||||||
|
|
||||||
|
@@ -7573,30 +7573,6 @@ int handler::ha_write_row(const uchar *buf)
|
|||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (table->versioned() && !table->vers_write)
|
|
||||||
{
|
|
||||||
Field *row_start= table->vers_start_field();
|
|
||||||
Field *row_end= table->vers_end_field();
|
|
||||||
MYSQL_TIME ltime;
|
|
||||||
|
|
||||||
bitmap_set_bit(table->read_set, row_start->field_index);
|
|
||||||
bitmap_set_bit(table->read_set, row_end->field_index);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Inserting the history row directly, check ROW_START <= ROW_END and
|
|
||||||
ROW_START is non-zero.
|
|
||||||
*/
|
|
||||||
if ((row_start->cmp(row_start->ptr, row_end->ptr) >= 0) ||
|
|
||||||
row_start->get_date(<ime, Datetime::Options(
|
|
||||||
TIME_NO_ZERO_DATE, time_round_mode_t(time_round_mode_t::FRAC_NONE))))
|
|
||||||
{
|
|
||||||
String val;
|
|
||||||
row_start->val_str(&val);
|
|
||||||
my_error(ER_WRONG_VALUE, MYF(0), row_start->field_name.str, val.ptr());
|
|
||||||
DBUG_RETURN(HA_ERR_GENERIC);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MYSQL_INSERT_ROW_START(table_share->db.str, table_share->table_name.str);
|
MYSQL_INSERT_ROW_START(table_share->db.str, table_share->table_name.str);
|
||||||
mark_trx_read_write();
|
mark_trx_read_write();
|
||||||
increment_statistics(&SSV::ha_write_count);
|
increment_statistics(&SSV::ha_write_count);
|
||||||
|
@@ -6127,13 +6127,6 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
|
|||||||
else if (!from_field)
|
else if (!from_field)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (thd->column_usage == MARK_COLUMNS_WRITE &&
|
|
||||||
from_field != view_ref_found &&
|
|
||||||
thd->vers_insert_history(from_field))
|
|
||||||
{
|
|
||||||
DBUG_ASSERT(from_field->table->versioned());
|
|
||||||
from_field->table->vers_write= false;
|
|
||||||
}
|
|
||||||
table_list= (cached_table ? cached_table :
|
table_list= (cached_table ? cached_table :
|
||||||
from_field != view_ref_found ?
|
from_field != view_ref_found ?
|
||||||
from_field->table->pos_in_table_list : 0);
|
from_field->table->pos_in_table_list : 0);
|
||||||
|
@@ -309,6 +309,7 @@ extern uint default_password_lifetime;
|
|||||||
extern my_bool disconnect_on_expired_password;
|
extern my_bool disconnect_on_expired_password;
|
||||||
|
|
||||||
enum secure_timestamp { SECTIME_NO, SECTIME_SUPER, SECTIME_REPL, SECTIME_YES };
|
enum secure_timestamp { SECTIME_NO, SECTIME_SUPER, SECTIME_REPL, SECTIME_YES };
|
||||||
|
bool is_set_timestamp_forbidden(THD *thd);
|
||||||
|
|
||||||
#ifdef HAVE_MMAP
|
#ifdef HAVE_MMAP
|
||||||
extern PSI_mutex_key key_PAGE_lock, key_LOCK_sync, key_LOCK_active,
|
extern PSI_mutex_key key_PAGE_lock, key_LOCK_sync, key_LOCK_active,
|
||||||
|
@@ -6309,11 +6309,17 @@ find_field_in_table(THD *thd, TABLE *table, const char *name, size_t length,
|
|||||||
!DBUG_IF("test_completely_invisible"))
|
!DBUG_IF("test_completely_invisible"))
|
||||||
DBUG_RETURN((Field*)0);
|
DBUG_RETURN((Field*)0);
|
||||||
|
|
||||||
if (field->invisible == INVISIBLE_SYSTEM &&
|
if (thd->column_usage != MARK_COLUMNS_READ &&
|
||||||
thd->column_usage != MARK_COLUMNS_READ &&
|
thd->column_usage != COLUMNS_READ)
|
||||||
thd->column_usage != COLUMNS_READ &&
|
{
|
||||||
!thd->vers_insert_history(field))
|
if (thd->vers_insert_history(field))
|
||||||
DBUG_RETURN((Field*)0);
|
{
|
||||||
|
DBUG_ASSERT(table->versioned());
|
||||||
|
table->vers_write= false;
|
||||||
|
}
|
||||||
|
else if (field->invisible == INVISIBLE_SYSTEM)
|
||||||
|
DBUG_RETURN((Field*)0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -8832,6 +8838,37 @@ err_no_arena:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool vers_update_or_validate_fields(TABLE *table)
|
||||||
|
{
|
||||||
|
if (!table->versioned())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (table->vers_write)
|
||||||
|
{
|
||||||
|
table->vers_update_fields();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Field *row_start= table->vers_start_field();
|
||||||
|
Field *row_end= table->vers_end_field();
|
||||||
|
MYSQL_TIME ltime;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Inserting the history row directly, check ROW_START < ROW_END and
|
||||||
|
ROW_START is non-zero.
|
||||||
|
*/
|
||||||
|
if ((row_start->cmp(row_start->ptr, row_end->ptr) < 0) &&
|
||||||
|
!row_start->get_date(<ime, Datetime::Options(
|
||||||
|
TIME_NO_ZERO_DATE, time_round_mode_t(time_round_mode_t::FRAC_NONE))))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
StringBuffer<MAX_DATETIME_FULL_WIDTH+1> val;
|
||||||
|
row_start->val_str(&val);
|
||||||
|
my_error(ER_WRONG_VALUE, MYF(0), row_start->field_name.str, val.c_ptr());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
** Fill a record with data (for INSERT or UPDATE)
|
** Fill a record with data (for INSERT or UPDATE)
|
||||||
** Returns : 1 if some field has wrong type
|
** Returns : 1 if some field has wrong type
|
||||||
@@ -8897,7 +8934,7 @@ fill_record(THD *thd, TABLE *table_arg, List<Item> &fields, List<Item> &values,
|
|||||||
rfield->field_index == table->next_number_field->field_index)
|
rfield->field_index == table->next_number_field->field_index)
|
||||||
table->auto_increment_field_not_null= TRUE;
|
table->auto_increment_field_not_null= TRUE;
|
||||||
const bool skip_sys_field= rfield->vers_sys_field() &&
|
const bool skip_sys_field= rfield->vers_sys_field() &&
|
||||||
(update || !thd->vers_insert_history(rfield));
|
(update || table->vers_write);
|
||||||
if ((rfield->vcol_info || skip_sys_field) &&
|
if ((rfield->vcol_info || skip_sys_field) &&
|
||||||
!value->vcol_assignment_allowed_value() &&
|
!value->vcol_assignment_allowed_value() &&
|
||||||
table->s->table_category != TABLE_CATEGORY_TEMPORARY)
|
table->s->table_category != TABLE_CATEGORY_TEMPORARY)
|
||||||
@@ -8953,8 +8990,9 @@ fill_record(THD *thd, TABLE *table_arg, List<Item> &fields, List<Item> &values,
|
|||||||
table_arg->update_default_fields(ignore_errors))
|
table_arg->update_default_fields(ignore_errors))
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
if (table_arg->versioned() && !only_unvers_fields)
|
if (!only_unvers_fields && vers_update_or_validate_fields(table_arg))
|
||||||
table_arg->vers_update_fields();
|
goto err;
|
||||||
|
|
||||||
/* Update virtual fields */
|
/* Update virtual fields */
|
||||||
if (table_arg->vfield &&
|
if (table_arg->vfield &&
|
||||||
table_arg->update_virtual_fields(table_arg->file, VCOL_UPDATE_FOR_WRITE))
|
table_arg->update_virtual_fields(table_arg->file, VCOL_UPDATE_FOR_WRITE))
|
||||||
@@ -9178,14 +9216,12 @@ fill_record(THD *thd, TABLE *table, Field **ptr, List<Item> &values,
|
|||||||
/* Ensure the end of the list of values is not reached */
|
/* Ensure the end of the list of values is not reached */
|
||||||
DBUG_ASSERT(value);
|
DBUG_ASSERT(value);
|
||||||
|
|
||||||
bool vers_sys_field= table->versioned() && field->vers_sys_field();
|
const bool skip_sys_field= field->vers_sys_field() &&
|
||||||
|
table->vers_write;
|
||||||
|
|
||||||
if (field->field_index == autoinc_index)
|
if (field->field_index == autoinc_index)
|
||||||
table->auto_increment_field_not_null= TRUE;
|
table->auto_increment_field_not_null= TRUE;
|
||||||
if ((unlikely(field->vcol_info) ||
|
if ((unlikely(field->vcol_info) || (skip_sys_field && !ignore_errors)) &&
|
||||||
(vers_sys_field &&
|
|
||||||
!ignore_errors &&
|
|
||||||
!thd->vers_insert_history(field))) &&
|
|
||||||
!value->vcol_assignment_allowed_value() &&
|
!value->vcol_assignment_allowed_value() &&
|
||||||
table->s->table_category != TABLE_CATEGORY_TEMPORARY)
|
table->s->table_category != TABLE_CATEGORY_TEMPORARY)
|
||||||
{
|
{
|
||||||
@@ -9193,7 +9229,7 @@ fill_record(THD *thd, TABLE *table, Field **ptr, List<Item> &values,
|
|||||||
ER_WARNING_NON_DEFAULT_VALUE_FOR_GENERATED_COLUMN,
|
ER_WARNING_NON_DEFAULT_VALUE_FOR_GENERATED_COLUMN,
|
||||||
ER_THD(thd, ER_WARNING_NON_DEFAULT_VALUE_FOR_GENERATED_COLUMN),
|
ER_THD(thd, ER_WARNING_NON_DEFAULT_VALUE_FOR_GENERATED_COLUMN),
|
||||||
field->field_name.str, table->s->table_name.str);
|
field->field_name.str, table->s->table_name.str);
|
||||||
if (vers_sys_field)
|
if (skip_sys_field)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -9210,8 +9246,8 @@ fill_record(THD *thd, TABLE *table, Field **ptr, List<Item> &values,
|
|||||||
thd->abort_on_warning= FALSE;
|
thd->abort_on_warning= FALSE;
|
||||||
if (table->default_field && table->update_default_fields(ignore_errors))
|
if (table->default_field && table->update_default_fields(ignore_errors))
|
||||||
goto err;
|
goto err;
|
||||||
if (table->versioned())
|
if (vers_update_or_validate_fields(table))
|
||||||
table->vers_update_fields();
|
goto err;
|
||||||
if (table->vfield &&
|
if (table->vfield &&
|
||||||
table->update_virtual_fields(table->file, VCOL_UPDATE_FOR_WRITE))
|
table->update_virtual_fields(table->file, VCOL_UPDATE_FOR_WRITE))
|
||||||
goto err;
|
goto err;
|
||||||
|
@@ -5575,7 +5575,7 @@ public:
|
|||||||
lex= backup_lex;
|
lex= backup_lex;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool vers_insert_history(const Field *field) const
|
bool vers_insert_history(const Field *field)
|
||||||
{
|
{
|
||||||
if (!field->vers_sys_field())
|
if (!field->vers_sys_field())
|
||||||
return false;
|
return false;
|
||||||
@@ -5590,22 +5590,7 @@ public:
|
|||||||
lex->sql_command != SQLCOM_REPLACE_SELECT &&
|
lex->sql_command != SQLCOM_REPLACE_SELECT &&
|
||||||
lex->sql_command != SQLCOM_LOAD)
|
lex->sql_command != SQLCOM_LOAD)
|
||||||
return false;
|
return false;
|
||||||
switch (opt_secure_timestamp)
|
return !is_set_timestamp_forbidden(this);
|
||||||
{
|
|
||||||
case SECTIME_NO:
|
|
||||||
return true;
|
|
||||||
case SECTIME_SUPER:
|
|
||||||
if (security_ctx->master_access & SUPER_ACL)
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
case SECTIME_REPL:
|
|
||||||
if (slave_thread)
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
case SECTIME_YES:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -4780,7 +4780,8 @@ static Sys_var_harows Sys_select_limit(
|
|||||||
VALID_RANGE(0, HA_POS_ERROR), DEFAULT(HA_POS_ERROR), BLOCK_SIZE(1));
|
VALID_RANGE(0, HA_POS_ERROR), DEFAULT(HA_POS_ERROR), BLOCK_SIZE(1));
|
||||||
|
|
||||||
static const char *secure_timestamp_levels[]= {"NO", "SUPER", "REPLICATION", "YES", 0};
|
static const char *secure_timestamp_levels[]= {"NO", "SUPER", "REPLICATION", "YES", 0};
|
||||||
bool Sys_var_timestamp::on_check_access_session(THD *thd) const
|
|
||||||
|
bool is_set_timestamp_forbidden(THD *thd)
|
||||||
{
|
{
|
||||||
switch (opt_secure_timestamp) {
|
switch (opt_secure_timestamp) {
|
||||||
case SECTIME_NO:
|
case SECTIME_NO:
|
||||||
@@ -4798,6 +4799,11 @@ bool Sys_var_timestamp::on_check_access_session(THD *thd) const
|
|||||||
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), buf);
|
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), buf);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Sys_var_timestamp::on_check_access_session(THD *thd) const
|
||||||
|
{
|
||||||
|
return is_set_timestamp_forbidden(thd);
|
||||||
|
}
|
||||||
static Sys_var_timestamp Sys_timestamp(
|
static Sys_var_timestamp Sys_timestamp(
|
||||||
"timestamp", "Set the time for this client",
|
"timestamp", "Set the time for this client",
|
||||||
sys_var::ONLY_SESSION, NO_CMD_LINE,
|
sys_var::ONLY_SESSION, NO_CMD_LINE,
|
||||||
@@ -6957,7 +6963,8 @@ static Sys_var_ulonglong Sys_max_rowid_filter_size(
|
|||||||
|
|
||||||
static Sys_var_bit Sys_system_versioning_insert_history(
|
static Sys_var_bit Sys_system_versioning_insert_history(
|
||||||
"system_versioning_insert_history",
|
"system_versioning_insert_history",
|
||||||
"Allows direct inserts into ROW_START and ROW_END columns",
|
"Allows direct inserts into ROW_START and ROW_END columns if "
|
||||||
|
"secure_timestamp allows changing @@timestamp",
|
||||||
SESSION_VAR(option_bits), CMD_LINE(OPT_ARG),
|
SESSION_VAR(option_bits), CMD_LINE(OPT_ARG),
|
||||||
OPTION_INSERT_HISTORY, DEFAULT(FALSE),
|
OPTION_INSERT_HISTORY, DEFAULT(FALSE),
|
||||||
NO_MUTEX_GUARD, IN_BINLOG);
|
NO_MUTEX_GUARD, IN_BINLOG);
|
||||||
|
@@ -9155,9 +9155,6 @@ bool TABLE::check_period_overlaps(const KEY &key,
|
|||||||
|
|
||||||
void TABLE::vers_update_fields()
|
void TABLE::vers_update_fields()
|
||||||
{
|
{
|
||||||
if (!vers_write)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (versioned(VERS_TIMESTAMP))
|
if (versioned(VERS_TIMESTAMP))
|
||||||
{
|
{
|
||||||
if (vers_start_field()->store_timestamp(in_use->query_start(),
|
if (vers_start_field()->store_timestamp(in_use->query_start(),
|
||||||
|
Reference in New Issue
Block a user