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)
4 HISTORICAL ROW
select * from tf;
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;
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;
x
# REPLACE
......@@ -81,8 +85,10 @@ x check_row(row_start, row_end)
3 HISTORICAL ROW
4 HISTORICAL ROW
# multi-UPDATE
truncate t1;
truncate t2;
delete from t1;
delete history from t1;
delete from t2;
delete history from t2;
insert into t1 values (1);
insert into t2 values (2, 2);
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
order by x;
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;
delete history from t1;
select * from t1 for system_time all;
--echo # REPLACE
......@@ -62,8 +67,10 @@ select *, check_row(row_start, row_end) from t1 for system_time all
order by x;
--echo # multi-UPDATE
truncate t1;
truncate t2;
delete from t1;
delete history from t1;
delete from t2;
delete history from t2;
insert into t1 values (1);
insert into t2 values (2, 2);
update tf, t2f set tf.x= 11, t2f.y= 22;
......
......@@ -396,14 +396,6 @@ for each row select count(*) from t1 into @a;
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
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
create or replace table t1 (x int) with system versioning;
lock table t1 write;
......
......@@ -106,5 +106,29 @@ call pr;
call pr;
drop procedure pr;
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;
create database test;
......@@ -341,15 +341,6 @@ create or replace trigger tr before insert on t2
for each row select count(*) from t1 into @a;
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
create or replace table t1 (x int) with system versioning;
lock table t1 write;
......
......@@ -117,5 +117,33 @@ call pr;
drop procedure pr;
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;
create database test;
......@@ -7931,3 +7931,5 @@ ER_PERIOD_CONSTRAINT_DROP
eng "Can't DROP CONSTRAINT `%s`. Use DROP PERIOD `%s` for this"
ER_TOO_LONG_KEYPART 42000 S1009
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,
bool Sql_cmd_truncate_table::lock_table(THD *thd, TABLE_LIST *table_ref,
bool *hton_can_recreate)
{
handlerton *hton;
bool versioned;
bool sequence= false;
TABLE *table= NULL;
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,
table_ref->table_name.str, NULL)))
DBUG_RETURN(TRUE);
*hton_can_recreate= ha_check_storage_engine_flag(table->file->ht,
HTON_CAN_RECREATE);
versioned= table->versioned();
hton= table->file->ht;
table_ref->mdl_request.ticket= table->mdl_ticket;
}
else
{
handlerton *hton;
bool is_sequence;
/* Acquire an exclusive lock. */
DBUG_ASSERT(table_ref->next_global == NULL);
if (lock_table_names(thd, table_ref, NULL,
thd->variables.lock_wait_timeout, 0))
DBUG_RETURN(TRUE);
if (!ha_table_exists(thd, &table_ref->db, &table_ref->table_name,
&hton, &is_sequence) ||
hton == view_pseudo_hton)
TABLE_SHARE *share= tdc_acquire_share(thd, table_ref, GTS_TABLE | GTS_VIEW);
if (share == NULL)
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,
table_ref->table_name.str);
DBUG_RETURN(TRUE);
}
}
*hton_can_recreate= !sequence
&& ha_check_storage_engine_flag(hton, HTON_CAN_RECREATE);
if (!hton)
if (versioned)
{
/*
The table exists, but its storage engine is unknown, perhaps not
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
try to open the table. This will produce the correct error message
about unknown engine.
*/
*hton_can_recreate= false;
}
else
*hton_can_recreate= !is_sequence && hton->flags & HTON_CAN_RECREATE;
my_error(ER_TRUNCATE_ILLEGAL_VERS, MYF(0));
DBUG_RETURN(TRUE);
}
/*
......
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