diff options
author | Alexander Nozdrin <alik@sun.com> | 2010-07-30 19:28:36 +0400 |
---|---|---|
committer | Alexander Nozdrin <alik@sun.com> | 2010-07-30 19:28:36 +0400 |
commit | a0ab253fbd622429beab6027cd532e3f203188be (patch) | |
tree | eaf5cc36760b4d96b253469ba54007facdbf1bf1 /mysql-test/t/sp-error.test | |
parent | 727da39fcd32ce2668efb3cac78237a51931c0cf (diff) | |
download | mariadb-git-a0ab253fbd622429beab6027cd532e3f203188be.tar.gz |
Auto-merge from mysql-trunk-bugfixing.
******
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.
Diffstat (limited to 'mysql-test/t/sp-error.test')
-rw-r--r-- | mysql-test/t/sp-error.test | 270 |
1 files changed, 270 insertions, 0 deletions
diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test index c8b2595e23d..13ca55a0127 100644 --- a/mysql-test/t/sp-error.test +++ b/mysql-test/t/sp-error.test @@ -2543,3 +2543,273 @@ DROP TABLE t1; --echo End of 5.1 tests +--echo # +--echo # Bug#23032: Handlers declared in a SP do not handle warnings generated in sub-SP +--echo # + +--echo +--echo # - Case 1 +--echo + +--disable_warnings +DROP PROCEDURE IF EXISTS p1; +DROP PROCEDURE IF EXISTS p2; +DROP PROCEDURE IF EXISTS p3; +DROP PROCEDURE IF EXISTS p4; +DROP PROCEDURE IF EXISTS p5; +DROP PROCEDURE IF EXISTS p6; +--enable_warnings + +delimiter |; + +CREATE PROCEDURE p1() + BEGIN + SELECT CAST('10 ' as unsigned integer); + SELECT 1; + CALL p2(); + END| + +CREATE PROCEDURE p2() + BEGIN + SELECT CAST('10 ' as unsigned integer); + END| + +delimiter ;| + +CALL p1(); + +DROP PROCEDURE p1; +DROP PROCEDURE p2; + +--echo +--echo # - Case 2 +--echo + +delimiter |; + +CREATE PROCEDURE p1() + BEGIN + DECLARE c INT DEFAULT 0; + DECLARE CONTINUE HANDLER FOR SQLWARNING SET c = c + 1; + CALL p2(); + CALL p3(); + CALL p4(); + SELECT c; + SELECT @@warning_count; + SHOW WARNINGS; + END| + +CREATE PROCEDURE p2() + BEGIN + SELECT CAST('10 ' as unsigned integer); + END| + +CREATE PROCEDURE p3() + BEGIN + SELECT CAST('10 ' as unsigned integer); + SELECT 1; + END| + +CREATE PROCEDURE p4() + BEGIN + SELECT CAST('10 ' as unsigned integer); + CALL p2(); + END| + +CREATE PROCEDURE p5() + BEGIN + SELECT CAST('10 ' as unsigned integer); + SHOW WARNINGS; + END| + +CREATE PROCEDURE P6() + BEGIN + DECLARE c INT DEFAULT 0; + DECLARE CONTINUE HANDLER FOR SQLWARNING SET c = c + 1; + CALL p5(); + SELECT c; + END| + +delimiter ;| + +CALL p1(); +CALL p6(); + +DROP PROCEDURE p1; +DROP PROCEDURE p2; +DROP PROCEDURE p3; +DROP PROCEDURE p4; +DROP PROCEDURE p5; +DROP PROCEDURE p6; + +--echo +--echo # - Case 3: check that "Exception trumps No Data". +--echo + +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings + +CREATE TABLE t1(a INT); +INSERT INTO t1 VALUES (1), (2), (3); + +delimiter |; + +CREATE PROCEDURE p1() +BEGIN + DECLARE c CURSOR FOR SELECT a FROM t1; + + OPEN c; + + BEGIN + DECLARE v1 INT; + DECLARE v2 INT; + + DECLARE EXIT HANDLER FOR SQLEXCEPTION + SELECT "Error caught (expected)"; + + DECLARE EXIT HANDLER FOR NOT FOUND + SELECT "End of Result Set found!"; + + WHILE TRUE DO + FETCH c INTO v1, v2; + END WHILE; + END; + + CLOSE c; + + SELECT a INTO @foo FROM t1 LIMIT 1; # Clear warning stack +END| + +delimiter ;| + +CALL p1(); + +DROP PROCEDURE p1; +DROP TABLE t1; + +--echo # +--echo # Bug#36185: Incorrect precedence for warning and exception handlers +--echo # + +--disable_warnings +DROP TABLE IF EXISTS t1; +DROP PROCEDURE IF EXISTS p1; +--enable_warnings + +CREATE TABLE t1 (a INT, b INT NOT NULL); + +delimiter |; + +CREATE PROCEDURE p1() +BEGIN + DECLARE CONTINUE HANDLER FOR SQLWARNING SELECT 'warning'; + DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SELECT 'exception'; + INSERT INTO t1 VALUES (CAST('10 ' AS SIGNED), NULL); +END| + +delimiter ;| + +CALL p1(); + +DROP TABLE t1; +DROP PROCEDURE p1; + +--echo # +--echo # Bug#5889: Exit handler for a warning doesn't hide the warning in trigger +--echo # + +--echo +--echo # - Case 1 +--echo + +CREATE TABLE t1(a INT, b INT); +INSERT INTO t1 VALUES (1, 2); + +delimiter |; + +CREATE TRIGGER t1_bu BEFORE UPDATE ON t1 FOR EACH ROW +BEGIN + DECLARE EXIT HANDLER FOR SQLWARNING + SET NEW.a = 10; + + SET NEW.a = 99999999999; +END| + +delimiter ;| + +UPDATE t1 SET b = 20; + +SHOW WARNINGS; + +SELECT * FROM t1; + +DROP TRIGGER t1_bu; +DROP TABLE t1; + +--echo +--echo # - Case 2 +--echo + +CREATE TABLE t1(a INT); +CREATE TABLE t2(b CHAR(1)); + +delimiter |; + +CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW +BEGIN + INSERT INTO t2 VALUES('ab'); # Produces a warning. + + INSERT INTO t2 VALUES('b'); # Does not produce a warning, + # previous warning should be cleared. +END| + +delimiter ;| + +INSERT INTO t1 VALUES(0); + +SHOW WARNINGS; + +SELECT * FROM t1; +SELECT * FROM t2; + +DROP TRIGGER t1_bi; +DROP TABLE t1; +DROP TABLE t2; + +--echo # +--echo # Bug#9857: Stored procedures: handler for sqlwarning ignored +--echo # + +SET @sql_mode_saved = @@sql_mode; +SET sql_mode = traditional; + +delimiter |; + +CREATE PROCEDURE p1() +BEGIN + DECLARE CONTINUE HANDLER FOR SQLWARNING + SELECT 'warning caught (expected)'; + + SELECT 5 / 0; +END| + +CREATE PROCEDURE p2() +BEGIN + DECLARE CONTINUE HANDLER FOR SQLEXCEPTION + SELECT 'error caught (unexpected)'; + + SELECT 5 / 0; +END| + +delimiter ;| + +CALL p1(); +SHOW WARNINGS; + +CALL p2(); +SHOW WARNINGS; + +DROP PROCEDURE p1; +DROP PROCEDURE p2; +SET sql_mode = @sql_mode_saved; |