mirror of
				https://github.com/MariaDB/server.git
				synced 2025-10-30 04:26:45 +03:00 
			
		
		
		
	******
This patch fixes the following bugs:
  - Bug#5889: Exit handler for a warning doesn't hide the warning in
    trigger
  - Bug#9857: Stored procedures: handler for sqlwarning ignored
  - Bug#23032: Handlers declared in a SP do not handle warnings generated
    in sub-SP
  - Bug#36185: Incorrect precedence for warning and exception handlers
The problem was in the way warnings/errors during stored routine execution
were handled. Prior to this patch the logic was as follows:
  - when a warning/an error happens: if we're executing a stored routine,
    and there is a handler for that warning/error, remember the handler,
    ignore the warning/error and continue execution.
  - after a stored routine instruction is executed: check for a remembered
    handler and activate one (if any).
This logic caused several problems:
  - if one instruction generates several warnings (errors) it's impossible
    to choose the right handler -- a handler for the first generated
    condition was chosen and remembered for activation.
  - mess with handling conditions in scopes different from the current one.
  - not putting generated warnings/errors into Warning Info (Diagnostic
    Area) is against The Standard.
The patch changes the logic as follows:
  - Diagnostic Area is cleared on the beginning of each statement that
    either is able to generate warnings, or is able to work with tables.
  - at the end of a stored routine instruction, Diagnostic Area is left
    intact.
  - Diagnostic Area is checked after each stored routine instruction. If
    an instruction generates several condition, it's now possible to take a
    look at all of them and determine an appropriate handler.
mysql-test/r/signal.result:
  Update result file:
    1. handled conditions are not cleared any more;
    2. reflect changes in signal.test
mysql-test/r/signal_demo3.result:
  Update result file: handled conditions are not cleared any more.
  Due to playing with max_error_count, resulting warning lists
  have changed.
mysql-test/r/sp-big.result:
  Update result file: handled conditions are not cleared any more.
mysql-test/r/sp-bugs.result:
  Update result file: handled conditions are not cleared any more.
mysql-test/r/sp-code.result:
  Update result file:
    1. handled conditions are not cleared any more.
    2. add result for a new test case in sp-code.test.
mysql-test/r/sp-error.result:
  Update result file:
    1. handled conditions are not cleared any more.
    2. add result for a new test case in sp-error.test.
mysql-test/r/sp.result:
  Update result file: handled conditions are not cleared any more.
mysql-test/r/sp_trans.result:
  Update result file: handled conditions are not cleared any more.
mysql-test/r/strict.result:
  Update result file: handled conditions are not cleared any more.
mysql-test/r/view.result:
  Update result file: handled conditions are not cleared any more.
mysql-test/suite/funcs_1/r/innodb_storedproc_02.result:
  Update result file: handled conditions are not cleared any more.
mysql-test/suite/funcs_1/r/memory_storedproc_02.result:
  Update result file: handled conditions are not cleared any more.
mysql-test/suite/funcs_1/r/myisam_storedproc_02.result:
  Update result file: handled conditions are not cleared any more.
mysql-test/suite/funcs_1/r/storedproc.result:
  Update result file: handled conditions are not cleared any more.
mysql-test/suite/rpl/r/rpl_row_sp005.result:
  Update result file: handled conditions are not cleared any more.
mysql-test/suite/rpl/r/rpl_row_sp006_InnoDB.result:
  Update result file: handled conditions are not cleared any more.
mysql-test/suite/rpl/r/rpl_row_trig003.result:
  Update result file: handled conditions are not cleared any more.
mysql-test/t/signal.test:
  Make a test case more readable in the result file.
mysql-test/t/sp-code.test:
  Add a test case for Bug#23032 checking that
  No Data takes precedence on Warning.
mysql-test/t/sp-error.test:
  Adding test cases for:
    - Bug#23032
    - Bug#36185
    - Bug#5889
    - Bug#9857
mysql-test/t/sp.test:
  Fixing test case to reflect behavioral changes made by the patch.
sql/sp_head.cc:
  Reset the per-statement warning count before executing
  a stored procedure instruction.
  
  Move to a separate function code which checks the
  completion status of the executed statement and searches
  for a handler.
  
  Remove redundant code now that search for a handler is
  done after execution, errors are always pushed.
sql/sp_pcontext.h:
  Remove unused code.
sql/sp_rcontext.cc:
  - Polish sp_rcontext::find_handler(): use sp_rcontext::m_hfound instead
    of an extra local variable;
  
  - Remove sp_rcontext::handle_condition();
  
  - Introduce sp_rcontext::activate_handler(), which prepares
    previously found handler for execution.
  
  - Move sp_rcontext::enter_handler() code into activate_handler(),
    because enter_handler() is used only from there;
  
  - Cleanups;
  
  - Introduce DBUG_EXECUTE_IF() for a test case in sp-code.test
sql/sp_rcontext.h:
  - Remove unused code
  - Cleanups
sql/sql_class.cc:
  Merge THD::raise_condition_no_handler() into THD::raise_condition().
  After the patch raise_condition_no_handler() was called
  in raise_condition() only.
sql/sql_class.h:
  Remove raise_condition_no_handler().
sql/sql_error.cc:
  Remove Warning_info::reserve_space() -- handled conditions are not
  cleared any more, so there is no need for RESIGNAL to re-push them.
sql/sql_error.h:
  Remove Warning_info::reserve_space().
sql/sql_signal.cc:
  Handled conditions are not cleared any more,
  so there is no need for RESIGNAL to re-push them.
		
	
		
			
				
	
	
		
			948 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			948 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| drop procedure if exists empty;
 | |
| drop procedure if exists code_sample;
 | |
| create procedure empty()
 | |
| begin
 | |
| end;
 | |
| show procedure code empty;
 | |
| Pos	Instruction
 | |
| drop procedure empty;
 | |
| create function almost_empty()
 | |
| returns int
 | |
| return 0;
 | |
| show function code almost_empty;
 | |
| Pos	Instruction
 | |
| 0	freturn 3 0
 | |
| drop function almost_empty;
 | |
| create procedure code_sample(x int, out err int, out nulls int)
 | |
| begin
 | |
| declare count int default 0;
 | |
| set nulls = 0;
 | |
| begin
 | |
| declare c cursor for select name from t1;
 | |
| declare exit handler for not found close c;
 | |
| open c;
 | |
| loop
 | |
| begin
 | |
| declare n varchar(20);
 | |
| declare continue handler for sqlexception set err=1;
 | |
| fetch c into n;
 | |
| if isnull(n) then
 | |
| set nulls = nulls + 1;
 | |
| else
 | |
| set count = count + 1;
 | |
| update t2 set idx = count where name=n;
 | |
| end if;
 | |
| end;
 | |
| end loop;
 | |
| end;
 | |
| select t.name, t.idx from t2 t order by idx asc;
 | |
| end//
 | |
| show procedure code code_sample;
 | |
| Pos	Instruction
 | |
| 0	set count@3 0
 | |
| 1	set nulls@2 0
 | |
| 2	cpush c@0
 | |
| 3	hpush_jump 6 4 EXIT
 | |
| 4	cclose c@0
 | |
| 5	hreturn 0 19
 | |
| 6	copen c@0
 | |
| 7	set n@4 NULL
 | |
| 8	hpush_jump 11 5 CONTINUE
 | |
| 9	set err@1 1
 | |
| 10	hreturn 5
 | |
| 11	cfetch c@0 n@4
 | |
| 12	jump_if_not 15(17) isnull(n@4)
 | |
| 13	set nulls@2 (nulls@2 + 1)
 | |
| 14	jump 17
 | |
| 15	set count@3 (count@3 + 1)
 | |
| 16	stmt 4 "update t2 set idx = count where name=n"
 | |
| 17	hpop 1
 | |
| 18	jump 7
 | |
| 19	hpop 1
 | |
| 20	cpop 1
 | |
| 21	stmt 0 "select t.name, t.idx from t2 t order ..."
 | |
| drop procedure code_sample;
 | |
| drop procedure if exists sudoku_solve;
 | |
| create procedure sudoku_solve(p_naive boolean, p_all boolean)
 | |
| deterministic
 | |
| modifies sql data
 | |
| begin
 | |
| drop temporary table if exists sudoku_work, sudoku_schedule;
 | |
| create temporary table sudoku_work
 | |
| (
 | |
| row smallint not null,
 | |
| col smallint not null,
 | |
| dig smallint not null,
 | |
| cnt smallint,
 | |
| key using btree (cnt),
 | |
| key using btree (row),
 | |
| key using btree (col),
 | |
| unique key using hash (row,col)
 | |
| );
 | |
| create temporary table sudoku_schedule
 | |
| (
 | |
| idx int not null auto_increment primary key,
 | |
| row smallint not null,
 | |
| col smallint not null
 | |
| );
 | |
| call sudoku_init();
 | |
| if p_naive then
 | |
| update sudoku_work set cnt = 0 where dig = 0;
 | |
| else
 | |
| call sudoku_count();
 | |
| end if;
 | |
| insert into sudoku_schedule (row,col)
 | |
| select row,col from sudoku_work where cnt is not null order by cnt desc;
 | |
| begin
 | |
| declare v_scounter bigint default 0;
 | |
| declare v_i smallint default 1;
 | |
| declare v_dig smallint;
 | |
| declare v_schedmax smallint;
 | |
| select count(*) into v_schedmax from sudoku_schedule;
 | |
| more: 
 | |
| loop
 | |
| begin
 | |
| declare v_tcounter bigint default 0;
 | |
| sched:
 | |
| while v_i <= v_schedmax do
 | |
| begin
 | |
| declare v_row, v_col smallint;
 | |
| select row,col into v_row,v_col from sudoku_schedule where v_i = idx;
 | |
| select dig into v_dig from sudoku_work
 | |
| where v_row = row and v_col = col;
 | |
| case v_dig
 | |
| when 0 then
 | |
| set v_dig = 1;
 | |
| update sudoku_work set dig = 1
 | |
| where v_row = row and v_col = col;
 | |
| when 9 then
 | |
| if v_i > 0 then
 | |
| update sudoku_work set dig = 0
 | |
| where v_row = row and v_col = col;
 | |
| set v_i = v_i - 1;
 | |
| iterate sched;
 | |
| else
 | |
| select v_scounter as 'Solutions';
 | |
| leave more;
 | |
| end if;
 | |
| else
 | |
| set v_dig = v_dig + 1;
 | |
| update sudoku_work set dig = v_dig
 | |
| where v_row = row and v_col = col;
 | |
| end case;
 | |
| set v_tcounter = v_tcounter + 1;
 | |
| if not sudoku_digit_ok(v_row, v_col, v_dig) then
 | |
| iterate sched;
 | |
| end if;
 | |
| set v_i = v_i + 1;
 | |
| end;
 | |
| end while sched;
 | |
| select dig from sudoku_work;
 | |
| select v_tcounter as 'Tests';
 | |
| set v_scounter = v_scounter + 1;
 | |
| if p_all and v_i > 0 then
 | |
| set v_i = v_i - 1;
 | |
| else
 | |
| leave more;
 | |
| end if;
 | |
| end;
 | |
| end loop more;
 | |
| end;
 | |
| drop temporary table sudoku_work, sudoku_schedule;
 | |
| end//
 | |
| show procedure code sudoku_solve;
 | |
| Pos	Instruction
 | |
| 0	stmt 9 "drop temporary table if exists sudoku..."
 | |
| 1	stmt 1 "create temporary table sudoku_work ( ..."
 | |
| 2	stmt 1 "create temporary table sudoku_schedul..."
 | |
