summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <monty@mysql.com>2003-12-21 12:48:03 +0200
committerunknown <monty@mysql.com>2003-12-21 12:48:03 +0200
commitc466a191d9eca3f08f72a197dab8600d834d21e8 (patch)
tree46587e1ec9574fce8a10979ad691d302509fde69 /sql
parent292bb8cbbeb2d0577fd3f15ffe59b2ffb078689d (diff)
downloadmariadb-git-c466a191d9eca3f08f72a197dab8600d834d21e8.tar.gz
Fixed memory leaks in SP
Some code cleanup mysql-test/r/sp.result: Update results after adding quotes around function/procedure names sql/sp.cc: Moved DBUG_ENTER after all variable declarations Eliminated some variables. Added more DBUG_ENTER commands. Added memory allocation checking in create_string() Fixed memory leak in sp_show_create_function() Removed usage of sprintf sql/sql_parse.cc: Simple cleanup Fixed memory leaks for mailformed SP definitions
Diffstat (limited to 'sql')
-rw-r--r--sql/sp.cc189
-rw-r--r--sql/sql_parse.cc106
2 files changed, 140 insertions, 155 deletions
diff --git a/sql/sp.cc b/sql/sp.cc
index 3a640cdc08e..dca67f803a4 100644
--- a/sql/sp.cc
+++ b/sql/sp.cc
@@ -61,13 +61,13 @@ static int
db_find_routine_aux(THD *thd, int type, char *name, uint namelen,
enum thr_lock_type ltype, TABLE **tablep, bool *opened)
{
- DBUG_ENTER("db_find_routine_aux");
- DBUG_PRINT("enter", ("type: %d name: %*s", type, namelen, name));
TABLE *table;
byte key[64+64+1]; // db, name, type
uint keylen;
+ DBUG_ENTER("db_find_routine_aux");
+ DBUG_PRINT("enter", ("type: %d name: %*s", type, namelen, name));
- // Put the key together
+ // Put the key used to read the row together
memset(key, (int)' ', 64); // QQ Empty db for now
keylen= namelen;
if (keylen > 64)
@@ -110,11 +110,10 @@ db_find_routine_aux(THD *thd, int type, char *name, uint namelen,
DBUG_RETURN(SP_OK);
}
+
static int
db_find_routine(THD *thd, int type, char *name, uint namelen, sp_head **sphp)
{
- DBUG_ENTER("db_find_routine");
- DBUG_PRINT("enter", ("type: %d name: %*s", type, namelen, name));
extern int yyparse(void *thd);
TABLE *table;
const char *params, *returns, *body;
@@ -129,6 +128,8 @@ db_find_routine(THD *thd, int type, char *name, uint namelen, sp_head **sphp)
char buff[65];
String str(buff, sizeof(buff), &my_charset_bin);
ulong sql_mode;
+ DBUG_ENTER("db_find_routine");
+ DBUG_PRINT("enter", ("type: %d name: %*s", type, namelen, name));
ret= db_find_routine_aux(thd, type, name, namelen, TL_READ, &table, &opened);
if (ret != SP_OK)
@@ -202,8 +203,8 @@ db_find_routine(THD *thd, int type, char *name, uint namelen, sp_head **sphp)
if (opened)
{
- close_thread_tables(thd, 0, 1);
opened= FALSE;
+ close_thread_tables(thd, 0, 1);
}
{
@@ -217,13 +218,18 @@ db_find_routine(THD *thd, int type, char *name, uint namelen, sp_head **sphp)
thd->variables.sql_mode= sql_mode;
thd->variables.select_limit= HA_POS_ERROR;
- defstr= create_string(thd, &deflen,
+ if (!(defstr= create_string(thd, &deflen,
type,
name, namelen,
params, strlen(params),
returns, strlen(returns),
body, strlen(body),
- &chistics);
+ &chistics)))
+ {
+ ret= SP_INTERNAL_ERROR;
+ goto done;
+ }
+
lex_start(thd, (uchar*)defstr, deflen);
if (yyparse(thd) || thd->is_fatal_error || thd->lex->sphead == NULL)
{
@@ -256,15 +262,16 @@ db_find_routine(THD *thd, int type, char *name, uint namelen, sp_head **sphp)
DBUG_RETURN(ret);
}
+
static int
db_create_routine(THD *thd, int type, sp_head *sp)
{
- DBUG_ENTER("db_create_routine");
- DBUG_PRINT("enter", ("type: %d name: %*s",type,sp->m_name.length,sp->m_name.str));
int ret;
TABLE *table;
TABLE_LIST tables;
char definer[HOSTNAME_LENGTH+USERNAME_LENGTH+2];
+ DBUG_ENTER("db_create_routine");
+ DBUG_PRINT("enter", ("type: %d name: %*s",type,sp->m_name.length,sp->m_name.str));
memset(&tables, 0, sizeof(tables));
tables.db= (char*)"mysql";
@@ -310,10 +317,9 @@ db_create_routine(THD *thd, int type, sp_head *sp)
store(sp->m_chistics->comment.str, sp->m_chistics->comment.length,
system_charset_info);
+ ret= SP_OK;
if (table->file->write_row(table->record[0]))
ret= SP_WRITE_ROW_FAILED;
- else
- ret= SP_OK;
}
done:
@@ -321,14 +327,15 @@ done:
DBUG_RETURN(ret);
}
+
static int
db_drop_routine(THD *thd, int type, char *name, uint namelen)
{
- DBUG_ENTER("db_drop_routine");
- DBUG_PRINT("enter", ("type: %d name: %*s", type, namelen, name));
TABLE *table;
int ret;
bool opened;
+ DBUG_ENTER("db_drop_routine");
+ DBUG_PRINT("enter", ("type: %d name: %*s", type, namelen, name));
ret= db_find_routine_aux(thd, type, name, namelen, TL_WRITE, &table, &opened);
if (ret == SP_OK)
@@ -342,16 +349,17 @@ db_drop_routine(THD *thd, int type, char *name, uint namelen)
DBUG_RETURN(ret);
}
+
static int
db_update_routine(THD *thd, int type, char *name, uint namelen,
char *newname, uint newnamelen,
st_sp_chistics *chistics)
{
- DBUG_ENTER("db_update_routine");
- DBUG_PRINT("enter", ("type: %d name: %*s", type, namelen, name));
TABLE *table;
int ret;
bool opened;
+ DBUG_ENTER("db_update_routine");
+ DBUG_PRINT("enter", ("type: %d name: %*s", type, namelen, name));
ret= db_find_routine_aux(thd, type, name, namelen, TL_WRITE, &table, &opened);
if (ret == SP_OK)
@@ -376,6 +384,7 @@ db_update_routine(THD *thd, int type, char *name, uint namelen,
DBUG_RETURN(ret);
}
+
struct st_used_field
{
const char *field_name;
@@ -396,6 +405,7 @@ static struct st_used_field init_fields[]=
{ 0, 0, MYSQL_TYPE_STRING, 0}
};
+
static int
print_field_values(THD *thd, TABLE *table,
struct st_used_field *used_fields,
@@ -444,14 +454,14 @@ print_field_values(THD *thd, TABLE *table,
return SP_OK;
}
+
static int
db_show_routine_status(THD *thd, int type, const char *wild)
{
- DBUG_ENTER("db_show_routine_status");
-
TABLE *table;
TABLE_LIST tables;
int res;
+ DBUG_ENTER("db_show_routine_status");
memset(&tables, 0, sizeof(tables));
tables.db= (char*)"mysql";
@@ -513,10 +523,7 @@ db_show_routine_status(THD *thd, int type, const char *wild)
table->file->index_init(0);
if ((res= table->file->index_first(table->record[0])))
{
- if (res == HA_ERR_END_OF_FILE)
- res= 0;
- else
- res= SP_INTERNAL_ERROR;
+ res= (res == HA_ERR_END_OF_FILE) ? 0 : SP_INTERNAL_ERROR;
goto err_case1;
}
if ((res= print_field_values(thd, table, used_fields, type, wild)))
@@ -529,67 +536,57 @@ db_show_routine_status(THD *thd, int type, const char *wild)
res= SP_OK;
}
- err_case1:
+err_case1:
send_eof(thd);
- err_case:
+err_case:
close_thread_tables(thd);
- done:
+done:
DBUG_RETURN(res);
}
-/*
- *
- * PROCEDURE
- *
- */
+/*****************************************************************************
+ PROCEDURE
+******************************************************************************/
sp_head *
sp_find_procedure(THD *thd, LEX_STRING *name)
{
- DBUG_ENTER("sp_find_procedure");
sp_head *sp;
-
+ DBUG_ENTER("sp_find_procedure");
DBUG_PRINT("enter", ("name: %*s", name->length, name->str));
- sp= sp_cache_lookup(&thd->sp_proc_cache, name->str, name->length);
- if (! sp)
+ if (!(sp= sp_cache_lookup(&thd->sp_proc_cache, name->str, name->length)))
{
if (db_find_routine(thd, TYPE_ENUM_PROCEDURE,
name->str, name->length, &sp) == SP_OK)
- {
sp_cache_insert(&thd->sp_proc_cache, sp);
- }
}
DBUG_RETURN(sp);
}
+
int
sp_create_procedure(THD *thd, sp_head *sp)
{
DBUG_ENTER("sp_create_procedure");
DBUG_PRINT("enter", ("name: %*s", sp->m_name.length, sp->m_name.str));
- int ret;
-
- ret= db_create_routine(thd, TYPE_ENUM_PROCEDURE, sp);
-
- DBUG_RETURN(ret);
+ DBUG_RETURN(db_create_routine(thd, TYPE_ENUM_PROCEDURE, sp));
}
+
int
sp_drop_procedure(THD *thd, char *name, uint namelen)
{
DBUG_ENTER("sp_drop_procedure");
DBUG_PRINT("enter", ("name: %*s", namelen, name));
- int ret;
sp_cache_remove(&thd->sp_proc_cache, name, namelen);
- ret= db_drop_routine(thd, TYPE_ENUM_PROCEDURE, name, namelen);
-
- DBUG_RETURN(ret);
+ DBUG_RETURN(db_drop_routine(thd, TYPE_ENUM_PROCEDURE, name, namelen));
}
+
int
sp_update_procedure(THD *thd, char *name, uint namelen,
char *newname, uint newnamelen,
@@ -597,30 +594,27 @@ sp_update_procedure(THD *thd, char *name, uint namelen,
{
DBUG_ENTER("sp_update_procedure");
DBUG_PRINT("enter", ("name: %*s", namelen, name));
- int ret;
sp_cache_remove(&thd->sp_proc_cache, name, namelen);
- ret= db_update_routine(thd, TYPE_ENUM_PROCEDURE, name, namelen,
- newname, newnamelen,
- chistics);
-
- DBUG_RETURN(ret);
+ DBUG_RETURN(db_update_routine(thd, TYPE_ENUM_PROCEDURE, name, namelen,
+ newname, newnamelen, chistics));
}
+
int
sp_show_create_procedure(THD *thd, LEX_STRING *name)
{
+ sp_head *sp;
DBUG_ENTER("sp_show_create_procedure");
DBUG_PRINT("enter", ("name: %*s", name->length, name->str));
- sp_head *sp;
- sp= sp_find_procedure(thd, name);
- if (sp)
- DBUG_RETURN(sp->show_create_procedure(thd));
+ if ((sp= sp_find_procedure(thd, name)))
+ DBUG_RETURN(sp->show_create_procedure(thd));
DBUG_RETURN(SP_KEY_NOT_FOUND);
}
+
int
sp_show_status_procedure(THD *thd, const char *wild)
{
@@ -628,55 +622,51 @@ sp_show_status_procedure(THD *thd, const char *wild)
DBUG_RETURN(db_show_routine_status(thd, TYPE_ENUM_PROCEDURE, wild));
}
-/*
- *
- * FUNCTION
- *
- */
+
+/*****************************************************************************
+ FUNCTION
+******************************************************************************/
sp_head *
sp_find_function(THD *thd, LEX_STRING *name)
{
- DBUG_ENTER("sp_find_function");
sp_head *sp;
-
+ DBUG_ENTER("sp_find_function");
DBUG_PRINT("enter", ("name: %*s", name->length, name->str));
- sp= sp_cache_lookup(&thd->sp_func_cache, name->str, name->length);
- if (! sp)
+ if (!(sp= sp_cache_lookup(&thd->sp_func_cache, name->str, name->length)))
{
if (db_find_routine(thd, TYPE_ENUM_FUNCTION,
name->str, name->length, &sp) != SP_OK)
sp= NULL;
+ else
+ sp_cache_insert(&thd->sp_func_cache, sp);
}
DBUG_RETURN(sp);
}
+
int
sp_create_function(THD *thd, sp_head *sp)
{
DBUG_ENTER("sp_create_function");
DBUG_PRINT("enter", ("name: %*s", sp->m_name.length, sp->m_name.str));
- int ret;
- ret= db_create_routine(thd, TYPE_ENUM_FUNCTION, sp);
-
- DBUG_RETURN(ret);
+ DBUG_RETURN(db_create_routine(thd, TYPE_ENUM_FUNCTION, sp));
}
+
int
sp_drop_function(THD *thd, char *name, uint namelen)
{
DBUG_ENTER("sp_drop_function");
DBUG_PRINT("enter", ("name: %*s", namelen, name));
- int ret;
sp_cache_remove(&thd->sp_func_cache, name, namelen);
- ret= db_drop_routine(thd, TYPE_ENUM_FUNCTION, name, namelen);
-
- DBUG_RETURN(ret);
+ DBUG_RETURN(db_drop_routine(thd, TYPE_ENUM_FUNCTION, name, namelen));
}
+
int
sp_update_function(THD *thd, char *name, uint namelen,
char *newname, uint newnamelen,
@@ -684,30 +674,26 @@ sp_update_function(THD *thd, char *name, uint namelen,
{
DBUG_ENTER("sp_update_procedure");
DBUG_PRINT("enter", ("name: %*s", namelen, name));
- int ret;
sp_cache_remove(&thd->sp_func_cache, name, namelen);
- ret= db_update_routine(thd, TYPE_ENUM_FUNCTION, name, namelen,
- newname, newnamelen,
- chistics);
-
- DBUG_RETURN(ret);
+ DBUG_RETURN(db_update_routine(thd, TYPE_ENUM_FUNCTION, name, namelen,
+ newname, newnamelen, chistics));
}
+
int
sp_show_create_function(THD *thd, LEX_STRING *name)
{
+ sp_head *sp;
DBUG_ENTER("sp_show_create_function");
DBUG_PRINT("enter", ("name: %*s", name->length, name->str));
- sp_head *sp;
- sp= sp_find_function(thd, name);
- if (sp)
+ if ((sp= sp_find_function(thd, name)))
DBUG_RETURN(sp->show_create_function(thd));
-
DBUG_RETURN(SP_KEY_NOT_FOUND);
}
+
int
sp_show_status_function(THD *thd, const char *wild)
{
@@ -715,6 +701,7 @@ sp_show_status_function(THD *thd, const char *wild)
DBUG_RETURN(db_show_routine_status(thd, TYPE_ENUM_FUNCTION, wild));
}
+
// QQ Temporary until the function call detection in sql_lex has been reworked.
bool
sp_function_exists(THD *thd, LEX_STRING *name)
@@ -722,17 +709,16 @@ sp_function_exists(THD *thd, LEX_STRING *name)
TABLE *table;
bool ret= FALSE;
bool opened= FALSE;
+ DBUG_ENTER("sp_function_exists");
if (sp_cache_lookup(&thd->sp_func_cache, name->str, name->length) ||
db_find_routine_aux(thd, TYPE_ENUM_FUNCTION,
name->str, name->length, TL_READ,
&table, &opened) == SP_OK)
- {
ret= TRUE;
- }
if (opened)
close_thread_tables(thd, 0, 1);
- return ret;
+ DBUG_RETURN(ret);
}
@@ -744,6 +730,7 @@ sp_lex_spfuns_key(const byte *ptr, uint *plen, my_bool first)
return (byte *)lsp->str;
}
+
void
sp_add_fun_to_lex(LEX *lex, LEX_STRING fun)
{
@@ -757,6 +744,7 @@ sp_add_fun_to_lex(LEX *lex, LEX_STRING fun)
}
}
+
void
sp_merge_funs(LEX *dst, LEX *src)
{
@@ -769,6 +757,7 @@ sp_merge_funs(LEX *dst, LEX *src)
}
}
+
int
sp_cache_functions(THD *thd, LEX *lex)
{
@@ -786,8 +775,7 @@ sp_cache_functions(THD *thd, LEX *lex)
LEX *newlex= new st_lex;
thd->lex= newlex;
- if (db_find_routine(thd, TYPE_ENUM_FUNCTION, ls->str, ls->length, &sp)
- == SP_OK)
+ if (db_find_routine(thd, TYPE_ENUM_FUNCTION, ls->str, ls->length, &sp) == SP_OK)
{
ret= sp_cache_functions(thd, newlex);
delete newlex;
@@ -809,6 +797,7 @@ sp_cache_functions(THD *thd, LEX *lex)
return ret;
}
+
static char *
create_string(THD *thd, ulong *lenp,
int type,
@@ -821,23 +810,17 @@ create_string(THD *thd, ulong *lenp,
char *buf, *ptr;
ulong buflen;
- buflen= 100 + namelen + paramslen + returnslen + bodylen +
- chistics->comment.length;
- ptr= buf= thd->alloc(buflen);
+ buflen= 100 + namelen + paramslen + returnslen + bodylen + chistics->comment.length;
+ if (!(buf= thd->alloc(buflen)))
+ return 0;
+
+ ptr= strxmov(buf, "CREATE ", (type == TYPE_ENUM_FUNCTION) ? "FUNCTION" : "PROCEDURE",
+ " `", name, "`(", params, ")", NullS);
+
if (type == TYPE_ENUM_FUNCTION)
- {
- ptr+= my_sprintf(buf,
- (buf, (char *)
- "CREATE FUNCTION %s(%s) RETURNS %s\n",
- name, params, returns));
- }
- else
- {
- ptr+= my_sprintf(buf,
- (buf, (char *)
- "CREATE PROCEDURE %s(%s)\n",
- name, params));
- }
+ ptr= strxmov(ptr, " RETURNS ", returns, NullS);
+ *ptr++= '\n';
+
if (chistics->detistic)
ptr= strmov(ptr, " DETERMINISTIC\n");
if (chistics->suid == IS_NOT_SUID)
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 32d6148e9cf..104db400133 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -3084,23 +3084,23 @@ mysql_execute_command(THD *thd)
break;
}
case SQLCOM_CREATE_FUNCTION: // UDF function
- {
- if (check_access(thd,INSERT_ACL,"mysql",0,1,0))
- break;
+ {
+ sp_head *sph;
+ if (check_access(thd,INSERT_ACL,"mysql",0,1,0))
+ break;
#ifdef HAVE_DLOPEN
- sp_head *sph= sp_find_function(thd, &lex->udf.name);
- if (sph)
- {
- net_printf(thd, ER_UDF_EXISTS, lex->udf.name.str);
- goto error;
- }
- if (!(res = mysql_create_function(thd,&lex->udf)))
- send_ok(thd);
+ if (!(sph= sp_find_function(thd, &lex->udf.name)))
+ {
+ net_printf(thd, ER_UDF_EXISTS, lex->udf.name.str);
+ goto error;
+ }
+ if (!(res = mysql_create_function(thd,&lex->udf)))
+ send_ok(thd);
#else
- res= -1;
+ res= -1;
#endif
break;
- }
+ }
#ifndef NO_EMBEDDED_ACCESS_CHECKS
case SQLCOM_DROP_USER:
{
@@ -3374,62 +3374,62 @@ mysql_execute_command(THD *thd)
break;
case SQLCOM_CREATE_PROCEDURE:
case SQLCOM_CREATE_SPFUNCTION:
+ {
if (!lex->sphead)
{
res= -1; // Shouldn't happen
break;
}
- else
- {
- uint namelen;
- char *name= lex->sphead->name(&namelen);
+ uint namelen;
+ char *name= lex->sphead->name(&namelen);
#ifdef HAVE_DLOPEN
- if (lex->sphead->m_type == TYPE_ENUM_FUNCTION)
- {
- udf_func *udf = find_udf(name, namelen);
-
- if (udf)
- {
- net_printf(thd, ER_UDF_EXISTS, name);
- goto error;
- }
- }
-#endif
- if (lex->sphead->m_type == TYPE_ENUM_FUNCTION &&
- !lex->sphead->m_has_return)
- {
- net_printf(thd, ER_SP_NORETURN, name);
- goto error;
- }
-
- res= lex->sphead->create(thd);
+ if (lex->sphead->m_type == TYPE_ENUM_FUNCTION)
+ {
+ udf_func *udf = find_udf(name, namelen);
- switch (res)
+ if (udf)
{
- case SP_OK:
- send_ok(thd);
- delete lex->sphead;
- lex->sphead= 0;
- break;
- case SP_WRITE_ROW_FAILED:
- net_printf(thd, ER_SP_ALREADY_EXISTS, SP_TYPE_STRING(lex), name);
- delete lex->sphead;
- lex->sphead= 0;
- goto error;
- default:
- net_printf(thd, ER_SP_STORE_FAILED, SP_TYPE_STRING(lex), name);
+ net_printf(thd, ER_UDF_EXISTS, name);
delete lex->sphead;
- lex->sphead= 0;
+ lex->sphead=0;
goto error;
}
+ }
+#endif
+ if (lex->sphead->m_type == TYPE_ENUM_FUNCTION &&
+ !lex->sphead->m_has_return)
+ {
+ net_printf(thd, ER_SP_NORETURN, name);
+ delete lex->sphead;
+ lex->sphead=0;
+ goto error;
+ }
+
+ res= lex->sphead->create(thd);
+ switch (res) {
+ case SP_OK:
+ send_ok(thd);
+ delete lex->sphead;
+ lex->sphead= 0;
break;
+ case SP_WRITE_ROW_FAILED:
+ net_printf(thd, ER_SP_ALREADY_EXISTS, SP_TYPE_STRING(lex), name);
+ delete lex->sphead;
+ lex->sphead= 0;
+ goto error;
+ default:
+ net_printf(thd, ER_SP_STORE_FAILED, SP_TYPE_STRING(lex), name);
+ delete lex->sphead;
+ lex->sphead= 0;
+ goto error;
}
+ break;
+ }
case SQLCOM_CALL:
{
sp_head *sp;
- sp= sp_find_procedure(thd, &lex->udf.name);
- if (! sp)
+ if (!(sp= sp_find_procedure(thd, &lex->udf.name)))
{
net_printf(thd, ER_SP_DOES_NOT_EXIST, "PROCEDURE", lex->udf.name);
goto error;
@@ -3611,6 +3611,7 @@ mysql_execute_command(THD *thd)
res= 0;
goto error;
}
+ res= 0;
break;
}
case SQLCOM_SHOW_STATUS_PROC:
@@ -4157,6 +4158,7 @@ mysql_parse(THD *thd, char *inBuf, uint length)
query_cache_abort(&thd->net);
if (thd->lex->sphead)
{
+ /* Clean up after failed stored procedure/function */
if (lex != thd->lex)
thd->lex->sphead->restore_lex(thd);
delete thd->lex->sphead;