Commit ececc502 authored by Sergei Golubchik's avatar Sergei Golubchik

MDEV-15966 Behavior for TRUNCATE versioned table is not documented and not covered by tests

* add error for truncation of versioned tables: `ER_TRUNCATE_ILLEGAL_VERS`
* make a full table open with `tdc_aquire_share` instead of just `ha_table_exists` check
test suites run: main, parts, versioning

Closes #785
parent 2400e069
...@@ -46,8 +46,12 @@ x check_row(row_start, row_end) ...@@ -46,8 +46,12 @@ x check_row(row_start, row_end)
4 HISTORICAL ROW 4 HISTORICAL ROW
select * from tf; select * from tf;
x x
# TRUNCATE # MDEV-15966: Behavior for TRUNCATE versioned table is not documented
# and not covered by tests
# As of standard, TRUNCATE on versioned tables is forbidden
truncate tf; truncate tf;
ERROR HY000: Got error 10000 'Error on remote system: 4160: Cannot truncate a versioned table' from FEDERATED
delete history from t1;
select * from t1 for system_time all; select * from t1 for system_time all;
x x
# REPLACE # REPLACE
...@@ -81,8 +85,10 @@ x check_row(row_start, row_end) ...@@ -81,8 +85,10 @@ x check_row(row_start, row_end)
3 HISTORICAL ROW 3 HISTORICAL ROW
4 HISTORICAL ROW 4 HISTORICAL ROW
# multi-UPDATE # multi-UPDATE
truncate t1; delete from t1;
truncate t2; delete history from t1;
delete from t2;
delete history from t2;
insert into t1 values (1); insert into t1 values (1);
insert into t2 values (2, 2); insert into t2 values (2, 2);
update tf, t2f set tf.x= 11, t2f.y= 22; update tf, t2f set tf.x= 11, t2f.y= 22;
......
...@@ -32,8 +32,13 @@ select *, check_row(row_start, row_end) from t1 for system_time all ...@@ -32,8 +32,13 @@ select *, check_row(row_start, row_end) from t1 for system_time all
order by x; order by x;
select * from tf; select * from tf;
--echo # TRUNCATE --echo # MDEV-15966: Behavior for TRUNCATE versioned table is not documented
--echo # and not covered by tests
--echo # As of standard, TRUNCATE on versioned tables is forbidden
--error ER_GET_ERRMSG
truncate tf; truncate tf;
delete history from t1;
select * from t1 for system_time all; select * from t1 for system_time all;
--echo # REPLACE --echo # REPLACE
...@@ -62,8 +67,10 @@ select *, check_row(row_start, row_end) from t1 for system_time all ...@@ -62,8 +67,10 @@ select *, check_row(row_start, row_end) from t1 for system_time all
order by x; order by x;
--echo # multi-UPDATE --echo # multi-UPDATE
truncate t1; delete from t1;
truncate t2; delete history from t1;
delete from t2;
delete history from t2;
insert into t1 values (1); insert into t1 values (1);
insert into t2 values (2, 2); insert into t2 values (2, 2);
update tf, t2f set tf.x= 11, t2f.y= 22; update tf, t2f set tf.x= 11, t2f.y= 22;
......
...@@ -396,14 +396,6 @@ for each row select count(*) from t1 into @a; ...@@ -396,14 +396,6 @@ for each row select count(*) from t1 into @a;
Warnings: Warnings:
Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead
insert into t2 values (1); insert into t2 values (1);
# MDEV-14741 Assertion `(trx)->start_file == 0' failed in row_truncate_table_for_mysql()
create or replace table t1 (i int) with system versioning
partition by system_time interval 1 hour (
partition p1 history,
partition pn current);
set autocommit= off;
truncate table t1;
set autocommit= on;
# MDEV-14747 ALTER PARTITION BY SYSTEM_TIME after LOCK TABLES # MDEV-14747 ALTER PARTITION BY SYSTEM_TIME after LOCK TABLES
create or replace table t1 (x int) with system versioning; create or replace table t1 (x int) with system versioning;
lock table t1 write; lock table t1 write;
......
...@@ -106,5 +106,29 @@ call pr; ...@@ -106,5 +106,29 @@ call pr;
call pr; call pr;
drop procedure pr; drop procedure pr;
drop table t1; drop table t1;
# MDEV-15966 Behavior for TRUNCATE versioned table is not documented and not covered by tests
create or replace table t1 (id int);
create or replace table t2 (id int) with system versioning;
# force cleaning table shares
flush tables t1, t2;
truncate table t1;
truncate table t2;
ERROR HY000: Cannot truncate a versioned table
# fetch table shares
describe t1;
Field Type Null Key Default Extra
id int(11) YES NULL
describe t2;
Field Type Null Key Default Extra
id int(11) YES NULL
truncate table t1;
truncate table t2;
ERROR HY000: Cannot truncate a versioned table
# enter locked tables mode
lock tables t1 WRITE, t2 WRITE;
truncate t1;
truncate t2;
ERROR HY000: Cannot truncate a versioned table
unlock tables;
drop database test; drop database test;
create database test; create database test;
...@@ -341,15 +341,6 @@ create or replace trigger tr before insert on t2 ...@@ -341,15 +341,6 @@ create or replace trigger tr before insert on t2
for each row select count(*) from t1 into @a; for each row select count(*) from t1 into @a;
insert into t2 values (1); insert into t2 values (1);
--echo # MDEV-14741 Assertion `(trx)->start_file == 0' failed in row_truncate_table_for_mysql()
create or replace table t1 (i int) with system versioning
partition by system_time interval 1 hour (
partition p1 history,
partition pn current);
set autocommit= off;
truncate table t1;
set autocommit= on;
--echo # MDEV-14747 ALTER PARTITION BY SYSTEM_TIME after LOCK TABLES --echo # MDEV-14747 ALTER PARTITION BY SYSTEM_TIME after LOCK TABLES
create or replace table t1 (x int) with system versioning; create or replace table t1 (x int) with system versioning;
lock table t1 write; lock table t1 write;
......
...@@ -117,5 +117,33 @@ call pr; ...@@ -117,5 +117,33 @@ call pr;
drop procedure pr; drop procedure pr;
drop table t1; drop table t1;
--echo # MDEV-15966 Behavior for TRUNCATE versioned table is not documented and not covered by tests
create or replace table t1 (id int);
create or replace table t2 (id int) with system versioning;
-- echo # force cleaning table shares
flush tables t1, t2;
truncate table t1;
--error ER_TRUNCATE_ILLEGAL_VERS
truncate table t2;
-- echo # fetch table shares
describe t1;
describe t2;
truncate table t1;
--error ER_TRUNCATE_ILLEGAL_VERS
truncate table t2;
--echo # enter locked tables mode
lock tables t1 WRITE, t2 WRITE;
truncate t1;
--error ER_TRUNCATE_ILLEGAL_VERS
truncate t2;
unlock tables;
drop database test; drop database test;
create database test; create database test;
...@@ -7931,3 +7931,5 @@ ER_PERIOD_CONSTRAINT_DROP ...@@ -7931,3 +7931,5 @@ ER_PERIOD_CONSTRAINT_DROP
eng "Can't DROP CONSTRAINT `%s`. Use DROP PERIOD `%s` for this" eng "Can't DROP CONSTRAINT `%s`. Use DROP PERIOD `%s` for this"
ER_TOO_LONG_KEYPART 42000 S1009 ER_TOO_LONG_KEYPART 42000 S1009
eng "Specified key part was too long; max key part length is %u bytes" eng "Specified key part was too long; max key part length is %u bytes"
ER_TRUNCATE_ILLEGAL_VERS
eng "Cannot truncate a versioned table"
...@@ -275,6 +275,9 @@ Sql_cmd_truncate_table::handler_truncate(THD *thd, TABLE_LIST *table_ref, ...@@ -275,6 +275,9 @@ Sql_cmd_truncate_table::handler_truncate(THD *thd, TABLE_LIST *table_ref,
bool Sql_cmd_truncate_table::lock_table(THD *thd, TABLE_LIST *table_ref, bool Sql_cmd_truncate_table::lock_table(THD *thd, TABLE_LIST *table_ref,
bool *hton_can_recreate) bool *hton_can_recreate)
{ {
handlerton *hton;
bool versioned;
bool sequence= false;
TABLE *table= NULL; TABLE *table= NULL;
DBUG_ENTER("Sql_cmd_truncate_table::lock_table"); DBUG_ENTER("Sql_cmd_truncate_table::lock_table");
...@@ -302,43 +305,43 @@ bool Sql_cmd_truncate_table::lock_table(THD *thd, TABLE_LIST *table_ref, ...@@ -302,43 +305,43 @@ bool Sql_cmd_truncate_table::lock_table(THD *thd, TABLE_LIST *table_ref,
table_ref->table_name.str, NULL))) table_ref->table_name.str, NULL)))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
*hton_can_recreate= ha_check_storage_engine_flag(table->file->ht, versioned= table->versioned();
HTON_CAN_RECREATE); hton= table->file->ht;
table_ref->mdl_request.ticket= table->mdl_ticket; table_ref->mdl_request.ticket= table->mdl_ticket;
} }
else else
{ {
handlerton *hton;
bool is_sequence;
/* Acquire an exclusive lock. */
DBUG_ASSERT(table_ref->next_global == NULL); DBUG_ASSERT(table_ref->next_global == NULL);
if (lock_table_names(thd, table_ref, NULL, if (lock_table_names(thd, table_ref, NULL,
thd->variables.lock_wait_timeout, 0)) thd->variables.lock_wait_timeout, 0))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
if (!ha_table_exists(thd, &table_ref->db, &table_ref->table_name, TABLE_SHARE *share= tdc_acquire_share(thd, table_ref, GTS_TABLE | GTS_VIEW);
&hton, &is_sequence) || if (share == NULL)
hton == view_pseudo_hton) DBUG_RETURN(TRUE);
DBUG_ASSERT(share != (TABLE_SHARE*)1);
versioned= share->versioned;
sequence= share->table_type == TABLE_TYPE_SEQUENCE;
hton= share->db_type();
tdc_release_share(share);
if (hton == view_pseudo_hton)
{ {
my_error(ER_NO_SUCH_TABLE, MYF(0), table_ref->db.str, my_error(ER_NO_SUCH_TABLE, MYF(0), table_ref->db.str,
table_ref->table_name.str); table_ref->table_name.str);
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
}
if (!hton) *hton_can_recreate= !sequence
{ && ha_check_storage_engine_flag(hton, HTON_CAN_RECREATE);
/*
The table exists, but its storage engine is unknown, perhaps not if (versioned)
loaded at the moment. We need to open and parse the frm to know the {
storage engine in question, so let's proceed with the truncation and my_error(ER_TRUNCATE_ILLEGAL_VERS, MYF(0));
try to open the table. This will produce the correct error message DBUG_RETURN(TRUE);
about unknown engine.
*/
*hton_can_recreate= false;
}
else
*hton_can_recreate= !is_sequence && hton->flags & HTON_CAN_RECREATE;
} }
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment