Skip to content

Commit

Permalink
MDEV-26606: ROW_NUMBER property value isn't passed from inside a stored
Browse files Browse the repository at this point in the history
procedure

Analysis: m_current_row_for_warning is reset to 1 during cleanup phase of
stored procedure. When we perform a copy because some statement of procedure
created warning, this reset value is passed to push_warning().
Hence the output is always 1.
Fix: Add a parameter in relevant functions to pass correct value of
row_number and don't use m_current_row_for_warning directly.
  • Loading branch information
mariadb-RuchaDeodhar committed Oct 6, 2021
1 parent 25921c9 commit 479e303
Show file tree
Hide file tree
Showing 6 changed files with 140 additions and 10 deletions.
60 changes: 58 additions & 2 deletions mysql-test/main/get_diagnostics.result
Original file line number Diff line number Diff line change
Expand Up @@ -1481,7 +1481,7 @@ ERROR HY000: Can't update table 't1' in stored function/trigger because it is al
GET DIAGNOSTICS CONDITION 1 @var119= ROW_NUMBER;
SELECT @var119;
@var119
2
1
INSERT INTO t1 VALUES (1) RETURNING id2;
ERROR 42S22: Unknown column 'id2' in 'field list'
GET DIAGNOSTICS CONDITION 1 @var120= ROW_NUMBER;
Expand Down Expand Up @@ -1523,7 +1523,7 @@ ERROR HY000: Can't update table 't1' in stored function/trigger because it is al
GET DIAGNOSTICS CONDITION 1 @var125= ROW_NUMBER;
SELECT @var125;
@var125
2
1
REPLACE INTO t1 VALUES (1) RETURNING id2;
ERROR 42S22: Unknown column 'id2' in 'field list'
GET DIAGNOSTICS CONDITION 1 @var126= ROW_NUMBER;
Expand Down Expand Up @@ -1552,3 +1552,59 @@ DROP TABLE t1,t2;
DROP FUNCTION f1;
DROP FUNCTION f2;
DROP VIEW v;
#
# MDEV-26606: ROW_NUMBER property value isn't passed from inside a
# stored procedure
#
# Test 1: Without RESIGNAL
CREATE OR REPLACE TABLE t1 (pk INT PRIMARY KEY);
CREATE OR REPLACE PROCEDURE sp(a INT) INSERT INTO t1 VALUES (2),(a);
SET @num=null, @msg=null;
INSERT INTO t1 VALUES(1);
CALL sp(1);
ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
GET DIAGNOSTICS CONDITION 1 @num = ROW_NUMBER, @msg = MESSAGE_TEXT;
SELECT @num, @msg;
@num @msg
2 Duplicate entry '1' for key 'PRIMARY'
DROP PROCEDURE sp;
DROP TABLE t1;
# Test 2: With RESIGNAL
CREATE OR REPLACE TABLE t1 (pk INT PRIMARY KEY);
CREATE OR REPLACE PROCEDURE sp(a INT)
BEGIN
DECLARE n INT;
DECLARE m VARCHAR(255);
DECLARE EXIT HANDLER FOR 1062
BEGIN
GET DIAGNOSTICS CONDITION 1 n = ROW_NUMBER, m = MESSAGE_TEXT;
SELECT n, m;
RESIGNAL;
END;
INSERT INTO t1 VALUES (2), (a);
END |
SET @num=null, @msg=null;
INSERT INTO t1 VALUES (1);
CALL sp(1);
n m
2 Duplicate entry '1' for key 'PRIMARY'
ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
GET DIAGNOSTICS CONDITION 1 @num = ROW_NUMBER, @msg = MESSAGE_TEXT;
SELECT @num, @msg;
@num @msg
2 Duplicate entry '1' for key 'PRIMARY'
DROP PROCEDURE sp;
DROP TABLE t1;
# Checking more errors
CREATE TABLE t1 (val1 TINYINT);
CREATE PROCEDURE sp(a INT) INSERT INTO t1 VALUES (2),(a);
INSERT INTO t1 VALUES(1);
CALL sp(100000);
Warnings:
Warning 1264 Out of range value for column 'val1' at row 2
GET DIAGNOSTICS CONDITION 1 @var1= ROW_NUMBER;
SELECT @var1;
@var1
2
DROP TABLE t1;
DROP PROCEDURE sp;
66 changes: 66 additions & 0 deletions mysql-test/main/get_diagnostics.test
Original file line number Diff line number Diff line change
Expand Up @@ -1430,3 +1430,69 @@ DROP TABLE t1,t2;
DROP FUNCTION f1;
DROP FUNCTION f2;
DROP VIEW v;

--echo #
--echo # MDEV-26606: ROW_NUMBER property value isn't passed from inside a
--echo # stored procedure
--echo #

--echo # Test 1: Without RESIGNAL

CREATE OR REPLACE TABLE t1 (pk INT PRIMARY KEY);
CREATE OR REPLACE PROCEDURE sp(a INT) INSERT INTO t1 VALUES (2),(a);
SET @num=null, @msg=null;

INSERT INTO t1 VALUES(1);

--error ER_DUP_ENTRY
CALL sp(1);
GET DIAGNOSTICS CONDITION 1 @num = ROW_NUMBER, @msg = MESSAGE_TEXT;
SELECT @num, @msg;

DROP PROCEDURE sp;
DROP TABLE t1;

--echo # Test 2: With RESIGNAL

CREATE OR REPLACE TABLE t1 (pk INT PRIMARY KEY);

DELIMITER |;
CREATE OR REPLACE PROCEDURE sp(a INT)
BEGIN
DECLARE n INT;
DECLARE m VARCHAR(255);
DECLARE EXIT HANDLER FOR 1062
BEGIN
GET DIAGNOSTICS CONDITION 1 n = ROW_NUMBER, m = MESSAGE_TEXT;
SELECT n, m;
RESIGNAL;
END;
INSERT INTO t1 VALUES (2), (a);
END |
DELIMITER ;|

SET @num=null, @msg=null;
INSERT INTO t1 VALUES (1);

--error ER_DUP_ENTRY
CALL sp(1);
GET DIAGNOSTICS CONDITION 1 @num = ROW_NUMBER, @msg = MESSAGE_TEXT;
SELECT @num, @msg;

DROP PROCEDURE sp;
DROP TABLE t1;

--echo # Checking more errors

CREATE TABLE t1 (val1 TINYINT);

CREATE PROCEDURE sp(a INT) INSERT INTO t1 VALUES (2),(a);

INSERT INTO t1 VALUES(1);

CALL sp(100000);
GET DIAGNOSTICS CONDITION 1 @var1= ROW_NUMBER;
SELECT @var1;

DROP TABLE t1;
DROP PROCEDURE sp;
2 changes: 2 additions & 0 deletions sql/lex.h
Original file line number Diff line number Diff line change
Expand Up @@ -567,6 +567,8 @@ SYMBOL symbols[] = {
{ "ROWS", SYM(ROWS_SYM)},
{ "ROWTYPE", SYM(ROWTYPE_MARIADB_SYM)},
{ "ROW_COUNT", SYM(ROW_COUNT_SYM)},
/** sql_function and condition_property_name for GET DIAGNOSTICS */
{ "ROW_NUMBER", SYM(ROW_NUMBER_SYM)},
{ "ROW_FORMAT", SYM(ROW_FORMAT_SYM)},
/** sql_function and condition_property_name for GET DIAGNOSTICS */
{ "ROW_NUMBER", SYM(ROW_NUMBER_SYM)},
Expand Down
3 changes: 2 additions & 1 deletion sql/sql_class.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1149,7 +1149,8 @@ Sql_condition* THD::raise_condition(uint sql_errno,
if (likely(!(is_fatal_error && (sql_errno == EE_OUTOFMEMORY ||
sql_errno == ER_OUTOFMEMORY))))
{
cond= da->push_warning(this, sql_errno, sqlstate, level, ucid, msg);
cond= da->push_warning(this, sql_errno, sqlstate, level, ucid, msg,
da->current_row_for_warning());
}
DBUG_RETURN(cond);
}
Expand Down
8 changes: 5 additions & 3 deletions sql/sql_error.cc
Original file line number Diff line number Diff line change
Expand Up @@ -663,7 +663,8 @@ void Warning_info::reserve_space(THD *thd, uint count)

Sql_condition *Warning_info::push_warning(THD *thd,
const Sql_condition_identity *value,
const char *msg)
const char *msg,
ulong current_row_number)
{
Sql_condition *cond= NULL;

Expand All @@ -673,7 +674,7 @@ Sql_condition *Warning_info::push_warning(THD *thd,
m_warn_list.elements() < thd->variables.max_error_count)
{
cond= new (& m_warn_root) Sql_condition(& m_warn_root, *value, msg,
m_current_row_for_warning);
current_row_number);
if (cond)
m_warn_list.push_back(cond);
}
Expand All @@ -689,7 +690,8 @@ Sql_condition *Warning_info::push_warning(THD *thd,
const Sql_condition *sql_condition)
{
Sql_condition *new_condition= push_warning(thd, sql_condition,
sql_condition->get_message_text());
sql_condition->get_message_text(),
sql_condition->m_row_number);

if (new_condition)
new_condition->copy_opt_attributes(sql_condition);
Expand Down
11 changes: 7 additions & 4 deletions sql/sql_error.h
Original file line number Diff line number Diff line change
Expand Up @@ -748,7 +748,8 @@ class Warning_info
*/
Sql_condition *push_warning(THD *thd,
const Sql_condition_identity *identity,
const char* msg);
const char* msg,
ulong current_row_number);

/**
Add a new SQL-condition to the current list and increment the respective
Expand Down Expand Up @@ -1179,10 +1180,12 @@ class Diagnostics_area: public Sql_state_errno,
const char* sqlstate,
Sql_condition::enum_warning_level level,
const Sql_user_condition_identity &ucid,
const char* msg)
const char* msg,
ulong current_row_number)
{
Sql_condition_identity tmp(sql_errno_arg, sqlstate, level, ucid);
return get_warning_info()->push_warning(thd, &tmp, msg);
return get_warning_info()->push_warning(thd, &tmp, msg,
current_row_number);
}

Sql_condition *push_warning(THD *thd,
Expand All @@ -1192,7 +1195,7 @@ class Diagnostics_area: public Sql_state_errno,
const char* msg)
{
return push_warning(thd, sqlerrno, sqlstate, level,
Sql_user_condition_identity(), msg);
Sql_user_condition_identity(), msg, 0);
}
void mark_sql_conditions_for_removal()
{ get_warning_info()->mark_sql_conditions_for_removal(); }
Expand Down

0 comments on commit 479e303

Please sign in to comment.