dead code - related to vtmd
(will be added back when it'll be used)
This commit is contained in:
parent
09e6280147
commit
35678c9572
@ -121,7 +121,6 @@ SET(SQL_EMBEDDED_SOURCES emb_qcache.cc libmysqld.c lib_sql.cc
|
||||
../sql/sql_tvc.cc ../sql/sql_tvc.h
|
||||
../sql/opt_split.cc
|
||||
../sql/item_vers.cc
|
||||
../sql/vtmd.cc
|
||||
${GEN_SOURCES}
|
||||
${MYSYS_LIBWRAP_SOURCE}
|
||||
)
|
||||
|
@ -9,7 +9,4 @@
|
||||
# Do not use any TAB characters for whitespace.
|
||||
#
|
||||
##############################################################################
|
||||
ddl : DDL Survival WIP
|
||||
vtmd : DDL Survival WIP
|
||||
vtmd_show : DDL Survival WIP
|
||||
cte: MDEV-14820
|
||||
|
@ -1,211 +0,0 @@
|
||||
set @@session.time_zone='+00:00';
|
||||
select ifnull(max(transaction_id), 0) into @start_trx_id from mysql.transaction_registry;
|
||||
set @test_start=now(6);
|
||||
create procedure if not exists verify_vtq()
|
||||
begin
|
||||
set @i= 0;
|
||||
select
|
||||
@i:= @i + 1 as No,
|
||||
transaction_id > 0 as A,
|
||||
commit_id > transaction_id as B,
|
||||
begin_timestamp > @test_start as C,
|
||||
commit_timestamp >= begin_timestamp as D
|
||||
from mysql.transaction_registry
|
||||
where transaction_id > @start_trx_id;
|
||||
select ifnull(max(transaction_id), 0)
|
||||
into @start_trx_id
|
||||
from mysql.transaction_registry;
|
||||
end~~
|
||||
create function if not exists default_engine()
|
||||
returns varchar(255)
|
||||
deterministic
|
||||
begin
|
||||
declare e varchar(255);
|
||||
select lower(engine) from information_schema.engines where support='DEFAULT' into e;
|
||||
return e;
|
||||
end~~
|
||||
create function if not exists sys_datatype()
|
||||
returns varchar(255)
|
||||
deterministic
|
||||
begin
|
||||
if default_engine() = 'innodb' then
|
||||
return 'bigint unsigned';
|
||||
elseif default_engine() = 'myisam' then
|
||||
return 'timestamp(6)';
|
||||
end if;
|
||||
return NULL;
|
||||
end~~
|
||||
create function if not exists sys_commit_ts(sys_field varchar(255))
|
||||
returns varchar(255)
|
||||
deterministic
|
||||
begin
|
||||
if default_engine() = 'innodb' then
|
||||
return concat('vtq_commit_ts(', sys_field, ')');
|
||||
elseif default_engine() = 'myisam' then
|
||||
return sys_field;
|
||||
end if;
|
||||
return NULL;
|
||||
end~~
|
||||
create procedure if not exists innodb_verify_vtq(recs int)
|
||||
begin
|
||||
declare i int default 1;
|
||||
if default_engine() = 'innodb' then
|
||||
call verify_vtq;
|
||||
elseif default_engine() = 'myisam' then
|
||||
create temporary table tmp (No int, A bool, B bool, C bool, D bool);
|
||||
while i <= recs do
|
||||
insert into tmp values (i, 1, 1, 1, 1);
|
||||
set i= i + 1;
|
||||
end while;
|
||||
select * from tmp;
|
||||
drop table tmp;
|
||||
end if;
|
||||
end~~
|
||||
create procedure concat_exec2(a varchar(255), b varchar(255))
|
||||
begin
|
||||
prepare stmt from concat(a, b);
|
||||
execute stmt;
|
||||
deallocate prepare stmt;
|
||||
end~~
|
||||
create procedure concat_exec3(a varchar(255), b varchar(255), c varchar(255))
|
||||
begin
|
||||
prepare stmt from concat(a, b, c);
|
||||
execute stmt;
|
||||
deallocate prepare stmt;
|
||||
end~~
|
||||
create function get_archive_table_name()
|
||||
returns varchar(255)
|
||||
begin
|
||||
return (select archive_name from t_vtmd for system_time all where archive_name is not NULL
|
||||
order by start desc limit 1);
|
||||
end~~
|
||||
create procedure drop_last_archive()
|
||||
begin
|
||||
call concat_exec2('drop table ', get_archive_table_name());
|
||||
end~~
|
||||
set versioning_alter_history= survive;
|
||||
create or replace table t (a int) with system versioning;
|
||||
insert into t values (1);
|
||||
update t set a=2 where a=1;
|
||||
select sys_trx_start from t where a=2 into @tm;
|
||||
alter table t add column b int;
|
||||
select * from t;
|
||||
a b
|
||||
2 NULL
|
||||
call concat_exec3('select * from ', get_archive_table_name(), ' for system_time all');
|
||||
a
|
||||
2
|
||||
1
|
||||
call concat_exec3('select @tm=sys_trx_start from ', get_archive_table_name(), ' for system_time all where a=2');
|
||||
@tm=sys_trx_start
|
||||
1
|
||||
select @tm<sys_trx_start from t where a=2;
|
||||
@tm<sys_trx_start
|
||||
1
|
||||
select sys_trx_start from t where a=2 into @tm;
|
||||
call concat_exec3('select @tm=sys_trx_end from ', get_archive_table_name(), ' for system_time all where a=2');
|
||||
@tm=sys_trx_end
|
||||
1
|
||||
call drop_last_archive();
|
||||
set versioning_alter_history= keep;
|
||||
drop table t_vtmd;
|
||||
drop table t;
|
||||
set versioning_alter_history= survive;
|
||||
create or replace table t (a int) with system versioning;
|
||||
insert into t values (1);
|
||||
update t set a=2 where a=1;
|
||||
select sys_trx_start from t where a=2 into @tm;
|
||||
alter table t add column b int;
|
||||
select * from t;
|
||||
a b
|
||||
2 NULL
|
||||
call concat_exec3('select * from ', get_archive_table_name(), ' for system_time all');
|
||||
a
|
||||
2
|
||||
1
|
||||
call concat_exec3('select @tm=sys_trx_start from ', get_archive_table_name(), ' for system_time all where a=2');
|
||||
@tm=sys_trx_start
|
||||
1
|
||||
select @tm<sys_trx_start from t where a=2;
|
||||
@tm<sys_trx_start
|
||||
1
|
||||
select sys_trx_start from t where a=2 into @tm;
|
||||
call concat_exec3('select @tm=sys_trx_end from ', get_archive_table_name(), ' for system_time all where a=2');
|
||||
@tm=sys_trx_end
|
||||
1
|
||||
call drop_last_archive();
|
||||
set versioning_alter_history= keep;
|
||||
drop table t_vtmd;
|
||||
drop table t;
|
||||
set versioning_alter_history= survive;
|
||||
create or replace table t (a int) with system versioning engine innodb;
|
||||
insert into t values (1);
|
||||
update t set a=2 where a=1;
|
||||
select sys_trx_start from t where a=2 into @tm;
|
||||
alter table t add column b int;
|
||||
select * from t;
|
||||
a b
|
||||
2 NULL
|
||||
call concat_exec3('select * from ', get_archive_table_name(), ' for system_time all');
|
||||
a
|
||||
2
|
||||
1
|
||||
call concat_exec3('select @tm=sys_trx_start from ', get_archive_table_name(), ' for system_time all where a=2');
|
||||
@tm=sys_trx_start
|
||||
1
|
||||
select @tm<sys_trx_start from t where a=2;
|
||||
@tm<sys_trx_start
|
||||
1
|
||||
select sys_trx_start from t where a=2 into @tm;
|
||||
call concat_exec3('select @tm=sys_trx_end from ', get_archive_table_name(), ' for system_time all where a=2');
|
||||
@tm=sys_trx_end
|
||||
1
|
||||
call drop_last_archive();
|
||||
set versioning_alter_history= keep;
|
||||
drop table t_vtmd;
|
||||
drop table t;
|
||||
set versioning_alter_history= survive;
|
||||
create or replace table t (a int) with system versioning engine innodb;
|
||||
insert into t values (1);
|
||||
update t set a=2 where a=1;
|
||||
alter table t add column b int, algorithm=inplace;
|
||||
set versioning_alter_history = keep;
|
||||
drop function get_archive_table_name;
|
||||
drop procedure drop_last_archive;
|
||||
select * from mysql.vtmd_template;
|
||||
start end name archive_name col_renames
|
||||
show create table mysql.vtmd_template;
|
||||
Table Create Table
|
||||
vtmd_template CREATE TABLE `vtmd_template` (
|
||||
`start` bigint(20) unsigned GENERATED ALWAYS AS ROW START COMMENT 'TRX_ID of table lifetime start',
|
||||
`end` bigint(20) unsigned GENERATED ALWAYS AS ROW END NOT NULL COMMENT 'TRX_ID of table lifetime end',
|
||||
`name` varchar(64) COLLATE utf8_bin NOT NULL COMMENT 'Table name during current lifetime period',
|
||||
`archive_name` varchar(64) COLLATE utf8_bin DEFAULT NULL COMMENT 'Name of archive table',
|
||||
`col_renames` blob DEFAULT NULL COMMENT 'Column name mappings from previous lifetime',
|
||||
PRIMARY KEY (`end`),
|
||||
KEY `archive_name` (`archive_name`),
|
||||
PERIOD FOR SYSTEM_TIME (`start`, `end`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin STATS_PERSISTENT=0 WITH SYSTEM VERSIONING
|
||||
call verify_vtq;
|
||||
No A B C D
|
||||
1 1 1 1 1
|
||||
2 1 1 1 1
|
||||
3 1 1 1 1
|
||||
4 1 1 1 1
|
||||
5 1 1 1 1
|
||||
6 1 1 1 1
|
||||
7 1 1 1 1
|
||||
8 1 1 1 1
|
||||
9 1 1 1 1
|
||||
10 1 1 1 1
|
||||
11 1 1 1 1
|
||||
12 1 1 1 1
|
||||
drop table t;
|
||||
drop table t_vtmd;
|
||||
drop procedure verify_vtq;
|
||||
drop procedure innodb_verify_vtq;
|
||||
drop function default_engine;
|
||||
drop function sys_commit_ts;
|
||||
drop function sys_datatype;
|
||||
drop procedure concat_exec2;
|
||||
drop procedure concat_exec3;
|
@ -1,365 +0,0 @@
|
||||
create or replace procedure drop_archives (in vtmd_name varchar(64))
|
||||
begin
|
||||
declare archive_name varchar(64);
|
||||
declare cur_done bool default false;
|
||||
declare cur cursor for
|
||||
select cur_tmp.archive_name from cur_tmp;
|
||||
declare continue handler for not found set cur_done = true;
|
||||
set @tmp= concat('
|
||||
create or replace temporary table
|
||||
cur_tmp as
|
||||
select vtmd.archive_name from ', vtmd_name, '
|
||||
for system_time all as vtmd
|
||||
where vtmd.archive_name is not null
|
||||
group by vtmd.archive_name');
|
||||
prepare stmt from @tmp; execute stmt; drop prepare stmt;
|
||||
open cur;
|
||||
fetch_loop: loop
|
||||
fetch cur into archive_name;
|
||||
if cur_done then
|
||||
leave fetch_loop;
|
||||
end if;
|
||||
set @tmp= concat('drop table ', archive_name);
|
||||
prepare stmt from @tmp; execute stmt; drop prepare stmt;
|
||||
end loop;
|
||||
drop table cur_tmp;
|
||||
end~~
|
||||
create or replace procedure check_vtmd (in vtmd_name varchar(64))
|
||||
begin
|
||||
set @tmp= concat('
|
||||
create or replace temporary table
|
||||
tmp_vtmd with system versioning as
|
||||
select * from ', vtmd_name, '
|
||||
for system_time all as vtmd');
|
||||
prepare stmt from @tmp; execute stmt; drop prepare stmt;
|
||||
set @inf= 0xFFFFFFFFFFFFFFFF + 0;
|
||||
set @start= null;
|
||||
select start from tmp_vtmd for system_time all order by start limit 1 into @start;
|
||||
select @start > 0 and @start < @inf;
|
||||
select
|
||||
start >= @start as A_start,
|
||||
(@start:= end) and end = @inf as B_end,
|
||||
name,
|
||||
substr(archive_name, 1, instr(archive_name, '_')) as C_archive_name
|
||||
from tmp_vtmd for system_time all;
|
||||
drop table tmp_vtmd;
|
||||
end~~
|
||||
create or replace procedure show_tables()
|
||||
begin
|
||||
show tables;
|
||||
select table_name, table_schema from information_schema.tables
|
||||
where table_schema not in ('mysql', 'performance_schema', 'information_schema', 'mtr')
|
||||
order by table_name;
|
||||
end~~
|
||||
set versioning_alter_history= keep;
|
||||
create table t0 (z int) with system versioning;
|
||||
show tables;
|
||||
Tables_in_test
|
||||
t0
|
||||
set versioning_alter_history= survive;
|
||||
create or replace table t0 (y int) with system versioning;
|
||||
show tables;
|
||||
Tables_in_test
|
||||
t0
|
||||
t0_vtmd
|
||||
show create table t0_vtmd;
|
||||
Table Create Table
|
||||
t0_vtmd CREATE TABLE `t0_vtmd` (
|
||||
`start` bigint(20) unsigned GENERATED ALWAYS AS ROW START COMMENT 'TRX_ID of table lifetime start',
|
||||
`end` bigint(20) unsigned GENERATED ALWAYS AS ROW END NOT NULL COMMENT 'TRX_ID of table lifetime end',
|
||||
`name` varchar(64) COLLATE utf8_bin NOT NULL COMMENT 'Table name during current lifetime period',
|
||||
`archive_name` varchar(64) COLLATE utf8_bin DEFAULT NULL COMMENT 'Name of archive table',
|
||||
`col_renames` blob DEFAULT NULL COMMENT 'Column name mappings from previous lifetime',
|
||||
PRIMARY KEY (`end`),
|
||||
KEY `archive_name` (`archive_name`),
|
||||
PERIOD FOR SYSTEM_TIME (`start`, `end`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin STATS_PERSISTENT=0 WITH SYSTEM VERSIONING
|
||||
call check_vtmd('t0_vtmd');
|
||||
@start > 0 and @start < @inf
|
||||
1
|
||||
A_start B_end name C_archive_name
|
||||
1 1 t0 NULL
|
||||
set versioning_alter_history= keep;
|
||||
drop table t0;
|
||||
set versioning_alter_history= survive;
|
||||
create table t0 (x int) with system versioning;
|
||||
ERROR HY000: VTMD error: `test.t0_vtmd` exists and not empty!
|
||||
drop table t0_vtmd;
|
||||
create table t0 (y int) with system versioning;
|
||||
create or replace table t0 (x int) with system versioning;
|
||||
insert into t0 values (1);
|
||||
set @t0= now(6);
|
||||
alter table t0 add column (y int);
|
||||
select * from t0 for system_time as of @t0;
|
||||
x
|
||||
1
|
||||
select * from t0;
|
||||
x y
|
||||
1 NULL
|
||||
call check_vtmd('t0_vtmd');
|
||||
@start > 0 and @start < @inf
|
||||
1
|
||||
A_start B_end name C_archive_name
|
||||
1 0 t0 t0_
|
||||
1 0 t0 t0_
|
||||
1 1 t0 NULL
|
||||
call drop_archives('t0_vtmd');
|
||||
drop table t0_vtmd;
|
||||
alter table t0 drop column y;
|
||||
call check_vtmd('t0_vtmd');
|
||||
@start > 0 and @start < @inf
|
||||
1
|
||||
A_start B_end name C_archive_name
|
||||
1 1 t0 t0_
|
||||
call drop_archives('t0_vtmd');
|
||||
set versioning_alter_history= keep;
|
||||
drop tables t0, t0_vtmd;
|
||||
set versioning_alter_history= survive;
|
||||
set versioning_alter_history= keep;
|
||||
create or replace table x0 (x int) with system versioning;
|
||||
set versioning_alter_history= survive;
|
||||
rename table x0 to d0;
|
||||
show tables;
|
||||
Tables_in_test
|
||||
d0
|
||||
set versioning_alter_history= keep;
|
||||
drop table d0;
|
||||
set versioning_alter_history= survive;
|
||||
create or replace table x0 (x int) with system versioning;
|
||||
rename table x0 to d0;
|
||||
show tables;
|
||||
Tables_in_test
|
||||
d0
|
||||
d0_vtmd
|
||||
call check_vtmd('d0_vtmd');
|
||||
@start > 0 and @start < @inf
|
||||
1
|
||||
A_start B_end name C_archive_name
|
||||
1 0 x0 NULL
|
||||
1 1 d0 NULL
|
||||
set versioning_alter_history= keep;
|
||||
drop table d0;
|
||||
set versioning_alter_history= survive;
|
||||
create or replace table x0 (x int) with system versioning;
|
||||
rename table x0 to d0;
|
||||
ERROR HY000: VTMD error: `test.d0_vtmd` table already exists!
|
||||
show tables;
|
||||
Tables_in_test
|
||||
d0_vtmd
|
||||
x0
|
||||
x0_vtmd
|
||||
drop table x0_vtmd;
|
||||
rename table x0 to d0;
|
||||
Warnings:
|
||||
Warning 4122 `test.d0_vtmd` table already exists!
|
||||
show tables;
|
||||
Tables_in_test
|
||||
d0
|
||||
d0_vtmd
|
||||
rename table d0 to duck;
|
||||
rename table duck to bay;
|
||||
rename table bay to sheer;
|
||||
rename table sheer to t0;
|
||||
call check_vtmd('t0_vtmd');
|
||||
@start > 0 and @start < @inf
|
||||
1
|
||||
A_start B_end name C_archive_name
|
||||
1 0 x0 NULL
|
||||
1 0 d0 NULL
|
||||
1 0 duck NULL
|
||||
1 0 bay NULL
|
||||
1 0 sheer NULL
|
||||
1 1 t0 NULL
|
||||
alter table t0 add column (y int);
|
||||
call check_vtmd('t0_vtmd');
|
||||
@start > 0 and @start < @inf
|
||||
1
|
||||
A_start B_end name C_archive_name
|
||||
1 0 x0 t0_
|
||||
1 0 d0 t0_
|
||||
1 0 duck t0_
|
||||
1 0 bay t0_
|
||||
1 0 sheer t0_
|
||||
1 0 t0 t0_
|
||||
1 1 t0 NULL
|
||||
alter table t0 add column (z int);
|
||||
alter table t0 drop column y;
|
||||
alter table t0 drop column z;
|
||||
create database db0;
|
||||
rename table t0 to db0.t0;
|
||||
show tables;
|
||||
Tables_in_test
|
||||
use db0;
|
||||
show tables;
|
||||
Tables_in_db0
|
||||
t0
|
||||
t0_vtmd
|
||||
call test.check_vtmd('db0.t0_vtmd');
|
||||
@start > 0 and @start < @inf
|
||||
1
|
||||
A_start B_end name C_archive_name
|
||||
1 0 x0 t0_
|
||||
1 0 d0 t0_
|
||||
1 0 duck t0_
|
||||
1 0 bay t0_
|
||||
1 0 sheer t0_
|
||||
1 0 t0 t0_
|
||||
1 0 t0 t0_
|
||||
1 0 t0 t0_
|
||||
1 0 t0 t0_
|
||||
1 1 t0 NULL
|
||||
create database db1;
|
||||
rename table t0 to db1.other_name;
|
||||
show tables;
|
||||
Tables_in_db0
|
||||
use db1;
|
||||
show tables;
|
||||
Tables_in_db1
|
||||
other_name
|
||||
other_name_vtmd
|
||||
call test.check_vtmd('db1.other_name_vtmd');
|
||||
@start > 0 and @start < @inf
|
||||
1
|
||||
A_start B_end name C_archive_name
|
||||
1 0 x0 t0_
|
||||
1 0 d0 t0_
|
||||
1 0 duck t0_
|
||||
1 0 bay t0_
|
||||
1 0 sheer t0_
|
||||
1 0 t0 t0_
|
||||
1 0 t0 t0_
|
||||
1 0 t0 t0_
|
||||
1 0 t0 t0_
|
||||
1 0 t0 NULL
|
||||
1 1 other_name NULL
|
||||
alter table other_name rename to t1;
|
||||
call test.check_vtmd('db1.t1_vtmd');
|
||||
@start > 0 and @start < @inf
|
||||
1
|
||||
A_start B_end name C_archive_name
|
||||
1 0 x0 t0_
|
||||
1 0 d0 t0_
|
||||
1 0 duck t0_
|
||||
1 0 bay t0_
|
||||
1 0 sheer t0_
|
||||
1 0 t0 t0_
|
||||
1 0 t0 t0_
|
||||
1 0 t0 t0_
|
||||
1 0 t0 t0_
|
||||
1 0 t0 NULL
|
||||
1 0 other_name NULL
|
||||
1 1 t1 NULL
|
||||
alter table t1 rename to test.t2, add column (y int);
|
||||
use test;
|
||||
show tables;
|
||||
Tables_in_test
|
||||
t2
|
||||
t2_vtmd
|
||||
call check_vtmd('t2_vtmd');
|
||||
@start > 0 and @start < @inf
|
||||
1
|
||||
A_start B_end name C_archive_name
|
||||
1 0 x0 t0_
|
||||
1 0 d0 t0_
|
||||
1 0 duck t0_
|
||||
1 0 bay t0_
|
||||
1 0 sheer t0_
|
||||
1 0 t0 t0_
|
||||
1 0 t0 t0_
|
||||
1 0 t0 t0_
|
||||
1 0 t0 t0_
|
||||
1 0 t0 t1_
|
||||
1 0 other_name t1_
|
||||
1 0 t1 t1_
|
||||
1 1 t2 NULL
|
||||
create or replace table t3 (x int) with system versioning;
|
||||
alter table t3 change x x bigint;
|
||||
alter table t3 change x x bigint after sys_trx_start;
|
||||
call check_vtmd('t3_vtmd');
|
||||
@start > 0 and @start < @inf
|
||||
1
|
||||
A_start B_end name C_archive_name
|
||||
1 0 t3 t3_
|
||||
1 0 t3 t3_
|
||||
1 1 t3 NULL
|
||||
set versioning_hide= auto;
|
||||
call show_tables();
|
||||
Tables_in_test
|
||||
t2
|
||||
t2_vtmd
|
||||
t3
|
||||
t3_vtmd
|
||||
table_name table_schema
|
||||
t2 test
|
||||
t2_vtmd test
|
||||
t3 test
|
||||
t3_vtmd test
|
||||
set versioning_hide= implicit;
|
||||
call show_tables();
|
||||
Tables_in_test
|
||||
t2
|
||||
t2_vtmd
|
||||
t3
|
||||
t3_vtmd
|
||||
table_name table_schema
|
||||
t2 test
|
||||
t2_vtmd test
|
||||
t3 test
|
||||
t3_vtmd test
|
||||
set versioning_hide= full;
|
||||
call show_tables();
|
||||
Tables_in_test
|
||||
t2
|
||||
t2_vtmd
|
||||
t3
|
||||
t3_vtmd
|
||||
table_name table_schema
|
||||
t2 test
|
||||
t2_vtmd test
|
||||
t3 test
|
||||
t3_vtmd test
|
||||
set versioning_hide= never;
|
||||
call show_tables();
|
||||
Tables_in_test
|
||||
t0_TIMESTAMP_SUFFIX
|
||||
t0_TIMESTAMP_SUFFIX
|
||||
t0_TIMESTAMP_SUFFIX
|
||||
t0_TIMESTAMP_SUFFIX
|
||||
t2
|
||||
t2_vtmd
|
||||
t3
|
||||
t3_TIMESTAMP_SUFFIX
|
||||
t3_TIMESTAMP_SUFFIX
|
||||
t3_vtmd
|
||||
table_name table_schema
|
||||
t0_TIMESTAMP_SUFFIX test
|
||||
t0_TIMESTAMP_SUFFIX test
|
||||
t0_TIMESTAMP_SUFFIX test
|
||||
t0_TIMESTAMP_SUFFIX test
|
||||
t1_TIMESTAMP_SUFFIX db1
|
||||
t2 test
|
||||
t2_vtmd test
|
||||
t3 test
|
||||
t3_TIMESTAMP_SUFFIX test
|
||||
t3_TIMESTAMP_SUFFIX test
|
||||
t3_vtmd test
|
||||
set versioning_hide= auto;
|
||||
create or replace table u0_vtmd (x int) with system versioning;
|
||||
show tables;
|
||||
Tables_in_test
|
||||
t2
|
||||
t2_vtmd
|
||||
t3
|
||||
t3_vtmd
|
||||
u0_vtmd
|
||||
u0_vtmd_vtmd
|
||||
Warnings:
|
||||
Warning 4122 Table `test.u0_vtmd` is not a VTMD table
|
||||
set versioning_alter_history= survive;
|
||||
create or replace table t (x int) with system versioning;
|
||||
select * from t for system_time all;
|
||||
x sys_trx_start sys_trx_end
|
||||
drop database db0;
|
||||
drop database db1;
|
||||
drop database test;
|
||||
create database test;
|
@ -1,229 +0,0 @@
|
||||
create or replace procedure drop_archives (in vtmd_name varchar(64))
|
||||
begin
|
||||
declare archive_name varchar(64);
|
||||
declare cur_done bool default false;
|
||||
declare cur cursor for
|
||||
select cur_tmp.archive_name from cur_tmp;
|
||||
declare continue handler for not found set cur_done = true;
|
||||
set @tmp= concat('
|
||||
create or replace temporary table
|
||||
cur_tmp as
|
||||
select vtmd.archive_name from ', vtmd_name, '
|
||||
for system_time all as vtmd
|
||||
where vtmd.archive_name is not null
|
||||
group by vtmd.archive_name');
|
||||
prepare stmt from @tmp; execute stmt; drop prepare stmt;
|
||||
open cur;
|
||||
fetch_loop: loop
|
||||
fetch cur into archive_name;
|
||||
if cur_done then
|
||||
leave fetch_loop;
|
||||
end if;
|
||||
set @tmp= concat('drop table ', archive_name);
|
||||
prepare stmt from @tmp; execute stmt; drop prepare stmt;
|
||||
end loop;
|
||||
drop table cur_tmp;
|
||||
end~~
|
||||
create procedure test_01(in engine varchar(64))
|
||||
begin
|
||||
set @tmp = concat('create table t (a int) with system versioning engine ', engine);
|
||||
prepare stmt from @tmp; execute stmt; drop prepare stmt;
|
||||
set @tm1 = now(6);
|
||||
alter table t add column b int;
|
||||
set @tm2 = now(6);
|
||||
alter table t add column c int;
|
||||
show create table t for system_time as of timestamp @tm1;
|
||||
show create table t for system_time as of timestamp @tm2;
|
||||
show create table t for system_time as of now;
|
||||
show create table t for system_time as of timestamp now(6);
|
||||
show create table t;
|
||||
set @tm3 = now(6);
|
||||
rename table t to tt;
|
||||
show create table tt for system_time as of timestamp @tm3;
|
||||
set @tm4 = now(6);
|
||||
alter table tt add column d int;
|
||||
show create table tt for system_time as of timestamp @tm3;
|
||||
show create table tt for system_time as of timestamp @tm4;
|
||||
show create table tt;
|
||||
drop table tt;
|
||||
call drop_archives('tt_vtmd');
|
||||
drop table tt_vtmd;
|
||||
end~~
|
||||
create table t (a int) with system versioning;
|
||||
show create table t for system_time as of now;
|
||||
ERROR HY000: VTMD error: Table 'test.t_vtmd' doesn't exist
|
||||
set versioning_alter_history=survive;
|
||||
create or replace table t (a int) with system versioning;
|
||||
show create table t for system_time between timestamp @tm1 and timestamp @tm1;
|
||||
ERROR HY000: SYSTEM_TIME range selector is prohibited
|
||||
show create table t for system_time from timestamp @tm1 to timestamp @tm1;
|
||||
ERROR HY000: SYSTEM_TIME range selector is prohibited
|
||||
show create table t for system_time as of timestamp '01-01-1990';
|
||||
ERROR HY000: VTMD error: Table 'test.t' doesn't exist
|
||||
show create table t for system_time as of timestamp '01-01-2020';
|
||||
ERROR HY000: VTMD error: Table 'test.t' doesn't exist
|
||||
drop table t;
|
||||
call drop_archives('t_vtmd');
|
||||
drop table t_vtmd;
|
||||
call test_01('myisam');
|
||||
Table Create Table
|
||||
t CREATE TABLE `t` (
|
||||
`a` int(11) DEFAULT NULL,
|
||||
`sys_trx_start` timestamp(6) GENERATED ALWAYS AS ROW START,
|
||||
`sys_trx_end` timestamp(6) GENERATED ALWAYS AS ROW END,
|
||||
PERIOD FOR SYSTEM_TIME (`sys_trx_start`, `sys_trx_end`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
|
||||
Table Create Table
|
||||
t CREATE TABLE `t` (
|
||||
`a` int(11) DEFAULT NULL,
|
||||
`sys_trx_start` timestamp(6) GENERATED ALWAYS AS ROW START,
|
||||
`sys_trx_end` timestamp(6) GENERATED ALWAYS AS ROW END,
|
||||
`b` int(11) DEFAULT NULL,
|
||||
PERIOD FOR SYSTEM_TIME (`sys_trx_start`, `sys_trx_end`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
|
||||
Table Create Table
|
||||
t CREATE TABLE `t` (
|
||||
`a` int(11) DEFAULT NULL,
|
||||
`sys_trx_start` timestamp(6) GENERATED ALWAYS AS ROW START,
|
||||
`sys_trx_end` timestamp(6) GENERATED ALWAYS AS ROW END,
|
||||
`b` int(11) DEFAULT NULL,
|
||||
`c` int(11) DEFAULT NULL,
|
||||
PERIOD FOR SYSTEM_TIME (`sys_trx_start`, `sys_trx_end`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
|
||||
Table Create Table
|
||||
t CREATE TABLE `t` (
|
||||
`a` int(11) DEFAULT NULL,
|
||||
`sys_trx_start` timestamp(6) GENERATED ALWAYS AS ROW START,
|
||||
`sys_trx_end` timestamp(6) GENERATED ALWAYS AS ROW END,
|
||||
`b` int(11) DEFAULT NULL,
|
||||
`c` int(11) DEFAULT NULL,
|
||||
PERIOD FOR SYSTEM_TIME (`sys_trx_start`, `sys_trx_end`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
|
||||
Table Create Table
|
||||
t CREATE TABLE `t` (
|
||||
`a` int(11) DEFAULT NULL,
|
||||
`sys_trx_start` timestamp(6) GENERATED ALWAYS AS ROW START,
|
||||
`sys_trx_end` timestamp(6) GENERATED ALWAYS AS ROW END,
|
||||
`b` int(11) DEFAULT NULL,
|
||||
`c` int(11) DEFAULT NULL,
|
||||
PERIOD FOR SYSTEM_TIME (`sys_trx_start`, `sys_trx_end`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
|
||||
Table Create Table
|
||||
tt CREATE TABLE `tt` (
|
||||
`a` int(11) DEFAULT NULL,
|
||||
`sys_trx_start` timestamp(6) GENERATED ALWAYS AS ROW START,
|
||||
`sys_trx_end` timestamp(6) GENERATED ALWAYS AS ROW END,
|
||||
`b` int(11) DEFAULT NULL,
|
||||
`c` int(11) DEFAULT NULL,
|
||||
PERIOD FOR SYSTEM_TIME (`sys_trx_start`, `sys_trx_end`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
|
||||
Table Create Table
|
||||
tt CREATE TABLE `tt` (
|
||||
`a` int(11) DEFAULT NULL,
|
||||
`sys_trx_start` timestamp(6) GENERATED ALWAYS AS ROW START,
|
||||
`sys_trx_end` timestamp(6) GENERATED ALWAYS AS ROW END,
|
||||
`b` int(11) DEFAULT NULL,
|
||||
`c` int(11) DEFAULT NULL,
|
||||
PERIOD FOR SYSTEM_TIME (`sys_trx_start`, `sys_trx_end`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
|
||||
Table Create Table
|
||||
tt CREATE TABLE `tt` (
|
||||
`a` int(11) DEFAULT NULL,
|
||||
`sys_trx_start` timestamp(6) GENERATED ALWAYS AS ROW START,
|
||||
`sys_trx_end` timestamp(6) GENERATED ALWAYS AS ROW END,
|
||||
`b` int(11) DEFAULT NULL,
|
||||
`c` int(11) DEFAULT NULL,
|
||||
PERIOD FOR SYSTEM_TIME (`sys_trx_start`, `sys_trx_end`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
|
||||
Table Create Table
|
||||
tt CREATE TABLE `tt` (
|
||||
`a` int(11) DEFAULT NULL,
|
||||
`sys_trx_start` timestamp(6) GENERATED ALWAYS AS ROW START,
|
||||
`sys_trx_end` timestamp(6) GENERATED ALWAYS AS ROW END,
|
||||
`b` int(11) DEFAULT NULL,
|
||||
`c` int(11) DEFAULT NULL,
|
||||
`d` int(11) DEFAULT NULL,
|
||||
PERIOD FOR SYSTEM_TIME (`sys_trx_start`, `sys_trx_end`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
|
||||
call test_01('innodb');
|
||||
Table Create Table
|
||||
t CREATE TABLE `t` (
|
||||
`a` int(11) DEFAULT NULL,
|
||||
`sys_trx_start` bigint(20) unsigned GENERATED ALWAYS AS ROW START,
|
||||
`sys_trx_end` bigint(20) unsigned GENERATED ALWAYS AS ROW END,
|
||||
PERIOD FOR SYSTEM_TIME (`sys_trx_start`, `sys_trx_end`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
|
||||
Table Create Table
|
||||
t CREATE TABLE `t` (
|
||||
`a` int(11) DEFAULT NULL,
|
||||
`sys_trx_start` bigint(20) unsigned GENERATED ALWAYS AS ROW START,
|
||||
`sys_trx_end` bigint(20) unsigned GENERATED ALWAYS AS ROW END,
|
||||
`b` int(11) DEFAULT NULL,
|
||||
PERIOD FOR SYSTEM_TIME (`sys_trx_start`, `sys_trx_end`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
|
||||
Table Create Table
|
||||
t CREATE TABLE `t` (
|
||||
`a` int(11) DEFAULT NULL,
|
||||
`sys_trx_start` bigint(20) unsigned GENERATED ALWAYS AS ROW START,
|
||||
`sys_trx_end` bigint(20) unsigned GENERATED ALWAYS AS ROW END,
|
||||
`b` int(11) DEFAULT NULL,
|
||||
`c` int(11) DEFAULT NULL,
|
||||
PERIOD FOR SYSTEM_TIME (`sys_trx_start`, `sys_trx_end`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
|
||||
Table Create Table
|
||||
t CREATE TABLE `t` (
|
||||
`a` int(11) DEFAULT NULL,
|
||||
`sys_trx_start` bigint(20) unsigned GENERATED ALWAYS AS ROW START,
|
||||
`sys_trx_end` bigint(20) unsigned GENERATED ALWAYS AS ROW END,
|
||||
`b` int(11) DEFAULT NULL,
|
||||
`c` int(11) DEFAULT NULL,
|
||||
PERIOD FOR SYSTEM_TIME (`sys_trx_start`, `sys_trx_end`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
|
||||
Table Create Table
|
||||
t CREATE TABLE `t` (
|
||||
`a` int(11) DEFAULT NULL,
|
||||
`sys_trx_start` bigint(20) unsigned GENERATED ALWAYS AS ROW START,
|
||||
`sys_trx_end` bigint(20) unsigned GENERATED ALWAYS AS ROW END,
|
||||
`b` int(11) DEFAULT NULL,
|
||||
`c` int(11) DEFAULT NULL,
|
||||
PERIOD FOR SYSTEM_TIME (`sys_trx_start`, `sys_trx_end`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
|
||||
Table Create Table
|
||||
tt CREATE TABLE `tt` (
|
||||
`a` int(11) DEFAULT NULL,
|
||||
`sys_trx_start` bigint(20) unsigned GENERATED ALWAYS AS ROW START,
|
||||
`sys_trx_end` bigint(20) unsigned GENERATED ALWAYS AS ROW END,
|
||||
`b` int(11) DEFAULT NULL,
|
||||
`c` int(11) DEFAULT NULL,
|
||||
PERIOD FOR SYSTEM_TIME (`sys_trx_start`, `sys_trx_end`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
|
||||
Table Create Table
|
||||
tt CREATE TABLE `tt` (
|
||||
`a` int(11) DEFAULT NULL,
|
||||
`sys_trx_start` bigint(20) unsigned GENERATED ALWAYS AS ROW START,
|
||||
`sys_trx_end` bigint(20) unsigned GENERATED ALWAYS AS ROW END,
|
||||
`b` int(11) DEFAULT NULL,
|
||||
`c` int(11) DEFAULT NULL,
|
||||
PERIOD FOR SYSTEM_TIME (`sys_trx_start`, `sys_trx_end`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
|
||||
Table Create Table
|
||||
tt CREATE TABLE `tt` (
|
||||
`a` int(11) DEFAULT NULL,
|
||||
`sys_trx_start` bigint(20) unsigned GENERATED ALWAYS AS ROW START,
|
||||
`sys_trx_end` bigint(20) unsigned GENERATED ALWAYS AS ROW END,
|
||||
`b` int(11) DEFAULT NULL,
|
||||
`c` int(11) DEFAULT NULL,
|
||||
PERIOD FOR SYSTEM_TIME (`sys_trx_start`, `sys_trx_end`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
|
||||
Table Create Table
|
||||
tt CREATE TABLE `tt` (
|
||||
`a` int(11) DEFAULT NULL,
|
||||
`sys_trx_start` bigint(20) unsigned GENERATED ALWAYS AS ROW START,
|
||||
`sys_trx_end` bigint(20) unsigned GENERATED ALWAYS AS ROW END,
|
||||
`b` int(11) DEFAULT NULL,
|
||||
`c` int(11) DEFAULT NULL,
|
||||
`d` int(11) DEFAULT NULL,
|
||||
PERIOD FOR SYSTEM_TIME (`sys_trx_start`, `sys_trx_end`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
|
||||
drop procedure test_01;
|
||||
drop procedure drop_archives;
|
@ -1,105 +0,0 @@
|
||||
-- source suite/versioning/common.inc
|
||||
|
||||
delimiter ~~;
|
||||
create function get_archive_table_name()
|
||||
returns varchar(255)
|
||||
begin
|
||||
return (select archive_name from t_vtmd for system_time all where archive_name is not NULL
|
||||
order by start desc limit 1);
|
||||
end~~
|
||||
|
||||
create procedure drop_last_archive()
|
||||
begin
|
||||
call concat_exec2('drop table ', get_archive_table_name());
|
||||
end~~
|
||||
delimiter ;~~
|
||||
|
||||
set versioning_alter_history= survive;
|
||||
|
||||
create or replace table t (a int) with system versioning;
|
||||
insert into t values (1);
|
||||
update t set a=2 where a=1;
|
||||
select sys_trx_start from t where a=2 into @tm;
|
||||
alter table t add column b int;
|
||||
|
||||
select * from t;
|
||||
call concat_exec3('select * from ', get_archive_table_name(), ' for system_time all');
|
||||
|
||||
call concat_exec3('select @tm=sys_trx_start from ', get_archive_table_name(), ' for system_time all where a=2');
|
||||
select @tm<sys_trx_start from t where a=2;
|
||||
select sys_trx_start from t where a=2 into @tm;
|
||||
call concat_exec3('select @tm=sys_trx_end from ', get_archive_table_name(), ' for system_time all where a=2');
|
||||
|
||||
call drop_last_archive();
|
||||
|
||||
|
||||
set versioning_alter_history= keep;
|
||||
drop table t_vtmd;
|
||||
drop table t;
|
||||
set versioning_alter_history= survive;
|
||||
|
||||
# same for INNODB ALGORITHM=COPY
|
||||
create or replace table t (a int) with system versioning;
|
||||
insert into t values (1);
|
||||
update t set a=2 where a=1;
|
||||
select sys_trx_start from t where a=2 into @tm;
|
||||
alter table t add column b int;
|
||||
|
||||
select * from t;
|
||||
call concat_exec3('select * from ', get_archive_table_name(), ' for system_time all');
|
||||
|
||||
call concat_exec3('select @tm=sys_trx_start from ', get_archive_table_name(), ' for system_time all where a=2');
|
||||
select @tm<sys_trx_start from t where a=2;
|
||||
select sys_trx_start from t where a=2 into @tm;
|
||||
call concat_exec3('select @tm=sys_trx_end from ', get_archive_table_name(), ' for system_time all where a=2');
|
||||
|
||||
call drop_last_archive();
|
||||
|
||||
|
||||
set versioning_alter_history= keep;
|
||||
drop table t_vtmd;
|
||||
drop table t;
|
||||
set versioning_alter_history= survive;
|
||||
|
||||
# same for INNODB default ALGORITHM
|
||||
create or replace table t (a int) with system versioning engine innodb;
|
||||
insert into t values (1);
|
||||
update t set a=2 where a=1;
|
||||
select sys_trx_start from t where a=2 into @tm;
|
||||
alter table t add column b int;
|
||||
|
||||
select * from t;
|
||||
call concat_exec3('select * from ', get_archive_table_name(), ' for system_time all');
|
||||
|
||||
call concat_exec3('select @tm=sys_trx_start from ', get_archive_table_name(), ' for system_time all where a=2');
|
||||
select @tm<sys_trx_start from t where a=2;
|
||||
select sys_trx_start from t where a=2 into @tm;
|
||||
call concat_exec3('select @tm=sys_trx_end from ', get_archive_table_name(), ' for system_time all where a=2');
|
||||
|
||||
call drop_last_archive();
|
||||
|
||||
|
||||
set versioning_alter_history= keep;
|
||||
drop table t_vtmd;
|
||||
drop table t;
|
||||
set versioning_alter_history= survive;
|
||||
|
||||
# no DDL for INNODB explicit ALGORITHM=INPLACE
|
||||
create or replace table t (a int) with system versioning engine innodb;
|
||||
insert into t values (1);
|
||||
update t set a=2 where a=1;
|
||||
alter table t add column b int, algorithm=inplace;
|
||||
|
||||
set versioning_alter_history = keep;
|
||||
|
||||
drop function get_archive_table_name;
|
||||
drop procedure drop_last_archive;
|
||||
|
||||
select * from mysql.vtmd_template;
|
||||
show create table mysql.vtmd_template;
|
||||
|
||||
call verify_vtq;
|
||||
drop table t;
|
||||
drop table t_vtmd;
|
||||
|
||||
-- source suite/versioning/common_finish.inc
|
@ -1,206 +0,0 @@
|
||||
-- source include/have_innodb.inc
|
||||
set default_storage_engine=innodb;
|
||||
|
||||
delimiter ~~;
|
||||
create or replace procedure drop_archives (in vtmd_name varchar(64))
|
||||
begin
|
||||
declare archive_name varchar(64);
|
||||
declare cur_done bool default false;
|
||||
declare cur cursor for
|
||||
select cur_tmp.archive_name from cur_tmp;
|
||||
declare continue handler for not found set cur_done = true;
|
||||
|
||||
set @tmp= concat('
|
||||
create or replace temporary table
|
||||
cur_tmp as
|
||||
select vtmd.archive_name from ', vtmd_name, '
|
||||
for system_time all as vtmd
|
||||
where vtmd.archive_name is not null
|
||||
group by vtmd.archive_name');
|
||||
prepare stmt from @tmp; execute stmt; drop prepare stmt;
|
||||
|
||||
open cur;
|
||||
fetch_loop: loop
|
||||
fetch cur into archive_name;
|
||||
if cur_done then
|
||||
leave fetch_loop;
|
||||
end if;
|
||||
set @tmp= concat('drop table ', archive_name);
|
||||
prepare stmt from @tmp; execute stmt; drop prepare stmt;
|
||||
end loop;
|
||||
|
||||
drop table cur_tmp;
|
||||
end~~
|
||||
delimiter ;~~
|
||||
|
||||
delimiter ~~;
|
||||
create or replace procedure check_vtmd (in vtmd_name varchar(64))
|
||||
begin
|
||||
set @tmp= concat('
|
||||
create or replace temporary table
|
||||
tmp_vtmd with system versioning as
|
||||
select * from ', vtmd_name, '
|
||||
for system_time all as vtmd');
|
||||
prepare stmt from @tmp; execute stmt; drop prepare stmt;
|
||||
|
||||
set @inf= 0xFFFFFFFFFFFFFFFF + 0;
|
||||
set @start= null;
|
||||
select start from tmp_vtmd for system_time all order by start limit 1 into @start;
|
||||
select @start > 0 and @start < @inf;
|
||||
select
|
||||
start >= @start as A_start,
|
||||
(@start:= end) and end = @inf as B_end,
|
||||
name,
|
||||
substr(archive_name, 1, instr(archive_name, '_')) as C_archive_name
|
||||
from tmp_vtmd for system_time all;
|
||||
|
||||
drop table tmp_vtmd;
|
||||
end~~
|
||||
delimiter ;~~
|
||||
|
||||
delimiter ~~;
|
||||
create or replace procedure show_tables()
|
||||
begin
|
||||
show tables;
|
||||
select table_name, table_schema from information_schema.tables
|
||||
where table_schema not in ('mysql', 'performance_schema', 'information_schema', 'mtr')
|
||||
order by table_name;
|
||||
end~~
|
||||
delimiter ;~~
|
||||
|
||||
# create
|
||||
set versioning_alter_history= keep;
|
||||
create table t0 (z int) with system versioning;
|
||||
show tables;
|
||||
set versioning_alter_history= survive;
|
||||
create or replace table t0 (y int) with system versioning;
|
||||
show tables;
|
||||
show create table t0_vtmd;
|
||||
call check_vtmd('t0_vtmd');
|
||||
|
||||
set versioning_alter_history= keep;
|
||||
drop table t0;
|
||||
set versioning_alter_history= survive;
|
||||
--error ER_VERS_VTMD_ERROR
|
||||
create table t0 (x int) with system versioning;
|
||||
|
||||
drop table t0_vtmd;
|
||||
create table t0 (y int) with system versioning;
|
||||
create or replace table t0 (x int) with system versioning;
|
||||
|
||||
# alter
|
||||
insert into t0 values (1);
|
||||
set @t0= now(6);
|
||||
alter table t0 add column (y int);
|
||||
select * from t0 for system_time as of @t0;
|
||||
select * from t0;
|
||||
call check_vtmd('t0_vtmd');
|
||||
|
||||
call drop_archives('t0_vtmd');
|
||||
drop table t0_vtmd;
|
||||
alter table t0 drop column y;
|
||||
call check_vtmd('t0_vtmd');
|
||||
|
||||
call drop_archives('t0_vtmd');
|
||||
set versioning_alter_history= keep;
|
||||
drop tables t0, t0_vtmd;
|
||||
set versioning_alter_history= survive;
|
||||
|
||||
# rename
|
||||
set versioning_alter_history= keep;
|
||||
create or replace table x0 (x int) with system versioning;
|
||||
set versioning_alter_history= survive;
|
||||
rename table x0 to d0;
|
||||
show tables;
|
||||
|
||||
set versioning_alter_history= keep;
|
||||
drop table d0;
|
||||
set versioning_alter_history= survive;
|
||||
create or replace table x0 (x int) with system versioning;
|
||||
rename table x0 to d0;
|
||||
show tables;
|
||||
call check_vtmd('d0_vtmd');
|
||||
|
||||
set versioning_alter_history= keep;
|
||||
drop table d0;
|
||||
set versioning_alter_history= survive;
|
||||
create or replace table x0 (x int) with system versioning;
|
||||
|
||||
--error ER_VERS_VTMD_ERROR
|
||||
rename table x0 to d0;
|
||||
show tables;
|
||||
|
||||
drop table x0_vtmd;
|
||||
rename table x0 to d0;
|
||||
show tables;
|
||||
|
||||
rename table d0 to duck;
|
||||
rename table duck to bay;
|
||||
rename table bay to sheer;
|
||||
rename table sheer to t0;
|
||||
call check_vtmd('t0_vtmd');
|
||||
|
||||
alter table t0 add column (y int);
|
||||
call check_vtmd('t0_vtmd');
|
||||
|
||||
# rename to different schema
|
||||
alter table t0 add column (z int);
|
||||
alter table t0 drop column y;
|
||||
alter table t0 drop column z;
|
||||
|
||||
create database db0;
|
||||
rename table t0 to db0.t0;
|
||||
show tables;
|
||||
use db0;
|
||||
show tables;
|
||||
call test.check_vtmd('db0.t0_vtmd');
|
||||
|
||||
create database db1;
|
||||
rename table t0 to db1.other_name;
|
||||
show tables;
|
||||
use db1;
|
||||
show tables;
|
||||
call test.check_vtmd('db1.other_name_vtmd');
|
||||
|
||||
# alter rename
|
||||
alter table other_name rename to t1;
|
||||
call test.check_vtmd('db1.t1_vtmd');
|
||||
|
||||
# alter rename and modify to different schema
|
||||
alter table t1 rename to test.t2, add column (y int);
|
||||
use test;
|
||||
show tables;
|
||||
call check_vtmd('t2_vtmd');
|
||||
|
||||
create or replace table t3 (x int) with system versioning;
|
||||
alter table t3 change x x bigint;
|
||||
alter table t3 change x x bigint after sys_trx_start;
|
||||
call check_vtmd('t3_vtmd');
|
||||
|
||||
# hide archive tables
|
||||
set versioning_hide= auto;
|
||||
call show_tables();
|
||||
|
||||
set versioning_hide= implicit;
|
||||
call show_tables();
|
||||
|
||||
set versioning_hide= full;
|
||||
call show_tables();
|
||||
|
||||
set versioning_hide= never;
|
||||
--replace_regex /\d{8}_\d{6}_\d{6}/TIMESTAMP_SUFFIX/
|
||||
call show_tables();
|
||||
|
||||
# wrong VTMD handling
|
||||
set versioning_hide= auto;
|
||||
create or replace table u0_vtmd (x int) with system versioning;
|
||||
show tables;
|
||||
|
||||
set versioning_alter_history= survive;
|
||||
create or replace table t (x int) with system versioning;
|
||||
select * from t for system_time all;
|
||||
|
||||
drop database db0;
|
||||
drop database db1;
|
||||
drop database test;
|
||||
create database test;
|
@ -1,92 +0,0 @@
|
||||
-- source include/have_innodb.inc
|
||||
|
||||
delimiter ~~;
|
||||
create or replace procedure drop_archives (in vtmd_name varchar(64))
|
||||
begin
|
||||
declare archive_name varchar(64);
|
||||
declare cur_done bool default false;
|
||||
declare cur cursor for
|
||||
select cur_tmp.archive_name from cur_tmp;
|
||||
declare continue handler for not found set cur_done = true;
|
||||
|
||||
set @tmp= concat('
|
||||
create or replace temporary table
|
||||
cur_tmp as
|
||||
select vtmd.archive_name from ', vtmd_name, '
|
||||
for system_time all as vtmd
|
||||
where vtmd.archive_name is not null
|
||||
group by vtmd.archive_name');
|
||||
prepare stmt from @tmp; execute stmt; drop prepare stmt;
|
||||
|
||||
open cur;
|
||||
fetch_loop: loop
|
||||
fetch cur into archive_name;
|
||||
if cur_done then
|
||||
leave fetch_loop;
|
||||
end if;
|
||||
set @tmp= concat('drop table ', archive_name);
|
||||
prepare stmt from @tmp; execute stmt; drop prepare stmt;
|
||||
end loop;
|
||||
|
||||
drop table cur_tmp;
|
||||
end~~
|
||||
delimiter ;~~
|
||||
|
||||
delimiter ~~;
|
||||
create procedure test_01(in engine varchar(64))
|
||||
begin
|
||||
set @tmp = concat('create table t (a int) with system versioning engine ', engine);
|
||||
prepare stmt from @tmp; execute stmt; drop prepare stmt;
|
||||
|
||||
set @tm1 = now(6);
|
||||
alter table t add column b int;
|
||||
|
||||
set @tm2 = now(6);
|
||||
alter table t add column c int;
|
||||
|
||||
show create table t for system_time as of timestamp @tm1;
|
||||
show create table t for system_time as of timestamp @tm2;
|
||||
show create table t for system_time as of now;
|
||||
show create table t for system_time as of timestamp now(6);
|
||||
show create table t;
|
||||
|
||||
set @tm3 = now(6);
|
||||
rename table t to tt;
|
||||
show create table tt for system_time as of timestamp @tm3;
|
||||
|
||||
set @tm4 = now(6);
|
||||
alter table tt add column d int;
|
||||
show create table tt for system_time as of timestamp @tm3;
|
||||
show create table tt for system_time as of timestamp @tm4;
|
||||
show create table tt;
|
||||
|
||||
drop table tt;
|
||||
call drop_archives('tt_vtmd');
|
||||
drop table tt_vtmd;
|
||||
end~~
|
||||
delimiter ;~~
|
||||
|
||||
create table t (a int) with system versioning;
|
||||
--error ER_VERS_VTMD_ERROR
|
||||
show create table t for system_time as of now;
|
||||
|
||||
set versioning_alter_history=survive;
|
||||
|
||||
create or replace table t (a int) with system versioning;
|
||||
--error ER_VERS_RANGE_PROHIBITED
|
||||
show create table t for system_time between timestamp @tm1 and timestamp @tm1;
|
||||
--error ER_VERS_RANGE_PROHIBITED
|
||||
show create table t for system_time from timestamp @tm1 to timestamp @tm1;
|
||||
--error ER_VERS_VTMD_ERROR
|
||||
show create table t for system_time as of timestamp '01-01-1990';
|
||||
--error ER_VERS_VTMD_ERROR
|
||||
show create table t for system_time as of timestamp '01-01-2020';
|
||||
drop table t;
|
||||
call drop_archives('t_vtmd');
|
||||
drop table t_vtmd;
|
||||
|
||||
call test_01('myisam');
|
||||
call test_01('innodb');
|
||||
|
||||
drop procedure test_01;
|
||||
drop procedure drop_archives;
|
@ -153,8 +153,7 @@ SET (SQL_SOURCE
|
||||
${CMAKE_CURRENT_BINARY_DIR}/sql_builtin.cc
|
||||
${GEN_SOURCES}
|
||||
${MYSYS_LIBWRAP_SOURCE}
|
||||
vtmd.cc
|
||||
)
|
||||
)
|
||||
|
||||
IF (CMAKE_SYSTEM_NAME MATCHES "Linux" OR
|
||||
CMAKE_SYSTEM_NAME MATCHES "Windows" OR
|
||||
|
@ -414,7 +414,6 @@ enum enum_alter_inplace_result {
|
||||
#define HA_CREATE_TMP_ALTER 8U
|
||||
#define HA_LEX_CREATE_SEQUENCE 16U
|
||||
#define HA_VERSIONED_TABLE 32U
|
||||
#define HA_VTMD 64U
|
||||
|
||||
#define HA_MAX_REC_LENGTH 65535
|
||||
|
||||
@ -2076,11 +2075,6 @@ struct Table_scope_and_contents_source_st
|
||||
{
|
||||
return options & HA_VERSIONED_TABLE;
|
||||
}
|
||||
|
||||
bool vtmd() const
|
||||
{
|
||||
return options & HA_VTMD;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
@ -202,9 +202,7 @@ struct vers_asof_timestamp_t
|
||||
enum vers_alter_history_enum
|
||||
{
|
||||
VERS_ALTER_HISTORY_ERROR= 0,
|
||||
VERS_ALTER_HISTORY_KEEP,
|
||||
VERS_ALTER_HISTORY_SURVIVE,
|
||||
VERS_ALTER_HISTORY_DROP
|
||||
VERS_ALTER_HISTORY_KEEP
|
||||
};
|
||||
/* System Versioning end */
|
||||
|
||||
|
@ -2647,30 +2647,6 @@ bool partition_info::has_same_partitioning(partition_info *new_part_info)
|
||||
}
|
||||
|
||||
|
||||
bool partition_info::vers_trx_id_to_ts(THD* thd, Field* in_trx_id, Field_timestamp& out_ts)
|
||||
{
|
||||
DBUG_ASSERT(table);
|
||||
handlerton *hton= plugin_hton(table->s->db_plugin);
|
||||
DBUG_ASSERT(hton);
|
||||
ulonglong trx_id= in_trx_id->val_int();
|
||||
TR_table trt(thd);
|
||||
bool found= trt.query(trx_id);
|
||||
if (!found)
|
||||
{
|
||||
push_warning_printf(thd,
|
||||
Sql_condition::WARN_LEVEL_WARN,
|
||||
WARN_VERS_TRX_MISSING,
|
||||
ER_THD(thd, WARN_VERS_TRX_MISSING),
|
||||
trx_id);
|
||||
return true;
|
||||
}
|
||||
MYSQL_TIME ts;
|
||||
trt[TR_table::FLD_COMMIT_TS]->get_date(&ts, 0);
|
||||
out_ts.store_time_dec(&ts, 6);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void partition_info::print_debug(const char *str, uint *value)
|
||||
{
|
||||
DBUG_ENTER("print_debug");
|
||||
|
@ -424,7 +424,6 @@ public:
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
bool vers_trx_id_to_ts(THD *thd, Field *in_trx_id, Field_timestamp &out_ts);
|
||||
};
|
||||
|
||||
uint32 get_next_partition_id_range(struct st_partition_iter* part_iter);
|
||||
|
@ -7844,8 +7844,8 @@ WARN_VERS_PARAMETERS
|
||||
ER_VERS_DROP_PARTITION_INTERVAL
|
||||
eng "Can only drop oldest partitions when rotating by INTERVAL"
|
||||
|
||||
WARN_VERS_TRX_MISSING
|
||||
eng "VTQ missing transaction ID %lu"
|
||||
ER_UNUSED_25
|
||||
eng "You should never see it"
|
||||
|
||||
WARN_VERS_PART_NON_HISTORICAL
|
||||
eng "Partition %`s contains non-historical data"
|
||||
@ -7859,8 +7859,8 @@ ER_VERS_ALTER_ENGINE_PROHIBITED
|
||||
ER_VERS_RANGE_PROHIBITED
|
||||
eng "SYSTEM_TIME range selector is prohibited"
|
||||
|
||||
ER_VERS_VTMD_ERROR
|
||||
eng "VTMD error: %s"
|
||||
ER_UNUSED_26
|
||||
eng "You should never see it"
|
||||
|
||||
ER_VERS_TABLE_MUST_HAVE_COLUMNS
|
||||
eng "Table %`s must have at least one versioned column"
|
||||
@ -7889,8 +7889,8 @@ ER_VERS_ALTER_SYSTEM_FIELD
|
||||
ER_DROP_VERSIONING_SYSTEM_TIME_PARTITION
|
||||
eng "Can not DROP SYSTEM VERSIONING for table %`s partitioned BY SYSTEM_TIME"
|
||||
|
||||
ER_NOT_LOG_TABLE
|
||||
eng "Table %`s.%`s is not a log table"
|
||||
ER_UNUSED_27
|
||||
eng "You should never see it"
|
||||
|
||||
ER_VERS_TRT_IS_DISABLED
|
||||
eng "Transaction registry is disabled"
|
||||
|
@ -238,11 +238,6 @@ void sp_cache_flush_obsolete(sp_cache **cp, sp_head **sp)
|
||||
}
|
||||
}
|
||||
|
||||
void sp_cache_flush(sp_cache *cp, sp_head *sp)
|
||||
{
|
||||
cp->remove(sp);
|
||||
}
|
||||
|
||||
/**
|
||||
Return the current global version of the cache.
|
||||
*/
|
||||
|
@ -60,7 +60,6 @@ void sp_cache_insert(sp_cache **cp, sp_head *sp);
|
||||
sp_head *sp_cache_lookup(sp_cache **cp, const Database_qualified_name *name);
|
||||
void sp_cache_invalidate();
|
||||
void sp_cache_flush_obsolete(sp_cache **cp, sp_head **sp);
|
||||
void sp_cache_flush(sp_cache *cp, sp_head *sp);
|
||||
ulong sp_cache_version();
|
||||
void sp_cache_enforce_limit(sp_cache *cp, ulong upper_limit_for_elements);
|
||||
|
||||
|
@ -41,18 +41,6 @@ public:
|
||||
ALTER_COLUMN_ORDER);
|
||||
}
|
||||
|
||||
bool partition_modifying() const
|
||||
{
|
||||
return partition_flags & (
|
||||
ALTER_PARTITION_DROP |
|
||||
ALTER_PARTITION_COALESCE |
|
||||
ALTER_PARTITION_REORGANIZE |
|
||||
ALTER_PARTITION_REMOVE |
|
||||
ALTER_PARTITION_TABLE_REORG |
|
||||
ALTER_PARTITION_EXCHANGE |
|
||||
ALTER_PARTITION_TRUNCATE);
|
||||
}
|
||||
|
||||
/**
|
||||
The different values of the ALGORITHM clause.
|
||||
Describes which algorithm to use when altering the table.
|
||||
|
@ -8821,31 +8821,10 @@ open_log_table(THD *thd, TABLE_LIST *one_table, Open_tables_backup *backup)
|
||||
|
||||
if ((table= open_ltable(thd, one_table, one_table->lock_type, flags)))
|
||||
{
|
||||
if (table->s->table_category == TABLE_CATEGORY_LOG)
|
||||
{
|
||||
/* Make sure all columns get assigned to a default value */
|
||||
table->use_all_columns();
|
||||
DBUG_ASSERT(table->s->no_replicate);
|
||||
}
|
||||
else
|
||||
{
|
||||
my_error(ER_NOT_LOG_TABLE, MYF(0), table->s->db.str, table->s->table_name.str);
|
||||
int error= 0;
|
||||
if (table->current_lock != F_UNLCK)
|
||||
{
|
||||
table->current_lock= F_UNLCK;
|
||||
error= table->file->ha_external_lock(thd, F_UNLCK);
|
||||
}
|
||||
if (error)
|
||||
table->file->print_error(error, MYF(0));
|
||||
else
|
||||
{
|
||||
tc_release_table(table);
|
||||
thd->reset_open_tables_state(thd);
|
||||
thd->restore_backup_open_tables_state(backup);
|
||||
table= NULL;
|
||||
}
|
||||
}
|
||||
DBUG_ASSERT(table->s->table_category == TABLE_CATEGORY_LOG);
|
||||
/* Make sure all columns get assigned to a default value */
|
||||
table->use_all_columns();
|
||||
DBUG_ASSERT(table->s->no_replicate);
|
||||
}
|
||||
else
|
||||
thd->restore_backup_open_tables_state(backup);
|
||||
|
@ -1174,7 +1174,7 @@ public:
|
||||
|
||||
void copy_non_errors_from_wi(THD *thd, const Warning_info *src_wi);
|
||||
|
||||
protected:
|
||||
private:
|
||||
Warning_info *get_warning_info() { return m_wi_stack.front(); }
|
||||
|
||||
const Warning_info *get_warning_info() const { return m_wi_stack.front(); }
|
||||
|
@ -7446,20 +7446,6 @@ int set_statement_var_if_exists(THD *thd, const char *var_name,
|
||||
}
|
||||
|
||||
|
||||
Query_tables_backup::Query_tables_backup(THD* _thd) :
|
||||
thd(_thd)
|
||||
{
|
||||
thd->lex->reset_n_backup_query_tables_list(&backup);
|
||||
thd->lex->sql_command= backup.sql_command;
|
||||
}
|
||||
|
||||
|
||||
Query_tables_backup::~Query_tables_backup()
|
||||
{
|
||||
thd->lex->restore_backup_query_tables_list(&backup);
|
||||
}
|
||||
|
||||
|
||||
bool LEX::sp_add_cfetch(THD *thd, const LEX_CSTRING *name)
|
||||
{
|
||||
uint offset;
|
||||
|
@ -1983,18 +1983,6 @@ private:
|
||||
};
|
||||
|
||||
|
||||
class Query_tables_backup
|
||||
{
|
||||
THD *thd;
|
||||
Query_tables_list backup;
|
||||
|
||||
public:
|
||||
Query_tables_backup(THD *_thd);
|
||||
~Query_tables_backup();
|
||||
const Query_tables_list& get() const { return backup; }
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
st_parsing_options contains the flags for constructions that are
|
||||
allowed in the current statement.
|
||||
|
@ -111,7 +111,6 @@
|
||||
|
||||
#include "wsrep_mysqld.h"
|
||||
#include "wsrep_thd.h"
|
||||
#include "vtmd.h"
|
||||
|
||||
static void wsrep_mysql_parse(THD *thd, char *rawbuf, uint length,
|
||||
Parser_state *parser_state,
|
||||
@ -3182,11 +3181,6 @@ bool Sql_cmd_call::execute(THD *thd)
|
||||
if (do_execute_sp(thd, sp))
|
||||
return true;
|
||||
|
||||
if (sp->sp_cache_version() == 0)
|
||||
{
|
||||
sp_cache_flush(thd->sp_proc_cache, sp);
|
||||
}
|
||||
|
||||
/*
|
||||
Disable slow log for the above call(), if calls are disabled.
|
||||
Instead we will log the executed statements to the slow log.
|
||||
@ -6459,21 +6453,6 @@ static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables)
|
||||
(ulonglong) thd->variables.select_limit);
|
||||
}
|
||||
|
||||
if (thd->variables.vers_alter_history == VERS_ALTER_HISTORY_SURVIVE)
|
||||
{
|
||||
for (TABLE_LIST *table= all_tables; table; table= table->next_local)
|
||||
{
|
||||
if (table->vers_conditions)
|
||||
{
|
||||
VTMD_exists vtmd(*table);
|
||||
if (vtmd.check_exists(thd))
|
||||
return 1;
|
||||
if (vtmd.exists && vtmd.setup_select(thd))
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!(res= open_and_lock_tables(thd, all_tables, TRUE, 0)))
|
||||
{
|
||||
if (lex->describe)
|
||||
|
@ -30,7 +30,6 @@
|
||||
#include "sql_base.h" // tdc_remove_table, lock_table_names,
|
||||
#include "sql_handler.h" // mysql_ha_rm_tables
|
||||
#include "sql_statistics.h"
|
||||
#include "vtmd.h"
|
||||
|
||||
static TABLE_LIST *rename_tables(THD *thd, TABLE_LIST *table_list,
|
||||
bool skip_error);
|
||||
@ -298,22 +297,12 @@ do_rename(THD *thd, TABLE_LIST *ren_table, const LEX_CSTRING *new_db,
|
||||
(void) rename_table_in_stat_tables(thd, &ren_table->db,
|
||||
&ren_table->table_name,
|
||||
new_db, &new_alias);
|
||||
VTMD_rename vtmd(*ren_table);
|
||||
if (thd->variables.vers_alter_history == VERS_ALTER_HISTORY_SURVIVE)
|
||||
{
|
||||
rc= vtmd.try_rename(thd, new_db->str, new_alias.str);
|
||||
if (rc)
|
||||
goto revert_table_name;
|
||||
}
|
||||
if ((rc= Table_triggers_list::change_table_name(thd, &ren_table->db,
|
||||
&old_alias,
|
||||
&ren_table->table_name,
|
||||
new_db,
|
||||
&new_alias)))
|
||||
{
|
||||
if (thd->variables.vers_alter_history == VERS_ALTER_HISTORY_SURVIVE)
|
||||
vtmd.revert_rename(thd, new_db->str);
|
||||
revert_table_name:
|
||||
/*
|
||||
We've succeeded in renaming table's .frm and in updating
|
||||
corresponding handler data, but have failed to update table's
|
||||
|
@ -62,7 +62,6 @@
|
||||
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||
#include "ha_partition.h"
|
||||
#endif
|
||||
#include "vtmd.h"
|
||||
#include "transaction.h"
|
||||
|
||||
enum enum_i_s_events_fields
|
||||
@ -1369,14 +1368,6 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list)
|
||||
MDL_savepoint mdl_savepoint= thd->mdl_context.mdl_savepoint();
|
||||
|
||||
TABLE_LIST archive;
|
||||
bool versioned= table_list->vers_conditions;
|
||||
if (versioned)
|
||||
{
|
||||
DBUG_ASSERT(table_list->vers_conditions == SYSTEM_TIME_AS_OF);
|
||||
VTMD_table vtmd(*table_list);
|
||||
if (vtmd.setup_select(thd))
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (mysqld_show_create_get_fields(thd, table_list, &field_list, &buffer))
|
||||
goto exit;
|
||||
@ -1418,13 +1409,6 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list)
|
||||
my_eof(thd);
|
||||
|
||||
exit:
|
||||
if (versioned)
|
||||
{
|
||||
/* If commit fails, we should be able to reset the OK status. */
|
||||
thd->get_stmt_da()->set_overwrite_status(true);
|
||||
trans_commit_stmt(thd);
|
||||
thd->get_stmt_da()->set_overwrite_status(false);
|
||||
}
|
||||
close_thread_tables(thd);
|
||||
/* Release any metadata locks taken during SHOW CREATE. */
|
||||
thd->mdl_context.rollback_to_savepoint(mdl_savepoint);
|
||||
@ -2150,7 +2134,7 @@ int show_create_table(THD *thd, TABLE_LIST *table_list, String *packet,
|
||||
}
|
||||
else
|
||||
{
|
||||
if (lower_case_table_names == 2 || table_list->vers_force_alias)
|
||||
if (lower_case_table_names == 2)
|
||||
{
|
||||
alias.str= table->alias.c_ptr();
|
||||
alias.length= table->alias.length();
|
||||
@ -4380,7 +4364,7 @@ int schema_tables_add(THD *thd, Dynamic_array<LEX_CSTRING*> *files,
|
||||
@retval 2 Not fatal error; Safe to ignore this file list
|
||||
*/
|
||||
|
||||
int
|
||||
static int
|
||||
make_table_name_list(THD *thd, Dynamic_array<LEX_CSTRING*> *table_names,
|
||||
LEX *lex, LOOKUP_FIELD_VALUES *lookup_field_vals,
|
||||
LEX_CSTRING *db_name)
|
||||
@ -5032,60 +5016,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
static bool get_all_archive_tables(THD *thd,
|
||||
Dynamic_array<String> &all_archive_tables)
|
||||
{
|
||||
if (thd->variables.vers_alter_history != VERS_ALTER_HISTORY_SURVIVE)
|
||||
return false;
|
||||
|
||||
Dynamic_array<LEX_CSTRING *> all_db;
|
||||
LOOKUP_FIELD_VALUES lookup_field_values= {
|
||||
{C_STRING_WITH_LEN("%")}, {NULL, 0}, true, false};
|
||||
if (make_db_list(thd, &all_db, &lookup_field_values))
|
||||
return true;
|
||||
|
||||
LEX_STRING information_schema= {C_STRING_WITH_LEN("information_schema")};
|
||||
for (size_t i= 0; i < all_db.elements(); i++)
|
||||
{
|
||||
LEX_CSTRING db= *all_db.at(i);
|
||||
if (db.length == information_schema.length &&
|
||||
!memcmp(db.str, information_schema.str, db.length))
|
||||
{
|
||||
all_db.del(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i= 0; i < all_db.elements(); i++)
|
||||
{
|
||||
LEX_CSTRING db_name= *all_db.at(i);
|
||||
Dynamic_array<String> archive_tables;
|
||||
if (VTMD_table::get_archive_tables(thd, db_name.str, db_name.length,
|
||||
archive_tables))
|
||||
return true;
|
||||
for (size_t i= 0; i < archive_tables.elements(); i++)
|
||||
if (all_archive_tables.push(archive_tables.at(i)))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool is_archive_table(const Dynamic_array<String> &all_archive_tables,
|
||||
const LEX_CSTRING candidate)
|
||||
{
|
||||
for (size_t i= 0; i < all_archive_tables.elements(); i++)
|
||||
{
|
||||
const String &archive_table= all_archive_tables.at(i);
|
||||
if (candidate.length == archive_table.length() &&
|
||||
!memcmp(candidate.str, archive_table.ptr(), candidate.length))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Fill I_S tables whose data are retrieved
|
||||
from frm files and storage engine
|
||||
@ -5127,7 +5057,6 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
|
||||
#endif
|
||||
uint table_open_method= tables->table_open_method;
|
||||
bool can_deadlock;
|
||||
Dynamic_array<String> all_archive_tables;
|
||||
MEM_ROOT tmp_mem_root;
|
||||
DBUG_ENTER("get_all_tables");
|
||||
|
||||
@ -5187,9 +5116,6 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
|
||||
if (make_db_list(thd, &db_names, &plan->lookup_field_vals))
|
||||
goto err;
|
||||
|
||||
if (get_all_archive_tables(thd, all_archive_tables))
|
||||
goto err;
|
||||
|
||||
/* Use tmp_mem_root to allocate data for opened tables */
|
||||
init_alloc_root(&tmp_mem_root, "get_all_tables", SHOW_ALLOC_BLOCK_SIZE,
|
||||
SHOW_ALLOC_BLOCK_SIZE, MY_THREAD_SPECIFIC);
|
||||
@ -5219,9 +5145,6 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
|
||||
LEX_CSTRING *table_name= table_names.at(i);
|
||||
DBUG_ASSERT(table_name->length <= NAME_LEN);
|
||||
|
||||
if (is_archive_table(all_archive_tables, *table_name))
|
||||
continue;
|
||||
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
if (!(thd->col_access & TABLE_ACLS))
|
||||
{
|
||||
|
@ -203,10 +203,6 @@ typedef struct st_lookup_field_values
|
||||
bool wild_table_value;
|
||||
} LOOKUP_FIELD_VALUES;
|
||||
|
||||
int make_table_name_list(THD *thd, Dynamic_array<LEX_CSTRING *> *table_names,
|
||||
LEX *lex, LOOKUP_FIELD_VALUES *lookup_field_vals,
|
||||
LEX_CSTRING *db_name);
|
||||
|
||||
/*
|
||||
INFORMATION_SCHEMA: Execution plan for get_all_tables() call
|
||||
*/
|
||||
|
269
sql/sql_table.cc
269
sql/sql_table.cc
@ -56,7 +56,6 @@
|
||||
#include "sql_audit.h"
|
||||
#include "sql_sequence.h"
|
||||
#include "tztime.h"
|
||||
#include "vtmd.h" // System Versioning
|
||||
|
||||
|
||||
#ifdef __WIN__
|
||||
@ -2313,7 +2312,6 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
|
||||
bool table_creation_was_logged= 1;
|
||||
LEX_CSTRING db= table->db;
|
||||
handlerton *table_type= 0;
|
||||
VTMD_drop vtmd(*table);
|
||||
|
||||
DBUG_PRINT("table", ("table_l: '%s'.'%s' table: %p s: %p",
|
||||
table->db.str, table->table_name.str, table->table,
|
||||
@ -2511,47 +2509,26 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
|
||||
// Remove extension for delete
|
||||
*(end= path + path_length - reg_ext_length)= '\0';
|
||||
|
||||
if ((thd->lex->sql_command == SQLCOM_DROP_TABLE ||
|
||||
thd->lex->sql_command == SQLCOM_CREATE_TABLE) &&
|
||||
thd->variables.vers_alter_history == VERS_ALTER_HISTORY_SURVIVE &&
|
||||
table_type && table_type != view_pseudo_hton)
|
||||
error= ha_delete_table(thd, table_type, path, &db, &table->table_name,
|
||||
!dont_log_query);
|
||||
if (!error)
|
||||
{
|
||||
error= vtmd.check_exists(thd);
|
||||
if (error)
|
||||
goto non_tmp_err;
|
||||
if (!vtmd.exists)
|
||||
goto drop_table;
|
||||
/* Delete the table definition file */
|
||||
strmov(end,reg_ext);
|
||||
if (table_type && table_type != view_pseudo_hton &&
|
||||
table_type->discover_table)
|
||||
{
|
||||
const char *name= vtmd.archive_name(thd);
|
||||
LEX_CSTRING new_name= { name, strlen(name) };
|
||||
error= mysql_rename_table(table_type, &table->db, &table->table_name,
|
||||
&table->db, &new_name, NO_FK_CHECKS);
|
||||
/*
|
||||
Table type is using discovery and may not need a .frm file.
|
||||
Delete it silently if it exists
|
||||
*/
|
||||
(void) mysql_file_delete(key_file_frm, path, MYF(0));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
drop_table:
|
||||
error= ha_delete_table(thd, table_type, path, &db, &table->table_name,
|
||||
!dont_log_query);
|
||||
if (!error)
|
||||
else if (mysql_file_delete(key_file_frm, path,
|
||||
MYF(MY_WME)))
|
||||
{
|
||||
/* Delete the table definition file */
|
||||
strmov(end,reg_ext);
|
||||
if (table_type && table_type != view_pseudo_hton &&
|
||||
table_type->discover_table)
|
||||
{
|
||||
/*
|
||||
Table type is using discovery and may not need a .frm file.
|
||||
Delete it silently if it exists
|
||||
*/
|
||||
(void) mysql_file_delete(key_file_frm, path, MYF(0));
|
||||
}
|
||||
else if (mysql_file_delete(key_file_frm, path,
|
||||
MYF(MY_WME)))
|
||||
{
|
||||
frm_delete_error= my_errno;
|
||||
DBUG_ASSERT(frm_delete_error);
|
||||
}
|
||||
frm_delete_error= my_errno;
|
||||
DBUG_ASSERT(frm_delete_error);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2572,26 +2549,9 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
|
||||
else if (frm_delete_error && if_exists)
|
||||
thd->clear_error();
|
||||
}
|
||||
non_tmp_err:
|
||||
non_tmp_error|= MY_TEST(error);
|
||||
}
|
||||
|
||||
if (!error && vtmd.exists)
|
||||
{
|
||||
enum_sql_command sql_command= thd->lex->sql_command;
|
||||
thd->lex->sql_command= SQLCOM_DROP_TABLE;
|
||||
error= vtmd.update(thd);
|
||||
thd->lex->sql_command= sql_command;
|
||||
if (error)
|
||||
{
|
||||
LEX_CSTRING archive_name;
|
||||
archive_name.str= vtmd.archive_name();
|
||||
archive_name.length= strlen(archive_name.str);
|
||||
mysql_rename_table(table_type, &table->db, &archive_name,
|
||||
&table->db, &table->table_name, NO_FK_CHECKS);
|
||||
}
|
||||
}
|
||||
|
||||
if (error)
|
||||
{
|
||||
if (wrong_tables.length())
|
||||
@ -5227,20 +5187,6 @@ bool mysql_create_table(THD *thd, TABLE_LIST *create_table,
|
||||
}
|
||||
}
|
||||
|
||||
if (create_info->versioned() &&
|
||||
thd->variables.vers_alter_history == VERS_ALTER_HISTORY_SURVIVE)
|
||||
{
|
||||
VTMD_table vtmd(*create_table);
|
||||
if (vtmd.update(thd))
|
||||
{
|
||||
thd->variables.vers_alter_history = VERS_ALTER_HISTORY_KEEP;
|
||||
mysql_rm_table_no_locks(thd, create_table, 0, 0, 0, 0, 1, 1);
|
||||
thd->variables.vers_alter_history = VERS_ALTER_HISTORY_SURVIVE;
|
||||
result= 1;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
err:
|
||||
/* In RBR we don't need to log CREATE TEMPORARY TABLE */
|
||||
if (thd->is_current_stmt_binlog_format_row() && create_info->tmp_table())
|
||||
@ -5405,59 +5351,6 @@ bool operator!=(const MYSQL_TIME &lhs, const MYSQL_TIME &rhs)
|
||||
lhs.time_type != rhs.time_type;
|
||||
}
|
||||
|
||||
// Sets row_end=MAX for rows with row_end=now(6)
|
||||
static bool vers_reset_alter_copy(THD *thd, TABLE *table)
|
||||
{
|
||||
const MYSQL_TIME query_start= thd->query_start_TIME();
|
||||
|
||||
READ_RECORD info;
|
||||
int error= 0;
|
||||
bool will_batch= false;
|
||||
ha_rows dup_key_found= 0;
|
||||
if (init_read_record(&info, thd, table, NULL, NULL, 0, 1, true))
|
||||
goto err;
|
||||
|
||||
will_batch= !table->file->start_bulk_update();
|
||||
|
||||
while (!(error= info.read_record()))
|
||||
{
|
||||
MYSQL_TIME current;
|
||||
if (table->vers_end_field()->get_date(¤t, 0))
|
||||
goto err_read_record;
|
||||
if (current != query_start)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
store_record(table, record[1]);
|
||||
table->vers_end_field()->set_max();
|
||||
if (will_batch)
|
||||
error= table->file->ha_bulk_update_row(table->record[1], table->record[0],
|
||||
&dup_key_found);
|
||||
else
|
||||
error= table->file->ha_update_row(table->record[1], table->record[0]);
|
||||
if (error && table->file->is_fatal_error(error, HA_CHECK_ALL))
|
||||
{
|
||||
table->file->print_error(error, MYF(ME_FATALERROR));
|
||||
goto err_read_record;
|
||||
}
|
||||
}
|
||||
|
||||
if (will_batch && (error= table->file->exec_bulk_update(&dup_key_found)))
|
||||
table->file->print_error(error, MYF(ME_FATALERROR));
|
||||
if (will_batch)
|
||||
table->file->end_bulk_update();
|
||||
|
||||
err_read_record:
|
||||
end_read_record(&info);
|
||||
|
||||
err:
|
||||
if (table->file->ha_external_lock(thd, F_UNLCK))
|
||||
return true;
|
||||
|
||||
return error ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
Rename a table.
|
||||
|
||||
@ -6609,9 +6502,6 @@ static bool fill_alter_inplace_info(THD *thd,
|
||||
if (table->s->frm_version < FRM_VER_TRUE_VARCHAR && varchar)
|
||||
ha_alter_info->handler_flags|= ALTER_STORED_COLUMN_TYPE;
|
||||
|
||||
if (thd->variables.vers_alter_history == VERS_ALTER_HISTORY_DROP)
|
||||
ha_alter_info->handler_flags|= ALTER_DROP_HISTORICAL;
|
||||
|
||||
DBUG_PRINT("info", ("handler_flags: %llu", ha_alter_info->handler_flags));
|
||||
|
||||
/*
|
||||
@ -8994,29 +8884,18 @@ simple_rename_or_index_change(THD *thd, TABLE_LIST *table_list,
|
||||
if (mysql_rename_table(old_db_type, &alter_ctx->db, &alter_ctx->table_name,
|
||||
&alter_ctx->new_db, &alter_ctx->new_alias, 0))
|
||||
error= -1;
|
||||
else
|
||||
{
|
||||
VTMD_rename vtmd(*table_list);
|
||||
if (thd->variables.vers_alter_history == VERS_ALTER_HISTORY_SURVIVE &&
|
||||
vtmd.try_rename(thd, alter_ctx->new_db.str, alter_ctx->new_alias.str))
|
||||
goto revert_table_name;
|
||||
|
||||
if (Table_triggers_list::change_table_name(thd,
|
||||
else if (Table_triggers_list::change_table_name(thd,
|
||||
&alter_ctx->db,
|
||||
&alter_ctx->alias,
|
||||
&alter_ctx->table_name,
|
||||
&alter_ctx->new_db,
|
||||
&alter_ctx->new_alias))
|
||||
{
|
||||
if (thd->variables.vers_alter_history == VERS_ALTER_HISTORY_SURVIVE)
|
||||
vtmd.revert_rename(thd, alter_ctx->new_db.str);
|
||||
revert_table_name:
|
||||
(void) mysql_rename_table(old_db_type,
|
||||
&alter_ctx->new_db, &alter_ctx->new_alias,
|
||||
&alter_ctx->db, &alter_ctx->table_name,
|
||||
NO_FK_CHECKS);
|
||||
error= -1;
|
||||
}
|
||||
{
|
||||
(void) mysql_rename_table(old_db_type,
|
||||
&alter_ctx->new_db, &alter_ctx->new_alias,
|
||||
&alter_ctx->db, &alter_ctx->table_name,
|
||||
NO_FK_CHECKS);
|
||||
error= -1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -9150,7 +9029,6 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db, const LEX_CSTRING *n
|
||||
|
||||
TABLE *table= table_list->table;
|
||||
bool versioned= table && table->versioned();
|
||||
bool vers_survival_mod= false;
|
||||
|
||||
if (versioned)
|
||||
{
|
||||
@ -9166,13 +9044,8 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db, const LEX_CSTRING *n
|
||||
DBUG_RETURN(true);
|
||||
}
|
||||
}
|
||||
bool vers_data_mod= alter_info->data_modifying();
|
||||
if (thd->variables.vers_alter_history == VERS_ALTER_HISTORY_SURVIVE)
|
||||
{
|
||||
vers_survival_mod= alter_info->data_modifying() || alter_info->partition_modifying();
|
||||
}
|
||||
else if (vers_data_mod && !thd->slave_thread &&
|
||||
thd->variables.vers_alter_history == VERS_ALTER_HISTORY_ERROR)
|
||||
if (alter_info->data_modifying() && !thd->slave_thread &&
|
||||
thd->variables.vers_alter_history == VERS_ALTER_HISTORY_ERROR)
|
||||
{
|
||||
my_error(ER_VERS_ALTER_NOT_ALLOWED, MYF(0),
|
||||
table_list->db.str, table_list->table_name.str);
|
||||
@ -9180,26 +9053,6 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db, const LEX_CSTRING *n
|
||||
}
|
||||
}
|
||||
|
||||
if (vers_survival_mod)
|
||||
{
|
||||
table_list->set_lock_type(thd, TL_WRITE);
|
||||
if (thd->mdl_context.upgrade_shared_lock(table_list->table->mdl_ticket,
|
||||
MDL_EXCLUSIVE,
|
||||
thd->variables.lock_wait_timeout))
|
||||
{
|
||||
DBUG_RETURN(true);
|
||||
}
|
||||
|
||||
if (table_list->table->versioned(VERS_TRX_ID) &&
|
||||
alter_info->requested_algorithm ==
|
||||
Alter_info::ALTER_TABLE_ALGORITHM_DEFAULT &&
|
||||
IF_PARTITIONING(!table_list->table->s->partition_info_str, 1))
|
||||
{
|
||||
// Changle default ALGORITHM to COPY for INNODB
|
||||
alter_info->requested_algorithm= Alter_info::ALTER_TABLE_ALGORITHM_COPY;
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG_SYNC(thd, "alter_opened_table");
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
@ -9509,9 +9362,7 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db, const LEX_CSTRING *n
|
||||
Upgrade from MDL_SHARED_UPGRADABLE to MDL_SHARED_NO_WRITE.
|
||||
Afterwards it's safe to take the table level lock.
|
||||
*/
|
||||
if ((!vers_survival_mod &&
|
||||
thd->mdl_context.upgrade_shared_lock(
|
||||
mdl_ticket, MDL_SHARED_NO_WRITE,
|
||||
if ((thd->mdl_context.upgrade_shared_lock(mdl_ticket, MDL_SHARED_NO_WRITE,
|
||||
thd->variables.lock_wait_timeout)) ||
|
||||
lock_tables(thd, table_list, alter_ctx.tables_opened, 0))
|
||||
{
|
||||
@ -9575,7 +9426,6 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db, const LEX_CSTRING *n
|
||||
handlerton *new_db_type= create_info->db_type;
|
||||
handlerton *old_db_type= table->s->db_type();
|
||||
TABLE *new_table= NULL;
|
||||
bool new_versioned= false;
|
||||
ha_rows copied=0,deleted=0;
|
||||
|
||||
/*
|
||||
@ -9925,7 +9775,6 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db, const LEX_CSTRING *n
|
||||
if (!new_table)
|
||||
goto err_new_table_cleanup;
|
||||
new_table->s->orig_table_name= table->s->table_name.str;
|
||||
new_versioned= new_table->versioned();
|
||||
/*
|
||||
Note: In case of MERGE table, we do not attach children. We do not
|
||||
copy data for MERGE tables. Only the children have data.
|
||||
@ -9953,11 +9802,6 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db, const LEX_CSTRING *n
|
||||
alter_info->keys_onoff,
|
||||
&alter_ctx))
|
||||
{
|
||||
if (vers_survival_mod && new_versioned && table->versioned(VERS_TIMESTAMP))
|
||||
{
|
||||
// Failure of this function may result in corruption of an original table.
|
||||
vers_reset_alter_copy(thd, table);
|
||||
}
|
||||
goto err_new_table_cleanup;
|
||||
}
|
||||
}
|
||||
@ -10058,15 +9902,8 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db, const LEX_CSTRING *n
|
||||
LEX_CSTRING backup_name;
|
||||
backup_name.str= backup_name_buff;
|
||||
|
||||
if (vers_survival_mod)
|
||||
{
|
||||
VTMD_table::archive_name(thd, alter_ctx.table_name.str, backup_name_buff,
|
||||
sizeof(backup_name_buff));
|
||||
backup_name.length= strlen(backup_name_buff);
|
||||
}
|
||||
else
|
||||
backup_name.length= my_snprintf(backup_name_buff, sizeof(backup_name_buff),
|
||||
"%s2-%lx-%lx", tmp_file_prefix,
|
||||
backup_name.length= my_snprintf(backup_name_buff, sizeof(backup_name_buff),
|
||||
"%s2-%lx-%lx", tmp_file_prefix,
|
||||
current_pid, (long) thd->thread_id);
|
||||
if (lower_case_table_names)
|
||||
my_casedn_str(files_charset_info, backup_name_buff);
|
||||
@ -10095,17 +9932,6 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db, const LEX_CSTRING *n
|
||||
goto err_with_mdl;
|
||||
}
|
||||
|
||||
if (vers_survival_mod && new_versioned)
|
||||
{
|
||||
DBUG_ASSERT(alter_info && table_list);
|
||||
VTMD_rename vtmd(*table_list);
|
||||
bool rc= alter_info->flags & ALTER_RENAME ?
|
||||
vtmd.try_rename(thd, alter_ctx.new_db.str, alter_ctx.new_alias.str, backup_name.str) :
|
||||
vtmd.update(thd, backup_name.str);
|
||||
if (rc)
|
||||
goto err_after_rename;
|
||||
}
|
||||
|
||||
// Check if we renamed the table and if so update trigger files.
|
||||
if (alter_ctx.is_table_renamed())
|
||||
{
|
||||
@ -10116,7 +9942,6 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db, const LEX_CSTRING *n
|
||||
&alter_ctx.new_db,
|
||||
&alter_ctx.new_alias))
|
||||
{
|
||||
err_after_rename:
|
||||
// Rename succeeded, delete the new table.
|
||||
(void) quick_rm_table(thd, new_db_type,
|
||||
&alter_ctx.new_db, &alter_ctx.new_alias, 0);
|
||||
@ -10131,8 +9956,7 @@ err_after_rename:
|
||||
}
|
||||
|
||||
// ALTER TABLE succeeded, delete the backup of the old table.
|
||||
if (!(vers_survival_mod && new_versioned) &&
|
||||
quick_rm_table(thd, old_db_type, &alter_ctx.db, &backup_name, FN_IS_TMP))
|
||||
if (quick_rm_table(thd, old_db_type, &alter_ctx.db, &backup_name, FN_IS_TMP))
|
||||
{
|
||||
/*
|
||||
The fact that deletion of the backup failed is not critical
|
||||
@ -10322,6 +10146,7 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to,
|
||||
bool make_versioned= !from->versioned() && to->versioned();
|
||||
bool make_unversioned= from->versioned() && !to->versioned();
|
||||
bool keep_versioned= from->versioned() && to->versioned();
|
||||
bool drop_history= false; // XXX
|
||||
Field *to_row_start= NULL, *to_row_end= NULL, *from_row_end= NULL;
|
||||
MYSQL_TIME query_start;
|
||||
DBUG_ENTER("copy_data_between_tables");
|
||||
@ -10434,17 +10259,9 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to,
|
||||
{
|
||||
from_row_end= from->vers_end_field();
|
||||
}
|
||||
else if (keep_versioned)
|
||||
else if (keep_versioned && drop_history)
|
||||
{
|
||||
if (thd->variables.vers_alter_history == VERS_ALTER_HISTORY_SURVIVE)
|
||||
{
|
||||
query_start= thd->query_start_TIME();
|
||||
from_row_end= from->vers_end_field();
|
||||
to_row_start= to->vers_start_field();
|
||||
} else if (thd->variables.vers_alter_history == VERS_ALTER_HISTORY_DROP)
|
||||
{
|
||||
from_row_end= from->vers_end_field();
|
||||
}
|
||||
from_row_end= from->vers_end_field();
|
||||
}
|
||||
|
||||
THD_STAGE_INFO(thd, stage_copy_to_tmp_table);
|
||||
@ -10503,11 +10320,8 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to,
|
||||
copy_ptr->do_copy(copy_ptr);
|
||||
}
|
||||
|
||||
if (thd->variables.vers_alter_history == VERS_ALTER_HISTORY_DROP &&
|
||||
from_row_end && !from_row_end->is_max())
|
||||
{
|
||||
if (drop_history && from_row_end && !from_row_end->is_max())
|
||||
continue;
|
||||
}
|
||||
|
||||
if (make_versioned)
|
||||
{
|
||||
@ -10520,17 +10334,6 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to,
|
||||
if (!from_row_end->is_max())
|
||||
continue; // Drop history rows.
|
||||
}
|
||||
else if (keep_versioned &&
|
||||
thd->variables.vers_alter_history == VERS_ALTER_HISTORY_SURVIVE)
|
||||
{
|
||||
if (!from_row_end->is_max())
|
||||
continue; // Do not copy history rows.
|
||||
|
||||
store_record(from, record[1]);
|
||||
from->vers_end_field()->store_time(&query_start);
|
||||
from->file->ha_update_row(from->record[1], from->record[0]);
|
||||
to_row_start->store_time(&query_start);
|
||||
}
|
||||
|
||||
prev_insert_id= to->file->next_insert_id;
|
||||
if (to->default_field)
|
||||
@ -10546,11 +10349,9 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to,
|
||||
error= 1;
|
||||
break;
|
||||
}
|
||||
if (keep_versioned && to->versioned(VERS_TRX_ID) &&
|
||||
thd->variables.vers_alter_history != VERS_ALTER_HISTORY_SURVIVE)
|
||||
{
|
||||
if (keep_versioned && to->versioned(VERS_TRX_ID))
|
||||
to->vers_write= false;
|
||||
}
|
||||
|
||||
error= to->file->ha_write_row(to->record[0]);
|
||||
to->auto_increment_field_not_null= FALSE;
|
||||
if (error)
|
||||
|
@ -13832,21 +13832,13 @@ show_param:
|
||||
Lex->set_command(SQLCOM_SHOW_CREATE_DB, $3);
|
||||
Lex->name= $4;
|
||||
}
|
||||
| CREATE TABLE_SYM table_ident opt_for_system_time_clause
|
||||
| CREATE TABLE_SYM table_ident
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
lex->sql_command = SQLCOM_SHOW_CREATE;
|
||||
if (!lex->select_lex.add_table_to_list(thd, $3, NULL,0))
|
||||
MYSQL_YYABORT;
|
||||
lex->create_info.storage_media= HA_SM_DEFAULT;
|
||||
|
||||
if (lex->vers_conditions.type != SYSTEM_TIME_UNSPECIFIED &&
|
||||
lex->vers_conditions.type != SYSTEM_TIME_AS_OF)
|
||||
{
|
||||
my_yyabort_error((ER_VERS_RANGE_PROHIBITED, MYF(0)));
|
||||
}
|
||||
if ($4)
|
||||
Lex->last_table()->vers_conditions= Lex->vers_conditions;
|
||||
}
|
||||
| CREATE VIEW_SYM table_ident
|
||||
{
|
||||
|
@ -396,13 +396,11 @@ static Sys_var_vers_asof Sys_vers_asof_timestamp(
|
||||
SESSION_VAR(vers_asof_timestamp.type), NO_CMD_LINE,
|
||||
Sys_var_vers_asof::asof_keywords, DEFAULT(SYSTEM_TIME_UNSPECIFIED));
|
||||
|
||||
static const char *vers_alter_history_keywords[]= {"ERROR", "KEEP",/* "SURVIVE", "DROP",*/ NULL};
|
||||
static const char *vers_alter_history_keywords[]= {"ERROR", "KEEP", NullS};
|
||||
static Sys_var_enum Sys_vers_alter_history(
|
||||
"system_versioning_alter_history", "Versioning ALTER TABLE mode. "
|
||||
"ERROR: Fail ALTER with error; " /* TODO: fail only when history non-empty */
|
||||
"KEEP: Keep historical system rows and subject them to ALTER; "
|
||||
/*"SURVIVE: Keep historical system rows intact; "
|
||||
"DROP: Drop historical system rows while processing ALTER"*/,
|
||||
"KEEP: Keep historical system rows and subject them to ALTER; ",
|
||||
SESSION_VAR(vers_alter_history), CMD_LINE(REQUIRED_ARG),
|
||||
vers_alter_history_keywords, DEFAULT(VERS_ALTER_HISTORY_ERROR));
|
||||
|
||||
|
35
sql/table.cc
35
sql/table.cc
@ -1198,8 +1198,6 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
|
||||
uint ext_key_parts= 0;
|
||||
plugin_ref se_plugin= 0;
|
||||
const uchar *system_period= 0;
|
||||
bool vtmd_used= false;
|
||||
share->vtmd= false;
|
||||
bool vers_can_native= false;
|
||||
const uchar *extra2_field_flags= 0;
|
||||
size_t extra2_field_flags_length= 0;
|
||||
@ -1302,17 +1300,6 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
|
||||
goto err;
|
||||
system_period = extra2;
|
||||
break;
|
||||
case EXTRA2_VTMD:
|
||||
if (vtmd_used)
|
||||
goto err;
|
||||
share->vtmd= *extra2;
|
||||
if (share->vtmd)
|
||||
{
|
||||
share->table_category= TABLE_CATEGORY_LOG;
|
||||
share->no_replicate= true;
|
||||
}
|
||||
vtmd_used= true;
|
||||
break;
|
||||
case EXTRA2_FIELD_FLAGS:
|
||||
if (extra2_field_flags)
|
||||
goto err;
|
||||
@ -7785,28 +7772,6 @@ void TABLE::vers_update_end()
|
||||
DBUG_ASSERT(0);
|
||||
}
|
||||
|
||||
|
||||
bool TABLE_LIST::vers_vtmd_name(String& out) const
|
||||
{
|
||||
static const char *vtmd_suffix= "_vtmd";
|
||||
static const size_t vtmd_suffix_len= strlen(vtmd_suffix);
|
||||
if (table_name.length > NAME_CHAR_LEN - vtmd_suffix_len)
|
||||
{
|
||||
my_printf_error(ER_VERS_VTMD_ERROR, "Table name is longer than %d characters", MYF(0),
|
||||
int(NAME_CHAR_LEN - vtmd_suffix_len));
|
||||
return true;
|
||||
}
|
||||
out.set(table_name.str, table_name.length, table_alias_charset);
|
||||
if (out.append(vtmd_suffix, vtmd_suffix_len + 1))
|
||||
{
|
||||
my_message(ER_VERS_VTMD_ERROR, "Failed allocate VTMD name", MYF(0));
|
||||
return true;
|
||||
}
|
||||
out.length(out.length() - 1);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Reset markers that fields are being updated
|
||||
*/
|
||||
|
@ -765,7 +765,6 @@ struct TABLE_SHARE
|
||||
*/
|
||||
|
||||
vers_sys_type_t versioned;
|
||||
bool vtmd;
|
||||
uint16 row_start_field;
|
||||
uint16 row_end_field;
|
||||
|
||||
@ -1527,12 +1526,6 @@ public:
|
||||
return versioned(type) ? vers_write : false;
|
||||
}
|
||||
|
||||
bool vers_vtmd() const
|
||||
{
|
||||
DBUG_ASSERT(s);
|
||||
return s->versioned && s->vtmd;
|
||||
}
|
||||
|
||||
Field *vers_start_field() const
|
||||
{
|
||||
DBUG_ASSERT(s && s->versioned);
|
||||
@ -2397,8 +2390,6 @@ struct TABLE_LIST
|
||||
|
||||
/* System Versioning */
|
||||
vers_select_conds_t vers_conditions;
|
||||
bool vers_vtmd_name(String &out) const;
|
||||
bool vers_force_alias;
|
||||
|
||||
/**
|
||||
@brief
|
||||
|
@ -287,11 +287,6 @@ LEX_CUSTRING build_frm_image(THD *thd, const LEX_CSTRING *table,
|
||||
extra2_size+= 1 + 1 + 2 * sizeof(uint16);
|
||||
}
|
||||
|
||||
if (create_info->vtmd())
|
||||
{
|
||||
extra2_size+= 1 + 1 + 1;
|
||||
}
|
||||
|
||||
bool has_extra2_field_flags_= has_extra2_field_flags(create_fields);
|
||||
if (has_extra2_field_flags_)
|
||||
{
|
||||
@ -364,13 +359,6 @@ LEX_CUSTRING build_frm_image(THD *thd, const LEX_CSTRING *table,
|
||||
pos+= sizeof(uint16);
|
||||
}
|
||||
|
||||
if (create_info->vtmd())
|
||||
{
|
||||
*pos++= EXTRA2_VTMD;
|
||||
*pos++= 1;
|
||||
*pos++= 1;
|
||||
}
|
||||
|
||||
if (has_extra2_field_flags_)
|
||||
pos= extra2_write_field_properties(pos, create_fields);
|
||||
|
||||
|
@ -176,7 +176,6 @@ enum extra2_frm_value_type {
|
||||
EXTRA2_DEFAULT_PART_ENGINE=1,
|
||||
EXTRA2_GIS=2,
|
||||
EXTRA2_PERIOD_FOR_SYSTEM_TIME=4,
|
||||
EXTRA2_VTMD=8,
|
||||
|
||||
#define EXTRA2_ENGINE_IMPORTANT 128
|
||||
|
||||
@ -185,8 +184,7 @@ enum extra2_frm_value_type {
|
||||
};
|
||||
|
||||
enum extra2_field_flags {
|
||||
VERS_OPTIMIZED_UPDATE= 1 << INVISIBLE_MAX_BITS,
|
||||
VERS_HIDDEN= 1 << (INVISIBLE_MAX_BITS + 1),
|
||||
VERS_OPTIMIZED_UPDATE= 1 << INVISIBLE_MAX_BITS
|
||||
};
|
||||
|
||||
int rea_create_table(THD *thd, LEX_CUSTRING *frm,
|
||||
|
@ -44,38 +44,4 @@ public:
|
||||
bool acquire_error() const { return error; }
|
||||
};
|
||||
|
||||
|
||||
class Local_da : public Diagnostics_area
|
||||
{
|
||||
THD *thd;
|
||||
uint sql_error;
|
||||
Diagnostics_area *saved_da;
|
||||
|
||||
public:
|
||||
Local_da(THD *_thd, uint _sql_error= 0) :
|
||||
Diagnostics_area(_thd->query_id, false, true),
|
||||
thd(_thd),
|
||||
sql_error(_sql_error),
|
||||
saved_da(_thd->get_stmt_da())
|
||||
{
|
||||
thd->set_stmt_da(this);
|
||||
}
|
||||
~Local_da()
|
||||
{
|
||||
if (saved_da)
|
||||
finish();
|
||||
}
|
||||
void finish()
|
||||
{
|
||||
DBUG_ASSERT(saved_da && thd);
|
||||
thd->set_stmt_da(saved_da);
|
||||
if (is_error())
|
||||
my_error(sql_error ? sql_error : sql_errno(), MYF(0), message());
|
||||
if (warn_count() > error_count())
|
||||
saved_da->copy_non_errors_from_wi(thd, get_warning_info());
|
||||
saved_da= NULL;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif // VERS_UTILS_INCLUDED
|
||||
|
687
sql/vtmd.cc
687
sql/vtmd.cc
@ -1,687 +0,0 @@
|
||||
#include "vtmd.h"
|
||||
#include "sql_base.h"
|
||||
#include "sql_class.h"
|
||||
#include "sql_handler.h" // mysql_ha_rm_tables()
|
||||
#include "sql_table.h"
|
||||
#include "sql_select.h"
|
||||
#include "table_cache.h" // tdc_remove_table()
|
||||
#include "key.h"
|
||||
#include "sql_show.h"
|
||||
#include "sql_parse.h"
|
||||
#include "sql_lex.h"
|
||||
#include "sp_head.h"
|
||||
#include "sp_rcontext.h"
|
||||
|
||||
LString VERS_VTMD_TEMPLATE(C_STRING_WITH_LEN("vtmd_template"));
|
||||
|
||||
bool
|
||||
VTMD_table::create(THD *thd)
|
||||
{
|
||||
Table_specification_st create_info;
|
||||
TABLE_LIST src_table, table;
|
||||
create_info.init(DDL_options_st::OPT_LIKE);
|
||||
create_info.options|= HA_VTMD;
|
||||
create_info.alias.str= vtmd_name.ptr();
|
||||
create_info.alias.length= vtmd_name.length();
|
||||
table.init_one_table(&about.db, &create_info.alias, NULL, TL_READ);
|
||||
src_table.init_one_table(&MYSQL_SCHEMA_NAME, &VERS_VTMD_TEMPLATE,
|
||||
&VERS_VTMD_TEMPLATE, TL_READ);
|
||||
|
||||
Query_tables_backup backup(thd);
|
||||
thd->lex->add_to_query_tables(&src_table);
|
||||
|
||||
MDL_auto_lock mdl_lock(thd, table);
|
||||
if (mdl_lock.acquire_error())
|
||||
return true;
|
||||
|
||||
Reprepare_observer *reprepare_observer= thd->m_reprepare_observer;
|
||||
thd->m_reprepare_observer= NULL;
|
||||
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||
partition_info *work_part_info= thd->work_part_info;
|
||||
thd->work_part_info= NULL;
|
||||
#endif
|
||||
bool rc= mysql_create_like_table(thd, &table, &src_table, &create_info);
|
||||
thd->m_reprepare_observer= reprepare_observer;
|
||||
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||
thd->work_part_info= work_part_info;
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
|
||||
bool
|
||||
VTMD_table::find_record(ulonglong row_end, bool &found)
|
||||
{
|
||||
int error;
|
||||
key_buf_t key;
|
||||
found= false;
|
||||
|
||||
DBUG_ASSERT(vtmd.table);
|
||||
|
||||
if (key.allocate(vtmd.table->s->max_unique_length))
|
||||
return true;
|
||||
|
||||
DBUG_ASSERT(row_end);
|
||||
vtmd.table->vers_end_field()->set_notnull();
|
||||
vtmd.table->vers_end_field()->store(row_end, true);
|
||||
key_copy(key, vtmd.table->record[0], vtmd.table->key_info + IDX_TRX_END, 0);
|
||||
|
||||
error= vtmd.table->file->ha_index_read_idx_map(vtmd.table->record[1], IDX_TRX_END,
|
||||
key,
|
||||
HA_WHOLE_KEY,
|
||||
HA_READ_KEY_EXACT);
|
||||
if (error)
|
||||
{
|
||||
if (error == HA_ERR_RECORD_DELETED || error == HA_ERR_KEY_NOT_FOUND)
|
||||
return false;
|
||||
vtmd.table->file->print_error(error, MYF(0));
|
||||
return true;
|
||||
}
|
||||
|
||||
restore_record(vtmd.table, record[1]);
|
||||
|
||||
found= true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
VTMD_table::open(THD *thd, Local_da &local_da, bool *created)
|
||||
{
|
||||
if (created)
|
||||
*created= false;
|
||||
|
||||
if (0 == vtmd_name.length() && about.vers_vtmd_name(vtmd_name))
|
||||
return true;
|
||||
|
||||
while (true) // max 2 iterations
|
||||
{
|
||||
LEX_CSTRING table_name= { vtmd_name.ptr(), vtmd_name.length() };
|
||||
vtmd.init_one_table(&about.db, &table_name, NULL,
|
||||
TL_WRITE_CONCURRENT_INSERT);
|
||||
|
||||
TABLE *res= open_log_table(thd, &vtmd, &open_tables_backup);
|
||||
if (res)
|
||||
return false;
|
||||
|
||||
if (created && !*created && local_da.is_error() &&
|
||||
local_da.sql_errno() == ER_NO_SUCH_TABLE)
|
||||
{
|
||||
local_da.reset_diagnostics_area();
|
||||
if (create(thd))
|
||||
break;
|
||||
*created= true;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
VTMD_table::update(THD *thd, const char* archive_name)
|
||||
{
|
||||
bool result= true;
|
||||
bool found= false;
|
||||
bool created;
|
||||
int error;
|
||||
size_t an_len= 0;
|
||||
ulonglong save_thd_options;
|
||||
{
|
||||
Local_da local_da(thd, ER_VERS_VTMD_ERROR);
|
||||
|
||||
save_thd_options= thd->variables.option_bits;
|
||||
thd->variables.option_bits&= ~OPTION_BIN_LOG;
|
||||
|
||||
if (open(thd, local_da, &created))
|
||||
goto open_error;
|
||||
|
||||
if (!vtmd.table->versioned())
|
||||
{
|
||||
my_message(ER_VERS_VTMD_ERROR, "VTMD is not versioned", MYF(0));
|
||||
goto quit;
|
||||
}
|
||||
|
||||
if (!created && find_record(ULONGLONG_MAX, found))
|
||||
goto quit;
|
||||
|
||||
if ((error= vtmd.table->file->extra(HA_EXTRA_MARK_AS_LOG_TABLE)))
|
||||
{
|
||||
vtmd.table->file->print_error(error, MYF(0));
|
||||
goto quit;
|
||||
}
|
||||
|
||||
/* Honor next number columns if present */
|
||||
vtmd.table->next_number_field= vtmd.table->found_next_number_field;
|
||||
|
||||
if (vtmd.table->s->fields != FIELD_COUNT)
|
||||
{
|
||||
my_printf_error(ER_VERS_VTMD_ERROR, "`%s.%s` unexpected fields count: %d", MYF(0),
|
||||
vtmd.table->s->db.str, vtmd.table->s->table_name.str, vtmd.table->s->fields);
|
||||
goto quit;
|
||||
}
|
||||
|
||||
if (archive_name)
|
||||
{
|
||||
an_len= strlen(archive_name);
|
||||
vtmd.table->field[FLD_ARCHIVE_NAME]->store(archive_name, an_len, table_alias_charset);
|
||||
vtmd.table->field[FLD_ARCHIVE_NAME]->set_notnull();
|
||||
}
|
||||
else
|
||||
{
|
||||
vtmd.table->field[FLD_ARCHIVE_NAME]->set_null();
|
||||
}
|
||||
vtmd.table->field[FLD_COL_RENAMES]->set_null();
|
||||
|
||||
if (found)
|
||||
{
|
||||
if (thd->lex->sql_command == SQLCOM_CREATE_TABLE)
|
||||
{
|
||||
my_printf_error(ER_VERS_VTMD_ERROR, "`%s.%s` exists and not empty!", MYF(0),
|
||||
vtmd.table->s->db.str, vtmd.table->s->table_name.str);
|
||||
goto quit;
|
||||
}
|
||||
vtmd.table->mark_columns_needed_for_update(); // not needed?
|
||||
if (archive_name)
|
||||
{
|
||||
vtmd.table->vers_write= false;
|
||||
error= vtmd.table->file->ha_update_row(vtmd.table->record[1], vtmd.table->record[0]);
|
||||
vtmd.table->vers_write= true;
|
||||
|
||||
if (!error)
|
||||
{
|
||||
if (thd->lex->sql_command == SQLCOM_DROP_TABLE)
|
||||
{
|
||||
error= vtmd.table->file->ha_delete_row(vtmd.table->record[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
DBUG_ASSERT(thd->lex->sql_command == SQLCOM_ALTER_TABLE);
|
||||
ulonglong row_end= (ulonglong) vtmd.table->vers_start_field()->val_int();
|
||||
store_record(vtmd.table, record[1]);
|
||||
vtmd.table->field[FLD_NAME]->store(about.table_name.str, about.table_name.length, system_charset_info);
|
||||
vtmd.table->field[FLD_NAME]->set_notnull();
|
||||
vtmd.table->field[FLD_ARCHIVE_NAME]->set_null();
|
||||
error= vtmd.table->file->ha_update_row(vtmd.table->record[1], vtmd.table->record[0]);
|
||||
if (error)
|
||||
goto err;
|
||||
|
||||
DBUG_ASSERT(an_len);
|
||||
while (true)
|
||||
{ // fill archive_name of last sequential renames
|
||||
bool found;
|
||||
if (find_record(row_end, found))
|
||||
goto quit;
|
||||
if (!found || !vtmd.table->field[FLD_ARCHIVE_NAME]->is_null())
|
||||
break;
|
||||
|
||||
store_record(vtmd.table, record[1]);
|
||||
vtmd.table->field[FLD_ARCHIVE_NAME]->store(archive_name, an_len, table_alias_charset);
|
||||
vtmd.table->field[FLD_ARCHIVE_NAME]->set_notnull();
|
||||
vtmd.table->vers_write= false;
|
||||
error= vtmd.table->file->ha_update_row(vtmd.table->record[1], vtmd.table->record[0]);
|
||||
vtmd.table->vers_write= true;
|
||||
if (error)
|
||||
goto err;
|
||||
row_end= (ulonglong) vtmd.table->vers_start_field()->val_int();
|
||||
} // while (true)
|
||||
} // else (thd->lex->sql_command != SQLCOM_DROP_TABLE)
|
||||
} // if (!error)
|
||||
} // if (archive_name)
|
||||
else
|
||||
{
|
||||
vtmd.table->field[FLD_NAME]->store(about.table_name.str,
|
||||
about.table_name.length,
|
||||
system_charset_info);
|
||||
vtmd.table->field[FLD_NAME]->set_notnull();
|
||||
error= vtmd.table->file->ha_update_row(vtmd.table->record[1],
|
||||
vtmd.table->record[0]);
|
||||
}
|
||||
} // if (found)
|
||||
else
|
||||
{
|
||||
vtmd.table->field[FLD_NAME]->store(about.table_name.str,
|
||||
about.table_name.length,
|
||||
system_charset_info);
|
||||
vtmd.table->field[FLD_NAME]->set_notnull();
|
||||
vtmd.table->mark_columns_needed_for_insert(); // not needed?
|
||||
error= vtmd.table->file->ha_write_row(vtmd.table->record[0]);
|
||||
}
|
||||
|
||||
if (error)
|
||||
{
|
||||
err:
|
||||
vtmd.table->file->print_error(error, MYF(0));
|
||||
}
|
||||
else
|
||||
result= local_da.is_error();
|
||||
}
|
||||
|
||||
quit:
|
||||
if (!result && vtmd.table->file->ht->prepare_commit_versioned)
|
||||
{
|
||||
DBUG_ASSERT(TR_table::use_transaction_registry); // FIXME: disable survival mode while TRT is disabled
|
||||
TR_table trt(thd, true);
|
||||
ulonglong trx_start_id= 0;
|
||||
ulonglong trx_end_id= vtmd.table->file->ht->prepare_commit_versioned(thd, &trx_start_id);
|
||||
result= trx_end_id && trt.update(trx_start_id, trx_end_id);
|
||||
}
|
||||
|
||||
close_log_table(thd, &open_tables_backup);
|
||||
|
||||
open_error:
|
||||
thd->variables.option_bits= save_thd_options;
|
||||
return result;
|
||||
}
|
||||
|
||||
bool
|
||||
VTMD_rename::move_archives(THD *thd, LString &new_db)
|
||||
{
|
||||
int error;
|
||||
bool rc= false;
|
||||
SString_fs archive;
|
||||
bool end_keyread= false;
|
||||
bool index_end= false;
|
||||
Open_tables_backup open_tables_backup;
|
||||
key_buf_t key;
|
||||
|
||||
LEX_CSTRING table_name= { vtmd_name.ptr(), vtmd_name.length() };
|
||||
vtmd.init_one_table(&about.db, &table_name, NULL, TL_READ);
|
||||
|
||||
TABLE *res= open_log_table(thd, &vtmd, &open_tables_backup);
|
||||
if (!res)
|
||||
return true;
|
||||
|
||||
if (key.allocate(vtmd.table->key_info[IDX_ARCHIVE_NAME].key_length))
|
||||
{
|
||||
close_log_table(thd, &open_tables_backup);
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((error= vtmd.table->file->ha_start_keyread(IDX_ARCHIVE_NAME)))
|
||||
goto err;
|
||||
end_keyread= true;
|
||||
|
||||
if ((error= vtmd.table->file->ha_index_init(IDX_ARCHIVE_NAME, true)))
|
||||
goto err;
|
||||
index_end= true;
|
||||
|
||||
error= vtmd.table->file->ha_index_first(vtmd.table->record[0]);
|
||||
while (!error)
|
||||
{
|
||||
if (!vtmd.table->field[FLD_ARCHIVE_NAME]->is_null())
|
||||
{
|
||||
vtmd.table->field[FLD_ARCHIVE_NAME]->val_str(&archive);
|
||||
key_copy(key,
|
||||
vtmd.table->record[0],
|
||||
&vtmd.table->key_info[IDX_ARCHIVE_NAME],
|
||||
vtmd.table->key_info[IDX_ARCHIVE_NAME].key_length,
|
||||
false);
|
||||
error= vtmd.table->file->ha_index_read_map(
|
||||
vtmd.table->record[0],
|
||||
key,
|
||||
vtmd.table->key_info[IDX_ARCHIVE_NAME].ext_key_part_map,
|
||||
HA_READ_PREFIX_LAST);
|
||||
if (!error)
|
||||
{
|
||||
if ((rc= move_table(thd, archive, new_db)))
|
||||
break;
|
||||
|
||||
error= vtmd.table->file->ha_index_next(vtmd.table->record[0]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
archive.length(0);
|
||||
error= vtmd.table->file->ha_index_next(vtmd.table->record[0]);
|
||||
}
|
||||
}
|
||||
|
||||
if (error && error != HA_ERR_END_OF_FILE)
|
||||
{
|
||||
err:
|
||||
vtmd.table->file->print_error(error, MYF(0));
|
||||
rc= true;
|
||||
}
|
||||
|
||||
if (index_end)
|
||||
vtmd.table->file->ha_index_end();
|
||||
if (end_keyread)
|
||||
vtmd.table->file->ha_end_keyread();
|
||||
|
||||
close_log_table(thd, &open_tables_backup);
|
||||
return rc;
|
||||
}
|
||||
|
||||
bool
|
||||
VTMD_rename::move_table(THD *thd, SString_fs &table_name, LString &new_db)
|
||||
{
|
||||
handlerton *table_hton= NULL;
|
||||
LEX_CSTRING tbl_name= { table_name.ptr(), table_name.length() };
|
||||
LEX_CSTRING db_name= { new_db.ptr(), new_db.length() };
|
||||
if (!ha_table_exists(thd, &about.db, &tbl_name, &table_hton) || !table_hton)
|
||||
{
|
||||
push_warning_printf( thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_VERS_VTMD_ERROR,
|
||||
"`%s.%s` archive doesn't exist",
|
||||
about.db.str, tbl_name.str);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ha_table_exists(thd, &db_name, &tbl_name))
|
||||
{
|
||||
my_printf_error(ER_VERS_VTMD_ERROR, "`%s.%s` archive already exists!",
|
||||
MYF(0),
|
||||
db_name.str, tbl_name.str);
|
||||
return true;
|
||||
}
|
||||
|
||||
TABLE_LIST tl;
|
||||
tl.init_one_table(&about.db, &tbl_name, NULL, TL_WRITE_ONLY);
|
||||
tl.mdl_request.set_type(MDL_EXCLUSIVE);
|
||||
|
||||
mysql_ha_rm_tables(thd, &tl);
|
||||
if (lock_table_names(thd, &tl, 0, thd->variables.lock_wait_timeout, 0))
|
||||
return true;
|
||||
tdc_remove_table(thd, TDC_RT_REMOVE_ALL, about.db.str, table_name, false);
|
||||
|
||||
bool rc= mysql_rename_table(table_hton,
|
||||
&about.db, &tbl_name, &db_name, &tbl_name,
|
||||
NO_FK_CHECKS);
|
||||
if (!rc)
|
||||
query_cache_invalidate3(thd, &tl, 0);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
bool
|
||||
VTMD_rename::try_rename(THD *thd, LString new_db, LString new_alias, const char *archive_name)
|
||||
{
|
||||
Local_da local_da(thd, ER_VERS_VTMD_ERROR);
|
||||
TABLE_LIST new_table;
|
||||
|
||||
if (check_exists(thd))
|
||||
return true;
|
||||
|
||||
LEX_CSTRING new_db_name= { XSTRING_WITH_LEN(new_db) };
|
||||
LEX_CSTRING new_tbl_name= { XSTRING_WITH_LEN(new_alias) };
|
||||
|
||||
new_table.init_one_table(&new_db_name, &new_tbl_name, NULL, TL_READ);
|
||||
|
||||
if (new_table.vers_vtmd_name(vtmd_new_name))
|
||||
return true;
|
||||
|
||||
LEX_CSTRING new_name= { vtmd_new_name.ptr(), vtmd_new_name.length() };
|
||||
|
||||
if (ha_table_exists(thd, &new_db_name, &new_name))
|
||||
{
|
||||
if (exists)
|
||||
{
|
||||
my_printf_error(ER_VERS_VTMD_ERROR, "`%s.%s` table already exists!",
|
||||
MYF(0),
|
||||
new_db_name.str, new_name.str);
|
||||
return true;
|
||||
}
|
||||
push_warning_printf( thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_VERS_VTMD_ERROR,
|
||||
"`%s.%s` table already exists!",
|
||||
new_db_name.str, new_name.str);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!exists)
|
||||
return false;
|
||||
|
||||
bool same_db= true;
|
||||
if (LString_fs(DB_WITH_LEN(about)) != LString_fs(new_db))
|
||||
{
|
||||
// Move archives before VTMD so if the operation is interrupted, it could be continued.
|
||||
if (move_archives(thd, new_db))
|
||||
return true;
|
||||
same_db= false;
|
||||
}
|
||||
|
||||
TABLE_LIST vtmd_tl;
|
||||
LEX_CSTRING table_name= { vtmd_name.ptr(), vtmd_name.length() };
|
||||
vtmd_tl.init_one_table(&about.db, &table_name, NULL, TL_WRITE_ONLY);
|
||||
vtmd_tl.mdl_request.set_type(MDL_EXCLUSIVE);
|
||||
|
||||
mysql_ha_rm_tables(thd, &vtmd_tl);
|
||||
if (lock_table_names(thd, &vtmd_tl, 0, thd->variables.lock_wait_timeout, 0))
|
||||
return true;
|
||||
tdc_remove_table(thd, TDC_RT_REMOVE_ALL, about.db.str, vtmd_name, false);
|
||||
if (local_da.is_error()) // just safety check
|
||||
return true;
|
||||
bool rc= mysql_rename_table(hton, &about.db, &table_name,
|
||||
&new_db_name, &new_name,
|
||||
NO_FK_CHECKS);
|
||||
if (!rc)
|
||||
{
|
||||
query_cache_invalidate3(thd, &vtmd_tl, 0);
|
||||
if (same_db || archive_name ||
|
||||
new_alias != LString(TABLE_NAME_WITH_LEN(about)))
|
||||
{
|
||||
local_da.finish();
|
||||
VTMD_table new_vtmd(new_table);
|
||||
rc= new_vtmd.update(thd, archive_name);
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
bool
|
||||
VTMD_rename::revert_rename(THD *thd, LString new_db)
|
||||
{
|
||||
DBUG_ASSERT(hton);
|
||||
Local_da local_da(thd, ER_VERS_VTMD_ERROR);
|
||||
|
||||
TABLE_LIST vtmd_tl;
|
||||
LEX_CSTRING new_name= { XSTRING_WITH_LEN(vtmd_new_name) };
|
||||
LEX_CSTRING v_name= { XSTRING_WITH_LEN(vtmd_name) };
|
||||
LEX_CSTRING new_db_name= { XSTRING_WITH_LEN(new_db) };
|
||||
|
||||
vtmd_tl.init_one_table(&about.db, &new_name, NULL, TL_WRITE_ONLY);
|
||||
vtmd_tl.mdl_request.set_type(MDL_EXCLUSIVE);
|
||||
mysql_ha_rm_tables(thd, &vtmd_tl);
|
||||
if (lock_table_names(thd, &vtmd_tl, 0, thd->variables.lock_wait_timeout, 0))
|
||||
return true;
|
||||
tdc_remove_table(thd, TDC_RT_REMOVE_ALL, new_db, vtmd_new_name, false);
|
||||
|
||||
bool rc= mysql_rename_table(hton, &new_db_name, &new_name,
|
||||
&new_db_name, &v_name,
|
||||
NO_FK_CHECKS);
|
||||
|
||||
if (!rc)
|
||||
query_cache_invalidate3(thd, &vtmd_tl, 0);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void
|
||||
VTMD_table::archive_name(
|
||||
THD* thd,
|
||||
const char* table_name,
|
||||
char* new_name,
|
||||
size_t new_name_size)
|
||||
{
|
||||
const MYSQL_TIME now= thd->query_start_TIME();
|
||||
my_snprintf(new_name, new_name_size, "%s_%04d%02d%02d_%02d%02d%02d_%06lu",
|
||||
table_name, now.year, now.month, now.day, now.hour, now.minute,
|
||||
now.second, (ulong) now.second_part);
|
||||
}
|
||||
|
||||
bool
|
||||
VTMD_table::find_archive_name(THD *thd, String &out)
|
||||
{
|
||||
READ_RECORD info;
|
||||
int error;
|
||||
SQL_SELECT *select= NULL;
|
||||
COND *conds= NULL;
|
||||
List<TABLE_LIST> dummy;
|
||||
SELECT_LEX &select_lex= thd->lex->select_lex;
|
||||
|
||||
Local_da local_da(thd, ER_VERS_VTMD_ERROR);
|
||||
if (open(thd, local_da))
|
||||
return true;
|
||||
|
||||
Name_resolution_context &ctx= thd->lex->select_lex.context;
|
||||
TABLE_LIST *table_list= ctx.table_list;
|
||||
TABLE_LIST *first_name_resolution_table= ctx.first_name_resolution_table;
|
||||
table_map map = vtmd.table->map;
|
||||
ctx.table_list= &vtmd;
|
||||
ctx.first_name_resolution_table= &vtmd;
|
||||
vtmd.table->map= 1;
|
||||
|
||||
vtmd.vers_conditions= about.vers_conditions;
|
||||
if ((error= select_lex.vers_setup_conds(thd, &vtmd, &conds)) ||
|
||||
(error= setup_conds(thd, &vtmd, dummy, &conds)))
|
||||
goto err;
|
||||
|
||||
select= make_select(vtmd.table, 0, 0, conds, NULL, 0, &error);
|
||||
if (error)
|
||||
goto loc_err;
|
||||
|
||||
error= init_read_record(&info, thd, vtmd.table, select, NULL,
|
||||
1 /* use_record_cache */, true /* print_error */,
|
||||
false /* disable_rr_cache */);
|
||||
if (error)
|
||||
goto loc_err;
|
||||
|
||||
while (!(error= info.read_record()) && !thd->killed && !thd->is_error())
|
||||
{
|
||||
if (!select || select->skip_record(thd) > 0)
|
||||
{
|
||||
vtmd.table->field[FLD_ARCHIVE_NAME]->val_str(&out);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (error < 0)
|
||||
my_error(ER_NO_SUCH_TABLE, MYF(0), about.db.str, about.alias.str);
|
||||
|
||||
loc_err:
|
||||
end_read_record(&info);
|
||||
err:
|
||||
delete select;
|
||||
ctx.table_list= table_list;
|
||||
ctx.first_name_resolution_table= first_name_resolution_table;
|
||||
vtmd.table->map= map;
|
||||
close_log_table(thd, &open_tables_backup);
|
||||
DBUG_ASSERT(!error || local_da.is_error());
|
||||
return error;
|
||||
}
|
||||
|
||||
static
|
||||
bool
|
||||
get_vtmd_tables(THD *thd, const char *db,
|
||||
size_t db_length, Dynamic_array<LEX_CSTRING *> &table_names)
|
||||
{
|
||||
LOOKUP_FIELD_VALUES lookup_field_values= {
|
||||
{db, db_length}, {C_STRING_WITH_LEN("%_vtmd")}, false, true};
|
||||
|
||||
int res= make_table_name_list(thd, &table_names, thd->lex, &lookup_field_values,
|
||||
&lookup_field_values.db_value);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
bool
|
||||
VTMD_table::get_archive_tables(THD *thd, const char *db, size_t db_length,
|
||||
Dynamic_array<String> &result)
|
||||
{
|
||||
Dynamic_array<LEX_CSTRING *> vtmd_tables;
|
||||
if (get_vtmd_tables(thd, db, db_length, vtmd_tables))
|
||||
return true;
|
||||
|
||||
Local_da local_da(thd, ER_VERS_VTMD_ERROR);
|
||||
for (uint i= 0; i < vtmd_tables.elements(); i++)
|
||||
{
|
||||
LEX_CSTRING table_name= *vtmd_tables.at(i);
|
||||
Open_tables_backup open_tables_backup;
|
||||
TABLE_LIST table_list;
|
||||
LEX_CSTRING db_name= {db, db_length};
|
||||
table_list.init_one_table(&db_name, &table_name, NULL, TL_READ);
|
||||
|
||||
TABLE *table= open_log_table(thd, &table_list, &open_tables_backup);
|
||||
if (!table || !table->vers_vtmd())
|
||||
{
|
||||
if (table)
|
||||
close_log_table(thd, &open_tables_backup);
|
||||
else
|
||||
{
|
||||
if (local_da.is_error() && local_da.sql_errno() == ER_NOT_LOG_TABLE)
|
||||
local_da.reset_diagnostics_area();
|
||||
else
|
||||
return true;
|
||||
}
|
||||
push_warning_printf(
|
||||
thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_VERS_VTMD_ERROR,
|
||||
"Table `%s.%s` is not a VTMD table",
|
||||
db, table_name.str);
|
||||
continue;
|
||||
}
|
||||
|
||||
READ_RECORD read_record;
|
||||
int error= 0;
|
||||
SQL_SELECT *sql_select= make_select(table, 0, 0, NULL, NULL, 0, &error);
|
||||
if (error)
|
||||
{
|
||||
close_log_table(thd, &open_tables_backup);
|
||||
return true;
|
||||
}
|
||||
error= init_read_record(&read_record, thd, table, sql_select, NULL, 1, 1, false);
|
||||
if (error)
|
||||
{
|
||||
delete sql_select;
|
||||
close_log_table(thd, &open_tables_backup);
|
||||
return true;
|
||||
}
|
||||
|
||||
while (!(error= read_record.read_record()))
|
||||
{
|
||||
Field *field= table->field[FLD_ARCHIVE_NAME];
|
||||
if (field->is_null())
|
||||
continue;
|
||||
|
||||
String archive_name;
|
||||
field->val_str(&archive_name);
|
||||
archive_name.set_ascii(strmake_root(thd->mem_root, archive_name.c_ptr(),
|
||||
archive_name.length()),
|
||||
archive_name.length());
|
||||
result.push(archive_name);
|
||||
}
|
||||
// check for EOF
|
||||
if (!thd->is_error())
|
||||
error= 0;
|
||||
|
||||
end_read_record(&read_record);
|
||||
delete sql_select;
|
||||
close_log_table(thd, &open_tables_backup);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool VTMD_table::setup_select(THD* thd)
|
||||
{
|
||||
SString archive_name;
|
||||
if (find_archive_name(thd, archive_name))
|
||||
return true;
|
||||
|
||||
if (archive_name.length() == 0)
|
||||
return false;
|
||||
|
||||
thd->make_lex_string(&about.table_name, archive_name.ptr(),
|
||||
archive_name.length());
|
||||
DBUG_ASSERT(!about.mdl_request.ticket);
|
||||
about.mdl_request.init(MDL_key::TABLE, about.db.str, about.table_name.str,
|
||||
about.mdl_request.type, about.mdl_request.duration);
|
||||
about.vers_force_alias= true;
|
||||
// Since we modified SELECT_LEX::table_list, we need to invalidate current SP
|
||||
if (thd->spcont)
|
||||
{
|
||||
DBUG_ASSERT(thd->spcont->m_sp);
|
||||
thd->spcont->m_sp->set_sp_cache_version(0);
|
||||
}
|
||||
return false;
|
||||
}
|
190
sql/vtmd.h
190
sql/vtmd.h
@ -1,190 +0,0 @@
|
||||
#ifndef VTMD_INCLUDED
|
||||
#define VTMD_INCLUDED
|
||||
|
||||
#include <mysqld_error.h>
|
||||
|
||||
#include "mariadb.h"
|
||||
#include "sql_priv.h"
|
||||
|
||||
#include "my_sys.h"
|
||||
#include "table.h"
|
||||
#include "unireg.h"
|
||||
|
||||
#include "vers_utils.h"
|
||||
|
||||
class key_buf_t
|
||||
{
|
||||
uchar* buf;
|
||||
|
||||
key_buf_t(const key_buf_t&); // disabled
|
||||
key_buf_t& operator= (const key_buf_t&); // disabled
|
||||
|
||||
public:
|
||||
key_buf_t() : buf(NULL)
|
||||
{}
|
||||
|
||||
~key_buf_t()
|
||||
{
|
||||
if (buf)
|
||||
my_free(buf);
|
||||
}
|
||||
|
||||
bool allocate(size_t alloc_size)
|
||||
{
|
||||
DBUG_ASSERT(!buf);
|
||||
buf= static_cast<uchar *>(my_malloc(alloc_size, MYF(0)));
|
||||
if (!buf)
|
||||
{
|
||||
my_message(ER_VERS_VTMD_ERROR, "failed to allocate key buffer", MYF(0));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
operator uchar* ()
|
||||
{
|
||||
DBUG_ASSERT(buf);
|
||||
return reinterpret_cast<uchar *>(buf);
|
||||
}
|
||||
};
|
||||
|
||||
class THD;
|
||||
|
||||
class VTMD_table
|
||||
{
|
||||
Open_tables_backup open_tables_backup;
|
||||
|
||||
protected:
|
||||
TABLE_LIST vtmd;
|
||||
TABLE_LIST &about;
|
||||
SString_t vtmd_name;
|
||||
|
||||
private:
|
||||
VTMD_table(const VTMD_table&); // prohibit copying references
|
||||
|
||||
public:
|
||||
enum {
|
||||
FLD_START= 0,
|
||||
FLD_END,
|
||||
FLD_NAME,
|
||||
FLD_ARCHIVE_NAME,
|
||||
FLD_COL_RENAMES,
|
||||
FIELD_COUNT
|
||||
};
|
||||
|
||||
enum {
|
||||
IDX_TRX_END= 0,
|
||||
IDX_ARCHIVE_NAME
|
||||
};
|
||||
|
||||
VTMD_table(TABLE_LIST &_about) :
|
||||
about(_about)
|
||||
{
|
||||
vtmd.table= NULL;
|
||||
}
|
||||
|
||||
bool create(THD *thd);
|
||||
bool find_record(ulonglong row_end, bool &found);
|
||||
bool open(THD *thd, Local_da &local_da, bool *created= NULL);
|
||||
bool update(THD *thd, const char* archive_name= NULL);
|
||||
bool setup_select(THD *thd);
|
||||
|
||||
static void archive_name(THD *thd, const char *table_name, char *new_name, size_t new_name_size);
|
||||
void archive_name(THD *thd, char *new_name, size_t new_name_size)
|
||||
{
|
||||
archive_name(thd, about.table_name.str, new_name, new_name_size);
|
||||
}
|
||||
|
||||
bool find_archive_name(THD *thd, String &out);
|
||||
static bool get_archive_tables(THD *thd, const char *db, size_t db_length,
|
||||
Dynamic_array<String> &result);
|
||||
};
|
||||
|
||||
class VTMD_exists : public VTMD_table
|
||||
{
|
||||
protected:
|
||||
handlerton *hton;
|
||||
|
||||
public:
|
||||
bool exists;
|
||||
|
||||
public:
|
||||
VTMD_exists(TABLE_LIST &_about) :
|
||||
VTMD_table(_about),
|
||||
hton(NULL),
|
||||
exists(false)
|
||||
{}
|
||||
|
||||
bool check_exists(THD *thd); // returns error status
|
||||
};
|
||||
|
||||
class VTMD_rename : public VTMD_exists
|
||||
{
|
||||
SString_t vtmd_new_name;
|
||||
|
||||
public:
|
||||
VTMD_rename(TABLE_LIST &_about) :
|
||||
VTMD_exists(_about)
|
||||
{}
|
||||
|
||||
bool try_rename(THD *thd, LString new_db, LString new_alias, const char* archive_name= NULL);
|
||||
bool revert_rename(THD *thd, LString new_db);
|
||||
|
||||
private:
|
||||
bool move_archives(THD *thd, LString &new_db);
|
||||
bool move_table(THD *thd, SString_fs &table_name, LString &new_db);
|
||||
};
|
||||
|
||||
class VTMD_drop : public VTMD_exists
|
||||
{
|
||||
char archive_name_[NAME_CHAR_LEN];
|
||||
|
||||
public:
|
||||
VTMD_drop(TABLE_LIST &_about) :
|
||||
VTMD_exists(_about)
|
||||
{
|
||||
*archive_name_= 0;
|
||||
}
|
||||
|
||||
const char* archive_name(THD *thd)
|
||||
{
|
||||
VTMD_table::archive_name(thd, archive_name_, sizeof(archive_name_));
|
||||
return archive_name_;
|
||||
}
|
||||
|
||||
const char* archive_name() const
|
||||
{
|
||||
DBUG_ASSERT(*archive_name_);
|
||||
return archive_name_;
|
||||
}
|
||||
|
||||
bool update(THD *thd)
|
||||
{
|
||||
DBUG_ASSERT(*archive_name_);
|
||||
return VTMD_exists::update(thd, archive_name_);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
inline
|
||||
bool
|
||||
VTMD_exists::check_exists(THD *thd)
|
||||
{
|
||||
LEX_CSTRING name;
|
||||
if (about.vers_vtmd_name(vtmd_name))
|
||||
return true;
|
||||
|
||||
name.str= vtmd_name.ptr();
|
||||
name.length= vtmd_name.length();
|
||||
exists= ha_table_exists(thd, &about.db, &name, &hton);
|
||||
|
||||
if (exists && !hton)
|
||||
{
|
||||
my_printf_error(ER_VERS_VTMD_ERROR, "`%s.%s` handlerton empty!", MYF(0),
|
||||
about.db.str, vtmd_name.ptr());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif // VTMD_INCLUDED
|
@ -8823,8 +8823,7 @@ ha_innobase::update_row(
|
||||
const bool vers_set_fields = m_prebuilt->versioned_write
|
||||
&& m_prebuilt->upd_node->update->affects_versioned();
|
||||
const bool vers_ins_row = vers_set_fields
|
||||
&& (table->s->vtmd
|
||||
|| thd_sql_command(m_user_thd) != SQLCOM_ALTER_TABLE);
|
||||
&& thd_sql_command(m_user_thd) != SQLCOM_ALTER_TABLE;
|
||||
|
||||
/* This is not a delete */
|
||||
m_prebuilt->upd_node->is_delete =
|
||||
|
Loading…
x
Reference in New Issue
Block a user