#At file:///home/malff/BZR-TREE/mysql-6.0-wl2110-review-part10/ 2675 Marc Alff 2008-07-22 WL#2110 (Stored Procedures: Implement SIGNAL) Formal review part 10/10: Tests This patch implements: - implements the SIGNAL / RESIGNAL tests - adjust existing tests (can't raise an error number 0) added: mysql-test/r/signal.result mysql-test/r/signal_code.result mysql-test/r/signal_demo1.result mysql-test/r/signal_demo2.result mysql-test/r/signal_demo3.result mysql-test/r/signal_sqlmode.result mysql-test/r/signal_utf32.result mysql-test/t/signal.test mysql-test/t/signal_code.test mysql-test/t/signal_demo1.test mysql-test/t/signal_demo2.test mysql-test/t/signal_demo3.test mysql-test/t/signal_sqlmode.test mysql-test/t/signal_utf32.test modified: mysql-test/r/partition_not_windows.result mysql-test/r/partition_symlink.result mysql-test/r/partition_windows.result mysql-test/r/symlink.result mysql-test/r/windows.result === modified file 'mysql-test/r/partition_not_windows.result' --- a/mysql-test/r/partition_not_windows.result 2008-03-27 20:34:49 +0000 +++ b/mysql-test/r/partition_not_windows.result 2008-07-23 00:30:04 +0000 @@ -24,8 +24,8 @@ data directory='/not/existing' index directory='/not/existing' ); Warnings: -Warning 0 DATA DIRECTORY option ignored -Warning 0 INDEX DIRECTORY option ignored +Warning 1105 DATA DIRECTORY option ignored +Warning 1105 INDEX DIRECTORY option ignored show create table t2; Table Create Table t2 CREATE TABLE `t2` ( === modified file 'mysql-test/r/partition_symlink.result' --- a/mysql-test/r/partition_symlink.result 2008-03-20 14:25:58 +0000 +++ b/mysql-test/r/partition_symlink.result 2008-07-23 00:30:04 +0000 @@ -101,8 +101,8 @@ data directory='/not/existing' index directory='/not/existing' ); Warnings: -Warning 0 DATA DIRECTORY option ignored -Warning 0 INDEX DIRECTORY option ignored +Warning 1105 DATA DIRECTORY option ignored +Warning 1105 INDEX DIRECTORY option ignored show create table t2; Table Create Table t2 CREATE TABLE `t2` ( === modified file 'mysql-test/r/partition_windows.result' --- a/mysql-test/r/partition_windows.result 2008-01-04 11:06:20 +0000 +++ b/mysql-test/r/partition_windows.result 2008-07-23 00:30:04 +0000 @@ -15,16 +15,16 @@ DATA DIRECTORY = 'E:/mysqltest/p2Data' INDEX DIRECTORY = 'F:/mysqltest/p2Index' ); Warnings: -Warning 0 DATA DIRECTORY option ignored -Warning 0 INDEX DIRECTORY option ignored -Warning 0 DATA DIRECTORY option ignored -Warning 0 INDEX DIRECTORY option ignored +Warning 1105 DATA DIRECTORY option ignored +Warning 1105 INDEX DIRECTORY option ignored +Warning 1105 DATA DIRECTORY option ignored +Warning 1105 INDEX DIRECTORY option ignored INSERT INTO t1 VALUES (NULL, "first", 1); INSERT INTO t1 VALUES (NULL, "second", 2); INSERT INTO t1 VALUES (NULL, "third", 3); ALTER TABLE t1 ADD PARTITION (PARTITION p3 DATA DIRECTORY = 'G:/mysqltest/p3Data' INDEX DIRECTORY = 'H:/mysqltest/p3Index'); Warnings: -Warning 0 DATA DIRECTORY option ignored -Warning 0 INDEX DIRECTORY option ignored +Warning 1105 DATA DIRECTORY option ignored +Warning 1105 INDEX DIRECTORY option ignored INSERT INTO t1 VALUES (NULL, "last", 4); DROP TABLE t1; === added file 'mysql-test/r/signal.result' --- a/mysql-test/r/signal.result 1970-01-01 00:00:00 +0000 +++ b/mysql-test/r/signal.result 2008-07-23 00:30:04 +0000 @@ -0,0 +1,2114 @@ +drop table if exists signal_non_reserved; +create table signal_non_reserved ( +class_origin int, +subclass_origin int, +constraint_catalog int, +constraint_schema int, +constraint_name int, +catalog_name int, +schema_name int, +table_name int, +column_name int, +cursor_name int, +message_text int, +sqlcode int +); +drop table signal_non_reserved; +drop table if exists diag_non_reserved; +create table diag_non_reserved ( +diagnostics int, +current int, +stacked int, +exception int +); +drop table diag_non_reserved; +drop table if exists diag_cond_non_reserved; +create table diag_cond_non_reserved ( +condition_identifier int, +condition_number int, +condition_name int, +connection_name int, +message_length int, +message_octet_length int, +parameter_mode int, +parameter_name int, +parameter_ordinal_position int, +returned_sqlstate int, +routine_catalog int, +routine_name int, +routine_schema int, +server_name int, +specific_name int, +trigger_catalog int, +trigger_name int, +trigger_schema int +); +drop table diag_cond_non_reserved; +drop table if exists diag_stmt_non_reserved; +create table diag_stmt_non_reserved ( +number int, +more int, +command_function int, +command_function_code int, +dynamic_function int, +dynamic_function_code int, +row_count int, +transactions_committed int, +transactions_rolled_back int, +transaction_active int +); +drop table diag_stmt_non_reserved; +drop table if exists test_reserved; +create table test_reserved (signal int); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'signal int)' at line 1 +create table test_reserved (resignal int); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'resignal int)' at line 1 +create table test_reserved (condition int); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'condition int)' at line 1 +drop procedure if exists test_invalid; +drop procedure if exists test_signal_syntax; +drop function if exists test_signal_func; +create procedure test_invalid() +begin +SIGNAL; +end $$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '; +end' at line 3 +create procedure test_invalid() +begin +SIGNAL foo; +end $$ +ERROR 42000: Undefined CONDITION: foo +create procedure test_invalid() +begin +DECLARE foo CONDITION FOR 1234; +SIGNAL foo; +end $$ +ERROR HY000: SIGNAL/RESIGNAL can only use a CONDITION defined with SQLSTATE +create procedure test_signal_syntax() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +SIGNAL foo; +end $$ +drop procedure test_signal_syntax $$ +create procedure test_signal_syntax() +begin +SIGNAL SQLSTATE '23000'; +end $$ +drop procedure test_signal_syntax $$ +create procedure test_signal_syntax() +begin +SIGNAL SQLSTATE VALUE '23000'; +end $$ +drop procedure test_signal_syntax $$ +create procedure test_signal_syntax() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +SIGNAL foo SET CLASS_ORIGIN = 'foo'; +end $$ +drop procedure test_signal_syntax $$ +create procedure test_signal_syntax() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +SIGNAL foo SET SUBCLASS_ORIGIN = 'foo'; +end $$ +drop procedure test_signal_syntax $$ +create procedure test_signal_syntax() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +SIGNAL foo SET CONSTRAINT_CATALOG = 'foo'; +end $$ +drop procedure test_signal_syntax $$ +create procedure test_signal_syntax() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +SIGNAL foo SET CONSTRAINT_SCHEMA = 'foo'; +end $$ +drop procedure test_signal_syntax $$ +create procedure test_signal_syntax() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +SIGNAL foo SET CONSTRAINT_NAME = 'foo'; +end $$ +drop procedure test_signal_syntax $$ +create procedure test_signal_syntax() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +SIGNAL foo SET CATALOG_NAME = 'foo'; +end $$ +drop procedure test_signal_syntax $$ +create procedure test_signal_syntax() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +SIGNAL foo SET SCHEMA_NAME = 'foo'; +end $$ +drop procedure test_signal_syntax $$ +create procedure test_signal_syntax() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +SIGNAL foo SET TABLE_NAME = 'foo'; +end $$ +drop procedure test_signal_syntax $$ +create procedure test_signal_syntax() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +SIGNAL foo SET COLUMN_NAME = 'foo'; +end $$ +drop procedure test_signal_syntax $$ +create procedure test_signal_syntax() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +SIGNAL foo SET CURSOR_NAME = 'foo'; +end $$ +drop procedure test_signal_syntax $$ +create procedure test_signal_syntax() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +SIGNAL foo SET MESSAGE_TEXT = 'foo'; +end $$ +drop procedure test_signal_syntax $$ +create procedure test_signal_syntax() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +SIGNAL foo SET MYSQL_ERRNO = 'foo'; +end $$ +drop procedure test_signal_syntax $$ +create procedure test_invalid() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +SIGNAL foo SET CLASS_ORIGIN = 'foo', CLASS_ORIGIN = 'bar'; +end $$ +ERROR 42000: Duplicate condition information item: CLASS_ORIGIN +create procedure test_invalid() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +SIGNAL foo SET MESSAGE_TEXT = 'foo', MESSAGE_TEXT = 'bar'; +end $$ +ERROR 42000: Duplicate condition information item: MESSAGE_TEXT +create procedure test_invalid() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +SIGNAL foo SET MYSQL_ERRNO = 'foo', MYSQL_ERRNO = 'bar'; +end $$ +ERROR 42000: Duplicate condition information item: MYSQL_ERRNO +create procedure test_signal_syntax() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +SIGNAL foo SET +CLASS_ORIGIN = 'foo', +SUBCLASS_ORIGIN = 'foo', +CONSTRAINT_CATALOG = 'foo', +CONSTRAINT_SCHEMA = 'foo', +CONSTRAINT_NAME = 'foo', +CATALOG_NAME = 'foo', +SCHEMA_NAME = 'foo', +TABLE_NAME = 'foo', +COLUMN_NAME = 'foo', +CURSOR_NAME = 'foo', +MESSAGE_TEXT = 'foo', +MYSQL_ERRNO = 'foo'; +end $$ +drop procedure test_signal_syntax $$ +SIGNAL SQLSTATE '00000' $$ +ERROR 42000: Bad SQLSTATE: '00000' +SIGNAL SQLSTATE '00001' $$ +ERROR 42000: Bad SQLSTATE: '00001' +create procedure test_invalid() +begin +SIGNAL SQLSTATE '00000'; +end $$ +ERROR 42000: Bad SQLSTATE: '00000' +create procedure test_invalid() +begin +SIGNAL SQLSTATE '00001'; +end $$ +ERROR 42000: Bad SQLSTATE: '00001' +create procedure test_invalid() +begin +SIGNAL SQLSTATE '12345' SET bla_bla = 'foo'; +end $$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'bla_bla = 'foo'; +end' at line 3 +create procedure test_invalid() +begin +SIGNAL SQLSTATE '12345' SET CONDITION_IDENTIFIER = 'foo'; +end $$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CONDITION_IDENTIFIER = 'foo'; +end' at line 3 +create procedure test_invalid() +begin +SIGNAL SQLSTATE '12345' SET CONDITION_NUMBER = 'foo'; +end $$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CONDITION_NUMBER = 'foo'; +end' at line 3 +create procedure test_invalid() +begin +SIGNAL SQLSTATE '12345' SET CONNECTION_NAME = 'foo'; +end $$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CONNECTION_NAME = 'foo'; +end' at line 3 +create procedure test_invalid() +begin +SIGNAL SQLSTATE '12345' SET MESSAGE_LENGTH = 'foo'; +end $$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'MESSAGE_LENGTH = 'foo'; +end' at line 3 +create procedure test_invalid() +begin +SIGNAL SQLSTATE '12345' SET MESSAGE_OCTET_LENGTH = 'foo'; +end $$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'MESSAGE_OCTET_LENGTH = 'foo'; +end' at line 3 +create procedure test_invalid() +begin +SIGNAL SQLSTATE '12345' SET PARAMETER_MODE = 'foo'; +end $$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'PARAMETER_MODE = 'foo'; +end' at line 3 +create procedure test_invalid() +begin +SIGNAL SQLSTATE '12345' SET PARAMETER_NAME = 'foo'; +end $$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'PARAMETER_NAME = 'foo'; +end' at line 3 +create procedure test_invalid() +begin +SIGNAL SQLSTATE '12345' SET PARAMETER_ORDINAL_POSITION = 'foo'; +end $$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'PARAMETER_ORDINAL_POSITION = 'foo'; +end' at line 3 +create procedure test_invalid() +begin +SIGNAL SQLSTATE '12345' SET RETURNED_SQLSTATE = 'foo'; +end $$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'RETURNED_SQLSTATE = 'foo'; +end' at line 3 +create procedure test_invalid() +begin +SIGNAL SQLSTATE '12345' SET ROUTINE_CATALOG = 'foo'; +end $$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'ROUTINE_CATALOG = 'foo'; +end' at line 3 +create procedure test_invalid() +begin +SIGNAL SQLSTATE '12345' SET ROUTINE_NAME = 'foo'; +end $$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'ROUTINE_NAME = 'foo'; +end' at line 3 +create procedure test_invalid() +begin +SIGNAL SQLSTATE '12345' SET ROUTINE_SCHEMA = 'foo'; +end $$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'ROUTINE_SCHEMA = 'foo'; +end' at line 3 +create procedure test_invalid() +begin +SIGNAL SQLSTATE '12345' SET SERVER_NAME = 'foo'; +end $$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SERVER_NAME = 'foo'; +end' at line 3 +create procedure test_invalid() +begin +SIGNAL SQLSTATE '12345' SET SPECIFIC_NAME = 'foo'; +end $$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SPECIFIC_NAME = 'foo'; +end' at line 3 +create procedure test_invalid() +begin +SIGNAL SQLSTATE '12345' SET TRIGGER_CATALOG = 'foo'; +end $$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'TRIGGER_CATALOG = 'foo'; +end' at line 3 +create procedure test_invalid() +begin +SIGNAL SQLSTATE '12345' SET TRIGGER_NAME = 'foo'; +end $$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'TRIGGER_NAME = 'foo'; +end' at line 3 +create procedure test_invalid() +begin +SIGNAL SQLSTATE '12345' SET TRIGGER_SCHEMA = 'foo'; +end $$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'TRIGGER_SCHEMA = 'foo'; +end' at line 3 +drop procedure if exists test_invalid; +drop procedure if exists test_resignal_syntax; +create procedure test_invalid() +begin +RESIGNAL foo; +end $$ +ERROR 42000: Undefined CONDITION: foo +create procedure test_resignal_syntax() +begin +RESIGNAL; +end $$ +drop procedure test_resignal_syntax $$ +create procedure test_invalid() +begin +DECLARE foo CONDITION FOR 1234; +RESIGNAL foo; +end $$ +ERROR HY000: SIGNAL/RESIGNAL can only use a CONDITION defined with SQLSTATE +create procedure test_resignal_syntax() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +RESIGNAL foo; +end $$ +drop procedure test_resignal_syntax $$ +create procedure test_resignal_syntax() +begin +RESIGNAL SQLSTATE '23000'; +end $$ +drop procedure test_resignal_syntax $$ +create procedure test_resignal_syntax() +begin +RESIGNAL SQLSTATE VALUE '23000'; +end $$ +drop procedure test_resignal_syntax $$ +create procedure test_resignal_syntax() +begin +RESIGNAL SET CLASS_ORIGIN = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ +create procedure test_resignal_syntax() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +RESIGNAL foo SET CLASS_ORIGIN = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ +create procedure test_resignal_syntax() +begin +RESIGNAL SET SUBCLASS_ORIGIN = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ +create procedure test_resignal_syntax() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +RESIGNAL foo SET SUBCLASS_ORIGIN = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ +create procedure test_resignal_syntax() +begin +RESIGNAL SET CONSTRAINT_CATALOG = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ +create procedure test_resignal_syntax() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +RESIGNAL foo SET CONSTRAINT_CATALOG = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ +create procedure test_resignal_syntax() +begin +RESIGNAL SET CONSTRAINT_SCHEMA = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ +create procedure test_resignal_syntax() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +RESIGNAL foo SET CONSTRAINT_SCHEMA = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ +create procedure test_resignal_syntax() +begin +RESIGNAL SET CONSTRAINT_NAME = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ +create procedure test_resignal_syntax() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +RESIGNAL foo SET CONSTRAINT_NAME = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ +create procedure test_resignal_syntax() +begin +RESIGNAL SET CATALOG_NAME = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ +create procedure test_resignal_syntax() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +RESIGNAL foo SET CATALOG_NAME = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ +create procedure test_resignal_syntax() +begin +RESIGNAL SET SCHEMA_NAME = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ +create procedure test_resignal_syntax() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +RESIGNAL foo SET SCHEMA_NAME = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ +create procedure test_resignal_syntax() +begin +RESIGNAL SET TABLE_NAME = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ +create procedure test_resignal_syntax() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +RESIGNAL foo SET TABLE_NAME = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ +create procedure test_resignal_syntax() +begin +RESIGNAL SET COLUMN_NAME = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ +create procedure test_resignal_syntax() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +RESIGNAL foo SET COLUMN_NAME = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ +create procedure test_resignal_syntax() +begin +RESIGNAL SET CURSOR_NAME = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ +create procedure test_resignal_syntax() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +RESIGNAL foo SET CURSOR_NAME = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ +create procedure test_resignal_syntax() +begin +RESIGNAL SET MESSAGE_TEXT = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ +create procedure test_resignal_syntax() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +RESIGNAL foo SET MESSAGE_TEXT = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ +create procedure test_resignal_syntax() +begin +RESIGNAL SET MYSQL_ERRNO = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ +create procedure test_resignal_syntax() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +RESIGNAL foo SET MYSQL_ERRNO = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ +create procedure test_invalid() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +RESIGNAL foo SET CLASS_ORIGIN = 'foo', CLASS_ORIGIN = 'bar'; +end $$ +ERROR 42000: Duplicate condition information item: CLASS_ORIGIN +create procedure test_invalid() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +RESIGNAL foo SET MESSAGE_TEXT = 'foo', MESSAGE_TEXT = 'bar'; +end $$ +ERROR 42000: Duplicate condition information item: MESSAGE_TEXT +create procedure test_invalid() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +RESIGNAL foo SET MYSQL_ERRNO = 'foo', MYSQL_ERRNO = 'bar'; +end $$ +ERROR 42000: Duplicate condition information item: MYSQL_ERRNO +create procedure test_resignal_syntax() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +RESIGNAL foo SET +CLASS_ORIGIN = 'foo', +SUBCLASS_ORIGIN = 'foo', +CONSTRAINT_CATALOG = 'foo', +CONSTRAINT_SCHEMA = 'foo', +CONSTRAINT_NAME = 'foo', +CATALOG_NAME = 'foo', +SCHEMA_NAME = 'foo', +TABLE_NAME = 'foo', +COLUMN_NAME = 'foo', +CURSOR_NAME = 'foo', +MESSAGE_TEXT = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ +create procedure test_invalid() +begin +RESIGNAL SQLSTATE '00000'; +end $$ +ERROR 42000: Bad SQLSTATE: '00000' +prepare stmt from 'SIGNAL SQLSTATE \'23000\''; +ERROR HY000: This command is not supported in the prepared statement protocol yet +prepare stmt from 'RESIGNAL SQLSTATE \'23000\''; +ERROR HY000: This command is not supported in the prepared statement protocol yet +drop procedure if exists test_signal; +drop procedure if exists test_resignal; +drop table if exists t_warn; +drop table if exists t_cursor; +create table t_warn(a integer(2)); +create table t_cursor(a integer); +SIGNAL foo; +ERROR 42000: Undefined CONDITION: foo +SIGNAL SQLSTATE '01000'; +Warnings: +Warning 1726 Unhandled user-defined warning +SIGNAL SQLSTATE '02000'; +ERROR 02000: Unhandled user-defined not found +SIGNAL SQLSTATE '23000'; +ERROR 23000: Unhandled user-defined exception +SIGNAL SQLSTATE VALUE '23000'; +ERROR 23000: Unhandled user-defined exception +SIGNAL SQLSTATE 'HY000' SET MYSQL_ERRNO = 65536; +ERROR 42000: Variable 'MYSQL_ERRNO' can't be set to the value of '65536' +SIGNAL SQLSTATE 'HY000' SET MYSQL_ERRNO = 99999; +ERROR 42000: Variable 'MYSQL_ERRNO' can't be set to the value of '99999' +SIGNAL SQLSTATE 'HY000' SET MYSQL_ERRNO = 4294967295; +ERROR 42000: Variable 'MYSQL_ERRNO' can't be set to the value of '4294967295' +SIGNAL SQLSTATE 'HY000' SET MYSQL_ERRNO = 0; +ERROR 42000: Variable 'MYSQL_ERRNO' can't be set to the value of '0' +SIGNAL SQLSTATE 'HY000' SET MYSQL_ERRNO = -1; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '-1' at line 1 +SIGNAL SQLSTATE 'HY000' SET MYSQL_ERRNO = 65535; +ERROR HY000: Unhandled user-defined exception +RESIGNAL; +ERROR 0K000: RESIGNAL when handler not active +RESIGNAL foo; +ERROR 42000: Undefined CONDITION: foo +RESIGNAL SQLSTATE '12345'; +ERROR 0K000: RESIGNAL when handler not active +RESIGNAL SQLSTATE VALUE '12345'; +ERROR 0K000: RESIGNAL when handler not active +create procedure test_signal() +begin +# max range +DECLARE foo CONDITION FOR SQLSTATE 'AABBB'; +SIGNAL foo SET MYSQL_ERRNO = 65535; +end $$ +call test_signal() $$ +ERROR AABBB: Unhandled user-defined exception +drop procedure test_signal $$ +create procedure test_signal() +begin +# max range +DECLARE foo CONDITION FOR SQLSTATE 'AABBB'; +SIGNAL foo SET MYSQL_ERRNO = 65536; +end $$ +call test_signal() $$ +ERROR 42000: Variable 'MYSQL_ERRNO' can't be set to the value of '65536' +drop procedure test_signal $$ +create procedure test_signal() +begin +# Error +DECLARE foo CONDITION FOR SQLSTATE '99999'; +SIGNAL foo SET MYSQL_ERRNO = 9999; +end $$ +call test_signal() $$ +ERROR 99999: Unhandled user-defined exception +drop procedure test_signal $$ +create procedure test_signal() +begin +# warning +DECLARE too_few_records CONDITION FOR SQLSTATE '01000'; +SIGNAL too_few_records SET MYSQL_ERRNO = 1261; +end $$ +call test_signal() $$ +Warnings: +Warning 1261 Unhandled user-defined warning +drop procedure test_signal $$ +create procedure test_signal() +begin +# Not found +DECLARE sp_fetch_no_data CONDITION FOR SQLSTATE '02000'; +SIGNAL sp_fetch_no_data SET MYSQL_ERRNO = 1329; +end $$ +call test_signal() $$ +ERROR 02000: Unhandled user-defined not found +drop procedure test_signal $$ +create procedure test_signal() +begin +# Error +DECLARE sp_cursor_already_open CONDITION FOR SQLSTATE '24000'; +SIGNAL sp_cursor_already_open SET MYSQL_ERRNO = 1325; +end $$ +call test_signal() $$ +ERROR 24000: Unhandled user-defined exception +drop procedure test_signal $$ +create procedure test_signal() +begin +# Severe error +DECLARE lock_deadlock CONDITION FOR SQLSTATE '40001'; +SIGNAL lock_deadlock SET MYSQL_ERRNO = 1213; +end $$ +call test_signal() $$ +ERROR 40001: Unhandled user-defined exception +drop procedure test_signal $$ +create procedure test_signal() +begin +# Unknown -> error +DECLARE foo CONDITION FOR SQLSTATE "99999"; +SIGNAL foo; +end $$ +call test_signal() $$ +ERROR 99999: Unhandled user-defined exception +drop procedure test_signal $$ +create procedure test_signal() +begin +# warning, no subclass +DECLARE warn CONDITION FOR SQLSTATE "01000"; +SIGNAL warn; +end $$ +call test_signal() $$ +Warnings: +Warning 1726 Unhandled user-defined warning +drop procedure test_signal $$ +create procedure test_signal() +begin +# warning, with subclass +DECLARE warn CONDITION FOR SQLSTATE "01123"; +SIGNAL warn; +end $$ +call test_signal() $$ +Warnings: +Warning 1726 Unhandled user-defined warning +drop procedure test_signal $$ +create procedure test_signal() +begin +# Not found, no subclass +DECLARE not_found CONDITION FOR SQLSTATE "02000"; +SIGNAL not_found; +end $$ +call test_signal() $$ +ERROR 02000: Unhandled user-defined not found +drop procedure test_signal $$ +create procedure test_signal() +begin +# Not found, with subclass +DECLARE not_found CONDITION FOR SQLSTATE "02XXX"; +SIGNAL not_found; +end $$ +call test_signal() $$ +ERROR 02XXX: Unhandled user-defined not found +drop procedure test_signal $$ +create procedure test_signal() +begin +# Error, no subclass +DECLARE error CONDITION FOR SQLSTATE "12000"; +SIGNAL error; +end $$ +call test_signal() $$ +ERROR 12000: Unhandled user-defined exception +drop procedure test_signal $$ +create procedure test_signal() +begin +# Error, with subclass +DECLARE error CONDITION FOR SQLSTATE "12ABC"; +SIGNAL error; +end $$ +call test_signal() $$ +ERROR 12ABC: Unhandled user-defined exception +drop procedure test_signal $$ +create procedure test_signal() +begin +# Severe error, no subclass +DECLARE error CONDITION FOR SQLSTATE "40000"; +SIGNAL error; +end $$ +call test_signal() $$ +ERROR 40000: Unhandled user-defined exception +drop procedure test_signal $$ +create procedure test_signal() +begin +# Severe error, with subclass +DECLARE error CONDITION FOR SQLSTATE "40001"; +SIGNAL error; +end $$ +call test_signal() $$ +ERROR 40001: Unhandled user-defined exception +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE foo CONDITION FOR SQLSTATE '99999'; +begin +DECLARE foo CONDITION FOR 8888; +end; +SIGNAL foo SET MYSQL_ERRNO=9999; /* outer */ +end $$ +call test_signal() $$ +ERROR 99999: Unhandled user-defined exception +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE foo CONDITION FOR 9999; +begin +DECLARE foo CONDITION FOR SQLSTATE '88888'; +SIGNAL foo SET MYSQL_ERRNO=8888; /* inner */ +end; +end $$ +call test_signal() $$ +ERROR 88888: Unhandled user-defined exception +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE foo CONDITION FOR SQLSTATE '99999'; +SIGNAL foo SET MYSQL_ERRNO = 1111; +end $$ +call test_signal() $$ +ERROR 99999: Unhandled user-defined exception +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE warn CONDITION FOR SQLSTATE "01000"; +SIGNAL warn SET MYSQL_ERRNO = 1111; +end $$ +call test_signal() $$ +Warnings: +Warning 1111 Unhandled user-defined warning +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE not_found CONDITION FOR SQLSTATE "02000"; +SIGNAL not_found SET MYSQL_ERRNO = 1111; +end $$ +call test_signal() $$ +ERROR 02000: Unhandled user-defined not found +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE error CONDITION FOR SQLSTATE "55000"; +SIGNAL error SET MYSQL_ERRNO = 1111; +end $$ +call test_signal() $$ +ERROR 55000: Unhandled user-defined exception +drop procedure test_signal $$ +SIGNAL SQLSTATE '77777' SET MESSAGE_TEXT='' $$ +ERROR 77777: +create procedure test_signal() +begin +DECLARE foo CONDITION FOR SQLSTATE '77777'; +SIGNAL foo SET +MESSAGE_TEXT = "", +MYSQL_ERRNO=5678; +end $$ +call test_signal() $$ +ERROR 77777: +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE foo CONDITION FOR SQLSTATE '99999'; +SIGNAL foo SET +MESSAGE_TEXT = "Something bad happened", +MYSQL_ERRNO=9999; +end $$ +call test_signal() $$ +ERROR 99999: Something bad happened +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE warn CONDITION FOR SQLSTATE "01000"; +SIGNAL warn SET MESSAGE_TEXT = "Something bad happened"; +end $$ +call test_signal() $$ +Warnings: +Warning 1726 Something bad happened +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE not_found CONDITION FOR SQLSTATE "02000"; +SIGNAL not_found SET MESSAGE_TEXT = "Something bad happened"; +end $$ +call test_signal() $$ +ERROR 02000: Something bad happened +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE error CONDITION FOR SQLSTATE "55000"; +SIGNAL error SET MESSAGE_TEXT = "Something bad happened"; +end $$ +call test_signal() $$ +ERROR 55000: Something bad happened +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE something CONDITION FOR SQLSTATE "01000"; +SIGNAL something SET MESSAGE_TEXT = _utf8 "This is a UTF8 text"; +end $$ +call test_signal() $$ +Warnings: +Warning 1726 This is a UTF8 text +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE something CONDITION FOR SQLSTATE "01000"; +SIGNAL something SET MESSAGE_TEXT = ""; +end $$ +call test_signal() $$ +Warnings: +Warning 1726 +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE error CONDITION FOR SQLSTATE '99999'; +SIGNAL error SET +MYSQL_ERRNO = NULL; +end $$ +call test_signal() $$ +ERROR 42000: Variable 'MYSQL_ERRNO' can't be set to the value of 'NULL' +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE error CONDITION FOR SQLSTATE '99999'; +SIGNAL error SET +CLASS_ORIGIN = NULL; +end $$ +call test_signal() $$ +ERROR 42000: Variable 'CLASS_ORIGIN' can't be set to the value of 'NULL' +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE error CONDITION FOR SQLSTATE '99999'; +SIGNAL error SET +SUBCLASS_ORIGIN = NULL; +end $$ +call test_signal() $$ +ERROR 42000: Variable 'SUBCLASS_ORIGIN' can't be set to the value of 'NULL' +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE error CONDITION FOR SQLSTATE '99999'; +SIGNAL error SET +CONSTRAINT_CATALOG = NULL; +end $$ +call test_signal() $$ +ERROR 42000: Variable 'CONSTRAINT_CATALOG' can't be set to the value of 'NULL' +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE error CONDITION FOR SQLSTATE '99999'; +SIGNAL error SET +CONSTRAINT_SCHEMA = NULL; +end $$ +call test_signal() $$ +ERROR 42000: Variable 'CONSTRAINT_SCHEMA' can't be set to the value of 'NULL' +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE error CONDITION FOR SQLSTATE '99999'; +SIGNAL error SET +CONSTRAINT_NAME = NULL; +end $$ +call test_signal() $$ +ERROR 42000: Variable 'CONSTRAINT_NAME' can't be set to the value of 'NULL' +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE error CONDITION FOR SQLSTATE '99999'; +SIGNAL error SET +CATALOG_NAME = NULL; +end $$ +call test_signal() $$ +ERROR 42000: Variable 'CATALOG_NAME' can't be set to the value of 'NULL' +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE error CONDITION FOR SQLSTATE '99999'; +SIGNAL error SET +SCHEMA_NAME = NULL; +end $$ +call test_signal() $$ +ERROR 42000: Variable 'SCHEMA_NAME' can't be set to the value of 'NULL' +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE error CONDITION FOR SQLSTATE '99999'; +SIGNAL error SET +TABLE_NAME = NULL; +end $$ +call test_signal() $$ +ERROR 42000: Variable 'TABLE_NAME' can't be set to the value of 'NULL' +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE error CONDITION FOR SQLSTATE '99999'; +SIGNAL error SET +COLUMN_NAME = NULL; +end $$ +call test_signal() $$ +ERROR 42000: Variable 'COLUMN_NAME' can't be set to the value of 'NULL' +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE error CONDITION FOR SQLSTATE '99999'; +SIGNAL error SET +CURSOR_NAME = NULL; +end $$ +call test_signal() $$ +ERROR 42000: Variable 'CURSOR_NAME' can't be set to the value of 'NULL' +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE error CONDITION FOR SQLSTATE '99999'; +SIGNAL error SET +MESSAGE_TEXT = NULL; +end $$ +call test_signal() $$ +ERROR 42000: Variable 'MESSAGE_TEXT' can't be set to the value of 'NULL' +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE something CONDITION FOR SQLSTATE '99999'; +DECLARE message_text VARCHAR(64) DEFAULT "Local string variable"; +DECLARE sqlcode INTEGER DEFAULT 1234; +SIGNAL something SET +MESSAGE_TEXT = message_text, +MYSQL_ERRNO = sqlcode; +end $$ +call test_signal() $$ +ERROR 99999: Local string variable +drop procedure test_signal $$ +create procedure test_signal(message_text VARCHAR(64), sqlcode INTEGER) +begin +DECLARE something CONDITION FOR SQLSTATE "12345"; +SIGNAL something SET +MESSAGE_TEXT = message_text, +MYSQL_ERRNO = sqlcode; +end $$ +call test_signal("Parameter string", NULL) $$ +ERROR 42000: Variable 'MYSQL_ERRNO' can't be set to the value of 'NULL' +call test_signal(NULL, 1234) $$ +ERROR 42000: Variable 'MESSAGE_TEXT' can't be set to the value of 'NULL' +call test_signal("Parameter string", 5678) $$ +ERROR 12345: Parameter string +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE something CONDITION FOR SQLSTATE "AABBB"; +SIGNAL something SET +MESSAGE_TEXT = @message_text, +MYSQL_ERRNO = @sqlcode; +end $$ +call test_signal() $$ +ERROR 42000: Variable 'MESSAGE_TEXT' can't be set to the value of 'NULL' +set @sqlcode= 12 $$ +call test_signal() $$ +ERROR 42000: Variable 'MESSAGE_TEXT' can't be set to the value of 'NULL' +set @message_text= "User variable" $$ +call test_signal() $$ +ERROR AABBB: User variable +drop procedure test_signal $$ +create procedure test_invalid() +begin +DECLARE something CONDITION FOR SQLSTATE "AABBB"; +SIGNAL something SET +MESSAGE_TEXT = @message_text := 'illegal', +MYSQL_ERRNO = @sqlcode := 1234; +end $$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ' +MYSQL_ERRNO = @sqlcode := 1234; +end' at line 5 +create procedure test_signal() +begin +DECLARE aaa VARCHAR(64); +DECLARE bbb VARCHAR(64); +DECLARE ccc VARCHAR(64); +DECLARE ddd VARCHAR(64); +DECLARE eee VARCHAR(64); +DECLARE fff VARCHAR(64); +DECLARE ggg VARCHAR(64); +DECLARE hhh VARCHAR(64); +DECLARE iii VARCHAR(64); +DECLARE jjj VARCHAR(64); +DECLARE kkk VARCHAR(64); +DECLARE warn CONDITION FOR SQLSTATE "01234"; +set aaa= repeat("A", 64); +set bbb= repeat("B", 64); +set ccc= repeat("C", 64); +set ddd= repeat("D", 64); +set eee= repeat("E", 64); +set fff= repeat("F", 64); +set ggg= repeat("G", 64); +set hhh= repeat("H", 64); +set iii= repeat("I", 64); +set jjj= repeat("J", 64); +set kkk= repeat("K", 64); +SIGNAL warn SET +CLASS_ORIGIN = aaa, +SUBCLASS_ORIGIN = bbb, +CONSTRAINT_CATALOG = ccc, +CONSTRAINT_SCHEMA = ddd, +CONSTRAINT_NAME = eee, +CATALOG_NAME = fff, +SCHEMA_NAME = ggg, +TABLE_NAME = hhh, +COLUMN_NAME = iii, +CURSOR_NAME = jjj, +MESSAGE_TEXT = kkk, +MYSQL_ERRNO = 65535; +end $$ +call test_signal() $$ +Warnings: +Warning 65535 KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE warn CONDITION FOR SQLSTATE "01234"; +SIGNAL warn SET +MYSQL_ERRNO = 999999999999999999999999999999999999999999999999999; +end $$ +call test_signal() $$ +ERROR 42000: Variable 'MYSQL_ERRNO' can't be set to the value of '999999999999999999999999999999999999999999999999999' +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE aaax VARCHAR(65); +DECLARE bbbx VARCHAR(65); +DECLARE cccx VARCHAR(65); +DECLARE dddx VARCHAR(65); +DECLARE eeex VARCHAR(65); +DECLARE fffx VARCHAR(65); +DECLARE gggx VARCHAR(65); +DECLARE hhhx VARCHAR(65); +DECLARE iiix VARCHAR(65); +DECLARE jjjx VARCHAR(65); +DECLARE kkkx VARCHAR(65); +DECLARE lllx VARCHAR(129); +DECLARE warn CONDITION FOR SQLSTATE "01234"; +set aaax= concat(repeat("A", 64), "X"); +set bbbx= concat(repeat("B", 64), "X"); +set cccx= concat(repeat("C", 64), "X"); +set dddx= concat(repeat("D", 64), "X"); +set eeex= concat(repeat("E", 64), "X"); +set fffx= concat(repeat("F", 64), "X"); +set gggx= concat(repeat("G", 64), "X"); +set hhhx= concat(repeat("H", 64), "X"); +set iiix= concat(repeat("I", 64), "X"); +set jjjx= concat(repeat("J", 64), "X"); +set kkkx= concat(repeat("K", 64), "X"); +set lllx= concat(repeat("1", 100), +repeat("2", 20), +repeat("8", 8), +"X"); +SIGNAL warn SET +CLASS_ORIGIN = aaax, +SUBCLASS_ORIGIN = bbbx, +CONSTRAINT_CATALOG = cccx, +CONSTRAINT_SCHEMA = dddx, +CONSTRAINT_NAME = eeex, +CATALOG_NAME = fffx, +SCHEMA_NAME = gggx, +TABLE_NAME = hhhx, +COLUMN_NAME = iiix, +CURSOR_NAME = jjjx, +MESSAGE_TEXT = lllx, +MYSQL_ERRNO = 10000; +end $$ +call test_signal() $$ +Warnings: +Warning 1731 Data truncated for condition item CLASS_ORIGIN +Warning 1731 Data truncated for condition item SUBCLASS_ORIGIN +Warning 1731 Data truncated for condition item CONSTRAINT_CATALOG +Warning 1731 Data truncated for condition item CONSTRAINT_SCHEMA +Warning 1731 Data truncated for condition item CONSTRAINT_NAME +Warning 1731 Data truncated for condition item CATALOG_NAME +Warning 1731 Data truncated for condition item SCHEMA_NAME +Warning 1731 Data truncated for condition item TABLE_NAME +Warning 1731 Data truncated for condition item COLUMN_NAME +Warning 1731 Data truncated for condition item CURSOR_NAME +Warning 1731 Data truncated for condition item MESSAGE_TEXT +Warning 10000 11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111112222222222222222222288888888 +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE warn CONDITION FOR SQLSTATE "01234"; +DECLARE CONTINUE HANDLER for SQLSTATE "01234" + begin +select "Caught by SQLSTATE"; +end; +SIGNAL warn SET +MESSAGE_TEXT = "Raising a warning", +MYSQL_ERRNO = 1012; +end $$ +call test_signal() $$ +Caught by SQLSTATE +Caught by SQLSTATE +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE warn CONDITION FOR SQLSTATE "01234"; +DECLARE CONTINUE HANDLER for 1012 +begin +select "Caught by number"; +end; +SIGNAL warn SET +MESSAGE_TEXT = "Raising a warning", +MYSQL_ERRNO = 1012; +end $$ +call test_signal() $$ +Caught by number +Caught by number +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE warn CONDITION FOR SQLSTATE "01234"; +DECLARE CONTINUE HANDLER for SQLWARNING +begin +select "Caught by SQLWARNING"; +end; +SIGNAL warn SET +MESSAGE_TEXT = "Raising a warning", +MYSQL_ERRNO = 1012; +end $$ +call test_signal() $$ +Caught by SQLWARNING +Caught by SQLWARNING +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE not_found CONDITION FOR SQLSTATE "02ABC"; +DECLARE CONTINUE HANDLER for SQLSTATE "02ABC" + begin +select "Caught by SQLSTATE"; +end; +SIGNAL not_found SET +MESSAGE_TEXT = "Raising a not found", +MYSQL_ERRNO = 1012; +end $$ +call test_signal() $$ +Caught by SQLSTATE +Caught by SQLSTATE +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE not_found CONDITION FOR SQLSTATE "02ABC"; +DECLARE CONTINUE HANDLER for 1012 +begin +select "Caught by number"; +end; +SIGNAL not_found SET +MESSAGE_TEXT = "Raising a not found", +MYSQL_ERRNO = 1012; +end $$ +call test_signal() $$ +Caught by number +Caught by number +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE not_found CONDITION FOR SQLSTATE "02ABC"; +DECLARE CONTINUE HANDLER for NOT FOUND +begin +select "Caught by NOT FOUND"; +end; +SIGNAL not_found SET +MESSAGE_TEXT = "Raising a not found", +MYSQL_ERRNO = 1012; +end $$ +call test_signal() $$ +Caught by NOT FOUND +Caught by NOT FOUND +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE error CONDITION FOR SQLSTATE "55555"; +DECLARE CONTINUE HANDLER for SQLSTATE "55555" + begin +select "Caught by SQLSTATE"; +end; +SIGNAL error SET +MESSAGE_TEXT = "Raising an error", +MYSQL_ERRNO = 1012; +end $$ +call test_signal() $$ +Caught by SQLSTATE +Caught by SQLSTATE +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE error CONDITION FOR SQLSTATE "55555"; +DECLARE CONTINUE HANDLER for 1012 +begin +select "Caught by number"; +end; +SIGNAL error SET +MESSAGE_TEXT = "Raising an error", +MYSQL_ERRNO = 1012; +end $$ +call test_signal() $$ +Caught by number +Caught by number +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE error CONDITION FOR SQLSTATE "55555"; +DECLARE CONTINUE HANDLER for SQLEXCEPTION +begin +select "Caught by SQLEXCEPTION"; +end; +SIGNAL error SET +MESSAGE_TEXT = "Raising an error", +MYSQL_ERRNO = 1012; +end $$ +call test_signal() $$ +Caught by SQLEXCEPTION +Caught by SQLEXCEPTION +drop procedure test_signal $$ +create function test_signal_func() returns integer +begin +DECLARE warn CONDITION FOR SQLSTATE "01XXX"; +SIGNAL warn SET +MESSAGE_TEXT = "This function SIGNAL a warning", +MYSQL_ERRNO = 1012; +return 5; +end $$ +select test_signal_func() $$ +test_signal_func() +5 +Warnings: +Warning 1012 This function SIGNAL a warning +drop function test_signal_func $$ +create function test_signal_func() returns integer +begin +DECLARE not_found CONDITION FOR SQLSTATE "02XXX"; +SIGNAL not_found SET +MESSAGE_TEXT = "This function SIGNAL not found", +MYSQL_ERRNO = 1012; +return 5; +end $$ +select test_signal_func() $$ +ERROR 02XXX: This function SIGNAL not found +drop function test_signal_func $$ +create function test_signal_func() returns integer +begin +DECLARE error CONDITION FOR SQLSTATE "50000"; +SIGNAL error SET +MESSAGE_TEXT = "This function SIGNAL an error", +MYSQL_ERRNO = 1012; +return 5; +end $$ +select test_signal_func() $$ +ERROR 50000: This function SIGNAL an error +drop function test_signal_func $$ +drop table if exists t1 $$ +create table t1 (a integer) $$ +create trigger t1_ai after insert on t1 for each row +begin +DECLARE msg VARCHAR(128); +DECLARE warn CONDITION FOR SQLSTATE "01XXX"; +set msg= concat("This trigger SIGNAL a warning, a=", NEW.a); +SIGNAL warn SET +MESSAGE_TEXT = msg, +MYSQL_ERRNO = 1012; +end $$ +insert into t1 values (1), (2) $$ +Warnings: +Warning 1012 This trigger SIGNAL a warning, a=2 +drop trigger t1_ai $$ +create trigger t1_ai after insert on t1 for each row +begin +DECLARE msg VARCHAR(128); +DECLARE not_found CONDITION FOR SQLSTATE "02XXX"; +set msg= concat("This trigger SIGNAL a not found, a=", NEW.a); +SIGNAL not_found SET +MESSAGE_TEXT = msg, +MYSQL_ERRNO = 1012; +end $$ +insert into t1 values (3), (4) $$ +ERROR 02XXX: This trigger SIGNAL a not found, a=3 +drop trigger t1_ai $$ +create trigger t1_ai after insert on t1 for each row +begin +DECLARE msg VARCHAR(128); +DECLARE error CONDITION FOR SQLSTATE "03XXX"; +set msg= concat("This trigger SIGNAL an error, a=", NEW.a); +SIGNAL error SET +MESSAGE_TEXT = msg, +MYSQL_ERRNO = 1012; +end $$ +insert into t1 values (5), (6) $$ +ERROR 03XXX: This trigger SIGNAL an error, a=5 +drop table t1 $$ +create table t1 (errno integer, msg varchar(128)) $$ +create trigger t1_ai after insert on t1 for each row +begin +DECLARE warn CONDITION FOR SQLSTATE "01XXX"; +SIGNAL warn SET +MESSAGE_TEXT = NEW.msg, +MYSQL_ERRNO = NEW.errno; +end $$ +insert into t1 set errno=1012, msg='Warning message 1 in trigger' $$ +Warnings: +Warning 1012 Warning message 1 in trigger +insert into t1 set errno=1013, msg='Warning message 2 in trigger' $$ +Warnings: +Warning 1013 Warning message 2 in trigger +drop table t1 $$ +drop table if exists t1 $$ +drop procedure if exists p1 $$ +drop function if exists f1 $$ +create table t1 (s1 int) $$ +insert into t1 values (1) $$ +create procedure p1() +begin +declare a int; +declare c cursor for select f1() from t1; +declare continue handler for sqlstate '03000' + select "caught 03000"; +declare continue handler for 1326 +select "caught cursor is not open"; +select "Before open"; +open c; +select "Before fetch"; +fetch c into a; +select "Before close"; +close c; +end $$ +create function f1() returns int +begin +signal sqlstate '03000'; +return 5; +end $$ +drop table t1 $$ +drop procedure p1 $$ +drop function f1 $$ +create procedure test_resignal() +begin +DECLARE warn CONDITION FOR SQLSTATE "01234"; +DECLARE CONTINUE HANDLER for 1012 +begin +select "before RESIGNAL"; +RESIGNAL; +select "after RESIGNAL"; +end; +SIGNAL warn SET +MESSAGE_TEXT = "Raising a warning", +MYSQL_ERRNO = 1012; +end $$ +call test_resignal() $$ +before RESIGNAL +before RESIGNAL +after RESIGNAL +after RESIGNAL +Warnings: +Warning 1012 Raising a warning +drop procedure test_resignal $$ +create procedure test_resignal() +begin +DECLARE not_found CONDITION FOR SQLSTATE "02222"; +DECLARE CONTINUE HANDLER for 1012 +begin +select "before RESIGNAL"; +RESIGNAL; +select "after RESIGNAL"; +end; +SIGNAL not_found SET +MESSAGE_TEXT = "Raising a not found", +MYSQL_ERRNO = 1012; +end $$ +call test_resignal() $$ +before RESIGNAL +before RESIGNAL +ERROR 02222: Raising a not found +drop procedure test_resignal $$ +create procedure test_resignal() +begin +DECLARE error CONDITION FOR SQLSTATE "55555"; +DECLARE CONTINUE HANDLER for 1012 +begin +select "before RESIGNAL"; +RESIGNAL; +select "after RESIGNAL"; +end; +SIGNAL error SET +MESSAGE_TEXT = "Raising an error", +MYSQL_ERRNO = 1012; +end $$ +call test_resignal() $$ +before RESIGNAL +before RESIGNAL +ERROR 55555: Raising an error +drop procedure test_resignal $$ +create procedure test_resignal() +begin +DECLARE CONTINUE HANDLER for sqlwarning +begin +select "before RESIGNAL"; +RESIGNAL; +select "after RESIGNAL"; +end; +insert into t_warn set a= 9999999999999999; +end $$ +call test_resignal() $$ +before RESIGNAL +before RESIGNAL +after RESIGNAL +after RESIGNAL +Warnings: +Warning 1264 Out of range value for column 'a' at row 1 +drop procedure test_resignal $$ +create procedure test_resignal() +begin +DECLARE x integer; +DECLARE c cursor for select * from t_cursor; +DECLARE CONTINUE HANDLER for not found +begin +select "before RESIGNAL"; +RESIGNAL; +select "after RESIGNAL"; +end; +open c; +fetch c into x; +close c; +end $$ +call test_resignal() $$ +before RESIGNAL +before RESIGNAL +ERROR 02000: No data - zero rows fetched, selected, or processed +drop procedure test_resignal $$ +create procedure test_resignal() +begin +DECLARE CONTINUE HANDLER for sqlexception +begin +select "before RESIGNAL"; +RESIGNAL; +select "after RESIGNAL"; +end; +drop table no_such_table; +end $$ +call test_resignal() $$ +before RESIGNAL +before RESIGNAL +ERROR 42S02: Unknown table 'no_such_table' +drop procedure test_resignal $$ +create procedure test_resignal() +begin +DECLARE warn CONDITION FOR SQLSTATE "01234"; +DECLARE CONTINUE HANDLER for 1012 +begin +select "before RESIGNAL"; +RESIGNAL SET +MESSAGE_TEXT = "RESIGNAL of a warning", +MYSQL_ERRNO = 5555 ; +select "after RESIGNAL"; +end; +SIGNAL warn SET +MESSAGE_TEXT = "Raising a warning", +MYSQL_ERRNO = 1012; +end $$ +call test_resignal() $$ +before RESIGNAL +before RESIGNAL +after RESIGNAL +after RESIGNAL +Warnings: +Warning 5555 RESIGNAL of a warning +drop procedure test_resignal $$ +create procedure test_resignal() +begin +DECLARE not_found CONDITION FOR SQLSTATE "02111"; +DECLARE CONTINUE HANDLER for 1012 +begin +select "before RESIGNAL"; +RESIGNAL SET +MESSAGE_TEXT = "RESIGNAL of a not found", +MYSQL_ERRNO = 5555 ; +select "after RESIGNAL"; +end; +SIGNAL not_found SET +MESSAGE_TEXT = "Raising a not found", +MYSQL_ERRNO = 1012; +end $$ +call test_resignal() $$ +before RESIGNAL +before RESIGNAL +ERROR 02111: RESIGNAL of a not found +drop procedure test_resignal $$ +create procedure test_resignal() +begin +DECLARE error CONDITION FOR SQLSTATE "33333"; +DECLARE CONTINUE HANDLER for 1012 +begin +select "before RESIGNAL"; +RESIGNAL SET +MESSAGE_TEXT = "RESIGNAL of an error", +MYSQL_ERRNO = 5555 ; +select "after RESIGNAL"; +end; +SIGNAL error SET +MESSAGE_TEXT = "Raising an error", +MYSQL_ERRNO = 1012; +end $$ +call test_resignal() $$ +before RESIGNAL +before RESIGNAL +ERROR 33333: RESIGNAL of an error +drop procedure test_resignal $$ +create procedure test_resignal() +begin +DECLARE CONTINUE HANDLER for sqlwarning +begin +select "before RESIGNAL"; +RESIGNAL SET +MESSAGE_TEXT = "RESIGNAL of a warning", +MYSQL_ERRNO = 5555 ; +select "after RESIGNAL"; +end; +insert into t_warn set a= 9999999999999999; +end $$ +call test_resignal() $$ +before RESIGNAL +before RESIGNAL +after RESIGNAL +after RESIGNAL +Warnings: +Warning 5555 RESIGNAL of a warning +drop procedure test_resignal $$ +create procedure test_resignal() +begin +DECLARE x integer; +DECLARE c cursor for select * from t_cursor; +DECLARE CONTINUE HANDLER for not found +begin +select "before RESIGNAL"; +RESIGNAL SET +MESSAGE_TEXT = "RESIGNAL of not found", +MYSQL_ERRNO = 5555 ; +select "after RESIGNAL"; +end; +open c; +fetch c into x; +close c; +end $$ +call test_resignal() $$ +before RESIGNAL +before RESIGNAL +ERROR 02000: RESIGNAL of not found +drop procedure test_resignal $$ +create procedure test_resignal() +begin +DECLARE CONTINUE HANDLER for sqlexception +begin +select "before RESIGNAL"; +RESIGNAL SET +MESSAGE_TEXT = "RESIGNAL of an error", +MYSQL_ERRNO = 5555 ; +select "after RESIGNAL"; +end; +drop table no_such_table; +end $$ +call test_resignal() $$ +before RESIGNAL +before RESIGNAL +ERROR 42S02: RESIGNAL of an error +drop procedure test_resignal $$ +create procedure test_resignal() +begin +DECLARE warn CONDITION FOR SQLSTATE "01111"; +DECLARE CONTINUE HANDLER for 1012 +begin +select "before RESIGNAL"; +RESIGNAL SQLSTATE "01222" SET +MESSAGE_TEXT = "RESIGNAL to warning", +MYSQL_ERRNO = 5555 ; +select "after RESIGNAL"; +end; +SIGNAL warn SET +MESSAGE_TEXT = "Raising a warning", +MYSQL_ERRNO = 1012; +end $$ +call test_resignal() $$ +before RESIGNAL +before RESIGNAL +after RESIGNAL +after RESIGNAL +Warnings: +Warning 1012 Raising a warning +Warning 5555 RESIGNAL to warning +drop procedure test_resignal $$ +create procedure test_resignal() +begin +DECLARE warn CONDITION FOR SQLSTATE "01111"; +DECLARE CONTINUE HANDLER for 1012 +begin +select "before RESIGNAL"; +RESIGNAL SQLSTATE "02222" SET +MESSAGE_TEXT = "RESIGNAL to not found", +MYSQL_ERRNO = 5555 ; +select "after RESIGNAL"; +end; +SIGNAL warn SET +MESSAGE_TEXT = "Raising a warning", +MYSQL_ERRNO = 1012; +end $$ +call test_resignal() $$ +before RESIGNAL +before RESIGNAL +ERROR 02222: RESIGNAL to not found +show warnings $$ +Level Code Message +Warning 1012 Raising a warning +Error 5555 RESIGNAL to not found +drop procedure test_resignal $$ +create procedure test_resignal() +begin +DECLARE warn CONDITION FOR SQLSTATE "01111"; +DECLARE CONTINUE HANDLER for 1012 +begin +select "before RESIGNAL"; +RESIGNAL SQLSTATE "33333" SET +MESSAGE_TEXT = "RESIGNAL to error", +MYSQL_ERRNO = 5555 ; +select "after RESIGNAL"; +end; +SIGNAL warn SET +MESSAGE_TEXT = "Raising a warning", +MYSQL_ERRNO = 1012; +end $$ +call test_resignal() $$ +before RESIGNAL +before RESIGNAL +ERROR 33333: RESIGNAL to error +show warnings $$ +Level Code Message +Warning 1012 Raising a warning +Error 5555 RESIGNAL to error +drop procedure test_resignal $$ +create procedure test_resignal() +begin +DECLARE not_found CONDITION FOR SQLSTATE "02ABC"; +DECLARE CONTINUE HANDLER for 1012 +begin +select "before RESIGNAL"; +RESIGNAL SQLSTATE "01222" SET +MESSAGE_TEXT = "RESIGNAL to warning", +MYSQL_ERRNO = 5555 ; +select "after RESIGNAL"; +end; +SIGNAL not_found SET +MESSAGE_TEXT = "Raising a not found", +MYSQL_ERRNO = 1012; +end $$ +call test_resignal() $$ +before RESIGNAL +before RESIGNAL +after RESIGNAL +after RESIGNAL +Warnings: +Error 1012 Raising a not found +Warning 5555 RESIGNAL to warning +drop procedure test_resignal $$ +create procedure test_resignal() +begin +DECLARE not_found CONDITION FOR SQLSTATE "02ABC"; +DECLARE CONTINUE HANDLER for 1012 +begin +select "before RESIGNAL"; +RESIGNAL SQLSTATE "02222" SET +MESSAGE_TEXT = "RESIGNAL to not found", +MYSQL_ERRNO = 5555 ; +select "after RESIGNAL"; +end; +SIGNAL not_found SET +MESSAGE_TEXT = "Raising a not found", +MYSQL_ERRNO = 1012; +end $$ +call test_resignal() $$ +before RESIGNAL +before RESIGNAL +ERROR 02222: RESIGNAL to not found +show warnings $$ +Level Code Message +Error 1012 Raising a not found +Error 5555 RESIGNAL to not found +drop procedure test_resignal $$ +create procedure test_resignal() +begin +DECLARE not_found CONDITION FOR SQLSTATE "02ABC"; +DECLARE CONTINUE HANDLER for 1012 +begin +select "before RESIGNAL"; +RESIGNAL SQLSTATE "33333" SET +MESSAGE_TEXT = "RESIGNAL to error", +MYSQL_ERRNO = 5555 ; +select "after RESIGNAL"; +end; +SIGNAL not_found SET +MESSAGE_TEXT = "Raising a not found", +MYSQL_ERRNO = 1012; +end $$ +call test_resignal() $$ +before RESIGNAL +before RESIGNAL +ERROR 33333: RESIGNAL to error +show warnings $$ +Level Code Message +Error 1012 Raising a not found +Error 5555 RESIGNAL to error +drop procedure test_resignal $$ +create procedure test_resignal() +begin +DECLARE error CONDITION FOR SQLSTATE "AAAAA"; +DECLARE CONTINUE HANDLER for 1012 +begin +select "before RESIGNAL"; +RESIGNAL SQLSTATE "01222" SET +MESSAGE_TEXT = "RESIGNAL to warning", +MYSQL_ERRNO = 5555 ; +select "after RESIGNAL"; +end; +SIGNAL error SET +MESSAGE_TEXT = "Raising an error", +MYSQL_ERRNO = 1012; +end $$ +call test_resignal() $$ +before RESIGNAL +before RESIGNAL +after RESIGNAL +after RESIGNAL +Warnings: +Error 1012 Raising an error +Warning 5555 RESIGNAL to warning +drop procedure test_resignal $$ +create procedure test_resignal() +begin +DECLARE error CONDITION FOR SQLSTATE "AAAAA"; +DECLARE CONTINUE HANDLER for 1012 +begin +select "before RESIGNAL"; +RESIGNAL SQLSTATE "02222" SET +MESSAGE_TEXT = "RESIGNAL to not found", +MYSQL_ERRNO = 5555 ; +select "after RESIGNAL"; +end; +SIGNAL error SET +MESSAGE_TEXT = "Raising an error", +MYSQL_ERRNO = 1012; +end $$ +call test_resignal() $$ +before RESIGNAL +before RESIGNAL +ERROR 02222: RESIGNAL to not found +show warnings $$ +Level Code Message +Error 1012 Raising an error +Error 5555 RESIGNAL to not found +drop procedure test_resignal $$ +create procedure test_resignal() +begin +DECLARE error CONDITION FOR SQLSTATE "AAAAA"; +DECLARE CONTINUE HANDLER for 1012 +begin +select "before RESIGNAL"; +RESIGNAL SQLSTATE "33333" SET +MESSAGE_TEXT = "RESIGNAL to error", +MYSQL_ERRNO = 5555 ; +select "after RESIGNAL"; +end; +SIGNAL error SET +MESSAGE_TEXT = "Raising an error", +MYSQL_ERRNO = 1012; +end $$ +call test_resignal() $$ +before RESIGNAL +before RESIGNAL +ERROR 33333: RESIGNAL to error +show warnings $$ +Level Code Message +Error 1012 Raising an error +Error 5555 RESIGNAL to error +drop procedure test_resignal $$ +create procedure test_resignal() +begin +DECLARE CONTINUE HANDLER for sqlwarning +begin +select "before RESIGNAL"; +RESIGNAL SQLSTATE "01111" SET +MESSAGE_TEXT = "RESIGNAL to a warning", +MYSQL_ERRNO = 5555 ; +select "after RESIGNAL"; +end; +insert into t_warn set a= 9999999999999999; +end $$ +call test_resignal() $$ +before RESIGNAL +before RESIGNAL +after RESIGNAL +after RESIGNAL +Warnings: +Warning 1264 Out of range value for column 'a' at row 1 +Warning 5555 RESIGNAL to a warning +drop procedure test_resignal $$ +create procedure test_resignal() +begin +DECLARE CONTINUE HANDLER for sqlwarning +begin +select "before RESIGNAL"; +RESIGNAL SQLSTATE "02444" SET +MESSAGE_TEXT = "RESIGNAL to a not found", +MYSQL_ERRNO = 5555 ; +select "after RESIGNAL"; +end; +insert into t_warn set a= 9999999999999999; +end $$ +call test_resignal() $$ +before RESIGNAL +before RESIGNAL +ERROR 02444: RESIGNAL to a not found +show warnings $$ +Level Code Message +Warning 1264 Out of range value for column 'a' at row 1 +Error 5555 RESIGNAL to a not found +drop procedure test_resignal $$ +create procedure test_resignal() +begin +DECLARE CONTINUE HANDLER for sqlwarning +begin +select "before RESIGNAL"; +RESIGNAL SQLSTATE "44444" SET +MESSAGE_TEXT = "RESIGNAL to an error", +MYSQL_ERRNO = 5555 ; +select "after RESIGNAL"; +end; +insert into t_warn set a= 9999999999999999; +end $$ +call test_resignal() $$ +before RESIGNAL +before RESIGNAL +ERROR 44444: RESIGNAL to an error +show warnings $$ +Level Code Message +Warning 1264 Out of range value for column 'a' at row 1 +Error 5555 RESIGNAL to an error +drop procedure test_resignal $$ +create procedure test_resignal() +begin +DECLARE x integer; +DECLARE c cursor for select * from t_cursor; +DECLARE CONTINUE HANDLER for not found +begin +select "before RESIGNAL"; +RESIGNAL SQLSTATE "01111" SET +MESSAGE_TEXT = "RESIGNAL to a warning", +MYSQL_ERRNO = 5555 ; +select "after RESIGNAL"; +end; +open c; +fetch c into x; +close c; +end $$ +call test_resignal() $$ +before RESIGNAL +before RESIGNAL +after RESIGNAL +after RESIGNAL +Warnings: +Error 1329 No data - zero rows fetched, selected, or processed +Warning 5555 RESIGNAL to a warning +drop procedure test_resignal $$ +create procedure test_resignal() +begin +DECLARE x integer; +DECLARE c cursor for select * from t_cursor; +DECLARE CONTINUE HANDLER for not found +begin +select "before RESIGNAL"; +RESIGNAL SQLSTATE "02444" SET +MESSAGE_TEXT = "RESIGNAL to a not found", +MYSQL_ERRNO = 5555 ; +select "after RESIGNAL"; +end; +open c; +fetch c into x; +close c; +end $$ +call test_resignal() $$ +before RESIGNAL +before RESIGNAL +ERROR 02444: RESIGNAL to a not found +show warnings $$ +Level Code Message +Error 1329 No data - zero rows fetched, selected, or processed +Error 5555 RESIGNAL to a not found +drop procedure test_resignal $$ +create procedure test_resignal() +begin +DECLARE x integer; +DECLARE c cursor for select * from t_cursor; +DECLARE CONTINUE HANDLER for not found +begin +select "before RESIGNAL"; +RESIGNAL SQLSTATE "44444" SET +MESSAGE_TEXT = "RESIGNAL to an error", +MYSQL_ERRNO = 5555 ; +select "after RESIGNAL"; +end; +open c; +fetch c into x; +close c; +end $$ +call test_resignal() $$ +before RESIGNAL +before RESIGNAL +ERROR 44444: RESIGNAL to an error +show warnings $$ +Level Code Message +Error 1329 No data - zero rows fetched, selected, or processed +Error 5555 RESIGNAL to an error +drop procedure test_resignal $$ +create procedure test_resignal() +begin +DECLARE CONTINUE HANDLER for sqlexception +begin +select "before RESIGNAL"; +RESIGNAL SQLSTATE "01111" SET +MESSAGE_TEXT = "RESIGNAL to a warning", +MYSQL_ERRNO = 5555 ; +select "after RESIGNAL"; +end; +drop table no_such_table; +end $$ +call test_resignal() $$ +before RESIGNAL +before RESIGNAL +after RESIGNAL +after RESIGNAL +Warnings: +Error 1051 Unknown table 'no_such_table' +Warning 5555 RESIGNAL to a warning +drop procedure test_resignal $$ +create procedure test_resignal() +begin +DECLARE CONTINUE HANDLER for sqlexception +begin +select "before RESIGNAL"; +RESIGNAL SQLSTATE "02444" SET +MESSAGE_TEXT = "RESIGNAL to a not found", +MYSQL_ERRNO = 5555 ; +select "after RESIGNAL"; +end; +drop table no_such_table; +end $$ +call test_resignal() $$ +before RESIGNAL +before RESIGNAL +ERROR 02444: RESIGNAL to a not found +show warnings $$ +Level Code Message +Error 1051 Unknown table 'no_such_table' +Error 5555 RESIGNAL to a not found +drop procedure test_resignal $$ +create procedure test_resignal() +begin +DECLARE CONTINUE HANDLER for sqlexception +begin +select "before RESIGNAL"; +RESIGNAL SQLSTATE "44444" SET +MESSAGE_TEXT = "RESIGNAL to an error", +MYSQL_ERRNO = 5555 ; +select "after RESIGNAL"; +end; +drop table no_such_table; +end $$ +call test_resignal() $$ +before RESIGNAL +before RESIGNAL +ERROR 44444: RESIGNAL to an error +show warnings $$ +Level Code Message +Error 1051 Unknown table 'no_such_table' +Error 5555 RESIGNAL to an error +drop procedure test_resignal $$ +drop procedure if exists peter_p1 $$ +drop procedure if exists peter_p2 $$ +CREATE PROCEDURE peter_p1 () +BEGIN +DECLARE x CONDITION FOR 1231; +DECLARE EXIT HANDLER FOR x +BEGIN +SELECT '2'; +RESIGNAL SET MYSQL_ERRNO = 9999; +END; +BEGIN +DECLARE EXIT HANDLER FOR x +BEGIN +SELECT '1'; +RESIGNAL SET SCHEMA_NAME = 'test'; +END; +SET @@sql_mode=NULL; +END; +END +$$ +CREATE PROCEDURE peter_p2 () +BEGIN +DECLARE x CONDITION for 9999; +DECLARE EXIT HANDLER FOR x +BEGIN +SELECT '3'; +RESIGNAL SET MESSAGE_TEXT = 'Hi, I am a useless error message'; +END; +CALL peter_p1(); +END +$$ +CALL peter_p2() $$ +1 +1 +2 +2 +3 +3 +ERROR 42000: Hi, I am a useless error message +show warnings $$ +Level Code Message +Error 9999 Hi, I am a useless error message +drop procedure peter_p1 $$ +drop procedure peter_p2 $$ +CREATE PROCEDURE peter_p1 () +BEGIN +DECLARE x CONDITION FOR SQLSTATE '42000'; +DECLARE EXIT HANDLER FOR x +BEGIN +SELECT '2'; +RESIGNAL x SET MYSQL_ERRNO = 9999; +END; +BEGIN +DECLARE EXIT HANDLER FOR x +BEGIN +SELECT '1'; +RESIGNAL x SET +SCHEMA_NAME = 'test', +MYSQL_ERRNO= 1231; +END; +/* Raises ER_WRONG_VALUE_FOR_VAR : 1231, SQLSTATE 42000 */ +SET @@sql_mode=NULL; +END; +END +$$ +CREATE PROCEDURE peter_p2 () +BEGIN +DECLARE x CONDITION for SQLSTATE '42000'; +DECLARE EXIT HANDLER FOR x +BEGIN +SELECT '3'; +RESIGNAL x SET +MESSAGE_TEXT = 'Hi, I am a useless error message', +MYSQL_ERRNO = 9999; +END; +CALL peter_p1(); +END +$$ +CALL peter_p2() $$ +1 +1 +2 +2 +3 +3 +ERROR 42000: Hi, I am a useless error message +show warnings $$ +Level Code Message +Error 1231 Variable 'sql_mode' can't be set to the value of 'NULL' +Error 1231 Unhandled user-defined exception +Error 9999 Unhandled user-defined exception +Error 9999 Hi, I am a useless error message +drop procedure peter_p1 $$ +drop procedure peter_p2 $$ +drop table t_warn; +drop table t_cursor; === added file 'mysql-test/r/signal_code.result' --- a/mysql-test/r/signal_code.result 1970-01-01 00:00:00 +0000 +++ b/mysql-test/r/signal_code.result 2008-07-23 00:30:04 +0000 @@ -0,0 +1,35 @@ +use test; +drop procedure if exists signal_proc; +drop function if exists signal_func; +create procedure signal_proc() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +SIGNAL foo; +SIGNAL foo SET MESSAGE_TEXT = "This is an error message"; +RESIGNAL foo; +RESIGNAL foo SET MESSAGE_TEXT = "This is an error message"; +end $$ +create function signal_func() returns int +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +SIGNAL foo; +SIGNAL foo SET MESSAGE_TEXT = "This is an error message"; +RESIGNAL foo; +RESIGNAL foo SET MESSAGE_TEXT = "This is an error message"; +return 0; +end $$ +show procedure code signal_proc; +Pos Instruction +0 stmt 133 "SIGNAL foo" +1 stmt 133 "SIGNAL foo SET MESSAGE_TEXT = "This i..." +2 stmt 134 "RESIGNAL foo" +3 stmt 134 "RESIGNAL foo SET MESSAGE_TEXT = "This..." +drop procedure signal_proc; +show function code signal_func; +Pos Instruction +0 stmt 133 "SIGNAL foo" +1 stmt 133 "SIGNAL foo SET MESSAGE_TEXT = "This i..." +2 stmt 134 "RESIGNAL foo" +3 stmt 134 "RESIGNAL foo SET MESSAGE_TEXT = "This..." +4 freturn 3 0 +drop function signal_func; === added file 'mysql-test/r/signal_demo1.result' --- a/mysql-test/r/signal_demo1.result 1970-01-01 00:00:00 +0000 +++ b/mysql-test/r/signal_demo1.result 2008-07-23 00:30:04 +0000 @@ -0,0 +1,264 @@ +drop database if exists demo; +create database demo; +use demo; +create table ab_physical_person ( +person_id integer, +first_name VARCHAR(50), +middle_initial CHAR, +last_name VARCHAR(50), +primary key (person_id)); +create table ab_moral_person ( +company_id integer, +name VARCHAR(100), +primary key (company_id)); +create table in_inventory ( +item_id integer, +descr VARCHAR(50), +stock integer, +primary key (item_id)); +create table po_order ( +po_id integer auto_increment, +cust_type char, /* arc relationship, see cust_id */ +cust_id integer, /* FK to ab_physical_person *OR* ab_moral_person */ +primary key (po_id)); +create table po_order_line ( +po_id integer, /* FK to po_order.po_id */ +line_no integer, +item_id integer, /* FK to in_inventory.item_id */ +qty integer); +create procedure check_pk_person(in person_type char, in id integer) +begin +declare x integer; +declare msg varchar(128); +/* +Test integrity constraints for an 'arc' relationship. +Based on 'person_type', 'id' points to either a +physical person, or a moral person. +*/ +case person_type +when 'P' then +begin +select count(person_id) from ab_physical_person +where ab_physical_person.person_id = id +into x; +if (x != 1) +then +set msg= concat('No such physical person, PK:', id); +SIGNAL SQLSTATE '45000' SET +MESSAGE_TEXT = msg, +MYSQL_ERRNO = 10000; +end if; +end; +when 'M' then +begin +select count(company_id) from ab_moral_person +where ab_moral_person.company_id = id +into x; +if (x != 1) +then +set msg= concat('No such moral person, PK:', id); +SIGNAL SQLSTATE '45000' SET +MESSAGE_TEXT = msg, +MYSQL_ERRNO = 10000; +end if; +end; +else +begin +set msg= concat('No such person type:', person_type); +SIGNAL SQLSTATE '45000' SET +MESSAGE_TEXT = msg, +MYSQL_ERRNO = 20000; +end; +end case; +end +$$ +create procedure check_pk_inventory(in id integer) +begin +declare x integer; +declare msg varchar(128); +select count(item_id) from in_inventory +where in_inventory.item_id = id +into x; +if (x != 1) +then +set msg= concat('Failed integrity constraint, table in_inventory, PK:', +id); +SIGNAL SQLSTATE '45000' SET +MESSAGE_TEXT = msg, +MYSQL_ERRNO = 10000; +end if; +end +$$ +create procedure check_pk_order(in id integer) +begin +declare x integer; +declare msg varchar(128); +select count(po_id) from po_order +where po_order.po_id = id +into x; +if (x != 1) +then +set msg= concat('Failed integrity constraint, table po_order, PK:', id); +SIGNAL SQLSTATE '45000' SET +MESSAGE_TEXT = msg, +MYSQL_ERRNO = 10000; +end if; +end +$$ +create trigger po_order_bi before insert on po_order +for each row +begin +call check_pk_person(NEW.cust_type, NEW.cust_id); +end +$$ +create trigger po_order_bu before update on po_order +for each row +begin +call check_pk_person(NEW.cust_type, NEW.cust_id); +end +$$ +create trigger po_order_line_bi before insert on po_order_line +for each row +begin +call check_pk_order(NEW.po_id); +call check_pk_inventory(NEW.item_id); +end +$$ +create trigger po_order_line_bu before update on po_order_line +for each row +begin +call check_pk_order(NEW.po_id); +call check_pk_inventory(NEW.item_id); +end +$$ +create procedure po_create_order( +in p_cust_type char, +in p_cust_id integer, +out id integer) +begin +insert into po_order set cust_type = p_cust_type, cust_id = p_cust_id; +set id = last_insert_id(); +end +$$ +create procedure po_add_order_line( +in po integer, +in line integer, +in item integer, +in q integer) +begin +insert into po_order_line set +po_id = po, line_no = line, item_id = item, qty = q; +end +$$ +select "Create sample data"; +Create sample data +Create sample data +insert into ab_physical_person values +( 1, "John", "A", "Doe"), +( 2, "Marry", "B", "Smith") +; +insert into ab_moral_person values +( 3, "ACME real estate, INC"), +( 4, "Local school") +; +insert into in_inventory values +( 100, "Table, dinner", 5), +( 101, "Chair", 20), +( 200, "Table, coffee", 3), +( 300, "School table", 25), +( 301, "School chairs", 50) +; +select * from ab_physical_person order by person_id; +person_id first_name middle_initial last_name +1 John A Doe +2 Marry B Smith +select * from ab_moral_person order by company_id; +company_id name +3 ACME real estate, INC +4 Local school +select * from in_inventory order by item_id; +item_id descr stock +100 Table, dinner 5 +101 Chair 20 +200 Table, coffee 3 +300 School table 25 +301 School chairs 50 +select "Entering an order !"; +Entering an order ! +Entering an order ! +set @my_po = 0; +/* John Doe wants 1 table and 4 chairs */ +call po_create_order("P", 1, @my_po); +call po_add_order_line (@my_po, 1, 100, 1); +call po_add_order_line (@my_po, 2, 101, 4); +/* Marry Smith wants a coffee table */ +call po_create_order("P", 2, @my_po); +call po_add_order_line (@my_po, 1, 200, 1); +select "Entering bad data in an order"; +Entering bad data in an order +Entering bad data in an order +call po_add_order_line (@my_po, 1, 999, 1); +ERROR 45000: Failed integrity constraint, table in_inventory, PK:999 +select "Entering bad data in an unknown order"; +Entering bad data in an unknown order +Entering bad data in an unknown order +call po_add_order_line (99, 1, 100, 1); +ERROR 45000: Failed integrity constraint, table po_order, PK:99 +select "Entering an order for an unknown company"; +Entering an order for an unknown company +Entering an order for an unknown company +call po_create_order("M", 7, @my_po); +ERROR 45000: No such moral person, PK:7 +select "Entering an order for an unknown person type"; +Entering an order for an unknown person type +Entering an order for an unknown person type +call po_create_order("X", 1, @my_po); +ERROR 45000: No such person type:X +/* The local school wants 10 class tables and 20 chairs */ +call po_create_order("M", 4, @my_po); +call po_add_order_line (@my_po, 1, 300, 10); +call po_add_order_line (@my_po, 2, 301, 20); +select * from po_order; +po_id cust_type cust_id +1 P 1 +2 P 2 +3 M 4 +select * from po_order_line; +po_id line_no item_id qty +1 1 100 1 +1 2 101 4 +2 1 200 1 +3 1 300 10 +3 2 301 20 +select po_id as "PO#", +( case cust_type +when "P" then concat (pp.first_name, +" ", +pp.middle_initial, +" ", +pp.last_name) +when "M" then mp.name +end ) as "Sold to" + from po_order po +left join ab_physical_person pp on po.cust_id = pp.person_id +left join ab_moral_person mp on po.cust_id = company_id +; +PO# Sold to +1 John A Doe +2 Marry B Smith +3 Local school +select po_id as "PO#", +ol.line_no as "Line", +ol.item_id as "Item", +inv.descr as "Description", +ol.qty as "Quantity" + from po_order_line ol, in_inventory inv +where inv.item_id = ol.item_id +order by ol.item_id, ol.line_no; +PO# Line Item Description Quantity +1 1 100 Table, dinner 1 +1 2 101 Chair 4 +2 1 200 Table, coffee 1 +3 1 300 School table 10 +3 2 301 School chairs 20 +drop database demo; === added file 'mysql-test/r/signal_demo2.result' --- a/mysql-test/r/signal_demo2.result 1970-01-01 00:00:00 +0000 +++ b/mysql-test/r/signal_demo2.result 2008-07-23 00:30:04 +0000 @@ -0,0 +1,197 @@ +drop database if exists demo; +create database demo; +use demo; +create procedure proc_top_a(p1 integer) +begin +## DECLARE CONTINUE HANDLER for SQLEXCEPTION, NOT FOUND +begin +end; +select "Starting ..."; +call proc_middle_a(p1); +select "The end"; +end +$$ +create procedure proc_middle_a(p1 integer) +begin +DECLARE l integer; +# without RESIGNAL: +# Should be: DECLARE EXIT HANDLER for SQLEXCEPTION, NOT FOUND +DECLARE EXIT HANDLER for 1 /* not sure how to handle exceptions */ +begin +select "Oops ... now what ?"; +end; +select "In prod_middle()"; +create temporary table t1(a integer, b integer); +select GET_LOCK("user_mutex", 10) into l; +insert into t1 set a = p1, b = p1; +call proc_bottom_a(p1); +select RELEASE_LOCK("user_mutex") into l; +drop temporary table t1; +end +$$ +create procedure proc_bottom_a(p1 integer) +begin +select "In proc_bottom()"; +if (p1 = 1) then +begin +select "Doing something that works ..."; +select * from t1; +end; +end if; +if (p1 = 2) then +begin +select "Doing something that fail (simulate an error) ..."; +drop table no_such_table; +end; +end if; +if (p1 = 3) then +begin +select "Doing something that *SHOULD* works ..."; +select * from t1; +end; +end if; +end +$$ +call proc_top_a(1); +Starting ... +Starting ... +In prod_middle() +In prod_middle() +In proc_bottom() +In proc_bottom() +Doing something that works ... +Doing something that works ... +a b +1 1 +The end +The end +call proc_top_a(2); +Starting ... +Starting ... +In prod_middle() +In prod_middle() +In proc_bottom() +In proc_bottom() +Doing something that fail (simulate an error) ... +Doing something that fail (simulate an error) ... +ERROR 42S02: Unknown table 'no_such_table' +call proc_top_a(3); +Starting ... +Starting ... +In prod_middle() +In prod_middle() +ERROR 42S01: Table 't1' already exists +call proc_top_a(1); +Starting ... +Starting ... +In prod_middle() +In prod_middle() +ERROR 42S01: Table 't1' already exists +drop temporary table if exists t1; +create procedure proc_top_b(p1 integer) +begin +select "Starting ..."; +call proc_middle_b(p1); +select "The end"; +end +$$ +create procedure proc_middle_b(p1 integer) +begin +DECLARE l integer; +DECLARE EXIT HANDLER for SQLEXCEPTION, NOT FOUND +begin +begin +DECLARE CONTINUE HANDLER for SQLEXCEPTION, NOT FOUND +begin +/* Ignore errors from the cleanup code */ +end; +select "Doing cleanup !"; +select RELEASE_LOCK("user_mutex") into l; +drop temporary table t1; +end; +RESIGNAL; +end; +select "In prod_middle()"; +create temporary table t1(a integer, b integer); +select GET_LOCK("user_mutex", 10) into l; +insert into t1 set a = p1, b = p1; +call proc_bottom_b(p1); +select RELEASE_LOCK("user_mutex") into l; +drop temporary table t1; +end +$$ +create procedure proc_bottom_b(p1 integer) +begin +select "In proc_bottom()"; +if (p1 = 1) then +begin +select "Doing something that works ..."; +select * from t1; +end; +end if; +if (p1 = 2) then +begin +select "Doing something that fail (simulate an error) ..."; +drop table no_such_table; +end; +end if; +if (p1 = 3) then +begin +select "Doing something that *SHOULD* works ..."; +select * from t1; +end; +end if; +end +$$ +call proc_top_b(1); +Starting ... +Starting ... +In prod_middle() +In prod_middle() +In proc_bottom() +In proc_bottom() +Doing something that works ... +Doing something that works ... +a b +1 1 +The end +The end +call proc_top_b(2); +Starting ... +Starting ... +In prod_middle() +In prod_middle() +In proc_bottom() +In proc_bottom() +Doing something that fail (simulate an error) ... +Doing something that fail (simulate an error) ... +Doing cleanup ! +Doing cleanup ! +ERROR 42S02: Unknown table 'no_such_table' +call proc_top_b(3); +Starting ... +Starting ... +In prod_middle() +In prod_middle() +In proc_bottom() +In proc_bottom() +Doing something that *SHOULD* works ... +Doing something that *SHOULD* works ... +a b +3 3 +The end +The end +call proc_top_b(1); +Starting ... +Starting ... +In prod_middle() +In prod_middle() +In proc_bottom() +In proc_bottom() +Doing something that works ... +Doing something that works ... +a b +1 1 +The end +The end +drop database demo; === added file 'mysql-test/r/signal_demo3.result' --- a/mysql-test/r/signal_demo3.result 1970-01-01 00:00:00 +0000 +++ b/mysql-test/r/signal_demo3.result 2008-07-23 00:30:04 +0000 @@ -0,0 +1,143 @@ +SET @start_global_value = @@global.max_error_count; +SELECT @start_global_value; +@start_global_value +64 +SET @start_session_value = @@session.max_error_count; +SELECT @start_session_value; +@start_session_value +64 +drop database if exists demo; +create database demo; +use demo; +create procedure proc_1() +begin +declare exit handler for sqlexception +resignal sqlstate '45000' set message_text='Oops in proc_1'; +call proc_2(); +end +$$ +create procedure proc_2() +begin +declare exit handler for sqlexception +resignal sqlstate '45000' set message_text='Oops in proc_2'; +call proc_3(); +end +$$ +create procedure proc_3() +begin +declare exit handler for sqlexception +resignal sqlstate '45000' set message_text='Oops in proc_3'; +call proc_4(); +end +$$ +create procedure proc_4() +begin +declare exit handler for sqlexception +resignal sqlstate '45000' set message_text='Oops in proc_4'; +call proc_5(); +end +$$ +create procedure proc_5() +begin +declare exit handler for sqlexception +resignal sqlstate '45000' set message_text='Oops in proc_5'; +call proc_6(); +end +$$ +create procedure proc_6() +begin +declare exit handler for sqlexception +resignal sqlstate '45000' set message_text='Oops in proc_6'; +call proc_7(); +end +$$ +create procedure proc_7() +begin +declare exit handler for sqlexception +resignal sqlstate '45000' set message_text='Oops in proc_7'; +call proc_8(); +end +$$ +create procedure proc_8() +begin +declare exit handler for sqlexception +resignal sqlstate '45000' set message_text='Oops in proc_8'; +call proc_9(); +end +$$ +create procedure proc_9() +begin +declare exit handler for sqlexception +resignal sqlstate '45000' set message_text='Oops in proc_9'; +## Do something that fails, to see how errors are reported +drop table oops_it_is_not_here; +end +$$ +call proc_1(); +ERROR 45000: Oops in proc_1 +show warnings; +Level Code Message +Error 1051 Unknown table 'oops_it_is_not_here' +Error 1728 Oops in proc_9 +Error 1728 Oops in proc_8 +Error 1728 Oops in proc_7 +Error 1728 Oops in proc_6 +Error 1728 Oops in proc_5 +Error 1728 Oops in proc_4 +Error 1728 Oops in proc_3 +Error 1728 Oops in proc_2 +Error 1728 Oops in proc_1 +SET @@session.max_error_count = 5; +SELECT @@session.max_error_count; +@@session.max_error_count +5 +call proc_1(); +ERROR 45000: Oops in proc_1 +show warnings; +Level Code Message +Error 1728 Oops in proc_5 +Error 1728 Oops in proc_4 +Error 1728 Oops in proc_3 +Error 1728 Oops in proc_2 +Error 1728 Oops in proc_1 +SET @@session.max_error_count = 7; +SELECT @@session.max_error_count; +@@session.max_error_count +7 +call proc_1(); +ERROR 45000: Oops in proc_1 +show warnings; +Level Code Message +Error 1728 Oops in proc_7 +Error 1728 Oops in proc_6 +Error 1728 Oops in proc_5 +Error 1728 Oops in proc_4 +Error 1728 Oops in proc_3 +Error 1728 Oops in proc_2 +Error 1728 Oops in proc_1 +SET @@session.max_error_count = 9; +SELECT @@session.max_error_count; +@@session.max_error_count +9 +call proc_1(); +ERROR 45000: Oops in proc_1 +show warnings; +Level Code Message +Error 1728 Oops in proc_9 +Error 1728 Oops in proc_8 +Error 1728 Oops in proc_7 +Error 1728 Oops in proc_6 +Error 1728 Oops in proc_5 +Error 1728 Oops in proc_4 +Error 1728 Oops in proc_3 +Error 1728 Oops in proc_2 +Error 1728 Oops in proc_1 +drop database demo; +SET @@global.max_error_count = @start_global_value; +SELECT @@global.max_error_count; +@@global.max_error_count +64 +SET @@session.max_error_count = @start_session_value; +SELECT @@session.max_error_count; +@@session.max_error_count +64 === added file 'mysql-test/r/signal_sqlmode.result' --- a/mysql-test/r/signal_sqlmode.result 1970-01-01 00:00:00 +0000 +++ b/mysql-test/r/signal_sqlmode.result 2008-07-23 00:30:04 +0000 @@ -0,0 +1,86 @@ +SET @save_sql_mode=@@sql_mode; +SET sql_mode=''; +drop procedure if exists p; +drop procedure if exists p2; +drop procedure if exists p3; +create procedure p() +begin +declare utf8_var VARCHAR(128) CHARACTER SET UTF8; +set utf8_var = concat(repeat('A', 128), 'X'); +select length(utf8_var), utf8_var; +end +$$ +create procedure p2() +begin +declare msg VARCHAR(129) CHARACTER SET UTF8; +set msg = concat(repeat('A', 128), 'X'); +select length(msg), msg; +signal sqlstate '55555' set message_text = msg; +end +$$ +create procedure p3() +begin +declare name VARCHAR(65) CHARACTER SET UTF8; +set name = concat(repeat('A', 64), 'X'); +select length(name), name; +signal sqlstate '55555' set +message_text = 'Message', +table_name = name; +end +$$ +call p; +length(utf8_var) utf8_var +128 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +Warnings: +Warning 1265 Data truncated for column 'utf8_var' at row 1 +call p2; +length(msg) msg +129 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAX +ERROR 55555: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +call p3; +length(name) name +65 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAX +ERROR 55555: Message +drop procedure p; +drop procedure p2; +drop procedure p3; +SET sql_mode='STRICT_ALL_TABLES'; +create procedure p() +begin +declare utf8_var VARCHAR(128) CHARACTER SET UTF8; +set utf8_var = concat(repeat('A', 128), 'X'); +select length(utf8_var), utf8_var; +end +$$ +create procedure p2() +begin +declare msg VARCHAR(129) CHARACTER SET UTF8; +set msg = concat(repeat('A', 128), 'X'); +select length(msg), msg; +signal sqlstate '55555' set message_text = msg; +end +$$ +create procedure p3() +begin +declare name VARCHAR(65) CHARACTER SET UTF8; +set name = concat(repeat('A', 64), 'X'); +select length(name), name; +signal sqlstate '55555' set +message_text = 'Message', +table_name = name; +end +$$ +call p; +ERROR 22001: Data too long for column 'utf8_var' at row 1 +call p2; +length(msg) msg +129 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAX +ERROR HY000: Data too long for condition item MESSAGE_TEXT +call p3; +length(name) name +65 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAX +ERROR HY000: Data too long for condition item TABLE_NAME +drop procedure p; +drop procedure p2; +drop procedure p3; +SET @@sql_mode=@save_sql_mode; === added file 'mysql-test/r/signal_utf32.result' --- a/mysql-test/r/signal_utf32.result 1970-01-01 00:00:00 +0000 +++ b/mysql-test/r/signal_utf32.result 2008-07-23 00:30:04 +0000 @@ -0,0 +1,34 @@ +drop procedure if exists test_signal; +create procedure test_signal() +begin +DECLARE something CONDITION FOR SQLSTATE "01000"; +SIGNAL something SET MESSAGE_TEXT = +_utf32 'a'; +end $$ +call test_signal() $$ +Warnings: +Warning 1726 a +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE something CONDITION FOR SQLSTATE "01000"; +SIGNAL something SET MESSAGE_TEXT = +_utf32 X'00000048000000450000004C0000004C0000004F'; +end $$ +call test_signal() $$ +Warnings: +Warning 1726 HELLO +drop procedure test_signal $$ +create procedure test_signal() +begin +declare continue handler for sqlexception +begin +declare msg varchar(128); +set msg= repeat(_utf32 0x000100cc, 128); +resignal set message_text = msg; +end; +signal sqlstate '77777'; +end $$ +call test_signal() $$ +ERROR 77777: ???????????????????????????????????????????????????????????????? +drop procedure test_signal $$ === modified file 'mysql-test/r/symlink.result' --- a/mysql-test/r/symlink.result 2008-04-14 10:15:04 +0000 +++ b/mysql-test/r/symlink.result 2008-07-23 00:30:04 +0000 @@ -83,7 +83,7 @@ drop database mysqltest; create table t1 (a int not null) engine=myisam; alter table t1 data directory="MYSQLTEST_VARDIR/tmp"; Warnings: -Warning 0 DATA DIRECTORY option ignored +Warning 1105 DATA DIRECTORY option ignored show create table t1; Table Create Table t1 CREATE TABLE `t1` ( @@ -92,7 +92,7 @@ t1 CREATE TABLE `t1` ( alter table t1 add b int; alter table t1 data directory="MYSQLTEST_VARDIR/log"; Warnings: -Warning 0 DATA DIRECTORY option ignored +Warning 1105 DATA DIRECTORY option ignored show create table t1; Table Create Table t1 CREATE TABLE `t1` ( @@ -101,7 +101,7 @@ t1 CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1 alter table t1 index directory="MYSQLTEST_VARDIR/log"; Warnings: -Warning 0 INDEX DIRECTORY option ignored +Warning 1105 INDEX DIRECTORY option ignored show create table t1; Table Create Table t1 CREATE TABLE `t1` ( @@ -168,8 +168,8 @@ ERROR HY000: Can't create/write to file SET @OLD_SQL_MODE=@@SQL_MODE, @@SQL_MODE='NO_DIR_IN_CREATE'; CREATE TABLE t1(a INT) DATA DIRECTORY='MYSQLTEST_VARDIR/tmp' INDEX DIRECTORY='MYSQLTEST_VARDIR/tmp'; Warnings: -Warning 0 DATA DIRECTORY option ignored -Warning 0 INDEX DIRECTORY option ignored +Warning 1105 DATA DIRECTORY option ignored +Warning 1105 INDEX DIRECTORY option ignored DROP TABLE t1; SET @@SQL_MODE=@OLD_SQL_MODE; End of 5.1 tests === modified file 'mysql-test/r/windows.result' --- a/mysql-test/r/windows.result 2007-11-18 13:33:12 +0000 +++ b/mysql-test/r/windows.result 2008-07-23 00:30:04 +0000 @@ -9,8 +9,8 @@ drop table nu; drop table if exists t1; CREATE TABLE t1 ( `ID` int(6) ) data directory 'c:/tmp/' index directory 'c:/tmp/' engine=MyISAM; Warnings: -Warning 0 DATA DIRECTORY option ignored -Warning 0 INDEX DIRECTORY option ignored +Warning 1105 DATA DIRECTORY option ignored +Warning 1105 INDEX DIRECTORY option ignored drop table t1; CREATE TABLE t1 (a int, b int); INSERT INTO t1 VALUES (1,1); === added file 'mysql-test/t/signal.test' --- a/mysql-test/t/signal.test 1970-01-01 00:00:00 +0000 +++ b/mysql-test/t/signal.test 2008-07-23 00:30:04 +0000 @@ -0,0 +1,2485 @@ +# Copyright (C) 2008 Sun Microsystems, Inc +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +# Tests for SIGNAL and RESIGNAL + +# +# PART 1: syntax +# + +# +# Test every new reserved and non reserved keywords +# + +--disable_warnings +drop table if exists signal_non_reserved; +--enable_warnings + +create table signal_non_reserved ( + class_origin int, + subclass_origin int, + constraint_catalog int, + constraint_schema int, + constraint_name int, + catalog_name int, + schema_name int, + table_name int, + column_name int, + cursor_name int, + message_text int, + sqlcode int +); + +drop table signal_non_reserved; + +--disable_warnings +drop table if exists diag_non_reserved; +--enable_warnings + +create table diag_non_reserved ( + diagnostics int, + current int, + stacked int, + exception int +); + +drop table diag_non_reserved; + +--disable_warnings +drop table if exists diag_cond_non_reserved; +--enable_warnings + +create table diag_cond_non_reserved ( + condition_identifier int, + condition_number int, + condition_name int, + connection_name int, + message_length int, + message_octet_length int, + parameter_mode int, + parameter_name int, + parameter_ordinal_position int, + returned_sqlstate int, + routine_catalog int, + routine_name int, + routine_schema int, + server_name int, + specific_name int, + trigger_catalog int, + trigger_name int, + trigger_schema int +); + +drop table diag_cond_non_reserved; + +--disable_warnings +drop table if exists diag_stmt_non_reserved; +--enable_warnings + +create table diag_stmt_non_reserved ( + number int, + more int, + command_function int, + command_function_code int, + dynamic_function int, + dynamic_function_code int, + row_count int, + transactions_committed int, + transactions_rolled_back int, + transaction_active int +); + +drop table diag_stmt_non_reserved; + +--disable_warnings +drop table if exists test_reserved; +--enable_warnings + +--error ER_PARSE_ERROR +create table test_reserved (signal int); + +--error ER_PARSE_ERROR +create table test_reserved (resignal int); + +--error ER_PARSE_ERROR +create table test_reserved (condition int); + +# +# Test the SIGNAL syntax +# + +--disable_warnings +drop procedure if exists test_invalid; +drop procedure if exists test_signal_syntax; +drop function if exists test_signal_func; +--enable_warnings + +delimiter $$; + +--error ER_PARSE_ERROR +create procedure test_invalid() +begin + SIGNAL; +end $$ + +--error ER_SP_COND_MISMATCH +create procedure test_invalid() +begin + SIGNAL foo; +end $$ + +--error ER_SIGNAL_BAD_CONDITION_TYPE +create procedure test_invalid() +begin + DECLARE foo CONDITION FOR 1234; + SIGNAL foo; +end $$ + +create procedure test_signal_syntax() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + SIGNAL foo; +end $$ +drop procedure test_signal_syntax $$ + +create procedure test_signal_syntax() +begin + SIGNAL SQLSTATE '23000'; +end $$ +drop procedure test_signal_syntax $$ + +create procedure test_signal_syntax() +begin + SIGNAL SQLSTATE VALUE '23000'; +end $$ +drop procedure test_signal_syntax $$ + +create procedure test_signal_syntax() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + SIGNAL foo SET CLASS_ORIGIN = 'foo'; +end $$ +drop procedure test_signal_syntax $$ + +create procedure test_signal_syntax() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + SIGNAL foo SET SUBCLASS_ORIGIN = 'foo'; +end $$ +drop procedure test_signal_syntax $$ + +create procedure test_signal_syntax() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + SIGNAL foo SET CONSTRAINT_CATALOG = 'foo'; +end $$ +drop procedure test_signal_syntax $$ + +create procedure test_signal_syntax() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + SIGNAL foo SET CONSTRAINT_SCHEMA = 'foo'; +end $$ +drop procedure test_signal_syntax $$ + +create procedure test_signal_syntax() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + SIGNAL foo SET CONSTRAINT_NAME = 'foo'; +end $$ +drop procedure test_signal_syntax $$ + +create procedure test_signal_syntax() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + SIGNAL foo SET CATALOG_NAME = 'foo'; +end $$ +drop procedure test_signal_syntax $$ + +create procedure test_signal_syntax() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + SIGNAL foo SET SCHEMA_NAME = 'foo'; +end $$ +drop procedure test_signal_syntax $$ + +create procedure test_signal_syntax() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + SIGNAL foo SET TABLE_NAME = 'foo'; +end $$ +drop procedure test_signal_syntax $$ + +create procedure test_signal_syntax() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + SIGNAL foo SET COLUMN_NAME = 'foo'; +end $$ +drop procedure test_signal_syntax $$ + +create procedure test_signal_syntax() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + SIGNAL foo SET CURSOR_NAME = 'foo'; +end $$ +drop procedure test_signal_syntax $$ + +create procedure test_signal_syntax() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + SIGNAL foo SET MESSAGE_TEXT = 'foo'; +end $$ +drop procedure test_signal_syntax $$ + +create procedure test_signal_syntax() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + SIGNAL foo SET MYSQL_ERRNO = 'foo'; +end $$ +drop procedure test_signal_syntax $$ + +--error ER_DUP_SIGNAL_SET +create procedure test_invalid() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + SIGNAL foo SET CLASS_ORIGIN = 'foo', CLASS_ORIGIN = 'bar'; +end $$ + +--error ER_DUP_SIGNAL_SET +create procedure test_invalid() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + SIGNAL foo SET MESSAGE_TEXT = 'foo', MESSAGE_TEXT = 'bar'; +end $$ + +--error ER_DUP_SIGNAL_SET +create procedure test_invalid() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + SIGNAL foo SET MYSQL_ERRNO = 'foo', MYSQL_ERRNO = 'bar'; +end $$ + +create procedure test_signal_syntax() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + SIGNAL foo SET + CLASS_ORIGIN = 'foo', + SUBCLASS_ORIGIN = 'foo', + CONSTRAINT_CATALOG = 'foo', + CONSTRAINT_SCHEMA = 'foo', + CONSTRAINT_NAME = 'foo', + CATALOG_NAME = 'foo', + SCHEMA_NAME = 'foo', + TABLE_NAME = 'foo', + COLUMN_NAME = 'foo', + CURSOR_NAME = 'foo', + MESSAGE_TEXT = 'foo', + MYSQL_ERRNO = 'foo'; +end $$ +drop procedure test_signal_syntax $$ + +--error ER_SP_BAD_SQLSTATE +SIGNAL SQLSTATE '00000' $$ + +--error ER_SP_BAD_SQLSTATE +SIGNAL SQLSTATE '00001' $$ + +--error ER_SP_BAD_SQLSTATE +create procedure test_invalid() +begin + SIGNAL SQLSTATE '00000'; +end $$ + +--error ER_SP_BAD_SQLSTATE +create procedure test_invalid() +begin + SIGNAL SQLSTATE '00001'; +end $$ + + +# +# Test conditions information that SIGNAL can not set +# + +--error ER_PARSE_ERROR +create procedure test_invalid() +begin + SIGNAL SQLSTATE '12345' SET bla_bla = 'foo'; +end $$ + +--error ER_PARSE_ERROR +create procedure test_invalid() +begin + SIGNAL SQLSTATE '12345' SET CONDITION_IDENTIFIER = 'foo'; +end $$ + +--error ER_PARSE_ERROR +create procedure test_invalid() +begin + SIGNAL SQLSTATE '12345' SET CONDITION_NUMBER = 'foo'; +end $$ + +--error ER_PARSE_ERROR +create procedure test_invalid() +begin + SIGNAL SQLSTATE '12345' SET CONNECTION_NAME = 'foo'; +end $$ + +--error ER_PARSE_ERROR +create procedure test_invalid() +begin + SIGNAL SQLSTATE '12345' SET MESSAGE_LENGTH = 'foo'; +end $$ + +--error ER_PARSE_ERROR +create procedure test_invalid() +begin + SIGNAL SQLSTATE '12345' SET MESSAGE_OCTET_LENGTH = 'foo'; +end $$ + +--error ER_PARSE_ERROR +create procedure test_invalid() +begin + SIGNAL SQLSTATE '12345' SET PARAMETER_MODE = 'foo'; +end $$ + +--error ER_PARSE_ERROR +create procedure test_invalid() +begin + SIGNAL SQLSTATE '12345' SET PARAMETER_NAME = 'foo'; +end $$ + +--error ER_PARSE_ERROR +create procedure test_invalid() +begin + SIGNAL SQLSTATE '12345' SET PARAMETER_ORDINAL_POSITION = 'foo'; +end $$ + +--error ER_PARSE_ERROR +create procedure test_invalid() +begin + SIGNAL SQLSTATE '12345' SET RETURNED_SQLSTATE = 'foo'; +end $$ + +--error ER_PARSE_ERROR +create procedure test_invalid() +begin + SIGNAL SQLSTATE '12345' SET ROUTINE_CATALOG = 'foo'; +end $$ + +--error ER_PARSE_ERROR +create procedure test_invalid() +begin + SIGNAL SQLSTATE '12345' SET ROUTINE_NAME = 'foo'; +end $$ + +--error ER_PARSE_ERROR +create procedure test_invalid() +begin + SIGNAL SQLSTATE '12345' SET ROUTINE_SCHEMA = 'foo'; +end $$ + +--error ER_PARSE_ERROR +create procedure test_invalid() +begin + SIGNAL SQLSTATE '12345' SET SERVER_NAME = 'foo'; +end $$ + +--error ER_PARSE_ERROR +create procedure test_invalid() +begin + SIGNAL SQLSTATE '12345' SET SPECIFIC_NAME = 'foo'; +end $$ + +--error ER_PARSE_ERROR +create procedure test_invalid() +begin + SIGNAL SQLSTATE '12345' SET TRIGGER_CATALOG = 'foo'; +end $$ + +--error ER_PARSE_ERROR +create procedure test_invalid() +begin + SIGNAL SQLSTATE '12345' SET TRIGGER_NAME = 'foo'; +end $$ + +--error ER_PARSE_ERROR +create procedure test_invalid() +begin + SIGNAL SQLSTATE '12345' SET TRIGGER_SCHEMA = 'foo'; +end $$ + +delimiter ;$$ + +# +# Test the RESIGNAL syntax +# + +--disable_warnings +drop procedure if exists test_invalid; +drop procedure if exists test_resignal_syntax; +--enable_warnings + +delimiter $$; + +--error ER_SP_COND_MISMATCH +create procedure test_invalid() +begin + RESIGNAL foo; +end $$ + +create procedure test_resignal_syntax() +begin + RESIGNAL; +end $$ +drop procedure test_resignal_syntax $$ + +--error ER_SIGNAL_BAD_CONDITION_TYPE +create procedure test_invalid() +begin + DECLARE foo CONDITION FOR 1234; + RESIGNAL foo; +end $$ + +create procedure test_resignal_syntax() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + RESIGNAL foo; +end $$ +drop procedure test_resignal_syntax $$ + +create procedure test_resignal_syntax() +begin + RESIGNAL SQLSTATE '23000'; +end $$ +drop procedure test_resignal_syntax $$ + +create procedure test_resignal_syntax() +begin + RESIGNAL SQLSTATE VALUE '23000'; +end $$ +drop procedure test_resignal_syntax $$ + +create procedure test_resignal_syntax() +begin + RESIGNAL SET CLASS_ORIGIN = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ + +create procedure test_resignal_syntax() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + RESIGNAL foo SET CLASS_ORIGIN = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ + +create procedure test_resignal_syntax() +begin + RESIGNAL SET SUBCLASS_ORIGIN = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ + +create procedure test_resignal_syntax() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + RESIGNAL foo SET SUBCLASS_ORIGIN = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ + +create procedure test_resignal_syntax() +begin + RESIGNAL SET CONSTRAINT_CATALOG = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ + +create procedure test_resignal_syntax() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + RESIGNAL foo SET CONSTRAINT_CATALOG = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ + +create procedure test_resignal_syntax() +begin + RESIGNAL SET CONSTRAINT_SCHEMA = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ + +create procedure test_resignal_syntax() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + RESIGNAL foo SET CONSTRAINT_SCHEMA = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ + +create procedure test_resignal_syntax() +begin + RESIGNAL SET CONSTRAINT_NAME = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ + +create procedure test_resignal_syntax() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + RESIGNAL foo SET CONSTRAINT_NAME = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ + +create procedure test_resignal_syntax() +begin + RESIGNAL SET CATALOG_NAME = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ + +create procedure test_resignal_syntax() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + RESIGNAL foo SET CATALOG_NAME = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ + +create procedure test_resignal_syntax() +begin + RESIGNAL SET SCHEMA_NAME = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ + +create procedure test_resignal_syntax() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + RESIGNAL foo SET SCHEMA_NAME = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ + +create procedure test_resignal_syntax() +begin + RESIGNAL SET TABLE_NAME = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ + +create procedure test_resignal_syntax() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + RESIGNAL foo SET TABLE_NAME = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ + +create procedure test_resignal_syntax() +begin + RESIGNAL SET COLUMN_NAME = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ + +create procedure test_resignal_syntax() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + RESIGNAL foo SET COLUMN_NAME = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ + +create procedure test_resignal_syntax() +begin + RESIGNAL SET CURSOR_NAME = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ + +create procedure test_resignal_syntax() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + RESIGNAL foo SET CURSOR_NAME = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ + +create procedure test_resignal_syntax() +begin + RESIGNAL SET MESSAGE_TEXT = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ + +create procedure test_resignal_syntax() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + RESIGNAL foo SET MESSAGE_TEXT = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ + +create procedure test_resignal_syntax() +begin + RESIGNAL SET MYSQL_ERRNO = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ + +create procedure test_resignal_syntax() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + RESIGNAL foo SET MYSQL_ERRNO = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ + +--error ER_DUP_SIGNAL_SET +create procedure test_invalid() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + RESIGNAL foo SET CLASS_ORIGIN = 'foo', CLASS_ORIGIN = 'bar'; +end $$ + +--error ER_DUP_SIGNAL_SET +create procedure test_invalid() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + RESIGNAL foo SET MESSAGE_TEXT = 'foo', MESSAGE_TEXT = 'bar'; +end $$ + +--error ER_DUP_SIGNAL_SET +create procedure test_invalid() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + RESIGNAL foo SET MYSQL_ERRNO = 'foo', MYSQL_ERRNO = 'bar'; +end $$ + +create procedure test_resignal_syntax() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + RESIGNAL foo SET + CLASS_ORIGIN = 'foo', + SUBCLASS_ORIGIN = 'foo', + CONSTRAINT_CATALOG = 'foo', + CONSTRAINT_SCHEMA = 'foo', + CONSTRAINT_NAME = 'foo', + CATALOG_NAME = 'foo', + SCHEMA_NAME = 'foo', + TABLE_NAME = 'foo', + COLUMN_NAME = 'foo', + CURSOR_NAME = 'foo', + MESSAGE_TEXT = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ + +--error ER_SP_BAD_SQLSTATE +create procedure test_invalid() +begin + RESIGNAL SQLSTATE '00000'; +end $$ + +delimiter ;$$ + +# +# PART 2: non preparable statements +# + +--error ER_UNSUPPORTED_PS +prepare stmt from 'SIGNAL SQLSTATE \'23000\''; + +--error ER_UNSUPPORTED_PS +prepare stmt from 'RESIGNAL SQLSTATE \'23000\''; + +# +# PART 3: runtime execution +# + +--disable_warnings +drop procedure if exists test_signal; +drop procedure if exists test_resignal; +drop table if exists t_warn; +drop table if exists t_cursor; +--enable_warnings + +# Helper tables +create table t_warn(a integer(2)); +create table t_cursor(a integer); + +# +# SIGNAL can also appear in a query +# + +--error ER_SP_COND_MISMATCH +SIGNAL foo; + +SIGNAL SQLSTATE '01000'; + +--error ER_SIGNAL_NOT_FOUND +SIGNAL SQLSTATE '02000'; + +--error ER_SIGNAL_EXCEPTION +SIGNAL SQLSTATE '23000'; + +--error ER_SIGNAL_EXCEPTION +SIGNAL SQLSTATE VALUE '23000'; + +--error ER_WRONG_VALUE_FOR_VAR +SIGNAL SQLSTATE 'HY000' SET MYSQL_ERRNO = 65536; + +--error ER_WRONG_VALUE_FOR_VAR +SIGNAL SQLSTATE 'HY000' SET MYSQL_ERRNO = 99999; + +--error ER_WRONG_VALUE_FOR_VAR +SIGNAL SQLSTATE 'HY000' SET MYSQL_ERRNO = 4294967295; + +--error ER_WRONG_VALUE_FOR_VAR +SIGNAL SQLSTATE 'HY000' SET MYSQL_ERRNO = 0; + +--error ER_PARSE_ERROR +SIGNAL SQLSTATE 'HY000' SET MYSQL_ERRNO = -1; + +--error 65535 +SIGNAL SQLSTATE 'HY000' SET MYSQL_ERRNO = 65535; + +# +# RESIGNAL can also appear in a query +# + +--error ER_RESIGNAL_NO_HANDLER +RESIGNAL; + +--error ER_SP_COND_MISMATCH +RESIGNAL foo; + +--error ER_RESIGNAL_NO_HANDLER +RESIGNAL SQLSTATE '12345'; + +--error ER_RESIGNAL_NO_HANDLER +RESIGNAL SQLSTATE VALUE '12345'; + +# +# Different kind of SIGNAL conditions +# + +delimiter $$; + +create procedure test_signal() +begin + # max range + DECLARE foo CONDITION FOR SQLSTATE 'AABBB'; + SIGNAL foo SET MYSQL_ERRNO = 65535; +end $$ + +--error 65535 +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + # max range + DECLARE foo CONDITION FOR SQLSTATE 'AABBB'; + SIGNAL foo SET MYSQL_ERRNO = 65536; +end $$ + +--error ER_WRONG_VALUE_FOR_VAR +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + # Error + DECLARE foo CONDITION FOR SQLSTATE '99999'; + SIGNAL foo SET MYSQL_ERRNO = 9999; +end $$ + +--error 9999 +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + # warning + DECLARE too_few_records CONDITION FOR SQLSTATE '01000'; + SIGNAL too_few_records SET MYSQL_ERRNO = 1261; +end $$ + +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + # Not found + DECLARE sp_fetch_no_data CONDITION FOR SQLSTATE '02000'; + SIGNAL sp_fetch_no_data SET MYSQL_ERRNO = 1329; +end $$ + +--error ER_SP_FETCH_NO_DATA +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + # Error + DECLARE sp_cursor_already_open CONDITION FOR SQLSTATE '24000'; + SIGNAL sp_cursor_already_open SET MYSQL_ERRNO = 1325; +end $$ + +--error ER_SP_CURSOR_ALREADY_OPEN +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + # Severe error + DECLARE lock_deadlock CONDITION FOR SQLSTATE '40001'; + SIGNAL lock_deadlock SET MYSQL_ERRNO = 1213; +end $$ + +--error ER_LOCK_DEADLOCK +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + # Unknown -> error + DECLARE foo CONDITION FOR SQLSTATE "99999"; + SIGNAL foo; +end $$ + +--error ER_SIGNAL_EXCEPTION +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + # warning, no subclass + DECLARE warn CONDITION FOR SQLSTATE "01000"; + SIGNAL warn; +end $$ + +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + # warning, with subclass + DECLARE warn CONDITION FOR SQLSTATE "01123"; + SIGNAL warn; +end $$ + +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + # Not found, no subclass + DECLARE not_found CONDITION FOR SQLSTATE "02000"; + SIGNAL not_found; +end $$ + +--error ER_SIGNAL_NOT_FOUND +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + # Not found, with subclass + DECLARE not_found CONDITION FOR SQLSTATE "02XXX"; + SIGNAL not_found; +end $$ + +--error ER_SIGNAL_NOT_FOUND +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + # Error, no subclass + DECLARE error CONDITION FOR SQLSTATE "12000"; + SIGNAL error; +end $$ + +--error ER_SIGNAL_EXCEPTION +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + # Error, with subclass + DECLARE error CONDITION FOR SQLSTATE "12ABC"; + SIGNAL error; +end $$ + +--error ER_SIGNAL_EXCEPTION +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + # Severe error, no subclass + DECLARE error CONDITION FOR SQLSTATE "40000"; + SIGNAL error; +end $$ + +--error ER_SIGNAL_EXCEPTION +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + # Severe error, with subclass + DECLARE error CONDITION FOR SQLSTATE "40001"; + SIGNAL error; +end $$ + +--error ER_SIGNAL_EXCEPTION +call test_signal() $$ +drop procedure test_signal $$ + +# Test the scope of condition + +create procedure test_signal() +begin + DECLARE foo CONDITION FOR SQLSTATE '99999'; + begin + DECLARE foo CONDITION FOR 8888; + end; + SIGNAL foo SET MYSQL_ERRNO=9999; /* outer */ +end $$ + +--error 9999 +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE foo CONDITION FOR 9999; + begin + DECLARE foo CONDITION FOR SQLSTATE '88888'; + SIGNAL foo SET MYSQL_ERRNO=8888; /* inner */ + end; +end $$ + +--error 8888 +call test_signal() $$ +drop procedure test_signal $$ + +# Test SET MYSQL_ERRNO + +create procedure test_signal() +begin + DECLARE foo CONDITION FOR SQLSTATE '99999'; + SIGNAL foo SET MYSQL_ERRNO = 1111; +end $$ + +--error 1111 +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE warn CONDITION FOR SQLSTATE "01000"; + SIGNAL warn SET MYSQL_ERRNO = 1111; +end $$ + +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE not_found CONDITION FOR SQLSTATE "02000"; + SIGNAL not_found SET MYSQL_ERRNO = 1111; +end $$ + +--error 1111 +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE error CONDITION FOR SQLSTATE "55000"; + SIGNAL error SET MYSQL_ERRNO = 1111; +end $$ + +--error 1111 +call test_signal() $$ +drop procedure test_signal $$ + +# Test SET MESSAGE_TEXT + +--error ER_SIGNAL_EXCEPTION +SIGNAL SQLSTATE '77777' SET MESSAGE_TEXT='' $$ + +create procedure test_signal() +begin + DECLARE foo CONDITION FOR SQLSTATE '77777'; + SIGNAL foo SET + MESSAGE_TEXT = "", + MYSQL_ERRNO=5678; +end $$ + +--error 5678 +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE foo CONDITION FOR SQLSTATE '99999'; + SIGNAL foo SET + MESSAGE_TEXT = "Something bad happened", + MYSQL_ERRNO=9999; +end $$ + +--error 9999 +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE warn CONDITION FOR SQLSTATE "01000"; + SIGNAL warn SET MESSAGE_TEXT = "Something bad happened"; +end $$ + +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE not_found CONDITION FOR SQLSTATE "02000"; + SIGNAL not_found SET MESSAGE_TEXT = "Something bad happened"; +end $$ + +--error ER_SIGNAL_NOT_FOUND +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE error CONDITION FOR SQLSTATE "55000"; + SIGNAL error SET MESSAGE_TEXT = "Something bad happened"; +end $$ + +--error ER_SIGNAL_EXCEPTION +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE something CONDITION FOR SQLSTATE "01000"; + SIGNAL something SET MESSAGE_TEXT = _utf8 "This is a UTF8 text"; +end $$ + +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE something CONDITION FOR SQLSTATE "01000"; + SIGNAL something SET MESSAGE_TEXT = ""; +end $$ + +call test_signal() $$ +drop procedure test_signal $$ + +# Test SET complex expressions + +create procedure test_signal() +begin + DECLARE error CONDITION FOR SQLSTATE '99999'; + SIGNAL error SET + MYSQL_ERRNO = NULL; +end $$ + +--error ER_WRONG_VALUE_FOR_VAR +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE error CONDITION FOR SQLSTATE '99999'; + SIGNAL error SET + CLASS_ORIGIN = NULL; +end $$ + +--error ER_WRONG_VALUE_FOR_VAR +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE error CONDITION FOR SQLSTATE '99999'; + SIGNAL error SET + SUBCLASS_ORIGIN = NULL; +end $$ + +--error ER_WRONG_VALUE_FOR_VAR +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE error CONDITION FOR SQLSTATE '99999'; + SIGNAL error SET + CONSTRAINT_CATALOG = NULL; +end $$ + +--error ER_WRONG_VALUE_FOR_VAR +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE error CONDITION FOR SQLSTATE '99999'; + SIGNAL error SET + CONSTRAINT_SCHEMA = NULL; +end $$ + +--error ER_WRONG_VALUE_FOR_VAR +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE error CONDITION FOR SQLSTATE '99999'; + SIGNAL error SET + CONSTRAINT_NAME = NULL; +end $$ + +--error ER_WRONG_VALUE_FOR_VAR +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE error CONDITION FOR SQLSTATE '99999'; + SIGNAL error SET + CATALOG_NAME = NULL; +end $$ + +--error ER_WRONG_VALUE_FOR_VAR +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE error CONDITION FOR SQLSTATE '99999'; + SIGNAL error SET + SCHEMA_NAME = NULL; +end $$ + +--error ER_WRONG_VALUE_FOR_VAR +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE error CONDITION FOR SQLSTATE '99999'; + SIGNAL error SET + TABLE_NAME = NULL; +end $$ + +--error ER_WRONG_VALUE_FOR_VAR +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE error CONDITION FOR SQLSTATE '99999'; + SIGNAL error SET + COLUMN_NAME = NULL; +end $$ + +--error ER_WRONG_VALUE_FOR_VAR +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE error CONDITION FOR SQLSTATE '99999'; + SIGNAL error SET + CURSOR_NAME = NULL; +end $$ + +--error ER_WRONG_VALUE_FOR_VAR +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE error CONDITION FOR SQLSTATE '99999'; + SIGNAL error SET + MESSAGE_TEXT = NULL; +end $$ + +--error ER_WRONG_VALUE_FOR_VAR +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE something CONDITION FOR SQLSTATE '99999'; + DECLARE message_text VARCHAR(64) DEFAULT "Local string variable"; + DECLARE sqlcode INTEGER DEFAULT 1234; + + SIGNAL something SET + MESSAGE_TEXT = message_text, + MYSQL_ERRNO = sqlcode; +end $$ + +--error 1234 +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal(message_text VARCHAR(64), sqlcode INTEGER) +begin + DECLARE something CONDITION FOR SQLSTATE "12345"; + + SIGNAL something SET + MESSAGE_TEXT = message_text, + MYSQL_ERRNO = sqlcode; +end $$ + +--error ER_WRONG_VALUE_FOR_VAR +call test_signal("Parameter string", NULL) $$ + +--error ER_WRONG_VALUE_FOR_VAR +call test_signal(NULL, 1234) $$ + +--error 5678 +call test_signal("Parameter string", 5678) $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE something CONDITION FOR SQLSTATE "AABBB"; + + SIGNAL something SET + MESSAGE_TEXT = @message_text, + MYSQL_ERRNO = @sqlcode; +end $$ + +--error ER_WRONG_VALUE_FOR_VAR +call test_signal() $$ + +set @sqlcode= 12 $$ + +--error ER_WRONG_VALUE_FOR_VAR +call test_signal() $$ + +set @message_text= "User variable" $$ + +--error 12 +call test_signal() $$ +drop procedure test_signal $$ + +--error ER_PARSE_ERROR +create procedure test_invalid() +begin + DECLARE something CONDITION FOR SQLSTATE "AABBB"; + + SIGNAL something SET + MESSAGE_TEXT = @message_text := 'illegal', + MYSQL_ERRNO = @sqlcode := 1234; +end $$ + +## create procedure test_signal() +## begin +## DECLARE something CONDITION FOR SQLSTATE "12345"; +## +## SIGNAL something SET +## MESSAGE_TEXT = concat("functions", " also works"), +## MYSQL_ERRNO = 1000 + 12; +## end $$ +## +## --error 1012 +## call test_signal() $$ +## drop procedure test_signal $$ + +## create procedure test_signal(code integer) +## begin +## DECLARE something CONDITION FOR SQLSTATE "12345"; +## +## SIGNAL something SET +## MESSAGE_TEXT = (select message_text from t1 where id=code), +## MYSQL_ERRNO = (select sqlcode from t1 where id=code); +## end $$ +## +## --disable_warnings +## drop table if exists t1 $$ +## --enable_warnings +## +## --error ER_NO_SUCH_TABLE +## call test_signal(1) $$ +## +## create table t1(id integer, message_text varchar(64), sqlcode integer) $$ +## +## --error ER_WRONG_VALUE_FOR_VAR +## call test_signal(1) $$ +## +## insert into t1 values ((1), ("First message"), (1001)) $$ +## insert into t1 values ((2), ("Second message"), (1002)) $$ +## +## --error 1001 +## call test_signal(1) $$ +## +## --error 1002 +## call test_signal(2) $$ + +## alter table t1 drop column message_text $$ +## +## --error ER_BAD_FIELD_ERROR +## call test_signal(2) $$ +## +## drop table t1 $$ +## drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE aaa VARCHAR(64); + DECLARE bbb VARCHAR(64); + DECLARE ccc VARCHAR(64); + DECLARE ddd VARCHAR(64); + DECLARE eee VARCHAR(64); + DECLARE fff VARCHAR(64); + DECLARE ggg VARCHAR(64); + DECLARE hhh VARCHAR(64); + DECLARE iii VARCHAR(64); + DECLARE jjj VARCHAR(64); + DECLARE kkk VARCHAR(64); + + DECLARE warn CONDITION FOR SQLSTATE "01234"; + + set aaa= repeat("A", 64); + set bbb= repeat("B", 64); + set ccc= repeat("C", 64); + set ddd= repeat("D", 64); + set eee= repeat("E", 64); + set fff= repeat("F", 64); + set ggg= repeat("G", 64); + set hhh= repeat("H", 64); + set iii= repeat("I", 64); + set jjj= repeat("J", 64); + set kkk= repeat("K", 64); + + SIGNAL warn SET + CLASS_ORIGIN = aaa, + SUBCLASS_ORIGIN = bbb, + CONSTRAINT_CATALOG = ccc, + CONSTRAINT_SCHEMA = ddd, + CONSTRAINT_NAME = eee, + CATALOG_NAME = fff, + SCHEMA_NAME = ggg, + TABLE_NAME = hhh, + COLUMN_NAME = iii, + CURSOR_NAME = jjj, + MESSAGE_TEXT = kkk, + MYSQL_ERRNO = 65535; +end $$ + +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE warn CONDITION FOR SQLSTATE "01234"; + + SIGNAL warn SET + MYSQL_ERRNO = 999999999999999999999999999999999999999999999999999; +end $$ + +--error ER_WRONG_VALUE_FOR_VAR +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE aaax VARCHAR(65); + DECLARE bbbx VARCHAR(65); + DECLARE cccx VARCHAR(65); + DECLARE dddx VARCHAR(65); + DECLARE eeex VARCHAR(65); + DECLARE fffx VARCHAR(65); + DECLARE gggx VARCHAR(65); + DECLARE hhhx VARCHAR(65); + DECLARE iiix VARCHAR(65); + DECLARE jjjx VARCHAR(65); + DECLARE kkkx VARCHAR(65); + DECLARE lllx VARCHAR(129); + + DECLARE warn CONDITION FOR SQLSTATE "01234"; + + set aaax= concat(repeat("A", 64), "X"); + set bbbx= concat(repeat("B", 64), "X"); + set cccx= concat(repeat("C", 64), "X"); + set dddx= concat(repeat("D", 64), "X"); + set eeex= concat(repeat("E", 64), "X"); + set fffx= concat(repeat("F", 64), "X"); + set gggx= concat(repeat("G", 64), "X"); + set hhhx= concat(repeat("H", 64), "X"); + set iiix= concat(repeat("I", 64), "X"); + set jjjx= concat(repeat("J", 64), "X"); + set kkkx= concat(repeat("K", 64), "X"); + set lllx= concat(repeat("1", 100), + repeat("2", 20), + repeat("8", 8), + "X"); + + SIGNAL warn SET + CLASS_ORIGIN = aaax, + SUBCLASS_ORIGIN = bbbx, + CONSTRAINT_CATALOG = cccx, + CONSTRAINT_SCHEMA = dddx, + CONSTRAINT_NAME = eeex, + CATALOG_NAME = fffx, + SCHEMA_NAME = gggx, + TABLE_NAME = hhhx, + COLUMN_NAME = iiix, + CURSOR_NAME = jjjx, + MESSAGE_TEXT = lllx, + MYSQL_ERRNO = 10000; +end $$ + +#NOTE: the warning text for ER_TRUNCATED_WRONG_VALUE contains +# value: '%-.128s', so the warning printed truncates the value too, +# which affects MESSAGE_TEXT (the X is missing) + +#NOTE: ER_TRUNCATED_WRONG_VALUE is raised as an error for DECIMAL, +# it's an existing bug: Bug#36457 +call test_signal() $$ +drop procedure test_signal $$ + +# Test that HANDLER can catch conditions raised by SIGNAL + +create procedure test_signal() +begin + DECLARE warn CONDITION FOR SQLSTATE "01234"; + DECLARE CONTINUE HANDLER for SQLSTATE "01234" + begin + select "Caught by SQLSTATE"; + end; + + SIGNAL warn SET + MESSAGE_TEXT = "Raising a warning", + MYSQL_ERRNO = 1012; +end $$ + +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE warn CONDITION FOR SQLSTATE "01234"; + DECLARE CONTINUE HANDLER for 1012 + begin + select "Caught by number"; + end; + + SIGNAL warn SET + MESSAGE_TEXT = "Raising a warning", + MYSQL_ERRNO = 1012; +end $$ + +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE warn CONDITION FOR SQLSTATE "01234"; + DECLARE CONTINUE HANDLER for SQLWARNING + begin + select "Caught by SQLWARNING"; + end; + + SIGNAL warn SET + MESSAGE_TEXT = "Raising a warning", + MYSQL_ERRNO = 1012; +end $$ + +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE not_found CONDITION FOR SQLSTATE "02ABC"; + DECLARE CONTINUE HANDLER for SQLSTATE "02ABC" + begin + select "Caught by SQLSTATE"; + end; + + SIGNAL not_found SET + MESSAGE_TEXT = "Raising a not found", + MYSQL_ERRNO = 1012; +end $$ + +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE not_found CONDITION FOR SQLSTATE "02ABC"; + DECLARE CONTINUE HANDLER for 1012 + begin + select "Caught by number"; + end; + + SIGNAL not_found SET + MESSAGE_TEXT = "Raising a not found", + MYSQL_ERRNO = 1012; +end $$ + +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE not_found CONDITION FOR SQLSTATE "02ABC"; + DECLARE CONTINUE HANDLER for NOT FOUND + begin + select "Caught by NOT FOUND"; + end; + + SIGNAL not_found SET + MESSAGE_TEXT = "Raising a not found", + MYSQL_ERRNO = 1012; +end $$ + +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE error CONDITION FOR SQLSTATE "55555"; + DECLARE CONTINUE HANDLER for SQLSTATE "55555" + begin + select "Caught by SQLSTATE"; + end; + + SIGNAL error SET + MESSAGE_TEXT = "Raising an error", + MYSQL_ERRNO = 1012; +end $$ + +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE error CONDITION FOR SQLSTATE "55555"; + DECLARE CONTINUE HANDLER for 1012 + begin + select "Caught by number"; + end; + + SIGNAL error SET + MESSAGE_TEXT = "Raising an error", + MYSQL_ERRNO = 1012; +end $$ + +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE error CONDITION FOR SQLSTATE "55555"; + DECLARE CONTINUE HANDLER for SQLEXCEPTION + begin + select "Caught by SQLEXCEPTION"; + end; + + SIGNAL error SET + MESSAGE_TEXT = "Raising an error", + MYSQL_ERRNO = 1012; +end $$ + +call test_signal() $$ +drop procedure test_signal $$ + +# Test where SIGNAL can be used + +create function test_signal_func() returns integer +begin + DECLARE warn CONDITION FOR SQLSTATE "01XXX"; + + SIGNAL warn SET + MESSAGE_TEXT = "This function SIGNAL a warning", + MYSQL_ERRNO = 1012; + + return 5; +end $$ + +select test_signal_func() $$ +drop function test_signal_func $$ + +create function test_signal_func() returns integer +begin + DECLARE not_found CONDITION FOR SQLSTATE "02XXX"; + + SIGNAL not_found SET + MESSAGE_TEXT = "This function SIGNAL not found", + MYSQL_ERRNO = 1012; + + return 5; +end $$ + +--error 1012 +select test_signal_func() $$ +drop function test_signal_func $$ + +create function test_signal_func() returns integer +begin + DECLARE error CONDITION FOR SQLSTATE "50000"; + + SIGNAL error SET + MESSAGE_TEXT = "This function SIGNAL an error", + MYSQL_ERRNO = 1012; + + return 5; +end $$ + +--error 1012 +select test_signal_func() $$ +drop function test_signal_func $$ + +--disable_warnings +drop table if exists t1 $$ +--enable_warnings + +create table t1 (a integer) $$ + +create trigger t1_ai after insert on t1 for each row +begin + DECLARE msg VARCHAR(128); + DECLARE warn CONDITION FOR SQLSTATE "01XXX"; + + set msg= concat("This trigger SIGNAL a warning, a=", NEW.a); + SIGNAL warn SET + MESSAGE_TEXT = msg, + MYSQL_ERRNO = 1012; +end $$ + +insert into t1 values (1), (2) $$ + +drop trigger t1_ai $$ + +create trigger t1_ai after insert on t1 for each row +begin + DECLARE msg VARCHAR(128); + DECLARE not_found CONDITION FOR SQLSTATE "02XXX"; + + set msg= concat("This trigger SIGNAL a not found, a=", NEW.a); + SIGNAL not_found SET + MESSAGE_TEXT = msg, + MYSQL_ERRNO = 1012; +end $$ + +--error 1012 +insert into t1 values (3), (4) $$ + +drop trigger t1_ai $$ + +create trigger t1_ai after insert on t1 for each row +begin + DECLARE msg VARCHAR(128); + DECLARE error CONDITION FOR SQLSTATE "03XXX"; + + set msg= concat("This trigger SIGNAL an error, a=", NEW.a); + SIGNAL error SET + MESSAGE_TEXT = msg, + MYSQL_ERRNO = 1012; +end $$ + +--error 1012 +insert into t1 values (5), (6) $$ + +drop table t1 $$ + +create table t1 (errno integer, msg varchar(128)) $$ + +create trigger t1_ai after insert on t1 for each row +begin + DECLARE warn CONDITION FOR SQLSTATE "01XXX"; + + SIGNAL warn SET + MESSAGE_TEXT = NEW.msg, + MYSQL_ERRNO = NEW.errno; +end $$ + +insert into t1 set errno=1012, msg='Warning message 1 in trigger' $$ +insert into t1 set errno=1013, msg='Warning message 2 in trigger' $$ + +drop table t1 $$ + +--disable_warnings +drop table if exists t1 $$ +drop procedure if exists p1 $$ +drop function if exists f1 $$ +--enable_warnings + +create table t1 (s1 int) $$ +insert into t1 values (1) $$ + +create procedure p1() +begin + declare a int; + declare c cursor for select f1() from t1; + declare continue handler for sqlstate '03000' + select "caught 03000"; + declare continue handler for 1326 + select "caught cursor is not open"; + + select "Before open"; + open c; + select "Before fetch"; + fetch c into a; + select "Before close"; + close c; +end $$ + +create function f1() returns int +begin + signal sqlstate '03000'; + return 5; +end $$ + +## FIXME : MEMORY plugin warning, valgrind leak, bug#36518 +## call p1() $$ + +drop table t1 $$ +drop procedure p1 $$ +drop function f1 $$ + +######################################################### +# Test the RESIGNAL runtime +######################################################### + +# 6 tests: +# {Signaled warning, Signaled Not Found, Signaled Error, +# warning, not found, error} --> RESIGNAL + +create procedure test_resignal() +begin + DECLARE warn CONDITION FOR SQLSTATE "01234"; + DECLARE CONTINUE HANDLER for 1012 + begin + select "before RESIGNAL"; + RESIGNAL; + select "after RESIGNAL"; + end; + + SIGNAL warn SET + MESSAGE_TEXT = "Raising a warning", + MYSQL_ERRNO = 1012; +end $$ + +call test_resignal() $$ +drop procedure test_resignal $$ + +create procedure test_resignal() +begin + DECLARE not_found CONDITION FOR SQLSTATE "02222"; + DECLARE CONTINUE HANDLER for 1012 + begin + select "before RESIGNAL"; + RESIGNAL; + select "after RESIGNAL"; + end; + + SIGNAL not_found SET + MESSAGE_TEXT = "Raising a not found", + MYSQL_ERRNO = 1012; +end $$ + +--error 1012 +call test_resignal() $$ +drop procedure test_resignal $$ + +create procedure test_resignal() +begin + DECLARE error CONDITION FOR SQLSTATE "55555"; + DECLARE CONTINUE HANDLER for 1012 + begin + select "before RESIGNAL"; + RESIGNAL; + select "after RESIGNAL"; + end; + + SIGNAL error SET + MESSAGE_TEXT = "Raising an error", + MYSQL_ERRNO = 1012; +end $$ + +--error 1012 +call test_resignal() $$ +drop procedure test_resignal $$ + +create procedure test_resignal() +begin + DECLARE CONTINUE HANDLER for sqlwarning + begin + select "before RESIGNAL"; + RESIGNAL; + select "after RESIGNAL"; + end; + + insert into t_warn set a= 9999999999999999; +end $$ + +call test_resignal() $$ +drop procedure test_resignal $$ + +create procedure test_resignal() +begin + DECLARE x integer; + DECLARE c cursor for select * from t_cursor; + DECLARE CONTINUE HANDLER for not found + begin + select "before RESIGNAL"; + RESIGNAL; + select "after RESIGNAL"; + end; + + open c; + fetch c into x; + close c; +end $$ + +--error ER_SP_FETCH_NO_DATA +call test_resignal() $$ +drop procedure test_resignal $$ + +create procedure test_resignal() +begin + DECLARE CONTINUE HANDLER for sqlexception + begin + select "before RESIGNAL"; + RESIGNAL; + select "after RESIGNAL"; + end; + + drop table no_such_table; +end $$ + +--error ER_BAD_TABLE_ERROR +call test_resignal() $$ +drop procedure test_resignal $$ + +# 6 tests: +# {Signaled warning, Signaled Not Found, Signaled Error, +# warning, not found, error} --> RESIGNAL SET ... + +create procedure test_resignal() +begin + DECLARE warn CONDITION FOR SQLSTATE "01234"; + DECLARE CONTINUE HANDLER for 1012 + begin + select "before RESIGNAL"; + RESIGNAL SET + MESSAGE_TEXT = "RESIGNAL of a warning", + MYSQL_ERRNO = 5555 ; + select "after RESIGNAL"; + end; + + SIGNAL warn SET + MESSAGE_TEXT = "Raising a warning", + MYSQL_ERRNO = 1012; +end $$ + +call test_resignal() $$ +drop procedure test_resignal $$ + +create procedure test_resignal() +begin + DECLARE not_found CONDITION FOR SQLSTATE "02111"; + DECLARE CONTINUE HANDLER for 1012 + begin + select "before RESIGNAL"; + RESIGNAL SET + MESSAGE_TEXT = "RESIGNAL of a not found", + MYSQL_ERRNO = 5555 ; + select "after RESIGNAL"; + end; + + SIGNAL not_found SET + MESSAGE_TEXT = "Raising a not found", + MYSQL_ERRNO = 1012; +end $$ + +--error 5555 +call test_resignal() $$ +drop procedure test_resignal $$ + +create procedure test_resignal() +begin + DECLARE error CONDITION FOR SQLSTATE "33333"; + DECLARE CONTINUE HANDLER for 1012 + begin + select "before RESIGNAL"; + RESIGNAL SET + MESSAGE_TEXT = "RESIGNAL of an error", + MYSQL_ERRNO = 5555 ; + select "after RESIGNAL"; + end; + + SIGNAL error SET + MESSAGE_TEXT = "Raising an error", + MYSQL_ERRNO = 1012; +end $$ + +--error 5555 +call test_resignal() $$ +drop procedure test_resignal $$ + +create procedure test_resignal() +begin + DECLARE CONTINUE HANDLER for sqlwarning + begin + select "before RESIGNAL"; + RESIGNAL SET + MESSAGE_TEXT = "RESIGNAL of a warning", + MYSQL_ERRNO = 5555 ; + select "after RESIGNAL"; + end; + + insert into t_warn set a= 9999999999999999; +end $$ + +call test_resignal() $$ +drop procedure test_resignal $$ + +create procedure test_resignal() +begin + DECLARE x integer; + DECLARE c cursor for select * from t_cursor; + DECLARE CONTINUE HANDLER for not found + begin + select "before RESIGNAL"; + RESIGNAL SET + MESSAGE_TEXT = "RESIGNAL of not found", + MYSQL_ERRNO = 5555 ; + select "after RESIGNAL"; + end; + + open c; + fetch c into x; + close c; +end $$ + +--error 5555 +call test_resignal() $$ +drop procedure test_resignal $$ + +create procedure test_resignal() +begin + DECLARE CONTINUE HANDLER for sqlexception + begin + select "before RESIGNAL"; + RESIGNAL SET + MESSAGE_TEXT = "RESIGNAL of an error", + MYSQL_ERRNO = 5555 ; + select "after RESIGNAL"; + end; + + drop table no_such_table; +end $$ + +--error 5555 +call test_resignal() $$ +drop procedure test_resignal $$ + +######################################################### + +# 3 tests: +# {Signaled warning} +# --> RESIGNAL SQLSTATE {warning, not found, error} SET ... + +create procedure test_resignal() +begin + DECLARE warn CONDITION FOR SQLSTATE "01111"; + DECLARE CONTINUE HANDLER for 1012 + begin + select "before RESIGNAL"; + RESIGNAL SQLSTATE "01222" SET + MESSAGE_TEXT = "RESIGNAL to warning", + MYSQL_ERRNO = 5555 ; + select "after RESIGNAL"; + end; + + SIGNAL warn SET + MESSAGE_TEXT = "Raising a warning", + MYSQL_ERRNO = 1012; +end $$ + +call test_resignal() $$ +drop procedure test_resignal $$ + +create procedure test_resignal() +begin + DECLARE warn CONDITION FOR SQLSTATE "01111"; + DECLARE CONTINUE HANDLER for 1012 + begin + select "before RESIGNAL"; + RESIGNAL SQLSTATE "02222" SET + MESSAGE_TEXT = "RESIGNAL to not found", + MYSQL_ERRNO = 5555 ; + select "after RESIGNAL"; + end; + + SIGNAL warn SET + MESSAGE_TEXT = "Raising a warning", + MYSQL_ERRNO = 1012; +end $$ + +--error 5555 +call test_resignal() $$ +show warnings $$ +drop procedure test_resignal $$ + +create procedure test_resignal() +begin + DECLARE warn CONDITION FOR SQLSTATE "01111"; + DECLARE CONTINUE HANDLER for 1012 + begin + select "before RESIGNAL"; + RESIGNAL SQLSTATE "33333" SET + MESSAGE_TEXT = "RESIGNAL to error", + MYSQL_ERRNO = 5555 ; + select "after RESIGNAL"; + end; + + SIGNAL warn SET + MESSAGE_TEXT = "Raising a warning", + MYSQL_ERRNO = 1012; +end $$ + +--error 5555 +call test_resignal() $$ +show warnings $$ +drop procedure test_resignal $$ + +# 3 tests: +# {Signaled not found} +# --> RESIGNAL SQLSTATE {warning, not found, error} SET ... + +create procedure test_resignal() +begin + DECLARE not_found CONDITION FOR SQLSTATE "02ABC"; + DECLARE CONTINUE HANDLER for 1012 + begin + select "before RESIGNAL"; + RESIGNAL SQLSTATE "01222" SET + MESSAGE_TEXT = "RESIGNAL to warning", + MYSQL_ERRNO = 5555 ; + select "after RESIGNAL"; + end; + + SIGNAL not_found SET + MESSAGE_TEXT = "Raising a not found", + MYSQL_ERRNO = 1012; +end $$ + +call test_resignal() $$ +drop procedure test_resignal $$ + +create procedure test_resignal() +begin + DECLARE not_found CONDITION FOR SQLSTATE "02ABC"; + DECLARE CONTINUE HANDLER for 1012 + begin + select "before RESIGNAL"; + RESIGNAL SQLSTATE "02222" SET + MESSAGE_TEXT = "RESIGNAL to not found", + MYSQL_ERRNO = 5555 ; + select "after RESIGNAL"; + end; + + SIGNAL not_found SET + MESSAGE_TEXT = "Raising a not found", + MYSQL_ERRNO = 1012; +end $$ + +--error 5555 +call test_resignal() $$ +show warnings $$ +drop procedure test_resignal $$ + +create procedure test_resignal() +begin + DECLARE not_found CONDITION FOR SQLSTATE "02ABC"; + DECLARE CONTINUE HANDLER for 1012 + begin + select "before RESIGNAL"; + RESIGNAL SQLSTATE "33333" SET + MESSAGE_TEXT = "RESIGNAL to error", + MYSQL_ERRNO = 5555 ; + select "after RESIGNAL"; + end; + + SIGNAL not_found SET + MESSAGE_TEXT = "Raising a not found", + MYSQL_ERRNO = 1012; +end $$ + +--error 5555 +call test_resignal() $$ +show warnings $$ +drop procedure test_resignal $$ + +# 3 tests: +# {Signaled error} +# --> RESIGNAL SQLSTATE {warning, not found, error} SET ... + +create procedure test_resignal() +begin + DECLARE error CONDITION FOR SQLSTATE "AAAAA"; + DECLARE CONTINUE HANDLER for 1012 + begin + select "before RESIGNAL"; + RESIGNAL SQLSTATE "01222" SET + MESSAGE_TEXT = "RESIGNAL to warning", + MYSQL_ERRNO = 5555 ; + select "after RESIGNAL"; + end; + + SIGNAL error SET + MESSAGE_TEXT = "Raising an error", + MYSQL_ERRNO = 1012; +end $$ + +call test_resignal() $$ +drop procedure test_resignal $$ + +create procedure test_resignal() +begin + DECLARE error CONDITION FOR SQLSTATE "AAAAA"; + DECLARE CONTINUE HANDLER for 1012 + begin + select "before RESIGNAL"; + RESIGNAL SQLSTATE "02222" SET + MESSAGE_TEXT = "RESIGNAL to not found", + MYSQL_ERRNO = 5555 ; + select "after RESIGNAL"; + end; + + SIGNAL error SET + MESSAGE_TEXT = "Raising an error", + MYSQL_ERRNO = 1012; +end $$ + +--error 5555 +call test_resignal() $$ +show warnings $$ +drop procedure test_resignal $$ + +create procedure test_resignal() +begin + DECLARE error CONDITION FOR SQLSTATE "AAAAA"; + DECLARE CONTINUE HANDLER for 1012 + begin + select "before RESIGNAL"; + RESIGNAL SQLSTATE "33333" SET + MESSAGE_TEXT = "RESIGNAL to error", + MYSQL_ERRNO = 5555 ; + select "after RESIGNAL"; + end; + + SIGNAL error SET + MESSAGE_TEXT = "Raising an error", + MYSQL_ERRNO = 1012; +end $$ + +--error 5555 +call test_resignal() $$ +show warnings $$ +drop procedure test_resignal $$ + +# 3 tests: +# {warning} +# --> RESIGNAL SQLSTATE {warning, not found, error} SET ... + +create procedure test_resignal() +begin + DECLARE CONTINUE HANDLER for sqlwarning + begin + select "before RESIGNAL"; + RESIGNAL SQLSTATE "01111" SET + MESSAGE_TEXT = "RESIGNAL to a warning", + MYSQL_ERRNO = 5555 ; + select "after RESIGNAL"; + end; + + insert into t_warn set a= 9999999999999999; +end $$ + +call test_resignal() $$ +drop procedure test_resignal $$ + +create procedure test_resignal() +begin + DECLARE CONTINUE HANDLER for sqlwarning + begin + select "before RESIGNAL"; + RESIGNAL SQLSTATE "02444" SET + MESSAGE_TEXT = "RESIGNAL to a not found", + MYSQL_ERRNO = 5555 ; + select "after RESIGNAL"; + end; + + insert into t_warn set a= 9999999999999999; +end $$ + +--error 5555 +call test_resignal() $$ +show warnings $$ +drop procedure test_resignal $$ + +create procedure test_resignal() +begin + DECLARE CONTINUE HANDLER for sqlwarning + begin + select "before RESIGNAL"; + RESIGNAL SQLSTATE "44444" SET + MESSAGE_TEXT = "RESIGNAL to an error", + MYSQL_ERRNO = 5555 ; + select "after RESIGNAL"; + end; + + insert into t_warn set a= 9999999999999999; +end $$ + +--error 5555 +call test_resignal() $$ +show warnings $$ +drop procedure test_resignal $$ + +# 3 tests: +# {not found} +# --> RESIGNAL SQLSTATE {warning, not found, error} SET ... + +create procedure test_resignal() +begin + DECLARE x integer; + DECLARE c cursor for select * from t_cursor; + DECLARE CONTINUE HANDLER for not found + begin + select "before RESIGNAL"; + RESIGNAL SQLSTATE "01111" SET + MESSAGE_TEXT = "RESIGNAL to a warning", + MYSQL_ERRNO = 5555 ; + select "after RESIGNAL"; + end; + + open c; + fetch c into x; + close c; +end $$ + +call test_resignal() $$ +drop procedure test_resignal $$ + +create procedure test_resignal() +begin + DECLARE x integer; + DECLARE c cursor for select * from t_cursor; + DECLARE CONTINUE HANDLER for not found + begin + select "before RESIGNAL"; + RESIGNAL SQLSTATE "02444" SET + MESSAGE_TEXT = "RESIGNAL to a not found", + MYSQL_ERRNO = 5555 ; + select "after RESIGNAL"; + end; + + open c; + fetch c into x; + close c; +end $$ + +--error 5555 +call test_resignal() $$ +show warnings $$ +drop procedure test_resignal $$ + +create procedure test_resignal() +begin + DECLARE x integer; + DECLARE c cursor for select * from t_cursor; + DECLARE CONTINUE HANDLER for not found + begin + select "before RESIGNAL"; + RESIGNAL SQLSTATE "44444" SET + MESSAGE_TEXT = "RESIGNAL to an error", + MYSQL_ERRNO = 5555 ; + select "after RESIGNAL"; + end; + + open c; + fetch c into x; + close c; +end $$ + +--error 5555 +call test_resignal() $$ +show warnings $$ +drop procedure test_resignal $$ + +# 3 tests: +# {error} +# --> RESIGNAL SQLSTATE {warning, not found, error} SET ... + +create procedure test_resignal() +begin + DECLARE CONTINUE HANDLER for sqlexception + begin + select "before RESIGNAL"; + RESIGNAL SQLSTATE "01111" SET + MESSAGE_TEXT = "RESIGNAL to a warning", + MYSQL_ERRNO = 5555 ; + select "after RESIGNAL"; + end; + + drop table no_such_table; +end $$ + +call test_resignal() $$ +drop procedure test_resignal $$ + +create procedure test_resignal() +begin + DECLARE CONTINUE HANDLER for sqlexception + begin + select "before RESIGNAL"; + RESIGNAL SQLSTATE "02444" SET + MESSAGE_TEXT = "RESIGNAL to a not found", + MYSQL_ERRNO = 5555 ; + select "after RESIGNAL"; + end; + + drop table no_such_table; +end $$ + +--error 5555 +call test_resignal() $$ +show warnings $$ +drop procedure test_resignal $$ + +create procedure test_resignal() +begin + DECLARE CONTINUE HANDLER for sqlexception + begin + select "before RESIGNAL"; + RESIGNAL SQLSTATE "44444" SET + MESSAGE_TEXT = "RESIGNAL to an error", + MYSQL_ERRNO = 5555 ; + select "after RESIGNAL"; + end; + + drop table no_such_table; +end $$ + +--error 5555 +call test_resignal() $$ +show warnings $$ +drop procedure test_resignal $$ + +######################################################### +# More complex cases +######################################################### + +--disable_warnings +drop procedure if exists peter_p1 $$ +drop procedure if exists peter_p2 $$ +--enable_warnings + +CREATE PROCEDURE peter_p1 () +BEGIN + DECLARE x CONDITION FOR 1231; + DECLARE EXIT HANDLER FOR x + BEGIN + SELECT '2'; + RESIGNAL SET MYSQL_ERRNO = 9999; + END; + + BEGIN + DECLARE EXIT HANDLER FOR x + BEGIN + SELECT '1'; + RESIGNAL SET SCHEMA_NAME = 'test'; + END; + SET @@sql_mode=NULL; + END; +END +$$ + +CREATE PROCEDURE peter_p2 () +BEGIN + DECLARE x CONDITION for 9999; + DECLARE EXIT HANDLER FOR x + BEGIN + SELECT '3'; + RESIGNAL SET MESSAGE_TEXT = 'Hi, I am a useless error message'; + END; + CALL peter_p1(); +END +$$ + +# +# Here, RESIGNAL only modifies the condition caught, +# so there is only 1 condition at the end +# The final SQLSTATE is 42000 (it comes from the error 1231), +# since the condition attributes are preserved. +# +--error 9999 +CALL peter_p2() $$ +show warnings $$ + +drop procedure peter_p1 $$ +drop procedure peter_p2 $$ + +CREATE PROCEDURE peter_p1 () +BEGIN + DECLARE x CONDITION FOR SQLSTATE '42000'; + DECLARE EXIT HANDLER FOR x + BEGIN + SELECT '2'; + RESIGNAL x SET MYSQL_ERRNO = 9999; + END; + + BEGIN + DECLARE EXIT HANDLER FOR x + BEGIN + SELECT '1'; + RESIGNAL x SET + SCHEMA_NAME = 'test', + MYSQL_ERRNO= 1231; + END; + /* Raises ER_WRONG_VALUE_FOR_VAR : 1231, SQLSTATE 42000 */ + SET @@sql_mode=NULL; + END; +END +$$ + +CREATE PROCEDURE peter_p2 () +BEGIN + DECLARE x CONDITION for SQLSTATE '42000'; + DECLARE EXIT HANDLER FOR x + BEGIN + SELECT '3'; + RESIGNAL x SET + MESSAGE_TEXT = 'Hi, I am a useless error message', + MYSQL_ERRNO = 9999; + END; + CALL peter_p1(); +END +$$ + +# +# Here, "RESIGNAL " create a new condition in the diagnostics +# area, so that there are 4 conditions at the end. +# +--error 9999 +CALL peter_p2() $$ +show warnings $$ + +drop procedure peter_p1 $$ +drop procedure peter_p2 $$ + +delimiter ;$$ + +drop table t_warn; +drop table t_cursor; + === added file 'mysql-test/t/signal_code.test' --- a/mysql-test/t/signal_code.test 1970-01-01 00:00:00 +0000 +++ b/mysql-test/t/signal_code.test 2008-07-23 00:30:04 +0000 @@ -0,0 +1,57 @@ +# Copyright (C) 2008 Sun Microsystems, Inc +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +# Tests for SIGNAL and RESIGNAL + +-- source include/have_debug.inc + +use test; + +--disable_warnings +drop procedure if exists signal_proc; +drop function if exists signal_func; +--enable_warnings + +delimiter $$; + +create procedure signal_proc() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + + SIGNAL foo; + SIGNAL foo SET MESSAGE_TEXT = "This is an error message"; + RESIGNAL foo; + RESIGNAL foo SET MESSAGE_TEXT = "This is an error message"; +end $$ + +create function signal_func() returns int +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + + SIGNAL foo; + SIGNAL foo SET MESSAGE_TEXT = "This is an error message"; + RESIGNAL foo; + RESIGNAL foo SET MESSAGE_TEXT = "This is an error message"; + return 0; +end $$ + +delimiter ;$$ + +show procedure code signal_proc; +drop procedure signal_proc; + +show function code signal_func; +drop function signal_func; + === added file 'mysql-test/t/signal_demo1.test' --- a/mysql-test/t/signal_demo1.test 1970-01-01 00:00:00 +0000 +++ b/mysql-test/t/signal_demo1.test 2008-07-23 00:30:04 +0000 @@ -0,0 +1,333 @@ +# Copyright (C) 2008 Sun Microsystems, Inc +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +# +# Demonstrate how SIGNAL can be used to enforce integrity constraints. +# + +# Naming: +# - PO: Purchase Order +# - AB: Address Book +# - IN: Inventory + +# Simplified schema: +# +# Relation 1: +# PO_ORDER (PK: po_id) 1:1 <---> 0:N (FK: po_id) PO_ORDER_LINE +# +# Relation 2: +# IN_INVENTORY (PK: item_id) 1:1 <---> 0:N (FK: item_id) PO_ORDER_LINE +# +# Relation 3: +# +--> 0:1 (PK: person_id) AB_PHYSICAL_PERSON +# PO_ORDER (FK: cust_id) 1:1 <--| +# +--> 0:1 (PK: company_id) AB_MORAL_PERSON +# This is an 'arc' relationship :) +# + + +--disable_warnings +drop database if exists demo; +--enable_warnings + +create database demo; + +use demo; + +create table ab_physical_person ( + person_id integer, + first_name VARCHAR(50), + middle_initial CHAR, + last_name VARCHAR(50), + primary key (person_id)); + +create table ab_moral_person ( + company_id integer, + name VARCHAR(100), + primary key (company_id)); + +create table in_inventory ( + item_id integer, + descr VARCHAR(50), + stock integer, + primary key (item_id)); + +create table po_order ( + po_id integer auto_increment, + cust_type char, /* arc relationship, see cust_id */ + cust_id integer, /* FK to ab_physical_person *OR* ab_moral_person */ + primary key (po_id)); + +create table po_order_line ( + po_id integer, /* FK to po_order.po_id */ + line_no integer, + item_id integer, /* FK to in_inventory.item_id */ + qty integer); + +delimiter $$; + +# +# Schema integrity enforcement +# + +create procedure check_pk_person(in person_type char, in id integer) +begin + declare x integer; + declare msg varchar(128); + + /* + Test integrity constraints for an 'arc' relationship. + Based on 'person_type', 'id' points to either a + physical person, or a moral person. + */ + case person_type + when 'P' then + begin + select count(person_id) from ab_physical_person + where ab_physical_person.person_id = id + into x; + + if (x != 1) + then + set msg= concat('No such physical person, PK:', id); + SIGNAL SQLSTATE '45000' SET + MESSAGE_TEXT = msg, + MYSQL_ERRNO = 10000; + end if; + end; + + when 'M' then + begin + select count(company_id) from ab_moral_person + where ab_moral_person.company_id = id + into x; + + if (x != 1) + then + set msg= concat('No such moral person, PK:', id); + SIGNAL SQLSTATE '45000' SET + MESSAGE_TEXT = msg, + MYSQL_ERRNO = 10000; + end if; + end; + + else + begin + set msg= concat('No such person type:', person_type); + SIGNAL SQLSTATE '45000' SET + MESSAGE_TEXT = msg, + MYSQL_ERRNO = 20000; + end; + end case; +end +$$ + +create procedure check_pk_inventory(in id integer) +begin + declare x integer; + declare msg varchar(128); + + select count(item_id) from in_inventory + where in_inventory.item_id = id + into x; + + if (x != 1) + then + set msg= concat('Failed integrity constraint, table in_inventory, PK:', + id); + SIGNAL SQLSTATE '45000' SET + MESSAGE_TEXT = msg, + MYSQL_ERRNO = 10000; + end if; +end +$$ + +create procedure check_pk_order(in id integer) +begin + declare x integer; + declare msg varchar(128); + + select count(po_id) from po_order + where po_order.po_id = id + into x; + + if (x != 1) + then + set msg= concat('Failed integrity constraint, table po_order, PK:', id); + SIGNAL SQLSTATE '45000' SET + MESSAGE_TEXT = msg, + MYSQL_ERRNO = 10000; + end if; +end +$$ + +create trigger po_order_bi before insert on po_order +for each row +begin + call check_pk_person(NEW.cust_type, NEW.cust_id); +end +$$ + +create trigger po_order_bu before update on po_order +for each row +begin + call check_pk_person(NEW.cust_type, NEW.cust_id); +end +$$ + +create trigger po_order_line_bi before insert on po_order_line +for each row +begin + call check_pk_order(NEW.po_id); + call check_pk_inventory(NEW.item_id); +end +$$ + +create trigger po_order_line_bu before update on po_order_line +for each row +begin + call check_pk_order(NEW.po_id); + call check_pk_inventory(NEW.item_id); +end +$$ + +# +# Application helpers +# + +create procedure po_create_order( + in p_cust_type char, + in p_cust_id integer, + out id integer) +begin + insert into po_order set cust_type = p_cust_type, cust_id = p_cust_id; + set id = last_insert_id(); +end +$$ + +create procedure po_add_order_line( + in po integer, + in line integer, + in item integer, + in q integer) +begin + insert into po_order_line set + po_id = po, line_no = line, item_id = item, qty = q; +end +$$ + +delimiter ;$$ + +select "Create sample data"; + +insert into ab_physical_person values + ( 1, "John", "A", "Doe"), + ( 2, "Marry", "B", "Smith") +; + +insert into ab_moral_person values + ( 3, "ACME real estate, INC"), + ( 4, "Local school") +; + +insert into in_inventory values + ( 100, "Table, dinner", 5), + ( 101, "Chair", 20), + ( 200, "Table, coffee", 3), + ( 300, "School table", 25), + ( 301, "School chairs", 50) +; + +select * from ab_physical_person order by person_id; +select * from ab_moral_person order by company_id; +select * from in_inventory order by item_id; + +select "Entering an order !"; + +set @my_po = 0; + +/* John Doe wants 1 table and 4 chairs */ +call po_create_order("P", 1, @my_po); + +call po_add_order_line (@my_po, 1, 100, 1); +call po_add_order_line (@my_po, 2, 101, 4); + +/* Marry Smith wants a coffee table */ +call po_create_order("P", 2, @my_po); + +call po_add_order_line (@my_po, 1, 200, 1); + +select "Entering bad data in an order"; + +# There is no item 999 in in_inventory +--error 10000 +call po_add_order_line (@my_po, 1, 999, 1); + +select "Entering bad data in an unknown order"; + +# There is no order 99 in po_order +--error 10000 +call po_add_order_line (99, 1, 100, 1); + +select "Entering an order for an unknown company"; + +# There is no moral person of id 7 +--error 10000 +call po_create_order("M", 7, @my_po); + +select "Entering an order for an unknown person type"; + +# There is no person of type X +--error 20000 +call po_create_order("X", 1, @my_po); + +/* The local school wants 10 class tables and 20 chairs */ +call po_create_order("M", 4, @my_po); + +call po_add_order_line (@my_po, 1, 300, 10); +call po_add_order_line (@my_po, 2, 301, 20); + +# Raw data +select * from po_order; +select * from po_order_line; + +# Creative reporting ... + +select po_id as "PO#", + ( case cust_type + when "P" then concat (pp.first_name, + " ", + pp.middle_initial, + " ", + pp.last_name) + when "M" then mp.name + end ) as "Sold to" + from po_order po + left join ab_physical_person pp on po.cust_id = pp.person_id + left join ab_moral_person mp on po.cust_id = company_id +; + +select po_id as "PO#", + ol.line_no as "Line", + ol.item_id as "Item", + inv.descr as "Description", + ol.qty as "Quantity" + from po_order_line ol, in_inventory inv + where inv.item_id = ol.item_id + order by ol.item_id, ol.line_no; + +drop database demo; + + === added file 'mysql-test/t/signal_demo2.test' --- a/mysql-test/t/signal_demo2.test 1970-01-01 00:00:00 +0000 +++ b/mysql-test/t/signal_demo2.test 2008-07-23 00:30:04 +0000 @@ -0,0 +1,207 @@ +# Copyright (C) 2008 Sun Microsystems, Inc +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +# +# Demonstrate how RESIGNAL can be used to 'catch' and 're-throw' an error +# + +--disable_warnings +drop database if exists demo; +--enable_warnings + +create database demo; + +use demo; + +delimiter $$; + +create procedure proc_top_a(p1 integer) +begin + ## DECLARE CONTINUE HANDLER for SQLEXCEPTION, NOT FOUND + begin + end; + + select "Starting ..."; + call proc_middle_a(p1); + select "The end"; +end +$$ + +create procedure proc_middle_a(p1 integer) +begin + DECLARE l integer; + # without RESIGNAL: + # Should be: DECLARE EXIT HANDLER for SQLEXCEPTION, NOT FOUND + DECLARE EXIT HANDLER for 1 /* not sure how to handle exceptions */ + begin + select "Oops ... now what ?"; + end; + + select "In prod_middle()"; + + create temporary table t1(a integer, b integer); + select GET_LOCK("user_mutex", 10) into l; + + insert into t1 set a = p1, b = p1; + + call proc_bottom_a(p1); + + select RELEASE_LOCK("user_mutex") into l; + drop temporary table t1; +end +$$ + +create procedure proc_bottom_a(p1 integer) +begin + select "In proc_bottom()"; + + if (p1 = 1) then + begin + select "Doing something that works ..."; + select * from t1; + end; + end if; + + if (p1 = 2) then + begin + select "Doing something that fail (simulate an error) ..."; + drop table no_such_table; + end; + end if; + + if (p1 = 3) then + begin + select "Doing something that *SHOULD* works ..."; + select * from t1; + end; + end if; + +end +$$ + +delimiter ;$$ + +# +# Code without RESIGNAL: +# errors are apparent to the caller, +# but there is no cleanup code, +# so that the environment (get_lock(), temporary table) is polluted ... +# +call proc_top_a(1); + +# Expected +--error ER_BAD_TABLE_ERROR +call proc_top_a(2); + +# Dirty state +--error ER_TABLE_EXISTS_ERROR +call proc_top_a(3); + +# Dirty state +--error ER_TABLE_EXISTS_ERROR +call proc_top_a(1); + +drop temporary table if exists t1; + +delimiter $$; + +create procedure proc_top_b(p1 integer) +begin + select "Starting ..."; + call proc_middle_b(p1); + select "The end"; +end +$$ + +create procedure proc_middle_b(p1 integer) +begin + DECLARE l integer; + DECLARE EXIT HANDLER for SQLEXCEPTION, NOT FOUND + begin + begin + DECLARE CONTINUE HANDLER for SQLEXCEPTION, NOT FOUND + begin + /* Ignore errors from the cleanup code */ + end; + + select "Doing cleanup !"; + select RELEASE_LOCK("user_mutex") into l; + drop temporary table t1; + end; + + RESIGNAL; + end; + + select "In prod_middle()"; + + create temporary table t1(a integer, b integer); + select GET_LOCK("user_mutex", 10) into l; + + insert into t1 set a = p1, b = p1; + + call proc_bottom_b(p1); + + select RELEASE_LOCK("user_mutex") into l; + drop temporary table t1; +end +$$ + +create procedure proc_bottom_b(p1 integer) +begin + select "In proc_bottom()"; + + if (p1 = 1) then + begin + select "Doing something that works ..."; + select * from t1; + end; + end if; + + if (p1 = 2) then + begin + select "Doing something that fail (simulate an error) ..."; + drop table no_such_table; + end; + end if; + + if (p1 = 3) then + begin + select "Doing something that *SHOULD* works ..."; + select * from t1; + end; + end if; + +end +$$ + +delimiter ;$$ + +# +# Code with RESIGNAL: +# errors are apparent to the caller, +# the but cleanup code did get a chance to act ... +# + +call proc_top_b(1); + +--error ER_BAD_TABLE_ERROR +call proc_top_b(2); + +call proc_top_b(3); + +call proc_top_b(1); + +drop database demo; + === added file 'mysql-test/t/signal_demo3.test' --- a/mysql-test/t/signal_demo3.test 1970-01-01 00:00:00 +0000 +++ b/mysql-test/t/signal_demo3.test 2008-07-23 00:30:04 +0000 @@ -0,0 +1,159 @@ +# Copyright (C) 2008 Sun Microsystems, Inc +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +# +# Demonstrate how RESIGNAL can be used to print a stack trace +# + +# Save defaults + +SET @start_global_value = @@global.max_error_count; +SELECT @start_global_value; +SET @start_session_value = @@session.max_error_count; +SELECT @start_session_value; + +--disable_warnings +drop database if exists demo; +--enable_warnings + +create database demo; + +use demo; + +delimiter $$; + +create procedure proc_1() +begin + declare exit handler for sqlexception + resignal sqlstate '45000' set message_text='Oops in proc_1'; + + call proc_2(); +end +$$ + +create procedure proc_2() +begin + declare exit handler for sqlexception + resignal sqlstate '45000' set message_text='Oops in proc_2'; + + call proc_3(); +end +$$ + +create procedure proc_3() +begin + declare exit handler for sqlexception + resignal sqlstate '45000' set message_text='Oops in proc_3'; + + call proc_4(); +end +$$ + +create procedure proc_4() +begin + declare exit handler for sqlexception + resignal sqlstate '45000' set message_text='Oops in proc_4'; + + call proc_5(); +end +$$ + +create procedure proc_5() +begin + declare exit handler for sqlexception + resignal sqlstate '45000' set message_text='Oops in proc_5'; + + call proc_6(); +end +$$ + +create procedure proc_6() +begin + declare exit handler for sqlexception + resignal sqlstate '45000' set message_text='Oops in proc_6'; + + call proc_7(); +end +$$ + +create procedure proc_7() +begin + declare exit handler for sqlexception + resignal sqlstate '45000' set message_text='Oops in proc_7'; + + call proc_8(); +end +$$ + +create procedure proc_8() +begin + declare exit handler for sqlexception + resignal sqlstate '45000' set message_text='Oops in proc_8'; + + call proc_9(); +end +$$ + +create procedure proc_9() +begin + declare exit handler for sqlexception + resignal sqlstate '45000' set message_text='Oops in proc_9'; + + ## Do something that fails, to see how errors are reported + drop table oops_it_is_not_here; +end +$$ + +delimiter ;$$ + +-- error ER_SIGNAL_EXCEPTION +call proc_1(); + +# This is the interesting part: +# the complete call stack from the origin of failure (proc_9) +# to the top level caller (proc_1) is available ... + +show warnings; + +SET @@session.max_error_count = 5; +SELECT @@session.max_error_count; + +-- error ER_SIGNAL_EXCEPTION +call proc_1(); +show warnings; + +SET @@session.max_error_count = 7; +SELECT @@session.max_error_count; + +-- error ER_SIGNAL_EXCEPTION +call proc_1(); +show warnings; + +SET @@session.max_error_count = 9; +SELECT @@session.max_error_count; + +-- error ER_SIGNAL_EXCEPTION +call proc_1(); +show warnings; + +drop database demo; + +# Restore defaults + +SET @@global.max_error_count = @start_global_value; +SELECT @@global.max_error_count; +SET @@session.max_error_count = @start_session_value; +SELECT @@session.max_error_count; + === added file 'mysql-test/t/signal_sqlmode.test' --- a/mysql-test/t/signal_sqlmode.test 1970-01-01 00:00:00 +0000 +++ b/mysql-test/t/signal_sqlmode.test 2008-07-23 00:30:04 +0000 @@ -0,0 +1,123 @@ +# Copyright (C) 2008 Sun Microsystems, Inc +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +# Tests for SIGNAL, RESIGNAL and GET DIAGNOSTICS + +SET @save_sql_mode=@@sql_mode; + +SET sql_mode=''; + +--disable_warnings +drop procedure if exists p; +drop procedure if exists p2; +drop procedure if exists p3; +--enable_warnings + +delimiter $$; + +create procedure p() +begin + declare utf8_var VARCHAR(128) CHARACTER SET UTF8; + set utf8_var = concat(repeat('A', 128), 'X'); + select length(utf8_var), utf8_var; +end +$$ + +create procedure p2() +begin + declare msg VARCHAR(129) CHARACTER SET UTF8; + set msg = concat(repeat('A', 128), 'X'); + select length(msg), msg; + + signal sqlstate '55555' set message_text = msg; +end +$$ + +create procedure p3() +begin + declare name VARCHAR(65) CHARACTER SET UTF8; + set name = concat(repeat('A', 64), 'X'); + select length(name), name; + + signal sqlstate '55555' set + message_text = 'Message', + table_name = name; +end +$$ +delimiter ;$$ + +call p; + +--error ER_SIGNAL_EXCEPTION +call p2; + +--error ER_SIGNAL_EXCEPTION +call p3; + +drop procedure p; +drop procedure p2; +drop procedure p3; + +SET sql_mode='STRICT_ALL_TABLES'; + +delimiter $$; + +create procedure p() +begin + declare utf8_var VARCHAR(128) CHARACTER SET UTF8; + set utf8_var = concat(repeat('A', 128), 'X'); + select length(utf8_var), utf8_var; +end +$$ + +create procedure p2() +begin + declare msg VARCHAR(129) CHARACTER SET UTF8; + set msg = concat(repeat('A', 128), 'X'); + select length(msg), msg; + + signal sqlstate '55555' set message_text = msg; +end +$$ + +create procedure p3() +begin + declare name VARCHAR(65) CHARACTER SET UTF8; + set name = concat(repeat('A', 64), 'X'); + select length(name), name; + + signal sqlstate '55555' set + message_text = 'Message', + table_name = name; +end +$$ + +delimiter ;$$ + +--error ER_DATA_TOO_LONG +call p; + +--error ER_COND_ITEM_TOO_LONG +call p2; + +--error ER_COND_ITEM_TOO_LONG +call p3; + +drop procedure p; +drop procedure p2; +drop procedure p3; + +SET @@sql_mode=@save_sql_mode; + === added file 'mysql-test/t/signal_utf32.test' --- a/mysql-test/t/signal_utf32.test 1970-01-01 00:00:00 +0000 +++ b/mysql-test/t/signal_utf32.test 2008-07-23 00:30:04 +0000 @@ -0,0 +1,63 @@ +# Copyright (C) 2008 Sun Microsystems, Inc +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +# Tests for SIGNAL, RESIGNAL and GET DIAGNOSTICS + +--source include/have_utf32.inc + +--disable_warnings +drop procedure if exists test_signal; +--enable_warnings + +delimiter $$; + +create procedure test_signal() +begin + DECLARE something CONDITION FOR SQLSTATE "01000"; + SIGNAL something SET MESSAGE_TEXT = + _utf32 'a'; +end $$ + +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE something CONDITION FOR SQLSTATE "01000"; + SIGNAL something SET MESSAGE_TEXT = + _utf32 X'00000048000000450000004C0000004C0000004F'; +end $$ + +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + declare continue handler for sqlexception + begin + declare msg varchar(128); + set msg= repeat(_utf32 0x000100cc, 128); + resignal set message_text = msg; + end; + + signal sqlstate '77777'; +end $$ + +--error ER_SIGNAL_EXCEPTION +call test_signal() $$ +drop procedure test_signal $$ + +delimiter ;$$ +