Skip to content

Commit d16d40b

Browse files
author
Alexey Botchkov
committed
MDEV-5273 Prepared statement doesn't return metadata after prepare.
SHOW CREATE PROCEDURE/FUNCTION fixed.
1 parent 34df314 commit d16d40b

File tree

4 files changed

+117
-0
lines changed

4 files changed

+117
-0
lines changed

sql/sp_head.cc

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2531,6 +2531,69 @@ bool check_show_routine_access(THD *thd, sp_head *sp, bool *full_access)
25312531
}
25322532

25332533

2534+
/**
2535+
Collect metadata for SHOW CREATE statement for stored routines.
2536+
2537+
@param thd Thread context.
2538+
@param type Stored routine type
2539+
@param type Stored routine type
2540+
(TYPE_ENUM_PROCEDURE or TYPE_ENUM_FUNCTION)
2541+
2542+
@return Error status.
2543+
@retval FALSE on success
2544+
@retval TRUE on error
2545+
*/
2546+
2547+
void
2548+
sp_head::show_create_routine_get_fields(THD *thd, int type, List<Item> *fields)
2549+
{
2550+
const char *col1_caption= type == TYPE_ENUM_PROCEDURE ?
2551+
"Procedure" : "Function";
2552+
2553+
const char *col3_caption= type == TYPE_ENUM_PROCEDURE ?
2554+
"Create Procedure" : "Create Function";
2555+
2556+
MEM_ROOT *mem_root= thd->mem_root;
2557+
2558+
/* Send header. */
2559+
2560+
fields->push_back(new (mem_root)
2561+
Item_empty_string(thd, col1_caption, NAME_CHAR_LEN),
2562+
mem_root);
2563+
fields->push_back(new (mem_root)
2564+
Item_empty_string(thd, "sql_mode", 256),
2565+
mem_root);
2566+
2567+
{
2568+
/*
2569+
NOTE: SQL statement field must be not less than 1024 in order not to
2570+
confuse old clients.
2571+
*/
2572+
2573+
Item_empty_string *stmt_fld=
2574+
new (mem_root) Item_empty_string(thd, col3_caption, 1024);
2575+
stmt_fld->maybe_null= TRUE;
2576+
2577+
fields->push_back(stmt_fld, mem_root);
2578+
}
2579+
2580+
fields->push_back(new (mem_root)
2581+
Item_empty_string(thd, "character_set_client",
2582+
MY_CS_NAME_SIZE),
2583+
mem_root);
2584+
2585+
fields->push_back(new (mem_root)
2586+
Item_empty_string(thd, "collation_connection",
2587+
MY_CS_NAME_SIZE),
2588+
mem_root);
2589+
2590+
fields->push_back(new (mem_root)
2591+
Item_empty_string(thd, "Database Collation",
2592+
MY_CS_NAME_SIZE),
2593+
mem_root);
2594+
}
2595+
2596+
25342597
/**
25352598
Implement SHOW CREATE statement for stored routines.
25362599

sql/sp_head.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,9 @@ class sp_head :private Query_arena
340340
bool
341341
execute_procedure(THD *thd, List<Item> *args);
342342

343+
static void
344+
show_create_routine_get_fields(THD *thd, int type, List<Item> *fields);
345+
343346
bool
344347
show_create_routine(THD *thd, int type);
345348

sql/sql_prepare.cc

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1963,6 +1963,29 @@ static bool mysql_test_show_binlogs(Prepared_statement *stmt)
19631963
}
19641964

19651965

1966+
/**
1967+
Validate and prepare for execution SHOW CREATE PROC/FUNC statement.
1968+
1969+
@param stmt prepared statement
1970+
1971+
@retval
1972+
FALSE success
1973+
@retval
1974+
TRUE error, error message is set in THD
1975+
*/
1976+
1977+
static bool mysql_test_show_create_routine(Prepared_statement *stmt, int type)
1978+
{
1979+
DBUG_ENTER("mysql_test_show_binlogs");
1980+
THD *thd= stmt->thd;
1981+
List<Item> fields;
1982+
1983+
sp_head::show_create_routine_get_fields(thd, type, &fields);
1984+
1985+
DBUG_RETURN(send_stmt_metadata(thd, stmt, &fields));
1986+
}
1987+
1988+
19661989
/**
19671990
@brief Validate and prepare for execution CREATE VIEW statement
19681991
@@ -2338,6 +2361,20 @@ static bool check_prepared_statement(Prepared_statement *stmt)
23382361
DBUG_RETURN(FALSE);
23392362
}
23402363
break;
2364+
case SQLCOM_SHOW_CREATE_PROC:
2365+
if (!(res= mysql_test_show_create_routine(stmt, TYPE_ENUM_PROCEDURE)))
2366+
{
2367+
/* Statement and field info has already been sent */
2368+
DBUG_RETURN(FALSE);
2369+
}
2370+
break;
2371+
case SQLCOM_SHOW_CREATE_FUNC:
2372+
if (!(res= mysql_test_show_create_routine(stmt, TYPE_ENUM_FUNCTION)))
2373+
{
2374+
/* Statement and field info has already been sent */
2375+
DBUG_RETURN(FALSE);
2376+
}
2377+
break;
23412378
case SQLCOM_CREATE_VIEW:
23422379
if (lex->create_view_mode == VIEW_ALTER)
23432380
{

tests/mysql_client_test.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,20 @@ static void test_prepare_simple()
457457
DIE_UNLESS(mysql_stmt_field_count(stmt) == 4);
458458
mysql_stmt_close(stmt);
459459

460+
/* show create procedure */
461+
strmov(query, "SHOW CREATE PROCEDURE e1;");
462+
stmt= mysql_simple_prepare(mysql, query);
463+
check_stmt(stmt);
464+
DIE_UNLESS(mysql_stmt_field_count(stmt) == 6);
465+
mysql_stmt_close(stmt);
466+
467+
/* show create function */
468+
strmov(query, "SHOW CREATE FUNCTION e1;");
469+
stmt= mysql_simple_prepare(mysql, query);
470+
check_stmt(stmt);
471+
DIE_UNLESS(mysql_stmt_field_count(stmt) == 6);
472+
mysql_stmt_close(stmt);
473+
460474
/* now fetch the results ..*/
461475
rc= mysql_commit(mysql);
462476
myquery(rc);

0 commit comments

Comments
 (0)