summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <pem@mysql.com>2003-04-02 20:42:28 +0200
committerunknown <pem@mysql.com>2003-04-02 20:42:28 +0200
commit2eebaf7bd364ec449c220160e6ff3d59461d13a3 (patch)
tree9fcfdb116729ea80bfec3c92c22a63e896243b06
parent60e7ad754f2f0467a9419c50714f43f4701f88f2 (diff)
downloadmariadb-git-2eebaf7bd364ec449c220160e6ff3d59461d13a3.tar.gz
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.
-rw-r--r--mysql-test/r/sp.result1
-rw-r--r--mysql-test/t/sp.test3
-rw-r--r--sql/sp.cc11
-rw-r--r--sql/sp_head.cc28
-rw-r--r--sql/sp_head.h22
-rw-r--r--sql/sp_pcontext.cc57
-rw-r--r--sql/sp_pcontext.h41
-rw-r--r--sql/sql_class.cc7
-rw-r--r--sql/sql_parse.cc4
9 files changed, 102 insertions, 72 deletions
diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result
index 4833b152f07..1ff6d1552f4 100644
--- a/mysql-test/r/sp.result
+++ b/mysql-test/r/sp.result
@@ -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();
diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test
index 95b3e4732a9..a12e06f24b1 100644
--- a/mysql-test/t/sp.test
+++ b/mysql-test/t/sp.test
@@ -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();
diff --git a/sql/sp.cc b/sql/sp.cc
index 5eb12c9fae5..c8dc328ced1 100644
--- a/sql/sp.cc
+++ b/sql/sp.cc
@@ -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();
}
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 61cf3228760..036207796c3 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -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)
{
diff --git a/sql/sp_head.h b/sql/sp_head.h
index 52cbdc56093..840276681a5 100644
--- a/sql/sp_head.h
+++ b/sql/sp_head.h
@@ -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
diff --git a/sql/sp_pcontext.cc b/sql/sp_pcontext.cc
index d59db9b449b..4d3cf80cd34 100644
--- a/sql/sp_pcontext.cc
+++ b/sql/sp_pcontext.cc
@@ -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)
{
diff --git a/sql/sp_pcontext.h b/sql/sp_pcontext.h
index c5b0f1d410b..6900e18aa93 100644
--- a/sql/sp_pcontext.h
+++ b/sql/sp_pcontext.h
@@ -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
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index d5197b65071..7247d5bc3d0 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -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;
}
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index f22e00a31bc..5259389778c 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -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);
}
}