Commit f2d4d4cf authored by tomas@poseidon.ndb.mysql.com's avatar tomas@poseidon.ndb.mysql.com

Merge tulin@bk-internal.mysql.com:/home/bk/mysql-5.1-new

into  poseidon.ndb.mysql.com:/home/tomas/mysql-5.1-new
parents 49d0bd9b f1374951
...@@ -86,3 +86,73 @@ INSERT INTO t1 VALUES (1),(1); ...@@ -86,3 +86,73 @@ INSERT INTO t1 VALUES (1),(1);
sync_slave_with_master; sync_slave_with_master;
# End of 4.1 tests # End of 4.1 tests
#
# BUG#15728: LAST_INSERT_ID function inside a stored function returns 0
#
# The solution is not to reset last_insert_id on enter to sub-statement.
#
connection master;
--disable_warnings
drop function if exists bug15728;
drop function if exists bug15728_insert;
drop table if exists t1, t2;
--enable_warnings
create table t1 (
id int not null auto_increment,
last_id int,
primary key (id)
);
create function bug15728() returns int(11)
return last_insert_id();
insert into t1 (last_id) values (0);
insert into t1 (last_id) values (last_insert_id());
insert into t1 (last_id) values (bug15728());
# Check that nested call replicates too.
create table t2 (
id int not null auto_increment,
last_id int,
primary key (id)
);
delimiter |;
create function bug15728_insert() returns int(11) modifies sql data
begin
insert into t2 (last_id) values (bug15728());
return bug15728();
end|
create trigger t1_bi before insert on t1 for each row
begin
declare res int;
select bug15728_insert() into res;
set NEW.last_id = res;
end|
delimiter ;|
insert into t1 (last_id) values (0);
drop trigger t1_bi;
# Check that nested call doesn't affect outer context.
select last_insert_id();
select bug15728_insert();
select last_insert_id();
insert into t1 (last_id) values (bug15728());
# This should be exactly one greater than in the previous call.
select last_insert_id();
save_master_pos;
connection slave;
sync_with_master;
select * from t1;
select * from t2;
connection master;
drop function bug15728;
drop function bug15728_insert;
drop table t1, t2;
# End of 5.0 tests
...@@ -73,3 +73,61 @@ CREATE TABLE t1 ( a INT UNIQUE ); ...@@ -73,3 +73,61 @@ CREATE TABLE t1 ( a INT UNIQUE );
SET FOREIGN_KEY_CHECKS=0; SET FOREIGN_KEY_CHECKS=0;
INSERT INTO t1 VALUES (1),(1); INSERT INTO t1 VALUES (1),(1);
Got one of the listed errors Got one of the listed errors
drop function if exists bug15728;
drop function if exists bug15728_insert;
drop table if exists t1, t2;
create table t1 (
id int not null auto_increment,
last_id int,
primary key (id)
);
create function bug15728() returns int(11)
return last_insert_id();
insert into t1 (last_id) values (0);
insert into t1 (last_id) values (last_insert_id());
insert into t1 (last_id) values (bug15728());
create table t2 (
id int not null auto_increment,
last_id int,
primary key (id)
);
create function bug15728_insert() returns int(11) modifies sql data
begin
insert into t2 (last_id) values (bug15728());
return bug15728();
end|
create trigger t1_bi before insert on t1 for each row
begin
declare res int;
select bug15728_insert() into res;
set NEW.last_id = res;
end|
insert into t1 (last_id) values (0);
drop trigger t1_bi;
select last_insert_id();
last_insert_id()
4
select bug15728_insert();
bug15728_insert()
2
select last_insert_id();
last_insert_id()
4
insert into t1 (last_id) values (bug15728());
select last_insert_id();
last_insert_id()
5
select * from t1;
id last_id
1 0
2 1
3 2
4 1
5 4
select * from t2;
id last_id
1 3
2 4
drop function bug15728;
drop function bug15728_insert;
drop table t1, t2;
drop table if exists t1;
create table t1 (
id char(16) not null default '',
data int not null
);
drop procedure if exists goto1//
create procedure goto1()
begin
declare y int;
label a;
select * from t1;
select count(*) into y from t1;
if y > 2 then
goto b;
end if;
insert into t1 values ("j", y);
goto a;
label b;
end//
call goto1()//
id data
id data
j 0
id data
j 0
j 1
id data
j 0
j 1
j 2
drop procedure goto1//
drop procedure if exists goto2//
create procedure goto2(a int)
begin
declare x int default 0;
declare continue handler for sqlstate '42S98' set x = 1;
label a;
select * from t1;
b:
while x < 2 do
begin
declare continue handler for sqlstate '42S99' set x = 2;
if a = 0 then
set x = x + 1;
iterate b;
elseif a = 1 then
leave b;
elseif a = 2 then
set a = 1;
goto a;
end if;
end;
end while b;
select * from t1;
end//
call goto2(0)//
id data
j 0
j 1
j 2
id data
j 0
j 1
j 2
call goto2(1)//
id data
j 0
j 1
j 2
id data
j 0
j 1
j 2
call goto2(2)//
id data
j 0
j 1
j 2
id data
j 0
j 1
j 2
id data
j 0
j 1
j 2
drop procedure goto2//
delete from t1//
drop procedure if exists goto3//
create procedure goto3()
begin
label L1;
begin
end;
goto L1;
end//
drop procedure goto3//
drop procedure if exists goto4//
create procedure goto4()
begin
begin
label lab1;
begin
goto lab1;
end;
end;
end//
drop procedure goto4//
drop procedure if exists goto5//
create procedure goto5()
begin
begin
begin
goto lab1;
end;
label lab1;
end;
end//
drop procedure goto5//
drop procedure if exists goto6//
create procedure goto6()
begin
label L1;
goto L5;
begin
label L2;
goto L1;
goto L5;
begin
label L3;
goto L1;
goto L2;
goto L3;
goto L4;
goto L5;
end;
goto L2;
goto L4;
label L4;
end;
label L5;
goto L1;
end//
drop procedure goto6//
create procedure foo()
begin
goto foo;
end//
ERROR 42000: GOTO with no matching label: foo
create procedure foo()
begin
begin
label foo;
end;
goto foo;
end//
ERROR 42000: GOTO with no matching label: foo
create procedure foo()
begin
goto foo;
begin
label foo;
end;
end//
ERROR 42000: GOTO with no matching label: foo
create procedure foo()
begin
begin
goto foo;
end;
begin
label foo;
end;
end//
ERROR 42000: GOTO with no matching label: foo
create procedure foo()
begin
begin
label foo;
end;
begin
goto foo;
end;
end//
ERROR 42000: GOTO with no matching label: foo
create procedure p()
begin
declare continue handler for sqlexception
begin
goto L1;
end;
select field from t1;
label L1;
end//
ERROR HY000: GOTO is not allowed in a stored procedure handler
drop procedure if exists bug6898//
create procedure bug6898()
begin
goto label1;
label label1;
begin end;
goto label1;
end//
drop procedure bug6898//
drop table t1;
...@@ -4858,4 +4858,60 @@ c 2 ...@@ -4858,4 +4858,60 @@ c 2
b 3 b 3
a 1 a 1
delete from t1| delete from t1|
drop function if exists bug15728|
drop table if exists t3|
create table t3 (
id int not null auto_increment,
primary key (id)
)|
create function bug15728() returns int(11)
return last_insert_id()|
insert into t3 values (0)|
select last_insert_id()|
last_insert_id()
1
select bug15728()|
bug15728()
1
drop function bug15728|
drop table t3|
drop procedure if exists bug18787|
create procedure bug18787()
begin
declare continue handler for sqlexception begin end;
select no_such_function();
end|
call bug18787()|
no_such_function()
NULL
drop procedure bug18787|
create database bug18344_012345678901|
use bug18344_012345678901|
create procedure bug18344() begin end|
create procedure bug18344_2() begin end|
create database bug18344_0123456789012|
use bug18344_0123456789012|
create procedure bug18344() begin end|
create procedure bug18344_2() begin end|
use test|
select schema_name from information_schema.schemata where
schema_name like 'bug18344%'|
schema_name
bug18344_012345678901
bug18344_0123456789012
select routine_name,routine_schema from information_schema.routines where
routine_schema like 'bug18344%'|
routine_name routine_schema
bug18344 bug18344_012345678901
bug18344_2 bug18344_012345678901
bug18344 bug18344_0123456789012
bug18344_2 bug18344_0123456789012
drop database bug18344_012345678901|
drop database bug18344_0123456789012|
select schema_name from information_schema.schemata where
schema_name like 'bug18344%'|
schema_name
select routine_name,routine_schema from information_schema.routines where
routine_schema like 'bug18344%'|
routine_name routine_schema
drop table t1,t2; drop table t1,t2;
drop tables if exists t1, t2;
drop view if exists v1;
delete from mysql.user where user like 'mysqltest\_%'; delete from mysql.user where user like 'mysqltest\_%';
delete from mysql.db where user like 'mysqltest\_%'; delete from mysql.db where user like 'mysqltest\_%';
delete from mysql.tables_priv where user like 'mysqltest\_%'; delete from mysql.tables_priv where user like 'mysqltest\_%';
...@@ -59,3 +61,18 @@ delete from mysql.db where user like 'mysqltest\_%'; ...@@ -59,3 +61,18 @@ delete from mysql.db where user like 'mysqltest\_%';
delete from mysql.tables_priv where user like 'mysqltest\_%'; delete from mysql.tables_priv where user like 'mysqltest\_%';
flush privileges; flush privileges;
drop table t1, t2; drop table t1, t2;
create table t1 (a int, b datetime);
insert into t1 values (1, 20010101000000), (2, 20020101000000);
grant all privileges on test.* to mysqltest_1@localhost;
create view v1 as select a, convert_tz(b, 'UTC', 'Europe/Moscow') as lb from t1;
select * from v1;
a lb
1 2001-01-01 03:00:00
2 2002-01-01 03:00:00
select * from v1, mysql.time_zone;
ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for table 'time_zone'
drop view v1;
create view v1 as select a, convert_tz(b, 'UTC', 'Europe/Moscow') as lb from t1, mysql.time_zone;
ERROR 42000: ANY command denied to user 'mysqltest_1'@'localhost' for table 'time_zone'
drop table t1;
drop user mysqltest_1@localhost;
...@@ -949,9 +949,42 @@ insert into t1 values ...@@ -949,9 +949,42 @@ insert into t1 values
create function f2() returns int return (select max(b) from t2); create function f2() returns int return (select max(b) from t2);
insert into t2 select a, f2() from t1; insert into t2 select a, f2() from t1;
load data infile '../std_data_ln/words.dat' into table t1 (a) set b:= f1(); load data infile '../std_data_ln/words.dat' into table t1 (a) set b:= f1();
drop table t1; drop tables t1, t2;
drop function f1; drop function f1;
drop function f2; drop function f2;
create table t1(i int not null, j int not null, n numeric(15,2), primary key(i,j));
create table t2(i int not null, n numeric(15,2), primary key(i));
create trigger t1_ai after insert on t1 for each row
begin
declare sn numeric(15,2);
select sum(n) into sn from t1 where i=new.i;
replace into t2 values(new.i, sn);
end|
insert into t1 values
(1,1,10.00),(1,2,10.00),(1,3,10.00),(1,4,10.00),(1,5,10.00),
(1,6,10.00),(1,7,10.00),(1,8,10.00),(1,9,10.00),(1,10,10.00),
(1,11,10.00),(1,12,10.00),(1,13,10.00),(1,14,10.00),(1,15,10.00);
select * from t1;
i j n
1 1 10.00
1 2 10.00
1 3 10.00
1 4 10.00
1 5 10.00
1 6 10.00
1 7 10.00
1 8 10.00
1 9 10.00
1 10 10.00
1 11 10.00
1 12 10.00
1 13 10.00
1 14 10.00
1 15 10.00
select * from t2;
i n
1 150.00
drop tables t1, t2;
DROP TABLE IF EXISTS t1; DROP TABLE IF EXISTS t1;
CREATE TABLE t1 ( CREATE TABLE t1 (
conn_id INT, conn_id INT,
......
...@@ -2623,3 +2623,29 @@ select * from v1; ...@@ -2623,3 +2623,29 @@ select * from v1;
ERROR HY000: Recursive stored functions and triggers are not allowed. ERROR HY000: Recursive stored functions and triggers are not allowed.
drop function f1; drop function f1;
drop view t1, v1; drop view t1, v1;
create table t1 (dt datetime);
insert into t1 values (20040101000000), (20050101000000), (20060101000000);
create view v1 as select convert_tz(dt, 'UTC', 'Europe/Moscow') as ldt from t1;
select * from v1;
ldt
2004-01-01 03:00:00
2005-01-01 03:00:00
2006-01-01 03:00:00
drop view v1;
create view v1 as select * from t1 where convert_tz(dt, 'UTC', 'Europe/Moscow') >= 20050101000000;
select * from v1;
dt
2005-01-01 00:00:00
2006-01-01 00:00:00
create view v2 as select * from v1 where dt < 20060101000000;
select * from v2;
dt
2005-01-01 00:00:00
drop view v2;
create view v2 as select convert_tz(dt, 'UTC', 'Europe/Moscow') as ldt from v1;
select * from v2;
ldt
2005-01-01 03:00:00
2006-01-01 03:00:00
drop view v1, v2;
drop table t1;
...@@ -35,7 +35,6 @@ rpl_row_func003 : BUG#19074 2006-13-04 andrei test failed ...@@ -35,7 +35,6 @@ rpl_row_func003 : BUG#19074 2006-13-04 andrei test failed
rpl_row_inexist_tbl : BUG#18948 2006-03-09 mats Disabled since patch makes this test wait forever rpl_row_inexist_tbl : BUG#18948 2006-03-09 mats Disabled since patch makes this test wait forever
rpl_sp : BUG#16456 2006-02-16 jmiller rpl_sp : BUG#16456 2006-02-16 jmiller
rpl_until : BUG#15886 2006-02-16 jmiller Unstable test case rpl_until : BUG#15886 2006-02-16 jmiller Unstable test case
sp-goto : BUG#18949 2006-02-16 jmiller GOTO is currently is disabled - will be fixed in the future
mysqldump : BUG#18078 2006-03-10 lars mysqldump : BUG#18078 2006-03-10 lars
udf : BUG#18564 2006-03-27 ian (Permission by Brian) udf : BUG#18564 2006-03-27 ian (Permission by Brian)
......
#
# The non-standard GOTO, for compatibility
#
# QQQ The "label" syntax is temporary, it will (hopefully)
# change to the more common "L:" syntax soon.
# For the time being, this feature is disabled, until
# the syntax (and some other known bugs) can be fixed.
#
# Test cases for bugs are added at the end. See template there.
#
--disable_warnings
drop table if exists t1;
--enable_warnings
create table t1 (
id char(16) not null default '',
data int not null
);
delimiter //;
--disable_warnings
drop procedure if exists goto1//
--enable_warnings
create procedure goto1()
begin
declare y int;
label a;
select * from t1;
select count(*) into y from t1;
if y > 2 then
goto b;
end if;
insert into t1 values ("j", y);
goto a;
label b;
end//
call goto1()//
drop procedure goto1//
# With dummy handlers, just to test restore of contexts with jumps
--disable_warnings
drop procedure if exists goto2//
--enable_warnings
create procedure goto2(a int)
begin
declare x int default 0;
declare continue handler for sqlstate '42S98' set x = 1;
label a;
select * from t1;
b:
while x < 2 do
begin
declare continue handler for sqlstate '42S99' set x = 2;
if a = 0 then
set x = x + 1;
iterate b;
elseif a = 1 then
leave b;
elseif a = 2 then
set a = 1;
goto a;
end if;
end;
end while b;
select * from t1;
end//
call goto2(0)//
call goto2(1)//
call goto2(2)//
drop procedure goto2//
delete from t1//
# Check label visibility for some more cases. We don't call these.
--disable_warnings
drop procedure if exists goto3//
--enable_warnings
create procedure goto3()
begin
label L1;
begin
end;
goto L1;
end//
drop procedure goto3//
--disable_warnings
drop procedure if exists goto4//
--enable_warnings
create procedure goto4()
begin
begin
label lab1;
begin
goto lab1;
end;
end;
end//
drop procedure goto4//
--disable_warnings
drop procedure if exists goto5//
--enable_warnings
create procedure goto5()
begin
begin
begin
goto lab1;
end;
label lab1;
end;
end//
drop procedure goto5//
--disable_warnings
drop procedure if exists goto6//
--enable_warnings
create procedure goto6()
begin
label L1;
goto L5;
begin
label L2;
goto L1;
goto L5;
begin
label L3;
goto L1;
goto L2;
goto L3;
goto L4;
goto L5;
end;
goto L2;
goto L4;
label L4;
end;
label L5;
goto L1;
end//
drop procedure goto6//
# Mismatching labels
--error 1308
create procedure foo()
begin
goto foo;
end//
--error 1308
create procedure foo()
begin
begin
label foo;
end;
goto foo;
end//
--error 1308
create procedure foo()
begin
goto foo;
begin
label foo;
end;
end//
--error 1308
create procedure foo()
begin
begin
goto foo;
end;
begin
label foo;
end;
end//
--error 1308
create procedure foo()
begin
begin
label foo;
end;
begin
goto foo;
end;
end//
# No goto in a handler
--error 1358
create procedure p()
begin
declare continue handler for sqlexception
begin
goto L1;
end;
select field from t1;
label L1;
end//
#
# Test cases for old bugs
#
#
# BUG#6898: Stored procedure crash if GOTO statements exist
#
--disable_warnings
drop procedure if exists bug6898//
--enable_warnings
create procedure bug6898()
begin
goto label1;
label label1;
begin end;
goto label1;
end//
drop procedure bug6898//
#
# BUG#NNNN: New bug synopsis
#
#--disable_warnings
#drop procedure if exists bugNNNN//
#--enable_warnings
#create procedure bugNNNN...
# Add bugs above this line. Use existing tables t1 and t2 when
# practical, or create table t3, t4 etc temporarily (and drop them).
delimiter ;//
drop table t1;
...@@ -5704,6 +5704,81 @@ select * from t1 order by @x| ...@@ -5704,6 +5704,81 @@ select * from t1 order by @x|
delete from t1| delete from t1|
#
# BUG#15728: LAST_INSERT_ID function inside a stored function returns 0
#
# The solution is not to reset last_insert_id on enter to sub-statement.
#
--disable_warnings
drop function if exists bug15728|
drop table if exists t3|
--enable_warnings
create table t3 (
id int not null auto_increment,
primary key (id)
)|
create function bug15728() returns int(11)
return last_insert_id()|
insert into t3 values (0)|
select last_insert_id()|
select bug15728()|
drop function bug15728|
drop table t3|
#
# BUG#18787: Server crashed when calling a stored procedure containing
# a misnamed function
#
--disable_warnings
drop procedure if exists bug18787|
--enable_warnings
create procedure bug18787()
begin
declare continue handler for sqlexception begin end;
select no_such_function();
end|
call bug18787()|
drop procedure bug18787|
#
# BUG#18344: DROP DATABASE does not drop associated routines
# (... if the database name is longer than 21 characters)
#
# 1234567890123456789012
create database bug18344_012345678901|
use bug18344_012345678901|
create procedure bug18344() begin end|
create procedure bug18344_2() begin end|
create database bug18344_0123456789012|
use bug18344_0123456789012|
create procedure bug18344() begin end|
create procedure bug18344_2() begin end|
use test|
select schema_name from information_schema.schemata where
schema_name like 'bug18344%'|
select routine_name,routine_schema from information_schema.routines where
routine_schema like 'bug18344%'|
drop database bug18344_012345678901|
drop database bug18344_0123456789012|
# Should be nothing left.
select schema_name from information_schema.schemata where
schema_name like 'bug18344%'|
select routine_name,routine_schema from information_schema.routines where
routine_schema like 'bug18344%'|
# #
# BUG#NNNN: New bug synopsis # BUG#NNNN: New bug synopsis
# #
......
# Embedded server testing does not support grants # Embedded server testing does not support grants
-- source include/not_embedded.inc -- source include/not_embedded.inc
--disable_warnings
drop tables if exists t1, t2;
drop view if exists v1;
--enable_warnings
# #
# Test for bug #6116 "SET time_zone := ... requires access to mysql.time_zone # Test for bug #6116 "SET time_zone := ... requires access to mysql.time_zone
# tables". We should allow implicit access to time zone description tables # tables". We should allow implicit access to time zone description tables
...@@ -82,3 +87,29 @@ flush privileges; ...@@ -82,3 +87,29 @@ flush privileges;
drop table t1, t2; drop table t1, t2;
# End of 4.1 tests # End of 4.1 tests
#
# Additional test for bug #15153: CONVERT_TZ() is not allowed in all
# places in views.
#
# Let us check that usage of CONVERT_TZ() function in view does not
# require additional privileges.
# Let us rely on that previous tests done proper cleanups
create table t1 (a int, b datetime);
insert into t1 values (1, 20010101000000), (2, 20020101000000);
grant all privileges on test.* to mysqltest_1@localhost;
connect (tzuser3, localhost, mysqltest_1,,);
create view v1 as select a, convert_tz(b, 'UTC', 'Europe/Moscow') as lb from t1;
select * from v1;
# Of course we should not be able select from mysql.time_zone tables
--error ER_TABLEACCESS_DENIED_ERROR
select * from v1, mysql.time_zone;
drop view v1;
--error ER_TABLEACCESS_DENIED_ERROR
create view v1 as select a, convert_tz(b, 'UTC', 'Europe/Moscow') as lb from t1, mysql.time_zone;
connection default;
drop table t1;
drop user mysqltest_1@localhost;
# End of 5.0 tests
...@@ -1111,10 +1111,34 @@ insert into t1 values ...@@ -1111,10 +1111,34 @@ insert into t1 values
create function f2() returns int return (select max(b) from t2); create function f2() returns int return (select max(b) from t2);
insert into t2 select a, f2() from t1; insert into t2 select a, f2() from t1;
load data infile '../std_data_ln/words.dat' into table t1 (a) set b:= f1(); load data infile '../std_data_ln/words.dat' into table t1 (a) set b:= f1();
drop table t1; drop tables t1, t2;
drop function f1; drop function f1;
drop function f2; drop function f2;
#
# Test for bug #16021 "Wrong index given to function in trigger" which
# was caused by the same bulk insert optimization as bug #17764 but had
# slightly different symptoms (instead of reporting table as crashed
# storage engine reported error number 124)
#
create table t1(i int not null, j int not null, n numeric(15,2), primary key(i,j));
create table t2(i int not null, n numeric(15,2), primary key(i));
delimiter |;
create trigger t1_ai after insert on t1 for each row
begin
declare sn numeric(15,2);
select sum(n) into sn from t1 where i=new.i;
replace into t2 values(new.i, sn);
end|
delimiter ;|
insert into t1 values
(1,1,10.00),(1,2,10.00),(1,3,10.00),(1,4,10.00),(1,5,10.00),
(1,6,10.00),(1,7,10.00),(1,8,10.00),(1,9,10.00),(1,10,10.00),
(1,11,10.00),(1,12,10.00),(1,13,10.00),(1,14,10.00),(1,15,10.00);
select * from t1;
select * from t2;
drop tables t1, t2;
# #
# Test for Bug #16461 connection_id() does not work properly inside trigger # Test for Bug #16461 connection_id() does not work properly inside trigger
# #
......
...@@ -2490,3 +2490,30 @@ rename table v2 to t1; ...@@ -2490,3 +2490,30 @@ rename table v2 to t1;
select * from v1; select * from v1;
drop function f1; drop function f1;
drop view t1, v1; drop view t1, v1;
#
# Bug #15153: CONVERT_TZ() is not allowed in all places in VIEWs
#
# Error was reported when one tried to use CONVERT_TZ() function
# select list of view which was processed using MERGE algorithm.
# (Also see additional test in timezone_grant.test)
create table t1 (dt datetime);
insert into t1 values (20040101000000), (20050101000000), (20060101000000);
# Let us test that convert_tz() can be used in view's select list
create view v1 as select convert_tz(dt, 'UTC', 'Europe/Moscow') as ldt from t1;
select * from v1;
drop view v1;
# And in its where part
create view v1 as select * from t1 where convert_tz(dt, 'UTC', 'Europe/Moscow') >= 20050101000000;
select * from v1;
# Other interesting case - a view which uses convert_tz() function
# through other view.
create view v2 as select * from v1 where dt < 20060101000000;
select * from v2;
drop view v2;
# And even more interesting case when view uses convert_tz() both
# directly and indirectly
create view v2 as select convert_tz(dt, 'UTC', 'Europe/Moscow') as ldt from v1;
select * from v2;
drop view v1, v2;
drop table t1;
...@@ -4747,7 +4747,9 @@ Item_func_sp::sp_result_field(void) const ...@@ -4747,7 +4747,9 @@ Item_func_sp::sp_result_field(void) const
dummy_table->s->table_name.str= empty_name; dummy_table->s->table_name.str= empty_name;
dummy_table->s->db.str= empty_name; dummy_table->s->db.str= empty_name;
} }
field= m_sp->create_result_field(max_length, name, dummy_table); if (!(field= m_sp->create_result_field(max_length, name, dummy_table)))
my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
DBUG_RETURN(field); DBUG_RETURN(field);
} }
...@@ -4773,8 +4775,14 @@ Item_func_sp::execute(Field **flp) ...@@ -4773,8 +4775,14 @@ Item_func_sp::execute(Field **flp)
if (!(f= *flp)) if (!(f= *flp))
{ {
*flp= f= sp_result_field(); if (!(*flp= f= sp_result_field()))
f->move_field((f->pack_length() > sizeof(result_buf)) ? {
/* Error set by sp_result_field() */
null_value= 1;
return TRUE;
}
f->move_field((f->pack_length() > sizeof(result_buf)) ?
sql_alloc(f->pack_length()) : result_buf); sql_alloc(f->pack_length()) : result_buf);
f->null_ptr= (uchar *)&null_value; f->null_ptr= (uchar *)&null_value;
f->null_bit= 1; f->null_bit= 1;
...@@ -4926,16 +4934,19 @@ longlong Item_func_found_rows::val_int() ...@@ -4926,16 +4934,19 @@ longlong Item_func_found_rows::val_int()
Field * Field *
Item_func_sp::tmp_table_field(TABLE *t_arg) Item_func_sp::tmp_table_field(TABLE *t_arg)
{ {
Field *res= 0; Field *field= 0;
DBUG_ENTER("Item_func_sp::tmp_table_field"); DBUG_ENTER("Item_func_sp::tmp_table_field");
if (m_sp) if (m_sp)
res= m_sp->create_result_field(max_length, (const char*) name, t_arg); field= m_sp->create_result_field(max_length, (const char*) name, t_arg);
if (!res) if (!field)
res= Item_func::tmp_table_field(t_arg); field= Item_func::tmp_table_field(t_arg);
DBUG_RETURN(res); if (!field)
my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
DBUG_RETURN(field);
} }
......
...@@ -227,9 +227,6 @@ static SYMBOL symbols[] = { ...@@ -227,9 +227,6 @@ static SYMBOL symbols[] = {
{ "GEOMETRYCOLLECTION",SYM(GEOMETRYCOLLECTION)}, { "GEOMETRYCOLLECTION",SYM(GEOMETRYCOLLECTION)},
{ "GET_FORMAT", SYM(GET_FORMAT)}, { "GET_FORMAT", SYM(GET_FORMAT)},
{ "GLOBAL", SYM(GLOBAL_SYM)}, { "GLOBAL", SYM(GLOBAL_SYM)},
#ifdef SP_GOTO
{ "GOTO", SYM(GOTO_SYM)},
#endif
{ "GRANT", SYM(GRANT)}, { "GRANT", SYM(GRANT)},
{ "GRANTS", SYM(GRANTS)}, { "GRANTS", SYM(GRANTS)},
{ "GROUP", SYM(GROUP)}, { "GROUP", SYM(GROUP)},
...@@ -279,10 +276,6 @@ static SYMBOL symbols[] = { ...@@ -279,10 +276,6 @@ static SYMBOL symbols[] = {
{ "KEY", SYM(KEY_SYM)}, { "KEY", SYM(KEY_SYM)},
{ "KEYS", SYM(KEYS)}, { "KEYS", SYM(KEYS)},
{ "KILL", SYM(KILL_SYM)}, { "KILL", SYM(KILL_SYM)},
#ifdef SP_GOTO
/* QQ This will go away when the GOTO label syntax is fixed */
{ "LABEL", SYM(LABEL_SYM)},
#endif
{ "LANGUAGE", SYM(LANGUAGE_SYM)}, { "LANGUAGE", SYM(LANGUAGE_SYM)},
{ "LAST", SYM(LAST_SYM)}, { "LAST", SYM(LAST_SYM)},
{ "LEADING", SYM(LEADING)}, { "LEADING", SYM(LEADING)},
......
...@@ -885,28 +885,23 @@ int ...@@ -885,28 +885,23 @@ int
sp_drop_db_routines(THD *thd, char *db) sp_drop_db_routines(THD *thd, char *db)
{ {
TABLE *table; TABLE *table;
byte key[64]; // db
uint keylen;
int ret; int ret;
uint key_len;
DBUG_ENTER("sp_drop_db_routines"); DBUG_ENTER("sp_drop_db_routines");
DBUG_PRINT("enter", ("db: %s", db)); DBUG_PRINT("enter", ("db: %s", db));
// Put the key used to read the row together
keylen= strlen(db);
if (keylen > 64)
keylen= 64;
memcpy(key, db, keylen);
memset(key+keylen, (int)' ', 64-keylen); // Pad with space
keylen= sizeof(key);
ret= SP_OPEN_TABLE_FAILED; ret= SP_OPEN_TABLE_FAILED;
if (!(table= open_proc_table_for_update(thd))) if (!(table= open_proc_table_for_update(thd)))
goto err; goto err;
table->field[MYSQL_PROC_FIELD_DB]->store(db, strlen(db), system_charset_info);
key_len= table->key_info->key_part[0].store_length;
ret= SP_OK; ret= SP_OK;
table->file->ha_index_init(0, 1); table->file->ha_index_init(0, 1);
if (! table->file->index_read(table->record[0], if (! table->file->index_read(table->record[0],
key, keylen, HA_READ_KEY_EXACT)) (byte *)table->field[MYSQL_PROC_FIELD_DB]->ptr,
key_len, HA_READ_KEY_EXACT))
{ {
int nxtres; int nxtres;
bool deleted= FALSE; bool deleted= FALSE;
...@@ -922,7 +917,8 @@ sp_drop_db_routines(THD *thd, char *db) ...@@ -922,7 +917,8 @@ sp_drop_db_routines(THD *thd, char *db)
break; break;
} }
} while (! (nxtres= table->file->index_next_same(table->record[0], } while (! (nxtres= table->file->index_next_same(table->record[0],
key, keylen))); (byte *)table->field[MYSQL_PROC_FIELD_DB]->ptr,
key_len)));
if (nxtres != HA_ERR_END_OF_FILE) if (nxtres != HA_ERR_END_OF_FILE)
ret= SP_KEY_NOT_FOUND; ret= SP_KEY_NOT_FOUND;
if (deleted) if (deleted)
......
...@@ -1709,44 +1709,11 @@ sp_head::backpatch(sp_label_t *lab) ...@@ -1709,44 +1709,11 @@ sp_head::backpatch(sp_label_t *lab)
while ((bp= li++)) while ((bp= li++))
{ {
if (bp->lab == lab || if (bp->lab == lab)
(bp->lab->type == SP_LAB_REF && bp->instr->backpatch(dest, lab->ctx);
my_strcasecmp(system_charset_info, bp->lab->name, lab->name) == 0))
{
if (bp->lab->type != SP_LAB_REF)
bp->instr->backpatch(dest, lab->ctx);
else
{
sp_label_t *dstlab= bp->lab->ctx->find_label(lab->name);
if (dstlab)
{
bp->lab= lab;
bp->instr->backpatch(dest, dstlab->ctx);
}
}
}
}
}
int
sp_head::check_backpatch(THD *thd)
{
bp_t *bp;
List_iterator_fast<bp_t> li(m_backpatch);
while ((bp= li++))
{
if (bp->lab->type == SP_LAB_REF)
{
my_error(ER_SP_LILABEL_MISMATCH, MYF(0), "GOTO", bp->lab->name);
return -1;
}
} }
return 0;
} }
/* /*
Prepare an instance of create_field for field creation (fill all necessary Prepare an instance of create_field for field creation (fill all necessary
attributes). attributes).
......
...@@ -264,13 +264,6 @@ class sp_head :private Query_arena ...@@ -264,13 +264,6 @@ class sp_head :private Query_arena
void void
backpatch(struct sp_label *); backpatch(struct sp_label *);
// Check that no unresolved references exist.
// If none found, 0 is returned, otherwise errors have been issued
// and -1 is returned.
// This is called by the parser at the end of a create procedure/function.
int
check_backpatch(THD *thd);
// Start a new cont. backpatch level. If 'i' is NULL, the level is just incr. // Start a new cont. backpatch level. If 'i' is NULL, the level is just incr.
void void
new_cont_backpatch(sp_instr_opt_meta *i); new_cont_backpatch(sp_instr_opt_meta *i);
......
...@@ -241,7 +241,7 @@ sp_pcontext::push_label(char *name, uint ip) ...@@ -241,7 +241,7 @@ sp_pcontext::push_label(char *name, uint ip)
{ {
lab->name= name; lab->name= name;
lab->ip= ip; lab->ip= ip;
lab->type= SP_LAB_GOTO; lab->type= SP_LAB_IMPL;
lab->ctx= this; lab->ctx= this;
m_label.push_front(lab); m_label.push_front(lab);
} }
......
...@@ -48,10 +48,9 @@ typedef struct sp_variable ...@@ -48,10 +48,9 @@ typedef struct sp_variable
} sp_variable_t; } sp_variable_t;
#define SP_LAB_REF 0 // Unresolved reference (for goto) #define SP_LAB_IMPL 0 // Implicit label generated by parser
#define SP_LAB_GOTO 1 // Free goto label #define SP_LAB_BEGIN 1 // Label at BEGIN
#define SP_LAB_BEGIN 2 // Label at BEGIN #define SP_LAB_ITER 2 // Label at iteration control
#define SP_LAB_ITER 3 // Label at iteration control
/* /*
An SQL/PSM label. Can refer to the identifier used with the An SQL/PSM label. Can refer to the identifier used with the
......
...@@ -2074,7 +2074,7 @@ void THD::restore_backup_open_tables_state(Open_tables_state *backup) ...@@ -2074,7 +2074,7 @@ void THD::restore_backup_open_tables_state(Open_tables_state *backup)
The following things is done The following things is done
- Disable binary logging for the duration of the statement - Disable binary logging for the duration of the statement
- Disable multi-result-sets for the duration of the statement - Disable multi-result-sets for the duration of the statement
- Value of last_insert_id() is reset and restored - Value of last_insert_id() is saved and restored
- Value set by 'SET INSERT_ID=#' is reset and restored - Value set by 'SET INSERT_ID=#' is reset and restored
- Value for found_rows() is reset and restored - Value for found_rows() is reset and restored
- examined_row_count is added to the total - examined_row_count is added to the total
...@@ -2086,6 +2086,8 @@ void THD::restore_backup_open_tables_state(Open_tables_state *backup) ...@@ -2086,6 +2086,8 @@ void THD::restore_backup_open_tables_state(Open_tables_state *backup)
We reset examined_row_count and cuted_fields and add these to the We reset examined_row_count and cuted_fields and add these to the
result to ensure that if we have a bug that would reset these within result to ensure that if we have a bug that would reset these within
a function, we are not loosing any rows from the main statement. a function, we are not loosing any rows from the main statement.
We do not reset value of last_insert_id().
****************************************************************************/ ****************************************************************************/
void THD::reset_sub_statement_state(Sub_statement_state *backup, void THD::reset_sub_statement_state(Sub_statement_state *backup,
...@@ -2112,7 +2114,6 @@ void THD::reset_sub_statement_state(Sub_statement_state *backup, ...@@ -2112,7 +2114,6 @@ void THD::reset_sub_statement_state(Sub_statement_state *backup,
/* Disable result sets */ /* Disable result sets */
client_capabilities &= ~CLIENT_MULTI_RESULTS; client_capabilities &= ~CLIENT_MULTI_RESULTS;
in_sub_stmt|= new_state; in_sub_stmt|= new_state;
last_insert_id= 0;
next_insert_id= 0; next_insert_id= 0;
insert_id_used= 0; insert_id_used= 0;
examined_row_count= 0; examined_row_count= 0;
......
...@@ -1059,15 +1059,23 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table) ...@@ -1059,15 +1059,23 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table)
!old_lex->can_not_use_merged()) !old_lex->can_not_use_merged())
{ {
List_iterator_fast<TABLE_LIST> ti(view_select->top_join_list); List_iterator_fast<TABLE_LIST> ti(view_select->top_join_list);
/*
Currently 'view_main_select_tables' differs from 'view_tables'
only then view has CONVERT_TZ() function in its select list.
This may change in future, for example if we enable merging
of views with subqueries in select list.
*/
TABLE_LIST *view_main_select_tables=
(TABLE_LIST*)lex->select_lex.table_list.first;
/* lex should contain at least one table */ /* lex should contain at least one table */
DBUG_ASSERT(view_tables != 0); DBUG_ASSERT(view_main_select_tables != 0);
table->effective_algorithm= VIEW_ALGORITHM_MERGE; table->effective_algorithm= VIEW_ALGORITHM_MERGE;
DBUG_PRINT("info", ("algorithm: MERGE")); DBUG_PRINT("info", ("algorithm: MERGE"));
table->updatable= (table->updatable_view != 0); table->updatable= (table->updatable_view != 0);
table->effective_with_check= table->effective_with_check=
old_lex->get_effective_with_check(table); old_lex->get_effective_with_check(table);
table->merge_underlying_list= view_tables; table->merge_underlying_list= view_main_select_tables;
/* /*
Let us set proper lock type for tables of the view's main select Let us set proper lock type for tables of the view's main select
since we may want to perform update or insert on view. This won't since we may want to perform update or insert on view. This won't
...@@ -1083,7 +1091,7 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table) ...@@ -1083,7 +1091,7 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table)
} }
/* prepare view context */ /* prepare view context */
lex->select_lex.context.resolve_in_table_list_only(view_tables); lex->select_lex.context.resolve_in_table_list_only(view_main_select_tables);
lex->select_lex.context.outer_context= 0; lex->select_lex.context.outer_context= 0;
lex->select_lex.context.select_lex= table->select_lex; lex->select_lex.context.select_lex= table->select_lex;
lex->select_lex.select_n_having_items+= lex->select_lex.select_n_having_items+=
...@@ -1099,7 +1107,7 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table) ...@@ -1099,7 +1107,7 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table)
tbl->select_lex= table->select_lex; tbl->select_lex= table->select_lex;
{ {
if (view_tables->next_local) if (view_main_select_tables->next_local)
{ {
table->multitable_view= TRUE; table->multitable_view= TRUE;
if (table->belong_to_view) if (table->belong_to_view)
......
...@@ -317,7 +317,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); ...@@ -317,7 +317,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token GEOMFROMWKB %token GEOMFROMWKB
%token GET_FORMAT %token GET_FORMAT
%token GLOBAL_SYM %token GLOBAL_SYM
%token GOTO_SYM
%token GRANT %token GRANT
%token GRANTS %token GRANTS
%token GREATEST_SYM %token GREATEST_SYM
...@@ -366,7 +365,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); ...@@ -366,7 +365,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token KEYS %token KEYS
%token KEY_SYM %token KEY_SYM
%token KILL_SYM %token KILL_SYM
%token LABEL_SYM
%token LANGUAGE_SYM %token LANGUAGE_SYM
%token LAST_INSERT_ID %token LAST_INSERT_ID
%token LAST_SYM %token LAST_SYM
...@@ -894,7 +892,7 @@ END_OF_INPUT ...@@ -894,7 +892,7 @@ END_OF_INPUT
%type <NONE> sp_proc_stmt_statement sp_proc_stmt_return %type <NONE> sp_proc_stmt_statement sp_proc_stmt_return
%type <NONE> sp_proc_stmt_if sp_proc_stmt_case_simple sp_proc_stmt_case %type <NONE> sp_proc_stmt_if sp_proc_stmt_case_simple sp_proc_stmt_case
%type <NONE> sp_labeled_control sp_proc_stmt_unlabeled sp_proc_stmt_leave %type <NONE> sp_labeled_control sp_proc_stmt_unlabeled sp_proc_stmt_leave
%type <NONE> sp_proc_stmt_iterate sp_proc_stmt_label sp_proc_stmt_goto %type <NONE> sp_proc_stmt_iterate
%type <NONE> sp_proc_stmt_open sp_proc_stmt_fetch sp_proc_stmt_close %type <NONE> sp_proc_stmt_open sp_proc_stmt_fetch sp_proc_stmt_close
%type <num> sp_decl_idents sp_opt_inout sp_handler_type sp_hcond_list %type <num> sp_decl_idents sp_opt_inout sp_handler_type sp_hcond_list
...@@ -1555,8 +1553,6 @@ ev_sql_stmt_inner: ...@@ -1555,8 +1553,6 @@ ev_sql_stmt_inner:
| sp_proc_stmt_unlabeled | sp_proc_stmt_unlabeled
| sp_proc_stmt_leave | sp_proc_stmt_leave
| sp_proc_stmt_iterate | sp_proc_stmt_iterate
| sp_proc_stmt_label
| sp_proc_stmt_goto
| sp_proc_stmt_open | sp_proc_stmt_open
| sp_proc_stmt_fetch | sp_proc_stmt_fetch
| sp_proc_stmt_close | sp_proc_stmt_close
...@@ -1691,8 +1687,6 @@ create_function_tail: ...@@ -1691,8 +1687,6 @@ create_function_tail:
if (sp->is_not_allowed_in_function("function")) if (sp->is_not_allowed_in_function("function"))
YYABORT; YYABORT;
if (sp->check_backpatch(YYTHD))
YYABORT;
lex->sql_command= SQLCOM_CREATE_SPFUNCTION; lex->sql_command= SQLCOM_CREATE_SPFUNCTION;
sp->init_strings(YYTHD, lex, lex->spname); sp->init_strings(YYTHD, lex, lex->spname);
if (!(sp->m_flags & sp_head::HAS_RETURN)) if (!(sp->m_flags & sp_head::HAS_RETURN))
...@@ -2245,8 +2239,6 @@ sp_proc_stmt: ...@@ -2245,8 +2239,6 @@ sp_proc_stmt:
| sp_proc_stmt_unlabeled | sp_proc_stmt_unlabeled
| sp_proc_stmt_leave | sp_proc_stmt_leave
| sp_proc_stmt_iterate | sp_proc_stmt_iterate
| sp_proc_stmt_label
| sp_proc_stmt_goto
| sp_proc_stmt_open | sp_proc_stmt_open
| sp_proc_stmt_fetch | sp_proc_stmt_fetch
| sp_proc_stmt_close | sp_proc_stmt_close
...@@ -2449,97 +2441,6 @@ sp_proc_stmt_iterate: ...@@ -2449,97 +2441,6 @@ sp_proc_stmt_iterate:
} }
; ;
sp_proc_stmt_label:
LABEL_SYM IDENT
{
#ifdef SP_GOTO
LEX *lex= Lex;
sp_head *sp= lex->sphead;
sp_pcontext *ctx= lex->spcont;
sp_label_t *lab= ctx->find_label($2.str);
if (lab)
{
my_error(ER_SP_LABEL_REDEFINE, MYF(0), $2.str);
YYABORT;
}
else
{
lab= ctx->push_label($2.str, sp->instructions());
lab->type= SP_LAB_GOTO;
lab->ctx= ctx;
sp->backpatch(lab);
}
#else
yyerror(ER(ER_SYNTAX_ERROR));
YYABORT;
#endif
}
;
sp_proc_stmt_goto:
GOTO_SYM IDENT
{
#ifdef SP_GOTO
LEX *lex= Lex;
sp_head *sp= lex->sphead;
sp_pcontext *ctx= lex->spcont;
uint ip= lex->sphead->instructions();
sp_label_t *lab;
sp_instr_jump *i;
sp_instr_hpop *ih;
sp_instr_cpop *ic;
if (sp->m_in_handler)
{
my_message(ER_SP_GOTO_IN_HNDLR, ER(ER_SP_GOTO_IN_HNDLR), MYF(0));
YYABORT;
}
lab= ctx->find_label($2.str);
if (! lab)
{
lab= (sp_label_t *)YYTHD->alloc(sizeof(sp_label_t));
lab->name= $2.str;
lab->ip= 0;
lab->type= SP_LAB_REF;
lab->ctx= ctx;
ih= new sp_instr_hpop(ip++, ctx, 0);
sp->push_backpatch(ih, lab);
sp->add_instr(ih);
ic= new sp_instr_cpop(ip++, ctx, 0);
sp->add_instr(ic);
sp->push_backpatch(ic, lab);
i= new sp_instr_jump(ip, ctx);
sp->push_backpatch(i, lab); /* Jumping forward */
sp->add_instr(i);
}
else
{
uint n;
n= ctx->diff_handlers(lab->ctx);
if (n)
{
ih= new sp_instr_hpop(ip++, ctx, n);
sp->add_instr(ih);
}
n= ctx->diff_cursors(lab->ctx);
if (n)
{
ic= new sp_instr_cpop(ip++, ctx, n);
sp->add_instr(ic);
}
i= new sp_instr_jump(ip, ctx, lab->ip); /* Jump back */
sp->add_instr(i);
}
#else
yyerror(ER(ER_SYNTAX_ERROR));
YYABORT;
#endif
}
;
sp_proc_stmt_open: sp_proc_stmt_open:
OPEN_SYM ident OPEN_SYM ident
{ {
...@@ -11064,8 +10965,6 @@ sp_tail: ...@@ -11064,8 +10965,6 @@ sp_tail:
LEX *lex= Lex; LEX *lex= Lex;
sp_head *sp= lex->sphead; sp_head *sp= lex->sphead;
if (sp->check_backpatch(YYTHD))
YYABORT;
sp->init_strings(YYTHD, lex, $3); sp->init_strings(YYTHD, lex, $3);
lex->sql_command= SQLCOM_CREATE_PROCEDURE; lex->sql_command= SQLCOM_CREATE_PROCEDURE;
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment