Commit ff5de38d authored by Rucha Deodhar's avatar Rucha Deodhar Committed by Sergei Golubchik

MDEV-26832: ROW_NUMBER in SIGNAL/RESIGNAL causes a syntax error

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.
parent b15a5f6f
......@@ -1689,3 +1689,42 @@ SELECT @n, @m;
@n @m
2 Out of range value for column 'f' at row 2
DROP TABLE t;
#
# 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;
......@@ -1565,3 +1565,56 @@ GET DIAGNOSTICS CONDITION 2 @n= ROW_NUMBER, @m = MESSAGE_TEXT;
SELECT @n, @m;
DROP TABLE t;
--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;
......@@ -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;
/**
......
......@@ -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;
}
......
......@@ -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.
......
......@@ -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:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment