mirror of
https://github.com/MariaDB/server.git
synced 2025-01-19 05:22:25 +01:00
Merge mysql.com:/usr/local/bk/mysql-5.0
into mysql.com:/home/pem/work/mysql-5.0-merge
This commit is contained in:
commit
8fa394da62
33 changed files with 565 additions and 392 deletions
|
@ -373,4 +373,5 @@
|
|||
#define ER_WARN_VIEW_WITHOUT_KEY 1354
|
||||
#define ER_VIEW_INVALID 1355
|
||||
#define ER_SP_NO_DROP_SP 1356
|
||||
#define ER_SP_GOTO_IN_HNDLR 1357
|
||||
#define ER_ERROR_MESSAGES 357
|
||||
|
|
|
@ -68,6 +68,42 @@ 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 foo()
|
||||
foo: loop
|
||||
foo: loop
|
||||
set @x=2;
|
||||
|
@ -288,6 +324,16 @@ declare continue handler for sqlstate '42S99' set x = 1;
|
|||
declare c cursor for select * from t1;
|
||||
end|
|
||||
ERROR 42000: Cursor declaration after handler declaration
|
||||
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
|
||||
create procedure bug1965()
|
||||
begin
|
||||
declare c cursor for select val from t1 order by valname;
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
reset master;
|
||||
use test;
|
||||
drop table if exists t1;
|
||||
drop table if exists t2;
|
||||
|
@ -398,7 +397,7 @@ id data
|
|||
i 3
|
||||
delete from t1|
|
||||
drop procedure i|
|
||||
create procedure j()
|
||||
create procedure goto1()
|
||||
begin
|
||||
declare y int;
|
||||
label a;
|
||||
|
@ -411,7 +410,7 @@ insert into t1 values ("j", y);
|
|||
goto a;
|
||||
label b;
|
||||
end|
|
||||
call j()|
|
||||
call goto1()|
|
||||
id data
|
||||
id data
|
||||
j 0
|
||||
|
@ -422,8 +421,8 @@ id data
|
|||
j 0
|
||||
j 1
|
||||
j 2
|
||||
drop procedure j|
|
||||
create procedure k(a int)
|
||||
drop procedure goto1|
|
||||
create procedure goto2(a int)
|
||||
begin
|
||||
declare x int default 0;
|
||||
declare continue handler for sqlstate '42S98' set x = 1;
|
||||
|
@ -446,7 +445,7 @@ end;
|
|||
end while b;
|
||||
select * from t1;
|
||||
end|
|
||||
call k(0)|
|
||||
call goto2(0)|
|
||||
id data
|
||||
j 0
|
||||
j 1
|
||||
|
@ -455,7 +454,7 @@ id data
|
|||
j 0
|
||||
j 1
|
||||
j 2
|
||||
call k(1)|
|
||||
call goto2(1)|
|
||||
id data
|
||||
j 0
|
||||
j 1
|
||||
|
@ -464,7 +463,7 @@ id data
|
|||
j 0
|
||||
j 1
|
||||
j 2
|
||||
call k(2)|
|
||||
call goto2(2)|
|
||||
id data
|
||||
j 0
|
||||
j 1
|
||||
|
@ -477,8 +476,60 @@ id data
|
|||
j 0
|
||||
j 1
|
||||
j 2
|
||||
drop procedure k|
|
||||
drop procedure goto2|
|
||||
delete from t1|
|
||||
create procedure goto3()
|
||||
begin
|
||||
label L1;
|
||||
begin
|
||||
end;
|
||||
goto L1;
|
||||
end|
|
||||
drop procedure goto3|
|
||||
create procedure goto4()
|
||||
begin
|
||||
begin
|
||||
label lab1;
|
||||
begin
|
||||
goto lab1;
|
||||
end;
|
||||
end;
|
||||
end|
|
||||
drop procedure goto4|
|
||||
create procedure goto5()
|
||||
begin
|
||||
begin
|
||||
begin
|
||||
goto lab1;
|
||||
end;
|
||||
label lab1;
|
||||
end;
|
||||
end|
|
||||
drop procedure goto5|
|
||||
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|
|
||||
insert into t1 values ("foo", 3), ("bar", 19)|
|
||||
insert into t2 values ("x", 9, 4.1), ("y", -1, 19.2), ("z", 3, 2.2)|
|
||||
create procedure sel1()
|
||||
|
@ -1536,11 +1587,8 @@ show errors;
|
|||
show columns from t1;
|
||||
show grants for 'root'@'localhost';
|
||||
show keys from t1;
|
||||
show master status;
|
||||
show open tables like 'foo';
|
||||
show privileges;
|
||||
show slave hosts;
|
||||
show slave status;
|
||||
show status like 'foo';
|
||||
show tables like 'foo';
|
||||
show variables like 'foo';
|
||||
|
@ -1567,8 +1615,6 @@ data int(11) 0
|
|||
Grants for root@localhost
|
||||
GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION
|
||||
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
|
||||
File Position Binlog_Do_DB Binlog_Ignore_DB
|
||||
master-bin.000001 22451
|
||||
Database Table In_use Name_locked
|
||||
Privilege Context Comment
|
||||
Alter Tables To alter the table
|
||||
|
@ -1594,8 +1640,6 @@ Shutdown Server Admin To shut down the server
|
|||
Super Server Admin To use KILL thread, SET GLOBAL, CHANGE MASTER, etc.
|
||||
Update Tables To update existing rows
|
||||
Usage Server Admin No privileges - allow connect only
|
||||
Server_id Host Port Rpl_recovery_rank Master_id
|
||||
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
|
||||
Variable_name Value
|
||||
Tables_in_test (foo) table_type
|
||||
Variable_name Value
|
||||
|
@ -1621,8 +1665,6 @@ data int(11) 0
|
|||
Grants for root@localhost
|
||||
GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION
|
||||
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
|
||||
File Position Binlog_Do_DB Binlog_Ignore_DB
|
||||
master-bin.000001 22451
|
||||
Database Table In_use Name_locked
|
||||
Privilege Context Comment
|
||||
Alter Tables To alter the table
|
||||
|
@ -1648,8 +1690,6 @@ Shutdown Server Admin To shut down the server
|
|||
Super Server Admin To use KILL thread, SET GLOBAL, CHANGE MASTER, etc.
|
||||
Update Tables To update existing rows
|
||||
Usage Server Admin No privileges - allow connect only
|
||||
Server_id Host Port Rpl_recovery_rank Master_id
|
||||
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
|
||||
Variable_name Value
|
||||
Tables_in_test (foo) table_type
|
||||
Variable_name Value
|
||||
|
|
|
@ -103,6 +103,42 @@ create procedure foo()
|
|||
begin
|
||||
goto foo;
|
||||
end|
|
||||
--error 1307
|
||||
create procedure foo()
|
||||
begin
|
||||
begin
|
||||
label foo;
|
||||
end;
|
||||
goto foo;
|
||||
end|
|
||||
--error 1307
|
||||
create procedure foo()
|
||||
begin
|
||||
goto foo;
|
||||
begin
|
||||
label foo;
|
||||
end;
|
||||
end|
|
||||
--error 1307
|
||||
create procedure foo()
|
||||
begin
|
||||
begin
|
||||
goto foo;
|
||||
end;
|
||||
begin
|
||||
label foo;
|
||||
end;
|
||||
end|
|
||||
--error 1307
|
||||
create procedure foo()
|
||||
begin
|
||||
begin
|
||||
label foo;
|
||||
end;
|
||||
begin
|
||||
goto foo;
|
||||
end;
|
||||
end|
|
||||
|
||||
# Redefining label
|
||||
--error 1308
|
||||
|
@ -380,6 +416,18 @@ begin
|
|||
declare c cursor for select * from t1;
|
||||
end|
|
||||
|
||||
--error 1357
|
||||
create procedure p()
|
||||
begin
|
||||
declare continue handler for sqlexception
|
||||
begin
|
||||
goto L1;
|
||||
end;
|
||||
|
||||
select field from t1;
|
||||
label L1;
|
||||
end|
|
||||
|
||||
#
|
||||
# BUG#1965
|
||||
#
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
#
|
||||
# Basic stored PROCEDURE tests
|
||||
#
|
||||
#
|
||||
|
||||
# Let us reset binary logs in order to make show master status
|
||||
# in test for bug 4902 repeatable.
|
||||
reset master;
|
||||
# Please keep this file free of --error cases and other
|
||||
# things that will not run in a single debugged mysqld
|
||||
# process (e.g. master-slave things).
|
||||
|
||||
use test;
|
||||
|
||||
|
@ -470,10 +468,10 @@ drop procedure i|
|
|||
|
||||
# The non-standard GOTO, for compatibility
|
||||
#
|
||||
# QQQ The "label" syntax is temporary.
|
||||
# QQQ This is no nearly enough, more tests are needed
|
||||
# QQQ The "label" syntax is temporary, it will (hopefully)
|
||||
# change to the more common "L:" syntax soon.
|
||||
#
|
||||
create procedure j()
|
||||
create procedure goto1()
|
||||
begin
|
||||
declare y int;
|
||||
|
||||
|
@ -488,12 +486,11 @@ label a;
|
|||
label b;
|
||||
end|
|
||||
|
||||
call j()|
|
||||
|
||||
drop procedure j|
|
||||
call goto1()|
|
||||
drop procedure goto1|
|
||||
|
||||
# With dummy handlers, just to test restore of contexts with jumps
|
||||
create procedure k(a int)
|
||||
create procedure goto2(a int)
|
||||
begin
|
||||
declare x int default 0;
|
||||
declare continue handler for sqlstate '42S98' set x = 1;
|
||||
|
@ -520,13 +517,70 @@ b:
|
|||
select * from t1;
|
||||
end|
|
||||
|
||||
call k(0)|
|
||||
call k(1)|
|
||||
call k(2)|
|
||||
call goto2(0)|
|
||||
call goto2(1)|
|
||||
call goto2(2)|
|
||||
|
||||
drop procedure k|
|
||||
drop procedure goto2|
|
||||
delete from t1|
|
||||
|
||||
# Check label visibility for some more cases. We don't call these.
|
||||
create procedure goto3()
|
||||
begin
|
||||
label L1;
|
||||
begin
|
||||
end;
|
||||
goto L1;
|
||||
end|
|
||||
drop procedure goto3|
|
||||
|
||||
create procedure goto4()
|
||||
begin
|
||||
begin
|
||||
label lab1;
|
||||
begin
|
||||
goto lab1;
|
||||
end;
|
||||
end;
|
||||
end|
|
||||
drop procedure goto4|
|
||||
|
||||
create procedure goto5()
|
||||
begin
|
||||
begin
|
||||
begin
|
||||
goto lab1;
|
||||
end;
|
||||
label lab1;
|
||||
end;
|
||||
end|
|
||||
drop procedure goto5|
|
||||
|
||||
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|
|
||||
|
||||
# SELECT with one of more result set sent back to the clinet
|
||||
insert into t1 values ("foo", 3), ("bar", 19)|
|
||||
insert into t2 values ("x", 9, 4.1), ("y", -1, 19.2), ("z", 3, 2.2)|
|
||||
|
@ -1761,11 +1815,8 @@ begin
|
|||
show columns from t1;
|
||||
show grants for 'root'@'localhost';
|
||||
show keys from t1;
|
||||
show master status;
|
||||
show open tables like 'foo';
|
||||
show privileges;
|
||||
show slave hosts;
|
||||
show slave status;
|
||||
show status like 'foo';
|
||||
show tables like 'foo';
|
||||
show variables like 'foo';
|
||||
|
@ -1773,6 +1824,9 @@ begin
|
|||
end|
|
||||
#show binlog events;
|
||||
#show storage engines;
|
||||
#show master status;
|
||||
#show slave hosts;
|
||||
#show slave status;
|
||||
|
||||
call bug4902()|
|
||||
call bug4902()|
|
||||
|
|
|
@ -369,3 +369,4 @@ character-set=latin2
|
|||
"View being updated does not have complete key of underlying table in it"
|
||||
"View '%-.64s.%-.64s' references invalid table(s) or column(s)"
|
||||
"Can't drop a %s from within another stored routine"
|
||||
"GOTO is not allowed in a stored procedure handler"
|
||||
|
|
|
@ -363,3 +363,4 @@ character-set=latin1
|
|||
"View being updated does not have complete key of underlying table in it"
|
||||
"View '%-.64s.%-.64s' references invalid table(s) or column(s)"
|
||||
"Can't drop a %s from within another stored routine"
|
||||
"GOTO is not allowed in a stored procedure handler"
|
||||
|
|
|
@ -371,3 +371,4 @@ character-set=latin1
|
|||
"View being updated does not have complete key of underlying table in it"
|
||||
"View '%-.64s.%-.64s' references invalid table(s) or column(s)"
|
||||
"Can't drop a %s from within another stored routine"
|
||||
"GOTO is not allowed in a stored procedure handler"
|
||||
|
|
|
@ -360,3 +360,4 @@ character-set=latin1
|
|||
"View being updated does not have complete key of underlying table in it"
|
||||
"View '%-.64s.%-.64s' references invalid table(s) or column(s)"
|
||||
"Can't drop a %s from within another stored routine"
|
||||
"GOTO is not allowed in a stored procedure handler"
|
||||
|
|
|
@ -365,3 +365,4 @@ character-set=latin7
|
|||
"View being updated does not have complete key of underlying table in it"
|
||||
"View '%-.64s.%-.64s' references invalid table(s) or column(s)"
|
||||
"Can't drop a %s from within another stored routine"
|
||||
"GOTO is not allowed in a stored procedure handler"
|
||||
|
|
|
@ -360,3 +360,4 @@ character-set=latin1
|
|||
"View being updated does not have complete key of underlying table in it"
|
||||
"View '%-.64s.%-.64s' references invalid table(s) or column(s)"
|
||||
"Can't drop a %s from within another stored routine"
|
||||
"GOTO is not allowed in a stored procedure handler"
|
||||
|
|
|
@ -372,3 +372,4 @@ character-set=latin1
|
|||
"View being updated does not have complete key of underlying table in it"
|
||||
"View '%-.64s.%-.64s' references invalid table(s) or column(s)"
|
||||
"Can't drop a %s from within another stored routine"
|
||||
"GOTO is not allowed in a stored procedure handler"
|
||||
|
|
|
@ -360,3 +360,4 @@ character-set=greek
|
|||
"View being updated does not have complete key of underlying table in it"
|
||||
"View '%-.64s.%-.64s' references invalid table(s) or column(s)"
|
||||
"Can't drop a %s from within another stored routine"
|
||||
"GOTO is not allowed in a stored procedure handler"
|
||||
|
|
|
@ -362,3 +362,4 @@ character-set=latin2
|
|||
"View being updated does not have complete key of underlying table in it"
|
||||
"View '%-.64s.%-.64s' references invalid table(s) or column(s)"
|
||||
"Can't drop a %s from within another stored routine"
|
||||
"GOTO is not allowed in a stored procedure handler"
|
||||
|
|
|
@ -360,3 +360,4 @@ character-set=latin1
|
|||
"View being updated does not have complete key of underlying table in it"
|
||||
"View '%-.64s.%-.64s' references invalid table(s) or column(s)"
|
||||
"Can't drop a %s from within another stored routine"
|
||||
"GOTO is not allowed in a stored procedure handler"
|
||||
|
|
|
@ -362,3 +362,4 @@ character-set=ujis
|
|||
"View being updated does not have complete key of underlying table in it"
|
||||
"View '%-.64s.%-.64s' references invalid table(s) or column(s)"
|
||||
"Can't drop a %s from within another stored routine"
|
||||
"GOTO is not allowed in a stored procedure handler"
|
||||
|
|
|
@ -360,3 +360,4 @@ character-set=euckr
|
|||
"View being updated does not have complete key of underlying table in it"
|
||||
"View '%-.64s.%-.64s' references invalid table(s) or column(s)"
|
||||
"Can't drop a %s from within another stored routine"
|
||||
"GOTO is not allowed in a stored procedure handler"
|
||||
|
|
|
@ -362,3 +362,4 @@ character-set=latin1
|
|||
"View being updated does not have complete key of underlying table in it"
|
||||
"View '%-.64s.%-.64s' references invalid table(s) or column(s)"
|
||||
"Can't drop a %s from within another stored routine"
|
||||
"GOTO is not allowed in a stored procedure handler"
|
||||
|
|
|
@ -362,3 +362,4 @@ character-set=latin1
|
|||
"View being updated does not have complete key of underlying table in it"
|
||||
"View '%-.64s.%-.64s' references invalid table(s) or column(s)"
|
||||
"Can't drop a %s from within another stored routine"
|
||||
"GOTO is not allowed in a stored procedure handler"
|
||||
|
|
|
@ -364,3 +364,4 @@ character-set=latin2
|
|||
"View being updated does not have complete key of underlying table in it"
|
||||
"View '%-.64s.%-.64s' references invalid table(s) or column(s)"
|
||||
"Can't drop a %s from within another stored routine"
|
||||
"GOTO is not allowed in a stored procedure handler"
|
||||
|
|
|
@ -361,3 +361,4 @@ character-set=latin1
|
|||
"View being updated does not have complete key of underlying table in it"
|
||||
"View '%-.64s.%-.64s' references invalid table(s) or column(s)"
|
||||
"Can't drop a %s from within another stored routine"
|
||||
"GOTO is not allowed in a stored procedure handler"
|
||||
|
|
|
@ -364,3 +364,4 @@ character-set=latin2
|
|||
"View being updated does not have complete key of underlying table in it"
|
||||
"View '%-.64s.%-.64s' references invalid table(s) or column(s)"
|
||||
"Can't drop a %s from within another stored routine"
|
||||
"GOTO is not allowed in a stored procedure handler"
|
||||
|
|
|
@ -362,3 +362,4 @@ character-set=koi8r
|
|||
"Обновляемый view не содержит ключа использованной в нем таблиц(ы)"
|
||||
"View '%-.64s.%-.64s' ссылается на несуществующие таблицы или слолбцы"
|
||||
"Can't drop a %s from within another stored routine"
|
||||
"GOTO is not allowed in a stored procedure handler"
|
||||
|
|
|
@ -366,3 +366,4 @@ character-set=cp1250
|
|||
"View being updated does not have complete key of underlying table in it"
|
||||
"View '%-.64s.%-.64s' references invalid table(s) or column(s)"
|
||||
"Can't drop a %s from within another stored routine"
|
||||
"GOTO is not allowed in a stored procedure handler"
|
||||
|
|
|
@ -368,3 +368,4 @@ character-set=latin2
|
|||
"View being updated does not have complete key of underlying table in it"
|
||||
"View '%-.64s.%-.64s' references invalid table(s) or column(s)"
|
||||
"Can't drop a %s from within another stored routine"
|
||||
"GOTO is not allowed in a stored procedure handler"
|
||||
|
|
|
@ -362,3 +362,4 @@ character-set=latin1
|
|||
"View being updated does not have complete key of underlying table in it"
|
||||
"View '%-.64s.%-.64s' references invalid table(s) or column(s)"
|
||||
"Can't drop a %s from within another stored routine"
|
||||
"GOTO is not allowed in a stored procedure handler"
|
||||
|
|
|
@ -360,3 +360,4 @@ character-set=latin1
|
|||
"View being updated does not have complete key of underlying table in it"
|
||||
"View '%-.64s.%-.64s' references invalid table(s) or column(s)"
|
||||
"Can't drop a %s from within another stored routine"
|
||||
"GOTO is not allowed in a stored procedure handler"
|
||||
|
|
|
@ -365,3 +365,4 @@ character-set=koi8u
|
|||
"View, що оновлюеться, не м╕стить повного ключа таблиц╕(ь), що викор╕стана в ньюому"
|
||||
"View '%-.64s.%-.64s' посила╓тся на не╕снуюч╕ таблиц╕ або стовбц╕"
|
||||
"Can't drop a %s from within another stored routine"
|
||||
"GOTO is not allowed in a stored procedure handler"
|
||||
|
|
|
@ -257,7 +257,7 @@ sp_head::operator delete(void *ptr, size_t size)
|
|||
|
||||
sp_head::sp_head()
|
||||
:Item_arena((bool)FALSE), m_returns_cs(NULL), m_has_return(FALSE),
|
||||
m_simple_case(FALSE), m_multi_results(FALSE)
|
||||
m_simple_case(FALSE), m_multi_results(FALSE), m_in_handler(FALSE)
|
||||
{
|
||||
DBUG_ENTER("sp_head::sp_head");
|
||||
|
||||
|
@ -272,7 +272,7 @@ sp_head::init(LEX *lex)
|
|||
{
|
||||
DBUG_ENTER("sp_head::init");
|
||||
|
||||
lex->spcont= m_pcont= new sp_pcontext();
|
||||
lex->spcont= m_pcont= new sp_pcontext(NULL);
|
||||
my_init_dynamic_array(&m_instr, sizeof(sp_instr *), 16, 8);
|
||||
m_param_begin= m_param_end= m_returns_begin= m_returns_end= m_body_begin= 0;
|
||||
m_qname.str= m_db.str= m_name.str= m_params.str= m_retstr.str=
|
||||
|
@ -514,10 +514,10 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, Item **resp)
|
|||
{
|
||||
DBUG_ENTER("sp_head::execute_function");
|
||||
DBUG_PRINT("info", ("function %s", m_name.str));
|
||||
uint csize = m_pcont->max_framesize();
|
||||
uint params = m_pcont->params();
|
||||
uint hmax = m_pcont->handlers();
|
||||
uint cmax = m_pcont->cursors();
|
||||
uint csize = m_pcont->max_pvars();
|
||||
uint params = m_pcont->current_pvars();
|
||||
uint hmax = m_pcont->max_handlers();
|
||||
uint cmax = m_pcont->max_cursors();
|
||||
sp_rcontext *octx = thd->spcont;
|
||||
sp_rcontext *nctx = NULL;
|
||||
uint i;
|
||||
|
@ -594,10 +594,10 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
|
|||
DBUG_ENTER("sp_head::execute_procedure");
|
||||
DBUG_PRINT("info", ("procedure %s", m_name.str));
|
||||
int ret= 0;
|
||||
uint csize = m_pcont->max_framesize();
|
||||
uint params = m_pcont->params();
|
||||
uint hmax = m_pcont->handlers();
|
||||
uint cmax = m_pcont->cursors();
|
||||
uint csize = m_pcont->max_pvars();
|
||||
uint params = m_pcont->current_pvars();
|
||||
uint hmax = m_pcont->max_handlers();
|
||||
uint cmax = m_pcont->max_cursors();
|
||||
sp_rcontext *octx = thd->spcont;
|
||||
sp_rcontext *nctx = NULL;
|
||||
my_bool tmp_octx = FALSE; // True if we have allocated a temporary octx
|
||||
|
@ -851,12 +851,18 @@ sp_head::backpatch(sp_label_t *lab)
|
|||
(bp->lab->type == SP_LAB_REF &&
|
||||
my_strcasecmp(system_charset_info, bp->lab->name, lab->name) == 0))
|
||||
{
|
||||
sp_scope_t sdiff;
|
||||
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 (bp->lab->type == SP_LAB_REF)
|
||||
bp->lab= lab;
|
||||
m_pcont->diff_scopes(0, &sdiff);
|
||||
bp->instr->backpatch(dest, sdiff.hndlrs, sdiff.curs);
|
||||
if (dstlab)
|
||||
{
|
||||
bp->lab= lab;
|
||||
bp->instr->backpatch(dest, dstlab->ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1236,7 +1242,7 @@ sp_instr_jump::print(String *str)
|
|||
uint
|
||||
sp_instr_jump::opt_mark(sp_head *sp)
|
||||
{
|
||||
m_dest= opt_shortcut_jump(sp);
|
||||
m_dest= opt_shortcut_jump(sp, this);
|
||||
if (m_dest != m_ip+1) /* Jumping to following instruction? */
|
||||
marked= 1;
|
||||
m_optdest= sp->get_instr(m_dest);
|
||||
|
@ -1244,15 +1250,18 @@ sp_instr_jump::opt_mark(sp_head *sp)
|
|||
}
|
||||
|
||||
uint
|
||||
sp_instr_jump::opt_shortcut_jump(sp_head *sp)
|
||||
sp_instr_jump::opt_shortcut_jump(sp_head *sp, sp_instr *start)
|
||||
{
|
||||
uint dest= m_dest;
|
||||
sp_instr *i;
|
||||
|
||||
while ((i= sp->get_instr(dest)))
|
||||
{
|
||||
uint ndest= i->opt_shortcut_jump(sp);
|
||||
uint ndest;
|
||||
|
||||
if (start == i)
|
||||
break;
|
||||
ndest= i->opt_shortcut_jump(sp, start);
|
||||
if (ndest == dest)
|
||||
break;
|
||||
dest= ndest;
|
||||
|
@ -1320,7 +1329,7 @@ sp_instr_jump_if::opt_mark(sp_head *sp)
|
|||
marked= 1;
|
||||
if ((i= sp->get_instr(m_dest)))
|
||||
{
|
||||
m_dest= i->opt_shortcut_jump(sp);
|
||||
m_dest= i->opt_shortcut_jump(sp, this);
|
||||
m_optdest= sp->get_instr(m_dest);
|
||||
}
|
||||
sp->opt_mark(m_dest);
|
||||
|
@ -1377,7 +1386,7 @@ sp_instr_jump_if_not::opt_mark(sp_head *sp)
|
|||
marked= 1;
|
||||
if ((i= sp->get_instr(m_dest)))
|
||||
{
|
||||
m_dest= i->opt_shortcut_jump(sp);
|
||||
m_dest= i->opt_shortcut_jump(sp, this);
|
||||
m_optdest= sp->get_instr(m_dest);
|
||||
}
|
||||
sp->opt_mark(m_dest);
|
||||
|
@ -1460,7 +1469,7 @@ sp_instr_hpush_jump::opt_mark(sp_head *sp)
|
|||
marked= 1;
|
||||
if ((i= sp->get_instr(m_dest)))
|
||||
{
|
||||
m_dest= i->opt_shortcut_jump(sp);
|
||||
m_dest= i->opt_shortcut_jump(sp, this);
|
||||
m_optdest= sp->get_instr(m_dest);
|
||||
}
|
||||
sp->opt_mark(m_dest);
|
||||
|
@ -1487,6 +1496,13 @@ sp_instr_hpop::print(String *str)
|
|||
str->qs_append(m_count);
|
||||
}
|
||||
|
||||
void
|
||||
sp_instr_hpop::backpatch(uint dest, sp_pcontext *dst_ctx)
|
||||
{
|
||||
m_count= m_ctx->diff_handlers(dst_ctx);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// sp_instr_hreturn
|
||||
//
|
||||
|
@ -1551,6 +1567,12 @@ sp_instr_cpop::print(String *str)
|
|||
str->qs_append(m_count);
|
||||
}
|
||||
|
||||
void
|
||||
sp_instr_cpop::backpatch(uint dest, sp_pcontext *dst_ctx)
|
||||
{
|
||||
m_count= m_ctx->diff_cursors(dst_ctx);
|
||||
}
|
||||
|
||||
//
|
||||
// sp_instr_copen
|
||||
//
|
||||
|
|
111
sql/sp_head.h
111
sql/sp_head.h
|
@ -86,6 +86,7 @@ public:
|
|||
my_bool m_has_return; // For FUNCTIONs only
|
||||
my_bool m_simple_case; // TRUE if parsing simple case, FALSE otherwise
|
||||
my_bool m_multi_results; // TRUE if a procedure with SELECT(s)
|
||||
my_bool m_in_handler; // TRUE if parser in a handler body
|
||||
uint m_old_cmq; // Old CLIENT_MULTI_QUERIES value
|
||||
st_sp_chistics *m_chistics;
|
||||
ulong m_sql_mode; // For SHOW CREATE
|
||||
|
@ -262,10 +263,11 @@ public:
|
|||
uint marked;
|
||||
Item *free_list; // My Items
|
||||
uint m_ip; // My index
|
||||
sp_pcontext *m_ctx; // My parse context
|
||||
|
||||
// Should give each a name or type code for debugging purposes?
|
||||
sp_instr(uint ip)
|
||||
:Sql_alloc(), marked(0), free_list(0), m_ip(ip)
|
||||
sp_instr(uint ip, sp_pcontext *ctx)
|
||||
:Sql_alloc(), marked(0), free_list(0), m_ip(ip), m_ctx(ctx)
|
||||
{}
|
||||
|
||||
virtual ~sp_instr()
|
||||
|
@ -279,7 +281,7 @@ public:
|
|||
|
||||
virtual void print(String *str) = 0;
|
||||
|
||||
virtual void backpatch(uint dest, uint hpop, uint cpop)
|
||||
virtual void backpatch(uint dest, sp_pcontext *dst_ctx)
|
||||
{}
|
||||
|
||||
virtual uint opt_mark(sp_head *sp)
|
||||
|
@ -288,7 +290,7 @@ public:
|
|||
return m_ip+1;
|
||||
}
|
||||
|
||||
virtual uint opt_shortcut_jump(sp_head *sp)
|
||||
virtual uint opt_shortcut_jump(sp_head *sp, sp_instr *start)
|
||||
{
|
||||
return m_ip;
|
||||
}
|
||||
|
@ -311,8 +313,8 @@ class sp_instr_stmt : public sp_instr
|
|||
|
||||
public:
|
||||
|
||||
sp_instr_stmt(uint ip)
|
||||
: sp_instr(ip), m_lex(NULL)
|
||||
sp_instr_stmt(uint ip, sp_pcontext *ctx)
|
||||
: sp_instr(ip, ctx), m_lex(NULL)
|
||||
{}
|
||||
|
||||
virtual ~sp_instr_stmt();
|
||||
|
@ -353,8 +355,10 @@ public:
|
|||
|
||||
TABLE_LIST *tables;
|
||||
|
||||
sp_instr_set(uint ip, uint offset, Item *val, enum enum_field_types type)
|
||||
: sp_instr(ip), tables(NULL), m_offset(offset), m_value(val), m_type(type)
|
||||
sp_instr_set(uint ip, sp_pcontext *ctx,
|
||||
uint offset, Item *val, enum enum_field_types type)
|
||||
: sp_instr(ip, ctx),
|
||||
tables(NULL), m_offset(offset), m_value(val), m_type(type)
|
||||
{}
|
||||
|
||||
virtual ~sp_instr_set()
|
||||
|
@ -382,12 +386,12 @@ public:
|
|||
|
||||
uint m_dest; // Where we will go
|
||||
|
||||
sp_instr_jump(uint ip)
|
||||
: sp_instr(ip), m_dest(0), m_optdest(0)
|
||||
sp_instr_jump(uint ip, sp_pcontext *ctx)
|
||||
: sp_instr(ip, ctx), m_dest(0), m_optdest(0)
|
||||
{}
|
||||
|
||||
sp_instr_jump(uint ip, uint dest)
|
||||
: sp_instr(ip), m_dest(dest), m_optdest(0)
|
||||
sp_instr_jump(uint ip, sp_pcontext *ctx, uint dest)
|
||||
: sp_instr(ip, ctx), m_dest(dest), m_optdest(0)
|
||||
{}
|
||||
|
||||
virtual ~sp_instr_jump()
|
||||
|
@ -399,11 +403,11 @@ public:
|
|||
|
||||
virtual uint opt_mark(sp_head *sp);
|
||||
|
||||
virtual uint opt_shortcut_jump(sp_head *sp);
|
||||
virtual uint opt_shortcut_jump(sp_head *sp, sp_instr *start);
|
||||
|
||||
virtual void opt_move(uint dst, List<sp_instr> *ibp);
|
||||
|
||||
virtual void backpatch(uint dest, uint hpop, uint cpop)
|
||||
virtual void backpatch(uint dest, sp_pcontext *dst_ctx)
|
||||
{
|
||||
if (m_dest == 0) // Don't reset
|
||||
m_dest= dest;
|
||||
|
@ -425,12 +429,12 @@ public:
|
|||
|
||||
TABLE_LIST *tables;
|
||||
|
||||
sp_instr_jump_if(uint ip, Item *i)
|
||||
: sp_instr_jump(ip), tables(NULL), m_expr(i)
|
||||
sp_instr_jump_if(uint ip, sp_pcontext *ctx, Item *i)
|
||||
: sp_instr_jump(ip, ctx), tables(NULL), m_expr(i)
|
||||
{}
|
||||
|
||||
sp_instr_jump_if(uint ip, Item *i, uint dest)
|
||||
: sp_instr_jump(ip, dest), tables(NULL), m_expr(i)
|
||||
sp_instr_jump_if(uint ip, sp_pcontext *ctx, Item *i, uint dest)
|
||||
: sp_instr_jump(ip, ctx, dest), tables(NULL), m_expr(i)
|
||||
{}
|
||||
|
||||
virtual ~sp_instr_jump_if()
|
||||
|
@ -442,7 +446,7 @@ public:
|
|||
|
||||
virtual uint opt_mark(sp_head *sp);
|
||||
|
||||
virtual uint opt_shortcut_jump(sp_head *sp)
|
||||
virtual uint opt_shortcut_jump(sp_head *sp, sp_instr *start)
|
||||
{
|
||||
return m_ip;
|
||||
}
|
||||
|
@ -463,12 +467,12 @@ public:
|
|||
|
||||
TABLE_LIST *tables;
|
||||
|
||||
sp_instr_jump_if_not(uint ip, Item *i)
|
||||
: sp_instr_jump(ip), tables(NULL), m_expr(i)
|
||||
sp_instr_jump_if_not(uint ip, sp_pcontext *ctx, Item *i)
|
||||
: sp_instr_jump(ip, ctx), tables(NULL), m_expr(i)
|
||||
{}
|
||||
|
||||
sp_instr_jump_if_not(uint ip, Item *i, uint dest)
|
||||
: sp_instr_jump(ip, dest), tables(NULL), m_expr(i)
|
||||
sp_instr_jump_if_not(uint ip, sp_pcontext *ctx, Item *i, uint dest)
|
||||
: sp_instr_jump(ip, ctx, dest), tables(NULL), m_expr(i)
|
||||
{}
|
||||
|
||||
virtual ~sp_instr_jump_if_not()
|
||||
|
@ -480,7 +484,7 @@ public:
|
|||
|
||||
virtual uint opt_mark(sp_head *sp);
|
||||
|
||||
virtual uint opt_shortcut_jump(sp_head *sp)
|
||||
virtual uint opt_shortcut_jump(sp_head *sp, sp_instr *start)
|
||||
{
|
||||
return m_ip;
|
||||
}
|
||||
|
@ -501,8 +505,9 @@ public:
|
|||
|
||||
TABLE_LIST *tables;
|
||||
|
||||
sp_instr_freturn(uint ip, Item *val, enum enum_field_types type)
|
||||
: sp_instr(ip), tables(NULL), m_value(val), m_type(type)
|
||||
sp_instr_freturn(uint ip, sp_pcontext *ctx,
|
||||
Item *val, enum enum_field_types type)
|
||||
: sp_instr(ip, ctx), tables(NULL), m_value(val), m_type(type)
|
||||
{}
|
||||
|
||||
virtual ~sp_instr_freturn()
|
||||
|
@ -533,8 +538,8 @@ class sp_instr_hpush_jump : public sp_instr_jump
|
|||
|
||||
public:
|
||||
|
||||
sp_instr_hpush_jump(uint ip, int htype, uint fp)
|
||||
: sp_instr_jump(ip), m_type(htype), m_frame(fp)
|
||||
sp_instr_hpush_jump(uint ip, sp_pcontext *ctx, int htype, uint fp)
|
||||
: sp_instr_jump(ip, ctx), m_type(htype), m_frame(fp)
|
||||
{
|
||||
m_handler= ip+1;
|
||||
m_cond.empty();
|
||||
|
@ -551,7 +556,7 @@ public:
|
|||
|
||||
virtual uint opt_mark(sp_head *sp);
|
||||
|
||||
virtual uint opt_shortcut_jump(sp_head *sp)
|
||||
virtual uint opt_shortcut_jump(sp_head *sp, sp_instr *start)
|
||||
{
|
||||
return m_ip;
|
||||
}
|
||||
|
@ -578,8 +583,8 @@ class sp_instr_hpop : public sp_instr
|
|||
|
||||
public:
|
||||
|
||||
sp_instr_hpop(uint ip, uint count)
|
||||
: sp_instr(ip), m_count(count)
|
||||
sp_instr_hpop(uint ip, sp_pcontext *ctx, uint count)
|
||||
: sp_instr(ip, ctx), m_count(count)
|
||||
{}
|
||||
|
||||
virtual ~sp_instr_hpop()
|
||||
|
@ -589,13 +594,7 @@ public:
|
|||
|
||||
virtual void print(String *str);
|
||||
|
||||
virtual void backpatch(uint dest, uint hpop, uint cpop)
|
||||
{
|
||||
if (hpop > m_count)
|
||||
m_count= 0;
|
||||
else
|
||||
m_count-= hpop;
|
||||
}
|
||||
virtual void backpatch(uint dest, sp_pcontext *dst_ctx);
|
||||
|
||||
virtual uint opt_mark(sp_head *sp)
|
||||
{
|
||||
|
@ -618,8 +617,8 @@ class sp_instr_hreturn : public sp_instr
|
|||
|
||||
public:
|
||||
|
||||
sp_instr_hreturn(uint ip, uint fp)
|
||||
: sp_instr(ip), m_frame(fp)
|
||||
sp_instr_hreturn(uint ip, sp_pcontext *ctx, uint fp)
|
||||
: sp_instr(ip, ctx), m_frame(fp)
|
||||
{}
|
||||
|
||||
virtual ~sp_instr_hreturn()
|
||||
|
@ -649,8 +648,8 @@ class sp_instr_cpush : public sp_instr
|
|||
|
||||
public:
|
||||
|
||||
sp_instr_cpush(uint ip, LEX *lex)
|
||||
: sp_instr(ip), m_lex(lex)
|
||||
sp_instr_cpush(uint ip, sp_pcontext *ctx, LEX *lex)
|
||||
: sp_instr(ip, ctx), m_lex(lex)
|
||||
{}
|
||||
|
||||
virtual ~sp_instr_cpush();
|
||||
|
@ -673,8 +672,8 @@ class sp_instr_cpop : public sp_instr
|
|||
|
||||
public:
|
||||
|
||||
sp_instr_cpop(uint ip, uint count)
|
||||
: sp_instr(ip), m_count(count)
|
||||
sp_instr_cpop(uint ip, sp_pcontext *ctx, uint count)
|
||||
: sp_instr(ip, ctx), m_count(count)
|
||||
{}
|
||||
|
||||
virtual ~sp_instr_cpop()
|
||||
|
@ -684,13 +683,7 @@ public:
|
|||
|
||||
virtual void print(String *str);
|
||||
|
||||
virtual void backpatch(uint dest, uint hpop, uint cpop)
|
||||
{
|
||||
if (cpop > m_count)
|
||||
m_count= 0;
|
||||
else
|
||||
m_count-= cpop;
|
||||
}
|
||||
virtual void backpatch(uint dest, sp_pcontext *dst_ctx);
|
||||
|
||||
virtual uint opt_mark(sp_head *sp)
|
||||
{
|
||||
|
@ -713,8 +706,8 @@ class sp_instr_copen : public sp_instr_stmt
|
|||
|
||||
public:
|
||||
|
||||
sp_instr_copen(uint ip, uint c)
|
||||
: sp_instr_stmt(ip), m_cursor(c)
|
||||
sp_instr_copen(uint ip, sp_pcontext *ctx, uint c)
|
||||
: sp_instr_stmt(ip, ctx), m_cursor(c)
|
||||
{}
|
||||
|
||||
virtual ~sp_instr_copen()
|
||||
|
@ -738,8 +731,8 @@ class sp_instr_cclose : public sp_instr
|
|||
|
||||
public:
|
||||
|
||||
sp_instr_cclose(uint ip, uint c)
|
||||
: sp_instr(ip), m_cursor(c)
|
||||
sp_instr_cclose(uint ip, sp_pcontext *ctx, uint c)
|
||||
: sp_instr(ip, ctx), m_cursor(c)
|
||||
{}
|
||||
|
||||
virtual ~sp_instr_cclose()
|
||||
|
@ -763,8 +756,8 @@ class sp_instr_cfetch : public sp_instr
|
|||
|
||||
public:
|
||||
|
||||
sp_instr_cfetch(uint ip, uint c)
|
||||
: sp_instr(ip), m_cursor(c)
|
||||
sp_instr_cfetch(uint ip, sp_pcontext *ctx, uint c)
|
||||
: sp_instr(ip, ctx), m_cursor(c)
|
||||
{
|
||||
m_varlist.empty();
|
||||
}
|
||||
|
@ -796,8 +789,8 @@ class sp_instr_error : public sp_instr
|
|||
|
||||
public:
|
||||
|
||||
sp_instr_error(uint ip, int errcode)
|
||||
: sp_instr(ip), m_errcode(errcode)
|
||||
sp_instr_error(uint ip, sp_pcontext *ctx, int errcode)
|
||||
: sp_instr(ip, ctx), m_errcode(errcode)
|
||||
{}
|
||||
|
||||
virtual ~sp_instr_error()
|
||||
|
|
|
@ -26,78 +26,97 @@
|
|||
#include "sp_pcontext.h"
|
||||
#include "sp_head.h"
|
||||
|
||||
sp_pcontext::sp_pcontext()
|
||||
: Sql_alloc(), m_params(0), m_framesize(0), m_handlers(0), m_cursmax(0),
|
||||
m_hndlrlev(0)
|
||||
sp_pcontext::sp_pcontext(sp_pcontext *prev)
|
||||
: Sql_alloc(), m_psubsize(0), m_csubsize(0), m_hsubsize(0),
|
||||
m_parent(prev), m_handlers(0)
|
||||
{
|
||||
VOID(my_init_dynamic_array(&m_pvar, sizeof(sp_pvar_t *), 16, 8));
|
||||
VOID(my_init_dynamic_array(&m_cond, sizeof(sp_cond_type_t *), 16, 8));
|
||||
VOID(my_init_dynamic_array(&m_cursor, sizeof(LEX_STRING), 16, 8));
|
||||
VOID(my_init_dynamic_array(&m_scopes, sizeof(sp_scope_t), 16, 8));
|
||||
VOID(my_init_dynamic_array(&m_glabel, sizeof(sp_label_t *), 16, 8));
|
||||
m_label.empty();
|
||||
m_children.empty();
|
||||
if (!prev)
|
||||
m_poffset= m_coffset= 0;
|
||||
else
|
||||
{
|
||||
m_poffset= prev->current_pvars();
|
||||
m_coffset= prev->current_cursors();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
sp_pcontext::destroy()
|
||||
{
|
||||
List_iterator_fast<sp_pcontext> li(m_children);
|
||||
sp_pcontext *child;
|
||||
|
||||
while ((child= li++))
|
||||
child->destroy();
|
||||
|
||||
m_children.empty();
|
||||
m_label.empty();
|
||||
delete_dynamic(&m_pvar);
|
||||
delete_dynamic(&m_cond);
|
||||
delete_dynamic(&m_cursor);
|
||||
delete_dynamic(&m_scopes);
|
||||
delete_dynamic(&m_glabel);
|
||||
m_label.empty();
|
||||
}
|
||||
|
||||
void
|
||||
sp_pcontext::push_scope()
|
||||
sp_pcontext *
|
||||
sp_pcontext::push_context()
|
||||
{
|
||||
sp_scope_t s;
|
||||
sp_pcontext *child= new sp_pcontext(this);
|
||||
|
||||
s.vars= m_pvar.elements;
|
||||
s.conds= m_cond.elements;
|
||||
s.hndlrs= m_hndlrlev;
|
||||
s.curs= m_cursor.elements;
|
||||
s.glab= m_glabel.elements;
|
||||
insert_dynamic(&m_scopes, (gptr)&s);
|
||||
if (child)
|
||||
m_children.push_back(child);
|
||||
return child;
|
||||
}
|
||||
|
||||
void
|
||||
sp_pcontext::pop_scope(sp_scope_t *sp)
|
||||
sp_pcontext *
|
||||
sp_pcontext::pop_context()
|
||||
{
|
||||
byte *p= pop_dynamic(&m_scopes);
|
||||
uint submax= max_pvars();
|
||||
|
||||
if (sp && p)
|
||||
memcpy(sp, p, sizeof(sp_scope_t));
|
||||
if (submax > m_parent->m_psubsize)
|
||||
m_parent->m_psubsize= submax;
|
||||
submax= max_handlers();
|
||||
if (submax > m_parent->m_hsubsize)
|
||||
m_parent->m_hsubsize= submax;
|
||||
submax= max_cursors();
|
||||
if (submax > m_parent->m_csubsize)
|
||||
m_parent->m_csubsize= submax;
|
||||
return m_parent;
|
||||
}
|
||||
|
||||
void
|
||||
sp_pcontext::diff_scopes(uint sold, sp_scope_t *diffs)
|
||||
uint
|
||||
sp_pcontext::diff_handlers(sp_pcontext *ctx)
|
||||
{
|
||||
uint snew= m_scopes.elements;
|
||||
sp_scope_t scope;
|
||||
uint n= 0;
|
||||
sp_pcontext *pctx= this;
|
||||
|
||||
diffs->vars= diffs->conds= diffs->hndlrs= diffs->curs= diffs->glab= 0;
|
||||
while (snew-- > sold)
|
||||
while (pctx && pctx != ctx)
|
||||
{
|
||||
get_dynamic(&m_scopes, (gptr)&scope, snew);
|
||||
diffs->vars+= scope.vars;
|
||||
diffs->conds+= scope.conds;
|
||||
diffs->hndlrs+= scope.hndlrs;
|
||||
diffs->curs+= scope.curs;
|
||||
diffs->glab+= scope.glab;
|
||||
}
|
||||
if (sold)
|
||||
{
|
||||
get_dynamic(&m_scopes, (gptr)&scope, sold-1);
|
||||
diffs->vars-= scope.vars;
|
||||
diffs->conds-= scope.conds;
|
||||
diffs->hndlrs-= scope.hndlrs;
|
||||
diffs->curs-= scope.curs;
|
||||
diffs->glab-= scope.glab;
|
||||
n+= pctx->max_handlers();
|
||||
pctx= pctx->parent_context();
|
||||
}
|
||||
if (pctx)
|
||||
return n;
|
||||
return 0; // Didn't find ctx
|
||||
}
|
||||
|
||||
uint
|
||||
sp_pcontext::diff_cursors(sp_pcontext *ctx)
|
||||
{
|
||||
uint n= 0;
|
||||
sp_pcontext *pctx= this;
|
||||
|
||||
while (pctx && pctx != ctx)
|
||||
{
|
||||
n+= pctx->max_cursors();
|
||||
pctx= pctx->parent_context();
|
||||
}
|
||||
if (pctx)
|
||||
return n;
|
||||
return 0; // Didn't find ctx
|
||||
}
|
||||
|
||||
/* This does a linear search (from newer to older variables, in case
|
||||
** we have shadowed names).
|
||||
|
@ -109,20 +128,9 @@ sp_pcontext::diff_scopes(uint sold, sp_scope_t *diffs)
|
|||
sp_pvar_t *
|
||||
sp_pcontext::find_pvar(LEX_STRING *name, my_bool scoped)
|
||||
{
|
||||
uint i = m_pvar.elements;
|
||||
uint limit;
|
||||
uint i= m_pvar.elements;
|
||||
|
||||
if (! scoped || m_scopes.elements == 0)
|
||||
limit= 0;
|
||||
else
|
||||
{
|
||||
sp_scope_t s;
|
||||
|
||||
get_dynamic(&m_scopes, (gptr)&s, m_scopes.elements-1);
|
||||
limit= s.vars;
|
||||
}
|
||||
|
||||
while (i-- > limit)
|
||||
while (i--)
|
||||
{
|
||||
sp_pvar_t *p;
|
||||
|
||||
|
@ -134,6 +142,8 @@ sp_pcontext::find_pvar(LEX_STRING *name, my_bool scoped)
|
|||
return p;
|
||||
}
|
||||
}
|
||||
if (!scoped && m_parent)
|
||||
return m_parent->find_pvar(name, scoped);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -145,13 +155,13 @@ sp_pcontext::push_pvar(LEX_STRING *name, enum enum_field_types type,
|
|||
|
||||
if (p)
|
||||
{
|
||||
if (m_pvar.elements == m_framesize)
|
||||
m_framesize += 1;
|
||||
if (m_pvar.elements == m_psubsize)
|
||||
m_psubsize+= 1;
|
||||
p->name.str= name->str;
|
||||
p->name.length= name->length;
|
||||
p->type= type;
|
||||
p->mode= mode;
|
||||
p->offset= m_pvar.elements;
|
||||
p->offset= current_pvars();
|
||||
p->isset= (mode == sp_param_out ? FALSE : TRUE);
|
||||
p->dflt= NULL;
|
||||
insert_dynamic(&m_pvar, (gptr)&p);
|
||||
|
@ -168,7 +178,7 @@ sp_pcontext::push_label(char *name, uint ip)
|
|||
lab->name= name;
|
||||
lab->ip= ip;
|
||||
lab->type= SP_LAB_GOTO;
|
||||
lab->scopes= 0;
|
||||
lab->ctx= this;
|
||||
m_label.push_front(lab);
|
||||
}
|
||||
return lab;
|
||||
|
@ -184,6 +194,8 @@ sp_pcontext::find_label(char *name)
|
|||
if (my_strcasecmp(system_charset_info, name, lab->name) == 0)
|
||||
return lab;
|
||||
|
||||
if (m_parent)
|
||||
return m_parent->find_label(name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -207,20 +219,9 @@ sp_pcontext::push_cond(LEX_STRING *name, sp_cond_type_t *val)
|
|||
sp_cond_type_t *
|
||||
sp_pcontext::find_cond(LEX_STRING *name, my_bool scoped)
|
||||
{
|
||||
uint i = m_cond.elements;
|
||||
uint limit;
|
||||
uint i= m_cond.elements;
|
||||
|
||||
if (! scoped || m_scopes.elements == 0)
|
||||
limit= 0;
|
||||
else
|
||||
{
|
||||
sp_scope_t s;
|
||||
|
||||
get_dynamic(&m_scopes, (gptr)&s, m_scopes.elements-1);
|
||||
limit= s.conds;
|
||||
}
|
||||
|
||||
while (i-- > limit)
|
||||
while (i--)
|
||||
{
|
||||
sp_cond_t *p;
|
||||
|
||||
|
@ -232,6 +233,8 @@ sp_pcontext::find_cond(LEX_STRING *name, my_bool scoped)
|
|||
return p->val;
|
||||
}
|
||||
}
|
||||
if (!scoped && m_parent)
|
||||
return m_parent->find_cond(name, scoped);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -240,11 +243,11 @@ sp_pcontext::push_cursor(LEX_STRING *name)
|
|||
{
|
||||
LEX_STRING n;
|
||||
|
||||
if (m_cursor.elements == m_csubsize)
|
||||
m_csubsize+= 1;
|
||||
n.str= name->str;
|
||||
n.length= name->length;
|
||||
insert_dynamic(&m_cursor, (gptr)&n);
|
||||
if (m_cursor.elements > m_cursmax)
|
||||
m_cursmax= m_cursor.elements;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -253,20 +256,9 @@ sp_pcontext::push_cursor(LEX_STRING *name)
|
|||
my_bool
|
||||
sp_pcontext::find_cursor(LEX_STRING *name, uint *poff, my_bool scoped)
|
||||
{
|
||||
uint i = m_cursor.elements;
|
||||
uint limit;
|
||||
uint i= m_cursor.elements;
|
||||
|
||||
if (! scoped || m_scopes.elements == 0)
|
||||
limit= 0;
|
||||
else
|
||||
{
|
||||
sp_scope_t s;
|
||||
|
||||
get_dynamic(&m_scopes, (gptr)&s, m_scopes.elements-1);
|
||||
limit= s.curs;
|
||||
}
|
||||
|
||||
while (i-- > limit)
|
||||
while (i--)
|
||||
{
|
||||
LEX_STRING n;
|
||||
|
||||
|
@ -279,43 +271,7 @@ sp_pcontext::find_cursor(LEX_STRING *name, uint *poff, my_bool scoped)
|
|||
return TRUE;
|
||||
}
|
||||
}
|
||||
if (!scoped && m_parent)
|
||||
return m_parent->find_cursor(name, poff, scoped);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
sp_label_t *
|
||||
sp_pcontext::push_glabel(char *name, uint ip)
|
||||
{
|
||||
sp_label_t *lab = (sp_label_t *)sql_alloc(sizeof(sp_label_t));
|
||||
|
||||
if (lab)
|
||||
{
|
||||
lab->name= name;
|
||||
lab->ip= ip;
|
||||
lab->type= SP_LAB_GOTO;
|
||||
lab->scopes= 0;
|
||||
insert_dynamic(&m_glabel, (gptr)&lab);
|
||||
}
|
||||
return lab;
|
||||
}
|
||||
|
||||
sp_label_t *
|
||||
sp_pcontext::find_glabel(char *name)
|
||||
{
|
||||
uint i= m_glabel.elements;
|
||||
|
||||
while (i--)
|
||||
{
|
||||
sp_label_t *lab;
|
||||
|
||||
get_dynamic(&m_glabel, (gptr)&lab, i);
|
||||
if (my_strcasecmp(system_charset_info, name, lab->name) == 0)
|
||||
return lab;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
sp_pcontext::pop_glabel(uint count)
|
||||
{
|
||||
(void)pop_dynamic(&m_glabel);
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ typedef struct sp_label
|
|||
char *name;
|
||||
uint ip; // Instruction index
|
||||
int type; // begin/iter or ref/free
|
||||
uint scopes; // No. of scopes at label
|
||||
struct sp_pcontext *ctx; // The label's context
|
||||
} sp_label_t;
|
||||
|
||||
typedef struct sp_cond_type
|
||||
|
@ -66,11 +66,6 @@ typedef struct sp_cond
|
|||
sp_cond_type_t *val;
|
||||
} sp_cond_t;
|
||||
|
||||
typedef struct sp_scope
|
||||
{
|
||||
uint vars, conds, hndlrs, curs, glab;
|
||||
} sp_scope_t;
|
||||
|
||||
class sp_pcontext : public Sql_alloc
|
||||
{
|
||||
sp_pcontext(const sp_pcontext &); /* Prevent use of these */
|
||||
|
@ -78,28 +73,30 @@ class sp_pcontext : public Sql_alloc
|
|||
|
||||
public:
|
||||
|
||||
sp_pcontext();
|
||||
sp_pcontext(sp_pcontext *prev);
|
||||
|
||||
// Free memory
|
||||
void
|
||||
destroy();
|
||||
|
||||
// For error checking of duplicate things
|
||||
void
|
||||
push_scope();
|
||||
sp_pcontext *
|
||||
push_context();
|
||||
|
||||
void
|
||||
pop_scope(sp_scope_t *sp = 0);
|
||||
// Returns the previous context, not the one we pop
|
||||
sp_pcontext *
|
||||
pop_context();
|
||||
|
||||
uint
|
||||
scopes()
|
||||
sp_pcontext *
|
||||
parent_context()
|
||||
{
|
||||
return m_scopes.elements;
|
||||
return m_parent;
|
||||
}
|
||||
|
||||
// Sets '*diffs' to the differences between current scope index snew and sold
|
||||
void
|
||||
diff_scopes(uint sold, sp_scope_t *diffs);
|
||||
uint
|
||||
diff_handlers(sp_pcontext *ctx);
|
||||
|
||||
uint
|
||||
diff_cursors(sp_pcontext *ctx);
|
||||
|
||||
|
||||
//
|
||||
|
@ -107,28 +104,27 @@ class sp_pcontext : public Sql_alloc
|
|||
//
|
||||
|
||||
inline uint
|
||||
max_framesize()
|
||||
max_pvars()
|
||||
{
|
||||
return m_framesize;
|
||||
return m_psubsize + m_pvar.elements;
|
||||
}
|
||||
|
||||
inline uint
|
||||
current_framesize()
|
||||
current_pvars()
|
||||
{
|
||||
return m_poffset + m_pvar.elements;
|
||||
}
|
||||
|
||||
inline uint
|
||||
context_pvars()
|
||||
{
|
||||
return m_pvar.elements;
|
||||
}
|
||||
|
||||
inline uint
|
||||
params()
|
||||
pvar_context2index(uint i)
|
||||
{
|
||||
return m_params;
|
||||
}
|
||||
|
||||
// Set the number of parameters to the current esize
|
||||
inline void
|
||||
set_params()
|
||||
{
|
||||
m_params= m_pvar.elements;
|
||||
return m_poffset + i;
|
||||
}
|
||||
|
||||
inline void
|
||||
|
@ -199,7 +195,11 @@ class sp_pcontext : public Sql_alloc
|
|||
inline sp_label_t *
|
||||
last_label()
|
||||
{
|
||||
return m_label.head();
|
||||
sp_label_t *lab= m_label.head();
|
||||
|
||||
if (!lab && m_parent)
|
||||
lab= m_parent->last_label();
|
||||
return lab;
|
||||
}
|
||||
|
||||
inline sp_label_t *
|
||||
|
@ -236,23 +236,17 @@ class sp_pcontext : public Sql_alloc
|
|||
}
|
||||
|
||||
inline uint
|
||||
handlers()
|
||||
max_handlers()
|
||||
{
|
||||
return m_handlers;
|
||||
return m_hsubsize + m_handlers;
|
||||
}
|
||||
|
||||
inline void
|
||||
push_handlers(uint count)
|
||||
push_handlers(uint n)
|
||||
{
|
||||
m_hndlrlev+= count;
|
||||
m_handlers+= n;
|
||||
}
|
||||
|
||||
inline void
|
||||
pop_handlers(uint count)
|
||||
{
|
||||
m_hndlrlev-= count;
|
||||
}
|
||||
|
||||
//
|
||||
// Cursors
|
||||
//
|
||||
|
@ -263,48 +257,41 @@ class sp_pcontext : public Sql_alloc
|
|||
my_bool
|
||||
find_cursor(LEX_STRING *name, uint *poff, my_bool scoped=0);
|
||||
|
||||
inline void
|
||||
pop_cursor(uint num)
|
||||
inline uint
|
||||
max_cursors()
|
||||
{
|
||||
while (num--)
|
||||
pop_dynamic(&m_cursor);
|
||||
return m_csubsize + m_cursor.elements;
|
||||
}
|
||||
|
||||
inline uint
|
||||
cursors()
|
||||
current_cursors()
|
||||
{
|
||||
return m_cursmax;
|
||||
return m_coffset + m_cursor.elements;
|
||||
}
|
||||
|
||||
//
|
||||
// GOTO labels
|
||||
//
|
||||
protected:
|
||||
|
||||
sp_label_t *
|
||||
push_glabel(char *name, uint ip);
|
||||
|
||||
sp_label_t *
|
||||
find_glabel(char *name);
|
||||
|
||||
void
|
||||
pop_glabel(uint count);
|
||||
// The maximum sub context's framesizes
|
||||
uint m_psubsize;
|
||||
uint m_csubsize;
|
||||
uint m_hsubsize;
|
||||
|
||||
private:
|
||||
|
||||
uint m_params; // The number of parameters
|
||||
uint m_framesize; // The maximum framesize
|
||||
uint m_handlers; // The total number of handlers
|
||||
uint m_cursmax; // The maximum number of cursors
|
||||
uint m_hndlrlev; // Current number of active handlers
|
||||
sp_pcontext *m_parent; // Parent context
|
||||
|
||||
uint m_poffset; // Variable offset for this context
|
||||
uint m_coffset; // Cursor offset for this context
|
||||
uint m_handlers; // No. of handlers in this context
|
||||
|
||||
DYNAMIC_ARRAY m_pvar; // Parameters/variables
|
||||
DYNAMIC_ARRAY m_cond; // Conditions
|
||||
DYNAMIC_ARRAY m_cursor; // Cursors
|
||||
DYNAMIC_ARRAY m_scopes; // For error checking
|
||||
DYNAMIC_ARRAY m_glabel; // Goto labels
|
||||
|
||||
List<sp_label_t> m_label; // The label list
|
||||
|
||||
List<sp_pcontext> m_children; // Children contexts, used for destruction
|
||||
|
||||
}; // class sp_pcontext : public Sql_alloc
|
||||
|
||||
|
||||
|
|
167
sql/sql_yacc.yy
167
sql/sql_yacc.yy
|
@ -1169,7 +1169,6 @@ create:
|
|||
LEX *lex= Lex;
|
||||
|
||||
lex->sphead->m_param_end= lex->tok_start;
|
||||
lex->spcont->set_params();
|
||||
bzero((char *)&lex->sp_chistics, sizeof(st_sp_chistics));
|
||||
}
|
||||
sp_c_chistics
|
||||
|
@ -1258,7 +1257,6 @@ create_function_tail:
|
|||
{
|
||||
LEX *lex= Lex;
|
||||
|
||||
lex->spcont->set_params();
|
||||
lex->sphead->m_param_end= lex->tok_start;
|
||||
}
|
||||
RETURNS_SYM
|
||||
|
@ -1470,25 +1468,28 @@ sp_decl:
|
|||
DECLARE_SYM sp_decl_idents type sp_opt_default
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
uint max= lex->spcont->current_framesize();
|
||||
sp_pcontext *ctx= lex->spcont;
|
||||
uint max= ctx->context_pvars();
|
||||
enum enum_field_types type= (enum enum_field_types)$3;
|
||||
Item *it= $4;
|
||||
|
||||
for (uint i = max-$2 ; i < max ; i++)
|
||||
{
|
||||
lex->spcont->set_type(i, type);
|
||||
ctx->set_type(i, type);
|
||||
if (! it)
|
||||
lex->spcont->set_isset(i, FALSE);
|
||||
ctx->set_isset(i, FALSE);
|
||||
else
|
||||
{
|
||||
sp_instr_set *in= new sp_instr_set(lex->sphead->instructions(),
|
||||
i, it, type);
|
||||
ctx,
|
||||
ctx->pvar_context2index(i),
|
||||
it, type);
|
||||
|
||||
in->tables= lex->query_tables;
|
||||
lex->query_tables= 0;
|
||||
lex->sphead->add_instr(in);
|
||||
lex->spcont->set_isset(i, TRUE);
|
||||
lex->spcont->set_default(i, it);
|
||||
ctx->set_isset(i, TRUE);
|
||||
ctx->set_default(i, it);
|
||||
}
|
||||
}
|
||||
$$.vars= $2;
|
||||
|
@ -1514,30 +1515,33 @@ sp_decl:
|
|||
sp_head *sp= lex->sphead;
|
||||
sp_pcontext *ctx= lex->spcont;
|
||||
sp_instr_hpush_jump *i=
|
||||
new sp_instr_hpush_jump(sp->instructions(), $2,
|
||||
ctx->current_framesize());
|
||||
new sp_instr_hpush_jump(sp->instructions(), ctx, $2,
|
||||
ctx->current_pvars());
|
||||
|
||||
sp->add_instr(i);
|
||||
sp->push_backpatch(i, ctx->push_label((char *)"", 0));
|
||||
ctx->add_handler();
|
||||
sp->m_in_handler= TRUE;
|
||||
}
|
||||
sp_hcond_list sp_proc_stmt
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
sp_head *sp= lex->sphead;
|
||||
sp_pcontext *ctx= lex->spcont;
|
||||
sp_label_t *hlab= lex->spcont->pop_label(); /* After this hdlr */
|
||||
|
||||
if ($2 == SP_HANDLER_CONTINUE)
|
||||
sp->add_instr(new sp_instr_hreturn(sp->instructions(),
|
||||
lex->spcont->current_framesize()));
|
||||
sp->add_instr(new sp_instr_hreturn(sp->instructions(), ctx,
|
||||
ctx->current_pvars()));
|
||||
else
|
||||
{ /* EXIT or UNDO handler, just jump to the end of the block */
|
||||
sp_instr_jump *i= new sp_instr_jump(sp->instructions());
|
||||
sp_instr_jump *i= new sp_instr_jump(sp->instructions(), ctx);
|
||||
|
||||
sp->add_instr(i);
|
||||
sp->push_backpatch(i, lex->spcont->last_label()); /* Block end */
|
||||
}
|
||||
lex->sphead->backpatch(hlab);
|
||||
sp->m_in_handler= FALSE;
|
||||
$$.vars= $$.conds= $$.curs= 0;
|
||||
$$.hndlrs= $6;
|
||||
}
|
||||
|
@ -1545,19 +1549,19 @@ sp_decl:
|
|||
{
|
||||
LEX *lex= Lex;
|
||||
sp_head *sp= lex->sphead;
|
||||
sp_pcontext *spc= lex->spcont;
|
||||
sp_pcontext *ctx= lex->spcont;
|
||||
uint offp;
|
||||
sp_instr_cpush *i;
|
||||
|
||||
if (spc->find_cursor(&$2, &offp, TRUE))
|
||||
if (ctx->find_cursor(&$2, &offp, TRUE))
|
||||
{
|
||||
net_printf(YYTHD, ER_SP_DUP_CURS, $2.str);
|
||||
delete $5;
|
||||
YYABORT;
|
||||
}
|
||||
i= new sp_instr_cpush(sp->instructions(), $5);
|
||||
i= new sp_instr_cpush(sp->instructions(), ctx, $5);
|
||||
sp->add_instr(i);
|
||||
lex->spcont->push_cursor(&$2);
|
||||
ctx->push_cursor(&$2);
|
||||
$$.vars= $$.conds= $$.hndlrs= 0;
|
||||
$$.curs= 1;
|
||||
}
|
||||
|
@ -1748,7 +1752,8 @@ sp_proc_stmt:
|
|||
}
|
||||
else
|
||||
{
|
||||
sp_instr_stmt *i=new sp_instr_stmt(lex->sphead->instructions());
|
||||
sp_instr_stmt *i=new sp_instr_stmt(lex->sphead->instructions(),
|
||||
lex->spcont);
|
||||
|
||||
i->set_lex(lex);
|
||||
lex->sphead->add_instr(i);
|
||||
|
@ -1776,6 +1781,7 @@ sp_proc_stmt:
|
|||
YYABORT;
|
||||
}
|
||||
i= new sp_instr_freturn(lex->sphead->instructions(),
|
||||
lex->spcont,
|
||||
$2, lex->sphead->m_returns);
|
||||
lex->sphead->add_instr(i);
|
||||
lex->sphead->m_has_return= TRUE;
|
||||
|
@ -1794,8 +1800,9 @@ sp_proc_stmt:
|
|||
at the same frame level, so we then know that it's the
|
||||
top-most variable in the frame. */
|
||||
LEX *lex= Lex;
|
||||
uint offset= lex->spcont->current_framesize();
|
||||
uint offset= lex->spcont->current_pvars();
|
||||
sp_instr_set *i = new sp_instr_set(lex->sphead->instructions(),
|
||||
lex->spcont,
|
||||
offset, $2, MYSQL_TYPE_STRING);
|
||||
LEX_STRING dummy;
|
||||
|
||||
|
@ -1839,19 +1846,17 @@ sp_proc_stmt:
|
|||
else
|
||||
{
|
||||
uint ip= sp->instructions();
|
||||
sp_scope_t sdiff;
|
||||
sp_instr_jump *i;
|
||||
sp_instr_hpop *ih;
|
||||
sp_instr_cpop *ic;
|
||||
|
||||
ctx->diff_scopes(0, &sdiff);
|
||||
ih= new sp_instr_hpop(ip++, sdiff.hndlrs);
|
||||
ih= new sp_instr_hpop(ip++, ctx, 0);
|
||||
sp->push_backpatch(ih, lab);
|
||||
sp->add_instr(ih);
|
||||
ic= new sp_instr_cpop(ip++, sdiff.curs);
|
||||
ic= new sp_instr_cpop(ip++, ctx, 0);
|
||||
sp->push_backpatch(ic, lab);
|
||||
sp->add_instr(ic);
|
||||
i= new sp_instr_jump(ip);
|
||||
i= new sp_instr_jump(ip, ctx);
|
||||
sp->push_backpatch(i, lab); /* Jumping forward */
|
||||
sp->add_instr(i);
|
||||
}
|
||||
|
@ -1872,14 +1877,15 @@ sp_proc_stmt:
|
|||
{
|
||||
sp_instr_jump *i;
|
||||
uint ip= sp->instructions();
|
||||
sp_scope_t sdiff;
|
||||
uint n;
|
||||
|
||||
ctx->diff_scopes(lab->scopes, &sdiff);
|
||||
if (sdiff.hndlrs)
|
||||
sp->add_instr(new sp_instr_hpop(ip++, sdiff.hndlrs));
|
||||
if (sdiff.curs)
|
||||
sp->add_instr(new sp_instr_cpop(ip++, sdiff.curs));
|
||||
i= new sp_instr_jump(ip, lab->ip); /* Jump back */
|
||||
n= ctx->diff_handlers(lab->ctx);
|
||||
if (n)
|
||||
sp->add_instr(new sp_instr_hpop(ip++, ctx, n));
|
||||
n= ctx->diff_cursors(lab->ctx);
|
||||
if (n)
|
||||
sp->add_instr(new sp_instr_cpop(ip++, ctx, n));
|
||||
i= new sp_instr_jump(ip, ctx, lab->ip); /* Jump back */
|
||||
sp->add_instr(i);
|
||||
}
|
||||
}
|
||||
|
@ -1890,8 +1896,6 @@ sp_proc_stmt:
|
|||
sp_pcontext *ctx= lex->spcont;
|
||||
sp_label_t *lab= ctx->find_label($2.str);
|
||||
|
||||
if (! lab)
|
||||
lab= ctx->find_glabel($2.str);
|
||||
if (lab)
|
||||
{
|
||||
net_printf(YYTHD, ER_SP_LABEL_REDEFINE, $2.str);
|
||||
|
@ -1899,9 +1903,9 @@ sp_proc_stmt:
|
|||
}
|
||||
else
|
||||
{
|
||||
lab= ctx->push_glabel($2.str, sp->instructions());
|
||||
lab= ctx->push_label($2.str, sp->instructions());
|
||||
lab->type= SP_LAB_GOTO;
|
||||
lab->scopes= ctx->scopes();
|
||||
lab->ctx= ctx;
|
||||
sp->backpatch(lab);
|
||||
}
|
||||
}
|
||||
|
@ -1911,48 +1915,52 @@ sp_proc_stmt:
|
|||
sp_head *sp= lex->sphead;
|
||||
sp_pcontext *ctx= lex->spcont;
|
||||
uint ip= lex->sphead->instructions();
|
||||
sp_label_t *lab= ctx->find_label($2.str);
|
||||
sp_scope_t sdiff;
|
||||
sp_label_t *lab;
|
||||
sp_instr_jump *i;
|
||||
sp_instr_hpop *ih;
|
||||
sp_instr_cpop *ic;
|
||||
|
||||
if (! lab)
|
||||
lab= ctx->find_glabel($2.str);
|
||||
|
||||
if (sp->m_in_handler)
|
||||
{
|
||||
send_error(lex->thd, ER_SP_GOTO_IN_HNDLR);
|
||||
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->scopes= 0;
|
||||
lab->ctx= ctx;
|
||||
|
||||
ctx->diff_scopes(0, &sdiff);
|
||||
ih= new sp_instr_hpop(ip++, sdiff.hndlrs);
|
||||
ih= new sp_instr_hpop(ip++, ctx, 0);
|
||||
sp->push_backpatch(ih, lab);
|
||||
sp->add_instr(ih);
|
||||
ic= new sp_instr_cpop(ip++, sdiff.curs);
|
||||
ic= new sp_instr_cpop(ip++, ctx, 0);
|
||||
sp->add_instr(ic);
|
||||
sp->push_backpatch(ic, lab);
|
||||
i= new sp_instr_jump(ip);
|
||||
i= new sp_instr_jump(ip, ctx);
|
||||
sp->push_backpatch(i, lab); /* Jumping forward */
|
||||
sp->add_instr(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
ctx->diff_scopes(lab->scopes, &sdiff);
|
||||
if (sdiff.hndlrs)
|
||||
uint n;
|
||||
|
||||
n= ctx->diff_handlers(lab->ctx);
|
||||
if (n)
|
||||
{
|
||||
ih= new sp_instr_hpop(ip++, sdiff.hndlrs);
|
||||
ih= new sp_instr_hpop(ip++, ctx, n);
|
||||
sp->add_instr(ih);
|
||||
}
|
||||
if (sdiff.curs)
|
||||
n= ctx->diff_cursors(lab->ctx);
|
||||
if (n)
|
||||
{
|
||||
ic= new sp_instr_cpop(ip++, sdiff.curs);
|
||||
ic= new sp_instr_cpop(ip++, ctx, n);
|
||||
sp->add_instr(ic);
|
||||
}
|
||||
i= new sp_instr_jump(ip, lab->ip); /* Jump back */
|
||||
i= new sp_instr_jump(ip, ctx, lab->ip); /* Jump back */
|
||||
sp->add_instr(i);
|
||||
}
|
||||
}
|
||||
|
@ -1968,7 +1976,7 @@ sp_proc_stmt:
|
|||
net_printf(YYTHD, ER_SP_CURSOR_MISMATCH, $2.str);
|
||||
YYABORT;
|
||||
}
|
||||
i= new sp_instr_copen(sp->instructions(), offset);
|
||||
i= new sp_instr_copen(sp->instructions(), lex->spcont, offset);
|
||||
sp->add_instr(i);
|
||||
}
|
||||
| FETCH_SYM ident INTO
|
||||
|
@ -1983,7 +1991,7 @@ sp_proc_stmt:
|
|||
net_printf(YYTHD, ER_SP_CURSOR_MISMATCH, $2.str);
|
||||
YYABORT;
|
||||
}
|
||||
i= new sp_instr_cfetch(sp->instructions(), offset);
|
||||
i= new sp_instr_cfetch(sp->instructions(), lex->spcont, offset);
|
||||
sp->add_instr(i);
|
||||
}
|
||||
sp_fetch_list
|
||||
|
@ -2000,7 +2008,7 @@ sp_proc_stmt:
|
|||
net_printf(YYTHD, ER_SP_CURSOR_MISMATCH, $2.str);
|
||||
YYABORT;
|
||||
}
|
||||
i= new sp_instr_cclose(sp->instructions(), offset);
|
||||
i= new sp_instr_cclose(sp->instructions(), lex->spcont, offset);
|
||||
sp->add_instr(i);
|
||||
}
|
||||
;
|
||||
|
@ -2056,7 +2064,7 @@ sp_if:
|
|||
sp_head *sp= lex->sphead;
|
||||
sp_pcontext *ctx= lex->spcont;
|
||||
uint ip= sp->instructions();
|
||||
sp_instr_jump_if_not *i = new sp_instr_jump_if_not(ip, $1);
|
||||
sp_instr_jump_if_not *i = new sp_instr_jump_if_not(ip, ctx, $1);
|
||||
|
||||
i->tables= lex->query_tables;
|
||||
lex->query_tables= 0;
|
||||
|
@ -2068,7 +2076,7 @@ sp_if:
|
|||
sp_head *sp= Lex->sphead;
|
||||
sp_pcontext *ctx= Lex->spcont;
|
||||
uint ip= sp->instructions();
|
||||
sp_instr_jump *i = new sp_instr_jump(ip);
|
||||
sp_instr_jump *i = new sp_instr_jump(ip, ctx);
|
||||
|
||||
sp->add_instr(i);
|
||||
sp->backpatch(ctx->pop_label());
|
||||
|
@ -2098,7 +2106,7 @@ sp_case:
|
|||
sp_instr_jump_if_not *i;
|
||||
|
||||
if (! sp->m_simple_case)
|
||||
i= new sp_instr_jump_if_not(ip, $1);
|
||||
i= new sp_instr_jump_if_not(ip, ctx, $1);
|
||||
else
|
||||
{ /* Simple case: <caseval> = <whenval> */
|
||||
LEX_STRING ivar;
|
||||
|
@ -2106,10 +2114,10 @@ sp_case:
|
|||
ivar.str= (char *)"_tmp_";
|
||||
ivar.length= 5;
|
||||
Item *var= (Item*) new Item_splocal(ivar,
|
||||
ctx->current_framesize()-1);
|
||||
ctx->current_pvars()-1);
|
||||
Item *expr= new Item_func_eq(var, $1);
|
||||
|
||||
i= new sp_instr_jump_if_not(ip, expr);
|
||||
i= new sp_instr_jump_if_not(ip, ctx, expr);
|
||||
lex->variables_used= 1;
|
||||
}
|
||||
sp->push_backpatch(i, ctx->push_label((char *)"", 0));
|
||||
|
@ -2122,7 +2130,7 @@ sp_case:
|
|||
sp_head *sp= Lex->sphead;
|
||||
sp_pcontext *ctx= Lex->spcont;
|
||||
uint ip= sp->instructions();
|
||||
sp_instr_jump *i = new sp_instr_jump(ip);
|
||||
sp_instr_jump *i = new sp_instr_jump(ip, ctx);
|
||||
|
||||
sp->add_instr(i);
|
||||
sp->backpatch(ctx->pop_label());
|
||||
|
@ -2141,7 +2149,8 @@ sp_whens:
|
|||
{
|
||||
sp_head *sp= Lex->sphead;
|
||||
uint ip= sp->instructions();
|
||||
sp_instr_error *i= new sp_instr_error(ip, ER_SP_CASE_NOT_FOUND);
|
||||
sp_instr_error *i= new sp_instr_error(ip, Lex->spcont,
|
||||
ER_SP_CASE_NOT_FOUND);
|
||||
|
||||
sp->add_instr(i);
|
||||
}
|
||||
|
@ -2166,7 +2175,6 @@ sp_labeled_control:
|
|||
lab= lex->spcont->push_label($1.str,
|
||||
lex->sphead->instructions());
|
||||
lab->type= SP_LAB_ITER;
|
||||
lab->scopes= ctx->scopes();
|
||||
}
|
||||
}
|
||||
sp_unlabeled_control sp_opt_label
|
||||
|
@ -2204,32 +2212,24 @@ sp_unlabeled_control:
|
|||
sp_label_t *lab= lex->spcont->last_label();
|
||||
|
||||
lab->type= SP_LAB_BEGIN;
|
||||
/* Scope duplicate checking */
|
||||
lex->spcont->push_scope();
|
||||
lex->spcont= lex->spcont->push_context();
|
||||
}
|
||||
sp_decls
|
||||
{
|
||||
Lex->spcont->push_handlers($3.hndlrs);
|
||||
}
|
||||
sp_proc_stmts
|
||||
END
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
sp_head *sp= lex->sphead;
|
||||
sp_pcontext *ctx= lex->spcont;
|
||||
sp_scope_t scope;
|
||||
|
||||
sp->backpatch(ctx->last_label()); /* We always have a label */
|
||||
ctx->pop_pvar($3.vars);
|
||||
ctx->pop_cond($3.conds);
|
||||
ctx->pop_handlers($3.hndlrs);
|
||||
ctx->pop_cursor($3.curs);
|
||||
if ($3.hndlrs)
|
||||
sp->add_instr(new sp_instr_hpop(sp->instructions(), $3.hndlrs));
|
||||
sp->add_instr(new sp_instr_hpop(sp->instructions(), ctx,
|
||||
$3.hndlrs));
|
||||
if ($3.curs)
|
||||
sp->add_instr(new sp_instr_cpop(sp->instructions(), $3.curs));
|
||||
ctx->pop_scope(&scope);
|
||||
ctx->pop_glabel(scope.glab);
|
||||
sp->add_instr(new sp_instr_cpop(sp->instructions(), ctx,
|
||||
$3.curs));
|
||||
lex->spcont= ctx->pop_context();
|
||||
}
|
||||
| LOOP_SYM
|
||||
sp_proc_stmts END LOOP_SYM
|
||||
|
@ -2237,7 +2237,7 @@ sp_unlabeled_control:
|
|||
LEX *lex= Lex;
|
||||
uint ip= lex->sphead->instructions();
|
||||
sp_label_t *lab= lex->spcont->last_label(); /* Jumping back */
|
||||
sp_instr_jump *i = new sp_instr_jump(ip, lab->ip);
|
||||
sp_instr_jump *i = new sp_instr_jump(ip, lex->spcont, lab->ip);
|
||||
|
||||
lex->sphead->add_instr(i);
|
||||
}
|
||||
|
@ -2246,7 +2246,8 @@ sp_unlabeled_control:
|
|||
LEX *lex= Lex;
|
||||
sp_head *sp= lex->sphead;
|
||||
uint ip= sp->instructions();
|
||||
sp_instr_jump_if_not *i = new sp_instr_jump_if_not(ip, $2);
|
||||
sp_instr_jump_if_not *i = new sp_instr_jump_if_not(ip, lex->spcont,
|
||||
$2);
|
||||
|
||||
/* Jumping forward */
|
||||
sp->push_backpatch(i, lex->spcont->last_label());
|
||||
|
@ -2259,7 +2260,7 @@ sp_unlabeled_control:
|
|||
LEX *lex= Lex;
|
||||
uint ip= lex->sphead->instructions();
|
||||
sp_label_t *lab= lex->spcont->last_label(); /* Jumping back */
|
||||
sp_instr_jump *i = new sp_instr_jump(ip, lab->ip);
|
||||
sp_instr_jump *i = new sp_instr_jump(ip, lex->spcont, lab->ip);
|
||||
|
||||
lex->sphead->add_instr(i);
|
||||
}
|
||||
|
@ -2268,7 +2269,8 @@ sp_unlabeled_control:
|
|||
LEX *lex= Lex;
|
||||
uint ip= lex->sphead->instructions();
|
||||
sp_label_t *lab= lex->spcont->last_label(); /* Jumping back */
|
||||
sp_instr_jump_if_not *i = new sp_instr_jump_if_not(ip, $4, lab->ip);
|
||||
sp_instr_jump_if_not *i = new sp_instr_jump_if_not(ip, lex->spcont,
|
||||
$4, lab->ip);
|
||||
|
||||
i->tables= lex->query_tables;
|
||||
lex->query_tables= 0;
|
||||
|
@ -6786,11 +6788,12 @@ option_value:
|
|||
}
|
||||
else
|
||||
{ /* An SP local variable */
|
||||
sp_pcontext *ctx= lex->spcont;
|
||||
sp_pvar_t *spv;
|
||||
sp_instr_set *i;
|
||||
Item *it;
|
||||
|
||||
spv= lex->spcont->find_pvar(&$1.base_name);
|
||||
spv= ctx->find_pvar(&$1.base_name);
|
||||
|
||||
if ($3)
|
||||
it= $3;
|
||||
|
@ -6798,7 +6801,7 @@ option_value:
|
|||
it= spv->dflt;
|
||||
else
|
||||
it= new Item_null();
|
||||
i= new sp_instr_set(lex->sphead->instructions(),
|
||||
i= new sp_instr_set(lex->sphead->instructions(), ctx,
|
||||
spv->offset, it, spv->type);
|
||||
i->tables= lex->query_tables;
|
||||
lex->query_tables= 0;
|
||||
|
|
Loading…
Reference in a new issue