Skip to content

Commit d631091

Browse files
committed
WL#6406 Stacked diagnostic areas
This worklog implements support for stacked diagnostic areas and the GET STACKED DIAGNOSTICS statement. Each connection has it's own stack of diagnostic areas. The diagnostic area on top of the stack is called the first diagnostic area. The diagnostic area just below is the second diagnostic area. There can be more than just two diagnostic areas, but only the top two are accessible. Normally all interaction happens with the first diagnostic area. This is where conditions (errors, warnings, notes) that are raised, are entered. The contents of the first diagnostic area can be queried by the existing GET [CURRENT] DIAGNOSTICS statement, while the contents of the second diagnostic area can be queried by the new GET STACKED DIAGNOSTICS statement. A new diagnostic area is pushed to the diagnostic area stack when a stored routine handler is activated. Initially, this new area contains a copy of the contents of the second diagnostic area (i.e. the first diagnostic area before the push). This allows GET STACKED DIAGNOSTICS to be used throughout the handler to inspect the conditions that triggered the handler, regardless of what happens with the first diagnostic area. This worklog also fixes Bug#14342913 SP HANDLER DOES NOT PRESERVE CURRENT DIAGNOSTICS AREA If a stored routine handler exits with RESIGNAL, the first diagnostic area now contains all conditions present when the handler was activated + the condition added by RESIGNAL. Before this fix, only the first condition present at handler activation was preserved. The worklog also contains serveral refactorings of the error handling API.
1 parent 23c1cfe commit d631091

File tree

112 files changed

+3151
-2120
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

112 files changed

+3151
-2120
lines changed

Diff for: libmysqld/emb_qcache.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -487,7 +487,7 @@ int emb_load_querycache_result(THD *thd, Querycache_stream *src)
487487
data->embedded_info->prev_ptr= prev_row;
488488
return_ok:
489489
net_send_eof(thd, thd->server_status,
490-
thd->get_stmt_da()->current_statement_warn_count());
490+
thd->get_stmt_da()->current_statement_cond_count());
491491
DBUG_RETURN(0);
492492
err:
493493
DBUG_RETURN(1);

Diff for: libmysqld/lib_sql.cc

+3-3
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ static my_bool emb_read_prepare_result(MYSQL *mysql, MYSQL_STMT *stmt)
246246
stmt->stmt_id= thd->client_stmt_id;
247247
stmt->param_count= thd->client_param_count;
248248
stmt->field_count= 0;
249-
mysql->warning_count= thd->get_stmt_da()->current_statement_warn_count();
249+
mysql->warning_count= thd->get_stmt_da()->current_statement_cond_count();
250250

251251
if (thd->first_data)
252252
{
@@ -437,7 +437,7 @@ static void emb_free_embedded_thd(MYSQL *mysql)
437437
static const char * emb_read_statistics(MYSQL *mysql)
438438
{
439439
THD *thd= (THD*)mysql->thd;
440-
return thd->is_error() ? thd->get_stmt_da()->message() : "";
440+
return thd->is_error() ? thd->get_stmt_da()->message_text() : "";
441441
}
442442

443443

@@ -1140,7 +1140,7 @@ bool Protocol::send_result_set_metadata(List<Item> *list, uint flags)
11401140

11411141
if (flags & SEND_EOF)
11421142
write_eof_packet(thd, thd->server_status,
1143-
thd->get_stmt_da()->current_statement_warn_count());
1143+
thd->get_stmt_da()->current_statement_cond_count());
11441144

11451145
DBUG_RETURN(prepare_for_send(list->elements));
11461146
err:

Diff for: mysql-test/r/get_diagnostics.result

