* remove ha_check_if_table_exists() and get_table_share_with_discover().
* rename check_if_table_exists() -> table_exists() and remove unneeded arguments
This commit is contained in:
parent
87a9d60ec6
commit
b0a5dd73fa
@ -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;
|
||||
|
@ -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,
|
||||
|
285
sql/sql_base.cc
285
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,6 +668,17 @@ 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->is_view && op == FRM_READ_TABLE_ONLY)
|
||||
{
|
||||
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->error)
|
||||
{
|
||||
/* Table definition contained an error */
|
||||
@ -680,12 +686,6 @@ TABLE_SHARE *get_table_share(THD *thd, TABLE_LIST *table_list, char *key,
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (share->is_view && op != FRM_READ_NO_ERROR_FOR_VIEW)
|
||||
{
|
||||
open_table_error(share, OPEN_FRM_NO_VIEWS, ENOENT);
|
||||
goto err;
|
||||
}
|
||||
|
||||
++share->ref_count;
|
||||
|
||||
if (share->ref_count == 1 && share->prev)
|
||||
@ -718,98 +718,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.
|
||||
|
||||
@ -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;
|
||||
DBUG_RETURN(TRUE);
|
||||
|
||||
build_table_filename(path, sizeof(path) - 1, table->db, table->table_name,
|
||||
reg_ext, 0);
|
||||
if (!path)
|
||||
{
|
||||
build_table_filename(path_buf, sizeof(path_buf) - 1,
|
||||
db, table_name, reg_ext, 0);
|
||||
path= path_buf;
|
||||
}
|
||||
|
||||
if (!access(path, F_OK))
|
||||
goto end;
|
||||
|
||||
if (fast_check)
|
||||
{
|
||||
*exists= FALSE;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* .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);
|
||||
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, ¬_used,
|
||||
FRM_READ_TABLE_ONLY, ¬_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 */
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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, ¬_used, hash_value);
|
||||
FRM_READ_TABLE_OR_VIEW, ¬_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),
|
||||
|
@ -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;
|
||||
}
|
||||
|
20
sql/table.cc
20
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:
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user