Fixed save/restore of current database when calling a procedure.
This commit is contained in:
parent
3946b8235c
commit
2c9ef84cc3
@ -243,6 +243,23 @@
|
|||||||
5) On success, set the new values of the OUT and INOUT parameters in
|
5) On success, set the new values of the OUT and INOUT parameters in
|
||||||
the caller's frame.
|
the caller's frame.
|
||||||
|
|
||||||
|
- USE database
|
||||||
|
|
||||||
|
Before executing the instruction we also keeps the current default
|
||||||
|
database (if any). If this was changed during execution (i.e. a "USE"
|
||||||
|
statement has been executed), we restore the current database to the
|
||||||
|
original.
|
||||||
|
|
||||||
|
This is the most useful way to handle USE in procedures. If we didn't,
|
||||||
|
the caller would find himself in a different database after calling
|
||||||
|
a function, which can be confusing.
|
||||||
|
Restoring the database also gives full freedom to the procedure writer:
|
||||||
|
- It's possible to write "general" procedures that are independent of
|
||||||
|
the actual database name.
|
||||||
|
- It's possible to write procedures that work on a particular database
|
||||||
|
by calling USE, without having to use fully qualified table names
|
||||||
|
everywhere (which doesn't help if you want to call other, "general",
|
||||||
|
procedures anyway).
|
||||||
|
|
||||||
- Evaluating Items
|
- Evaluating Items
|
||||||
|
|
||||||
@ -340,6 +357,9 @@
|
|||||||
Dropping is done by simply getting the procedure with the sp_find()
|
Dropping is done by simply getting the procedure with the sp_find()
|
||||||
function and calling sp_drop() (both in sp.{cc,h}).
|
function and calling sp_drop() (both in sp.{cc,h}).
|
||||||
|
|
||||||
|
DROP PROCEDURE/FUNCTION also supports the non-standard "IF EXISTS",
|
||||||
|
analogous to other DROP statements in MySQL.
|
||||||
|
|
||||||
|
|
||||||
- Class and function APIs
|
- Class and function APIs
|
||||||
|
|
||||||
|
@ -18,6 +18,16 @@ id data
|
|||||||
foo 42
|
foo 42
|
||||||
delete from t1;
|
delete from t1;
|
||||||
drop procedure foo42;
|
drop procedure foo42;
|
||||||
|
create procedure u()
|
||||||
|
use sptmp;
|
||||||
|
create database sptmp;
|
||||||
|
use test;
|
||||||
|
call u();
|
||||||
|
select database();
|
||||||
|
database()
|
||||||
|
test
|
||||||
|
drop database sptmp;
|
||||||
|
drop procedure u;
|
||||||
create procedure bar(x char(16), y int)
|
create procedure bar(x char(16), y int)
|
||||||
insert into test.t1 values (x, y);
|
insert into test.t1 values (x, y);
|
||||||
call bar("bar", 666);
|
call bar("bar", 666);
|
||||||
|
@ -31,6 +31,18 @@ delete from t1;
|
|||||||
drop procedure foo42;
|
drop procedure foo42;
|
||||||
|
|
||||||
|
|
||||||
|
# USE test: Make sure we remain in the same DB.
|
||||||
|
create procedure u()
|
||||||
|
use sptmp;
|
||||||
|
|
||||||
|
create database sptmp;
|
||||||
|
use test;
|
||||||
|
call u();
|
||||||
|
select database();
|
||||||
|
drop database sptmp;
|
||||||
|
drop procedure u;
|
||||||
|
|
||||||
|
|
||||||
# Single statement, two IN params.
|
# Single statement, two IN params.
|
||||||
create procedure bar(x char(16), y int)
|
create procedure bar(x char(16), y int)
|
||||||
insert into test.t1 values (x, y);
|
insert into test.t1 values (x, y);
|
||||||
|
@ -131,9 +131,14 @@ int
|
|||||||
sp_head::execute(THD *thd)
|
sp_head::execute(THD *thd)
|
||||||
{
|
{
|
||||||
DBUG_ENTER("sp_head::execute");
|
DBUG_ENTER("sp_head::execute");
|
||||||
|
char *olddbname;
|
||||||
|
char *olddbptr= thd->db;
|
||||||
int ret= 0;
|
int ret= 0;
|
||||||
uint ip= 0;
|
uint ip= 0;
|
||||||
|
|
||||||
|
if (olddbptr)
|
||||||
|
olddbname= my_strdup(olddbptr, MYF(MY_WME));
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
sp_instr *i;
|
sp_instr *i;
|
||||||
@ -144,6 +149,16 @@ sp_head::execute(THD *thd)
|
|||||||
DBUG_PRINT("execute", ("Instruction %u", ip));
|
DBUG_PRINT("execute", ("Instruction %u", ip));
|
||||||
ret= i->execute(thd, &ip);
|
ret= i->execute(thd, &ip);
|
||||||
} while (ret == 0);
|
} while (ret == 0);
|
||||||
|
|
||||||
|
/* 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)
|
||||||
|
{
|
||||||
|
/* QQ Maybe we should issue some special error message or warning here,
|
||||||
|
if this fails?? */
|
||||||
|
ret= mysql_change_db(thd, olddbname);
|
||||||
|
my_free(olddbname, MYF(0));
|
||||||
|
}
|
||||||
DBUG_RETURN(ret);
|
DBUG_RETURN(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user