Commit 6438ca9f authored by Jon Olav Hauglid's avatar Jon Olav Hauglid

Backport of revno: 2617.81.4

Bug #47274 assert in open_table on CREATE TABLE <already existing>

The problem was an assertion during execution of CREATE TABLES. 
This assertion would occur if INSERT DELAYED or REPLACE DELAYED
were used to update a table containing an AUTO_INCREMENT column
and if the inserted row had a user-supplied value for that column.
Any CREATE TABLE statement (including CREATE TABLE SELECT and
CREATE TABLE LIKE) trying to create the same table and 
which followed the INSERT/REPLACED would cause the assertion.

The problem was only noticeable on debug builds of the server
and not present in the mysql-5.1 tree.

The cause of the problem was that the code for delayed insert did
not properly reset the TABLE->auto_increment_if_null flag after 
The flag is used to indicate that a non-null value of an auto_increment field
has been provided by the user or retrieved from a current record.
Open_tables() contains an assertion that tests this flag, and this
was triggered by CREATE TABLE.

This patch fixes the problem by resetting the auto_increment_if_null
field to FALSE once INSERT/REPLACE DELAYED has updated the table, 
similar to what is done already for regular INSERT statements.

Test case added to delayed.test.
parent 7fc88467
...@@ -311,3 +311,25 @@ a b ...@@ -311,3 +311,25 @@ a b
drop table t1; drop table t1;
set global low_priority_updates = @old_delayed_updates; set global low_priority_updates = @old_delayed_updates;
End of 5.1 tests End of 5.1 tests
#
# Bug #47274 assert in open_table on CREATE TABLE <already existing>
#
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t2;
CREATE TABLE t1 ( f1 INTEGER AUTO_INCREMENT, PRIMARY KEY (f1));
# The following CREATE TABLEs before gave an assert.
INSERT DELAYED t1 VALUES (4);
CREATE TABLE t1 AS SELECT 1 AS f1;
ERROR 42S01: Table 't1' already exists
REPLACE DELAYED t1 VALUES (5);
CREATE TABLE t1 AS SELECT 1 AS f1;
ERROR 42S01: Table 't1' already exists
INSERT DELAYED t1 VALUES (6);
CREATE TABLE t1 (f1 INTEGER);
ERROR 42S01: Table 't1' already exists
CREATE TABLE t2 (f1 INTEGER);
INSERT DELAYED t1 VALUES (7);
CREATE TABLE t1 LIKE t2;
ERROR 42S01: Table 't1' already exists
DROP TABLE t2;
DROP TABLE t1;
...@@ -329,3 +329,38 @@ drop table t1; ...@@ -329,3 +329,38 @@ drop table t1;
set global low_priority_updates = @old_delayed_updates; set global low_priority_updates = @old_delayed_updates;
--echo End of 5.1 tests --echo End of 5.1 tests
--echo #
--echo # Bug #47274 assert in open_table on CREATE TABLE <already existing>
--echo #
--disable_warnings
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t2;
--enable_warnings
CREATE TABLE t1 ( f1 INTEGER AUTO_INCREMENT, PRIMARY KEY (f1));
--echo # The following CREATE TABLEs before gave an assert.
INSERT DELAYED t1 VALUES (4);
--error ER_TABLE_EXISTS_ERROR
CREATE TABLE t1 AS SELECT 1 AS f1;
REPLACE DELAYED t1 VALUES (5);
--error ER_TABLE_EXISTS_ERROR
CREATE TABLE t1 AS SELECT 1 AS f1;
INSERT DELAYED t1 VALUES (6);
--error ER_TABLE_EXISTS_ERROR
CREATE TABLE t1 (f1 INTEGER);
CREATE TABLE t2 (f1 INTEGER);
INSERT DELAYED t1 VALUES (7);
--error ER_TABLE_EXISTS_ERROR
CREATE TABLE t1 LIKE t2;
DROP TABLE t2;
DROP TABLE t1;
...@@ -2729,6 +2729,12 @@ bool Delayed_insert::handle_inserts(void) ...@@ -2729,6 +2729,12 @@ bool Delayed_insert::handle_inserts(void)
thread_safe_increment(delayed_insert_writes,&LOCK_delayed_status); thread_safe_increment(delayed_insert_writes,&LOCK_delayed_status);
pthread_mutex_lock(&mutex); pthread_mutex_lock(&mutex);
/*
Reset the table->auto_increment_field_not_null as it is valid for
only one row.
*/
table->auto_increment_field_not_null= FALSE;
delete row; delete row;
/* /*
Let READ clients do something once in a while Let READ clients do something once in a while
......
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