Commit 2eebaf7b authored by unknown's avatar unknown

Getting rid of lots of memory leaks (but not quite all of them yet,

some will go away when temporary code is replaced).


mysql-test/r/sp.result:
  Drop db before creating.
mysql-test/t/sp.test:
  Drop db before creating.
parent 60e7ad75
......@@ -20,6 +20,7 @@ delete from t1;
drop procedure foo42;
create procedure u()
use sptmp;
drop database if exists sptmp;
create database sptmp;
use test;
call u();
......
......@@ -35,6 +35,9 @@ drop procedure foo42;
create procedure u()
use sptmp;
--disable_warnings
drop database if exists sptmp;
--enable_warnings
create database sptmp;
use test;
call u();
......
......@@ -19,8 +19,8 @@
#include "sp.h"
#include "sp_head.h"
static sp_head *
sp_find_cached_function(THD *thd, char *name, uint namelen);
static sp_head *
sp_find_cached_function(THD *thd, char *name, uint namelen);
/*
*
......@@ -373,6 +373,13 @@ sp_cache_functions(THD *thd, LEX *lex)
void
sp_clear_function_cache(THD *thd)
{
//QQ This doesn't work for some completely mysterious reason, but since this
//QQ is tempoarary code anyway, we just ignore it for now.
//QQ List_iterator_fast<sp_head> li(thd->spfuns);
//QQ sp_head *sp;
//QQ while ((sp= li++))
//QQ sp->destroy();
thd->spfuns.empty();
}
......
......@@ -92,7 +92,7 @@ eval_func_item(THD *thd, Item *it, enum enum_field_types type)
}
sp_head::sp_head(LEX_STRING *name, LEX *lex)
: m_simple_case(FALSE)
: Sql_alloc(), m_simple_case(FALSE)
{
const char *dstr = (const char*)lex->buf;
......@@ -126,19 +126,34 @@ sp_head::create(THD *thd)
DBUG_RETURN(ret);
}
void
sp_head::destroy()
{
delete_dynamic(&m_instr);
m_pcont->destroy();
}
int
sp_head::execute(THD *thd)
{
DBUG_ENTER("sp_head::execute");
char *olddbname;
char olddbname[128];
char *olddbptr= thd->db;
int ret= 0;
uint ip= 0;
LINT_INIT(olddbname);
if (olddbptr)
olddbname= my_strdup(olddbptr, MYF(MY_WME));
{
uint i= 0;
char *p= olddbptr;
/* Fast inline strncpy without padding... */
while (*p && i < sizeof(olddbname))
olddbname[i++]= *p++;
if (i == sizeof(olddbname))
i-= 1; // QQ Error or warning for truncate?
olddbname[i]= '\0';
}
do
{
......@@ -156,13 +171,12 @@ sp_head::execute(THD *thd)
ret= -1;
/* If the DB has changed, the pointer has changed too, but the
original thd->db will then have been freed */
if (olddbptr && olddbptr != thd->db && olddbname)
if (olddbptr && olddbptr != thd->db)
{
/* QQ Maybe we should issue some special error message or warning here,
if this fails?? */
if (! thd->killed)
ret= mysql_change_db(thd, olddbname);
my_free(olddbname, MYF(0));
}
DBUG_RETURN(ret);
}
......@@ -399,7 +413,7 @@ sp_head::restore_lex(THD *thd)
void
sp_head::push_backpatch(sp_instr *i, sp_label_t *lab)
{
bp_t *bp= (bp_t *)my_malloc(sizeof(bp_t), MYF(MY_WME));
bp_t *bp= (bp_t *)sql_alloc(sizeof(bp_t));
if (bp)
{
......
......@@ -52,21 +52,15 @@ public:
List<char *> m_tables; // Used tables.
#endif
static void *operator new(size_t size)
{
return (void*) sql_alloc((uint) size);
}
static void operator delete(void *ptr, size_t size)
{
/* Empty */
}
sp_head(LEX_STRING *name, LEX *lex);
int
create(THD *thd);
// Free memory
void
destroy();
int
execute_function(THD *thd, Item **args, uint argcount, Item **resp);
......@@ -134,11 +128,13 @@ private:
inline sp_instr *
get_instr(uint i)
{
sp_instr *in= NULL;
sp_instr *ip;
if (i < m_instr.elements)
get_dynamic(&m_instr, (gptr)&in, i);
return in;
get_dynamic(&m_instr, (gptr)&ip, i);
else
ip= NULL;
return ip;
}
int
......
......@@ -27,30 +27,20 @@
#include "sp_head.h"
sp_pcontext::sp_pcontext()
: m_params(0), m_framesize(0), m_i(0), m_genlab(0)
: Sql_alloc(), m_params(0), m_framesize(0), m_genlab(0)
{
m_pvar_size = 16;
m_pvar = (sp_pvar_t *)my_malloc(m_pvar_size * sizeof(sp_pvar_t), MYF(MY_WME));
if (m_pvar)
memset(m_pvar, 0, m_pvar_size * sizeof(sp_pvar_t));
VOID(my_init_dynamic_array(&m_pvar, sizeof(sp_pvar_t *), 16, 8));
m_label.empty();
}
void
sp_pcontext::grow()
sp_pcontext::destroy()
{
uint sz = m_pvar_size + 8;
sp_pvar_t *a = (sp_pvar_t *)my_realloc((char *)m_pvar,
sz * sizeof(sp_pvar_t),
MYF(MY_WME | MY_ALLOW_ZERO_PTR));
if (a)
{
m_pvar_size = sz;
m_pvar = a;
}
delete_dynamic(&m_pvar);
m_label.empty();
}
/* This does a linear search (from newer to older variables, in case
** we have shadowed names).
** It's possible to have a more efficient allocation and search method,
......@@ -61,19 +51,20 @@ sp_pcontext::grow()
sp_pvar_t *
sp_pcontext::find_pvar(LEX_STRING *name)
{
uint i = m_i;
uint i = m_pvar.elements;
while (i-- > 0)
{
uint len= (m_pvar[i].name.length > name->length ?
m_pvar[i].name.length : name->length);
sp_pvar_t *p= find_pvar(i);
uint len= (p->name.length > name->length ?
p->name.length : name->length);
if (my_strncasecmp(system_charset_info,
name->str,
m_pvar[i].name.str,
p->name.str,
len) == 0)
{
return m_pvar + i;
return p;
}
}
return NULL;
......@@ -83,26 +74,26 @@ void
sp_pcontext::push(LEX_STRING *name, enum enum_field_types type,
sp_param_mode_t mode)
{
if (m_i >= m_pvar_size)
grow();
if (m_i < m_pvar_size)
sp_pvar_t *p= (sp_pvar_t *)sql_alloc(sizeof(sp_pvar_t));
if (p)
{
if (m_i == m_framesize)
if (m_pvar.elements == m_framesize)
m_framesize += 1;
m_pvar[m_i].name.str= name->str;
m_pvar[m_i].name.length= name->length,
m_pvar[m_i].type= type;
m_pvar[m_i].mode= mode;
m_pvar[m_i].offset= m_i;
m_pvar[m_i].isset= (mode == sp_param_out ? FALSE : TRUE);
m_i += 1;
p->name.str= name->str;
p->name.length= name->length;
p->type= type;
p->mode= mode;
p->offset= m_pvar.elements;
p->isset= (mode == sp_param_out ? FALSE : TRUE);
insert_dynamic(&m_pvar, (gptr)&p);
}
}
sp_label_t *
sp_pcontext::push_label(char *name, uint ip)
{
sp_label_t *lab = (sp_label_t *)my_malloc(sizeof(sp_label_t), MYF(MY_WME));
sp_label_t *lab = (sp_label_t *)sql_alloc(sizeof(sp_label_t));
if (lab)
{
......
......@@ -53,6 +53,10 @@ class sp_pcontext : public Sql_alloc
sp_pcontext();
// Free memory
void
destroy();
inline uint
max_framesize()
{
......@@ -62,7 +66,7 @@ class sp_pcontext : public Sql_alloc
inline uint
current_framesize()
{
return m_i;
return m_pvar.elements;
}
inline uint
......@@ -75,21 +79,25 @@ class sp_pcontext : public Sql_alloc
inline void
set_params()
{
m_params= m_i;
m_params= m_pvar.elements;
}
inline void
set_type(uint i, enum enum_field_types type)
{
if (i < m_i)
m_pvar[i].type= type;
sp_pvar_t *p= find_pvar(i);
if (p)
p->type= type;
}
inline void
set_isset(uint i, my_bool val)
{
if (i < m_i)
m_pvar[i].isset= val;
sp_pvar_t *p= find_pvar(i);
if (p)
p->isset= val;
}
void
......@@ -99,8 +107,8 @@ class sp_pcontext : public Sql_alloc
inline void
pop(uint num = 1)
{
if (num < m_i)
m_i -= num;
while (num--)
pop_dynamic(&m_pvar);
}
// Find by name
......@@ -111,9 +119,13 @@ class sp_pcontext : public Sql_alloc
sp_pvar_t *
find_pvar(uint i)
{
if (i >= m_i)
return NULL;
return m_pvar+i;
sp_pvar_t *p;
if (i < m_pvar.elements)
get_dynamic(&m_pvar, (gptr)&p, i);
else
p= NULL;
return p;
}
sp_label_t *
......@@ -138,13 +150,8 @@ private:
uint m_params; // The number of parameters
uint m_framesize; // The maximum framesize
uint m_i; // The current index (during parsing)
sp_pvar_t *m_pvar;
uint m_pvar_size; // Current size of m_pvar.
void
grow();
DYNAMIC_ARRAY m_pvar;
List<sp_label_t> m_label; // The label list
uint m_genlab; // Gen. label counter
......
......@@ -191,6 +191,9 @@ THD::THD():user_time(0), is_fatal_error(0),
pthread_mutex_unlock(&LOCK_thread_count);
randominit(&rand, tmp + (ulong) &rand, tmp + (ulong) ::query_id);
}
/* QQ init the temporary function cache */
spfuns.empty();
}
......@@ -282,6 +285,10 @@ void THD::cleanup(void)
pthread_mutex_unlock(&LOCK_user_locks);
ull= 0;
}
// extern void sp_clear_function_cache(THD *);
// sp_clear_function_cache(this);
cleanup_done=1;
DBUG_VOID_RETURN;
}
......
......@@ -2810,6 +2810,7 @@ mysql_execute_command(THD *thd)
sp_head *sph= sp_find_function(thd, &lex->udf.name);
if (sph)
{
sph->destroy(); // QQ Free memory. Remove this when caching!!!
net_printf(thd, ER_UDF_EXISTS, lex->udf.name.str);
goto error;
}
......@@ -3050,6 +3051,8 @@ mysql_execute_command(THD *thd)
thd->net.no_send_ok= nsok;
#endif
sp->destroy(); // QQ Free memory. Remove this when caching!!!
if (res == 0)
send_ok(thd);
else
......@@ -3075,6 +3078,7 @@ mysql_execute_command(THD *thd)
{
/* QQ This is an no-op right now, since we haven't
put the characteristics in yet. */
sp->destroy(); // QQ Free memory. Remove this when caching!!!
send_ok(thd);
}
}
......
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