| 3	stmt 89 "call sudoku_init()"
 | |
| 4	jump_if_not 7(8) p_naive@0
 | |
| 5	stmt 4 "update sudoku_work set cnt = 0 where ..."
 | |
| 6	jump 8
 | |
| 7	stmt 89 "call sudoku_count()"
 | |
| 8	stmt 6 "insert into sudoku_schedule (row,col)..."
 | |
| 9	set v_scounter@2 0
 | |
| 10	set v_i@3 1
 | |
| 11	set v_dig@4 NULL
 | |
| 12	set v_schedmax@5 NULL
 | |
| 13	stmt 0 "select count(*) into v_schedmax from ..."
 | |
| 14	set v_tcounter@6 0
 | |
| 15	jump_if_not 39(39) (v_i@3 <= v_schedmax@5)
 | |
| 16	set v_row@7 NULL
 | |
| 17	set v_col@8 NULL
 | |
| 18	stmt 0 "select row,col into v_row,v_col from ..."
 | |
| 19	stmt 0 "select dig into v_dig from sudoku_wor..."
 | |
| 20	set_case_expr (34) 0 v_dig@4
 | |
| 21	jump_if_not 25(34) (case_expr@0 = 0)
 | |
| 22	set v_dig@4 1
 | |
| 23	stmt 4 "update sudoku_work set dig = 1 where ..."
 | |
| 24	jump 34
 | |
| 25	jump_if_not 32(34) (case_expr@0 = 9)
 | |
| 26	jump_if_not 30(34) (v_i@3 > 0)
 | |
| 27	stmt 4 "update sudoku_work set dig = 0 where ..."
 | |
| 28	set v_i@3 (v_i@3 - 1)
 | |
| 29	jump 15
 | |
| 30	stmt 0 "select v_scounter as 'Solutions'"
 | |
| 31	jump 45
 | |
| 32	set v_dig@4 (v_dig@4 + 1)
 | |
| 33	stmt 4 "update sudoku_work set dig = v_dig wh..."
 | |
| 34	set v_tcounter@6 (v_tcounter@6 + 1)
 | |
| 35	jump_if_not 37(37) (not(`sudoku_digit_ok`(v_row@7,v_col@8,v_dig@4)))
 | |
| 36	jump 15
 | |
| 37	set v_i@3 (v_i@3 + 1)
 | |
| 38	jump 15
 | |
| 39	stmt 0 "select dig from sudoku_work"
 | |
| 40	stmt 0 "select v_tcounter as 'Tests'"
 | |
| 41	set v_scounter@2 (v_scounter@2 + 1)
 | |
| 42	jump_if_not 45(14) (p_all@1 and (v_i@3 > 0))
 | |
| 43	set v_i@3 (v_i@3 - 1)
 | |
| 44	jump 14
 | |
| 45	stmt 9 "drop temporary table sudoku_work, sud..."
 | |
| drop procedure sudoku_solve;
 | |
| DROP PROCEDURE IF EXISTS proc_19194_simple;
 | |
| DROP PROCEDURE IF EXISTS proc_19194_searched;
 | |
| DROP PROCEDURE IF EXISTS proc_19194_nested_1;
 | |
| DROP PROCEDURE IF EXISTS proc_19194_nested_2;
 | |
| DROP PROCEDURE IF EXISTS proc_19194_nested_3;
 | |
| DROP PROCEDURE IF EXISTS proc_19194_nested_4;
 | |
| CREATE PROCEDURE proc_19194_simple(i int)
 | |
| BEGIN
 | |
| DECLARE str CHAR(10);
 | |
| CASE i
 | |
| WHEN 1 THEN SET str="1";
 | |
| WHEN 2 THEN SET str="2";
 | |
| WHEN 3 THEN SET str="3";
 | |
| ELSE SET str="unknown";
 | |
| END CASE;
 | |
| SELECT str;
 | |
| END|
 | |
| CREATE PROCEDURE proc_19194_searched(i int)
 | |
| BEGIN
 | |
| DECLARE str CHAR(10);
 | |
| CASE
 | |
| WHEN i=1 THEN SET str="1";
 | |
| WHEN i=2 THEN SET str="2";
 | |
| WHEN i=3 THEN SET str="3";
 | |
| ELSE SET str="unknown";
 | |
| END CASE;
 | |
| SELECT str;
 | |
| END|
 | |
| CREATE PROCEDURE proc_19194_nested_1(i int, j int)
 | |
| BEGIN
 | |
| DECLARE str_i CHAR(10);
 | |
| DECLARE str_j CHAR(10);
 | |
| CASE i
 | |
| WHEN 10 THEN SET str_i="10";
 | |
| WHEN 20 THEN
 | |
| BEGIN
 | |
| set str_i="20";
 | |
| CASE
 | |
| WHEN j=1 THEN SET str_j="1";
 | |
| WHEN j=2 THEN SET str_j="2";
 | |
| WHEN j=3 THEN SET str_j="3";
 | |
| ELSE SET str_j="unknown";
 | |
| END CASE;
 | |
| select "i was 20";
 | |
| END;
 | |
| WHEN 30 THEN SET str_i="30";
 | |
| WHEN 40 THEN SET str_i="40";
 | |
| ELSE SET str_i="unknown";
 | |
| END CASE;
 | |
| SELECT str_i, str_j;
 | |
| END|
 | |
| CREATE PROCEDURE proc_19194_nested_2(i int, j int)
 | |
| BEGIN
 | |
| DECLARE str_i CHAR(10);
 | |
| DECLARE str_j CHAR(10);
 | |
| CASE
 | |
| WHEN i=10 THEN SET str_i="10";
 | |
| WHEN i=20 THEN
 | |
| BEGIN
 | |
| set str_i="20";
 | |
| CASE j
 | |
| WHEN 1 THEN SET str_j="1";
 | |
| WHEN 2 THEN SET str_j="2";
 | |
| WHEN 3 THEN SET str_j="3";
 | |
| ELSE SET str_j="unknown";
 | |
| END CASE;
 | |
| select "i was 20";
 | |
| END;
 | |
| WHEN i=30 THEN SET str_i="30";
 | |
| WHEN i=40 THEN SET str_i="40";
 | |
| ELSE SET str_i="unknown";
 | |
| END CASE;
 | |
| SELECT str_i, str_j;
 | |
| END|
 | |
| CREATE PROCEDURE proc_19194_nested_3(i int, j int)
 | |
| BEGIN
 | |
| DECLARE str_i CHAR(10);
 | |
| DECLARE str_j CHAR(10);
 | |
| CASE i
 | |
| WHEN 10 THEN SET str_i="10";
 | |
| WHEN 20 THEN
 | |
| BEGIN
 | |
| set str_i="20";
 | |
| CASE j
 | |
| WHEN 1 THEN SET str_j="1";
 | |
| WHEN 2 THEN SET str_j="2";
 | |
| WHEN 3 THEN SET str_j="3";
 | |
| ELSE SET str_j="unknown";
 | |
| END CASE;
 | |
| select "i was 20";
 | |
| END;
 | |
| WHEN 30 THEN SET str_i="30";
 | |
| WHEN 40 THEN SET str_i="40";
 | |
| ELSE SET str_i="unknown";
 | |
| END CASE;
 | |
| SELECT str_i, str_j;
 | |
| END|
 | |
| CREATE PROCEDURE proc_19194_nested_4(i int, j int)
 | |
| BEGIN
 | |
| DECLARE str_i CHAR(10);
 | |
| DECLARE str_j CHAR(10);
 | |
| CASE
 | |
| WHEN i=10 THEN SET str_i="10";
 | |
| WHEN i=20 THEN
 | |
| BEGIN
 | |
| set str_i="20";
 | |
| CASE
 | |
| WHEN j=1 THEN SET str_j="1";
 | |
| WHEN j=2 THEN SET str_j="2";
 | |
| WHEN j=3 THEN SET str_j="3";
 | |
| ELSE SET str_j="unknown";
 | |
| END CASE;
 | |
| select "i was 20";
 | |
| END;
 | |
| WHEN i=30 THEN SET str_i="30";
 | |
| WHEN i=40 THEN SET str_i="40";
 | |
| ELSE SET str_i="unknown";
 | |
| END CASE;
 | |
| SELECT str_i, str_j;
 | |
| END|
 | |
| SHOW PROCEDURE CODE proc_19194_simple;
 | |
| Pos	Instruction
 | |
| 0	set str@1 NULL
 | |
| 1	set_case_expr (12) 0 i@0
 | |
| 2	jump_if_not 5(12) (case_expr@0 = 1)
 | |
| 3	set str@1 '1'
 | |
| 4	jump 12
 | |
| 5	jump_if_not 8(12) (case_expr@0 = 2)
 | |
| 6	set str@1 '2'
 | |
| 7	jump 12
 | |
| 8	jump_if_not 11(12) (case_expr@0 = 3)
 | |
| 9	set str@1 '3'
 | |
| 10	jump 12
 | |
| 11	set str@1 'unknown'
 | |
| 12	stmt 0 "SELECT str"
 | |
| SHOW PROCEDURE CODE proc_19194_searched;
 | |
| Pos	Instruction
 | |
| 0	set str@1 NULL
 | |
| 1	jump_if_not 4(11) (i@0 = 1)
 | |
| 2	set str@1 '1'
 | |
| 3	jump 11
 | |
| 4	jump_if_not 7(11) (i@0 = 2)
 | |
| 5	set str@1 '2'
 | |
| 6	jump 11
 | |
| 7	jump_if_not 10(11) (i@0 = 3)
 | |
| 8	set str@1 '3'
 | |
| 9	jump 11
 | |
| 10	set str@1 'unknown'
 | |
| 11	stmt 0 "SELECT str"
 | |
| SHOW PROCEDURE CODE proc_19194_nested_1;
 | |
| Pos	Instruction
 | |
| 0	set str_i@2 NULL
 | |
| 1	set str_j@3 NULL
 | |
| 2	set_case_expr (27) 0 i@0
 | |
| 3	jump_if_not 6(27) (case_expr@0 = 10)
 | |
| 4	set str_i@2 '10'
 | |
| 5	jump 27
 | |
| 6	jump_if_not 20(27) (case_expr@0 = 20)
 | |
| 7	set str_i@2 '20'
 | |
| 8	jump_if_not 11(18) (j@1 = 1)
 | |
| 9	set str_j@3 '1'
 | |
| 10	jump 18
 | |
| 11	jump_if_not 14(18) (j@1 = 2)
 | |
| 12	set str_j@3 '2'
 | |
| 13	jump 18
 | |
| 14	jump_if_not 17(18) (j@1 = 3)
 | |
| 15	set str_j@3 '3'
 | |
| 16	jump 18
 | |
| 17	set str_j@3 'unknown'
 | |
| 18	stmt 0 "select "i was 20""
 | |
| 19	jump 27
 | |
| 20	jump_if_not 23(27) (case_expr@0 = 30)
 | |
| 21	set str_i@2 '30'
 | |
| 22	jump 27
 | |
| 23	jump_if_not 26(27) (case_expr@0 = 40)
 | |
| 24	set str_i@2 '40'
 | |
| 25	jump 27
 | |
| 26	set str_i@2 'unknown'
 | |
| 27	stmt 0 "SELECT str_i, str_j"
 | |
| SHOW PROCEDURE CODE proc_19194_nested_2;
 | |
| Pos	Instruction
 | |
| 0	set str_i@2 NULL
 | |
| 1	set str_j@3 NULL
 | |
| 2	jump_if_not 5(27) (i@0 = 10)
 | |
| 3	set str_i@2 '10'
 | |
| 4	jump 27
 | |
| 5	jump_if_not 20(27) (i@0 = 20)
 | |
| 6	set str_i@2 '20'
 | |
| 7	set_case_expr (18) 0 j@1
 | |
| 8	jump_if_not 11(18) (case_expr@0 = 1)
 | |
| 9	set str_j@3 '1'
 | |
| 10	jump 18
 | |
| 11	jump_if_not 14(18) (case_expr@0 = 2)
 | |
| 12	set str_j@3 '2'
 | |
| 13	jump 18
 | |
| 14	jump_if_not 17(18) (case_expr@0 = 3)
 | |
| 15	set str_j@3 '3'
 | |
| 16	jump 18
 | |
| 17	set str_j@3 'unknown'
 | |
| 18	stmt 0 "select "i was 20""
 | |
| 19	jump 27
 | |
| 20	jump_if_not 23(27) (i@0 = 30)
 | |
| 21	set str_i@2 '30'
 | |
| 22	jump 27
 | |
| 23	jump_if_not 26(27) (i@0 = 40)
 | |
| 24	set str_i@2 '40'
 | |
| 25	jump 27
 | |
| 26	set str_i@2 'unknown'
 | |
| 27	stmt 0 "SELECT str_i, str_j"
 | |
| SHOW PROCEDURE CODE proc_19194_nested_3;
 | |
| Pos	Instruction
 | |
| 0	set str_i@2 NULL
 | |
| 1	set str_j@3 NULL
 | |
| 2	set_case_expr (28) 0 i@0
 | |
| 3	jump_if_not 6(28) (case_expr@0 = 10)
 | |
| 4	set str_i@2 '10'
 | |
| 5	jump 28
 | |
| 6	jump_if_not 21(28) (case_expr@0 = 20)
 | |
| 7	set str_i@2 '20'
 | |
| 8	set_case_expr (19) 1 j@1
 | |
| 9	jump_if_not 12(19) (case_expr@1 = 1)
 | |
| 10	set str_j@3 '1'
 | |
| 11	jump 19
 | |
| 12	jump_if_not 15(19) (case_expr@1 = 2)
 | |
| 13	set str_j@3 '2'
 | |
| 14	jump 19
 | |
| 15	jump_if_not 18(19) (case_expr@1 = 3)
 | |
| 16	set str_j@3 '3'
 | |
| 17	jump 19
 | |
| 18	set str_j@3 'unknown'
 | |
| 19	stmt 0 "select "i was 20""
 | |
| 20	jump 28
 | |
| 21	jump_if_not 24(28) (case_expr@0 = 30)
 | |
| 22	set str_i@2 '30'
 | |
| 23	jump 28
 | |
| 24	jump_if_not 27(28) (case_expr@0 = 40)
 | |
| 25	set str_i@2 '40'
 | |
| 26	jump 28
 | |
| 27	set str_i@2 'unknown'
 | |
| 28	stmt 0 "SELECT str_i, str_j"
 | |
| SHOW PROCEDURE CODE proc_19194_nested_4;
 | |
| Pos	Instruction
 | |
| 0	set str_i@2 NULL
 | |
| 1	set str_j@3 NULL
 | |
| 2	jump_if_not 5(26) (i@0 = 10)
 | |
| 3	set str_i@2 '10'
 | |
| 4	jump 26
 | |
| 5	jump_if_not 19(26) (i@0 = 20)
 | |
| 6	set str_i@2 '20'
 | |
| 7	jump_if_not 10(17) (j@1 = 1)
 | |
| 8	set str_j@3 '1'
 | |
| 9	jump 17
 | |
| 10	jump_if_not 13(17) (j@1 = 2)
 | |
| 11	set str_j@3 '2'
 | |
| 12	jump 17
 | |
| 13	jump_if_not 16(17) (j@1 = 3)
 | |
| 14	set str_j@3 '3'
 | |
| 15	jump 17
 | |
| 16	set str_j@3 'unknown'
 | |
| 17	stmt 0 "select "i was 20""
 | |
| 18	jump 26
 | |
| 19	jump_if_not 22(26) (i@0 = 30)
 | |
| 20	set str_i@2 '30'
 | |
| 21	jump 26
 | |
| 22	jump_if_not 25(26) (i@0 = 40)
 | |
| 23	set str_i@2 '40'
 | |
| 24	jump 26
 | |
| 25	set str_i@2 'unknown'
 | |
| 26	stmt 0 "SELECT str_i, str_j"
 | |
| CALL proc_19194_nested_1(10, 1);
 | |
| str_i	str_j
 | |
| 10	NULL
 | |
| CALL proc_19194_nested_1(25, 1);
 | |
| str_i	str_j
 | |
| unknown	NULL
 | |
| CALL proc_19194_nested_1(20, 1);
 | |
| i was 20
 | |
| i was 20
 | |
| str_i	str_j
 | |
| 20	1
 | |
| CALL proc_19194_nested_1(20, 2);
 | |
| i was 20
 | |
| i was 20
 | |
| str_i	str_j
 | |
| 20	2
 | |
| CALL proc_19194_nested_1(20, 3);
 | |
| i was 20
 | |
| i was 20
 | |
| str_i	str_j
 | |
| 20	3
 | |
| CALL proc_19194_nested_1(20, 4);
 | |
| i was 20
 | |
| i was 20
 | |
| str_i	str_j
 | |
| 20	unknown
 | |
| CALL proc_19194_nested_1(30, 1);
 | |
| str_i	str_j
 | |
| 30	NULL
 | |
| CALL proc_19194_nested_1(40, 1);
 | |
| str_i	str_j
 | |
| 40	NULL
 | |
| CALL proc_19194_nested_1(0, 0);
 | |
| str_i	str_j
 | |
| unknown	NULL
 | |
| CALL proc_19194_nested_2(10, 1);
 | |
| str_i	str_j
 | |
