diff options
Diffstat (limited to 'sql/sql_show.cc')
-rw-r--r-- | sql/sql_show.cc | 116 |
1 files changed, 47 insertions, 69 deletions
diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 939db979804..4d58db2e36c 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -660,22 +660,30 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list) Protocol *protocol= thd->protocol; char buff[2048]; String buffer(buff, sizeof(buff), system_charset_info); + List<Item> field_list; + bool error= TRUE; DBUG_ENTER("mysqld_show_create"); DBUG_PRINT("enter",("db: %s table: %s",table_list->db, table_list->table_name)); + /* + Metadata locks taken during SHOW CREATE should be released when + the statmement completes as it is an information statement. + */ + MDL_ticket *mdl_savepoint= thd->mdl_context.mdl_savepoint(); + /* We want to preserve the tree for views. */ thd->lex->view_prepare_mode= TRUE; { Show_create_error_handler view_error_suppressor(thd, table_list); thd->push_internal_handler(&view_error_suppressor); - bool error= + bool open_error= open_normal_and_derived_tables(thd, table_list, MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL); thd->pop_internal_handler(); - if (error && (thd->killed || thd->is_error())) - DBUG_RETURN(TRUE); + if (open_error && (thd->killed || thd->is_error())) + goto exit; } /* TODO: add environment variables show when it become possible */ @@ -683,7 +691,7 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list) { my_error(ER_WRONG_OBJECT, MYF(0), table_list->db, table_list->table_name, "VIEW"); - DBUG_RETURN(TRUE); + goto exit; } buffer.length(0); @@ -695,9 +703,8 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list) view_store_create_info(thd, table_list, &buffer) : store_create_info(thd, table_list, &buffer, NULL, FALSE /* show_database */))) - DBUG_RETURN(TRUE); + goto exit; - List<Item> field_list; if (table_list->view) { field_list.push_back(new Item_empty_string("View",NAME_CHAR_LEN)); @@ -718,7 +725,8 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list) if (protocol->send_result_set_metadata(&field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - DBUG_RETURN(TRUE); + goto exit; + protocol->prepare_for_resend(); if (table_list->view) protocol->store(table_list->view_name.str, system_charset_info); @@ -746,10 +754,16 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list) protocol->store(buffer.ptr(), buffer.length(), buffer.charset()); if (protocol->write()) - DBUG_RETURN(TRUE); + goto exit; + error= FALSE; my_eof(thd); - DBUG_RETURN(FALSE); + +exit: + close_thread_tables(thd); + /* Release any metadata locks taken during SHOW CREATE. */ + thd->mdl_context.rollback_to_savepoint(mdl_savepoint); + DBUG_RETURN(error); } bool mysqld_show_create_db(THD *thd, char *dbname, @@ -5709,52 +5723,6 @@ static int get_schema_partitions_record(THD *thd, TABLE_LIST *tables, } -#ifdef NOT_USED -static interval_type get_real_interval_type(interval_type i_type) -{ - switch (i_type) { - case INTERVAL_YEAR: - return INTERVAL_YEAR; - - case INTERVAL_QUARTER: - case INTERVAL_YEAR_MONTH: - case INTERVAL_MONTH: - return INTERVAL_MONTH; - - case INTERVAL_WEEK: - case INTERVAL_DAY: - return INTERVAL_DAY; - - case INTERVAL_DAY_HOUR: - case INTERVAL_HOUR: - return INTERVAL_HOUR; - - case INTERVAL_DAY_MINUTE: - case INTERVAL_HOUR_MINUTE: - case INTERVAL_MINUTE: - return INTERVAL_MINUTE; - - case INTERVAL_DAY_SECOND: - case INTERVAL_HOUR_SECOND: - case INTERVAL_MINUTE_SECOND: - case INTERVAL_SECOND: - return INTERVAL_SECOND; - - case INTERVAL_DAY_MICROSECOND: - case INTERVAL_HOUR_MICROSECOND: - case INTERVAL_MINUTE_MICROSECOND: - case INTERVAL_SECOND_MICROSECOND: - case INTERVAL_MICROSECOND: - return INTERVAL_MICROSECOND; - case INTERVAL_LAST: - DBUG_ASSERT(0); - } - DBUG_ASSERT(0); - return INTERVAL_SECOND; -} - -#endif - #ifdef HAVE_EVENT_SCHEDULER /* Loads an event from mysql.event and copies it's data to a row of @@ -7774,6 +7742,10 @@ TABLE_LIST *get_trigger_table(THD *thd, const sp_name *trg_name) bool show_create_trigger(THD *thd, const sp_name *trg_name) { TABLE_LIST *lst= get_trigger_table(thd, trg_name); + uint num_tables; /* NOTE: unused, only to pass to open_tables(). */ + Table_triggers_list *triggers; + int trigger_idx; + bool error= TRUE; if (!lst) return TRUE; @@ -7785,35 +7757,35 @@ bool show_create_trigger(THD *thd, const sp_name *trg_name) } /* - Open the table by name in order to load Table_triggers_list object. - - NOTE: there is race condition here -- the table can be dropped after - LOCK_open is released. It will be fixed later by acquiring shared - metadata lock on trigger or table name. + Metadata locks taken during SHOW CREATE TRIGGER should be released when + the statement completes as it is an information statement. */ + MDL_ticket *mdl_savepoint= thd->mdl_context.mdl_savepoint(); - uint num_tables; /* NOTE: unused, only to pass to open_tables(). */ - - if (open_tables(thd, &lst, &num_tables, 0)) + /* + Open the table by name in order to load Table_triggers_list object. + */ + if (open_tables(thd, &lst, &num_tables, + MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL)) { my_error(ER_TRG_CANT_OPEN_TABLE, MYF(0), (const char *) trg_name->m_db.str, (const char *) lst->table_name); - return TRUE; + goto exit; /* Perform closing actions and return error status. */ } - Table_triggers_list *triggers= lst->table->triggers; + triggers= lst->table->triggers; if (!triggers) { my_error(ER_TRG_DOES_NOT_EXIST, MYF(0)); - return TRUE; + goto exit; } - int trigger_idx= triggers->find_trigger_by_name(&trg_name->m_name); + trigger_idx= triggers->find_trigger_by_name(&trg_name->m_name); if (trigger_idx < 0) { @@ -7821,16 +7793,22 @@ bool show_create_trigger(THD *thd, const sp_name *trg_name) (const char *) trg_name->m_db.str, (const char *) lst->table_name); - return TRUE; + goto exit; } - return show_create_trigger_impl(thd, triggers, trigger_idx); + error= show_create_trigger_impl(thd, triggers, trigger_idx); /* NOTE: if show_create_trigger_impl() failed, that means we could not send data to the client. In this case we simply raise the error status and client connection will be closed. */ + +exit: + close_thread_tables(thd); + /* Release any metadata locks taken during SHOW CREATE TRIGGER. */ + thd->mdl_context.rollback_to_savepoint(mdl_savepoint); + return error; } class IS_internal_schema_access : public ACL_internal_schema_access |