Commit d9e6810e authored by unknown's avatar unknown

Bugfixes in SHOW CREATE PROCEDURE/FUNCTION and SHOW PROCEDURE/FUNCTION STATUS;

- dropped routines should not show up in status
- error handling for non-existing routines

+ some cleanup.


mysql-test/r/sp-error.result:
  Test SHOW CREATE PROCEDURE for non-existing procedure.
mysql-test/r/sp.result:
  Additional SHOW FUNCTION/PROCEDURE STATUS calls (make sure they don't show
  after being dropped).
mysql-test/t/sp-error.test:
  Test SHOW CREATE PROCEDURE for non-existing procedure.
mysql-test/t/sp.test:
  Additional SHOW FUNCTION/PROCEDURE STATUS calls (make sure they don't show
  after being dropped).
sql/sp.cc:
  Fixed bug in SHOW ... STATUS after a routine has been dropped,
  and fixed the error return codes (for correct error handling).
  Also some general cleanup.
sql/sp.h:
  Fixed prefix for external functions (should be sp_, not db_).
sql/sql_parse.cc:
  Fixed error handling in SHOW CREATE PROCEDURE/FUNCTION.
parent 5603426a
...@@ -36,6 +36,8 @@ ERROR HY000: PROCEDURE foo does not exist ...@@ -36,6 +36,8 @@ ERROR HY000: PROCEDURE foo does not exist
drop procedure if exists foo; drop procedure if exists foo;
Warnings: Warnings:
Warning 1286 PROCEDURE foo does not exist Warning 1286 PROCEDURE foo does not exist
show create procedure foo;
ERROR HY000: PROCEDURE foo does not exist
create procedure foo() create procedure foo()
foo: loop foo: loop
leave bar; leave bar;
......
...@@ -809,6 +809,8 @@ Name Type Creator Modified Created Suid Comment ...@@ -809,6 +809,8 @@ Name Type Creator Modified Created Suid Comment
fac function root@localhost 0000-00-00 00:00:00 0000-00-00 00:00:00 Y fac function root@localhost 0000-00-00 00:00:00 0000-00-00 00:00:00 Y
drop procedure ifac; drop procedure ifac;
drop function fac; drop function fac;
show function status like '%f%';
Name Type Creator Modified Created Suid Comment
drop table if exists primes; drop table if exists primes;
create table primes ( create table primes (
i int unsigned not null primary key, i int unsigned not null primary key,
...@@ -908,6 +910,8 @@ i p ...@@ -908,6 +910,8 @@ i p
drop table primes; drop table primes;
drop procedure opp; drop procedure opp;
drop procedure ip; drop procedure ip;
show procedure status like '%p%';
Name Type Creator Modified Created Suid Comment
create procedure bar(x char(16), y int) create procedure bar(x char(16), y int)
comment "111111111111" sql security invoker comment "111111111111" sql security invoker
insert into test.t1 values (x, y); insert into test.t1 values (x, y);
......
...@@ -62,6 +62,8 @@ drop function foo| ...@@ -62,6 +62,8 @@ drop function foo|
--error 1286 --error 1286
call foo()| call foo()|
drop procedure if exists foo| drop procedure if exists foo|
--error 1286
show create procedure foo|
# LEAVE/ITERATE with no match # LEAVE/ITERATE with no match
--error 1289 --error 1289
......
...@@ -947,6 +947,8 @@ drop table fac| ...@@ -947,6 +947,8 @@ drop table fac|
show function status like '%f%'| show function status like '%f%'|
drop procedure ifac| drop procedure ifac|
drop function fac| drop function fac|
--replace_column 4 '0000-00-00 00:00:00' 5 '0000-00-00 00:00:00'
show function status like '%f%'|
# primes # primes
...@@ -1034,6 +1036,8 @@ select * from primes where i=45 or i=100 or i=199| ...@@ -1034,6 +1036,8 @@ select * from primes where i=45 or i=100 or i=199|
drop table primes| drop table primes|
drop procedure opp| drop procedure opp|
drop procedure ip| drop procedure ip|
--replace_column 4 '0000-00-00 00:00:00' 5 '0000-00-00 00:00:00'
show procedure status like '%p%'|
# Comment & suid # Comment & suid
create procedure bar(x char(16), y int) create procedure bar(x char(16), y int)
......
...@@ -322,7 +322,8 @@ static struct st_used_field init_fields[]= ...@@ -322,7 +322,8 @@ static struct st_used_field init_fields[]=
{ 0, 0, MYSQL_TYPE_STRING, 0} { 0, 0, MYSQL_TYPE_STRING, 0}
}; };
int print_field_values(THD *thd, TABLE *table, static int
print_field_values(THD *thd, TABLE *table,
struct st_used_field *used_fields, struct st_used_field *used_fields,
int type, const char *wild) int type, const char *wild)
{ {
...@@ -332,9 +333,8 @@ int print_field_values(THD *thd, TABLE *table, ...@@ -332,9 +333,8 @@ int print_field_values(THD *thd, TABLE *table,
{ {
String *tmp_string= new String(); String *tmp_string= new String();
struct st_used_field *used_field= used_fields; struct st_used_field *used_field= used_fields;
get_field(&thd->mem_root,
used_field->field, get_field(&thd->mem_root, used_field->field, tmp_string);
tmp_string);
if (!wild || !wild[0] || !wild_compare(tmp_string->ptr(), wild, 0)) if (!wild || !wild[0] || !wild_compare(tmp_string->ptr(), wild, 0))
{ {
protocol->prepare_for_resend(); protocol->prepare_for_resend();
...@@ -361,19 +361,20 @@ int print_field_values(THD *thd, TABLE *table, ...@@ -361,19 +361,20 @@ int print_field_values(THD *thd, TABLE *table,
} }
} }
if (protocol->write()) if (protocol->write())
return 1; return SP_INTERNAL_ERROR;
} }
} }
return 0; return SP_OK;
} }
int static int
db_show_routine_status(THD *thd, int type, const char *wild) db_show_routine_status(THD *thd, int type, const char *wild)
{ {
DBUG_ENTER("db_show_routine_status"); DBUG_ENTER("db_show_routine_status");
TABLE *table; TABLE *table;
TABLE_LIST tables; TABLE_LIST tables;
int res;
memset(&tables, 0, sizeof(tables)); memset(&tables, 0, sizeof(tables));
tables.db= (char*)"mysql"; tables.db= (char*)"mysql";
...@@ -381,7 +382,8 @@ db_show_routine_status(THD *thd, int type, const char *wild) ...@@ -381,7 +382,8 @@ db_show_routine_status(THD *thd, int type, const char *wild)
if (! (table= open_ltable(thd, &tables, TL_READ))) if (! (table= open_ltable(thd, &tables, TL_READ)))
{ {
DBUG_RETURN(1); res= SP_OPEN_TABLE_FAILED;
goto done;
} }
else else
{ {
...@@ -389,6 +391,7 @@ db_show_routine_status(THD *thd, int type, const char *wild) ...@@ -389,6 +391,7 @@ db_show_routine_status(THD *thd, int type, const char *wild)
List<Item> field_list; List<Item> field_list;
struct st_used_field *used_field; struct st_used_field *used_field;
st_used_field used_fields[array_elements(init_fields)]; st_used_field used_fields[array_elements(init_fields)];
memcpy((char*) used_fields, (char*) init_fields, sizeof(used_fields)); memcpy((char*) used_fields, (char*) init_fields, sizeof(used_fields));
/* Init header */ /* Init header */
for (used_field= &used_fields[0]; for (used_field= &used_fields[0];
...@@ -408,7 +411,10 @@ db_show_routine_status(THD *thd, int type, const char *wild) ...@@ -408,7 +411,10 @@ db_show_routine_status(THD *thd, int type, const char *wild)
} }
/* Print header */ /* Print header */
if (thd->protocol->send_fields(&field_list,1)) if (thd->protocol->send_fields(&field_list,1))
{
res= SP_INTERNAL_ERROR;
goto err_case; goto err_case;
}
/* Init fields */ /* Init fields */
setup_tables(&tables); setup_tables(&tables);
...@@ -421,27 +427,37 @@ db_show_routine_status(THD *thd, int type, const char *wild) ...@@ -421,27 +427,37 @@ db_show_routine_status(THD *thd, int type, const char *wild)
used_field->field_name); used_field->field_name);
if (!(used_field->field= find_field_in_tables(thd, field, &tables, if (!(used_field->field= find_field_in_tables(thd, field, &tables,
&not_used, TRUE))) &not_used, TRUE)))
{
res= SP_INTERNAL_ERROR;
goto err_case1; goto err_case1;
} }
}
table->file->index_init(0); table->file->index_init(0);
table->file->index_first(table->record[0]); if ((res= table->file->index_first(table->record[0])))
if (print_field_values(thd, table, used_fields, type, wild)) {
if (res == HA_ERR_END_OF_FILE)
res= 0;
else
res= SP_INTERNAL_ERROR;
goto err_case1;
}
if ((res= print_field_values(thd, table, used_fields, type, wild)))
goto err_case1; goto err_case1;
while (!table->file->index_next(table->record[0])) while (!table->file->index_next(table->record[0]))
{ {
if (print_field_values(thd, table, used_fields, type, wild)) if ((res= print_field_values(thd, table, used_fields, type, wild)))
goto err_case1; goto err_case1;
} }
send_eof(thd); res= SP_OK;
close_thread_tables(thd);
DBUG_RETURN(0);
} }
err_case1:
err_case1:
send_eof(thd); send_eof(thd);
err_case: err_case:
close_thread_tables(thd); close_thread_tables(thd);
DBUG_RETURN(1); done:
DBUG_RETURN(res);
} }
...@@ -533,13 +549,13 @@ sp_show_create_procedure(THD *thd, LEX_STRING *name) ...@@ -533,13 +549,13 @@ sp_show_create_procedure(THD *thd, LEX_STRING *name)
if (sp) if (sp)
DBUG_RETURN(sp->show_create_procedure(thd)); DBUG_RETURN(sp->show_create_procedure(thd));
DBUG_RETURN(1); DBUG_RETURN(SP_KEY_NOT_FOUND);
} }
int int
db_show_status_procedure(THD *thd, const char *wild) sp_show_status_procedure(THD *thd, const char *wild)
{ {
DBUG_ENTER("db_show_status_procedure"); DBUG_ENTER("sp_show_status_procedure");
DBUG_RETURN(db_show_routine_status(thd, TYPE_ENUM_PROCEDURE, wild)); DBUG_RETURN(db_show_routine_status(thd, TYPE_ENUM_PROCEDURE, wild));
} }
...@@ -628,13 +644,13 @@ sp_show_create_function(THD *thd, LEX_STRING *name) ...@@ -628,13 +644,13 @@ sp_show_create_function(THD *thd, LEX_STRING *name)
if (sp) if (sp)
DBUG_RETURN(sp->show_create_function(thd)); DBUG_RETURN(sp->show_create_function(thd));
DBUG_RETURN(1); DBUG_RETURN(SP_KEY_NOT_FOUND);
} }
int int
db_show_status_function(THD *thd, const char *wild) sp_show_status_function(THD *thd, const char *wild)
{ {
DBUG_ENTER("db_show_status_function"); DBUG_ENTER("sp_show_status_function");
DBUG_RETURN(db_show_routine_status(thd, TYPE_ENUM_FUNCTION, wild)); DBUG_RETURN(db_show_routine_status(thd, TYPE_ENUM_FUNCTION, wild));
} }
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
#ifndef _SP_H_ #ifndef _SP_H_
#define _SP_H_ #define _SP_H_
// Return codes from sp_create_* and sp_drop_*: // Return codes from sp_create_*, sp_drop_*, and sp_show_*:
#define SP_OK 0 #define SP_OK 0
#define SP_KEY_NOT_FOUND -1 #define SP_KEY_NOT_FOUND -1
#define SP_OPEN_TABLE_FAILED -2 #define SP_OPEN_TABLE_FAILED -2
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#define SP_DELETE_ROW_FAILED -4 #define SP_DELETE_ROW_FAILED -4
#define SP_GET_FIELD_FAILED -5 #define SP_GET_FIELD_FAILED -5
#define SP_PARSE_ERROR -6 #define SP_PARSE_ERROR -6
#define SP_INTERNAL_ERROR -7
sp_head * sp_head *
sp_find_procedure(THD *thd, LEX_STRING *name); sp_find_procedure(THD *thd, LEX_STRING *name);
...@@ -47,7 +48,7 @@ int ...@@ -47,7 +48,7 @@ int
sp_show_create_procedure(THD *thd, LEX_STRING *name); sp_show_create_procedure(THD *thd, LEX_STRING *name);
int int
db_show_status_procedure(THD *thd, const char *wild); sp_show_status_procedure(THD *thd, const char *wild);
sp_head * sp_head *
sp_find_function(THD *thd, LEX_STRING *name); sp_find_function(THD *thd, LEX_STRING *name);
...@@ -68,7 +69,7 @@ int ...@@ -68,7 +69,7 @@ int
sp_show_create_function(THD *thd, LEX_STRING *name); sp_show_create_function(THD *thd, LEX_STRING *name);
int int
db_show_status_function(THD *thd, const char *wild); sp_show_status_function(THD *thd, const char *wild);
// QQ Temporary until the function call detection in sql_lex has been reworked. // QQ Temporary until the function call detection in sql_lex has been reworked.
bool bool
......
...@@ -3592,10 +3592,11 @@ mysql_execute_command(THD *thd) ...@@ -3592,10 +3592,11 @@ mysql_execute_command(THD *thd)
goto error; goto error;
} }
res= sp_show_create_procedure(thd, &lex->udf.name); res= sp_show_create_procedure(thd, &lex->udf.name);
if (res == SP_KEY_NOT_FOUND) if (res != SP_OK)
{ { /* We don't distinguish between errors for now */
net_printf(thd, ER_SP_DOES_NOT_EXIST, net_printf(thd, ER_SP_DOES_NOT_EXIST,
SP_COM_STRING(lex), lex->udf.name.str); SP_COM_STRING(lex), lex->udf.name.str);
res= 0;
goto error; goto error;
} }
break; break;
...@@ -3608,23 +3609,24 @@ mysql_execute_command(THD *thd) ...@@ -3608,23 +3609,24 @@ mysql_execute_command(THD *thd)
goto error; goto error;
} }
res= sp_show_create_function(thd, &lex->udf.name); res= sp_show_create_function(thd, &lex->udf.name);
if (res == SP_KEY_NOT_FOUND) if (res != SP_OK)
{ { /* We don't distinguish between errors for now */
net_printf(thd, ER_SP_DOES_NOT_EXIST, net_printf(thd, ER_SP_DOES_NOT_EXIST,
SP_COM_STRING(lex), lex->udf.name.str); SP_COM_STRING(lex), lex->udf.name.str);
res= 0;
goto error; goto error;
} }
break; break;
} }
case SQLCOM_SHOW_STATUS_PROC: case SQLCOM_SHOW_STATUS_PROC:
{ {
res= db_show_status_procedure(thd, (lex->wild ? res= sp_show_status_procedure(thd, (lex->wild ?
lex->wild->ptr() : NullS)); lex->wild->ptr() : NullS));
break; break;
} }
case SQLCOM_SHOW_STATUS_FUNC: case SQLCOM_SHOW_STATUS_FUNC:
{ {
res= db_show_status_function(thd, (lex->wild ? res= sp_show_status_function(thd, (lex->wild ?
lex->wild->ptr() : NullS)); lex->wild->ptr() : NullS));
break; break;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment