diff options
Diffstat (limited to 'sql/sql_table.cc')
-rw-r--r-- | sql/sql_table.cc | 128 |
1 files changed, 68 insertions, 60 deletions
diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 296953b3375..0be329e76c2 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -25,7 +25,7 @@ #include "sql_table.h" #include "sql_parse.h" // test_if_data_home_dir #include "sql_cache.h" // query_cache_* -#include "sql_base.h" // open_table_uncached, lock_table_names +#include "sql_base.h" // lock_table_names #include "lock.h" // mysql_unlock_tables #include "strfunc.h" // find_type2, find_set #include "sql_truncate.h" // regenerate_locked_table @@ -2030,7 +2030,7 @@ bool mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists, LEX_STRING db_name= { table->db, table->db_length }; LEX_STRING table_name= { table->table_name, table->table_name_length }; if (table->open_type == OT_BASE_ONLY || - !find_temporary_table(thd, table)) + !thd->find_temporary_table(table)) (void) delete_statistics_for_table(thd, &db_name, &table_name); } } @@ -2283,23 +2283,17 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, */ DBUG_ASSERT(!(thd->locked_tables_mode && table->open_type != OT_BASE_ONLY && - find_temporary_table(thd, table) && + thd->find_temporary_table(table) && table->mdl_request.ticket != NULL)); - /* - drop_temporary_table may return one of the following error codes: - . 0 - a temporary table was successfully dropped. - . 1 - a temporary table was not found. - . -1 - a temporary table is used by an outer statement. - */ if (table->open_type == OT_BASE_ONLY || !is_temporary_table(table)) error= 1; else { table_creation_was_logged= table->table->s->table_creation_was_logged; - if ((error= drop_temporary_table(thd, table->table, &is_trans)) == -1) + if (thd->drop_temporary_table(table->table, &is_trans, true)) { - DBUG_ASSERT(thd->in_sub_stmt); + error= 1; goto err; } table->table= 0; @@ -4635,7 +4629,8 @@ err: which was created. @param[out] key_count Number of keys in table which was created. - If one creates a temporary table, this is automatically opened + If one creates a temporary table, its is automatically opened and its + TABLE_SHARE is added to THD::all_temp_tables list. Note that this function assumes that caller already have taken exclusive metadata lock on table being created or used some other @@ -4695,20 +4690,22 @@ int create_table_impl(THD *thd, /* Check if table exists */ if (create_info->tmp_table()) { - TABLE *tmp_table; - if (find_and_use_temporary_table(thd, db, table_name, &tmp_table)) - goto err; + /* + If a table exists, it must have been pre-opened. Try looking for one + in-use in THD::all_temp_tables list of TABLE_SHAREs. + */ + TABLE *tmp_table= thd->find_temporary_table(db, table_name); + if (tmp_table) { bool table_creation_was_logged= tmp_table->s->table_creation_was_logged; if (options.or_replace()) { - bool tmp; /* We are using CREATE OR REPLACE on an existing temporary table Remove the old table so that we can re-create it. */ - if (drop_temporary_table(thd, tmp_table, &tmp)) + if (thd->drop_temporary_table(tmp_table, NULL, true)) goto err; } else if (options.if_not_exists()) @@ -4847,17 +4844,12 @@ int create_table_impl(THD *thd, create_info->table= 0; if (!frm_only && create_info->tmp_table()) { - /* - Open a table (skipping table cache) and add it into - THD::temporary_tables list. - */ - - TABLE *table= open_table_uncached(thd, create_info->db_type, frm, path, - db, table_name, true, true); + TABLE *table= thd->create_and_open_tmp_table(create_info->db_type, frm, + path, db, table_name, true); if (!table) { - (void) rm_temporary_table(create_info->db_type, path); + (void) thd->rm_temporary_table(create_info->db_type, path); goto err; } @@ -7143,7 +7135,8 @@ static bool mysql_inplace_alter_table(THD *thd, HA_EXTRA_NOT_USED, NULL); table_list->table= table= NULL; - close_temporary_table(thd, altered_table, true, false); + + thd->drop_temporary_table(altered_table, NULL, false); /* Replace the old .FRM with the new .FRM, but keep the old name for now. @@ -7233,7 +7226,7 @@ static bool mysql_inplace_alter_table(THD *thd, thd->locked_tables_list.unlink_all_closed_tables(thd, NULL, 0); /* QQ; do something about metadata locks ? */ } - close_temporary_table(thd, altered_table, true, false); + thd->drop_temporary_table(altered_table, NULL, false); // Delete temporary .frm/.par (void) quick_rm_table(thd, create_info->db_type, alter_ctx->new_db, alter_ctx->tmp_name, FN_IS_TMP | NO_HA_TABLE); @@ -8385,7 +8378,12 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, { if (table->s->tmp_table != NO_TMP_TABLE) { - if (find_temporary_table(thd, alter_ctx.new_db, alter_ctx.new_name)) + /* + Check whether a temporary table exists with same requested new name. + If such table exists, there must be a corresponding TABLE_SHARE in + THD::all_temp_tables list. + */ + if (thd->find_tmp_table_share(alter_ctx.new_db, alter_ctx.new_name)) { my_error(ER_TABLE_EXISTS_ERROR, MYF(0), alter_ctx.new_alias); DBUG_RETURN(true); @@ -8821,11 +8819,11 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, // We assume that the table is non-temporary. DBUG_ASSERT(!table->s->tmp_table); - if (!(altered_table= open_table_uncached(thd, new_db_type, &frm, - alter_ctx.get_tmp_path(), - alter_ctx.new_db, - alter_ctx.tmp_name, - true, false))) + if (!(altered_table= + thd->create_and_open_tmp_table(new_db_type, &frm, + alter_ctx.get_tmp_path(), + alter_ctx.new_db, alter_ctx.tmp_name, + false))) goto err_new_table_cleanup; /* Set markers for fields in TABLE object for altered table. */ @@ -8865,7 +8863,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, { ha_alter_info.report_unsupported_error("LOCK=NONE/SHARED", "LOCK=EXCLUSIVE"); - close_temporary_table(thd, altered_table, true, false); + thd->drop_temporary_table(altered_table, NULL, false); goto err_new_table_cleanup; } break; @@ -8876,7 +8874,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, Alter_info::ALTER_TABLE_LOCK_NONE) { ha_alter_info.report_unsupported_error("LOCK=NONE", "LOCK=SHARED"); - close_temporary_table(thd, altered_table, true, false); + thd->drop_temporary_table(altered_table, NULL, false); goto err_new_table_cleanup; } break; @@ -8890,7 +8888,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, { ha_alter_info.report_unsupported_error("ALGORITHM=INPLACE", "ALGORITHM=COPY"); - close_temporary_table(thd, altered_table, true, false); + thd->drop_temporary_table(altered_table, NULL, false); goto err_new_table_cleanup; } // COPY with LOCK=NONE is not supported, no point in trying. @@ -8898,7 +8896,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, Alter_info::ALTER_TABLE_LOCK_NONE) { ha_alter_info.report_unsupported_error("LOCK=NONE", "LOCK=SHARED"); - close_temporary_table(thd, altered_table, true, false); + thd->drop_temporary_table(altered_table, NULL, false); goto err_new_table_cleanup; } // Otherwise use COPY @@ -8906,7 +8904,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, break; case HA_ALTER_ERROR: default: - close_temporary_table(thd, altered_table, true, false); + thd->drop_temporary_table(altered_table, NULL, false); goto err_new_table_cleanup; } @@ -8925,7 +8923,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, } else { - close_temporary_table(thd, altered_table, true, false); + thd->drop_temporary_table(altered_table, NULL, false); } } @@ -8978,13 +8976,18 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, if (create_info->tmp_table()) { - if (!open_table_uncached(thd, new_db_type, &frm, - alter_ctx.get_tmp_path(), - alter_ctx.new_db, alter_ctx.tmp_name, - true, true)) + TABLE *tmp_table= + thd->create_and_open_tmp_table(new_db_type, &frm, + alter_ctx.get_tmp_path(), + alter_ctx.new_db, alter_ctx.tmp_name, + true); + if (!tmp_table) + { goto err_new_table_cleanup; + } } + /* Open the table since we need to copy the data. */ if (table->s->tmp_table != NO_TMP_TABLE) { @@ -8992,18 +8995,24 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, tbl.init_one_table(alter_ctx.new_db, strlen(alter_ctx.new_db), alter_ctx.tmp_name, strlen(alter_ctx.tmp_name), alter_ctx.tmp_name, TL_READ_NO_INSERT); - /* Table is in thd->temporary_tables */ - (void) open_temporary_table(thd, &tbl); + /* + Table can be found in the list of open tables in THD::all_temp_tables + list. + */ + tbl.table= thd->find_temporary_table(&tbl); new_table= tbl.table; } else { - /* table is a normal table: Create temporary table in same directory */ - /* Open our intermediate table. */ - new_table= open_table_uncached(thd, new_db_type, &frm, - alter_ctx.get_tmp_path(), - alter_ctx.new_db, alter_ctx.tmp_name, - true, true); + /* + table is a normal table: Create temporary table in same directory. + Open our intermediate table. + */ + new_table= + thd->create_and_open_tmp_table(new_db_type, &frm, + alter_ctx.get_tmp_path(), + alter_ctx.new_db, alter_ctx.tmp_name, + true); } if (!new_table) goto err_new_table_cleanup; @@ -9071,10 +9080,10 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, new_table->s->table_creation_was_logged= table->s->table_creation_was_logged; /* Remove link to old table and rename the new one */ - close_temporary_table(thd, table, true, true); + thd->drop_temporary_table(table, NULL, true); /* Should pass the 'new_name' as we store table name in the cache */ - if (rename_temporary_table(thd, new_table, - alter_ctx.new_db, alter_ctx.new_name)) + if (thd->rename_temporary_table(new_table, alter_ctx.new_db, + alter_ctx.new_name)) goto err_new_table_cleanup; /* We don't replicate alter table statement on temporary tables */ if (!thd->is_current_stmt_binlog_format_row() && @@ -9086,10 +9095,10 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, /* Close the intermediate table that will be the new table, but do - not delete it! Even altough MERGE tables do not have their children - attached here it is safe to call close_temporary_table(). + not delete it! Even though MERGE tables do not have their children + attached here it is safe to call THD::drop_temporary_table(). */ - close_temporary_table(thd, new_table, true, false); + thd->drop_temporary_table(new_table, NULL, false); new_table= NULL; DEBUG_SYNC(thd, "alter_table_before_rename_result_table"); @@ -9231,8 +9240,7 @@ err_new_table_cleanup: my_free(const_cast<uchar*>(frm.str)); if (new_table) { - /* close_temporary_table() frees the new_table pointer. */ - close_temporary_table(thd, new_table, true, true); + thd->drop_temporary_table(new_table, NULL, true); } else (void) quick_rm_table(thd, new_db_type, @@ -9732,7 +9740,7 @@ bool mysql_checksum_table(THD *thd, TABLE_LIST *tables, /* Allow to open real tables only. */ table->required_type= FRMTYPE_TABLE; - if (open_temporary_tables(thd, table) || + if (thd->open_temporary_tables(table) || open_and_lock_tables(thd, table, FALSE, 0)) { t= NULL; |