diff options
author | Rucha Deodhar <rucha.deodhar@mariadb.com> | 2021-10-15 00:40:06 +0530 |
---|---|---|
committer | Rucha Deodhar <rucha.deodhar@mariadb.com> | 2021-10-15 19:00:27 +0530 |
commit | afa411cda0ccebe822f3dd86acc359d0f61b746f (patch) | |
tree | f87012568da02b83eb2485f0e5fb70c5290e75d0 | |
parent | a6cf8b34a834e5d16155f8bb3f33d57a4f87eb9e (diff) | |
download | mariadb-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.result | 39 | ||||
-rw-r--r-- | mysql-test/main/get_diagnostics.test | 53 | ||||
-rw-r--r-- | sql/sql_class.h | 3 | ||||
-rw-r--r-- | sql/sql_error.cc | 1 | ||||
-rw-r--r-- | sql/sql_signal.cc | 21 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 2 |
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: |