From d16d40be2c47d8be5360ae7604f0199635dc0063 Mon Sep 17 00:00:00 2001 From: Alexey Botchkov Date: Wed, 27 Jan 2016 14:58:52 +0400 Subject: MDEV-5273 Prepared statement doesn't return metadata after prepare. SHOW CREATE PROCEDURE/FUNCTION fixed. --- sql/sp_head.cc | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ sql/sp_head.h | 3 +++ sql/sql_prepare.cc | 37 ++++++++++++++++++++++++++++++++ 3 files changed, 103 insertions(+) (limited to 'sql') diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 01e649bb746..ea112bc8296 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -2531,6 +2531,69 @@ bool check_show_routine_access(THD *thd, sp_head *sp, bool *full_access) } +/** + Collect metadata for SHOW CREATE statement for stored routines. + + @param thd Thread context. + @param type Stored routine type + @param type Stored routine type + (TYPE_ENUM_PROCEDURE or TYPE_ENUM_FUNCTION) + + @return Error status. + @retval FALSE on success + @retval TRUE on error +*/ + +void +sp_head::show_create_routine_get_fields(THD *thd, int type, List *fields) +{ + const char *col1_caption= type == TYPE_ENUM_PROCEDURE ? + "Procedure" : "Function"; + + const char *col3_caption= type == TYPE_ENUM_PROCEDURE ? + "Create Procedure" : "Create Function"; + + MEM_ROOT *mem_root= thd->mem_root; + + /* Send header. */ + + fields->push_back(new (mem_root) + Item_empty_string(thd, col1_caption, NAME_CHAR_LEN), + mem_root); + fields->push_back(new (mem_root) + Item_empty_string(thd, "sql_mode", 256), + mem_root); + + { + /* + NOTE: SQL statement field must be not less than 1024 in order not to + confuse old clients. + */ + + Item_empty_string *stmt_fld= + new (mem_root) Item_empty_string(thd, col3_caption, 1024); + stmt_fld->maybe_null= TRUE; + + fields->push_back(stmt_fld, mem_root); + } + + fields->push_back(new (mem_root) + Item_empty_string(thd, "character_set_client", + MY_CS_NAME_SIZE), + mem_root); + + fields->push_back(new (mem_root) + Item_empty_string(thd, "collation_connection", + MY_CS_NAME_SIZE), + mem_root); + + fields->push_back(new (mem_root) + Item_empty_string(thd, "Database Collation", + MY_CS_NAME_SIZE), + mem_root); +} + + /** Implement SHOW CREATE statement for stored routines. diff --git a/sql/sp_head.h b/sql/sp_head.h index dbdb957aa79..5a91423739c 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -340,6 +340,9 @@ public: bool execute_procedure(THD *thd, List *args); + static void + show_create_routine_get_fields(THD *thd, int type, List *fields); + bool show_create_routine(THD *thd, int type); diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index c67acff32f6..8497d712b80 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -1963,6 +1963,29 @@ static bool mysql_test_show_binlogs(Prepared_statement *stmt) } +/** + Validate and prepare for execution SHOW CREATE PROC/FUNC statement. + + @param stmt prepared statement + + @retval + FALSE success + @retval + TRUE error, error message is set in THD +*/ + +static bool mysql_test_show_create_routine(Prepared_statement *stmt, int type) +{ + DBUG_ENTER("mysql_test_show_binlogs"); + THD *thd= stmt->thd; + List fields; + + sp_head::show_create_routine_get_fields(thd, type, &fields); + + DBUG_RETURN(send_stmt_metadata(thd, stmt, &fields)); +} + + /** @brief Validate and prepare for execution CREATE VIEW statement @@ -2338,6 +2361,20 @@ static bool check_prepared_statement(Prepared_statement *stmt) DBUG_RETURN(FALSE); } break; + case SQLCOM_SHOW_CREATE_PROC: + if (!(res= mysql_test_show_create_routine(stmt, TYPE_ENUM_PROCEDURE))) + { + /* Statement and field info has already been sent */ + DBUG_RETURN(FALSE); + } + break; + case SQLCOM_SHOW_CREATE_FUNC: + if (!(res= mysql_test_show_create_routine(stmt, TYPE_ENUM_FUNCTION))) + { + /* Statement and field info has already been sent */ + DBUG_RETURN(FALSE); + } + break; case SQLCOM_CREATE_VIEW: if (lex->create_view_mode == VIEW_ALTER) { -- cgit v1.2.1