summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavi Arnaut <Davi.Arnaut@Sun.COM>2010-05-27 17:40:54 -0300
committerDavi Arnaut <Davi.Arnaut@Sun.COM>2010-05-27 17:40:54 -0300
commitfcbc77b064b7fde7c0d5519e89b3715bbac8fc2c (patch)
tree4e6ea173d93497d194e0298b20fc4abb785faee8
parent2397d7fe1938cca45f96dd5bf73a343ea0fcacf7 (diff)
downloadmariadb-git-fcbc77b064b7fde7c0d5519e89b3715bbac8fc2c.tar.gz
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.
-rw-r--r--mysql-test/r/archive.result8
-rw-r--r--mysql-test/t/archive.test10
-rw-r--r--sql/sql_truncate.cc21
3 files changed, 39 insertions, 0 deletions
diff --git a/mysql-test/r/archive.result b/mysql-test/r/archive.result
index 783a54a6b8c..ea6311a721b 100644
--- a/mysql-test/r/archive.result
+++ b/mysql-test/r/archive.result
@@ -12748,3 +12748,11 @@ SELECT * FROM t1;
ERROR HY000: Can't find file: 't1' (errno: 2)
DROP 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;
diff --git a/mysql-test/t/archive.test b/mysql-test/t/archive.test
index b2545e98f3e..29f69f64d10 100644
--- a/mysql-test/t/archive.test
+++ b/mysql-test/t/archive.test
@@ -1669,3 +1669,13 @@ FLUSH TABLE t1;
SELECT * FROM t1;
--error ER_BAD_TABLE_ERROR
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;
diff --git a/sql/sql_truncate.cc b/sql/sql_truncate.cc
index 47a98769d57..8fc04588aaa 100644
--- a/sql/sql_truncate.cc
+++ b/sql/sql_truncate.cc
@@ -52,6 +52,22 @@ delete_all_rows(THD *thd, TABLE *table)
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.
If it is unsupported, switch to row by row deletion.
*/
@@ -455,6 +471,11 @@ bool mysql_truncate_table(THD *thd, TABLE_LIST *table_ref)
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)
mdl_ticket->downgrade_exclusive_lock(MDL_SHARED_NO_READ_WRITE);