polardbxengine/mysql-test/suite/xengine_main/t/wl5928.test

660 lines
15 KiB
Plaintext

--echo # WL#5928: Most statements should clear the diagnostic area
SELECT @@max_heap_table_size INTO @old_max_heap_table_size;
SET sql_mode = 'NO_ENGINE_SUBSTITUTION';
--echo #
--echo # Throw error, run some queries that shouldn't change diagnostics.
--echo #
--error ER_BAD_TABLE_ERROR
DROP TABLE no_such_table;
SHOW ERRORS;
SHOW WARNINGS;
SHOW COUNT(*) ERRORS;
SHOW COUNT(*) WARNINGS;
GET DIAGNOSTICS @n = NUMBER;
GET DIAGNOSTICS CONDITION 1 @err_no = MYSQL_ERRNO, @err_txt = MESSAGE_TEXT;
SELECT @n, @err_no, @err_txt;
--echo
--echo #
--echo # Contrary to SHOW, these will now reset the diagnostics area:
--echo #
# This will fail on --ps-protocol because that does a {prepare, execute}
# sequence for each command (rather than preparing earlier). This means
# that there is a prepare "SELECT @@warning_count" in between the execute
# of the throwing statement and that of the SELECT @@warning_count. Thus,
# the prepare will clear the diagnostics before the execute can see them.
# To prevent hard to find errors due to counter-intuitive semantics, we
# fail @@warning_count and @@error_count with ER_UNSUPPORTED_PS during
# prepare!
--disable_ps_protocol
--error ER_BAD_TABLE_ERROR
DROP TABLE no_such_table;
SELECT @@error_count;
SELECT @@error_count;
--error ER_BAD_TABLE_ERROR
DROP TABLE no_such_table;
SELECT @@warning_count;
SELECT @@warning_count;
CREATE TABLE IF NOT EXISTS t2 (f1 INT);
CREATE TABLE IF NOT EXISTS t2 (f1 INT);
SELECT @@warning_count;
DROP TABLE t2;
--enable_ps_protocol
--echo
--echo #
--echo # Parse-error
--echo #
--echo # Errors may occur during the parse-stage -- before we know whether
--echo # the current statement is a diagnostics statement and must preserve the
--echo # previous statement's diagnostics area! Show that we handle this right.
--echo #
--error ER_BAD_TABLE_ERROR
DROP TABLE no_such_table;
--echo parser may use message for ER_SYNTAX_ERROR, but always uses number
--echo ER_PARSE_ERROR instead.
--echo Only sql_binlog.cc actually uses number ER_SYNTAX_ERROR.
--error ER_PARSE_ERROR
GET DIAGNOSTICS;
GET DIAGNOSTICS @n = NUMBER;
GET DIAGNOSTICS CONDITION 1 @err_no = MYSQL_ERRNO, @err_txt = MESSAGE_TEXT;
SELECT @n, @err_no, @err_txt;
--echo Here is another error the parser can throw, though:
--error ER_UNKNOWN_SYSTEM_VARIABLE
SET GLOBAL wombat = 'pangolin';
--echo
--echo #
--echo # SP: Stored Procedures
--echo #
# neutral:
# - DECLARE CONDITION
# - DECLARE HANDLER
# - BEGIN..END
DELIMITER |;
CREATE PROCEDURE p0_proc_with_warning ()
BEGIN
SELECT CAST('2001-01-01' AS SIGNED INT);
END|
CREATE PROCEDURE p1_declare_handler_preserves ()
BEGIN
DECLARE CONTINUE HANDLER FOR NOT FOUND
BEGIN
/* Nes gadol hayah poh -- first handler should have been called.
DECLARE another handler. This should NOT clear the DA! */
DECLARE red CONDITION FOR 1051;
DECLARE CONTINUE HANDLER FOR red
BEGIN
GET DIAGNOSTICS @n0 = NUMBER;
GET DIAGNOSTICS CONDITION 1 @e0 = MYSQL_ERRNO, @t0 = MESSAGE_TEXT;
END;
/* The important bit here is that there are two diagnostics statements
in a row, so we can show that the first one does not clear the
diagnostics area. */
GET DIAGNOSTICS @n1 = NUMBER;
GET DIAGNOSTICS CONDITION 1 @e1 = MYSQL_ERRNO, @t1 = MESSAGE_TEXT;
END;
SET @n1 = 0, @e1 = 0, @t1 = 'handler was not run or GET DIAGNOSTICS failed';
SIGNAL SQLSTATE '02000' SET MESSAGE_TEXT = 'signal message';
/* Show handler was called, and DA was read intact despite of other
DECLAREs on the way: */
SELECT @n1, @e1, @t1;
END|
CREATE PROCEDURE p2_declare_variable_clears ()
BEGIN
DECLARE CONTINUE HANDLER FOR NOT FOUND
BEGIN
/* DECLARE a variable. This will clear the diagnostics area, so
the subsequent GET DIAGNOSTICS will fail. It in turn will flag
a warning (not an exception), which will remain unseen, as it
in turn gets cleared by the next statement (SELECT). */
DECLARE v1 INT;
GET DIAGNOSTICS @n2 = NUMBER;
GET DIAGNOSTICS CONDITION 1 @e2 = MYSQL_ERRNO, @t2 = MESSAGE_TEXT;
END;
SET @n2 = 0, @e2 = 0, @t2 = 'handler was not run or GET DIAGNOSTICS failed';
SIGNAL SQLSTATE '02000' SET MESSAGE_TEXT = 'signal message';
/* Show handler was called, and DA was NOT read intact because of DECLARE VARIABLE. */
SELECT @n2, @e2, @t2;
END|
CREATE PROCEDURE p6_bubble_warning ()
BEGIN
DECLARE CONTINUE HANDLER FOR NOT FOUND
BEGIN
/* Absurdly high CONDITION number will cause GET DIAG to fail.
As it is the last statement, warning should bubble up to caller. */
GET DIAGNOSTICS CONDITION 99 @e6 = MYSQL_ERRNO, @t6 = MESSAGE_TEXT;
END;
SET @n2 = 0, @e2 = 0, @t2 = 'handler was not run or GET DIAGNOSTICS failed';
SIGNAL SQLSTATE '02000' SET MESSAGE_TEXT = 'signal message';
END|
CREATE PROCEDURE p5_declare_variable_clears ()
BEGIN
DECLARE CONTINUE HANDLER FOR NOT FOUND
BEGIN
/* DECLARE a VARIABLE with a broken DEFAULT. This will throw a
warning at runtime, which GET DIAGNOSTICS will see instead of
the previous condition (the SIGNAL). */
DECLARE v1 INT DEFAULT 'meow';
GET DIAGNOSTICS @n5 = NUMBER;
GET DIAGNOSTICS CONDITION 1 @e5= MYSQL_ERRNO, @t5 = MESSAGE_TEXT;
END;
SET @n5 = 0, @e5 = 0, @t5 = 'handler was not run or GET DIAGNOSTICS failed';
SIGNAL SQLSTATE '02000' SET MESSAGE_TEXT = 'signal message';
/* Show handler was called, and DA was NOT read intact because of DECLARE VARIABLE. */
SELECT @n5, @e5, @t5;
SELECT "still here, we got a warning, not an exception!";
END|
CREATE PROCEDURE p3_non_diagnostics_stmt_clears ()
BEGIN
DECLARE CONTINUE HANDLER FOR NOT FOUND
BEGIN
/* Do some stuff before using GET (CURRENT, not STACKED) DIAGNOSTICS.
This will clear the DA.
show that handler was run, even if GET DIAG below fails! */
SET @t3 = 'handler was run, but GET DIAGNOSTICS failed';
SELECT 1 FROM DUAL;
GET CURRENT DIAGNOSTICS @n3 = NUMBER;
GET CURRENT DIAGNOSTICS CONDITION 1 @e3 = MYSQL_ERRNO, @t3 = MESSAGE_TEXT;
END;
SET @n3 = 0, @e3 = 0, @t3 = 'handler was not run or GET DIAGNOSTICS failed';
SIGNAL SQLSTATE '02000' SET MESSAGE_TEXT = 'signal message';
/* Show handler was called. */
SELECT @n3, @e3, @t3;
END|
CREATE PROCEDURE p4_unhandled_exception_returned ()
BEGIN
/* This will throw an exception which we do not handle,
so execution will abort, and the caller will see
the error. */
DROP TABLE no_such_table;
SELECT "we should never get here";
END|
# this guards against a regression to MySQL Bug#4902 (see sp.test),
# a failure to handle MULTI_RESULTS correctly. That's a crashing bug.
CREATE PROCEDURE p7_show_warnings ()
BEGIN
SHOW VARIABLES LIKE 'foo';
SHOW WARNINGS;
SELECT "(SHOW WARNINGS does not have to come last)";
END|
CREATE PROCEDURE p8a_empty ()
BEGIN
END|
CREATE PROCEDURE p8b_show_warnings ()
BEGIN
SHOW WARNINGS;
END|
DELIMITER ;|
--echo
--echo # warning bubbles up as it is thrown in the last statement (END does not count).
--echo # 1292, "truncated"
CALL p0_proc_with_warning;
DROP PROCEDURE p0_proc_with_warning;
--echo
--echo # DECLARE HANDLER does not reset DA.
--echo # 1643, "signal message"
CALL p1_declare_handler_preserves;
DROP PROCEDURE p1_declare_handler_preserves;
--echo
--echo # DECLARE VARIABLE clears DA.
--echo # 0 (but "GET DIAGNOSTICS failed")
CALL p2_declare_variable_clears;
DROP PROCEDURE p2_declare_variable_clears;
--echo
--echo # DECLARE VARIABLE with broken DEFAULT throws error.
--echo # 1366, "Incorrect integer value"
CALL p5_declare_variable_clears;
DROP PROCEDURE p5_declare_variable_clears;
--echo
--echo # show that GET DIAGNOSTICS produces warnings on failure.
--echo # 1758, "GET DIAGNOSTICS failed: Invalid condition number"
CALL p6_bubble_warning;
DROP PROCEDURE p6_bubble_warning;
--echo
--echo # non-diagnostics statement in handler clears DA before GET DIAGNOSTICS
--echo # 0 (but "GET DIAGNOSTICS failed")
CALL p3_non_diagnostics_stmt_clears;
DROP PROCEDURE p3_non_diagnostics_stmt_clears;
--echo
--echo # unhandled exception terminates SP, bubbles up
--echo # 1051, "unknown table"
--error ER_BAD_TABLE_ERROR
CALL p4_unhandled_exception_returned;
DROP PROCEDURE p4_unhandled_exception_returned;
--echo
--echo # SHOW WARNINGS is flagged MULTI_RESULTS. Show that we can handle that.
--echo # 1051, "unknown table"
CALL p7_show_warnings;
DROP PROCEDURE p7_show_warnings;
--echo
--echo # CALL is a procedure statement, so a called procedure won't see
--echo # warnings generated in its caller, and a post-CALL statement
--echo # won't see warnings from before the CALL even if the procedure
--echo # was empty.
--error ER_BAD_TABLE_ERROR
DROP TABLE no_such_table;
CALL p8a_empty;
SHOW WARNINGS;
DROP PROCEDURE p8a_empty;
--error ER_BAD_TABLE_ERROR
DROP TABLE no_such_table;
CALL p8b_show_warnings;
DROP PROCEDURE p8b_show_warnings;
--echo
--echo #
--echo # SF: Stored Functions
--echo #
DELIMITER |;
CREATE FUNCTION f2_unseen_warnings() RETURNS INT
BEGIN
/* throw a warning */
SET @@max_heap_table_size= 1;
/* RETURN counts as a statement as per the standard, so clears DA */
RETURN 1;
END|
DELIMITER ;|
DELIMITER |;
CREATE FUNCTION f3_stacking_warnings() RETURNS TEXT
BEGIN
/* throw a warning */
RETURN CAST('2001-01-01' AS SIGNED INT);
END|
DELIMITER ;|
# show we didn't break this
DELIMITER |;
--error ER_SP_NO_RETSET
CREATE FUNCTION f4_show_warnings() RETURNS TEXT
BEGIN
SHOW WARNINGS;
RETURN "yeah, not so much";
END|
DELIMITER ;|
--echo
--echo # SF: warnings within remain unseen, except when from last statement (RETURN)
SELECT f2_unseen_warnings();
SHOW WARNINGS;
SET @@max_heap_table_size= 1;
DROP FUNCTION f2_unseen_warnings;
--echo
--echo # SF: warnings within bubble up, if from last statement (RETURN).
--echo # warnings from multiple function calls are all preserved.
SELECT f3_stacking_warnings(),f3_stacking_warnings(),f3_stacking_warnings();
DROP FUNCTION f3_stacking_warnings;
--echo
--echo # PS
--echo #
--echo # show prepared statements still throw warnings OK
PREPARE stmt1 FROM 'create table if not exists t1 (f1 int)';
EXECUTE stmt1;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;
DROP TABLE t1;
--echo # show prepared statements can activate handler
PREPARE stmt1 FROM 'create table if not exists t1 (f1 int)';
EXECUTE stmt1;
DELIMITER |;
CREATE PROCEDURE p10_ps_with_warning ()
BEGIN
DECLARE CONTINUE HANDLER FOR 1050 SELECT "a warn place";
EXECUTE stmt1;
END|
DELIMITER ;|
CALL p10_ps_with_warning ();
DROP PROCEDURE p10_ps_with_warning;
DEALLOCATE PREPARE stmt1;
DROP TABLE t1;
--echo # show prepared statements still throw warnings OK
PREPARE stmt1 FROM 'create table if not exists t1 (f1 year(4))';
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;
DROP TABLE t1;
--echo
--echo # GET DIAGNOSTICS is not supported as prepared statement for now.
--echo # (It shouldn't be; Foundation 2007, 4.33.7)
--echo # This placeholder is intended to fail once that changes, so we
--echo # can add a proper test for it here.
SET @sql1='GET DIAGNOSTICS CONDITION 1 @err_no = MYSQL_ERRNO, @err_txt = MESSAGE_TEXT';
--error ER_UNSUPPORTED_PS
PREPARE stmt1 FROM @sql1;
--echo
--echo # Foundation 2007, 4.33.7 says diagnostics statements shouldn't be preparable!
--error ER_UNSUPPORTED_PS
PREPARE stmt2 FROM 'SHOW WARNINGS';
--error ER_UNSUPPORTED_PS
PREPARE stmt2 FROM 'SHOW ERRORS';
--error ER_UNSUPPORTED_PS
PREPARE stmt2 FROM 'SHOW COUNT(*) WARNINGS';
--error ER_UNSUPPORTED_PS
PREPARE stmt2 FROM 'SHOW COUNT(*) ERRORS';
--error ER_UNSUPPORTED_PS
PREPARE stmt2 FROM 'SELECT @@warning_count';
--error ER_UNSUPPORTED_PS
PREPARE stmt2 FROM 'SELECT @@error_count';
--echo
--echo # Bug#11745821: SELECT WITH NO TABLES BUT A DERIVED TABLE RESETS WARNING LIST, CONTRARY T
--echo #
# 1a)
# throw warning
SET @@max_heap_table_size= 1;
# SELECT without tables now clears it:
SELECT 1;
SHOW WARNINGS;
--echo
# 1b)
# throw warning
SET @@max_heap_table_size= 1;
# SELECT with sub-SELECT (but still without tables) still clears it:
SELECT 1 FROM (SELECT 1) t1;
SHOW WARNINGS;
--echo
--echo # additional tests derived from PeterG's mails.
--echo #
DELIMITER |;
CREATE PROCEDURE peter1 ()
BEGIN
DECLARE v INTEGER DEFAULT 1234;
DECLARE CONTINUE HANDLER FOR SQLWARNING
BEGIN
SHOW WARNINGS;
SELECT "handler done: ",v;
END;
CREATE TABLE gg (smallint_column SMALLINT);
CALL peter2(v);
END|
CREATE PROCEDURE peter2 (INOUT v INTEGER)
BEGIN
INSERT INTO gg (smallint_column) VALUES (32769);
GET DIAGNOSTICS v = ROW_COUNT;
END|
CREATE PROCEDURE peter3(a DECIMAL(2,2))
BEGIN
DECLARE b DECIMAL(2,2) DEFAULT @var;
END|
DELIMITER ;|
CALL peter1();
DROP PROCEDURE peter2;
DROP PROCEDURE peter1;
DROP TABLE gg;
SET @var="foo";
CALL peter3("bar");
DROP PROCEDURE peter3;
--echo
--echo # additional adapted tests from sp
--echo #
DELIMITER |;
CREATE TABLE t3 (id INT NOT NULL)|
CREATE PROCEDURE bug15231_1()
BEGIN
DECLARE xid INTEGER;
DECLARE xdone INTEGER DEFAULT 0;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET xdone = 1;
SET xid=NULL;
CALL bug15231_2a(xid);
SELECT "1,0", xid, xdone;
SET xid=NULL;
CALL bug15231_2b(xid);
SELECT "NULL, 1", xid, xdone;
END|
# This no longer works; SELECT id ... throws a warning, then the
# subsequent statements clear the diagnostics area before exit,
# and the caller never sees the warning, and therefore doesn't
# run the NOT FOUND handler!
CREATE PROCEDURE bug15231_2a(INOUT ioid INTEGER)
BEGIN
SELECT "Before NOT FOUND condition is triggered" AS '1';
SELECT id INTO ioid FROM t3 WHERE id=ioid;
SELECT "After NOT FOUND condtition is triggered" AS '2';
IF ioid IS NULL THEN
SET ioid=1;
END IF;
END|
# This works! The warning is thrown on the last procedure
# statement (END isn't, and therefore doesn't clear the
# diagnostics area). Therefore, the caller sees the warning,
# and runs the NOT FOUND handler.
CREATE PROCEDURE bug15231_2b(INOUT ioid INTEGER)
BEGIN
SELECT id INTO ioid FROM t3 WHERE id=ioid;
END|
CALL bug15231_1()|
DROP PROCEDURE bug15231_1|
DROP PROCEDURE bug15231_2a|
DROP PROCEDURE bug15231_2b|
--echo #
CREATE PROCEDURE bug15231_3()
BEGIN
DECLARE EXIT HANDLER FOR SQLWARNING
SELECT 'Caught it (correct)' AS 'Result';
CALL bug15231_4();
END|
CREATE PROCEDURE bug15231_4()
BEGIN
DECLARE x DECIMAL(2,1);
SET x = 'zap';
SHOW WARNINGS;
END|
CALL bug15231_3()|
--echo #
CREATE PROCEDURE bug15231_5()
BEGIN
DECLARE EXIT HANDLER FOR SQLWARNING
SELECT 'Caught it (wrong)' AS 'Result';
CALL bug15231_6();
END|
CREATE PROCEDURE bug15231_6()
BEGIN
DECLARE x DECIMAL(2,1);
SET x = 'zap';
SELECT id FROM t3;
END|
CALL bug15231_5()|
--echo #
--echo #
CREATE PROCEDURE bug15231_7()
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION
SELECT 'Caught it (right)' AS 'Result';
CALL bug15231_8();
END|
CREATE PROCEDURE bug15231_8()
BEGIN
DROP TABLE no_such_table;
SELECT 'Caught it (wrong)' AS 'Result';
END|
CALL bug15231_7()|
--echo #
DROP TABLE t3|
DROP PROCEDURE bug15231_3|
DROP PROCEDURE bug15231_4|
DROP PROCEDURE bug15231_5|
DROP PROCEDURE bug15231_6|
DROP PROCEDURE bug15231_7|
DROP PROCEDURE bug15231_8|
DELIMITER ;|
SET sql_mode = 'NO_ENGINE_SUBSTITUTION';
--echo
SET @@max_heap_table_size= @old_max_heap_table_size;
--echo
--echo #
--echo # Done WL#5928
--echo #
--echo
--echo # END 5.7 TESTS
--echo #
--source suite/xengine/include/check_xengine_log_error.inc