1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-27 18:02:13 +03:00

WL#5370 Keep forward-compatibility when changing

'CREATE TABLE IF NOT EXISTS ... SELECT' behaviour
BUG#47132, BUG#47442, BUG49494, BUG#23992 and BUG#48814 will disappear
automatically after the this patch.
BUG#55617 is fixed by this patch too.
            
This is the 5.5 part.
It implements:
- 'CREATE TABLE IF NOT EXISTS ... SELECT' statement will not insert
  anything and binlog anything if the table already exists.
  It only generate a warning that table already exists.
- A couple of test cases for the behavior changing.
This commit is contained in:
2010-08-18 17:35:41 +08:00
parent 8977575cff
commit d3b7cd3ff2
31 changed files with 806 additions and 302 deletions

View File

@ -3581,17 +3581,6 @@ static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
create_info, alter_info, 0,
select_field_count))
{
if (create_info->table_existed)
{
/*
This means that someone created table underneath server
or it was created via different mysqld front-end to the
cluster. We don't have much options but throw an error.
*/
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), create_table->table_name);
DBUG_RETURN(0);
}
DBUG_EXECUTE_IF("sleep_create_select_before_open", my_sleep(6000000););
if (!(create_info->options & HA_LEX_CREATE_TMP_TABLE))
@ -3709,15 +3698,13 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
TABLE const *const table = *tables;
if (thd->is_current_stmt_binlog_format_row() &&
!table->s->tmp_table &&
!ptr->get_create_info()->table_existed)
!table->s->tmp_table)
{
if (int error= ptr->binlog_show_create_table(tables, count))
return error;
}
return 0;
}
select_create *ptr;
TABLE_LIST *create_table;
TABLE_LIST *select_tables;
@ -3740,34 +3727,15 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
thd->binlog_start_trans_and_stmt();
}
DBUG_ASSERT(create_table->table == NULL);
DBUG_EXECUTE_IF("sleep_create_select_before_check_if_exists", my_sleep(6000000););
if (create_table->table)
{
/* Table already exists and was open at open_and_lock_tables() stage. */
if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
{
/* Mark that table existed */
create_info->table_existed= 1;
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
create_table->table_name);
if (thd->is_current_stmt_binlog_format_row())
binlog_show_create_table(&(create_table->table), 1);
table= create_table->table;
}
else
{
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), create_table->table_name);
DBUG_RETURN(-1);
}
}
else
if (!(table= create_table_from_items(thd, create_info, create_table,
alter_info, &values,
&extra_lock, hook_ptr)))
/* abort() deletes table */
DBUG_RETURN(-1);
if (!(table= create_table_from_items(thd, create_info, create_table,
alter_info, &values,
&extra_lock, hook_ptr)))
/* abort() deletes table */
DBUG_RETURN(-1);
if (extra_lock)
{
@ -3887,10 +3855,6 @@ void select_create::send_error(uint errcode,const char *err)
("Current table (at 0x%lu) %s a temporary (or non-existant) table",
(ulong) table,
table && !table->s->tmp_table ? "is NOT" : "is"));
DBUG_PRINT("info",
("Table %s prior to executing this statement",
get_create_info()->table_existed ? "existed" : "did not exist"));
/*
This will execute any rollbacks that are necessary before writing
the transcation cache.
@ -3979,8 +3943,7 @@ void select_create::abort_result_set()
table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
table->auto_increment_field_not_null= FALSE;
if (!create_info->table_existed)
drop_open_table(thd, table, create_table->db, create_table->table_name);
drop_open_table(thd, table, create_table->db, create_table->table_name);
table=0; // Safety
}
DBUG_VOID_RETURN;