diff options
author | Alexey Botchkov <holyfoot@askmonty.org> | 2016-01-27 14:58:52 +0400 |
---|---|---|
committer | Alexey Botchkov <holyfoot@askmonty.org> | 2016-01-28 11:12:03 +0400 |
commit | d16d40be2c47d8be5360ae7604f0199635dc0063 (patch) | |
tree | b239d01faadc378f239b29d706da19bf8a0386e3 | |
parent | 34df3140f2e5fe3a8531c5f6eb430e2192bfa737 (diff) | |
download | mariadb-git-d16d40be2c47d8be5360ae7604f0199635dc0063.tar.gz |
MDEV-5273 Prepared statement doesn't return metadata after prepare.
SHOW CREATE PROCEDURE/FUNCTION fixed.
-rw-r--r-- | sql/sp_head.cc | 63 | ||||
-rw-r--r-- | sql/sp_head.h | 3 | ||||
-rw-r--r-- | sql/sql_prepare.cc | 37 | ||||
-rw-r--r-- | tests/mysql_client_test.c | 14 |
4 files changed, 117 insertions, 0 deletions
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 @@ -2532,6 +2532,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<Item> *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. @param thd Thread context. 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<Item> *args); + static void + show_create_routine_get_fields(THD *thd, int type, List<Item> *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 @@ -1964,6 +1964,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<Item> 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 @param stmt prepared 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) { diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index ccc39d5f9ce..dd892b45449 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -457,6 +457,20 @@ static void test_prepare_simple() DIE_UNLESS(mysql_stmt_field_count(stmt) == 4); mysql_stmt_close(stmt); + /* show create procedure */ + strmov(query, "SHOW CREATE PROCEDURE e1;"); + stmt= mysql_simple_prepare(mysql, query); + check_stmt(stmt); + DIE_UNLESS(mysql_stmt_field_count(stmt) == 6); + mysql_stmt_close(stmt); + + /* show create function */ + strmov(query, "SHOW CREATE FUNCTION e1;"); + stmt= mysql_simple_prepare(mysql, query); + check_stmt(stmt); + DIE_UNLESS(mysql_stmt_field_count(stmt) == 6); + mysql_stmt_close(stmt); + /* now fetch the results ..*/ rc= mysql_commit(mysql); myquery(rc); |