Commit 5a4f8e21 authored by Konstantin Osipov's avatar Konstantin Osipov

Backport of:

------------------------------------------------------------
 2599.161.3 Ingo Struewing      2009-07-21
 Bug#20667 - Truncate table fails for a write locked table

 TRUNCATE TABLE was not allowed under LOCK TABLES.

 The patch removes this restriction. mysql_truncate()
 does now handle that case.


mysql-test/r/merge.result:
  Bug#20667 - Truncate table fails for a write locked table
  Updated test result.
mysql-test/r/truncate.result:
  Bug#20667 - Truncate table fails for a write locked table
  Updated test result.
mysql-test/r/truncate_coverage.result:
  Bug#20667 - Truncate table fails for a write locked table
  New test result.
mysql-test/t/merge.test:
  Bug#20667 - Truncate table fails for a write locked table
  Updated test case due to now working TRUNCATE under LOCK TABLES.
  Added some SELECTs to show that child tables are truncated.
mysql-test/t/truncate.test:
  Bug#20667 - Truncate table fails for a write locked table
  Added test cases for TRUNCATE under LOCK TABLE.
mysql-test/t/truncate_coverage.test:
  Bug#20667 - Truncate table fails for a write locked table
  New test file. Coverage tests for TRUNCATE.
sql/sql_delete.cc:
  Bug#20667 - Truncate table fails for a write locked table
  Added branches for thd->locked_tables_mode.
sql/sql_parse.cc:
  Bug#20667 - Truncate table fails for a write locked table
  Deleted rejection of TRUNCATE in case of LOCK TABLES.
