Simplistic, experimental framework for Stored Procedures (SPs).
Implements creation and dropping of PROCEDUREs, IN, OUT, and INOUT parameters,
single-statement procedures, rudimentary multi-statement (begin-end) prodedures
(when the client can handle it), and local variables.
Missing most of the embedded SQL language, all attributes, FUNCTIONs, error handling,
reparses procedures at each call (no caching), etc, etc.
Certainly buggy too, but procedures can actually be created and called....
2002-12-08 19:59:22 +01:00
|
|
|
/* Copyright (C) 2002 MySQL AB
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program; if not, write to the Free Software
|
|
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
|
|
|
|
|
|
|
#ifdef __GNUC__
|
|
|
|
#pragma implementation
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "mysql_priv.h"
|
|
|
|
#include "sp_head.h"
|
2002-12-12 13:14:23 +01:00
|
|
|
#include "sp.h"
|
Simplistic, experimental framework for Stored Procedures (SPs).
Implements creation and dropping of PROCEDUREs, IN, OUT, and INOUT parameters,
single-statement procedures, rudimentary multi-statement (begin-end) prodedures
(when the client can handle it), and local variables.
Missing most of the embedded SQL language, all attributes, FUNCTIONs, error handling,
reparses procedures at each call (no caching), etc, etc.
Certainly buggy too, but procedures can actually be created and called....
2002-12-08 19:59:22 +01:00
|
|
|
#include "sp_pcontext.h"
|
|
|
|
#include "sp_rcontext.h"
|
|
|
|
|
2003-02-26 19:22:29 +01:00
|
|
|
Item_result
|
|
|
|
sp_map_result_type(enum enum_field_types type)
|
|
|
|
{
|
|
|
|
switch (type)
|
|
|
|
{
|
|
|
|
case MYSQL_TYPE_TINY:
|
|
|
|
case MYSQL_TYPE_SHORT:
|
|
|
|
case MYSQL_TYPE_LONG:
|
|
|
|
case MYSQL_TYPE_LONGLONG:
|
|
|
|
case MYSQL_TYPE_INT24:
|
|
|
|
return INT_RESULT;
|
|
|
|
case MYSQL_TYPE_DECIMAL:
|
|
|
|
case MYSQL_TYPE_FLOAT:
|
|
|
|
case MYSQL_TYPE_DOUBLE:
|
|
|
|
return REAL_RESULT;
|
|
|
|
default:
|
|
|
|
return STRING_RESULT;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Simplistic, experimental framework for Stored Procedures (SPs).
Implements creation and dropping of PROCEDUREs, IN, OUT, and INOUT parameters,
single-statement procedures, rudimentary multi-statement (begin-end) prodedures
(when the client can handle it), and local variables.
Missing most of the embedded SQL language, all attributes, FUNCTIONs, error handling,
reparses procedures at each call (no caching), etc, etc.
Certainly buggy too, but procedures can actually be created and called....
2002-12-08 19:59:22 +01:00
|
|
|
/* Evaluate a (presumed) func item. Always returns an item, the parameter
|
|
|
|
** if nothing else.
|
|
|
|
*/
|
2003-10-14 12:59:28 +02:00
|
|
|
Item *
|
|
|
|
sp_eval_func_item(THD *thd, Item *it, enum enum_field_types type)
|
Simplistic, experimental framework for Stored Procedures (SPs).
Implements creation and dropping of PROCEDUREs, IN, OUT, and INOUT parameters,
single-statement procedures, rudimentary multi-statement (begin-end) prodedures
(when the client can handle it), and local variables.
Missing most of the embedded SQL language, all attributes, FUNCTIONs, error handling,
reparses procedures at each call (no caching), etc, etc.
Certainly buggy too, but procedures can actually be created and called....
2002-12-08 19:59:22 +01:00
|
|
|
{
|
2003-10-14 12:59:28 +02:00
|
|
|
DBUG_ENTER("sp_eval_func_item");
|
Simplistic, experimental framework for Stored Procedures (SPs).
Implements creation and dropping of PROCEDUREs, IN, OUT, and INOUT parameters,
single-statement procedures, rudimentary multi-statement (begin-end) prodedures
(when the client can handle it), and local variables.
Missing most of the embedded SQL language, all attributes, FUNCTIONs, error handling,
reparses procedures at each call (no caching), etc, etc.
Certainly buggy too, but procedures can actually be created and called....
2002-12-08 19:59:22 +01:00
|
|
|
it= it->this_item();
|
2003-03-20 11:57:05 +01:00
|
|
|
DBUG_PRINT("info", ("type: %d", type));
|
Simplistic, experimental framework for Stored Procedures (SPs).
Implements creation and dropping of PROCEDUREs, IN, OUT, and INOUT parameters,
single-statement procedures, rudimentary multi-statement (begin-end) prodedures
(when the client can handle it), and local variables.
Missing most of the embedded SQL language, all attributes, FUNCTIONs, error handling,
reparses procedures at each call (no caching), etc, etc.
Certainly buggy too, but procedures can actually be created and called....
2002-12-08 19:59:22 +01:00
|
|
|
|
2003-11-20 18:30:02 +01:00
|
|
|
if (!it->fixed && it->fix_fields(thd, 0, &it))
|
2003-03-20 11:57:05 +01:00
|
|
|
{
|
|
|
|
DBUG_PRINT("info", ("fix_fields() failed"));
|
|
|
|
DBUG_RETURN(it); // Shouldn't happen?
|
|
|
|
}
|
2002-12-13 18:25:36 +01:00
|
|
|
|
2002-12-12 13:14:23 +01:00
|
|
|
/* QQ How do we do this? Is there some better way? */
|
2003-11-20 18:30:02 +01:00
|
|
|
if (type == MYSQL_TYPE_NULL)
|
2003-02-26 19:22:29 +01:00
|
|
|
it= new Item_null();
|
|
|
|
else
|
Simplistic, experimental framework for Stored Procedures (SPs).
Implements creation and dropping of PROCEDUREs, IN, OUT, and INOUT parameters,
single-statement procedures, rudimentary multi-statement (begin-end) prodedures
(when the client can handle it), and local variables.
Missing most of the embedded SQL language, all attributes, FUNCTIONs, error handling,
reparses procedures at each call (no caching), etc, etc.
Certainly buggy too, but procedures can actually be created and called....
2002-12-08 19:59:22 +01:00
|
|
|
{
|
2003-02-26 19:22:29 +01:00
|
|
|
switch (sp_map_result_type(type)) {
|
|
|
|
case INT_RESULT:
|
2003-11-20 18:30:02 +01:00
|
|
|
{
|
|
|
|
longlong i= it->val_int();
|
|
|
|
|
|
|
|
if (it->null_value)
|
2003-11-21 14:00:40 +01:00
|
|
|
{
|
|
|
|
DBUG_PRINT("info", ("INT_RESULT: null"));
|
2003-11-20 18:30:02 +01:00
|
|
|
it= new Item_null();
|
2003-11-21 14:00:40 +01:00
|
|
|
}
|
2003-11-20 18:30:02 +01:00
|
|
|
else
|
2003-11-21 14:00:40 +01:00
|
|
|
{
|
|
|
|
DBUG_PRINT("info", ("INT_RESULT: %d", i));
|
2003-11-20 18:30:02 +01:00
|
|
|
it= new Item_int(it->val_int());
|
2003-11-21 14:00:40 +01:00
|
|
|
}
|
2003-11-20 18:30:02 +01:00
|
|
|
break;
|
|
|
|
}
|
2003-02-26 19:22:29 +01:00
|
|
|
case REAL_RESULT:
|
2003-11-20 18:30:02 +01:00
|
|
|
{
|
|
|
|
double d= it->val();
|
|
|
|
|
|
|
|
if (it->null_value)
|
2003-11-21 14:00:40 +01:00
|
|
|
{
|
|
|
|
DBUG_PRINT("info", ("REAL_RESULT: null"));
|
2003-11-20 18:30:02 +01:00
|
|
|
it= new Item_null();
|
2003-11-21 14:00:40 +01:00
|
|
|
}
|
2003-11-20 18:30:02 +01:00
|
|
|
else
|
2003-11-21 14:00:40 +01:00
|
|
|
{
|
|
|
|
DBUG_PRINT("info", ("REAL_RESULT: %g", d));
|
2003-11-20 18:30:02 +01:00
|
|
|
it= new Item_real(it->val());
|
2003-11-21 14:00:40 +01:00
|
|
|
}
|
2003-11-20 18:30:02 +01:00
|
|
|
break;
|
|
|
|
}
|
2003-02-26 19:22:29 +01:00
|
|
|
default:
|
|
|
|
{
|
|
|
|
char buffer[MAX_FIELD_WIDTH];
|
2003-08-26 17:41:40 +02:00
|
|
|
String tmp(buffer, sizeof(buffer), it->collation.collation);
|
2003-02-26 19:22:29 +01:00
|
|
|
String *s= it->val_str(&tmp);
|
|
|
|
|
2003-11-20 18:30:02 +01:00
|
|
|
if (it->null_value)
|
2003-11-21 14:00:40 +01:00
|
|
|
{
|
|
|
|
DBUG_PRINT("info", ("default result: null"));
|
2003-11-20 18:30:02 +01:00
|
|
|
it= new Item_null();
|
2003-11-21 14:00:40 +01:00
|
|
|
}
|
2003-11-20 18:30:02 +01:00
|
|
|
else
|
2003-11-21 14:00:40 +01:00
|
|
|
{
|
|
|
|
DBUG_PRINT("info",("default result: %*s",s->length(),s->c_ptr_quick()));
|
2003-11-20 18:30:02 +01:00
|
|
|
it= new Item_string(thd->strmake(s->c_ptr_quick(), s->length()),
|
|
|
|
s->length(), it->collation.collation);
|
2003-11-21 14:00:40 +01:00
|
|
|
}
|
2003-02-26 19:22:29 +01:00
|
|
|
break;
|
|
|
|
}
|
Simplistic, experimental framework for Stored Procedures (SPs).
Implements creation and dropping of PROCEDUREs, IN, OUT, and INOUT parameters,
single-statement procedures, rudimentary multi-statement (begin-end) prodedures
(when the client can handle it), and local variables.
Missing most of the embedded SQL language, all attributes, FUNCTIONs, error handling,
reparses procedures at each call (no caching), etc, etc.
Certainly buggy too, but procedures can actually be created and called....
2002-12-08 19:59:22 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-03-20 11:57:05 +01:00
|
|
|
DBUG_RETURN(it);
|
Simplistic, experimental framework for Stored Procedures (SPs).
Implements creation and dropping of PROCEDUREs, IN, OUT, and INOUT parameters,
single-statement procedures, rudimentary multi-statement (begin-end) prodedures
(when the client can handle it), and local variables.
Missing most of the embedded SQL language, all attributes, FUNCTIONs, error handling,
reparses procedures at each call (no caching), etc, etc.
Certainly buggy too, but procedures can actually be created and called....
2002-12-08 19:59:22 +01:00
|
|
|
}
|
|
|
|
|
2003-06-29 18:15:17 +02:00
|
|
|
void *
|
|
|
|
sp_head::operator new(size_t size)
|
|
|
|
{
|
|
|
|
DBUG_ENTER("sp_head::operator new");
|
|
|
|
MEM_ROOT own_root;
|
|
|
|
sp_head *sp;
|
|
|
|
|
|
|
|
bzero((char *)&own_root, sizeof(own_root));
|
|
|
|
init_alloc_root(&own_root, MEM_ROOT_BLOCK_SIZE, MEM_ROOT_PREALLOC);
|
|
|
|
sp= (sp_head *)alloc_root(&own_root, size);
|
|
|
|
sp->m_mem_root= own_root;
|
|
|
|
|
|
|
|
DBUG_RETURN(sp);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
sp_head::operator delete(void *ptr, size_t size)
|
|
|
|
{
|
|
|
|
DBUG_ENTER("sp_head::operator delete");
|
|
|
|
MEM_ROOT own_root;
|
|
|
|
sp_head *sp= (sp_head *)ptr;
|
|
|
|
|
|
|
|
memcpy(&own_root, (const void *)&sp->m_mem_root, sizeof(MEM_ROOT));
|
|
|
|
free_root(&own_root, MYF(0));
|
|
|
|
|
|
|
|
DBUG_VOID_RETURN;
|
|
|
|
}
|
|
|
|
|
2003-07-01 17:19:48 +02:00
|
|
|
sp_head::sp_head()
|
2003-10-03 17:38:12 +02:00
|
|
|
: Sql_alloc(), m_has_return(FALSE), m_simple_case(FALSE),
|
|
|
|
m_multi_results(FALSE), m_free_list(NULL)
|
Simplistic, experimental framework for Stored Procedures (SPs).
Implements creation and dropping of PROCEDUREs, IN, OUT, and INOUT parameters,
single-statement procedures, rudimentary multi-statement (begin-end) prodedures
(when the client can handle it), and local variables.
Missing most of the embedded SQL language, all attributes, FUNCTIONs, error handling,
reparses procedures at each call (no caching), etc, etc.
Certainly buggy too, but procedures can actually be created and called....
2002-12-08 19:59:22 +01:00
|
|
|
{
|
2003-04-03 20:00:52 +02:00
|
|
|
DBUG_ENTER("sp_head::sp_head");
|
2003-07-01 17:19:48 +02:00
|
|
|
|
|
|
|
m_backpatch.empty();
|
|
|
|
m_lex.empty();
|
|
|
|
DBUG_VOID_RETURN;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2003-11-17 18:21:36 +01:00
|
|
|
sp_head::init(LEX_STRING *name, LEX *lex)
|
2003-07-01 17:19:48 +02:00
|
|
|
{
|
|
|
|
DBUG_ENTER("sp_head::init");
|
Simplistic, experimental framework for Stored Procedures (SPs).
Implements creation and dropping of PROCEDUREs, IN, OUT, and INOUT parameters,
single-statement procedures, rudimentary multi-statement (begin-end) prodedures
(when the client can handle it), and local variables.
Missing most of the embedded SQL language, all attributes, FUNCTIONs, error handling,
reparses procedures at each call (no caching), etc, etc.
Certainly buggy too, but procedures can actually be created and called....
2002-12-08 19:59:22 +01:00
|
|
|
const char *dstr = (const char*)lex->buf;
|
|
|
|
|
2003-07-01 17:19:48 +02:00
|
|
|
DBUG_PRINT("info", ("name: %*s", name->length, name->str));
|
2003-04-03 16:00:09 +02:00
|
|
|
m_name.length= name->length;
|
2003-07-01 17:19:48 +02:00
|
|
|
m_name.str= lex->thd->strmake(name->str, name->length);
|
2003-04-03 16:00:09 +02:00
|
|
|
m_defstr.length= lex->end_of_query - lex->buf;
|
2003-06-02 11:25:01 +02:00
|
|
|
m_defstr.str= lex->thd->strmake(dstr, m_defstr.length);
|
2003-07-01 17:19:48 +02:00
|
|
|
lex->spcont= m_pcont= new sp_pcontext();
|
Simplistic, experimental framework for Stored Procedures (SPs).
Implements creation and dropping of PROCEDUREs, IN, OUT, and INOUT parameters,
single-statement procedures, rudimentary multi-statement (begin-end) prodedures
(when the client can handle it), and local variables.
Missing most of the embedded SQL language, all attributes, FUNCTIONs, error handling,
reparses procedures at each call (no caching), etc, etc.
Certainly buggy too, but procedures can actually be created and called....
2002-12-08 19:59:22 +01:00
|
|
|
my_init_dynamic_array(&m_instr, sizeof(sp_instr *), 16, 8);
|
2003-04-03 20:00:52 +02:00
|
|
|
DBUG_VOID_RETURN;
|
Simplistic, experimental framework for Stored Procedures (SPs).
Implements creation and dropping of PROCEDUREs, IN, OUT, and INOUT parameters,
single-statement procedures, rudimentary multi-statement (begin-end) prodedures
(when the client can handle it), and local variables.
Missing most of the embedded SQL language, all attributes, FUNCTIONs, error handling,
reparses procedures at each call (no caching), etc, etc.
Certainly buggy too, but procedures can actually be created and called....
2002-12-08 19:59:22 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
sp_head::create(THD *thd)
|
|
|
|
{
|
2003-02-12 16:17:03 +01:00
|
|
|
DBUG_ENTER("sp_head::create");
|
2003-02-21 17:37:05 +01:00
|
|
|
int ret;
|
|
|
|
|
|
|
|
DBUG_PRINT("info", ("type: %d name: %s def: %s",
|
2003-04-03 16:00:09 +02:00
|
|
|
m_type, m_name.str, m_defstr.str));
|
2003-02-21 17:37:05 +01:00
|
|
|
if (m_type == TYPE_ENUM_FUNCTION)
|
|
|
|
ret= sp_create_function(thd,
|
2003-04-03 16:00:09 +02:00
|
|
|
m_name.str, m_name.length,
|
2003-05-06 18:09:20 +02:00
|
|
|
m_defstr.str, m_defstr.length,
|
2003-12-10 19:05:37 +01:00
|
|
|
m_chistics);
|
2003-02-21 17:37:05 +01:00
|
|
|
else
|
|
|
|
ret= sp_create_procedure(thd,
|
2003-04-03 16:00:09 +02:00
|
|
|
m_name.str, m_name.length,
|
2003-05-06 18:09:20 +02:00
|
|
|
m_defstr.str, m_defstr.length,
|
2003-12-10 19:05:37 +01:00
|
|
|
m_chistics);
|
Simplistic, experimental framework for Stored Procedures (SPs).
Implements creation and dropping of PROCEDUREs, IN, OUT, and INOUT parameters,
single-statement procedures, rudimentary multi-statement (begin-end) prodedures
(when the client can handle it), and local variables.
Missing most of the embedded SQL language, all attributes, FUNCTIONs, error handling,
reparses procedures at each call (no caching), etc, etc.
Certainly buggy too, but procedures can actually be created and called....
2002-12-08 19:59:22 +01:00
|
|
|
|
2003-02-21 17:37:05 +01:00
|
|
|
DBUG_RETURN(ret);
|
Simplistic, experimental framework for Stored Procedures (SPs).
Implements creation and dropping of PROCEDUREs, IN, OUT, and INOUT parameters,
single-statement procedures, rudimentary multi-statement (begin-end) prodedures
(when the client can handle it), and local variables.
Missing most of the embedded SQL language, all attributes, FUNCTIONs, error handling,
reparses procedures at each call (no caching), etc, etc.
Certainly buggy too, but procedures can actually be created and called....
2002-12-08 19:59:22 +01:00
|
|
|
}
|
|
|
|
|
2003-06-29 18:15:17 +02:00
|
|
|
sp_head::~sp_head()
|
|
|
|
{
|
|
|
|
destroy();
|
|
|
|
if (m_thd)
|
|
|
|
restore_thd_mem_root(m_thd);
|
|
|
|
}
|
|
|
|
|
2003-04-02 20:42:28 +02:00
|
|
|
void
|
|
|
|
sp_head::destroy()
|
|
|
|
{
|
2003-04-03 20:00:52 +02:00
|
|
|
DBUG_ENTER("sp_head::destroy");
|
|
|
|
DBUG_PRINT("info", ("name: %s", m_name.str));
|
2003-06-29 18:15:17 +02:00
|
|
|
sp_instr *i;
|
|
|
|
LEX *lex;
|
|
|
|
|
|
|
|
for (uint ip = 0 ; (i = get_instr(ip)) ; ip++)
|
|
|
|
delete i;
|
2003-04-02 20:42:28 +02:00
|
|
|
delete_dynamic(&m_instr);
|
|
|
|
m_pcont->destroy();
|
2003-06-29 18:15:17 +02:00
|
|
|
free_items(m_free_list);
|
|
|
|
while ((lex= (LEX *)m_lex.pop()))
|
|
|
|
{
|
|
|
|
if (lex != &m_thd->main_lex) // We got interrupted and have lex'es left
|
|
|
|
delete lex;
|
|
|
|
}
|
2003-04-03 20:00:52 +02:00
|
|
|
DBUG_VOID_RETURN;
|
2003-04-02 20:42:28 +02:00
|
|
|
}
|
2003-02-26 19:22:29 +01:00
|
|
|
|
Simplistic, experimental framework for Stored Procedures (SPs).
Implements creation and dropping of PROCEDUREs, IN, OUT, and INOUT parameters,
single-statement procedures, rudimentary multi-statement (begin-end) prodedures
(when the client can handle it), and local variables.
Missing most of the embedded SQL language, all attributes, FUNCTIONs, error handling,
reparses procedures at each call (no caching), etc, etc.
Certainly buggy too, but procedures can actually be created and called....
2002-12-08 19:59:22 +01:00
|
|
|
int
|
|
|
|
sp_head::execute(THD *thd)
|
|
|
|
{
|
2003-02-12 16:17:03 +01:00
|
|
|
DBUG_ENTER("sp_head::execute");
|
2003-04-02 20:42:28 +02:00
|
|
|
char olddbname[128];
|
2003-03-26 15:02:48 +01:00
|
|
|
char *olddbptr= thd->db;
|
2003-09-16 14:26:08 +02:00
|
|
|
sp_rcontext *ctx= thd->spcont;
|
Simplistic, experimental framework for Stored Procedures (SPs).
Implements creation and dropping of PROCEDUREs, IN, OUT, and INOUT parameters,
single-statement procedures, rudimentary multi-statement (begin-end) prodedures
(when the client can handle it), and local variables.
Missing most of the embedded SQL language, all attributes, FUNCTIONs, error handling,
reparses procedures at each call (no caching), etc, etc.
Certainly buggy too, but procedures can actually be created and called....
2002-12-08 19:59:22 +01:00
|
|
|
int ret= 0;
|
2003-02-26 19:22:29 +01:00
|
|
|
uint ip= 0;
|
|
|
|
|
2003-03-26 15:02:48 +01:00
|
|
|
if (olddbptr)
|
2003-04-02 20:42:28 +02:00
|
|
|
{
|
|
|
|
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';
|
|
|
|
}
|
2003-03-26 15:02:48 +01:00
|
|
|
|
2003-09-16 14:26:08 +02:00
|
|
|
if (ctx)
|
|
|
|
ctx->clear_handler();
|
2003-02-26 19:22:29 +01:00
|
|
|
do
|
|
|
|
{
|
|
|
|
sp_instr *i;
|
2003-09-16 14:26:08 +02:00
|
|
|
uint hip; // Handler ip
|
2003-02-26 19:22:29 +01:00
|
|
|
|
|
|
|
i = get_instr(ip); // Returns NULL when we're done.
|
|
|
|
if (i == NULL)
|
|
|
|
break;
|
|
|
|
DBUG_PRINT("execute", ("Instruction %u", ip));
|
|
|
|
ret= i->execute(thd, &ip);
|
2003-09-16 14:26:08 +02:00
|
|
|
// Check if an exception has occurred and a handler has been found
|
2003-11-19 11:26:18 +01:00
|
|
|
// Note: We havo to check even if ret==0, since warnings (and some
|
|
|
|
// errors don't return a non-zero value.
|
|
|
|
if (!thd->killed && ctx)
|
2003-09-16 14:26:08 +02:00
|
|
|
{
|
|
|
|
uint hf;
|
|
|
|
|
|
|
|
switch (ctx->found_handler(&hip, &hf))
|
|
|
|
{
|
|
|
|
case SP_HANDLER_NONE:
|
|
|
|
break;
|
|
|
|
case SP_HANDLER_CONTINUE:
|
|
|
|
ctx->save_variables(hf);
|
|
|
|
ctx->push_hstack(ip);
|
|
|
|
// Fall through
|
|
|
|
default:
|
|
|
|
ip= hip;
|
|
|
|
ret= 0;
|
|
|
|
ctx->clear_handler();
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
2003-03-28 17:02:31 +01:00
|
|
|
} while (ret == 0 && !thd->killed);
|
2003-03-26 15:02:48 +01:00
|
|
|
|
2003-03-28 17:02:31 +01:00
|
|
|
DBUG_PRINT("info", ("ret=%d killed=%d", ret, thd->killed));
|
|
|
|
if (thd->killed)
|
|
|
|
ret= -1;
|
2003-03-26 15:02:48 +01:00
|
|
|
/* If the DB has changed, the pointer has changed too, but the
|
|
|
|
original thd->db will then have been freed */
|
2003-04-02 20:42:28 +02:00
|
|
|
if (olddbptr && olddbptr != thd->db)
|
2003-03-26 15:02:48 +01:00
|
|
|
{
|
|
|
|
/* QQ Maybe we should issue some special error message or warning here,
|
|
|
|
if this fails?? */
|
2003-03-28 17:02:31 +01:00
|
|
|
if (! thd->killed)
|
|
|
|
ret= mysql_change_db(thd, olddbname);
|
2003-03-26 15:02:48 +01:00
|
|
|
}
|
2003-02-26 19:22:29 +01:00
|
|
|
DBUG_RETURN(ret);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
sp_head::execute_function(THD *thd, Item **argp, uint argcount, Item **resp)
|
|
|
|
{
|
2003-03-02 19:17:41 +01:00
|
|
|
DBUG_ENTER("sp_head::execute_function");
|
2003-04-03 16:00:09 +02:00
|
|
|
DBUG_PRINT("info", ("function %s", m_name.str));
|
2003-03-02 19:17:41 +01:00
|
|
|
uint csize = m_pcont->max_framesize();
|
|
|
|
uint params = m_pcont->params();
|
2003-09-16 14:26:08 +02:00
|
|
|
uint hmax = m_pcont->handlers();
|
2003-10-10 16:57:21 +02:00
|
|
|
uint cmax = m_pcont->cursors();
|
2003-02-26 19:22:29 +01:00
|
|
|
sp_rcontext *octx = thd->spcont;
|
|
|
|
sp_rcontext *nctx = NULL;
|
|
|
|
uint i;
|
|
|
|
int ret;
|
|
|
|
|
2003-04-17 13:20:02 +02:00
|
|
|
if (argcount != params)
|
|
|
|
{
|
|
|
|
// Need to use my_printf_error here, or it will not terminate the
|
|
|
|
// invoking query properly.
|
|
|
|
my_printf_error(ER_SP_WRONG_NO_OF_ARGS, ER(ER_SP_WRONG_NO_OF_ARGS), MYF(0),
|
|
|
|
"FUNCTION", m_name.str, params, argcount);
|
|
|
|
DBUG_RETURN(-1);
|
|
|
|
}
|
|
|
|
|
|
|
|
// QQ Should have some error checking here? (types, etc...)
|
2003-10-10 16:57:21 +02:00
|
|
|
nctx= new sp_rcontext(csize, hmax, cmax);
|
2003-02-26 19:22:29 +01:00
|
|
|
for (i= 0 ; i < params && i < argcount ; i++)
|
|
|
|
{
|
2003-03-02 19:17:41 +01:00
|
|
|
sp_pvar_t *pvar = m_pcont->find_pvar(i);
|
2003-02-26 19:22:29 +01:00
|
|
|
|
2003-10-14 12:59:28 +02:00
|
|
|
nctx->push_item(sp_eval_func_item(thd, *argp++, pvar->type));
|
2003-02-26 19:22:29 +01:00
|
|
|
}
|
2003-04-23 21:31:47 +02:00
|
|
|
// Close tables opened for subselect in argument list
|
|
|
|
close_thread_tables(thd);
|
|
|
|
|
2003-02-26 19:22:29 +01:00
|
|
|
// The rest of the frame are local variables which are all IN.
|
2003-10-20 16:59:45 +02:00
|
|
|
// Default all variables to null (those with default clauses will
|
|
|
|
// be set by an set instruction).
|
|
|
|
{
|
|
|
|
Item_null *nit= NULL; // Re-use this, and only create if needed
|
|
|
|
for (; i < csize ; i++)
|
|
|
|
{
|
|
|
|
if (! nit)
|
|
|
|
nit= new Item_null();
|
|
|
|
nctx->push_item(nit);
|
|
|
|
}
|
|
|
|
}
|
2003-02-26 19:22:29 +01:00
|
|
|
thd->spcont= nctx;
|
|
|
|
|
|
|
|
ret= execute(thd);
|
|
|
|
if (ret == 0)
|
2003-10-03 17:38:12 +02:00
|
|
|
{
|
|
|
|
Item *it= nctx->get_result();
|
|
|
|
|
|
|
|
if (it)
|
|
|
|
*resp= it;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
my_printf_error(ER_SP_NORETURNEND, ER(ER_SP_NORETURNEND), MYF(0),
|
|
|
|
m_name.str);
|
|
|
|
ret= -1;
|
|
|
|
}
|
|
|
|
}
|
2003-02-26 19:22:29 +01:00
|
|
|
|
2003-10-10 16:57:21 +02:00
|
|
|
nctx->pop_all_cursors(); // To avoid memory leaks after an error
|
2003-02-26 19:22:29 +01:00
|
|
|
thd->spcont= octx;
|
|
|
|
DBUG_RETURN(ret);
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
sp_head::execute_procedure(THD *thd, List<Item> *args)
|
|
|
|
{
|
2003-03-02 19:17:41 +01:00
|
|
|
DBUG_ENTER("sp_head::execute_procedure");
|
2003-04-03 16:00:09 +02:00
|
|
|
DBUG_PRINT("info", ("procedure %s", m_name.str));
|
2003-02-26 19:22:29 +01:00
|
|
|
int ret;
|
Simplistic, experimental framework for Stored Procedures (SPs).
Implements creation and dropping of PROCEDUREs, IN, OUT, and INOUT parameters,
single-statement procedures, rudimentary multi-statement (begin-end) prodedures
(when the client can handle it), and local variables.
Missing most of the embedded SQL language, all attributes, FUNCTIONs, error handling,
reparses procedures at each call (no caching), etc, etc.
Certainly buggy too, but procedures can actually be created and called....
2002-12-08 19:59:22 +01:00
|
|
|
sp_instr *p;
|
2003-03-02 19:17:41 +01:00
|
|
|
uint csize = m_pcont->max_framesize();
|
|
|
|
uint params = m_pcont->params();
|
2003-09-16 14:26:08 +02:00
|
|
|
uint hmax = m_pcont->handlers();
|
2003-10-10 16:57:21 +02:00
|
|
|
uint cmax = m_pcont->cursors();
|
Simplistic, experimental framework for Stored Procedures (SPs).
Implements creation and dropping of PROCEDUREs, IN, OUT, and INOUT parameters,
single-statement procedures, rudimentary multi-statement (begin-end) prodedures
(when the client can handle it), and local variables.
Missing most of the embedded SQL language, all attributes, FUNCTIONs, error handling,
reparses procedures at each call (no caching), etc, etc.
Certainly buggy too, but procedures can actually be created and called....
2002-12-08 19:59:22 +01:00
|
|
|
sp_rcontext *octx = thd->spcont;
|
|
|
|
sp_rcontext *nctx = NULL;
|
2003-02-02 17:44:39 +01:00
|
|
|
my_bool tmp_octx = FALSE; // True if we have allocated a temporary octx
|
Simplistic, experimental framework for Stored Procedures (SPs).
Implements creation and dropping of PROCEDUREs, IN, OUT, and INOUT parameters,
single-statement procedures, rudimentary multi-statement (begin-end) prodedures
(when the client can handle it), and local variables.
Missing most of the embedded SQL language, all attributes, FUNCTIONs, error handling,
reparses procedures at each call (no caching), etc, etc.
Certainly buggy too, but procedures can actually be created and called....
2002-12-08 19:59:22 +01:00
|
|
|
|
2003-04-17 13:20:02 +02:00
|
|
|
if (args->elements != params)
|
|
|
|
{
|
|
|
|
net_printf(thd, ER_SP_WRONG_NO_OF_ARGS, "PROCEDURE", m_name.str,
|
|
|
|
params, args->elements);
|
|
|
|
DBUG_RETURN(-1);
|
|
|
|
}
|
|
|
|
|
2003-10-10 16:57:21 +02:00
|
|
|
if (csize > 0 || hmax > 0 || cmax > 0)
|
Simplistic, experimental framework for Stored Procedures (SPs).
Implements creation and dropping of PROCEDUREs, IN, OUT, and INOUT parameters,
single-statement procedures, rudimentary multi-statement (begin-end) prodedures
(when the client can handle it), and local variables.
Missing most of the embedded SQL language, all attributes, FUNCTIONs, error handling,
reparses procedures at each call (no caching), etc, etc.
Certainly buggy too, but procedures can actually be created and called....
2002-12-08 19:59:22 +01:00
|
|
|
{
|
2003-10-28 15:43:49 +01:00
|
|
|
Item_null *nit= NULL; // Re-use this, and only create if needed
|
Simplistic, experimental framework for Stored Procedures (SPs).
Implements creation and dropping of PROCEDUREs, IN, OUT, and INOUT parameters,
single-statement procedures, rudimentary multi-statement (begin-end) prodedures
(when the client can handle it), and local variables.
Missing most of the embedded SQL language, all attributes, FUNCTIONs, error handling,
reparses procedures at each call (no caching), etc, etc.
Certainly buggy too, but procedures can actually be created and called....
2002-12-08 19:59:22 +01:00
|
|
|
uint i;
|
2003-02-26 19:22:29 +01:00
|
|
|
List_iterator_fast<Item> li(*args);
|
2003-02-21 17:37:05 +01:00
|
|
|
Item *it;
|
Simplistic, experimental framework for Stored Procedures (SPs).
Implements creation and dropping of PROCEDUREs, IN, OUT, and INOUT parameters,
single-statement procedures, rudimentary multi-statement (begin-end) prodedures
(when the client can handle it), and local variables.
Missing most of the embedded SQL language, all attributes, FUNCTIONs, error handling,
reparses procedures at each call (no caching), etc, etc.
Certainly buggy too, but procedures can actually be created and called....
2002-12-08 19:59:22 +01:00
|
|
|
|
2003-10-10 16:57:21 +02:00
|
|
|
nctx= new sp_rcontext(csize, hmax, cmax);
|
2003-02-02 17:44:39 +01:00
|
|
|
if (! octx)
|
|
|
|
{ // Create a temporary old context
|
2003-10-10 16:57:21 +02:00
|
|
|
octx= new sp_rcontext(csize, hmax, cmax);
|
|
|
|
tmp_octx= TRUE;
|
2003-02-02 17:44:39 +01:00
|
|
|
}
|
2003-04-17 13:20:02 +02:00
|
|
|
// QQ: Should do type checking?
|
Simplistic, experimental framework for Stored Procedures (SPs).
Implements creation and dropping of PROCEDUREs, IN, OUT, and INOUT parameters,
single-statement procedures, rudimentary multi-statement (begin-end) prodedures
(when the client can handle it), and local variables.
Missing most of the embedded SQL language, all attributes, FUNCTIONs, error handling,
reparses procedures at each call (no caching), etc, etc.
Certainly buggy too, but procedures can actually be created and called....
2002-12-08 19:59:22 +01:00
|
|
|
for (i = 0 ; (it= li++) && i < params ; i++)
|
|
|
|
{
|
2003-03-02 19:17:41 +01:00
|
|
|
sp_pvar_t *pvar = m_pcont->find_pvar(i);
|
Simplistic, experimental framework for Stored Procedures (SPs).
Implements creation and dropping of PROCEDUREs, IN, OUT, and INOUT parameters,
single-statement procedures, rudimentary multi-statement (begin-end) prodedures
(when the client can handle it), and local variables.
Missing most of the embedded SQL language, all attributes, FUNCTIONs, error handling,
reparses procedures at each call (no caching), etc, etc.
Certainly buggy too, but procedures can actually be created and called....
2002-12-08 19:59:22 +01:00
|
|
|
|
2002-12-11 14:24:29 +01:00
|
|
|
if (! pvar)
|
|
|
|
nctx->set_oindex(i, -1); // Shouldn't happen
|
Simplistic, experimental framework for Stored Procedures (SPs).
Implements creation and dropping of PROCEDUREs, IN, OUT, and INOUT parameters,
single-statement procedures, rudimentary multi-statement (begin-end) prodedures
(when the client can handle it), and local variables.
Missing most of the embedded SQL language, all attributes, FUNCTIONs, error handling,
reparses procedures at each call (no caching), etc, etc.
Certainly buggy too, but procedures can actually be created and called....
2002-12-08 19:59:22 +01:00
|
|
|
else
|
2002-12-11 14:24:29 +01:00
|
|
|
{
|
|
|
|
if (pvar->mode == sp_param_out)
|
2003-10-28 15:43:49 +01:00
|
|
|
{
|
|
|
|
if (! nit)
|
|
|
|
nit= new Item_null();
|
|
|
|
nctx->push_item(nit); // OUT
|
|
|
|
}
|
2002-12-11 14:24:29 +01:00
|
|
|
else
|
2003-10-14 12:59:28 +02:00
|
|
|
nctx->push_item(sp_eval_func_item(thd, it,pvar->type)); // IN or INOUT
|
2002-12-11 14:24:29 +01:00
|
|
|
// Note: If it's OUT or INOUT, it must be a variable.
|
2003-10-16 15:45:27 +02:00
|
|
|
// QQ: We can check for global variables here, or should we do it
|
|
|
|
// while parsing?
|
2002-12-11 14:24:29 +01:00
|
|
|
if (pvar->mode == sp_param_in)
|
|
|
|
nctx->set_oindex(i, -1); // IN
|
|
|
|
else // OUT or INOUT
|
|
|
|
nctx->set_oindex(i, static_cast<Item_splocal *>(it)->get_offset());
|
|
|
|
}
|
Simplistic, experimental framework for Stored Procedures (SPs).
Implements creation and dropping of PROCEDUREs, IN, OUT, and INOUT parameters,
single-statement procedures, rudimentary multi-statement (begin-end) prodedures
(when the client can handle it), and local variables.
Missing most of the embedded SQL language, all attributes, FUNCTIONs, error handling,
reparses procedures at each call (no caching), etc, etc.
Certainly buggy too, but procedures can actually be created and called....
2002-12-08 19:59:22 +01:00
|
|
|
}
|
2003-04-23 21:31:47 +02:00
|
|
|
// Close tables opened for subselect in argument list
|
|
|
|
close_thread_tables(thd);
|
|
|
|
|
Simplistic, experimental framework for Stored Procedures (SPs).
Implements creation and dropping of PROCEDUREs, IN, OUT, and INOUT parameters,
single-statement procedures, rudimentary multi-statement (begin-end) prodedures
(when the client can handle it), and local variables.
Missing most of the embedded SQL language, all attributes, FUNCTIONs, error handling,
reparses procedures at each call (no caching), etc, etc.
Certainly buggy too, but procedures can actually be created and called....
2002-12-08 19:59:22 +01:00
|
|
|
// The rest of the frame are local variables which are all IN.
|
2003-10-17 17:13:49 +02:00
|
|
|
// Default all variables to null (those with default clauses will
|
|
|
|
// be set by an set instruction).
|
2003-10-28 15:43:49 +01:00
|
|
|
for (; i < csize ; i++)
|
2003-10-17 17:13:49 +02:00
|
|
|
{
|
2003-10-28 15:43:49 +01:00
|
|
|
if (! nit)
|
|
|
|
nit= new Item_null();
|
|
|
|
nctx->push_item(nit);
|
2003-10-17 17:13:49 +02:00
|
|
|
}
|
Simplistic, experimental framework for Stored Procedures (SPs).
Implements creation and dropping of PROCEDUREs, IN, OUT, and INOUT parameters,
single-statement procedures, rudimentary multi-statement (begin-end) prodedures
(when the client can handle it), and local variables.
Missing most of the embedded SQL language, all attributes, FUNCTIONs, error handling,
reparses procedures at each call (no caching), etc, etc.
Certainly buggy too, but procedures can actually be created and called....
2002-12-08 19:59:22 +01:00
|
|
|
thd->spcont= nctx;
|
|
|
|
}
|
|
|
|
|
2003-02-26 19:22:29 +01:00
|
|
|
ret= execute(thd);
|
Simplistic, experimental framework for Stored Procedures (SPs).
Implements creation and dropping of PROCEDUREs, IN, OUT, and INOUT parameters,
single-statement procedures, rudimentary multi-statement (begin-end) prodedures
(when the client can handle it), and local variables.
Missing most of the embedded SQL language, all attributes, FUNCTIONs, error handling,
reparses procedures at each call (no caching), etc, etc.
Certainly buggy too, but procedures can actually be created and called....
2002-12-08 19:59:22 +01:00
|
|
|
|
|
|
|
// Don't copy back OUT values if we got an error
|
|
|
|
if (ret == 0 && csize > 0)
|
|
|
|
{
|
2003-03-02 19:17:41 +01:00
|
|
|
List_iterator_fast<Item> li(*args);
|
2003-02-21 17:37:05 +01:00
|
|
|
Item *it;
|
2003-02-02 17:44:39 +01:00
|
|
|
|
|
|
|
// Copy back all OUT or INOUT values to the previous frame, or
|
|
|
|
// set global user variables
|
|
|
|
for (uint i = 0 ; (it= li++) && i < params ; i++)
|
Simplistic, experimental framework for Stored Procedures (SPs).
Implements creation and dropping of PROCEDUREs, IN, OUT, and INOUT parameters,
single-statement procedures, rudimentary multi-statement (begin-end) prodedures
(when the client can handle it), and local variables.
Missing most of the embedded SQL language, all attributes, FUNCTIONs, error handling,
reparses procedures at each call (no caching), etc, etc.
Certainly buggy too, but procedures can actually be created and called....
2002-12-08 19:59:22 +01:00
|
|
|
{
|
|
|
|
int oi = nctx->get_oindex(i);
|
|
|
|
|
|
|
|
if (oi >= 0)
|
2003-02-02 17:44:39 +01:00
|
|
|
{
|
|
|
|
if (! tmp_octx)
|
|
|
|
octx->set_item(nctx->get_oindex(i), nctx->get_item(i));
|
|
|
|
else
|
2003-10-16 15:45:27 +02:00
|
|
|
{
|
|
|
|
// QQ Currently we just silently ignore non-user-variable arguments.
|
|
|
|
// We should check this during parsing, when setting up the call
|
|
|
|
// above
|
|
|
|
if (it->type() == Item::FUNC_ITEM)
|
|
|
|
{
|
|
|
|
Item_func *fi= static_cast<Item_func*>(it);
|
|
|
|
|
|
|
|
if (fi->functype() == Item_func::GUSERVAR_FUNC)
|
|
|
|
{ // A global user variable
|
|
|
|
Item *item= nctx->get_item(i);
|
|
|
|
Item_func_set_user_var *suv;
|
|
|
|
Item_func_get_user_var *guv=
|
|
|
|
static_cast<Item_func_get_user_var*>(fi);
|
|
|
|
|
|
|
|
suv= new Item_func_set_user_var(guv->get_name(), item);
|
|
|
|
suv->fix_fields(thd, NULL, &item);
|
|
|
|
suv->fix_length_and_dec();
|
2003-11-19 16:59:35 +01:00
|
|
|
suv->check();
|
2003-10-16 15:45:27 +02:00
|
|
|
suv->update();
|
|
|
|
}
|
|
|
|
}
|
2003-02-02 17:44:39 +01:00
|
|
|
}
|
|
|
|
}
|
Simplistic, experimental framework for Stored Procedures (SPs).
Implements creation and dropping of PROCEDUREs, IN, OUT, and INOUT parameters,
single-statement procedures, rudimentary multi-statement (begin-end) prodedures
(when the client can handle it), and local variables.
Missing most of the embedded SQL language, all attributes, FUNCTIONs, error handling,
reparses procedures at each call (no caching), etc, etc.
Certainly buggy too, but procedures can actually be created and called....
2002-12-08 19:59:22 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-10-10 16:57:21 +02:00
|
|
|
if (tmp_octx)
|
|
|
|
octx= NULL;
|
|
|
|
if (nctx)
|
|
|
|
nctx->pop_all_cursors(); // To avoid memory leaks after an error
|
|
|
|
thd->spcont= octx;
|
|
|
|
|
2003-02-12 16:17:03 +01:00
|
|
|
DBUG_RETURN(ret);
|
Simplistic, experimental framework for Stored Procedures (SPs).
Implements creation and dropping of PROCEDUREs, IN, OUT, and INOUT parameters,
single-statement procedures, rudimentary multi-statement (begin-end) prodedures
(when the client can handle it), and local variables.
Missing most of the embedded SQL language, all attributes, FUNCTIONs, error handling,
reparses procedures at each call (no caching), etc, etc.
Certainly buggy too, but procedures can actually be created and called....
2002-12-08 19:59:22 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-12-12 13:14:23 +01:00
|
|
|
// Reset lex during parsing, before we parse a sub statement.
|
Simplistic, experimental framework for Stored Procedures (SPs).
Implements creation and dropping of PROCEDUREs, IN, OUT, and INOUT parameters,
single-statement procedures, rudimentary multi-statement (begin-end) prodedures
(when the client can handle it), and local variables.
Missing most of the embedded SQL language, all attributes, FUNCTIONs, error handling,
reparses procedures at each call (no caching), etc, etc.
Certainly buggy too, but procedures can actually be created and called....
2002-12-08 19:59:22 +01:00
|
|
|
void
|
|
|
|
sp_head::reset_lex(THD *thd)
|
|
|
|
{
|
2003-05-23 15:32:31 +02:00
|
|
|
DBUG_ENTER("sp_head::reset_lex");
|
|
|
|
LEX *sublex;
|
2003-06-29 18:15:17 +02:00
|
|
|
LEX *oldlex= thd->lex;
|
2003-05-23 15:32:31 +02:00
|
|
|
|
2003-06-29 18:15:17 +02:00
|
|
|
(void)m_lex.push_front(oldlex);
|
2003-05-23 15:32:31 +02:00
|
|
|
thd->lex= sublex= new st_lex;
|
2003-06-29 18:15:17 +02:00
|
|
|
sublex->yylineno= oldlex->yylineno;
|
Simplistic, experimental framework for Stored Procedures (SPs).
Implements creation and dropping of PROCEDUREs, IN, OUT, and INOUT parameters,
single-statement procedures, rudimentary multi-statement (begin-end) prodedures
(when the client can handle it), and local variables.
Missing most of the embedded SQL language, all attributes, FUNCTIONs, error handling,
reparses procedures at each call (no caching), etc, etc.
Certainly buggy too, but procedures can actually be created and called....
2002-12-08 19:59:22 +01:00
|
|
|
/* Reset most stuff. The length arguments doesn't matter here. */
|
2003-06-29 18:15:17 +02:00
|
|
|
lex_start(thd, oldlex->buf, oldlex->end_of_query - oldlex->ptr);
|
Simplistic, experimental framework for Stored Procedures (SPs).
Implements creation and dropping of PROCEDUREs, IN, OUT, and INOUT parameters,
single-statement procedures, rudimentary multi-statement (begin-end) prodedures
(when the client can handle it), and local variables.
Missing most of the embedded SQL language, all attributes, FUNCTIONs, error handling,
reparses procedures at each call (no caching), etc, etc.
Certainly buggy too, but procedures can actually be created and called....
2002-12-08 19:59:22 +01:00
|
|
|
/* We must reset ptr and end_of_query again */
|
2003-06-29 18:15:17 +02:00
|
|
|
sublex->ptr= oldlex->ptr;
|
|
|
|
sublex->end_of_query= oldlex->end_of_query;
|
|
|
|
sublex->tok_start= oldlex->tok_start;
|
Simplistic, experimental framework for Stored Procedures (SPs).
Implements creation and dropping of PROCEDUREs, IN, OUT, and INOUT parameters,
single-statement procedures, rudimentary multi-statement (begin-end) prodedures
(when the client can handle it), and local variables.
Missing most of the embedded SQL language, all attributes, FUNCTIONs, error handling,
reparses procedures at each call (no caching), etc, etc.
Certainly buggy too, but procedures can actually be created and called....
2002-12-08 19:59:22 +01:00
|
|
|
/* And keep the SP stuff too */
|
2003-06-29 18:15:17 +02:00
|
|
|
sublex->sphead= oldlex->sphead;
|
|
|
|
sublex->spcont= oldlex->spcont;
|
2003-05-23 15:32:31 +02:00
|
|
|
mysql_init_query(thd, true); // Only init lex
|
2003-06-29 18:15:17 +02:00
|
|
|
sublex->sp_lex_in_use= FALSE;
|
2003-05-23 15:32:31 +02:00
|
|
|
DBUG_VOID_RETURN;
|
Simplistic, experimental framework for Stored Procedures (SPs).
Implements creation and dropping of PROCEDUREs, IN, OUT, and INOUT parameters,
single-statement procedures, rudimentary multi-statement (begin-end) prodedures
(when the client can handle it), and local variables.
Missing most of the embedded SQL language, all attributes, FUNCTIONs, error handling,
reparses procedures at each call (no caching), etc, etc.
Certainly buggy too, but procedures can actually be created and called....
2002-12-08 19:59:22 +01:00
|
|
|
}
|
|
|
|
|
2002-12-12 13:14:23 +01:00
|
|
|
// Restore lex during parsing, after we have parsed a sub statement.
|
Simplistic, experimental framework for Stored Procedures (SPs).
Implements creation and dropping of PROCEDUREs, IN, OUT, and INOUT parameters,
single-statement procedures, rudimentary multi-statement (begin-end) prodedures
(when the client can handle it), and local variables.
Missing most of the embedded SQL language, all attributes, FUNCTIONs, error handling,
reparses procedures at each call (no caching), etc, etc.
Certainly buggy too, but procedures can actually be created and called....
2002-12-08 19:59:22 +01:00
|
|
|
void
|
|
|
|
sp_head::restore_lex(THD *thd)
|
|
|
|
{
|
2003-05-23 15:32:31 +02:00
|
|
|
DBUG_ENTER("sp_head::restore_lex");
|
|
|
|
LEX *sublex= thd->lex;
|
2003-06-29 18:15:17 +02:00
|
|
|
LEX *oldlex= (LEX *)m_lex.pop();
|
2003-12-04 15:54:37 +01:00
|
|
|
SELECT_LEX *sl;
|
2003-06-29 18:15:17 +02:00
|
|
|
|
|
|
|
if (! oldlex)
|
|
|
|
return; // Nothing to restore
|
2003-05-23 15:32:31 +02:00
|
|
|
|
Simplistic, experimental framework for Stored Procedures (SPs).
Implements creation and dropping of PROCEDUREs, IN, OUT, and INOUT parameters,
single-statement procedures, rudimentary multi-statement (begin-end) prodedures
(when the client can handle it), and local variables.
Missing most of the embedded SQL language, all attributes, FUNCTIONs, error handling,
reparses procedures at each call (no caching), etc, etc.
Certainly buggy too, but procedures can actually be created and called....
2002-12-08 19:59:22 +01:00
|
|
|
// Update some state in the old one first
|
2003-06-29 18:15:17 +02:00
|
|
|
oldlex->ptr= sublex->ptr;
|
|
|
|
oldlex->next_state= sublex->next_state;
|
2003-12-04 15:54:37 +01:00
|
|
|
for (sl= sublex->all_selects_list ;
|
2003-10-03 12:39:12 +02:00
|
|
|
sl ;
|
|
|
|
sl= sl->next_select_in_list())
|
|
|
|
{
|
2003-11-19 11:26:18 +01:00
|
|
|
// Save WHERE clause pointers to avoid damaging by optimisation
|
2003-10-03 12:39:12 +02:00
|
|
|
sl->prep_where= sl->where;
|
2003-11-19 11:26:18 +01:00
|
|
|
if (sl->with_wild)
|
|
|
|
{
|
|
|
|
// Copy item_list. We will restore it before calling the
|
|
|
|
// sub-statement, so it's ok to pop them.
|
|
|
|
sl->item_list_copy.empty();
|
|
|
|
while (Item *it= sl->item_list.pop())
|
|
|
|
sl->item_list_copy.push_back(it);
|
|
|
|
}
|
2003-10-03 12:39:12 +02:00
|
|
|
}
|
2002-12-13 18:25:36 +01:00
|
|
|
|
2002-12-19 18:43:25 +01:00
|
|
|
// Collect some data from the sub statement lex.
|
2003-06-29 18:15:17 +02:00
|
|
|
sp_merge_funs(oldlex, sublex);
|
|
|
|
#ifdef NOT_USED_NOW
|
2003-04-27 17:35:54 +02:00
|
|
|
// QQ We're not using this at the moment.
|
2003-05-23 15:32:31 +02:00
|
|
|
if (sublex.sql_command == SQLCOM_CALL)
|
2002-12-13 18:25:36 +01:00
|
|
|
{
|
2002-12-19 18:43:25 +01:00
|
|
|
// It would be slightly faster to keep the list sorted, but we need
|
|
|
|
// an "insert before" method to do that.
|
2003-05-23 15:32:31 +02:00
|
|
|
char *proc= sublex.udf.name.str;
|
2002-12-13 18:25:36 +01:00
|
|
|
|
2003-02-21 17:37:05 +01:00
|
|
|
List_iterator_fast<char *> li(m_calls);
|
|
|
|
char **it;
|
2002-12-19 18:43:25 +01:00
|
|
|
|
2003-02-21 17:37:05 +01:00
|
|
|
while ((it= li++))
|
2003-03-27 17:35:27 +01:00
|
|
|
if (my_strcasecmp(system_charset_info, proc, *it) == 0)
|
2002-12-13 18:25:36 +01:00
|
|
|
break;
|
|
|
|
if (! it)
|
2003-02-21 17:37:05 +01:00
|
|
|
m_calls.push_back(&proc);
|
2002-12-19 18:43:25 +01:00
|
|
|
|
|
|
|
}
|
|
|
|
// Merge used tables
|
|
|
|
// QQ ...or just open tables in thd->open_tables?
|
|
|
|
// This is not entirerly clear at the moment, but for now, we collect
|
|
|
|
// tables here.
|
2003-12-04 15:54:37 +01:00
|
|
|
for (sl= sublex.all_selects_list ;
|
2002-12-19 18:43:25 +01:00
|
|
|
sl ;
|
|
|
|
sl= sl->next_select())
|
|
|
|
{
|
|
|
|
for (TABLE_LIST *tables= sl->get_table_list() ;
|
|
|
|
tables ;
|
|
|
|
tables= tables->next)
|
|
|
|
{
|
|
|
|
List_iterator_fast<char *> li(m_tables);
|
|
|
|
char **tb;
|
|
|
|
|
|
|
|
while ((tb= li++))
|
2003-03-27 17:35:27 +01:00
|
|
|
if (my_strcasecmp(system_charset_info, tables->real_name, *tb) == 0)
|
2002-12-19 18:43:25 +01:00
|
|
|
break;
|
|
|
|
if (! tb)
|
|
|
|
m_tables.push_back(&tables->real_name);
|
|
|
|
}
|
2002-12-13 18:25:36 +01:00
|
|
|
}
|
2003-03-02 19:17:41 +01:00
|
|
|
#endif
|
2003-06-29 18:15:17 +02:00
|
|
|
if (! sublex->sp_lex_in_use)
|
|
|
|
delete sublex;
|
|
|
|
thd->lex= oldlex;
|
2003-05-23 15:32:31 +02:00
|
|
|
DBUG_VOID_RETURN;
|
Simplistic, experimental framework for Stored Procedures (SPs).
Implements creation and dropping of PROCEDUREs, IN, OUT, and INOUT parameters,
single-statement procedures, rudimentary multi-statement (begin-end) prodedures
(when the client can handle it), and local variables.
Missing most of the embedded SQL language, all attributes, FUNCTIONs, error handling,
reparses procedures at each call (no caching), etc, etc.
Certainly buggy too, but procedures can actually be created and called....
2002-12-08 19:59:22 +01:00
|
|
|
}
|
|
|
|
|
2002-12-11 14:24:29 +01:00
|
|
|
void
|
2002-12-16 15:40:44 +01:00
|
|
|
sp_head::push_backpatch(sp_instr *i, sp_label_t *lab)
|
2002-12-11 14:24:29 +01:00
|
|
|
{
|
2003-04-02 20:42:28 +02:00
|
|
|
bp_t *bp= (bp_t *)sql_alloc(sizeof(bp_t));
|
2002-12-16 15:40:44 +01:00
|
|
|
|
|
|
|
if (bp)
|
|
|
|
{
|
|
|
|
bp->lab= lab;
|
|
|
|
bp->instr= i;
|
|
|
|
(void)m_backpatch.push_front(bp);
|
|
|
|
}
|
2002-12-11 14:24:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2002-12-16 15:40:44 +01:00
|
|
|
sp_head::backpatch(sp_label_t *lab)
|
Simplistic, experimental framework for Stored Procedures (SPs).
Implements creation and dropping of PROCEDUREs, IN, OUT, and INOUT parameters,
single-statement procedures, rudimentary multi-statement (begin-end) prodedures
(when the client can handle it), and local variables.
Missing most of the embedded SQL language, all attributes, FUNCTIONs, error handling,
reparses procedures at each call (no caching), etc, etc.
Certainly buggy too, but procedures can actually be created and called....
2002-12-08 19:59:22 +01:00
|
|
|
{
|
2002-12-16 15:40:44 +01:00
|
|
|
bp_t *bp;
|
2002-12-12 13:14:23 +01:00
|
|
|
uint dest= instructions();
|
2002-12-16 15:40:44 +01:00
|
|
|
List_iterator_fast<bp_t> li(m_backpatch);
|
Simplistic, experimental framework for Stored Procedures (SPs).
Implements creation and dropping of PROCEDUREs, IN, OUT, and INOUT parameters,
single-statement procedures, rudimentary multi-statement (begin-end) prodedures
(when the client can handle it), and local variables.
Missing most of the embedded SQL language, all attributes, FUNCTIONs, error handling,
reparses procedures at each call (no caching), etc, etc.
Certainly buggy too, but procedures can actually be created and called....
2002-12-08 19:59:22 +01:00
|
|
|
|
2002-12-16 15:40:44 +01:00
|
|
|
while ((bp= li++))
|
|
|
|
if (bp->lab == lab)
|
|
|
|
{
|
|
|
|
sp_instr_jump *i= static_cast<sp_instr_jump *>(bp->instr);
|
Simplistic, experimental framework for Stored Procedures (SPs).
Implements creation and dropping of PROCEDUREs, IN, OUT, and INOUT parameters,
single-statement procedures, rudimentary multi-statement (begin-end) prodedures
(when the client can handle it), and local variables.
Missing most of the embedded SQL language, all attributes, FUNCTIONs, error handling,
reparses procedures at each call (no caching), etc, etc.
Certainly buggy too, but procedures can actually be created and called....
2002-12-08 19:59:22 +01:00
|
|
|
|
2002-12-16 15:40:44 +01:00
|
|
|
i->set_destination(dest);
|
|
|
|
}
|
Simplistic, experimental framework for Stored Procedures (SPs).
Implements creation and dropping of PROCEDUREs, IN, OUT, and INOUT parameters,
single-statement procedures, rudimentary multi-statement (begin-end) prodedures
(when the client can handle it), and local variables.
Missing most of the embedded SQL language, all attributes, FUNCTIONs, error handling,
reparses procedures at each call (no caching), etc, etc.
Certainly buggy too, but procedures can actually be created and called....
2002-12-08 19:59:22 +01:00
|
|
|
}
|
|
|
|
|
2003-11-17 18:21:36 +01:00
|
|
|
int
|
|
|
|
sp_head::show_create_procedure(THD *thd)
|
|
|
|
{
|
|
|
|
Protocol *protocol= thd->protocol;
|
|
|
|
char buff[2048];
|
|
|
|
String buffer(buff, sizeof(buff), system_charset_info);
|
|
|
|
int res;
|
|
|
|
List<Item> field_list;
|
|
|
|
|
|
|
|
DBUG_ENTER("sp_head::show_create_procedure");
|
|
|
|
DBUG_PRINT("info", ("procedure %s", m_name.str));
|
|
|
|
|
|
|
|
field_list.push_back(new Item_empty_string("Procedure",NAME_LEN));
|
|
|
|
// 1024 is for not to confuse old clients
|
|
|
|
field_list.push_back(new Item_empty_string("Create Procedure",
|
|
|
|
max(buffer.length(),1024)));
|
|
|
|
if (protocol->send_fields(&field_list, 1))
|
|
|
|
DBUG_RETURN(1);
|
|
|
|
protocol->prepare_for_resend();
|
|
|
|
protocol->store(m_name.str, m_name.length, system_charset_info);
|
|
|
|
protocol->store(m_defstr.str, m_defstr.length, system_charset_info);
|
|
|
|
res= protocol->write();
|
|
|
|
send_eof(thd);
|
|
|
|
DBUG_RETURN(res);
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
sp_head::show_create_function(THD *thd)
|
|
|
|
{
|
|
|
|
Protocol *protocol= thd->protocol;
|
|
|
|
char buff[2048];
|
|
|
|
String buffer(buff, sizeof(buff), system_charset_info);
|
|
|
|
int res;
|
|
|
|
List<Item> field_list;
|
|
|
|
|
|
|
|
DBUG_ENTER("sp_head::show_create_function");
|
|
|
|
DBUG_PRINT("info", ("procedure %s", m_name.str));
|
Simplistic, experimental framework for Stored Procedures (SPs).
Implements creation and dropping of PROCEDUREs, IN, OUT, and INOUT parameters,
single-statement procedures, rudimentary multi-statement (begin-end) prodedures
(when the client can handle it), and local variables.
Missing most of the embedded SQL language, all attributes, FUNCTIONs, error handling,
reparses procedures at each call (no caching), etc, etc.
Certainly buggy too, but procedures can actually be created and called....
2002-12-08 19:59:22 +01:00
|
|
|
|
2003-11-17 18:21:36 +01:00
|
|
|
field_list.push_back(new Item_empty_string("Function",NAME_LEN));
|
|
|
|
field_list.push_back(new Item_empty_string("Create Function",
|
|
|
|
max(buffer.length(),1024)));
|
|
|
|
if (protocol->send_fields(&field_list, 1))
|
|
|
|
DBUG_RETURN(1);
|
|
|
|
protocol->prepare_for_resend();
|
|
|
|
protocol->store(m_name.str, m_name.length, system_charset_info);
|
|
|
|
protocol->store(m_defstr.str, m_defstr.length, system_charset_info);
|
|
|
|
res= protocol->write();
|
|
|
|
send_eof(thd);
|
|
|
|
DBUG_RETURN(res);
|
|
|
|
}
|
2002-12-11 14:24:29 +01:00
|
|
|
// ------------------------------------------------------------------
|
Simplistic, experimental framework for Stored Procedures (SPs).
Implements creation and dropping of PROCEDUREs, IN, OUT, and INOUT parameters,
single-statement procedures, rudimentary multi-statement (begin-end) prodedures
(when the client can handle it), and local variables.
Missing most of the embedded SQL language, all attributes, FUNCTIONs, error handling,
reparses procedures at each call (no caching), etc, etc.
Certainly buggy too, but procedures can actually be created and called....
2002-12-08 19:59:22 +01:00
|
|
|
|
|
|
|
//
|
|
|
|
// sp_instr_stmt
|
|
|
|
//
|
2003-06-29 18:15:17 +02:00
|
|
|
sp_instr_stmt::~sp_instr_stmt()
|
|
|
|
{
|
|
|
|
if (m_lex)
|
|
|
|
delete m_lex;
|
|
|
|
}
|
|
|
|
|
Simplistic, experimental framework for Stored Procedures (SPs).
Implements creation and dropping of PROCEDUREs, IN, OUT, and INOUT parameters,
single-statement procedures, rudimentary multi-statement (begin-end) prodedures
(when the client can handle it), and local variables.
Missing most of the embedded SQL language, all attributes, FUNCTIONs, error handling,
reparses procedures at each call (no caching), etc, etc.
Certainly buggy too, but procedures can actually be created and called....
2002-12-08 19:59:22 +01:00
|
|
|
int
|
2002-12-11 14:24:29 +01:00
|
|
|
sp_instr_stmt::execute(THD *thd, uint *nextp)
|
Simplistic, experimental framework for Stored Procedures (SPs).
Implements creation and dropping of PROCEDUREs, IN, OUT, and INOUT parameters,
single-statement procedures, rudimentary multi-statement (begin-end) prodedures
(when the client can handle it), and local variables.
Missing most of the embedded SQL language, all attributes, FUNCTIONs, error handling,
reparses procedures at each call (no caching), etc, etc.
Certainly buggy too, but procedures can actually be created and called....
2002-12-08 19:59:22 +01:00
|
|
|
{
|
2003-02-12 16:17:03 +01:00
|
|
|
DBUG_ENTER("sp_instr_stmt::execute");
|
2003-05-23 15:32:31 +02:00
|
|
|
DBUG_PRINT("info", ("command: %d", m_lex->sql_command));
|
2003-10-10 16:57:21 +02:00
|
|
|
int res= exec_stmt(thd, m_lex);
|
|
|
|
*nextp = m_ip+1;
|
|
|
|
DBUG_RETURN(res);
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
sp_instr_stmt::exec_stmt(THD *thd, LEX *lex)
|
|
|
|
{
|
2003-05-23 15:32:31 +02:00
|
|
|
LEX *olex; // The other lex
|
2003-10-03 12:39:12 +02:00
|
|
|
Item *freelist;
|
2003-12-04 15:17:55 +01:00
|
|
|
SELECT_LEX *sl;
|
2003-01-15 15:39:36 +01:00
|
|
|
int res;
|
Simplistic, experimental framework for Stored Procedures (SPs).
Implements creation and dropping of PROCEDUREs, IN, OUT, and INOUT parameters,
single-statement procedures, rudimentary multi-statement (begin-end) prodedures
(when the client can handle it), and local variables.
Missing most of the embedded SQL language, all attributes, FUNCTIONs, error handling,
reparses procedures at each call (no caching), etc, etc.
Certainly buggy too, but procedures can actually be created and called....
2002-12-08 19:59:22 +01:00
|
|
|
|
2003-05-23 15:32:31 +02:00
|
|
|
olex= thd->lex; // Save the other lex
|
2003-10-10 16:57:21 +02:00
|
|
|
thd->lex= lex; // Use my own lex
|
2003-05-23 15:32:31 +02:00
|
|
|
thd->lex->thd = thd; // QQ Not reentrant!
|
|
|
|
thd->lex->unit.thd= thd; // QQ Not reentrant
|
2003-10-03 12:39:12 +02:00
|
|
|
freelist= thd->free_list;
|
|
|
|
thd->free_list= NULL;
|
|
|
|
thd->query_id= query_id++;
|
|
|
|
|
|
|
|
// Copy WHERE clause pointers to avoid damaging by optimisation
|
|
|
|
// Also clear ref_pointer_arrays.
|
2003-12-04 15:17:55 +01:00
|
|
|
for (sl= lex->all_selects_list ;
|
2003-10-03 12:39:12 +02:00
|
|
|
sl ;
|
|
|
|
sl= sl->next_select_in_list())
|
|
|
|
{
|
2003-11-19 11:26:18 +01:00
|
|
|
if (lex->sql_command == SQLCOM_CREATE_TABLE ||
|
|
|
|
lex->sql_command == SQLCOM_INSERT_SELECT)
|
|
|
|
{ // Destroys sl->table_list.first
|
|
|
|
sl->table_list_first_copy= sl->table_list.first;
|
|
|
|
}
|
2003-10-10 16:57:21 +02:00
|
|
|
if (sl->with_wild)
|
|
|
|
{
|
2003-11-19 11:26:18 +01:00
|
|
|
// Restore item_list
|
|
|
|
// Note: We have to do this before executing the sub-statement,
|
|
|
|
// to make sure that the list nodes are in the right
|
|
|
|
// memroot.
|
|
|
|
List_iterator_fast<Item> li(sl->item_list_copy);
|
2003-10-14 12:59:28 +02:00
|
|
|
|
2003-11-19 11:26:18 +01:00
|
|
|
sl->item_list.empty();
|
2003-10-10 16:57:21 +02:00
|
|
|
while (Item *it= li++)
|
2003-11-19 11:26:18 +01:00
|
|
|
sl->item_list.push_back(it);
|
2003-10-10 16:57:21 +02:00
|
|
|
}
|
2003-10-03 12:39:12 +02:00
|
|
|
sl->ref_pointer_array= 0;
|
|
|
|
if (sl->prep_where)
|
|
|
|
sl->where= sl->prep_where->copy_andor_structure(thd);
|
2003-10-14 12:59:28 +02:00
|
|
|
for (ORDER *order= (ORDER *)sl->order_list.first ;
|
|
|
|
order ;
|
|
|
|
order= order->next)
|
|
|
|
{
|
|
|
|
order->item_copy= order->item;
|
|
|
|
}
|
|
|
|
for (ORDER *group= (ORDER *)sl->group_list.first ;
|
|
|
|
group ;
|
|
|
|
group= group->next)
|
|
|
|
{
|
|
|
|
group->item_copy= group->item;
|
|
|
|
}
|
2003-10-03 12:39:12 +02:00
|
|
|
}
|
Simplistic, experimental framework for Stored Procedures (SPs).
Implements creation and dropping of PROCEDUREs, IN, OUT, and INOUT parameters,
single-statement procedures, rudimentary multi-statement (begin-end) prodedures
(when the client can handle it), and local variables.
Missing most of the embedded SQL language, all attributes, FUNCTIONs, error handling,
reparses procedures at each call (no caching), etc, etc.
Certainly buggy too, but procedures can actually be created and called....
2002-12-08 19:59:22 +01:00
|
|
|
|
2003-01-15 15:39:36 +01:00
|
|
|
res= mysql_execute_command(thd);
|
2003-10-03 12:39:12 +02:00
|
|
|
|
2003-02-28 15:07:14 +01:00
|
|
|
if (thd->lock || thd->open_tables || thd->derived_tables)
|
|
|
|
{
|
|
|
|
thd->proc_info="closing tables";
|
|
|
|
close_thread_tables(thd); /* Free tables */
|
|
|
|
}
|
Simplistic, experimental framework for Stored Procedures (SPs).
Implements creation and dropping of PROCEDUREs, IN, OUT, and INOUT parameters,
single-statement procedures, rudimentary multi-statement (begin-end) prodedures
(when the client can handle it), and local variables.
Missing most of the embedded SQL language, all attributes, FUNCTIONs, error handling,
reparses procedures at each call (no caching), etc, etc.
Certainly buggy too, but procedures can actually be created and called....
2002-12-08 19:59:22 +01:00
|
|
|
|
2003-12-04 15:17:55 +01:00
|
|
|
for (sl= lex->all_selects_list ;
|
2003-10-10 16:57:21 +02:00
|
|
|
sl ;
|
|
|
|
sl= sl->next_select_in_list())
|
|
|
|
{
|
2003-11-19 11:26:18 +01:00
|
|
|
TABLE_LIST *tabs;
|
|
|
|
|
|
|
|
// We have closed all tables, get rid of pointers to them
|
|
|
|
for (tabs=(TABLE_LIST *)sl->table_list.first ;
|
|
|
|
tabs ;
|
|
|
|
tabs= tabs->next)
|
2003-10-10 16:57:21 +02:00
|
|
|
{
|
2003-11-19 11:26:18 +01:00
|
|
|
tabs->table= NULL;
|
|
|
|
}
|
|
|
|
if (lex->sql_command == SQLCOM_CREATE_TABLE ||
|
|
|
|
lex->sql_command == SQLCOM_INSERT_SELECT)
|
|
|
|
{ // Restore sl->table_list.first
|
|
|
|
sl->table_list.first= sl->table_list_first_copy;
|
2003-10-10 16:57:21 +02:00
|
|
|
}
|
2003-10-14 12:59:28 +02:00
|
|
|
for (ORDER *order= (ORDER *)sl->order_list.first ;
|
|
|
|
order ;
|
|
|
|
order= order->next)
|
|
|
|
{
|
|
|
|
order->item= order->item_copy;
|
|
|
|
}
|
|
|
|
for (ORDER *group= (ORDER *)sl->group_list.first ;
|
|
|
|
group ;
|
|
|
|
group= group->next)
|
|
|
|
{
|
|
|
|
group->item= group->item_copy;
|
|
|
|
}
|
2003-10-10 16:57:21 +02:00
|
|
|
}
|
2003-05-23 15:32:31 +02:00
|
|
|
thd->lex= olex; // Restore the other lex
|
2003-10-03 12:39:12 +02:00
|
|
|
thd->free_list= freelist;
|
Simplistic, experimental framework for Stored Procedures (SPs).
Implements creation and dropping of PROCEDUREs, IN, OUT, and INOUT parameters,
single-statement procedures, rudimentary multi-statement (begin-end) prodedures
(when the client can handle it), and local variables.
Missing most of the embedded SQL language, all attributes, FUNCTIONs, error handling,
reparses procedures at each call (no caching), etc, etc.
Certainly buggy too, but procedures can actually be created and called....
2002-12-08 19:59:22 +01:00
|
|
|
|
2003-10-10 16:57:21 +02:00
|
|
|
return res;
|
Simplistic, experimental framework for Stored Procedures (SPs).
Implements creation and dropping of PROCEDUREs, IN, OUT, and INOUT parameters,
single-statement procedures, rudimentary multi-statement (begin-end) prodedures
(when the client can handle it), and local variables.
Missing most of the embedded SQL language, all attributes, FUNCTIONs, error handling,
reparses procedures at each call (no caching), etc, etc.
Certainly buggy too, but procedures can actually be created and called....
2002-12-08 19:59:22 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// sp_instr_set
|
|
|
|
//
|
|
|
|
int
|
2002-12-11 14:24:29 +01:00
|
|
|
sp_instr_set::execute(THD *thd, uint *nextp)
|
Simplistic, experimental framework for Stored Procedures (SPs).
Implements creation and dropping of PROCEDUREs, IN, OUT, and INOUT parameters,
single-statement procedures, rudimentary multi-statement (begin-end) prodedures
(when the client can handle it), and local variables.
Missing most of the embedded SQL language, all attributes, FUNCTIONs, error handling,
reparses procedures at each call (no caching), etc, etc.
Certainly buggy too, but procedures can actually be created and called....
2002-12-08 19:59:22 +01:00
|
|
|
{
|
2003-02-12 16:17:03 +01:00
|
|
|
DBUG_ENTER("sp_instr_set::execute");
|
|
|
|
DBUG_PRINT("info", ("offset: %u", m_offset));
|
2003-10-14 12:59:28 +02:00
|
|
|
thd->spcont->set_item(m_offset, sp_eval_func_item(thd, m_value, m_type));
|
2002-12-11 14:24:29 +01:00
|
|
|
*nextp = m_ip+1;
|
2003-02-12 16:17:03 +01:00
|
|
|
DBUG_RETURN(0);
|
2002-12-11 14:24:29 +01:00
|
|
|
}
|
|
|
|
|
2003-03-05 19:45:17 +01:00
|
|
|
//
|
|
|
|
// sp_instr_jump
|
|
|
|
//
|
|
|
|
int
|
|
|
|
sp_instr_jump::execute(THD *thd, uint *nextp)
|
|
|
|
{
|
|
|
|
DBUG_ENTER("sp_instr_jump::execute");
|
|
|
|
DBUG_PRINT("info", ("destination: %u", m_dest));
|
|
|
|
|
|
|
|
*nextp= m_dest;
|
|
|
|
DBUG_RETURN(0);
|
|
|
|
}
|
|
|
|
|
2002-12-11 14:24:29 +01:00
|
|
|
//
|
|
|
|
// sp_instr_jump_if
|
|
|
|
//
|
|
|
|
int
|
|
|
|
sp_instr_jump_if::execute(THD *thd, uint *nextp)
|
|
|
|
{
|
2003-02-12 16:17:03 +01:00
|
|
|
DBUG_ENTER("sp_instr_jump_if::execute");
|
|
|
|
DBUG_PRINT("info", ("destination: %u", m_dest));
|
2003-10-14 12:59:28 +02:00
|
|
|
Item *it= sp_eval_func_item(thd, m_expr, MYSQL_TYPE_TINY);
|
2002-12-11 14:24:29 +01:00
|
|
|
|
|
|
|
if (it->val_int())
|
|
|
|
*nextp = m_dest;
|
|
|
|
else
|
|
|
|
*nextp = m_ip+1;
|
2003-02-12 16:17:03 +01:00
|
|
|
DBUG_RETURN(0);
|
2002-12-11 14:24:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// sp_instr_jump_if_not
|
|
|
|
//
|
|
|
|
int
|
|
|
|
sp_instr_jump_if_not::execute(THD *thd, uint *nextp)
|
|
|
|
{
|
2003-02-12 16:17:03 +01:00
|
|
|
DBUG_ENTER("sp_instr_jump_if_not::execute");
|
|
|
|
DBUG_PRINT("info", ("destination: %u", m_dest));
|
2003-10-14 12:59:28 +02:00
|
|
|
Item *it= sp_eval_func_item(thd, m_expr, MYSQL_TYPE_TINY);
|
2002-12-11 14:24:29 +01:00
|
|
|
|
|
|
|
if (! it->val_int())
|
|
|
|
*nextp = m_dest;
|
|
|
|
else
|
|
|
|
*nextp = m_ip+1;
|
2003-02-12 16:17:03 +01:00
|
|
|
DBUG_RETURN(0);
|
Simplistic, experimental framework for Stored Procedures (SPs).
Implements creation and dropping of PROCEDUREs, IN, OUT, and INOUT parameters,
single-statement procedures, rudimentary multi-statement (begin-end) prodedures
(when the client can handle it), and local variables.
Missing most of the embedded SQL language, all attributes, FUNCTIONs, error handling,
reparses procedures at each call (no caching), etc, etc.
Certainly buggy too, but procedures can actually be created and called....
2002-12-08 19:59:22 +01:00
|
|
|
}
|
2003-02-26 19:22:29 +01:00
|
|
|
|
|
|
|
//
|
2003-09-16 14:26:08 +02:00
|
|
|
// sp_instr_freturn
|
2003-02-26 19:22:29 +01:00
|
|
|
//
|
|
|
|
int
|
2003-09-16 14:26:08 +02:00
|
|
|
sp_instr_freturn::execute(THD *thd, uint *nextp)
|
2003-02-26 19:22:29 +01:00
|
|
|
{
|
2003-09-16 14:26:08 +02:00
|
|
|
DBUG_ENTER("sp_instr_freturn::execute");
|
2003-10-14 12:59:28 +02:00
|
|
|
thd->spcont->set_result(sp_eval_func_item(thd, m_value, m_type));
|
2003-02-26 19:22:29 +01:00
|
|
|
*nextp= UINT_MAX;
|
|
|
|
DBUG_RETURN(0);
|
|
|
|
}
|
2003-09-16 14:26:08 +02:00
|
|
|
|
|
|
|
//
|
|
|
|
// sp_instr_hpush_jump
|
|
|
|
//
|
|
|
|
int
|
|
|
|
sp_instr_hpush_jump::execute(THD *thd, uint *nextp)
|
|
|
|
{
|
|
|
|
DBUG_ENTER("sp_instr_hpush_jump::execute");
|
|
|
|
List_iterator_fast<sp_cond_type_t> li(m_cond);
|
|
|
|
sp_cond_type_t *p;
|
|
|
|
|
|
|
|
while ((p= li++))
|
|
|
|
thd->spcont->push_handler(p, m_handler, m_type, m_frame);
|
|
|
|
|
|
|
|
*nextp= m_dest;
|
|
|
|
DBUG_RETURN(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// sp_instr_hpop
|
|
|
|
//
|
|
|
|
int
|
|
|
|
sp_instr_hpop::execute(THD *thd, uint *nextp)
|
|
|
|
{
|
|
|
|
DBUG_ENTER("sp_instr_hpop::execute");
|
|
|
|
thd->spcont->pop_handlers(m_count);
|
|
|
|
*nextp= m_ip+1;
|
|
|
|
DBUG_RETURN(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// sp_instr_hreturn
|
|
|
|
//
|
|
|
|
int
|
|
|
|
sp_instr_hreturn::execute(THD *thd, uint *nextp)
|
|
|
|
{
|
|
|
|
DBUG_ENTER("sp_instr_hreturn::execute");
|
|
|
|
thd->spcont->restore_variables(m_frame);
|
|
|
|
*nextp= thd->spcont->pop_hstack();
|
|
|
|
DBUG_RETURN(0);
|
|
|
|
}
|
2003-10-10 16:57:21 +02:00
|
|
|
|
|
|
|
//
|
|
|
|
// sp_instr_cpush
|
|
|
|
//
|
|
|
|
int
|
|
|
|
sp_instr_cpush::execute(THD *thd, uint *nextp)
|
|
|
|
{
|
|
|
|
DBUG_ENTER("sp_instr_cpush::execute");
|
|
|
|
thd->spcont->push_cursor(m_lex);
|
|
|
|
*nextp= m_ip+1;
|
|
|
|
DBUG_RETURN(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
sp_instr_cpush::~sp_instr_cpush()
|
|
|
|
{
|
|
|
|
if (m_lex)
|
|
|
|
delete m_lex;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// sp_instr_cpop
|
|
|
|
//
|
|
|
|
int
|
|
|
|
sp_instr_cpop::execute(THD *thd, uint *nextp)
|
|
|
|
{
|
|
|
|
DBUG_ENTER("sp_instr_cpop::execute");
|
|
|
|
thd->spcont->pop_cursors(m_count);
|
|
|
|
*nextp= m_ip+1;
|
|
|
|
DBUG_RETURN(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// sp_instr_copen
|
|
|
|
//
|
|
|
|
int
|
|
|
|
sp_instr_copen::execute(THD *thd, uint *nextp)
|
|
|
|
{
|
|
|
|
sp_cursor *c= thd->spcont->get_cursor(m_cursor);
|
|
|
|
int res;
|
|
|
|
DBUG_ENTER("sp_instr_copen::execute");
|
|
|
|
|
|
|
|
if (! c)
|
|
|
|
res= -1;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
LEX *lex= c->pre_open(thd);
|
|
|
|
|
|
|
|
if (! lex)
|
|
|
|
res= -1;
|
|
|
|
else
|
|
|
|
res= exec_stmt(thd, lex);
|
|
|
|
c->post_open(thd, (res == 0 ? TRUE : FALSE));
|
|
|
|
}
|
|
|
|
|
|
|
|
*nextp= m_ip+1;
|
|
|
|
DBUG_RETURN(res);
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// sp_instr_cclose
|
|
|
|
//
|
|
|
|
int
|
|
|
|
sp_instr_cclose::execute(THD *thd, uint *nextp)
|
|
|
|
{
|
|
|
|
sp_cursor *c= thd->spcont->get_cursor(m_cursor);
|
|
|
|
int res;
|
|
|
|
DBUG_ENTER("sp_instr_cclose::execute");
|
|
|
|
|
|
|
|
if (! c)
|
|
|
|
res= -1;
|
|
|
|
else
|
|
|
|
res= c->close(thd);
|
|
|
|
*nextp= m_ip+1;
|
|
|
|
DBUG_RETURN(res);
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// sp_instr_cfetch
|
|
|
|
//
|
|
|
|
int
|
|
|
|
sp_instr_cfetch::execute(THD *thd, uint *nextp)
|
|
|
|
{
|
|
|
|
sp_cursor *c= thd->spcont->get_cursor(m_cursor);
|
|
|
|
int res;
|
|
|
|
DBUG_ENTER("sp_instr_cfetch::execute");
|
|
|
|
|
|
|
|
if (! c)
|
|
|
|
res= -1;
|
|
|
|
else
|
|
|
|
res= c->fetch(thd, &m_varlist);
|
|
|
|
*nextp= m_ip+1;
|
|
|
|
DBUG_RETURN(res);
|
|
|
|
}
|