mirror of
https://github.com/MariaDB/server.git
synced 2025-01-19 05:22:25 +01:00
Merge mysql.com:/usr/local/bk/mysql-5.0
into mysql.com:/home/pem/work/mysql-5.0 sql/sql_parse.cc: Auto merged
This commit is contained in:
commit
739c135112
9 changed files with 102 additions and 72 deletions
|
@ -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();
|
||||
|
|
11
sql/sp.cc
11
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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
@ -3046,6 +3047,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
|
||||
|
@ -3071,6 +3074,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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue