diff options
-rw-r--r-- | .bzrignore | 1 | ||||
-rw-r--r-- | mysql-test/r/sp.result | 61 | ||||
-rw-r--r-- | mysql-test/t/sp.test | 63 | ||||
-rw-r--r-- | sql/sp_head.cc | 6 | ||||
-rw-r--r-- | sql/sql_error.cc | 4 | ||||
-rw-r--r-- | sql/sql_error.h | 14 |
6 files changed, 146 insertions, 3 deletions
diff --git a/.bzrignore b/.bzrignore index 57209c72b87..37ae77824f8 100644 --- a/.bzrignore +++ b/.bzrignore @@ -1068,6 +1068,7 @@ vio/viotest.cpp ylwrap zlib/*.ds? sql-bench/test-table-elimination +sql/share/bulgarian sql/share/czech sql/share/danish sql/share/dutch diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index defd3955f6c..a0f21b434d1 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -7916,4 +7916,65 @@ DROP FUNCTION f1; DROP FUNCTION f2; DROP FUNCTION f3; DROP FUNCTION f4; + +Stored procedures and a condition handler in a nested procedure call +doesn't suppress the condition from being passed on to the calling +procedure + +drop procedure if exists p1; +drop procedure if exists p0; +create table t1 (id int); +create procedure p1 () begin +declare i int default 0; +declare continue handler for not found begin +select "You should see this message and the warning that generated this" as "message"; +show warnings; +end; +select id into i from t1; +end$$ +create procedure p0 () begin +declare continue handler for not found begin +select "You should NOT see this message" as "message"; +end; +call p1(); +end$$ +call p0(); +message +You should see this message and the warning that generated this +Level Code Message +Warning 1329 No data - zero rows fetched, selected, or processed +Warnings: +Warning 1329 No data - zero rows fetched, selected, or processed +drop procedure p1; +drop procedure p0; +drop table t1; + +Test if stored procedures propagates errors + +create table t1 (id int primary key); +create procedure p1 () begin +insert into t1 values(1); +insert into t1 values(2); +insert into t1 values(2); +insert into t1 values(3); +end$$ +create procedure p2 () begin +declare x int; +select id into x from t1 where id=5; +end$$ +call p1(); +ERROR 23000: Duplicate entry '2' for key 'PRIMARY' +show warnings; +Level Code Message +Error 1062 Duplicate entry '2' for key 'PRIMARY' +select * from t1; +id +1 +2 +call p2(); +Warnings: +Warning 1329 No data - zero rows fetched, selected, or processed +drop procedure p1; +drop procedure p2; +drop table t1; # End of 5.5 test diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 0a368826ee7..3590dc66187 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -9209,5 +9209,66 @@ DROP FUNCTION f2; DROP FUNCTION f3; DROP FUNCTION f4; ---echo # End of 5.5 test +--echo +--echo Stored procedures and a condition handler in a nested procedure call +--echo doesn't suppress the condition from being passed on to the calling +--echo procedure +--echo + +--disable_warnings +drop procedure if exists p1; +drop procedure if exists p0; +--enable_warnings + +create table t1 (id int); +delimiter $$; +create procedure p1 () begin +declare i int default 0; +declare continue handler for not found begin +select "You should see this message and the warning that generated this" as "message"; +show warnings; +end; +select id into i from t1; +end$$ +create procedure p0 () begin +declare continue handler for not found begin +select "You should NOT see this message" as "message"; +end; +call p1(); +end$$ +delimiter ;$$ +call p0(); +drop procedure p1; +drop procedure p0; +drop table t1; + +--echo +--echo Test if stored procedures propagates errors +--echo + +create table t1 (id int primary key); +delimiter $$; +create procedure p1 () begin +insert into t1 values(1); +insert into t1 values(2); +insert into t1 values(2); +insert into t1 values(3); +end$$ +create procedure p2 () begin + declare x int; + select id into x from t1 where id=5; +end$$ +delimiter ;$$ +--error ER_DUP_ENTRY +call p1(); +show warnings; +select * from t1; +call p2(); + +drop procedure p1; +drop procedure p2; + +drop table t1; + +--echo # End of 5.5 test diff --git a/sql/sp_head.cc b/sql/sp_head.cc index be6dc935dcc..847a4f214ab 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -1160,8 +1160,9 @@ find_handler_after_execution(THD *thd, sp_rcontext *ctx) MYSQL_ERROR *err; while ((err= it++)) { - if (err->get_level() != MYSQL_ERROR::WARN_LEVEL_WARN && - err->get_level() != MYSQL_ERROR::WARN_LEVEL_NOTE) + if ((err->get_level() != MYSQL_ERROR::WARN_LEVEL_WARN && + err->get_level() != MYSQL_ERROR::WARN_LEVEL_NOTE) || + err->handled()) continue; if (ctx->find_handler(thd, @@ -1170,6 +1171,7 @@ find_handler_after_execution(THD *thd, sp_rcontext *ctx) err->get_level(), err->get_message_text())) { + err->mark_handled(); break; } } diff --git a/sql/sql_error.cc b/sql/sql_error.cc index 61281af1d0a..a4f5b210285 100644 --- a/sql/sql_error.cc +++ b/sql/sql_error.cc @@ -185,6 +185,7 @@ MYSQL_ERROR::MYSQL_ERROR() m_cursor_name((const char*) NULL, 0, & my_charset_utf8_bin), m_message_text(), m_sql_errno(0), + m_handled(0), m_level(MYSQL_ERROR::WARN_LEVEL_ERROR), m_mem_root(NULL) { @@ -212,6 +213,7 @@ void MYSQL_ERROR::clear() m_cursor_name.length(0); m_message_text.length(0); m_sql_errno= 0; + m_handled= 0; m_level= MYSQL_ERROR::WARN_LEVEL_ERROR; } @@ -229,6 +231,7 @@ MYSQL_ERROR::MYSQL_ERROR(MEM_ROOT *mem_root) m_cursor_name((const char*) NULL, 0, & my_charset_utf8_bin), m_message_text(), m_sql_errno(0), + m_handled(0), m_level(MYSQL_ERROR::WARN_LEVEL_ERROR), m_mem_root(mem_root) { @@ -267,6 +270,7 @@ MYSQL_ERROR::copy_opt_attributes(const MYSQL_ERROR *cond) copy_string(m_mem_root, & m_table_name, & cond->m_table_name); copy_string(m_mem_root, & m_column_name, & cond->m_column_name); copy_string(m_mem_root, & m_cursor_name, & cond->m_cursor_name); + m_handled= cond->m_handled; } void diff --git a/sql/sql_error.h b/sql/sql_error.h index 00ade934226..0483e7c65d1 100644 --- a/sql/sql_error.h +++ b/sql/sql_error.h @@ -191,6 +191,17 @@ public: MYSQL_ERROR::enum_warning_level get_level() const { return m_level; } + /** check if condition was handled by a condition handler */ + bool handled() const + { + return m_handled; + } + /** mark that condition was handled */ + void mark_handled() + { + m_handled= 1; + } + private: /* The interface of MYSQL_ERROR is mostly private, by design, @@ -306,6 +317,9 @@ private: /** MySQL extension, MYSQL_ERRNO condition item. */ uint m_sql_errno; + /** Marker if error/warning was handled by a continue handler */ + bool m_handled; + /** SQL RETURNED_SQLSTATE condition item. This member is always NUL terminated. |