Backport of:

------------------------------------------------------------
revno: 2617.68.25
committer: Dmitry Lenev <dlenev@mysql.com>
branch nick: mysql-next-bg-pre2-2
timestamp: Wed 2009-09-16 18:26:50 +0400
message:
  Follow-up for one of pre-requisite patches for fixing bug #30977
  "Concurrent statement using stored function and DROP FUNCTION
  breaks SBR".

  Made enum_mdl_namespace enum part of MDL_key class and removed MDL_
  prefix from the names of enum members. In order to do the latter
  changed name of PROCEDURE symbol to PROCEDURE_SYM (otherwise macro
  which was automatically generated for this symbol conflicted with
  MDL_key::PROCEDURE enum member).
This commit is contained in:
Konstantin Osipov 2009-12-10 11:21:38 +03:00
parent 4f85df4b95
commit 2e73ea7ea8
16 changed files with 72 additions and 59 deletions

View File

@ -416,7 +416,7 @@ static SYMBOL symbols[] = {
{ "PREV", SYM(PREV_SYM)},
{ "PRIMARY", SYM(PRIMARY_SYM)},
{ "PRIVILEGES", SYM(PRIVILEGES)},
{ "PROCEDURE", SYM(PROCEDURE)},
{ "PROCEDURE", SYM(PROCEDURE_SYM)},
{ "PROCESS" , SYM(PROCESS)},
{ "PROCESSLIST", SYM(PROCESSLIST_SYM)},
{ "PROFILE", SYM(PROFILE_SYM)},

View File

@ -957,7 +957,8 @@ bool lock_table_names(THD *thd, TABLE_LIST *table_list)
for (lock_table= table_list; lock_table; lock_table= lock_table->next_local)
{
lock_table->mdl_request.init(MDL_TABLE, lock_table->db, lock_table->table_name,
lock_table->mdl_request.init(MDL_key::TABLE,
lock_table->db, lock_table->table_name,
MDL_EXCLUSIVE);
mdl_requests.push_front(&lock_table->mdl_request);
}

View File

@ -307,7 +307,7 @@ void MDL_context::merge(MDL_context *src)
@param mdl_type The MDL lock type for the request.
*/
void MDL_request::init(enum_mdl_namespace mdl_namespace,
void MDL_request::init(MDL_key::enum_mdl_namespace mdl_namespace,
const char *db_arg,
const char *name_arg,
enum enum_mdl_type mdl_type_arg)
@ -355,7 +355,7 @@ void MDL_request::init(const MDL_key *key_arg,
*/
MDL_request *
MDL_request::create(enum_mdl_namespace mdl_namespace, const char *db,
MDL_request::create(MDL_key::enum_mdl_namespace mdl_namespace, const char *db,
const char *name, enum_mdl_type mdl_type,
MEM_ROOT *root)
{
@ -1444,7 +1444,7 @@ void MDL_context::release_global_shared_lock()
*/
bool
MDL_context::is_exclusive_lock_owner(enum_mdl_namespace mdl_namespace,
MDL_context::is_exclusive_lock_owner(MDL_key::enum_mdl_namespace mdl_namespace,
const char *db, const char *name)
{
MDL_request mdl_request;
@ -1470,7 +1470,7 @@ MDL_context::is_exclusive_lock_owner(enum_mdl_namespace mdl_namespace,
*/
bool
MDL_context::is_lock_owner(enum_mdl_namespace mdl_namespace,
MDL_context::is_lock_owner(MDL_key::enum_mdl_namespace mdl_namespace,
const char *db, const char *name)
{
MDL_key key(mdl_namespace, db, name);

View File

@ -47,20 +47,6 @@ enum enum_mdl_type {MDL_SHARED=0, MDL_SHARED_HIGH_PRIO,
enum enum_mdl_state { MDL_PENDING, MDL_ACQUIRED };
/**
Object namespaces
Different types of objects exist in different namespaces
- MDL_TABLE is for tables and views.
- MDL_FUNCTION is for stored functions.
- MDL_PROCEDURE is for stored procedures.
- MDL_TRIGGER is for triggers.
Note that although there isn't metadata locking on triggers,
it's necessary to have a separate namespace for them since
MDL_key is also used outside of the MDL subsystem.
*/
enum enum_mdl_namespace { MDL_TABLE=0, MDL_FUNCTION, MDL_PROCEDURE, MDL_TRIGGER };
/** Maximal length of key for metadata locking subsystem. */
#define MAX_MDLKEY_LENGTH (1 + NAME_LEN + 1 + NAME_LEN + 1)
@ -77,6 +63,23 @@ enum enum_mdl_namespace { MDL_TABLE=0, MDL_FUNCTION, MDL_PROCEDURE, MDL_TRIGGER
class MDL_key
{
public:
/**
Object namespaces
Different types of objects exist in different namespaces
- TABLE is for tables and views.
- FUNCTION is for stored functions.
- PROCEDURE is for stored procedures.
- TRIGGER is for triggers.
Note that although there isn't metadata locking on triggers,
it's necessary to have a separate namespace for them since
MDL_key is also used outside of the MDL subsystem.
*/
enum enum_mdl_namespace { TABLE=0,
FUNCTION,
PROCEDURE,
TRIGGER };
const uchar *ptr() const { return (uchar*) m_ptr; }
uint length() const { return m_length; }
@ -185,7 +188,8 @@ public:
MDL_key key;
public:
void init(enum_mdl_namespace namespace_arg, const char *db_arg, const char *name_arg,
void init(MDL_key::enum_mdl_namespace namespace_arg,
const char *db_arg, const char *name_arg,
enum_mdl_type mdl_type_arg);
void init(const MDL_key *key_arg, enum_mdl_type mdl_type_arg);
/** Set type of lock request. Can be only applied to pending locks. */
@ -196,9 +200,9 @@ public:
}
bool is_shared() const { return type < MDL_EXCLUSIVE; }
static MDL_request *create(enum_mdl_namespace mdl_namespace, const char *db,
const char *name, enum_mdl_type mdl_type,
MEM_ROOT *root);
static MDL_request *create(MDL_key::enum_mdl_namespace mdl_namespace,
const char *db, const char *name,
enum_mdl_type mdl_type, MEM_ROOT *root);
/*
This is to work around the ugliness of TABLE_LIST
@ -340,10 +344,11 @@ public:
void release_lock(MDL_ticket *ticket);
void release_global_shared_lock();
bool is_exclusive_lock_owner(enum_mdl_namespace mdl_namespace,
bool is_exclusive_lock_owner(MDL_key::enum_mdl_namespace mdl_namespace,
const char *db,
const char *name);
bool is_lock_owner(enum_mdl_namespace mdl_namespace, const char *db, const char *name);
bool is_lock_owner(MDL_key::enum_mdl_namespace mdl_namespace,
const char *db, const char *name);
inline bool has_locks() const
{

View File

@ -1473,7 +1473,8 @@ bool sp_add_used_routine(Query_tables_list *prelocking_ctx, Query_arena *arena,
void sp_add_used_routine(Query_tables_list *prelocking_ctx, Query_arena *arena,
sp_name *rt, char rt_type)
{
MDL_key key((rt_type == TYPE_ENUM_FUNCTION) ? MDL_FUNCTION : MDL_PROCEDURE,
MDL_key key((rt_type == TYPE_ENUM_FUNCTION) ? MDL_key::FUNCTION :
MDL_key::PROCEDURE,
rt->m_db.str, rt->m_name.str);
(void)sp_add_used_routine(prelocking_ctx, arena, &key, 0);
prelocking_ctx->sroutines_list_own_last= prelocking_ctx->sroutines_list.next;

View File

@ -3975,7 +3975,8 @@ sp_head::add_used_tables_to_table_list(THD *thd,
table->prelocking_placeholder= 1;
table->belong_to_view= belong_to_view;
table->trg_event_map= stab->trg_event_map;
table->mdl_request.init(MDL_TABLE, table->db, table->table_name, MDL_SHARED);
table->mdl_request.init(MDL_key::TABLE, table->db, table->table_name,
MDL_SHARED);
/* Everyting else should be zeroed */
@ -4017,7 +4018,8 @@ sp_add_to_query_tables(THD *thd, LEX *lex,
table->lock_type= locktype;
table->select_lex= lex->current_select;
table->cacheable_table= 1;
table->mdl_request.init(MDL_TABLE, table->db, table->table_name, MDL_SHARED);
table->mdl_request.init(MDL_key::TABLE, table->db, table->table_name,
MDL_SHARED);
lex->add_to_query_tables(table);
return table;

View File

@ -476,7 +476,7 @@ TABLE_SHARE *get_table_share(THD *thd, TABLE_LIST *table_list, char *key,
To be able perform any operation on table we should own
some kind of metadata lock on it.
*/
DBUG_ASSERT(thd->mdl_context.is_lock_owner(MDL_TABLE, table_list->db,
DBUG_ASSERT(thd->mdl_context.is_lock_owner(MDL_key::TABLE, table_list->db,
table_list->table_name));
/* Read table definition from cache */
@ -2546,7 +2546,7 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
TABLES breaks metadata locking protocol (potentially can lead
to deadlocks) it should be disallowed.
*/
if (thd->mdl_context.is_lock_owner(MDL_TABLE, table_list->db,
if (thd->mdl_context.is_lock_owner(MDL_key::TABLE, table_list->db,
table_list->table_name))
{
char path[FN_REFLEN + 1];
@ -3781,13 +3781,13 @@ open_and_process_routine(THD *thd, Query_tables_list *prelocking_ctx,
switch (rt->mdl_request.key.mdl_namespace())
{
case MDL_FUNCTION:
case MDL_PROCEDURE:
case MDL_key::FUNCTION:
case MDL_key::PROCEDURE:
{
char qname_buff[NAME_LEN*2+1+1];
sp_name name(&rt->mdl_request.key, qname_buff);
sp_head *sp;
int type= (rt->mdl_request.key.mdl_namespace() == MDL_FUNCTION) ?
int type= (rt->mdl_request.key.mdl_namespace() == MDL_key::FUNCTION) ?
TYPE_ENUM_FUNCTION : TYPE_ENUM_PROCEDURE;
if (sp_cache_routine(thd, type, &name, &sp))
@ -3800,7 +3800,7 @@ open_and_process_routine(THD *thd, Query_tables_list *prelocking_ctx,
}
}
break;
case MDL_TRIGGER:
case MDL_key::TRIGGER:
break;
default:
/* Impossible type value. */
@ -4305,7 +4305,7 @@ handle_routine(THD *thd, Query_tables_list *prelocking_ctx,
*/
if (rt != (Sroutine_hash_entry*)prelocking_ctx->sroutines_list.first ||
rt->mdl_request.key.mdl_namespace() != MDL_PROCEDURE)
rt->mdl_request.key.mdl_namespace() != MDL_key::PROCEDURE)
{
*need_prelocking= TRUE;
sp_update_stmt_used_routines(thd, prelocking_ctx, &sp->m_sroutines,
@ -8234,7 +8234,8 @@ void tdc_remove_table(THD *thd, enum_tdc_remove_table_type remove_type,
safe_mutex_assert_owner(&LOCK_open);
DBUG_ASSERT(remove_type == TDC_RT_REMOVE_UNUSED ||
thd->mdl_context.is_exclusive_lock_owner(MDL_TABLE, db, table_name));
thd->mdl_context.is_exclusive_lock_owner(MDL_key::TABLE,
db, table_name));
key_length=(uint) (strmov(strmov(key,db)+1,table_name)-key)+1;

View File

@ -1177,7 +1177,7 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok)
thd->lex->alter_info.flags & ALTER_ADMIN_PARTITION)
goto trunc_by_del;
mdl_request.init(MDL_TABLE, table_list->db, table_list->table_name, MDL_EXCLUSIVE);
mdl_request.init(MDL_key::TABLE, table_list->db, table_list->table_name, MDL_EXCLUSIVE);
if (thd->mdl_context.acquire_exclusive_lock(&mdl_request))
DBUG_RETURN(TRUE);

View File

@ -264,7 +264,7 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen)
memcpy(hash_tables->db, tables->db, dblen);
memcpy(hash_tables->table_name, tables->table_name, namelen);
memcpy(hash_tables->alias, tables->alias, aliaslen);
hash_tables->mdl_request.init(MDL_TABLE, db, name, MDL_SHARED);
hash_tables->mdl_request.init(MDL_key::TABLE, db, name, MDL_SHARED);
/* add to hash */
if (my_hash_insert(&thd->handler_tables_hash, (uchar*) hash_tables))

View File

@ -6024,7 +6024,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
ptr->next_name_resolution_table= NULL;
/* Link table in global list (all used tables) */
lex->add_to_query_tables(ptr);
ptr->mdl_request.init(MDL_TABLE, ptr->db, ptr->table_name, MDL_SHARED);
ptr->mdl_request.init(MDL_key::TABLE, ptr->db, ptr->table_name, MDL_SHARED);
DBUG_RETURN(ptr);
}

View File

@ -3081,7 +3081,7 @@ try_acquire_high_prio_shared_mdl_lock(THD *thd, TABLE_LIST *table,
bool can_deadlock)
{
bool error;
table->mdl_request.init(MDL_TABLE, table->db, table->table_name,
table->mdl_request.init(MDL_key::TABLE, table->db, table->table_name,
MDL_SHARED_HIGH_PRIO);
while (!(error=
thd->mdl_context.try_acquire_shared_lock(&table->mdl_request)) &&

View File

@ -4140,7 +4140,7 @@ bool mysql_create_table(THD *thd, const char *db, const char *table_name,
if (!(create_info->options & HA_LEX_CREATE_TMP_TABLE))
{
target_mdl_request.init(MDL_TABLE, db, table_name, MDL_EXCLUSIVE);
target_mdl_request.init(MDL_key::TABLE, db, table_name, MDL_EXCLUSIVE);
if (thd->mdl_context.try_acquire_exclusive_lock(&target_mdl_request))
{
result= TRUE;
@ -4361,7 +4361,8 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list,
uint key_length;
key_length= create_table_def_key(thd, key, table_list, 0);
table_list->mdl_request.init(MDL_TABLE, table_list->db, table_list->table_name,
table_list->mdl_request.init(MDL_key::TABLE,
table_list->db, table_list->table_name,
MDL_EXCLUSIVE);
if (thd->mdl_context.acquire_exclusive_lock(&table_list->mdl_request))
DBUG_RETURN(0);
@ -5271,7 +5272,7 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table,
}
else
{
table->mdl_request.init(MDL_TABLE, db, table_name, MDL_EXCLUSIVE);
table->mdl_request.init(MDL_key::TABLE, db, table_name, MDL_EXCLUSIVE);
if (thd->mdl_context.try_acquire_exclusive_lock(&table->mdl_request))
DBUG_RETURN(TRUE);
@ -6637,7 +6638,8 @@ view_err:
}
else
{
target_mdl_request.init(MDL_TABLE, new_db, new_name, MDL_EXCLUSIVE);
target_mdl_request.init(MDL_key::TABLE, new_db, new_name,
MDL_EXCLUSIVE);
if (thd->mdl_context.try_acquire_exclusive_lock(&target_mdl_request))
DBUG_RETURN(TRUE);
if (target_mdl_request.ticket == NULL)

View File

@ -1888,7 +1888,7 @@ bool Table_triggers_list::change_table_name(THD *thd, const char *db,
In the future, only an exclusive metadata lock will be enough.
*/
#ifndef DBUG_OFF
if (thd->mdl_context.is_exclusive_lock_owner(MDL_TABLE, db, old_table))
if (thd->mdl_context.is_exclusive_lock_owner(MDL_key::TABLE, db, old_table))
safe_mutex_assert_owner(&LOCK_open);
#endif
@ -2057,7 +2057,7 @@ add_tables_and_routines_for_triggers(THD *thd,
if (trigger)
{
MDL_key key(MDL_TRIGGER, trigger->m_db.str, trigger->m_name.str);
MDL_key key(MDL_key::TRIGGER, trigger->m_db.str, trigger->m_name.str);
if (sp_add_used_routine(prelocking_ctx, thd->stmt_arena,
&key, table_list->belong_to_view))

View File

@ -922,7 +922,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token PREV_SYM
%token PRIMARY_SYM /* SQL-2003-R */
%token PRIVILEGES /* SQL-2003-N */
%token PROCEDURE /* SQL-2003-R */
%token PROCEDURE_SYM /* SQL-2003-R */
%token PROCESS
%token PROCESSLIST_SYM
%token PROFILE_SYM
@ -5807,7 +5807,7 @@ alter:
lex->sql_command= SQLCOM_ALTER_DB_UPGRADE;
lex->name= $3;
}
| ALTER PROCEDURE sp_name
| ALTER PROCEDURE_SYM sp_name
{
LEX *lex= Lex;
@ -9439,7 +9439,7 @@ dec_num:
procedure_clause:
/* empty */
| PROCEDURE ident /* Procedure name */
| PROCEDURE_SYM ident /* Procedure name */
{
LEX *lex=Lex;
@ -9695,7 +9695,7 @@ drop:
spname->init_qname(thd);
lex->spname= spname;
}
| DROP PROCEDURE if_exists sp_name
| DROP PROCEDURE_SYM if_exists sp_name
{
LEX *lex=Lex;
if (lex->sphead)
@ -10446,7 +10446,7 @@ show_param:
{
Lex->sql_command = SQLCOM_SHOW_SLAVE_STAT;
}
| CREATE PROCEDURE sp_name
| CREATE PROCEDURE_SYM sp_name
{
LEX *lex= Lex;
@ -10466,7 +10466,7 @@ show_param:
lex->sql_command= SQLCOM_SHOW_CREATE_TRIGGER;
lex->spname= $3;
}
| PROCEDURE STATUS_SYM wild_and_where
| PROCEDURE_SYM STATUS_SYM wild_and_where
{
LEX *lex= Lex;
lex->sql_command= SQLCOM_SHOW_STATUS_PROC;
@ -10480,7 +10480,7 @@ show_param:
if (prepare_schema_table(YYTHD, lex, 0, SCH_PROCEDURES))
MYSQL_YYABORT;
}
| PROCEDURE CODE_SYM sp_name
| PROCEDURE_SYM CODE_SYM sp_name
{
Lex->sql_command= SQLCOM_SHOW_PROC_CODE;
Lex->spname= $3;
@ -12671,7 +12671,7 @@ revoke_command:
lex->sql_command= SQLCOM_REVOKE;
lex->type= TYPE_ENUM_FUNCTION;
}
| grant_privileges ON PROCEDURE grant_ident FROM grant_list
| grant_privileges ON PROCEDURE_SYM grant_ident FROM grant_list
{
LEX *lex= Lex;
if (lex->columns.elements)
@ -12713,7 +12713,7 @@ grant_command:
lex->sql_command= SQLCOM_GRANT;
lex->type= TYPE_ENUM_FUNCTION;
}
| grant_privileges ON PROCEDURE grant_ident TO_SYM grant_list
| grant_privileges ON PROCEDURE_SYM grant_ident TO_SYM grant_list
require_clause grant_options
{
LEX *lex= Lex;
@ -13721,7 +13721,7 @@ sf_tail:
;
sp_tail:
PROCEDURE remember_name sp_name
PROCEDURE_SYM remember_name sp_name
{
LEX *lex= Lex;
sp_head *sp;

View File

@ -4822,7 +4822,8 @@ size_t max_row_length(TABLE *table, const uchar *data)
void init_mdl_requests(TABLE_LIST *table_list)
{
for ( ; table_list ; table_list= table_list->next_global)
table_list->mdl_request.init(MDL_TABLE, table_list->db, table_list->table_name,
table_list->mdl_request.init(MDL_key::TABLE,
table_list->db, table_list->table_name,
MDL_SHARED);
}

View File

@ -1125,7 +1125,7 @@ struct TABLE_LIST
table_name_length= table_name_length_arg;
alias= (char*) alias_arg;
lock_type= lock_type_arg;
mdl_request.init(MDL_TABLE, db, table_name, MDL_SHARED);
mdl_request.init(MDL_key::TABLE, db, table_name, MDL_SHARED);
}
/*