+129
Original file line numberDiff line numberDiff line change
@@ -800,3 +800,132 @@ GET DIAGNOSTICS @var1 = NUMBER;
800800
SHOW STATUS LIKE 'Com%get_diagnostics';
801801
Variable_name Value
802802
Com_get_diagnostics 1
803+
#
804+
# WL#6406 Stacked diagnostic areas
805+
#
806+
#
807+
# Test non-reserved keywords: STACKED
808+
CREATE TABLE t1 (stacked INT);
809+
INSERT INTO t1 (stacked) values (1);
810+
SELECT stacked FROM t1 WHERE stacked = 1;
811+
stacked
812+
1
813+
SELECT `stacked` FROM t1 WHERE `stacked` = 1;
814+
stacked
815+
1
816+
DROP TABLE t1;
817+
CREATE PROCEDURE p1()
818+
BEGIN
819+
DECLARE stacked INT DEFAULT 1;
820+
SELECT stacked;
821+
END|
822+
CALL p1();
823+
stacked
824+
1
825+
DROP PROCEDURE p1;
826+
#
827+
# Test GET STACKED DIAGNOSTICS syntax
828+
GET STACKED;
829+
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 '' at line 1
830+
GET STACKED DIAGNOSTICS;
831+
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 '' at line 1
832+
#
833+
# Error if used without active HANDLER
834+
GET STACKED DIAGNOSTICS @var1 = NUMBER;
835+
ERROR 0Z002: GET STACKED DIAGNOSTICS when handler not active
836+
CREATE PROCEDURE p1() GET STACKED DIAGNOSTICS @var1 = NUMBER;
837+
CALL p1();
838+
ERROR 0Z002: GET STACKED DIAGNOSTICS when handler not active
839+
DROP PROCEDURE p1;
840+
CREATE FUNCTION f1() RETURNS INT
841+
BEGIN
842+
GET STACKED DIAGNOSTICS @var1 = NUMBER;
843+
RETURN 1;
844+
END|
845+
SELECT f1();
846+
ERROR 0Z002: GET STACKED DIAGNOSTICS when handler not active
847+
DROP FUNCTION f1;
848+
#
849+
# GET CURRENT DIAGNOSTICS = GET STACKED DIAGNOSTICS
850+
# when handler is first activated
851+
# GET STACKED DIAGNOSTICS doesn't change during handler
852+
CREATE TABLE t1(a INT);
853+
CREATE PROCEDURE p1()
854+
BEGIN
855+
DECLARE EXIT HANDLER FOR SQLEXCEPTION
856+
BEGIN
857+
DECLARE msg1 TEXT;
858+
DECLARE errno1 INT;
859+
DECLARE msg2 TEXT;
860+
DECLARE errno2 INT;
861+
DECLARE msg4 TEXT;
862+
DECLARE errno4 INT;
863+
# Should be identical
864+
GET CURRENT DIAGNOSTICS CONDITION 1 msg1 = MESSAGE_TEXT, errno1 = MYSQL_ERRNO;
865+
SELECT msg1, errno1;
866+
GET STACKED DIAGNOSTICS CONDITION 1 msg2 = MESSAGE_TEXT, errno2 = MYSQL_ERRNO;
867+
SELECT msg2, errno2;
868+
SELECT * FROM t1; # Clear first diagnostics area
869+
# CURRENT should be empty, STACKED unchanged
870+
GET CURRENT DIAGNOSTICS @cno = NUMBER;
871+
SELECT @cno;
872+
GET STACKED DIAGNOSTICS CONDITION 1 msg4 = MESSAGE_TEXT, errno4 = MYSQL_ERRNO;
873+
SELECT msg4, errno4;
874+
END;
875+
DROP TABLE non_existent;
876+
END|
877+
CALL p1();
878+
msg1 errno1
879+
Unknown table 'test.non_existent' 1051
880+
msg2 errno2
881+
Unknown table 'test.non_existent' 1051
882+
a
883+
@cno
884+
0
885+
msg4 errno4
886+
Unknown table 'test.non_existent' 1051
887+
DROP PROCEDURE p1;
888+
DROP TABLE t1;
889+
#
890+
# RESIGNAL of a warning should modify the warning both in first and
891+
# second diagnostics area.
892+
CREATE PROCEDURE p1()
893+
BEGIN
894+
DECLARE CONTINUE HANDLER FOR SQLWARNING
895+
BEGIN
896+
DECLARE msg1 TEXT;
897+
DECLARE errno1 INT;
898+
DECLARE msg2 TEXT;
899+
DECLARE errno2 INT;
900+
DECLARE msg3 TEXT;
901+
DECLARE errno3 INT;
902+
DECLARE msg4 TEXT;
903+
DECLARE errno4 INT;
904+
# Should be identical
905+
GET CURRENT DIAGNOSTICS CONDITION 1 msg1 = MESSAGE_TEXT, errno1 = MYSQL_ERRNO;
906+
SELECT msg1, errno1;
907+
GET STACKED DIAGNOSTICS CONDITION 1 msg2 = MESSAGE_TEXT, errno2 = MYSQL_ERRNO;
908+
SELECT msg2, errno2;
909+
RESIGNAL SET MYSQL_ERRNO= 9999, MESSAGE_TEXT= 'Changed by resignal';
910+
# Should be changed, but still identical
911+
GET CURRENT DIAGNOSTICS CONDITION 1 msg3 = MESSAGE_TEXT, errno3 = MYSQL_ERRNO;
912+
SELECT msg3, errno3;
913+
GET STACKED DIAGNOSTICS CONDITION 1 msg4 = MESSAGE_TEXT, errno4 = MYSQL_ERRNO;
914+
SELECT msg4, errno4;
915+
END;
916+
SELECT 10 + 'a';
917+
END|
918+
CALL p1();
919+
10 + 'a'
920+
10
921+
msg1 errno1
922+
Truncated incorrect DOUBLE value: 'a' 1292
923+
msg2 errno2
924+
Truncated incorrect DOUBLE value: 'a' 1292
925+
msg3 errno3
926+
Changed by resignal 9999
927+
msg4 errno4
928+
Changed by resignal 9999
929+
Warnings:
930+
Warning 9999 Changed by resignal
931+
DROP PROCEDURE p1;

0 commit comments

Comments
 (0)