parent 3097c22a
...@@ -1046,18 +1046,21 @@ c1 ...@@ -1046,18 +1046,21 @@ c1
LOCK TABLE t1 WRITE, t2 WRITE, t3 WRITE; LOCK TABLE t1 WRITE, t2 WRITE, t3 WRITE;
INSERT INTO t1 VALUES (1); INSERT INTO t1 VALUES (1);
TRUNCATE TABLE t3; TRUNCATE TABLE t3;
ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
SELECT * FROM t3; SELECT * FROM t3;
c1 c1
1 UNLOCK TABLES;
2 SELECT * FROM t1;
c1
SELECT * FROM t2;
c1
# #
# Truncate child table under locked tables. # Truncate child table under locked tables.
LOCK TABLE t1 WRITE, t2 WRITE, t3 WRITE;
INSERT INTO t1 VALUES (1);
INSERT INTO t2 VALUES (2);
TRUNCATE TABLE t1; TRUNCATE TABLE t1;
ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
SELECT * FROM t3; SELECT * FROM t3;
c1 c1
1
2 2
UNLOCK TABLES; UNLOCK TABLES;
DROP TABLE t1, t2, t3; DROP TABLE t1, t2, t3;
...@@ -1089,18 +1092,24 @@ INSERT INTO t1 VALUES (1); ...@@ -1089,18 +1092,24 @@ INSERT INTO t1 VALUES (1);
CREATE TABLE t4 (c1 INT, INDEX(c1)); CREATE TABLE t4 (c1 INT, INDEX(c1));
LOCK TABLE t4 WRITE; LOCK TABLE t4 WRITE;
TRUNCATE TABLE t3; TRUNCATE TABLE t3;
ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
SELECT * FROM t3; SELECT * FROM t3;
c1 c1
1 SELECT * FROM t1;
2 c1
SELECT * FROM t2;
c1
# #
# Truncate temporary child table under locked tables. # Truncate temporary child table under locked tables.
INSERT INTO t1 VALUES (1);
INSERT INTO t2 VALUES (2);
TRUNCATE TABLE t1; TRUNCATE TABLE t1;
ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
SELECT * FROM t3; SELECT * FROM t3;
c1 c1
1 2
SELECT * FROM t1;
c1
SELECT * FROM t2;
c1
2 2
UNLOCK TABLES; UNLOCK TABLES;
DROP TABLE t1, t2, t3, t4; DROP TABLE t1, t2, t3, t4;
......
drop table if exists t1; drop table if exists t1, t2;
create table t1 (a integer, b integer,c1 CHAR(10)); create table t1 (a integer, b integer,c1 CHAR(10));
insert into t1 (a) values (1),(2); insert into t1 (a) values (1),(2);
truncate table t1; truncate table t1;
...@@ -61,6 +61,91 @@ ERROR 42S02: Table 'test.v1' doesn't exist ...@@ -61,6 +61,91 @@ ERROR 42S02: Table 'test.v1' doesn't exist
drop view v1; drop view v1;
drop table t1; drop table t1;
# #
# Bug#20667 - Truncate table fails for a write locked table
#
CREATE TABLE t1 (c1 INT);
LOCK TABLE t1 WRITE;
INSERT INTO t1 VALUES (1);
SELECT * FROM t1;
c1
1
TRUNCATE TABLE t1;
SELECT * FROM t1;
c1
UNLOCK TABLES;
LOCK TABLE t1 READ;
TRUNCATE TABLE t1;
ERROR HY000: Table 't1' was locked with a READ lock and can't be updated
UNLOCK TABLES;
CREATE TABLE t2 (c1 INT);
LOCK TABLE t2 WRITE;
TRUNCATE TABLE t1;
ERROR HY000: Table 't1' was not locked with LOCK TABLES
UNLOCK TABLES;
CREATE VIEW v1 AS SELECT t1.c1 FROM t1,t2 WHERE t1.c1 = t2.c1;
INSERT INTO t1 VALUES (1), (2), (3);
INSERT INTO t2 VALUES (1), (3), (4);
SELECT * FROM v1;
c1
1
3
TRUNCATE v1;
ERROR 42S02: Table 'test.v1' doesn't exist
SELECT * FROM v1;
c1
1
3
LOCK TABLE t1 WRITE;
SELECT * FROM v1;
ERROR HY000: Table 'v1' was not locked with LOCK TABLES
TRUNCATE v1;
ERROR 42S02: Table 'test.v1' doesn't exist
SELECT * FROM v1;
ERROR HY000: Table 'v1' was not locked with LOCK TABLES
UNLOCK TABLES;
LOCK TABLE t1 WRITE, t2 WRITE;
SELECT * FROM v1;
ERROR HY000: Table 'v1' was not locked with LOCK TABLES
TRUNCATE v1;
ERROR 42S02: Table 'test.v1' doesn't exist
SELECT * FROM v1;
ERROR HY000: Table 'v1' was not locked with LOCK TABLES
UNLOCK TABLES;
LOCK TABLE v1 WRITE;
SELECT * FROM v1;
c1
1
3
TRUNCATE v1;
ERROR 42S02: Table 'test.v1' doesn't exist
SELECT * FROM v1;
c1
1
3
UNLOCK TABLES;
LOCK TABLE t1 WRITE, t2 WRITE, v1 WRITE;
SELECT * FROM v1;
c1
1
3
TRUNCATE v1;
ERROR 42S02: Table 'test.v1' doesn't exist
SELECT * FROM v1;
c1
1
3
UNLOCK TABLES;
DROP VIEW v1;
DROP TABLE t1, t2;
CREATE PROCEDURE p1() SET @a = 5;
TRUNCATE p1;
ERROR 42S02: Table 'test.p1' doesn't exist
SHOW CREATE PROCEDURE p1;
Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation
p1 CREATE DEFINER=`root`@`localhost` PROCEDURE `p1`()
SET @a = 5 latin1 latin1_swedish_ci latin1_swedish_ci
DROP PROCEDURE p1;
#
# Bug#46452 Crash in MDL, HANDLER OPEN + TRUNCATE TABLE # Bug#46452 Crash in MDL, HANDLER OPEN + TRUNCATE TABLE
# #
DROP TABLE IF EXISTS t1; DROP TABLE IF EXISTS t1;
......
SET DEBUG_SYNC='RESET';
DROP TABLE IF EXISTS t1;
#
# Bug#20667 - Truncate table fails for a write locked table
#
CREATE TABLE t1 (c1 INT);
INSERT INTO t1 VALUES (1);
#
# connection con1
START TRANSACTION;
INSERT INTO t1 VALUES (2);
#
# connection default
LOCK TABLE t1 WRITE;
SET DEBUG_SYNC='mdl_upgrade_shared_lock_to_exclusive SIGNAL waiting';
TRUNCATE TABLE t1;
#
# connection con1
SET DEBUG_SYNC='now WAIT_FOR waiting';
KILL QUERY @id;
COMMIT;
#
# connection default
ERROR 70100: Query execution was interrupted
UNLOCK TABLES;
DROP TABLE t1;
SET DEBUG_SYNC='RESET';
CREATE TABLE t1 (c1 INT);
INSERT INTO t1 VALUES (1);
#
# connection con1
START TRANSACTION;
INSERT INTO t1 VALUES (2);
#
# connection default
LOCK TABLE t1 WRITE;
SET DEBUG_SYNC='mdl_upgrade_shared_lock_to_exclusive SIGNAL waiting';
TRUNCATE TABLE t1;
#
# connection con1
SET DEBUG_SYNC='now WAIT_FOR waiting';
COMMIT;
#
# connection default
ERROR 42S02: Table 'test.t1' doesn't exist
UNLOCK TABLES;
DROP TABLE t1;
ERROR 42S02: Unknown table 't1'
SET DEBUG_SYNC='RESET';
CREATE TABLE t1 (c1 INT);
INSERT INTO t1 VALUES (1);
#
# connection con1
START TRANSACTION;
INSERT INTO t1 VALUES (2);
#
# connection default
SET DEBUG_SYNC='mdl_acquire_exclusive_locks_wait SIGNAL waiting';
TRUNCATE TABLE t1;
#
# connection con1
SET DEBUG_SYNC='now WAIT_FOR waiting';
KILL QUERY @id;
COMMIT;
#
# connection default
ERROR 70100: Query execution was interrupted
UNLOCK TABLES;
DROP TABLE t1;
SET DEBUG_SYNC='RESET';
...@@ -675,12 +675,16 @@ SELECT * FROM t3; ...@@ -675,12 +675,16 @@ SELECT * FROM t3;
--echo # Truncate MERGE table under locked tables. --echo # Truncate MERGE table under locked tables.
LOCK TABLE t1 WRITE, t2 WRITE, t3 WRITE; LOCK TABLE t1 WRITE, t2 WRITE, t3 WRITE;
INSERT INTO t1 VALUES (1); INSERT INTO t1 VALUES (1);
--error ER_LOCK_OR_ACTIVE_TRANSACTION
TRUNCATE TABLE t3; TRUNCATE TABLE t3;
SELECT * FROM t3; SELECT * FROM t3;
UNLOCK TABLES;
SELECT * FROM t1;
SELECT * FROM t2;
--echo # --echo #
--echo # Truncate child table under locked tables. --echo # Truncate child table under locked tables.
--error ER_LOCK_OR_ACTIVE_TRANSACTION LOCK TABLE t1 WRITE, t2 WRITE, t3 WRITE;
INSERT INTO t1 VALUES (1);
INSERT INTO t2 VALUES (2);
TRUNCATE TABLE t1; TRUNCATE TABLE t1;
SELECT * FROM t3; SELECT * FROM t3;
UNLOCK TABLES; UNLOCK TABLES;
...@@ -706,14 +710,18 @@ SELECT * FROM t3; ...@@ -706,14 +710,18 @@ SELECT * FROM t3;
INSERT INTO t1 VALUES (1); INSERT INTO t1 VALUES (1);
CREATE TABLE t4 (c1 INT, INDEX(c1)); CREATE TABLE t4 (c1 INT, INDEX(c1));
LOCK TABLE t4 WRITE; LOCK TABLE t4 WRITE;
--error ER_LOCK_OR_ACTIVE_TRANSACTION
TRUNCATE TABLE t3; TRUNCATE TABLE t3;
SELECT * FROM t3; SELECT * FROM t3;
SELECT * FROM t1;
SELECT * FROM t2;
--echo # --echo #
--echo # Truncate temporary child table under locked tables. --echo # Truncate temporary child table under locked tables.
--error ER_LOCK_OR_ACTIVE_TRANSACTION INSERT INTO t1 VALUES (1);
INSERT INTO t2 VALUES (2);
TRUNCATE TABLE t1; TRUNCATE TABLE t1;
SELECT * FROM t3; SELECT * FROM t3;
SELECT * FROM t1;
SELECT * FROM t2;
UNLOCK TABLES; UNLOCK TABLES;
DROP TABLE t1, t2, t3, t4; DROP TABLE t1, t2, t3, t4;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
# Test of truncate # Test of truncate
# #
--disable_warnings --disable_warnings
drop table if exists t1; drop table if exists t1, t2;
--enable_warnings --enable_warnings
create table t1 (a integer, b integer,c1 CHAR(10)); create table t1 (a integer, b integer,c1 CHAR(10));
...@@ -69,6 +69,77 @@ drop table t1; ...@@ -69,6 +69,77 @@ drop table t1;
# End of 5.0 tests # End of 5.0 tests
--echo #
--echo # Bug#20667 - Truncate table fails for a write locked table
--echo #
CREATE TABLE t1 (c1 INT);
LOCK TABLE t1 WRITE;
INSERT INTO t1 VALUES (1);
SELECT * FROM t1;
TRUNCATE TABLE t1;
SELECT * FROM t1;
UNLOCK TABLES;
#
LOCK TABLE t1 READ;
--error ER_TABLE_NOT_LOCKED_FOR_WRITE
TRUNCATE TABLE t1;
UNLOCK TABLES;
#
CREATE TABLE t2 (c1 INT);
LOCK TABLE t2 WRITE;
--error ER_TABLE_NOT_LOCKED
TRUNCATE TABLE t1;
UNLOCK TABLES;
#
CREATE VIEW v1 AS SELECT t1.c1 FROM t1,t2 WHERE t1.c1 = t2.c1;
INSERT INTO t1 VALUES (1), (2), (3);
INSERT INTO t2 VALUES (1), (3), (4);
SELECT * FROM v1;
--error ER_NO_SUCH_TABLE
TRUNCATE v1;
SELECT * FROM v1;
#
LOCK TABLE t1 WRITE;
--error ER_TABLE_NOT_LOCKED
SELECT * FROM v1;
--error ER_NO_SUCH_TABLE
TRUNCATE v1;
--error ER_TABLE_NOT_LOCKED
SELECT * FROM v1;
UNLOCK TABLES;
#
LOCK TABLE t1 WRITE, t2 WRITE;
--error ER_TABLE_NOT_LOCKED
SELECT * FROM v1;
--error ER_NO_SUCH_TABLE
TRUNCATE v1;
--error ER_TABLE_NOT_LOCKED
SELECT * FROM v1;
UNLOCK TABLES;
#
LOCK TABLE v1 WRITE;
SELECT * FROM v1;
--error ER_NO_SUCH_TABLE
TRUNCATE v1;
SELECT * FROM v1;
UNLOCK TABLES;
#
LOCK TABLE t1 WRITE, t2 WRITE, v1 WRITE;
SELECT * FROM v1;
--error ER_NO_SUCH_TABLE
TRUNCATE v1;
SELECT * FROM v1;
UNLOCK TABLES;
#
DROP VIEW v1;
DROP TABLE t1, t2;
#
CREATE PROCEDURE p1() SET @a = 5;
--error ER_NO_SUCH_TABLE
TRUNCATE p1;
SHOW CREATE PROCEDURE p1;
DROP PROCEDURE p1;
--echo # --echo #
--echo # Bug#46452 Crash in MDL, HANDLER OPEN + TRUNCATE TABLE --echo # Bug#46452 Crash in MDL, HANDLER OPEN + TRUNCATE TABLE
--echo # --echo #
......
#
# Code coverage testing of TRUNCATE TABLE.
#
# Ingo Struewing, 2009-07-20
#
--source include/have_debug_sync.inc
SET DEBUG_SYNC='RESET';
--let $MYSQLD_DATADIR= `SELECT @@datadir`
--disable_warnings
DROP TABLE IF EXISTS t1;
--enable_warnings
--echo #
--echo # Bug#20667 - Truncate table fails for a write locked table
--echo #
########
# Attack wait_while_table_is_used(). Kill query while trying to
# upgrade MDL.
#
CREATE TABLE t1 (c1 INT);
INSERT INTO t1 VALUES (1);
#
# Start a transaction and execute a DML in it. Since 5.4.4 this leaves
# a shared meta data lock (MDL) behind. TRUNCATE shall block on it.
#
--echo #
--echo # connection con1
--connect (con1, localhost, root,,)
START TRANSACTION;
INSERT INTO t1 VALUES (2);
#
# Get connection id of default connection.
# Lock the table and start TRUNCATE, which will block on MDL upgrade.
#
--echo #
--echo # connection default
--connection default
let $ID= `SELECT @id := CONNECTION_ID()`;
LOCK TABLE t1 WRITE;
SET DEBUG_SYNC='mdl_upgrade_shared_lock_to_exclusive SIGNAL waiting';
send TRUNCATE TABLE t1;
#
# Get the default connection ID into a variable in an invisible statement.
# Kill the TRUNCATE query. This shall result in an error return
# from wait_while_table_is_used().
#
--echo #
--echo # connection con1
--connection con1
SET DEBUG_SYNC='now WAIT_FOR waiting';
let $invisible_assignment_in_select = `SELECT @id := $ID`;
KILL QUERY @id;
COMMIT;
--disconnect con1
--echo #
--echo # connection default
--connection default
--error ER_QUERY_INTERRUPTED
reap;
UNLOCK TABLES;
DROP TABLE t1;
SET DEBUG_SYNC='RESET';
########
# Attack reopen_tables(). Remove form file.
#
CREATE TABLE t1 (c1 INT);
INSERT INTO t1 VALUES (1);
#
# Start a transaction and execute a DML in it. Since 5.4.4 this leaves
# a shared meta data lock (MDL) behind. TRUNCATE shall block on it.
#
--echo #
--echo # connection con1
--connect (con1, localhost, root,,)
START TRANSACTION;
INSERT INTO t1 VALUES (2);
#
# Lock the table and start TRUNCATE, which will block on MDL upgrade.
#
--echo #
--echo # connection default
--connection default
LOCK TABLE t1 WRITE;
SET DEBUG_SYNC='mdl_upgrade_shared_lock_to_exclusive SIGNAL waiting';
send TRUNCATE TABLE t1;
#
# Remove datafile.
# Commit to let TRUNCATE continue.
#
--echo #
--echo # connection con1
--connection con1
SET DEBUG_SYNC='now WAIT_FOR waiting';
--remove_file $MYSQLD_DATADIR/test/t1.frm
COMMIT;
--disconnect con1
--echo #
--echo # connection default
--connection default
--error ER_NO_SUCH_TABLE
reap;
UNLOCK TABLES;
--error ER_BAD_TABLE_ERROR
DROP TABLE t1;
SET DEBUG_SYNC='RESET';
########
# Attack acquire_exclusive_locks(). Hold a global read lock.
# Non-LOCK TABLE case.
#
CREATE TABLE t1 (c1 INT);
INSERT INTO t1 VALUES (1);
#
# Start a transaction and execute a DML in it. Since 5.4.4 this leaves
# a shared meta data lock (MDL) behind. TRUNCATE shall block on it.
#
--echo #
--echo # connection con1
--connect (con1, localhost, root,,)
START TRANSACTION;
INSERT INTO t1 VALUES (2);
#
# Get connection id of default connection.
# Start TRUNCATE, which will block on acquire_exclusive_locks().
#
--echo #
--echo # connection default
--connection default
let $ID= `SELECT @id := CONNECTION_ID()`;
SET DEBUG_SYNC='mdl_acquire_exclusive_locks_wait SIGNAL waiting';
send TRUNCATE TABLE t1;
#
# Get the default connection ID into a variable in an invisible statement.
# Kill the TRUNCATE query. This shall result in an error return
# from wait_while_table_is_used().
#
--echo #
--echo # connection con1
--connection con1
SET DEBUG_SYNC='now WAIT_FOR waiting';
let $invisible_assignment_in_select = `SELECT @id := $ID`;
KILL QUERY @id;
COMMIT;
--disconnect con1
--echo #
--echo # connection default
--connection default
--error ER_QUERY_INTERRUPTED
reap;
UNLOCK TABLES;
DROP TABLE t1;
SET DEBUG_SYNC='RESET';
...@@ -1098,9 +1098,15 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok) ...@@ -1098,9 +1098,15 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok)
HA_CREATE_INFO create_info; HA_CREATE_INFO create_info;
char path[FN_REFLEN + 1]; char path[FN_REFLEN + 1];
TABLE *table; TABLE *table;
bool error; bool error= TRUE;
uint path_length; uint path_length;
MDL_request mdl_request; MDL_request mdl_request;
/*
Is set if we're under LOCK TABLES, and used
to downgrade the exclusive lock after the
table was truncated.
*/
MDL_ticket *mdl_ticket= NULL;
bool has_mdl_lock= FALSE; bool has_mdl_lock= FALSE;
DBUG_ENTER("mysql_truncate"); DBUG_ENTER("mysql_truncate");
...@@ -1177,21 +1183,47 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok) ...@@ -1177,21 +1183,47 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok)
thd->lex->alter_info.flags & ALTER_ADMIN_PARTITION) thd->lex->alter_info.flags & ALTER_ADMIN_PARTITION)
goto trunc_by_del; goto trunc_by_del;
mdl_request.init(MDL_key::TABLE, table_list->db, table_list->table_name, MDL_EXCLUSIVE);
if (thd->locked_tables_mode)
{
if (!(table= find_write_locked_table(thd->open_tables, table_list->db,
table_list->table_name)))
DBUG_RETURN(TRUE);
mdl_ticket= table->mdl_ticket;
if (wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN))
goto end;
close_all_tables_for_name(thd, table->s, FALSE);
}
else
{
/*
Even though we could use the previous execution branch
here just as well, we must not try to open the table:
MySQL manual documents that TRUNCATE can be used to
repair a damaged table, i.e. a table that can not be
fully "opened". In particular MySQL manual says:
As long as the table format file tbl_name.frm is valid,
the table can be re-created as an empty table with TRUNCATE
TABLE, even if the data or index files have become corrupted.
*/
mdl_request.init(MDL_key::TABLE, table_list->db, table_list->table_name,
MDL_EXCLUSIVE);
if (thd->mdl_context.acquire_exclusive_lock(&mdl_request)) if (thd->mdl_context.acquire_exclusive_lock(&mdl_request))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
has_mdl_lock= TRUE; has_mdl_lock= TRUE;
pthread_mutex_lock(&LOCK_open); pthread_mutex_lock(&LOCK_open);
tdc_remove_table(thd, TDC_RT_REMOVE_ALL, table_list->db, tdc_remove_table(thd, TDC_RT_REMOVE_ALL, table_list->db,
table_list->table_name); table_list->table_name);
pthread_mutex_unlock(&LOCK_open); pthread_mutex_unlock(&LOCK_open);
} }
}
// Remove the .frm extension AIX 5.2 64-bit compiler bug (BUG#16155): this /*
// crashes, replacement works. *(path + path_length - reg_ext_length)= Remove the .frm extension AIX 5.2 64-bit compiler bug (BUG#16155): this
// '\0'; crashes, replacement works. *(path + path_length - reg_ext_length)=
'\0';
*/
path[path_length - reg_ext_length] = 0; path[path_length - reg_ext_length] = 0;
pthread_mutex_lock(&LOCK_open); pthread_mutex_lock(&LOCK_open);
error= ha_create_table(thd, path, table_list->db, table_list->table_name, error= ha_create_table(thd, path, table_list->db, table_list->table_name,
...@@ -1202,6 +1234,12 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok) ...@@ -1202,6 +1234,12 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok)
end: end:
if (!dont_send_ok) if (!dont_send_ok)
{ {
if (thd->locked_tables_mode && thd->locked_tables_list.reopen_tables(thd))
thd->locked_tables_list.unlink_all_closed_tables(thd, NULL, 0);
/*
Even if we failed to reopen some tables,
the operation itself succeeded, write the binlog.
*/
if (!error) if (!error)
{ {
/* /*
...@@ -1213,12 +1251,11 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok) ...@@ -1213,12 +1251,11 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok)
} }
if (has_mdl_lock) if (has_mdl_lock)
thd->mdl_context.release_lock(mdl_request.ticket); thd->mdl_context.release_lock(mdl_request.ticket);
if (mdl_ticket)
mdl_ticket->downgrade_exclusive_lock();
} }
else if (error)
{ DBUG_PRINT("exit", ("error: %d", error));
if (has_mdl_lock)
thd->mdl_context.release_lock(mdl_request.ticket);
}
DBUG_RETURN(error); DBUG_RETURN(error);
trunc_by_del: trunc_by_del:
......
...@@ -3078,7 +3078,7 @@ case SQLCOM_PREPARE: ...@@ -3078,7 +3078,7 @@ case SQLCOM_PREPARE:
Don't allow this within a transaction because we want to use Don't allow this within a transaction because we want to use
re-generate table re-generate table
*/ */
if (thd->locked_tables_mode || thd->active_transaction()) if (thd->active_transaction())
{ {
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION, my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0)); ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
......
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