summaryrefslogtreecommitdiff
path: root/sql/sql_show.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_show.cc')
-rw-r--r--sql/sql_show.cc116
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