| 10	NULL
 | |
| CALL proc_19194_nested_2(25, 1);
 | |
| str_i	str_j
 | |
| unknown	NULL
 | |
| CALL proc_19194_nested_2(20, 1);
 | |
| i was 20
 | |
| i was 20
 | |
| str_i	str_j
 | |
| 20	1
 | |
| CALL proc_19194_nested_2(20, 2);
 | |
| i was 20
 | |
| i was 20
 | |
| str_i	str_j
 | |
| 20	2
 | |
| CALL proc_19194_nested_2(20, 3);
 | |
| i was 20
 | |
| i was 20
 | |
| str_i	str_j
 | |
| 20	3
 | |
| CALL proc_19194_nested_2(20, 4);
 | |
| i was 20
 | |
| i was 20
 | |
| str_i	str_j
 | |
| 20	unknown
 | |
| CALL proc_19194_nested_2(30, 1);
 | |
| str_i	str_j
 | |
| 30	NULL
 | |
| CALL proc_19194_nested_2(40, 1);
 | |
| str_i	str_j
 | |
| 40	NULL
 | |
| CALL proc_19194_nested_2(0, 0);
 | |
| str_i	str_j
 | |
| unknown	NULL
 | |
| CALL proc_19194_nested_3(10, 1);
 | |
| str_i	str_j
 | |
| 10	NULL
 | |
| CALL proc_19194_nested_3(25, 1);
 | |
| str_i	str_j
 | |
| unknown	NULL
 | |
| CALL proc_19194_nested_3(20, 1);
 | |
| i was 20
 | |
| i was 20
 | |
| str_i	str_j
 | |
| 20	1
 | |
| CALL proc_19194_nested_3(20, 2);
 | |
| i was 20
 | |
| i was 20
 | |
| str_i	str_j
 | |
| 20	2
 | |
| CALL proc_19194_nested_3(20, 3);
 | |
| i was 20
 | |
| i was 20
 | |
| str_i	str_j
 | |
| 20	3
 | |
| CALL proc_19194_nested_3(20, 4);
 | |
| i was 20
 | |
| i was 20
 | |
| str_i	str_j
 | |
| 20	unknown
 | |
| CALL proc_19194_nested_3(30, 1);
 | |
| str_i	str_j
 | |
| 30	NULL
 | |
| CALL proc_19194_nested_3(40, 1);
 | |
| str_i	str_j
 | |
| 40	NULL
 | |
| CALL proc_19194_nested_3(0, 0);
 | |
| str_i	str_j
 | |
| unknown	NULL
 | |
| CALL proc_19194_nested_4(10, 1);
 | |
| str_i	str_j
 | |
| 10	NULL
 | |
| CALL proc_19194_nested_4(25, 1);
 | |
| str_i	str_j
 | |
| unknown	NULL
 | |
| CALL proc_19194_nested_4(20, 1);
 | |
| i was 20
 | |
| i was 20
 | |
| str_i	str_j
 | |
| 20	1
 | |
| CALL proc_19194_nested_4(20, 2);
 | |
| i was 20
 | |
| i was 20
 | |
| str_i	str_j
 | |
| 20	2
 | |
| CALL proc_19194_nested_4(20, 3);
 | |
| i was 20
 | |
| i was 20
 | |
| str_i	str_j
 | |
| 20	3
 | |
| CALL proc_19194_nested_4(20, 4);
 | |
| i was 20
 | |
| i was 20
 | |
| str_i	str_j
 | |
| 20	unknown
 | |
| CALL proc_19194_nested_4(30, 1);
 | |
| str_i	str_j
 | |
| 30	NULL
 | |
| CALL proc_19194_nested_4(40, 1);
 | |
| str_i	str_j
 | |
| 40	NULL
 | |
| CALL proc_19194_nested_4(0, 0);
 | |
| str_i	str_j
 | |
| unknown	NULL
 | |
| DROP PROCEDURE proc_19194_simple;
 | |
| DROP PROCEDURE proc_19194_searched;
 | |
| DROP PROCEDURE proc_19194_nested_1;
 | |
| DROP PROCEDURE proc_19194_nested_2;
 | |
| DROP PROCEDURE proc_19194_nested_3;
 | |
| DROP PROCEDURE proc_19194_nested_4;
 | |
| DROP PROCEDURE IF EXISTS p1;
 | |
| CREATE PROCEDURE p1() CREATE INDEX idx ON t1 (c1);
 | |
| SHOW PROCEDURE CODE p1;
 | |
| Pos	Instruction
 | |
| 0	stmt 2 "CREATE INDEX idx ON t1 (c1)"
 | |
| DROP PROCEDURE p1;
 | |
| drop table if exists t1;
 | |
| drop procedure if exists proc_26977_broken;
 | |
| drop procedure if exists proc_26977_works;
 | |
| create table t1(a int unique);
 | |
| create procedure proc_26977_broken(v int)
 | |
| begin
 | |
| declare i int default 5;
 | |
| declare continue handler for sqlexception
 | |
| begin
 | |
| select 'caught something';
 | |
| retry:
 | |
| while i > 0 do
 | |
| begin
 | |
| set i = i - 1;
 | |
| select 'looping', i;
 | |
| end;
 | |
| end while retry;
 | |
| end;
 | |
| select 'do something';
 | |
| insert into t1 values (v);
 | |
| select 'do something again';
 | |
| insert into t1 values (v);
 | |
| end//
 | |
| create procedure proc_26977_works(v int)
 | |
| begin
 | |
| declare i int default 5;
 | |
| declare continue handler for sqlexception
 | |
| begin
 | |
| select 'caught something';
 | |
| retry:
 | |
| while i > 0 do
 | |
| begin
 | |
| set i = i - 1;
 | |
| select 'looping', i;
 | |
| end;
 | |
| end while retry;
 | |
| select 'optimizer: keep hreturn';
 | |
| end;
 | |
| select 'do something';
 | |
| insert into t1 values (v);
 | |
| select 'do something again';
 | |
| insert into t1 values (v);
 | |
| end//
 | |
| show procedure code proc_26977_broken;
 | |
| Pos	Instruction
 | |
| 0	set i@1 5
 | |
| 1	hpush_jump 8 2 CONTINUE
 | |
| 2	stmt 0 "select 'caught something'"
 | |
| 3	jump_if_not 7(7) (i@1 > 0)
 | |
| 4	set i@1 (i@1 - 1)
 | |
| 5	stmt 0 "select 'looping', i"
 | |
| 6	jump 3
 | |
| 7	hreturn 2
 | |
| 8	stmt 0 "select 'do something'"
 | |
| 9	stmt 5 "insert into t1 values (v)"
 | |
| 10	stmt 0 "select 'do something again'"
 | |
| 11	stmt 5 "insert into t1 values (v)"
 | |
| 12	hpop 1
 | |
| show procedure code proc_26977_works;
 | |
| Pos	Instruction
 | |
| 0	set i@1 5
 | |
| 1	hpush_jump 9 2 CONTINUE
 | |
| 2	stmt 0 "select 'caught something'"
 | |
| 3	jump_if_not 7(7) (i@1 > 0)
 | |
| 4	set i@1 (i@1 - 1)
 | |
| 5	stmt 0 "select 'looping', i"
 | |
| 6	jump 3
 | |
| 7	stmt 0 "select 'optimizer: keep hreturn'"
 | |
| 8	hreturn 2
 | |
| 9	stmt 0 "select 'do something'"
 | |
| 10	stmt 5 "insert into t1 values (v)"
 | |
| 11	stmt 0 "select 'do something again'"
 | |
| 12	stmt 5 "insert into t1 values (v)"
 | |
| 13	hpop 1
 | |
| call proc_26977_broken(1);
 | |
| do something
 | |
| do something
 | |
| do something again
 | |
| do something again
 | |
| caught something
 | |
| caught something
 | |
| looping	i
 | |
| looping	4
 | |
| looping	i
 | |
| looping	3
 | |
| looping	i
 | |
| looping	2
 | |
| looping	i
 | |
| looping	1
 | |
| looping	i
 | |
| looping	0
 | |
| Warnings:
 | |
| Error	1062	Duplicate entry '1' for key 'a'
 | |
| call proc_26977_works(2);
 | |
| do something
 | |
| do something
 | |
| do something again
 | |
| do something again
 | |
| caught something
 | |
| caught something
 | |
| looping	i
 | |
| looping	4
 | |
| looping	i
 | |
| looping	3
 | |
| looping	i
 | |
| looping	2
 | |
| looping	i
 | |
| looping	1
 | |
| looping	i
 | |
| looping	0
 | |
| optimizer: keep hreturn
 | |
| optimizer: keep hreturn
 | |
| Warnings:
 | |
| Error	1062	Duplicate entry '2' for key 'a'
 | |
| drop table t1;
 | |
| drop procedure proc_26977_broken;
 | |
| drop procedure proc_26977_works;
 | |
| drop procedure if exists proc_33618_h;
 | |
| drop procedure if exists proc_33618_c;
 | |
| create procedure proc_33618_h(num int)
 | |
| begin
 | |
| declare count1 int default '0';
 | |
| declare vb varchar(30);
 | |
| declare last_row int;
 | |
| while(num>=1) do
 | |
| set num=num-1;
 | |
| begin
 | |
| declare cur1 cursor for select `a` from t_33618;
 | |
| declare continue handler for not found set last_row = 1;
 | |
| set last_row:=0;
 | |
| open cur1;
 | |
| rep1:
 | |
| repeat
 | |
| begin
 | |
| declare exit handler for 1062 begin end;
 | |
| fetch cur1 into vb;
 | |
| if (last_row = 1) then
 | |
| ## should generate a hpop instruction here
 | |
| leave rep1;
 | |
| end if;
 | |
| end;
 | |
| until last_row=1
 | |
| end repeat;
 | |
| close cur1;
 | |
| end;
 | |
| end while;
 | |
| end//
 | |
| create procedure proc_33618_c(num int)
 | |
| begin
 | |
| declare count1 int default '0';
 | |
| declare vb varchar(30);
 | |
| declare last_row int;
 | |
| while(num>=1) do
 | |
| set num=num-1;
 | |
| begin
 | |
| declare cur1 cursor for select `a` from t_33618;
 | |
| declare continue handler for not found set last_row = 1;
 | |
| set last_row:=0;
 | |
| open cur1;
 | |
| rep1:
 | |
| repeat
 | |
| begin
 | |
| declare cur2 cursor for select `b` from t_33618;
 | |
| fetch cur1 into vb;
 | |
| if (last_row = 1) then
 | |
| ## should generate a cpop instruction here
 | |
| leave rep1;
 | |
| end if;
 | |
| end;
 | |
| until last_row=1
 | |
| end repeat;
 | |
| close cur1;
 | |
| end;
 | |
| end while;
 | |
| end//
 | |
| show procedure code proc_33618_h;
 | |
| Pos	Instruction
 | |
| 0	set count1@1 '0'
 | |
| 1	set vb@2 NULL
 | |
| 2	set last_row@3 NULL
 | |
| 3	jump_if_not 24(24) (num@0 >= 1)
 | |
| 4	set num@0 (num@0 - 1)
 | |
| 5	cpush cur1@0
 | |
| 6	hpush_jump 9 4 CONTINUE
 | |
| 7	set last_row@3 1
 | |
| 8	hreturn 4
 | |
| 9	set last_row@3 0
 | |
| 10	copen cur1@0
 | |
| 11	hpush_jump 13 4 EXIT
 | |
| 12	hreturn 0 17
 | |
| 13	cfetch cur1@0 vb@2
 | |
