#At file:///home/alik/MySQL/bzr/00/bug55850/mysql-5.5-bugteam-bug55850/ based on revid:alexander.nozdrin@stripped
3097 Alexander Nozdrin 2010-10-14
Patch for Bug#55850 (Trigger warnings not cleared).
The problem was that the warnings risen by a trigger were not cleared.
The warnings should be cleared if the trigger completes successfully.
The fix is to skip merging warnings into caller's Warning Info for triggers.
modified:
mysql-test/r/sp-error.result
mysql-test/t/sp-error.test
sql/sp_head.cc
sql/sp_head.h
=== modified file 'mysql-test/r/sp-error.result'
--- a/mysql-test/r/sp-error.result 2010-10-06 17:35:29 +0000
+++ b/mysql-test/r/sp-error.result 2010-10-14 13:06:37 +0000
@@ -1869,9 +1869,6 @@ DROP PROCEDURE p1;
#
# Bug#5889: Exit handler for a warning doesn't hide the warning in trigger
#
-
-# - Case 1
-
CREATE TABLE t1(a INT, b INT);
INSERT INTO t1 VALUES (1, 2);
CREATE TRIGGER t1_bu BEFORE UPDATE ON t1 FOR EACH ROW
@@ -1883,36 +1880,11 @@ END|
UPDATE t1 SET b = 20;
SHOW WARNINGS;
Level Code Message
-Warning 1264 Out of range value for column 'a' at row 1
SELECT * FROM t1;
a b
10 20
DROP TRIGGER t1_bu;
DROP TABLE t1;
-
-# - Case 2
-
-CREATE TABLE t1(a INT);
-CREATE TABLE t2(b CHAR(1));
-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|
-INSERT INTO t1 VALUES(0);
-SHOW WARNINGS;
-Level Code Message
-SELECT * FROM t1;
-a
-0
-SELECT * FROM t2;
-b
-a
-b
-DROP TRIGGER t1_bi;
-DROP TABLE t1;
-DROP TABLE t2;
#
# Bug#9857: Stored procedures: handler for sqlwarning ignored
#
@@ -1949,3 +1921,26 @@ Warning 1365 Division by 0
DROP PROCEDURE p1;
DROP PROCEDURE p2;
SET sql_mode = @sql_mode_saved;
+#
+# Bug#55850: Trigger warnings not cleared.
+#
+DROP TABLE IF EXISTS t1;
+DROP TABLE IF EXISTS t2;
+DROP PROCEDURE IF EXISTS p1;
+CREATE TABLE t1(x SMALLINT, y SMALLINT, z SMALLINT);
+CREATE TABLE t2(a SMALLINT, b SMALLINT, c SMALLINT,
+d SMALLINT, e SMALLINT, f SMALLINT);
+CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW
+INSERT INTO t2(a, b, c) VALUES(99999, 99999, 99999);
+CREATE TRIGGER t1_ai AFTER INSERT ON t1 FOR EACH ROW
+INSERT INTO t2(d, e, f) VALUES(99999, 99999, 99999);
+CREATE PROCEDURE p1()
+INSERT INTO t1 VALUES(99999, 99999, 99999);
+CALL p1();
+Warnings:
+Warning 1264 Out of range value for column 'x' at row 1
+Warning 1264 Out of range value for column 'y' at row 1
+Warning 1264 Out of range value for column 'z' at row 1
+DROP TABLE t1;
+DROP TABLE t2;
+DROP PROCEDURE p1;
=== modified file 'mysql-test/t/sp-error.test'
--- a/mysql-test/t/sp-error.test 2010-07-30 15:28:36 +0000
+++ b/mysql-test/t/sp-error.test 2010-10-14 13:06:37 +0000
@@ -2719,10 +2719,6 @@ DROP PROCEDURE p1;
--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);
@@ -2747,36 +2743,6 @@ 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 #
@@ -2813,3 +2779,46 @@ SHOW WARNINGS;
DROP PROCEDURE p1;
DROP PROCEDURE p2;
SET sql_mode = @sql_mode_saved;
+
+--echo #
+--echo # Bug#55850: Trigger warnings not cleared.
+--echo #
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+DROP TABLE IF EXISTS t2;
+DROP PROCEDURE IF EXISTS p1;
+--enable_warnings
+
+CREATE TABLE t1(x SMALLINT, y SMALLINT, z SMALLINT);
+CREATE TABLE t2(a SMALLINT, b SMALLINT, c SMALLINT,
+ d SMALLINT, e SMALLINT, f SMALLINT);
+
+CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW
+ INSERT INTO t2(a, b, c) VALUES(99999, 99999, 99999);
+
+CREATE TRIGGER t1_ai AFTER INSERT ON t1 FOR EACH ROW
+ INSERT INTO t2(d, e, f) VALUES(99999, 99999, 99999);
+
+CREATE PROCEDURE p1()
+ INSERT INTO t1 VALUES(99999, 99999, 99999);
+
+# What happened before the patch was:
+# - INSERT INTO t1 added 3 warnings about overflow in 'x', 'y' and 'z' columns;
+# - t1_bi run and added 3 warnings about overflow in 'a', 'b' and 'c' columns;
+# - t1_ai run and added 3 warnings about overflow in 'd', 'e' and 'f' columns;
+# => we had 9 warnings.
+#
+# Now what happens is:
+# - INSERT INTO t1 adds 3 warnings about overflow in 'x', 'y' and 'z' columns;
+# - t1_bi adds 3 warnings about overflow in 'a', 'b' and 'c' columns;
+# - The warnings added by triggers are cleared;
+# - t1_ai run and added 3 warnings about overflow in 'd', 'e' and 'f' columns;
+# - The warnings added by triggers are cleared;
+# => we have 3 warnings.
+
+CALL p1();
+
+DROP TABLE t1;
+DROP TABLE t2;
+DROP PROCEDURE p1;
=== modified file 'sql/sp_head.cc'
--- a/sql/sp_head.cc 2010-10-06 17:35:29 +0000
+++ b/sql/sp_head.cc 2010-10-14 13:06:37 +0000
@@ -1217,7 +1217,7 @@ find_handler_after_execution(THD *thd, s
*/
bool
-sp_head::execute(THD *thd)
+sp_head::execute(THD *thd, bool merge_warnings_to_caller)
{
DBUG_ENTER("sp_head::execute");
char saved_cur_db_name_buf[NAME_LEN+1];
@@ -1492,7 +1492,8 @@ sp_head::execute(THD *thd)
state= EXECUTED;
/* Restore the caller's original warning information area. */
- saved_warning_info->merge_with_routine_info(thd, thd->warning_info);
+ if (merge_warnings_to_caller)
+ saved_warning_info->merge_with_routine_info(thd, thd->warning_info);
thd->warning_info= saved_warning_info;
done:
@@ -1714,7 +1715,7 @@ sp_head::execute_trigger(THD *thd,
thd->spcont= nctx;
- err_status= execute(thd);
+ err_status= execute(thd, FALSE);
err_with_cleanup:
thd->restore_active_arena(&call_arena, &backup_arena);
@@ -1931,7 +1932,7 @@ sp_head::execute_function(THD *thd, Item
*/
thd->set_n_backup_active_arena(&call_arena, &backup_arena);
- err_status= execute(thd);
+ err_status= execute(thd, TRUE);
thd->restore_active_arena(&call_arena, &backup_arena);
@@ -2164,7 +2165,7 @@ sp_head::execute_procedure(THD *thd, Lis
#endif
if (!err_status)
- err_status= execute(thd);
+ err_status= execute(thd, TRUE);
if (save_log_general)
thd->variables.option_bits &= ~OPTION_LOG_OFF;
=== modified file 'sql/sp_head.h'
--- a/sql/sp_head.h 2010-08-16 15:16:07 +0000
+++ b/sql/sp_head.h 2010-10-14 13:06:37 +0000
@@ -527,7 +527,7 @@ private:
HASH m_sptabs;
bool
- execute(THD *thd);
+ execute(THD *thd, bool merge_warnings_to_caller);
/**
Perform a forward flow analysis in the generated code.
Attachment: [text/bzr-bundle] bzr/alexander.nozdrin@oracle.com-20101014130637-3kcjuuaqvng31tr8.bundle
| Thread |
|---|
| • bzr commit into mysql-5.5-bugteam branch (alexander.nozdrin:3097) Bug#55850 | Alexander Nozdrin | 14 Oct |