summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRucha Deodhar <rucha.deodhar@mariadb.com>2021-10-15 00:40:06 +0530
committerRucha Deodhar <rucha.deodhar@mariadb.com>2021-10-15 19:00:27 +0530
commitafa411cda0ccebe822f3dd86acc359d0f61b746f (patch)
treef87012568da02b83eb2485f0e5fb70c5290e75d0
parenta6cf8b34a834e5d16155f8bb3f33d57a4f87eb9e (diff)
downloadmariadb-git-bb-10.7-MDEV-26832.tar.gz
MDEV-26832: ROW_NUMBER in SIGNAL/RESIGNAL causes a syntax errorbb-10.7-MDEV-26832
Analysis: Parser was missing ROW_NUMBER as syntax for SIGNAL and RESIGNAL. Fix: Fix parser and fix how m_row_number is copied like other attributes to avoid ROW_NUMBER from assuming default value.
-rw-r--r--mysql-test/main/get_diagnostics.result39
-rw-r--r--mysql-test/main/get_diagnostics.test53
-rw-r--r--sql/sql_class.h3
-rw-r--r--sql/sql_error.cc1
-rw-r--r--sql/sql_signal.cc21
-rw-r--r--sql/sql_yacc.yy2
6 files changed, 118 insertions, 1 deletions
diff --git a/mysql-test/main/get_diagnostics.result b/mysql-test/main/get_diagnostics.result
index 7bd1bde10de..840b4f32d2d 100644
--- a/mysql-test/main/get_diagnostics.result
+++ b/mysql-test/main/get_diagnostics.result
@@ -1671,3 +1671,42 @@ SELECT @rnum, @msg, @err;
@rnum @msg @err
3 Data truncated for column 'a' at row 3 1265
DROP TABLE t1;
+#
+# MDEV-26832: ROW_NUMBER in SIGNAL/RESIGNAL causes a syntax error
+#
+# using signal
+CREATE PROCEDURE signal_syntax()
+BEGIN
+DECLARE errno INT DEFAULT 0;
+DECLARE msg TEXT DEFAULT "foo";
+DECLARE row_num INT DEFAULT 0;
+DECLARE cond CONDITION FOR SQLSTATE "01234";
+DECLARE CONTINUE HANDLER for 1012
+BEGIN
+GET DIAGNOSTICS CONDITION 1 errno = MYSQL_ERRNO, msg = MESSAGE_TEXT, row_num= ROW_NUMBER;
+END;
+SIGNAL cond SET MESSAGE_TEXT = "Signal message", MYSQL_ERRNO = 1012, ROW_NUMBER= 5;
+SELECT errno, msg, row_num;
+END|
+CALL signal_syntax();
+errno msg row_num
+1012 Signal message 5
+DROP PROCEDURE signal_syntax;
+# using resignal
+CREATE PROCEDURE resignal_syntax()
+BEGIN
+DECLARE CONTINUE HANDLER
+FOR 1146
+BEGIN
+RESIGNAL SET
+MESSAGE_TEXT = '`temptab` does not exist', ROW_NUMBER= 105;
+END;
+SELECT `c` FROM `temptab`;
+END|
+CALL resignal_syntax();
+ERROR 42S02: `temptab` does not exist
+GET DIAGNOSTICS CONDITION 1 @row_num= ROW_NUMBER;
+SELECT @row_num;
+@row_num
+105
+DROP PROCEDURE resignal_syntax;
diff --git a/mysql-test/main/get_diagnostics.test b/mysql-test/main/get_diagnostics.test
index 83ea1dee343..d3dd6b7f91f 100644
--- a/mysql-test/main/get_diagnostics.test
+++ b/mysql-test/main/get_diagnostics.test
@@ -1552,3 +1552,56 @@ GET DIAGNOSTICS CONDITION 2 @rnum = ROW_NUMBER, @msg = MESSAGE_TEXT, @err = MYSQ
SELECT @rnum, @msg, @err;
DROP TABLE t1;
+
+--echo #
+--echo # MDEV-26832: ROW_NUMBER in SIGNAL/RESIGNAL causes a syntax error
+--echo #
+
+--echo # using signal
+
+DELIMITER |;
+CREATE PROCEDURE signal_syntax()
+BEGIN
+ DECLARE errno INT DEFAULT 0;
+ DECLARE msg TEXT DEFAULT "foo";
+ DECLARE row_num INT DEFAULT 0;
+ DECLARE cond CONDITION FOR SQLSTATE "01234";
+ DECLARE CONTINUE HANDLER for 1012
+ BEGIN
+ GET DIAGNOSTICS CONDITION 1 errno = MYSQL_ERRNO, msg = MESSAGE_TEXT, row_num= ROW_NUMBER;
+ END;
+
+ SIGNAL cond SET MESSAGE_TEXT = "Signal message", MYSQL_ERRNO = 1012, ROW_NUMBER= 5;
+
+ SELECT errno, msg, row_num;
+END|
+DELIMITER ;|
+
+CALL signal_syntax();
+
+DROP PROCEDURE signal_syntax;
+
+--echo # using resignal
+
+DELIMITER |;
+
+CREATE PROCEDURE resignal_syntax()
+BEGIN
+ DECLARE CONTINUE HANDLER
+ FOR 1146
+ BEGIN
+ RESIGNAL SET
+ MESSAGE_TEXT = '`temptab` does not exist', ROW_NUMBER= 105;
+ END;
+ SELECT `c` FROM `temptab`;
+END|
+
+DELIMITER ;|
+
+--error ER_NO_SUCH_TABLE
+CALL resignal_syntax();
+
+GET DIAGNOSTICS CONDITION 1 @row_num= ROW_NUMBER;
+SELECT @row_num;
+
+DROP PROCEDURE resignal_syntax;
diff --git a/sql/sql_class.h b/sql/sql_class.h
index e569fcd32d6..e8793e1688f 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -560,7 +560,8 @@ typedef enum enum_diag_condition_item_name
DIAG_CURSOR_NAME= 9,
DIAG_MESSAGE_TEXT= 10,
DIAG_MYSQL_ERRNO= 11,
- LAST_DIAG_SET_PROPERTY= DIAG_MYSQL_ERRNO
+ DIAG_ROW_NUMBER= 12,
+ LAST_DIAG_SET_PROPERTY= DIAG_ROW_NUMBER
} Diag_condition_item_name;
/**
diff --git a/sql/sql_error.cc b/sql/sql_error.cc
index a2178831697..c557b30e98e 100644
--- a/sql/sql_error.cc
+++ b/sql/sql_error.cc
@@ -204,6 +204,7 @@ Sql_condition::copy_opt_attributes(const Sql_condition *cond)
copy_string(m_mem_root, & m_table_name, & cond->m_table_name);
copy_string(m_mem_root, & m_column_name, & cond->m_column_name);
copy_string(m_mem_root, & m_cursor_name, & cond->m_cursor_name);
+ m_row_number= cond->m_row_number;
}
diff --git a/sql/sql_signal.cc b/sql/sql_signal.cc
index e023923bd1a..6ccc16c53e5 100644
--- a/sql/sql_signal.cc
+++ b/sql/sql_signal.cc
@@ -44,6 +44,7 @@ const LEX_CSTRING Diag_condition_item_names[]=
{ STRING_WITH_LEN("CURSOR_NAME") },
{ STRING_WITH_LEN("MESSAGE_TEXT") },
{ STRING_WITH_LEN("MYSQL_ERRNO") },
+ { STRING_WITH_LEN("ROW_NUMBER") },
{ STRING_WITH_LEN("CONDITION_IDENTIFIER") },
{ STRING_WITH_LEN("CONDITION_NUMBER") },
@@ -309,6 +310,26 @@ int Sql_cmd_common_signal::eval_signal_informations(THD *thd, Sql_condition *con
cond->m_sql_errno= (int) code;
}
+ set= m_set_signal_information.m_item[DIAG_ROW_NUMBER];
+ if (set != NULL)
+ {
+ if (set->is_null())
+ {
+ thd->raise_error_printf(ER_WRONG_VALUE_FOR_VAR,
+ "ROW_NUMBER", "NULL");
+ goto end;
+ }
+ longlong row_number_value= set->val_int();
+ if (row_number_value < 0)
+ {
+ str= set->val_str(& str_value);
+ thd->raise_error_printf(ER_WRONG_VALUE_FOR_VAR,
+ "ROW_NUMBER", str->c_ptr_safe());
+ goto end;
+ }
+ cond->m_row_number= (ulong) row_number_value;
+ }
+
/*
The various item->val_xxx() methods don't return an error code,
but flag thd in case of failure.
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index deb78f4dfe4..841ae6ff1f1 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -3475,6 +3475,8 @@ signal_condition_information_item_name:
{ $$= DIAG_MESSAGE_TEXT; }
| MYSQL_ERRNO_SYM
{ $$= DIAG_MYSQL_ERRNO; }
+ | ROW_NUMBER_SYM
+ { $$= DIAG_ROW_NUMBER; }
;
resignal_stmt: