summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Golubchik <sergii@pisem.net>2013-04-09 15:35:15 +0200
committerSergei Golubchik <sergii@pisem.net>2013-04-09 15:35:15 +0200
commitb0a5dd73fa7d9f239661cc1683422f14e69c53eb (patch)
tree803e21ef37e2ba4007e74866435694d77e4df06a
parent87a9d60ec625c8f1e8563de648105b36add9e940 (diff)
downloadmariadb-git-b0a5dd73fa7d9f239661cc1683422f14e69c53eb.tar.gz
* remove ha_check_if_table_exists() and get_table_share_with_discover().
* rename check_if_table_exists() -> table_exists() and remove unneeded arguments
-rw-r--r--sql/handler.cc27
-rw-r--r--sql/handler.h2
-rw-r--r--sql/sql_base.cc281
-rw-r--r--sql/sql_base.h11
-rw-r--r--sql/sql_db.cc8
-rw-r--r--sql/sql_show.cc11
-rw-r--r--sql/sql_table.cc49
-rw-r--r--sql/table.cc20
-rw-r--r--sql/table.h6
9 files changed, 117 insertions, 298 deletions
diff --git a/sql/handler.cc b/sql/handler.cc
index 58e8524dd8d..8da997c2df2 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -4203,33 +4203,6 @@ int ha_create_table_from_engine(THD* thd, const char *db, const char *name)
}
-/**
- Try to find a table in a storage engine.
-
- @param db Normalized table schema name
- @param name Normalized table name.
- @param[out] exists Only valid if the function succeeded.
-
- @retval TRUE An error is found
- @retval FALSE Success, check *exists
-*/
-
-bool
-ha_check_if_table_exists(THD* thd, const char *db, const char *name,
- bool *exists)
-{
- uchar *frmblob= NULL;
- size_t frmlen;
- DBUG_ENTER("ha_check_if_table_exists");
-
- *exists= ! ha_discover(thd, db, name, &frmblob, &frmlen);
- if (*exists)
- my_free(frmblob);
-
- DBUG_RETURN(FALSE);
-}
-
-
void st_ha_check_opt::init()
{
flags= sql_flags= 0;
diff --git a/sql/handler.h b/sql/handler.h
index 93edfb2296e..79e757c5649 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -3068,8 +3068,6 @@ bool ha_show_status(THD *thd, handlerton *db_type, enum ha_stat_type stat);
/* discovery */
int ha_create_table_from_engine(THD* thd, const char *db, const char *name);
-bool ha_check_if_table_exists(THD* thd, const char *db, const char *name,
- bool *exists);
int ha_discover(THD* thd, const char* dbname, const char* name,
uchar** frmblob, size_t* frmlen);
int ha_discover_table_names(THD *thd, LEX_STRING *db, MY_DIR *dirp,
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index cbcd8045348..6f393f3329c 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -575,18 +575,13 @@ static void table_def_unuse_table(TABLE *table)
table_list Table that should be opened
key Table cache key
key_length Length of key
- db_flags Flags to open_table_def():
- OPEN_VIEW
+ op operation: what to open table or view
error out: Error code from open_table_def()
IMPLEMENTATION
Get a table definition from the table definition cache.
If it doesn't exist, create a new from the table definition file.
- NOTES
- We must have wrlock on LOCK_open when we come here
- (To be changed later)
-
RETURN
0 Error
# Share for table
@@ -673,16 +668,21 @@ TABLE_SHARE *get_table_share(THD *thd, TABLE_LIST *table_list, char *key,
We found an existing table definition. Return it if we didn't get
an error when reading the table definition from file.
*/
- if (share->error)
+ if (share->is_view && op == FRM_READ_TABLE_ONLY)
{
- /* Table definition contained an error */
- open_table_error(share, share->error, share->open_errno);
+ open_table_error(share, OPEN_FRM_NOT_A_TABLE, ENOENT);
+ goto err;
+ }
+ if (!share->is_view && op == FRM_READ_VIEW_ONLY)
+ {
+ open_table_error(share, OPEN_FRM_NOT_A_VIEW, ENOENT);
goto err;
}
- if (share->is_view && op != FRM_READ_NO_ERROR_FOR_VIEW)
+ if (share->error)
{
- open_table_error(share, OPEN_FRM_NO_VIEWS, ENOENT);
+ /* Table definition contained an error */
+ open_table_error(share, share->error, share->open_errno);
goto err;
}
@@ -719,98 +719,6 @@ end:
/**
- Get a table share. If it didn't exist, try creating it from engine
-
- For arguments and return values, see get_table_share()
-*/
-
-static TABLE_SHARE *
-get_table_share_with_discover(THD *thd, TABLE_LIST *table_list,
- char *key, uint key_length,
- enum read_frm_op op, enum open_frm_error *error,
- my_hash_value_type hash_value)
-
-{
- TABLE_SHARE *share;
- bool exists;
- DBUG_ENTER("get_table_share_with_discover");
-
- share= get_table_share(thd, table_list, key, key_length, op, error,
- hash_value);
- /*
- If share is not NULL, we found an existing share.
-
- If share is NULL, and there is no error, we're inside
- pre-locking, which silences 'ER_NO_SUCH_TABLE' errors
- with the intention to silently drop non-existing tables
- from the pre-locking list. In this case we still need to try
- auto-discover before returning a NULL share.
-
- Or, we're inside SHOW CREATE VIEW, which
- also installs a silencer for ER_NO_SUCH_TABLE error.
-
- If share is NULL and the error is ER_NO_SUCH_TABLE, this is
- the same as above, only that the error was not silenced by
- pre-locking or SHOW CREATE VIEW.
-
- In both these cases it won't harm to try to discover the
- table.
-
- Finally, if share is still NULL, it's a real error and we need
- to abort.
-
- @todo Rework alternative ways to deal with ER_NO_SUCH TABLE.
- */
- if (share ||
- (thd->is_error() && thd->stmt_da->sql_errno() != ER_NO_SUCH_TABLE &&
- thd->stmt_da->sql_errno() != ER_NO_SUCH_TABLE_IN_ENGINE))
- DBUG_RETURN(share);
-
- *error= OPEN_FRM_OK;
-
- /* Table didn't exist. Check if some engine can provide it */
- if (ha_check_if_table_exists(thd, table_list->db, table_list->table_name,
- &exists))
- {
- thd->clear_error();
- /* Conventionally, the storage engine API does not report errors. */
- my_error(ER_OUT_OF_RESOURCES, MYF(0));
- }
- else if (! exists)
- {
- /*
- No such table in any engine.
- Hide "Table doesn't exist" errors if the table belongs to a view.
- The check for thd->is_error() is necessary to not push an
- unwanted error in case the error was already silenced.
- @todo Rework the alternative ways to deal with ER_NO_SUCH TABLE.
- */
- if (thd->is_error())
- {
- if (table_list->parent_l)
- {
- thd->clear_error();
- my_error(ER_WRONG_MRG_TABLE, MYF(0));
- }
- else if (table_list->belong_to_view)
- {
- TABLE_LIST *view= table_list->belong_to_view;
- thd->clear_error();
- my_error(ER_VIEW_INVALID, MYF(0),
- view->view_db.str, view->view_name.str);
- }
- }
- }
- else
- {
- thd->clear_error();
- *error= OPEN_FRM_DISCOVER; /* Run auto-discover. */
- }
- DBUG_RETURN(NULL);
-}
-
-
-/**
Mark that we are not using table share anymore.
@param share Table share
@@ -871,7 +779,7 @@ void release_table_share(TABLE_SHARE *share)
# TABLE_SHARE for table
*/
-TABLE_SHARE *get_cached_table_share(const char *db, const char *table_name)
+static TABLE_SHARE *get_cached_table_share(const char *db, const char *table_name)
{
char key[SAFE_NAME_LEN*2+2];
uint key_length;
@@ -2445,10 +2353,9 @@ void drop_open_table(THD *thd, TABLE *table, const char *db_name,
or in some storage engine.
@param thd Thread context
- @param table Table list element
- @param fast_check Check only if share or .frm file exists
- @param[out] exists Out parameter which is set to TRUE if table
- exists and to FALSE otherwise.
+ @param db database name
+ @param table_name table name
+ @param path (optional) path to the frm file
@note This function acquires LOCK_open internally.
@@ -2460,48 +2367,36 @@ void drop_open_table(THD *thd, TABLE *table, const char *db_name,
@retval FALSE No error. 'exists' out parameter set accordingly.
*/
-bool check_if_table_exists(THD *thd, TABLE_LIST *table, bool fast_check,
- bool *exists)
+bool table_exists(THD *thd, const char *db, const char *table_name,
+ const char *path)
{
- char path[FN_REFLEN + 1];
+ char path_buf[FN_REFLEN + 1];
TABLE_SHARE *share;
- DBUG_ENTER("check_if_table_exists");
-
- *exists= TRUE;
-
- DBUG_ASSERT(fast_check ||
- thd->mdl_context.
- is_lock_owner(MDL_key::TABLE, table->db,
- table->table_name, MDL_SHARED));
+ DBUG_ENTER("table_exists");
mysql_mutex_lock(&LOCK_open);
- share= get_cached_table_share(table->db, table->table_name);
+ share= get_cached_table_share(db, table_name);
mysql_mutex_unlock(&LOCK_open);
if (share)
- goto end;
-
- build_table_filename(path, sizeof(path) - 1, table->db, table->table_name,
- reg_ext, 0);
-
- if (!access(path, F_OK))
- goto end;
+ DBUG_RETURN(TRUE);
- if (fast_check)
+ if (!path)
{
- *exists= FALSE;
- goto end;
+ build_table_filename(path_buf, sizeof(path_buf) - 1,
+ db, table_name, reg_ext, 0);
+ path= path_buf;
}
- /* .FRM file doesn't exist. Check if some engine can provide it. */
- if (ha_check_if_table_exists(thd, table->db, table->table_name, exists))
- {
- my_printf_error(ER_OUT_OF_RESOURCES, "Failed to open '%-.64s', error while "
- "unpacking from engine", MYF(0), table->table_name);
+ if (!access(path, F_OK))
DBUG_RETURN(TRUE);
- }
-end:
- DBUG_RETURN(FALSE);
+
+ /* .FRM file doesn't exist. Try to discover it */
+ uchar *frmblob= NULL;
+ size_t frmlen;
+ bool exists= ! ha_discover(thd, db, table_name, &frmblob, &frmlen);
+ my_free(frmblob);
+ DBUG_RETURN(exists);
}
@@ -2781,6 +2676,7 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
enum open_frm_error error;
TABLE_SHARE *share;
my_hash_value_type hash_value;
+ enum read_frm_op read_op;
DBUG_ENTER("open_table");
/* an open table operation needs a lot of the stack space */
@@ -3040,12 +2936,7 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
if (table_list->open_strategy == TABLE_LIST::OPEN_IF_EXISTS)
{
- bool exists;
-
- if (check_if_table_exists(thd, table_list, 0, &exists))
- DBUG_RETURN(TRUE);
-
- if (!exists)
+ if (!table_exists(thd, table_list))
DBUG_RETURN(FALSE);
/* Table exists. Let us try to open it. */
@@ -3053,21 +2944,41 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
else if (table_list->open_strategy == TABLE_LIST::OPEN_STUB)
DBUG_RETURN(FALSE);
+ if (table_list->i_s_requested_object & OPEN_TABLE_ONLY)
+ read_op = FRM_READ_TABLE_ONLY;
+ else
+ if (table_list->i_s_requested_object & OPEN_VIEW_ONLY)
+ read_op = FRM_READ_VIEW_ONLY;
+ else
+ read_op = FRM_READ_TABLE_OR_VIEW;
+
retry_share:
- if (!(share= get_table_share_with_discover(thd, table_list, key, key_length,
- FRM_READ_NO_ERROR_FOR_VIEW,
- &error, hash_value)))
+ share= get_table_share(thd, table_list, key, key_length,
+ read_op, &error, hash_value);
+
+ if (!share)
{
/*
- If thd->is_error() is not set, we either need discover or the error was
- silenced by the prelocking handler, in which case we should skip this
- table.
+ Hide "Table doesn't exist" errors if the table belongs to a view.
+ The check for thd->is_error() is necessary to not push an
+ unwanted error in case the error was already silenced.
+ @todo Rework the alternative ways to deal with ER_NO_SUCH TABLE.
*/
- if (error == OPEN_FRM_DISCOVER && !thd->is_error())
+ if (thd->is_error())
{
- (void) ot_ctx->request_backoff_action(Open_table_context::OT_DISCOVER,
- table_list);
+ if (table_list->parent_l)
+ {
+ thd->clear_error();
+ my_error(ER_WRONG_MRG_TABLE, MYF(0));
+ }
+ else if (table_list->belong_to_view)
+ {
+ TABLE_LIST *view= table_list->belong_to_view;
+ thd->clear_error();
+ my_error(ER_VIEW_INVALID, MYF(0),
+ view->view_db.str, view->view_name.str);
+ }
}
DBUG_RETURN(TRUE);
}
@@ -3090,12 +3001,6 @@ retry_share:
*/
if (check_and_update_table_version(thd, table_list, share))
goto err_lock;
- if (table_list->i_s_requested_object & OPEN_TABLE_ONLY)
- {
- my_error(ER_NO_SUCH_TABLE, MYF(0), table_list->db,
- table_list->table_name);
- goto err_lock;
- }
/* Open view */
if (open_new_frm(thd, share, alias,
@@ -3117,20 +3022,6 @@ retry_share:
DBUG_RETURN(FALSE);
}
- /*
- Note that situation when we are trying to open a table for what
- was a view during previous execution of PS will be handled in by
- the caller. Here we should simply open our table even if
- TABLE_LIST::view is true.
- */
-
- if (table_list->i_s_requested_object & OPEN_VIEW_ONLY)
- {
- my_error(ER_NO_SUCH_TABLE, MYF(0), table_list->db,
- table_list->table_name);
- goto err_lock;
- }
-
mysql_mutex_lock(&LOCK_open);
if (!(flags & MYSQL_OPEN_IGNORE_FLUSH) ||
(share->protected_against_usage() && !(flags & MYSQL_OPEN_FOR_REPAIR)))
@@ -3894,11 +3785,12 @@ bool tdc_open_view(THD *thd, TABLE_LIST *table_list, const char *alias,
hash_value= my_calc_hash(&table_def_cache, (uchar*) cache_key,
cache_key_length);
if (!(share= get_table_share(thd, table_list, cache_key, cache_key_length,
- FRM_READ_NO_ERROR_FOR_VIEW, &error, hash_value)))
+ FRM_READ_VIEW_ONLY, &error, hash_value)))
return TRUE;
- bool err= !share->is_view ||
- open_new_frm(thd, share, alias,
+ DBUG_ASSERT(share->is_view);
+
+ bool err= open_new_frm(thd, share, alias,
(HA_OPEN_KEYFILE | HA_OPEN_RNDFILE |
HA_GET_INDEX | HA_TRY_READ_ONLY),
READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD | flags,
@@ -3908,10 +3800,6 @@ bool tdc_open_view(THD *thd, TABLE_LIST *table_list, const char *alias,
release_table_share(share);
mysql_mutex_unlock(&LOCK_open);
- if (err)
- my_error(ER_WRONG_OBJECT, MYF(0), table_list->db,
- table_list->table_name, "VIEW");
-
return err;
}
@@ -3985,12 +3873,11 @@ static bool auto_repair_table(THD *thd, TABLE_LIST *table_list)
cache_key_length);
if (!(share= get_table_share(thd, table_list, cache_key, cache_key_length,
- FRM_READ_NO_ERROR_FOR_VIEW, &not_used,
+ FRM_READ_TABLE_ONLY, &not_used,
hash_value)))
goto end_free;
- if (share->is_view)
- goto end_release;
+ DBUG_ASSERT(! share->is_view);
if (open_table_from_share(thd, share, table_list->alias,
(uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE |
@@ -4016,7 +3903,6 @@ static bool auto_repair_table(THD *thd, TABLE_LIST *table_list)
result= FALSE;
}
-end_release:
mysql_mutex_lock(&LOCK_open);
release_table_share(share);
/* Remove the repaired share from the table cache. */
@@ -4786,7 +4672,7 @@ lock_table_names(THD *thd,
if (mdl_requests.is_empty())
DBUG_RETURN(FALSE);
- /* Check if CREATE TABLE IF NOT EXISTS was used */
+ /* Check if CREATE TABLE was used */
create_table= (tables_start && tables_start->open_strategy ==
TABLE_LIST::OPEN_IF_EXISTS);
@@ -4825,12 +4711,9 @@ lock_table_names(THD *thd,
for (;;)
{
- bool exists= TRUE;
- bool res;
-
if (create_table)
thd->push_internal_handler(&error_handler); // Avoid warnings & errors
- res= thd->mdl_context.acquire_locks(&mdl_requests, lock_wait_timeout);
+ bool res= thd->mdl_context.acquire_locks(&mdl_requests, lock_wait_timeout);
if (create_table)
thd->pop_internal_handler();
if (!res)
@@ -4840,13 +4723,10 @@ lock_table_names(THD *thd,
DBUG_RETURN(TRUE); // Return original error
/*
- We come here in the case of lock timeout when executing
- CREATE TABLE IF NOT EXISTS.
- Verify that table really exists (it should as we got a lock conflict)
+ We come here in the case of lock timeout when executing CREATE TABLE.
+ Verify that table does exist (it usually does, as we got a lock conflict)
*/
- if (check_if_table_exists(thd, tables_start, 1, &exists))
- DBUG_RETURN(TRUE); // Should never happen
- if (exists)
+ if (table_exists(thd, tables_start))
{
if (thd->lex->create_info.options & HA_LEX_CREATE_IF_NOT_EXISTS)
{
@@ -4858,17 +4738,16 @@ lock_table_names(THD *thd,
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), tables_start->table_name);
DBUG_RETURN(TRUE);
}
- /* purecov: begin inspected */
/*
- We got error from acquire_locks but table didn't exists.
- In theory this should never happen, except maybe in
- CREATE or DROP DATABASE scenario.
+ We got error from acquire_locks, but the table didn't exists.
+ This could happen if another connection runs a statement
+ involving this non-existent table, and this statement took the mdl,
+ but didn't error out with ER_NO_SUCH_TABLE yet (yes, a race condition).
We play safe and restart the original acquire_locks with the
- original timeout
+ original timeout.
*/
create_table= 0;
lock_wait_timeout= org_lock_wait_timeout;
- /* purecov: end */
}
}
diff --git a/sql/sql_base.h b/sql/sql_base.h
index e0612397361..8bcbbff556e 100644
--- a/sql/sql_base.h
+++ b/sql/sql_base.h
@@ -112,7 +112,6 @@ TABLE_SHARE *get_table_share(THD *thd, TABLE_LIST *table_list, char *key,
enum open_frm_error *error,
my_hash_value_type hash_value);
void release_table_share(TABLE_SHARE *share);
-TABLE_SHARE *get_cached_table_share(const char *db, const char *table_name);
TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type update,
uint lock_flags);
@@ -333,8 +332,14 @@ TABLE *find_table_for_mdl_upgrade(THD *thd, const char *db,
const char *table_name,
bool no_error);
void mark_tmp_table_for_reuse(TABLE *table);
-bool check_if_table_exists(THD *thd, TABLE_LIST *table, bool fast_check,
- bool *exists);
+
+bool table_exists(THD *thd, const char *db, const char *table_name,
+ const char *path);
+static inline bool table_exists(THD *thd, TABLE_LIST *table)
+{
+ return table_exists(thd, table->db, table->table_name, NULL);
+}
+
int update_virtual_fields(THD *thd, TABLE *table,
enum enum_vcol_update_mode vcol_update_mode= VCOL_UPDATE_FOR_READ);
int dynamic_column_error_message(enum_dyncol_func_result rc);
diff --git a/sql/sql_db.cc b/sql/sql_db.cc
index b287aad49ef..359f74155db 100644
--- a/sql/sql_db.cc
+++ b/sql/sql_db.cc
@@ -934,16 +934,10 @@ update_binlog:
for (tbl= tables; tbl; tbl= tbl->next_local)
{
uint tbl_name_len;
- bool exists;
char quoted_name[FN_REFLEN+3];
// Only write drop table to the binlog for tables that no longer exist.
- if (check_if_table_exists(thd, tbl, 0, &exists))
- {
- error= true;
- goto exit;
- }
- if (exists)
+ if (table_exists(thd, tbl))
continue;
my_snprintf(quoted_name, sizeof(quoted_name), "%`s", tbl->table_name);
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 45c3318987c..c99c345f13f 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -4057,12 +4057,14 @@ fill_schema_table_by_open(THD *thd, bool is_show_fields_or_keys,
of backward compatibility.
*/
if (!is_show_fields_or_keys && result && thd->is_error() &&
- thd->stmt_da->sql_errno() == ER_NO_SUCH_TABLE)
+ (thd->stmt_da->sql_errno() == ER_NO_SUCH_TABLE ||
+ thd->stmt_da->sql_errno() == ER_WRONG_OBJECT))
{
/*
Hide error for a non-existing table.
For example, this error can occur when we use a where condition
- with a db name and table, but the table does not exist.
+ with a db name and table, but the table does not exist or
+ there is a view with the same name.
*/
result= false;
thd->clear_error();
@@ -4383,7 +4385,7 @@ static int fill_schema_table_from_frm(THD *thd, TABLE_LIST *tables,
key_length= create_table_def_key(thd, key, &table_list, 0);
hash_value= my_calc_hash(&table_def_cache, (uchar*) key, key_length);
share= get_table_share(thd, &table_list, key, key_length,
- FRM_READ_NO_ERROR_FOR_VIEW, &not_used, hash_value);
+ FRM_READ_TABLE_OR_VIEW, &not_used, hash_value);
if (!share)
{
res= 0;
@@ -4407,10 +4409,7 @@ static int fill_schema_table_from_frm(THD *thd, TABLE_LIST *tables,
res= 1;
goto end_share;
}
- }
- if (share->is_view)
- {
if (open_new_frm(thd, share, table_name->str,
(uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE |
HA_GET_INDEX | HA_TRY_READ_ONLY),
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 4ab7fc28381..ea1b7b3398b 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -2279,11 +2279,8 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
}
DEBUG_SYNC(thd, "rm_table_no_locks_before_delete_table");
error= 0;
- if (drop_temporary ||
- ((access(path, F_OK) &&
- ha_create_table_from_engine(thd, db, alias)) ||
- (!drop_view &&
- dd_frm_type(thd, path, &frm_db_type) != FRMTYPE_TABLE)))
+ if (drop_temporary || !table_exists(thd, db, alias, path) ||
+ (!drop_view && dd_frm_type(thd, path, &frm_db_type) != FRMTYPE_TABLE))
{
/*
One of the following cases happened:
@@ -4320,50 +4317,10 @@ bool mysql_create_table_no_lock(THD *thd,
if (!internal_tmp_table && !(create_info->options & HA_LEX_CREATE_TMP_TABLE))
{
- if (!access(path,F_OK))
+ if (table_exists(thd, db, table_name, path))
{
if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
goto warn;
- my_error(ER_TABLE_EXISTS_ERROR,MYF(0),table_name);
- goto err;
- }
- /*
- We don't assert here, but check the result, because the table could be
- in the table definition cache and in the same time the .frm could be
- missing from the disk, in case of manual intervention which deletes
- the .frm file. The user has to use FLUSH TABLES; to clear the cache.
- Then she could create the table. This case is pretty obscure and
- therefore we don't introduce a new error message only for it.
- */
- mysql_mutex_lock(&LOCK_open);
- if (get_cached_table_share(db, table_name))
- {
- mysql_mutex_unlock(&LOCK_open);
- my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table_name);
- goto err;
- }
- mysql_mutex_unlock(&LOCK_open);
- }
-
- /*
- Check that table with given name does not already
- exist in any storage engine. In such a case it should
- be discovered and the error ER_TABLE_EXISTS_ERROR be returned
- unless user specified CREATE TABLE IF EXISTS
- An exclusive metadata lock ensures that no
- one else is attempting to discover the table. Since
- it's not on disk as a frm file, no one could be using it!
- */
- if (!(create_info->options & HA_LEX_CREATE_TMP_TABLE))
- {
- bool create_if_not_exists =
- create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS;
- bool exists_in_engine;
- ha_check_if_table_exists(thd, db, table_name, &exists_in_engine);
- if (exists_in_engine)
- {
- if (create_if_not_exists)
- goto warn;
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table_name);
goto err;
}
diff --git a/sql/table.cc b/sql/table.cc
index cd933e0e4a6..ca92909b9a7 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -685,8 +685,8 @@ enum open_frm_error open_table_def(THD *thd, TABLE_SHARE *share,
if (memcmp(head, STRING_WITH_LEN("TYPE=VIEW\n")) == 0)
{
share->is_view= 1;
- share->error= op == FRM_READ_NO_ERROR_FOR_VIEW
- ? OPEN_FRM_OK : OPEN_FRM_NO_VIEWS;
+ share->error= op == FRM_READ_TABLE_ONLY
+ ? OPEN_FRM_NOT_A_TABLE : OPEN_FRM_OK;
goto err;
}
if (!is_binary_frm_header(head))
@@ -695,6 +695,11 @@ enum open_frm_error open_table_def(THD *thd, TABLE_SHARE *share,
share->error = OPEN_FRM_CORRUPTED;
goto err;
}
+ if (op == FRM_READ_VIEW_ONLY)
+ {
+ share->error = OPEN_FRM_NOT_A_VIEW;
+ goto err;
+ }
if (my_fstat(file, &stats, MYF(0)))
goto err;
@@ -2802,7 +2807,7 @@ void open_table_error(TABLE_SHARE *share, enum open_frm_error error,
int db_errno)
{
char buff[FN_REFLEN];
- myf errortype= ME_ERROR+ME_WAITTANG; // Write fatals error to log
+ const myf errortype= ME_ERROR+ME_WAITTANG; // Write fatals error to log
DBUG_ENTER("open_table_error");
switch (error) {
@@ -2825,8 +2830,15 @@ void open_table_error(TABLE_SHARE *share, enum open_frm_error error,
break;
case OPEN_FRM_ERROR_ALREADY_ISSUED:
break;
+ case OPEN_FRM_NOT_A_VIEW:
+ my_error(ER_WRONG_OBJECT, MYF(0), share->db.str,
+ share->table_name.str, "VIEW");
+ break;
+ case OPEN_FRM_NOT_A_TABLE:
+ my_error(ER_WRONG_OBJECT, MYF(0), share->db.str,
+ share->table_name.str, "TABLE");
+ break;
case OPEN_FRM_DISCOVER:
- case OPEN_FRM_NO_VIEWS:
DBUG_ASSERT(0); // open_table_error() is never called for this one
break;
case OPEN_FRM_CORRUPTED:
diff --git a/sql/table.h b/sql/table.h
index af359377e61..1ac3dcba0ba 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -569,7 +569,8 @@ enum open_frm_error {
OPEN_FRM_CORRUPTED,
OPEN_FRM_DISCOVER,
OPEN_FRM_ERROR_ALREADY_ISSUED,
- OPEN_FRM_NO_VIEWS,
+ OPEN_FRM_NOT_A_VIEW,
+ OPEN_FRM_NOT_A_TABLE
};
/**
@@ -2448,7 +2449,8 @@ static inline void dbug_tmp_restore_column_maps(MY_BITMAP *read_set,
enum read_frm_op {
FRM_READ_TABLE_ONLY,
- FRM_READ_NO_ERROR_FOR_VIEW
+ FRM_READ_VIEW_ONLY,
+ FRM_READ_TABLE_OR_VIEW
};
size_t max_row_length(TABLE *table, const uchar *data);