mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
Fixed BUG#1862 (flush table in SPs didn't work).
Fixed various bugs: setting local variables to NULL, SELECT INTO var now actually might work, SELECT INTO with not row now gives a "no data" warning (instead of the "empty query" error), etc. Updated test cases accordingly. mysql-test/r/sp-error.result: Corrected security syntax for alter/create procedure. mysql-test/r/sp.result: Corrected security syntax for alter/create procedure. New tests for setting local variables to null, bug fixes for SELECT INTO var, FLUSH TABLES calls (BUG#1862), and corrected "no data" warning for SELECT INTO with no rows. mysql-test/t/sp-error.test: Corrected security syntax for alter/create procedure. mysql-test/t/sp.test: Corrected security syntax for alter/create procedure. New tests for setting local variables to null, bug fixes for SELECT INTO var, FLUSH TABLES calls (BUG#1862), and corrected "no data" warning for SELECT INTO with no rows. sql/lex.h: Added SQL_SYM (and added a few _SYM suffixes for new symbols). sql/sp_head.cc: Fixed bug in the item_list copying for "with_wild" cases (list nodes ended up in the wrong memroot). Catch errors and warnings even if return values is 0 from sub-statements. Restore table_list which is zapped by SQLCOM_CREATE_TABLE and INSERT_SELECT. Set old table pointers to NULL after sub-statement call (since all tables are closed). sql/sql_class.cc: Corrected error message when no rows return by a SELECT INTO var; should be a "no data" warning. sql/sql_lex.h: Have to store the original table_list first pointer for some sub-statements in SPs. sql/sql_yacc.yy: Corrected SECURITY INVOKER/DEFINER syntax ("SQL" missing), added some _SYM suffixes, and fixed valgrind complaints for SP COMMENTs. (Also removed some now irrelevant comments.)
This commit is contained in:
@ -187,7 +187,7 @@ end;
|
|||||||
call p();
|
call p();
|
||||||
ERROR HY000: Cursor is not open
|
ERROR HY000: Cursor is not open
|
||||||
drop procedure p;
|
drop procedure p;
|
||||||
alter procedure bar3 SECURITY INVOKER;
|
alter procedure bar3 sql security invoker;
|
||||||
ERROR HY000: PROCEDURE bar3 does not exist
|
ERROR HY000: PROCEDURE bar3 does not exist
|
||||||
alter procedure bar3 name
|
alter procedure bar3 name
|
||||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA;
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA;
|
||||||
|
@ -75,6 +75,23 @@ id data
|
|||||||
locset 21
|
locset 21
|
||||||
delete from t1;
|
delete from t1;
|
||||||
drop procedure locset;
|
drop procedure locset;
|
||||||
|
drop table if exists t3;
|
||||||
|
create table t3 ( d date, i int, f double, s varchar(32) );
|
||||||
|
create procedure nullset()
|
||||||
|
begin
|
||||||
|
declare ld date;
|
||||||
|
declare li int;
|
||||||
|
declare lf double;
|
||||||
|
declare ls varchar(32);
|
||||||
|
set ld = null, li = null, lf = null, ls = null;
|
||||||
|
insert into t3 values (ld, li, lf, ls);
|
||||||
|
end;
|
||||||
|
call nullset();
|
||||||
|
select * from t3;
|
||||||
|
d i f s
|
||||||
|
NULL NULL NULL NULL
|
||||||
|
drop table t3;
|
||||||
|
drop procedure nullset;
|
||||||
create procedure mixset(x char(16), y int)
|
create procedure mixset(x char(16), y int)
|
||||||
begin
|
begin
|
||||||
declare z int;
|
declare z int;
|
||||||
@ -390,6 +407,47 @@ into 100 100
|
|||||||
into2 102 100
|
into2 102 100
|
||||||
delete from t1;
|
delete from t1;
|
||||||
drop procedure into_test2;
|
drop procedure into_test2;
|
||||||
|
create procedure into_test3()
|
||||||
|
begin
|
||||||
|
declare x char(16);
|
||||||
|
declare y int;
|
||||||
|
select * into x,y from test.t1 limit 1;
|
||||||
|
insert into test.t2 values (x, y, 0.0);
|
||||||
|
end;
|
||||||
|
insert into t1 values ("into3", 19);
|
||||||
|
delete from t2;
|
||||||
|
call into_test3();
|
||||||
|
call into_test3();
|
||||||
|
select * from t2;
|
||||||
|
s i d
|
||||||
|
into3 19 0
|
||||||
|
into3 19 0
|
||||||
|
delete from t1;
|
||||||
|
delete from t2;
|
||||||
|
drop procedure into_test3;
|
||||||
|
create procedure into_test4()
|
||||||
|
begin
|
||||||
|
declare x int;
|
||||||
|
select data into x from test.t1 limit 1;
|
||||||
|
insert into test.t3 values ("into4", x);
|
||||||
|
end;
|
||||||
|
delete from t1;
|
||||||
|
drop table if exists t3;
|
||||||
|
create table t3 ( s char(16), d int);
|
||||||
|
call into_test4();
|
||||||
|
Warnings:
|
||||||
|
select * from t3;
|
||||||
|
s d
|
||||||
|
into4 NULL
|
||||||
|
insert into t1 values ("i4", 77);
|
||||||
|
call into_test4();
|
||||||
|
select * from t3;
|
||||||
|
s d
|
||||||
|
into4 NULL
|
||||||
|
into4 77
|
||||||
|
delete from t1;
|
||||||
|
drop table t3;
|
||||||
|
drop procedure into_test4;
|
||||||
create procedure into_outfile(x char(16), y int)
|
create procedure into_outfile(x char(16), y int)
|
||||||
begin
|
begin
|
||||||
insert into test.t1 values (x, y);
|
insert into test.t1 values (x, y);
|
||||||
@ -475,9 +533,6 @@ s i d
|
|||||||
xxxyyy 12 2.71828182845905
|
xxxyyy 12 2.71828182845905
|
||||||
select * from t2;
|
select * from t2;
|
||||||
s i d
|
s i d
|
||||||
a 1 1.1
|
|
||||||
b 2 1.2
|
|
||||||
c 3 1.3
|
|
||||||
xxxyyy 12 2.71828182845905
|
xxxyyy 12 2.71828182845905
|
||||||
ab 24 1324.36598821719
|
ab 24 1324.36598821719
|
||||||
delete from t2;
|
delete from t2;
|
||||||
@ -551,7 +606,7 @@ create procedure hndlr4()
|
|||||||
begin
|
begin
|
||||||
declare x int default 0;
|
declare x int default 0;
|
||||||
declare val int; # No default
|
declare val int; # No default
|
||||||
declare continue handler for sqlexception set x=1;
|
declare continue handler for 1306 set x=1;
|
||||||
select data into val from test.t3 where id='z' limit 1; # No hits
|
select data into val from test.t3 where id='z' limit 1; # No hits
|
||||||
insert into test.t3 values ('z', val);
|
insert into test.t3 values ('z', val);
|
||||||
end;
|
end;
|
||||||
@ -695,6 +750,21 @@ select @1, @2;
|
|||||||
2 NULL
|
2 NULL
|
||||||
drop table t70;
|
drop table t70;
|
||||||
drop procedure bug1656;
|
drop procedure bug1656;
|
||||||
|
drop table if exists t3;
|
||||||
|
create table t3(a int);
|
||||||
|
create procedure bug1862()
|
||||||
|
begin
|
||||||
|
insert into t3 values(2);
|
||||||
|
flush tables;
|
||||||
|
end;
|
||||||
|
call bug1862();
|
||||||
|
call bug1862();
|
||||||
|
select * from t3;
|
||||||
|
a
|
||||||
|
2
|
||||||
|
2
|
||||||
|
drop table t3;
|
||||||
|
drop procedure bug1862;
|
||||||
drop table if exists fac;
|
drop table if exists fac;
|
||||||
create table fac (n int unsigned not null primary key, f bigint unsigned);
|
create table fac (n int unsigned not null primary key, f bigint unsigned);
|
||||||
create procedure ifac(n int unsigned)
|
create procedure ifac(n int unsigned)
|
||||||
@ -839,21 +909,22 @@ drop table primes;
|
|||||||
drop procedure opp;
|
drop procedure opp;
|
||||||
drop procedure ip;
|
drop procedure ip;
|
||||||
create procedure bar(x char(16), y int)
|
create procedure bar(x char(16), y int)
|
||||||
comment "111111111111" SECURITY INVOKER
|
comment "111111111111" sql security invoker
|
||||||
insert into test.t1 values (x, y);
|
insert into test.t1 values (x, y);
|
||||||
show procedure status like 'bar';
|
show procedure status like 'bar';
|
||||||
Name Type Creator Modified Created Suid Comment
|
Name Type Creator Modified Created Suid Comment
|
||||||
bar procedure root@localhost 0000-00-00 00:00:00 0000-00-00 00:00:00 N 111111111111
|
bar procedure root@localhost 0000-00-00 00:00:00 0000-00-00 00:00:00 N 111111111111
|
||||||
alter procedure bar name bar2 comment "2222222222" SECURITY DEFINER;
|
alter procedure bar name bar2 comment "2222222222" sql security definer;
|
||||||
alter procedure bar2 name bar comment "3333333333";
|
alter procedure bar2 name bar comment "3333333333";
|
||||||
alter procedure bar;
|
alter procedure bar;
|
||||||
show create procedure bar;
|
show create procedure bar;
|
||||||
Procedure Create Procedure
|
Procedure Create Procedure
|
||||||
bar create procedure bar(x char(16), y int)
|
bar create procedure bar(x char(16), y int)
|
||||||
comment "111111111111" SECURITY INVOKER
|
comment "111111111111" sql security invoker
|
||||||
insert into test.t1 values (x, y)
|
insert into test.t1 values (x, y)
|
||||||
show procedure status like 'bar';
|
show procedure status like 'bar';
|
||||||
Name Type Creator Modified Created Suid Comment
|
Name Type Creator Modified Created Suid Comment
|
||||||
bar procedure root@localhost 0000-00-00 00:00:00 0000-00-00 00:00:00 Y 3333333333
|
bar procedure root@localhost 0000-00-00 00:00:00 0000-00-00 00:00:00 Y 3333333333
|
||||||
|
drop procedure bar;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
drop table t2;
|
drop table t2;
|
||||||
|
@ -257,7 +257,7 @@ call p()|
|
|||||||
drop procedure p|
|
drop procedure p|
|
||||||
|
|
||||||
--error 1282
|
--error 1282
|
||||||
alter procedure bar3 SECURITY INVOKER|
|
alter procedure bar3 sql security invoker|
|
||||||
--error 1059
|
--error 1059
|
||||||
alter procedure bar3 name
|
alter procedure bar3 name
|
||||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA|
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA|
|
||||||
|
@ -109,6 +109,29 @@ delete from t1|
|
|||||||
drop procedure locset|
|
drop procedure locset|
|
||||||
|
|
||||||
|
|
||||||
|
# Set things to null
|
||||||
|
--disable_warnings
|
||||||
|
drop table if exists t3|
|
||||||
|
--enable_warnings
|
||||||
|
create table t3 ( d date, i int, f double, s varchar(32) )|
|
||||||
|
|
||||||
|
create procedure nullset()
|
||||||
|
begin
|
||||||
|
declare ld date;
|
||||||
|
declare li int;
|
||||||
|
declare lf double;
|
||||||
|
declare ls varchar(32);
|
||||||
|
|
||||||
|
set ld = null, li = null, lf = null, ls = null;
|
||||||
|
insert into t3 values (ld, li, lf, ls);
|
||||||
|
end|
|
||||||
|
|
||||||
|
call nullset()|
|
||||||
|
select * from t3|
|
||||||
|
drop table t3|
|
||||||
|
drop procedure nullset|
|
||||||
|
|
||||||
|
|
||||||
# The peculiar (non-standard) mixture of variables types in SET.
|
# The peculiar (non-standard) mixture of variables types in SET.
|
||||||
create procedure mixset(x char(16), y int)
|
create procedure mixset(x char(16), y int)
|
||||||
begin
|
begin
|
||||||
@ -460,6 +483,52 @@ delete from t1|
|
|||||||
drop procedure into_test2|
|
drop procedure into_test2|
|
||||||
|
|
||||||
|
|
||||||
|
# SELECT * INTO ... (bug test)
|
||||||
|
create procedure into_test3()
|
||||||
|
begin
|
||||||
|
declare x char(16);
|
||||||
|
declare y int;
|
||||||
|
|
||||||
|
select * into x,y from test.t1 limit 1;
|
||||||
|
insert into test.t2 values (x, y, 0.0);
|
||||||
|
end|
|
||||||
|
|
||||||
|
insert into t1 values ("into3", 19)|
|
||||||
|
delete from t2|
|
||||||
|
# Two call needed for bug test
|
||||||
|
call into_test3()|
|
||||||
|
call into_test3()|
|
||||||
|
select * from t2|
|
||||||
|
delete from t1|
|
||||||
|
delete from t2|
|
||||||
|
drop procedure into_test3|
|
||||||
|
|
||||||
|
|
||||||
|
# SELECT INTO with no data is a warning ("no data", which we will
|
||||||
|
# not see normally). When not caught, execution proceeds.
|
||||||
|
create procedure into_test4()
|
||||||
|
begin
|
||||||
|
declare x int;
|
||||||
|
|
||||||
|
select data into x from test.t1 limit 1;
|
||||||
|
insert into test.t3 values ("into4", x);
|
||||||
|
end|
|
||||||
|
|
||||||
|
delete from t1|
|
||||||
|
--disable_warnings
|
||||||
|
drop table if exists t3|
|
||||||
|
--enable_warnings
|
||||||
|
create table t3 ( s char(16), d int)|
|
||||||
|
call into_test4()|
|
||||||
|
select * from t3|
|
||||||
|
insert into t1 values ("i4", 77)|
|
||||||
|
call into_test4()|
|
||||||
|
select * from t3|
|
||||||
|
delete from t1|
|
||||||
|
drop table t3|
|
||||||
|
drop procedure into_test4|
|
||||||
|
|
||||||
|
|
||||||
# These two (and the two procedures above) caused an assert() to fail in
|
# These two (and the two procedures above) caused an assert() to fail in
|
||||||
# sql_base.cc:lock_tables() at some point.
|
# sql_base.cc:lock_tables() at some point.
|
||||||
|
|
||||||
@ -658,7 +727,7 @@ create procedure hndlr4()
|
|||||||
begin
|
begin
|
||||||
declare x int default 0;
|
declare x int default 0;
|
||||||
declare val int; # No default
|
declare val int; # No default
|
||||||
declare continue handler for sqlexception set x=1;
|
declare continue handler for 1306 set x=1;
|
||||||
|
|
||||||
select data into val from test.t3 where id='z' limit 1; # No hits
|
select data into val from test.t3 where id='z' limit 1; # No hits
|
||||||
|
|
||||||
@ -823,6 +892,28 @@ drop table t70|
|
|||||||
drop procedure bug1656|
|
drop procedure bug1656|
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# BUG#1862
|
||||||
|
#
|
||||||
|
--disable_warnings
|
||||||
|
drop table if exists t3|
|
||||||
|
--enable_warnings
|
||||||
|
create table t3(a int)|
|
||||||
|
|
||||||
|
create procedure bug1862()
|
||||||
|
begin
|
||||||
|
insert into t3 values(2);
|
||||||
|
flush tables;
|
||||||
|
end|
|
||||||
|
|
||||||
|
call bug1862()|
|
||||||
|
# the second call caused a segmentation
|
||||||
|
call bug1862()|
|
||||||
|
select * from t3|
|
||||||
|
drop table t3|
|
||||||
|
drop procedure bug1862|
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Some "real" examples
|
# Some "real" examples
|
||||||
#
|
#
|
||||||
@ -946,16 +1037,17 @@ drop procedure ip|
|
|||||||
|
|
||||||
# Comment & suid
|
# Comment & suid
|
||||||
create procedure bar(x char(16), y int)
|
create procedure bar(x char(16), y int)
|
||||||
comment "111111111111" SECURITY INVOKER
|
comment "111111111111" sql security invoker
|
||||||
insert into test.t1 values (x, y)|
|
insert into test.t1 values (x, y)|
|
||||||
--replace_column 4 '0000-00-00 00:00:00' 5 '0000-00-00 00:00:00'
|
--replace_column 4 '0000-00-00 00:00:00' 5 '0000-00-00 00:00:00'
|
||||||
show procedure status like 'bar'|
|
show procedure status like 'bar'|
|
||||||
alter procedure bar name bar2 comment "2222222222" SECURITY DEFINER|
|
alter procedure bar name bar2 comment "2222222222" sql security definer|
|
||||||
alter procedure bar2 name bar comment "3333333333"|
|
alter procedure bar2 name bar comment "3333333333"|
|
||||||
alter procedure bar|
|
alter procedure bar|
|
||||||
show create procedure bar|
|
show create procedure bar|
|
||||||
--replace_column 4 '0000-00-00 00:00:00' 5 '0000-00-00 00:00:00'
|
--replace_column 4 '0000-00-00 00:00:00' 5 '0000-00-00 00:00:00'
|
||||||
show procedure status like 'bar'|
|
show procedure status like 'bar'|
|
||||||
|
drop procedure bar|
|
||||||
|
|
||||||
delimiter ;|
|
delimiter ;|
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
@ -130,7 +130,7 @@ static SYMBOL symbols[] = {
|
|||||||
{ "DECLARE", SYM(DECLARE_SYM),0,0},
|
{ "DECLARE", SYM(DECLARE_SYM),0,0},
|
||||||
{ "DES_KEY_FILE", SYM(DES_KEY_FILE),0,0},
|
{ "DES_KEY_FILE", SYM(DES_KEY_FILE),0,0},
|
||||||
{ "DEFAULT", SYM(DEFAULT),0,0},
|
{ "DEFAULT", SYM(DEFAULT),0,0},
|
||||||
{ "DEFINER", SYM(DEFINER),0,0},
|
{ "DEFINER", SYM(DEFINER_SYM),0,0},
|
||||||
{ "DELAYED", SYM(DELAYED_SYM),0,0},
|
{ "DELAYED", SYM(DELAYED_SYM),0,0},
|
||||||
{ "DELAY_KEY_WRITE", SYM(DELAY_KEY_WRITE_SYM),0,0},
|
{ "DELAY_KEY_WRITE", SYM(DELAY_KEY_WRITE_SYM),0,0},
|
||||||
{ "DELETE", SYM(DELETE_SYM),0,0},
|
{ "DELETE", SYM(DELETE_SYM),0,0},
|
||||||
@ -233,7 +233,7 @@ static SYMBOL symbols[] = {
|
|||||||
{ "ISOLATION", SYM(ISOLATION),0,0},
|
{ "ISOLATION", SYM(ISOLATION),0,0},
|
||||||
{ "ISSUER", SYM(ISSUER_SYM),0,0},
|
{ "ISSUER", SYM(ISSUER_SYM),0,0},
|
||||||
{ "ITERATE", SYM(ITERATE_SYM),0,0},
|
{ "ITERATE", SYM(ITERATE_SYM),0,0},
|
||||||
{ "INVOKER", SYM(INVOKER),0,0},
|
{ "INVOKER", SYM(INVOKER_SYM),0,0},
|
||||||
{ "JOIN", SYM(JOIN_SYM),0,0},
|
{ "JOIN", SYM(JOIN_SYM),0,0},
|
||||||
{ "KEY", SYM(KEY_SYM),0,0},
|
{ "KEY", SYM(KEY_SYM),0,0},
|
||||||
{ "KEYS", SYM(KEYS),0,0},
|
{ "KEYS", SYM(KEYS),0,0},
|
||||||
@ -370,7 +370,7 @@ static SYMBOL symbols[] = {
|
|||||||
{ "SAVEPOINT", SYM(SAVEPOINT_SYM),0,0},
|
{ "SAVEPOINT", SYM(SAVEPOINT_SYM),0,0},
|
||||||
{ "SECOND", SYM(SECOND_SYM),0,0},
|
{ "SECOND", SYM(SECOND_SYM),0,0},
|
||||||
{ "SECOND_MICROSECOND", SYM(SECOND_MICROSECOND_SYM),0,0},
|
{ "SECOND_MICROSECOND", SYM(SECOND_MICROSECOND_SYM),0,0},
|
||||||
{ "SECURITY", SYM(SECURITY),0,0},
|
{ "SECURITY", SYM(SECURITY_SYM),0,0},
|
||||||
{ "SEPARATOR", SYM(SEPARATOR_SYM),0,0},
|
{ "SEPARATOR", SYM(SEPARATOR_SYM),0,0},
|
||||||
{ "SELECT", SYM(SELECT_SYM),0,0},
|
{ "SELECT", SYM(SELECT_SYM),0,0},
|
||||||
{ "SENSITIVE", SYM(SENSITIVE_SYM),0,0},
|
{ "SENSITIVE", SYM(SENSITIVE_SYM),0,0},
|
||||||
@ -389,6 +389,7 @@ static SYMBOL symbols[] = {
|
|||||||
{ "SONAME", SYM(UDF_SONAME_SYM),0,0},
|
{ "SONAME", SYM(UDF_SONAME_SYM),0,0},
|
||||||
{ "SPATIAL", SYM(SPATIAL_SYM),0,0},
|
{ "SPATIAL", SYM(SPATIAL_SYM),0,0},
|
||||||
{ "SPECIFIC", SYM(SPECIFIC_SYM),0,0},
|
{ "SPECIFIC", SYM(SPECIFIC_SYM),0,0},
|
||||||
|
{ "SQL", SYM(SQL_SYM),0,0},
|
||||||
{ "SQLEXCEPTION", SYM(SQLEXCEPTION_SYM),0,0},
|
{ "SQLEXCEPTION", SYM(SQLEXCEPTION_SYM),0,0},
|
||||||
{ "SQLSTATE", SYM(SQLSTATE_SYM),0,0},
|
{ "SQLSTATE", SYM(SQLSTATE_SYM),0,0},
|
||||||
{ "SQLWARNING", SYM(SQLWARNING_SYM),0,0},
|
{ "SQLWARNING", SYM(SQLWARNING_SYM),0,0},
|
||||||
|
@ -234,7 +234,9 @@ 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);
|
||||||
// Check if an exception has occurred and a handler has been found
|
// Check if an exception has occurred and a handler has been found
|
||||||
if (ret && !thd->killed && ctx)
|
// 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)
|
||||||
{
|
{
|
||||||
uint hf;
|
uint hf;
|
||||||
|
|
||||||
@ -509,12 +511,20 @@ sp_head::restore_lex(THD *thd)
|
|||||||
// Update some state in the old one first
|
// Update some state in the old one first
|
||||||
oldlex->ptr= sublex->ptr;
|
oldlex->ptr= sublex->ptr;
|
||||||
oldlex->next_state= sublex->next_state;
|
oldlex->next_state= sublex->next_state;
|
||||||
// Save WHERE clause pointers to avoid damaging by optimisation
|
|
||||||
for (SELECT_LEX *sl= sublex->all_selects_list ;
|
for (SELECT_LEX *sl= sublex->all_selects_list ;
|
||||||
sl ;
|
sl ;
|
||||||
sl= sl->next_select_in_list())
|
sl= sl->next_select_in_list())
|
||||||
{
|
{
|
||||||
|
// Save WHERE clause pointers to avoid damaging by optimisation
|
||||||
sl->prep_where= sl->where;
|
sl->prep_where= sl->where;
|
||||||
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Collect some data from the sub statement lex.
|
// Collect some data from the sub statement lex.
|
||||||
@ -687,14 +697,22 @@ sp_instr_stmt::exec_stmt(THD *thd, LEX *lex)
|
|||||||
sl ;
|
sl ;
|
||||||
sl= sl->next_select_in_list())
|
sl= sl->next_select_in_list())
|
||||||
{
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
if (sl->with_wild)
|
if (sl->with_wild)
|
||||||
{
|
{
|
||||||
List_iterator_fast<Item> li(sl->item_list);
|
// 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);
|
||||||
|
|
||||||
// Copy item_list
|
sl->item_list.empty();
|
||||||
sl->item_list_copy.empty();
|
|
||||||
while (Item *it= li++)
|
while (Item *it= li++)
|
||||||
sl->item_list_copy.push_back(it);
|
sl->item_list.push_back(it);
|
||||||
}
|
}
|
||||||
sl->ref_pointer_array= 0;
|
sl->ref_pointer_array= 0;
|
||||||
if (sl->prep_where)
|
if (sl->prep_where)
|
||||||
@ -725,12 +743,19 @@ sp_instr_stmt::exec_stmt(THD *thd, LEX *lex)
|
|||||||
sl ;
|
sl ;
|
||||||
sl= sl->next_select_in_list())
|
sl= sl->next_select_in_list())
|
||||||
{
|
{
|
||||||
if (sl->with_wild)
|
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)
|
||||||
{
|
{
|
||||||
// Restore item_list
|
tabs->table= NULL;
|
||||||
sl->item_list.empty();
|
}
|
||||||
while (Item *it= sl->item_list_copy.pop())
|
if (lex->sql_command == SQLCOM_CREATE_TABLE ||
|
||||||
sl->item_list.push_back(it);
|
lex->sql_command == SQLCOM_INSERT_SELECT)
|
||||||
|
{ // Restore sl->table_list.first
|
||||||
|
sl->table_list.first= sl->table_list_first_copy;
|
||||||
}
|
}
|
||||||
for (ORDER *order= (ORDER *)sl->order_list.first ;
|
for (ORDER *order= (ORDER *)sl->order_list.first ;
|
||||||
order ;
|
order ;
|
||||||
|
@ -1253,14 +1253,8 @@ bool select_dumpvar::send_data(List<Item> &items)
|
|||||||
|
|
||||||
bool select_dumpvar::send_eof()
|
bool select_dumpvar::send_eof()
|
||||||
{
|
{
|
||||||
if (row_count)
|
if (! row_count)
|
||||||
{
|
send_warning(thd, ER_SP_FETCH_NO_DATA);
|
||||||
::send_ok(thd,row_count);
|
::send_ok(thd,row_count);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
my_error(ER_EMPTY_QUERY,MYF(0));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -362,6 +362,7 @@ public:
|
|||||||
SQL_LIST table_list, group_list; /* FROM & GROUP BY clauses */
|
SQL_LIST table_list, group_list; /* FROM & GROUP BY clauses */
|
||||||
List<Item> item_list; /* list of fields & expressions */
|
List<Item> item_list; /* list of fields & expressions */
|
||||||
List<Item> item_list_copy; /* For SPs */
|
List<Item> item_list_copy; /* For SPs */
|
||||||
|
byte *table_list_first_copy; /* For SPs */
|
||||||
List<String> interval_list, use_index, *use_index_ptr,
|
List<String> interval_list, use_index, *use_index_ptr,
|
||||||
ignore_index, *ignore_index_ptr;
|
ignore_index, *ignore_index_ptr;
|
||||||
/*
|
/*
|
||||||
|
@ -137,7 +137,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
|
|||||||
%token CREATE
|
%token CREATE
|
||||||
%token CROSS
|
%token CROSS
|
||||||
%token CUBE_SYM
|
%token CUBE_SYM
|
||||||
%token DEFINER
|
%token DEFINER_SYM
|
||||||
%token DELETE_SYM
|
%token DELETE_SYM
|
||||||
%token DUAL_SYM
|
%token DUAL_SYM
|
||||||
%token DO_SYM
|
%token DO_SYM
|
||||||
@ -167,6 +167,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
|
|||||||
%token SELECT_SYM
|
%token SELECT_SYM
|
||||||
%token SHOW
|
%token SHOW
|
||||||
%token SLAVE
|
%token SLAVE
|
||||||
|
%token SQL_SYM
|
||||||
%token SQL_THREAD
|
%token SQL_THREAD
|
||||||
%token START_SYM
|
%token START_SYM
|
||||||
%token STD_SYM
|
%token STD_SYM
|
||||||
@ -270,7 +271,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
|
|||||||
%token INOUT_SYM
|
%token INOUT_SYM
|
||||||
%token INTO
|
%token INTO
|
||||||
%token IN_SYM
|
%token IN_SYM
|
||||||
%token INVOKER
|
%token INVOKER_SYM
|
||||||
%token ISOLATION
|
%token ISOLATION
|
||||||
%token JOIN_SYM
|
%token JOIN_SYM
|
||||||
%token KEYS
|
%token KEYS
|
||||||
@ -364,7 +365,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
|
|||||||
%token ROW_FORMAT_SYM
|
%token ROW_FORMAT_SYM
|
||||||
%token ROW_SYM
|
%token ROW_SYM
|
||||||
%token RTREE_SYM
|
%token RTREE_SYM
|
||||||
%token SECURITY
|
%token SECURITY_SYM
|
||||||
%token SET
|
%token SET
|
||||||
%token SEPARATOR_SYM
|
%token SEPARATOR_SYM
|
||||||
%token SERIAL_SYM
|
%token SERIAL_SYM
|
||||||
@ -1120,20 +1121,20 @@ create_function_tail:
|
|||||||
;
|
;
|
||||||
|
|
||||||
sp_comment:
|
sp_comment:
|
||||||
/* Empty */ { $$.str=0; }
|
/* Empty */ { $$.str= 0; $$.length= 0; }
|
||||||
| COMMENT_SYM TEXT_STRING_sys { $$= $2; }
|
| COMMENT_SYM TEXT_STRING_sys { $$= $2; }
|
||||||
;
|
;
|
||||||
|
|
||||||
sp_newname:
|
sp_newname:
|
||||||
/* Empty */ { $$.str=0; }
|
/* Empty */ { $$.str= 0; $$.length= 0; }
|
||||||
| NAME_SYM ident { $$= $2; }
|
| NAME_SYM ident { $$= $2; }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
sp_suid:
|
sp_suid:
|
||||||
/* Empty */ { Lex->suid= IS_DEFAULT_SUID; }
|
/* Empty */ { Lex->suid= IS_DEFAULT_SUID; }
|
||||||
| SECURITY DEFINER { Lex->suid= IS_SUID; }
|
| SQL_SYM SECURITY_SYM DEFINER_SYM { Lex->suid= IS_SUID; }
|
||||||
| SECURITY INVOKER { Lex->suid= IS_NOT_SUID; }
|
| SQL_SYM SECURITY_SYM INVOKER_SYM { Lex->suid= IS_NOT_SUID; }
|
||||||
;
|
;
|
||||||
|
|
||||||
call:
|
call:
|
||||||
@ -2603,30 +2604,35 @@ alter:
|
|||||||
lex->name=$3.str;
|
lex->name=$3.str;
|
||||||
}
|
}
|
||||||
| ALTER PROCEDURE ident sp_newname sp_comment sp_suid
|
| ALTER PROCEDURE ident sp_newname sp_comment sp_suid
|
||||||
/* QQ Characteristics missing for now */
|
|
||||||
opt_restrict
|
opt_restrict
|
||||||
{
|
{
|
||||||
|
THD *thd= YYTHD;
|
||||||
LEX *lex=Lex;
|
LEX *lex=Lex;
|
||||||
|
|
||||||
/* This is essensially an no-op right now, since we haven't
|
|
||||||
put the characteristics in yet. */
|
|
||||||
lex->sql_command= SQLCOM_ALTER_PROCEDURE;
|
lex->sql_command= SQLCOM_ALTER_PROCEDURE;
|
||||||
lex->udf.name= $3;
|
lex->udf.name= $3;
|
||||||
lex->name= $4.str;
|
lex->name= $4.str;
|
||||||
lex->comment= &$5;
|
/* $5 is a yacc/bison internal struct, so we can't keep
|
||||||
|
the pointer to it for use outside the parser. */
|
||||||
|
lex->comment= (LEX_STRING *)thd->alloc(sizeof(LEX_STRING));
|
||||||
|
lex->comment->str= $5.str;
|
||||||
|
lex->comment->length= $5.length;
|
||||||
}
|
}
|
||||||
| ALTER FUNCTION_SYM ident sp_newname sp_comment sp_suid
|
| ALTER FUNCTION_SYM ident sp_newname sp_comment sp_suid
|
||||||
/* QQ Characteristics missing for now */
|
|
||||||
opt_restrict
|
opt_restrict
|
||||||
{
|
{
|
||||||
|
THD *thd= YYTHD;
|
||||||
LEX *lex=Lex;
|
LEX *lex=Lex;
|
||||||
|
|
||||||
/* This is essensially an no-op right now, since we haven't
|
|
||||||
put the characteristics in yet. */
|
|
||||||
lex->sql_command= SQLCOM_ALTER_FUNCTION;
|
lex->sql_command= SQLCOM_ALTER_FUNCTION;
|
||||||
lex->udf.name= $3;
|
lex->udf.name= $3;
|
||||||
lex->name= $4.str;
|
lex->name= $4.str;
|
||||||
lex->comment= &$5;
|
/* $5 is a yacc/bison internal struct, so we can't keep
|
||||||
|
the pointer to it for use outside the parser. */
|
||||||
|
lex->comment= (LEX_STRING *)thd->alloc(sizeof(LEX_STRING));
|
||||||
|
lex->comment= (LEX_STRING *)thd->alloc(sizeof(LEX_STRING));
|
||||||
|
lex->comment->str= $5.str;
|
||||||
|
lex->comment->length= $5.length;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -5612,7 +5618,7 @@ keyword:
|
|||||||
| DATETIME {}
|
| DATETIME {}
|
||||||
| DATE_SYM {}
|
| DATE_SYM {}
|
||||||
| DAY_SYM {}
|
| DAY_SYM {}
|
||||||
| DEFINER {}
|
| DEFINER_SYM {}
|
||||||
| DELAY_KEY_WRITE_SYM {}
|
| DELAY_KEY_WRITE_SYM {}
|
||||||
| DES_KEY_FILE {}
|
| DES_KEY_FILE {}
|
||||||
| DIRECTORY_SYM {}
|
| DIRECTORY_SYM {}
|
||||||
@ -5648,7 +5654,7 @@ keyword:
|
|||||||
| HOSTS_SYM {}
|
| HOSTS_SYM {}
|
||||||
| HOUR_SYM {}
|
| HOUR_SYM {}
|
||||||
| IDENTIFIED_SYM {}
|
| IDENTIFIED_SYM {}
|
||||||
| INVOKER {}
|
| INVOKER_SYM {}
|
||||||
| IMPORT {}
|
| IMPORT {}
|
||||||
| INDEXES {}
|
| INDEXES {}
|
||||||
| ISOLATION {}
|
| ISOLATION {}
|
||||||
@ -5735,7 +5741,7 @@ keyword:
|
|||||||
| RTREE_SYM {}
|
| RTREE_SYM {}
|
||||||
| SAVEPOINT_SYM {}
|
| SAVEPOINT_SYM {}
|
||||||
| SECOND_SYM {}
|
| SECOND_SYM {}
|
||||||
| SECURITY {}
|
| SECURITY_SYM {}
|
||||||
| SERIAL_SYM {}
|
| SERIAL_SYM {}
|
||||||
| SERIALIZABLE_SYM {}
|
| SERIALIZABLE_SYM {}
|
||||||
| SESSION_SYM {}
|
| SESSION_SYM {}
|
||||||
|
Reference in New Issue
Block a user