Skip to content

Commit 0f080dd

Browse files
committed
MDEV-23094: Multiple calls to a Stored Procedure from another Stored Procedure crashes server
Added system-SELECT to IF/WHILE/REPET/FOR for correct subqueries connecting. Added control of system/usual selects for correct error detection.
1 parent 571764c commit 0f080dd

File tree

11 files changed

+601
-30
lines changed

11 files changed

+601
-30
lines changed

mysql-test/main/parser.result

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1908,4 +1908,93 @@ KILL ( SELECT 1 ) + LASTVAL(s);
19081908
ERROR 42000: KILL does not support subqueries or stored functions
19091909
KILL LASTVAL(s);
19101910
ERROR 42000: KILL does not support subqueries or stored functions
1911+
#
1912+
# MDEV-23094: Multiple calls to a Stored Procedure from another
1913+
# Stored Procedure crashes server
1914+
#
1915+
create table t1 (id1 int primary key, data1 int);
1916+
create table t2 (id2 int primary key, data2 int);
1917+
create procedure p1(IN id int, IN dt int)
1918+
begin
1919+
if (exists(select * from t1 where id1 = id and data1 = dt) or
1920+
not exists (select * from t2 where id2 = id and data2 = dt))
1921+
then
1922+
select 1;
1923+
end if;
1924+
end //
1925+
call p1(1,2);
1926+
1
1927+
1
1928+
call p1(1,2);
1929+
1
1930+
1
1931+
drop procedure p1;
1932+
create procedure p1(IN id int, IN dt int)
1933+
begin
1934+
case (exists(select * from t1 where id1 = id and data1 = dt) or
1935+
not exists (select * from t2 where id2 = id and data2 = dt))
1936+
when 1 then
1937+
select 1;
1938+
else
1939+
select 0;
1940+
end case;
1941+
end //
1942+
call p1(1,2);
1943+
1
1944+
1
1945+
call p1(1,2);
1946+
1
1947+
1
1948+
drop procedure p1;
1949+
create procedure p1(IN id int, IN dt int)
1950+
begin
1951+
declare wcont int default 1;
1952+
while (exists(select * from t1 where id1 = id and data1 = dt) or
1953+
not exists (select * from t2 where id2 = id and data2 = dt)) and wcont
1954+
do
1955+
select 1;
1956+
set wcont=0;
1957+
end while;
1958+
end //
1959+
call p1(1,2);
1960+
1
1961+
1
1962+
call p1(1,2);
1963+
1
1964+
1
1965+
drop procedure p1;
1966+
create procedure p1(IN id int, IN dt int)
1967+
begin
1968+
declare count int default 1;
1969+
repeat
1970+
select 1;
1971+
set count=count+1;
1972+
until (exists(select * from t1 where id1 = id and data1 = dt) or
1973+
not exists (select * from t2 where id2 = id and data2 = dt)) and
1974+
count < 3
1975+
end repeat;
1976+
end //
1977+
call p1(1,2);
1978+
1
1979+
1
1980+
call p1(1,2);
1981+
1
1982+
1
1983+
drop procedure p1;
1984+
create procedure p1(IN id int, IN dt int)
1985+
begin
1986+
for i in 1..(exists(select * from t1 where id1 = id and data1 = dt) or
1987+
not exists (select * from t2 where id2 = id and data2 = dt))
1988+
do
1989+
select 1;
1990+
end for;
1991+
end //
1992+
call p1(1,2);
1993+
1
1994+
1
1995+
call p1(1,2);
1996+
1
1997+
1
1998+
drop procedure p1;
1999+
drop table t1,t2;
19112000
# End of 10.4 tests

mysql-test/main/parser.test

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1696,4 +1696,101 @@ KILL ( SELECT 1 ) + LASTVAL(s);
16961696
--error ER_SUBQUERIES_NOT_SUPPORTED
16971697
KILL LASTVAL(s);
16981698

