Commit c57b2f50 authored by Davi Arnaut's avatar Davi Arnaut

Bug#42643: InnoDB does not support replication of TRUNCATE TABLE

Post-merge fix: Retrieve handler statistics to workaround quirks
of the archive storage engine.

mysql-test/t/archive.test:
  Add test case.
sql/sql_truncate.cc:
  Call info method with has side-effects related to the archive
  storage engine. It will cause rows to become visible, allowing
  a error to be thrown once we attempt to delete the rows.
parent b9a851d4
...@@ -12748,3 +12748,11 @@ SELECT * FROM t1; ...@@ -12748,3 +12748,11 @@ SELECT * FROM t1;
ERROR HY000: Can't find file: 't1' (errno: 2) ERROR HY000: Can't find file: 't1' (errno: 2)
DROP TABLE t1; DROP TABLE t1;
ERROR 42S02: Unknown table 't1' ERROR 42S02: Unknown table 't1'
#
# Ensure that TRUNCATE fails for non-empty archive tables.
#
CREATE TABLE t1 (a INT) ENGINE=ARCHIVE;
INSERT INTO t1 VALUES (1);
TRUNCATE TABLE t1;
ERROR HY000: Table storage engine for 't1' doesn't have this option
DROP TABLE t1;
...@@ -1669,3 +1669,13 @@ FLUSH TABLE t1; ...@@ -1669,3 +1669,13 @@ FLUSH TABLE t1;
SELECT * FROM t1; SELECT * FROM t1;
--error ER_BAD_TABLE_ERROR --error ER_BAD_TABLE_ERROR
DROP TABLE t1; DROP TABLE t1;
--echo #
--echo # Ensure that TRUNCATE fails for non-empty archive tables.
--echo #
CREATE TABLE t1 (a INT) ENGINE=ARCHIVE;
INSERT INTO t1 VALUES (1);
--error ER_ILLEGAL_HA
TRUNCATE TABLE t1;
DROP TABLE t1;
...@@ -51,6 +51,22 @@ delete_all_rows(THD *thd, TABLE *table) ...@@ -51,6 +51,22 @@ delete_all_rows(THD *thd, TABLE *table)
/* Replication of truncate table must be statement based. */ /* Replication of truncate table must be statement based. */
thd->clear_current_stmt_binlog_format_row(); thd->clear_current_stmt_binlog_format_row();
/*
Update handler statistics (e.g. table->file->stats.records).
Might be used by the storage engine to aggregate information
necessary to allow deletion. Currently, this seems to be
meaningful only to the archive storage engine, which uses
the info method to set the number of records. Although
archive does not support deletion, it becomes necessary in
order to return a error if the table is not empty.
*/
error= table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
if (error && error != HA_ERR_WRONG_COMMAND)
{
table->file->print_error(error, MYF(0));
goto end;
}
/* /*
Attempt to delete all rows in the table. Attempt to delete all rows in the table.
If it is unsupported, switch to row by row deletion. If it is unsupported, switch to row by row deletion.
...@@ -455,6 +471,11 @@ bool mysql_truncate_table(THD *thd, TABLE_LIST *table_ref) ...@@ -455,6 +471,11 @@ bool mysql_truncate_table(THD *thd, TABLE_LIST *table_ref)
trans_rollback(thd); trans_rollback(thd);
} }
/*
A locked table ticket was upgraded to a exclusive lock. After the
the query has been written to the binary log, downgrade the lock
to a shared one.
*/
if (mdl_ticket) if (mdl_ticket)
mdl_ticket->downgrade_exclusive_lock(MDL_SHARED_NO_READ_WRITE); mdl_ticket->downgrade_exclusive_lock(MDL_SHARED_NO_READ_WRITE);
......
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