| 14	jump_if_not 17(17) (last_row@3 = 1)
 | |
| 15	hpop 1
 | |
| 16	jump 19
 | |
| 17	hpop 1
 | |
| 18	jump_if_not 11(19) (last_row@3 = 1)
 | |
| 19	cclose cur1@0
 | |
| 20	hpop 1
 | |
| 21	cpop 1
 | |
| 22	jump 3
 | |
| show procedure code proc_33618_c;
 | |
| Pos	Instruction
 | |
| 0	set count1@1 '0'
 | |
| 1	set vb@2 NULL
 | |
| 2	set last_row@3 NULL
 | |
| 3	jump_if_not 23(23) (num@0 >= 1)
 | |
| 4	set num@0 (num@0 - 1)
 | |
| 5	cpush cur1@0
 | |
| 6	hpush_jump 9 4 CONTINUE
 | |
| 7	set last_row@3 1
 | |
| 8	hreturn 4
 | |
| 9	set last_row@3 0
 | |
| 10	copen cur1@0
 | |
| 11	cpush cur2@1
 | |
| 12	cfetch cur1@0 vb@2
 | |
| 13	jump_if_not 16(16) (last_row@3 = 1)
 | |
| 14	cpop 1
 | |
| 15	jump 18
 | |
| 16	cpop 1
 | |
| 17	jump_if_not 11(18) (last_row@3 = 1)
 | |
| 18	cclose cur1@0
 | |
| 19	hpop 1
 | |
| 20	cpop 1
 | |
| 21	jump 3
 | |
| drop procedure proc_33618_h;
 | |
| drop procedure proc_33618_c;
 | |
| drop procedure if exists p_20906_a;
 | |
| drop procedure if exists p_20906_b;
 | |
| create procedure p_20906_a() SET @a=@a+1, @b=@b+1;
 | |
| show procedure code p_20906_a;
 | |
| Pos	Instruction
 | |
| 0	stmt 31 "SET @a=@a+1"
 | |
| 1	stmt 31 "SET  @b=@b+1"
 | |
| set @a=1;
 | |
| set @b=1;
 | |
| call p_20906_a();
 | |
| select @a, @b;
 | |
| @a	@b
 | |
| 2	2
 | |
| create procedure p_20906_b() SET @a=@a+1, @b=@b+1, @c=@c+1;
 | |
| show procedure code p_20906_b;
 | |
| Pos	Instruction
 | |
| 0	stmt 31 "SET @a=@a+1"
 | |
| 1	stmt 31 "SET  @b=@b+1"
 | |
| 2	stmt 31 "SET  @c=@c+1"
 | |
| set @a=1;
 | |
| set @b=1;
 | |
| set @c=1;
 | |
| call p_20906_b();
 | |
| select @a, @b, @c;
 | |
| @a	@b	@c
 | |
| 2	2	2
 | |
| drop procedure p_20906_a;
 | |
| drop procedure p_20906_b;
 | |
| End of 5.0 tests.
 | |
| CREATE PROCEDURE p1() 
 | |
| BEGIN 
 | |
| DECLARE dummy int default 0;
 | |
| CASE 12 
 | |
| WHEN 12 
 | |
| THEN SET dummy = 0;
 | |
| END CASE;
 | |
| END//
 | |
| SHOW PROCEDURE CODE p1;
 | |
| Pos	Instruction
 | |
| 0	set dummy@0 0
 | |
| 1	set_case_expr (6) 0 12
 | |
| 2	jump_if_not 5(6) (case_expr@0 = 12)
 | |
| 3	set dummy@0 0
 | |
| 4	jump 6
 | |
| 5	error 1339
 | |
| DROP PROCEDURE p1;
 | |
| #
 | |
| # Bug#23032: Handlers declared in a SP do not handle warnings generated in sub-SP
 | |
| #
 | |
| 
 | |
| # - Case 4: check that "No Data trumps Warning".
 | |
| 
 | |
| CREATE TABLE t1(a INT);
 | |
| INSERT INTO t1 VALUES (1), (2), (3);
 | |
| CREATE PROCEDURE p1()
 | |
| BEGIN
 | |
| DECLARE c CURSOR FOR SELECT a FROM t1;
 | |
| OPEN c;
 | |
| BEGIN
 | |
| DECLARE v INT;
 | |
| DECLARE CONTINUE HANDLER FOR SQLWARNING
 | |
| BEGIN
 | |
| SELECT "Warning found!";
 | |
| SHOW WARNINGS;
 | |
| END;
 | |
| DECLARE EXIT HANDLER FOR NOT FOUND
 | |
| BEGIN
 | |
| SELECT "End of Result Set found!";
 | |
| SHOW WARNINGS;
 | |
| END;
 | |
| WHILE TRUE DO
 | |
| FETCH c INTO v;
 | |
| END WHILE;
 | |
| END;
 | |
| CLOSE c;
 | |
| SELECT a INTO @foo FROM t1 LIMIT 1; # Clear warning stack
 | |
| END|
 | |
| SET SESSION debug="+d,bug23032_emit_warning";
 | |
| CALL p1();
 | |
| Warning found!
 | |
| Warning found!
 | |
| Level	Code	Message
 | |
| Warning	1105	Unknown error
 | |
| Warning found!
 | |
| Warning found!
 | |
| Level	Code	Message
 | |
| Warning	1105	Unknown error
 | |
| Warning found!
 | |
| Warning found!
 | |
| Level	Code	Message
 | |
| Warning	1105	Unknown error
 | |
| End of Result Set found!
 | |
| End of Result Set found!
 | |
| Level	Code	Message
 | |
| Warning	1105	Unknown error
 | |
| Error	1329	No data - zero rows fetched, selected, or processed
 | |
| SET SESSION debug="-d,bug23032_emit_warning";
 | |
| DROP PROCEDURE p1;
 | |
| DROP TABLE t1;
 |