1699+
--echo #
1700+
--echo # MDEV-23094: Multiple calls to a Stored Procedure from another
1701+
--echo # Stored Procedure crashes server
1702+
--echo #
1703+
1704+
create table t1 (id1 int primary key, data1 int);
1705+
create table t2 (id2 int primary key, data2 int);
1706+
1707+
delimiter //;
1708+
create procedure p1(IN id int, IN dt int)
1709+
begin
1710+
if (exists(select * from t1 where id1 = id and data1 = dt) or
1711+
not exists (select * from t2 where id2 = id and data2 = dt))
1712+
then
1713+
select 1;
1714+
end if;
1715+
end //
1716+
delimiter ;//
1717+
1718+
call p1(1,2);
1719+
call p1(1,2);
1720+
1721+
drop procedure p1;
1722+
1723+
delimiter //;
1724+
create procedure p1(IN id int, IN dt int)
1725+
begin
1726+
case (exists(select * from t1 where id1 = id and data1 = dt) or
1727+
not exists (select * from t2 where id2 = id and data2 = dt))
1728+
when 1 then
1729+
select 1;
1730+
else
1731+
select 0;
1732+
end case;
1733+
end //
1734+
delimiter ;//
1735+
1736+
call p1(1,2);
1737+
call p1(1,2);
1738+
1739+
drop procedure p1;
1740+
1741+
delimiter //;
1742+
create procedure p1(IN id int, IN dt int)
1743+
begin
1744+
declare wcont int default 1;
1745+
while (exists(select * from t1 where id1 = id and data1 = dt) or
1746+
not exists (select * from t2 where id2 = id and data2 = dt)) and wcont
1747+
do
1748+
select 1;
1749+
set wcont=0;
1750+
end while;
1751+
end //
1752+
delimiter ;//
1753+
1754+
call p1(1,2);
1755+
call p1(1,2);
1756+
1757+
drop procedure p1;
1758+
1759+
delimiter //;
1760+
create procedure p1(IN id int, IN dt int)
1761+
begin
1762+
declare count int default 1;
1763+
repeat
1764+
select 1;
1765+
set count=count+1;
1766+
until (exists(select * from t1 where id1 = id and data1 = dt) or
1767+
not exists (select * from t2 where id2 = id and data2 = dt)) and
1768+
count < 3
1769+
end repeat;
1770+
end //
1771+
delimiter ;//
1772+
1773+
call p1(1,2);
1774+
call p1(1,2);
1775+
1776+
drop procedure p1;
1777+
1778+
delimiter //;
1779+
create procedure p1(IN id int, IN dt int)
1780+
begin
1781+
for i in 1..(exists(select * from t1 where id1 = id and data1 = dt) or
1782+
not exists (select * from t2 where id2 = id and data2 = dt))
1783+
do
1784+
select 1;
1785+
end for;
1786+
end //
1787+
delimiter ;//
1788+
1789+
call p1(1,2);
1790+
call p1(1,2);
1791+
1792+
drop procedure p1;
1793+
1794+
drop table t1,t2;
1795+
16991796
--echo # End of 10.4 tests

mysql-test/suite/compat/oracle/r/parser.result

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -643,3 +643,118 @@ END;
643643
#
644644
# End of 10.3 tests
645645
#
646+
#
647+
# MDEV-21998: Server crashes in st_select_lex::add_table_to_list
648+
# upon mix of KILL and sequences
649+
#
650+
KILL ( SELECT 1 ) + LASTVAL(s);
651+
ERROR 42000: KILL does not support subqueries or stored functions
652+
KILL LASTVAL(s);
653+
ERROR 42000: KILL does not support subqueries or stored functions
654+
#
655+
# MDEV-23094: Multiple calls to a Stored Procedure from another
656+
# Stored Procedure crashes server
657+
#
658+
create table t1 (id1 int primary key, data1 int);
659+
create table t2 (id2 int primary key, data2 int);
660+
create procedure p1(id int,dt int) as
661+
begin
662+
if (exists(select * from t1 where id1 = id and data1 = dt) or
663+
not exists (select * from t2 where id2 = id and data2 = dt))
664+
then
665+
select 1;
666+
end if;
667+
end //
668+
call p1(1,2);
669+
1
670+
1
671+
call p1(1,2);
672+
1
673+
1
674+
drop procedure p1;
675+
create procedure p1(id int, dt int) as
676+
begin
677+
case (exists(select * from t1 where id1 = id and data1 = dt) or
678+
not exists (select * from t2 where id2 = id and data2 = dt))
679+
when 1 then
680+
select 1;
681+
else
682+
select 0;
683+
end case;
684+
end //
685+
call p1(1,2);
686+
1
687+
1
688+
call p1(1,2);
689+
1
690+
1
691+
drop procedure p1;
692+
create procedure p1(id int, dt int) as
693+
begin
694+
declare wcont int default 1;
695+
begin
696+
while (exists(select * from t1 where id1 = id and data1 = dt) or
697+
not exists (select * from t2 where id2 = id and data2 = dt)) and wcont
698+
loop
699+
select 1;
700+
set wcont=0;
701+
end loop;
702+
end;
703+
end //
704+
call p1(1,2);
705+
1
706+
1
707+
call p1(1,2);
708+
1
709+
1
710+
drop procedure p1;
711+
create procedure p1(id int, dt int) as
712+
begin
713+
declare count int default 1;
714+
begin
715+
repeat
716+
select 1;
717+
set count=count+1;
718+
until (exists(select * from t1 where id1 = id and data1 = dt) or
719+
not exists (select * from t2 where id2 = id and data2 = dt)) and
720+
count < 3
721+
end repeat;
722+
end;
723+
end //
724+
call p1(1,2);
725+
1
726+
1
727+
call p1(1,2);
728+
1
729+
1
730+
drop procedure p1;
731+
create procedure p1(id int, dt int) as
732+
begin
733+
for i in 1..(exists(select * from t1 where id1 = id and data1 = dt) or
734+
not exists (select * from t2 where id2 = id and data2 = dt))
735+
loop
736+
select 1;
737+
end loop;
738+
end //
739+
call p1(1,2);
740+
1
741+
1
742+
call p1(1,2);
743+
1
744+
1
745+
drop procedure p1;
746+
set sql_mode=ORACLE;
747+
create or replace procedure p1(id int, dt int) as
748+
begin
749+
while (1)
750+
loop
751+
exit when (exists(select * from t1 where id1 = id and data1 = dt) or
752+
not exists (select * from t2 where id2 = id and data2 = dt));
753+
end loop;
754+
end;
755+
//
756+
call p1(1,2);
757+
call p1(1,2);
758+
drop procedure p1;
759+
drop table t1,t2;
760+
# End of 10.4 tests

0 commit comments

Comments
 (0)