Skip to content

Commit 479e303

Browse files
MDEV-26606: ROW_NUMBER property value isn't passed from inside a stored
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.
1 parent 25921c9 commit 479e303

File tree

6 files changed

+140
-10
lines changed

6 files changed

+140
-10
lines changed

mysql-test/main/get_diagnostics.result

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1481,7 +1481,7 @@ ERROR HY000: Can't update table 't1' in stored function/trigger because it is al
14811481
GET DIAGNOSTICS CONDITION 1 @var119= ROW_NUMBER;
14821482
SELECT @var119;
14831483
@var119
1484-
2
1484+
1
14851485
INSERT INTO t1 VALUES (1) RETURNING id2;
14861486
ERROR 42S22: Unknown column 'id2' in 'field list'
14871487
GET DIAGNOSTICS CONDITION 1 @var120= ROW_NUMBER;
@@ -1523,7 +1523,7 @@ ERROR HY000: Can't update table 't1' in stored function/trigger because it is al
15231523
GET DIAGNOSTICS CONDITION 1 @var125= ROW_NUMBER;
15241524
SELECT @var125;
15251525
@var125
1526-
2
1526+
1
15271527
REPLACE INTO t1 VALUES (1) RETURNING id2;
15281528
ERROR 42S22: Unknown column 'id2' in 'field list'
15291529
GET DIAGNOSTICS CONDITION 1 @var126= ROW_NUMBER;
@@ -1552,3 +1552,59 @@ DROP TABLE t1,t2;
15521552
DROP FUNCTION f1;
15531553
DROP FUNCTION f2;
15541554
DROP VIEW v;
1555+
#
1556+
# MDEV-26606: ROW_NUMBER property value isn't passed from inside a
1557+
# stored procedure
1558+
#
1559+
# Test 1: Without RESIGNAL
1560+
CREATE OR REPLACE TABLE t1 (pk INT PRIMARY KEY);
1561+
CREATE OR REPLACE PROCEDURE sp(a INT) INSERT INTO t1 VALUES (2),(a);
1562+
SET @num=null, @msg=null;
1563+
INSERT INTO t1 VALUES(1);
1564+
CALL sp(1);
1565+
ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
1566+
GET DIAGNOSTICS CONDITION 1 @num = ROW_NUMBER, @msg = MESSAGE_TEXT;
1567+
SELECT @num, @msg;
1568+
@num @msg
1569+
2 Duplicate entry '1' for key 'PRIMARY'
1570+
DROP PROCEDURE sp;
1571+
DROP TABLE t1;
1572+
# Test 2: With RESIGNAL
1573+
CREATE OR REPLACE TABLE t1 (pk INT PRIMARY KEY);
1574+
CREATE OR REPLACE PROCEDURE sp(a INT)
1575+
BEGIN
1576+
DECLARE n INT;
1577+
DECLARE m VARCHAR(255);
1578+
DECLARE EXIT HANDLER FOR 1062
1579+
BEGIN
1580+
GET DIAGNOSTICS CONDITION 1 n = ROW_NUMBER, m = MESSAGE_TEXT;
1581+
SELECT n, m;
1582+
RESIGNAL;
1583+
END;
1584+
INSERT INTO t1 VALUES (2), (a);
1585+
END |
1586+
SET @num=null, @msg=null;
1587+
INSERT INTO t1 VALUES (1);
1588+
CALL sp(1);
1589+
n m
1590+
2 Duplicate entry '1' for key 'PRIMARY'
1591+
ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
1592+
GET DIAGNOSTICS CONDITION 1 @num = ROW_NUMBER, @msg = MESSAGE_TEXT;
1593+
SELECT @num, @msg;
1594+
@num @msg
1595+
2 Duplicate entry '1' for key 'PRIMARY'
1596+
DROP PROCEDURE sp;
1597+
DROP TABLE t1;
1598+
# Checking more errors
1599+
CREATE TABLE t1 (val1 TINYINT);
1600+
CREATE PROCEDURE sp(a INT) INSERT INTO t1 VALUES (2),(a);
1601+
INSERT INTO t1 VALUES(1);
1602+
CALL sp(100000);
1603+
Warnings:
1604+
Warning 1264 Out of range value for column 'val1' at row 2
1605+
GET DIAGNOSTICS CONDITION 1 @var1= ROW_NUMBER;
1606+
SELECT @var1;
1607+
@var1
1608+
2
1609+
DROP TABLE t1;
1610+
DROP PROCEDURE sp;

mysql-test/main/get_diagnostics.test

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1430,3 +1430,69 @@ DROP TABLE t1,t2;
14301430
DROP FUNCTION f1;
14311431
DROP FUNCTION f2;
14321432
DROP VIEW v;
1433+
1434+
--echo #
1435+
--echo # MDEV-26606: ROW_NUMBER property value isn't passed from inside a
1436+
--echo # stored procedure
1437+
--echo #
1438+
1439+
--echo # Test 1: Without RESIGNAL
1440+
1441+
CREATE OR REPLACE TABLE t1 (pk INT PRIMARY KEY);
1442+
CREATE OR REPLACE PROCEDURE sp(a INT) INSERT INTO t1 VALUES (2),(a);
1443+
SET @num=null, @msg=null;
1444+
1445+
INSERT INTO t1 VALUES(1);
1446+
1447+
--error ER_DUP_ENTRY
1448+
CALL sp(1);
1449+
GET DIAGNOSTICS CONDITION 1 @num = ROW_NUMBER, @msg = MESSAGE_TEXT;
1450+
SELECT @num, @msg;
1451+
1452+
DROP PROCEDURE sp;
1453+
DROP TABLE t1;
1454+
1455+
--echo # Test 2: With RESIGNAL
1456+
1457+
CREATE OR REPLACE TABLE t1 (pk INT PRIMARY KEY);
1458+
1459+
DELIMITER |;
1460+
CREATE OR REPLACE PROCEDURE sp(a INT)
1461+
BEGIN
1462+
DECLARE n INT;
1463+
DECLARE m VARCHAR(255);
1464+
DECLARE EXIT HANDLER FOR 1062
1465+
BEGIN
1466+
GET DIAGNOSTICS CONDITION 1 n = ROW_NUMBER, m = MESSAGE_TEXT;
1467+
SELECT n, m;
1468+
RESIGNAL;
1469+
END;
1470+
INSERT INTO t1 VALUES (2), (a);
1471+
END |
1472+
DELIMITER ;|
1473+
1474+
SET @num=null, @msg=null;
1475+
INSERT INTO t1 VALUES (1);
1476+
1477+
--error ER_DUP_ENTRY
1478+
CALL sp(1);
1479+
GET DIAGNOSTICS CONDITION 1 @num = ROW_NUMBER, @msg = MESSAGE_TEXT;
1480+
SELECT @num, @msg;
1481+
1482+
DROP PROCEDURE sp;
1483+
DROP TABLE t1;
1484+
1485+
--echo # Checking more errors
1486+
1487+
CREATE TABLE t1 (val1 TINYINT);
1488+
1489+
CREATE PROCEDURE sp(a INT) INSERT INTO t1 VALUES (2),(a);
1490+
1491+
INSERT INTO t1 VALUES(1);
1492+
1493+
CALL sp(100000);
1494+
GET DIAGNOSTICS CONDITION 1 @var1= ROW_NUMBER;
1495+
SELECT @var1;
1496+
1497+
DROP TABLE t1;
1498+
DROP PROCEDURE sp;

sql/lex.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -567,6 +567,8 @@ SYMBOL symbols[] = {
567567
{ "ROWS", SYM(ROWS_SYM)},
568568
{ "ROWTYPE", SYM(ROWTYPE_MARIADB_SYM)},
569569
{ "ROW_COUNT", SYM(ROW_COUNT_SYM)},
570+
/** sql_function and condition_property_name for GET DIAGNOSTICS */
571+
{ "ROW_NUMBER", SYM(ROW_NUMBER_SYM)},
570572
{ "ROW_FORMAT", SYM(ROW_FORMAT_SYM)},
571573
/** sql_function and condition_property_name for GET DIAGNOSTICS */
572574
{ "ROW_NUMBER", SYM(ROW_NUMBER_SYM)},

sql/sql_class.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1149,7 +1149,8 @@ Sql_condition* THD::raise_condition(uint sql_errno,
11491149
if (likely(!(is_fatal_error && (sql_errno == EE_OUTOFMEMORY ||
11501150
sql_errno == ER_OUTOFMEMORY))))
11511151
{
1152-
cond= da->push_warning(this, sql_errno, sqlstate, level, ucid, msg);
1152+
cond= da->push_warning(this, sql_errno, sqlstate, level, ucid, msg,
1153+
da->current_row_for_warning());
11531154
}
11541155
DBUG_RETURN(cond);
11551156
}

sql/sql_error.cc

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -663,7 +663,8 @@ void Warning_info::reserve_space(THD *thd, uint count)
663663

664664
Sql_condition *Warning_info::push_warning(THD *thd,
665665
const Sql_condition_identity *value,
666-
const char *msg)
666+
const char *msg,
667+
ulong current_row_number)
667668
{
668669
Sql_condition *cond= NULL;
669670

@@ -673,7 +674,7 @@ Sql_condition *Warning_info::push_warning(THD *thd,
673674
m_warn_list.elements() < thd->variables.max_error_count)
674675
{
675676
cond= new (& m_warn_root) Sql_condition(& m_warn_root, *value, msg,
676-
m_current_row_for_warning);
677+
current_row_number);
677678
if (cond)
678679
m_warn_list.push_back(cond);
679680
}
@@ -689,7 +690,8 @@ Sql_condition *Warning_info::push_warning(THD *thd,
689690
const Sql_condition *sql_condition)
690691
{
691692
Sql_condition *new_condition= push_warning(thd, sql_condition,
692-
sql_condition->get_message_text());
693+
sql_condition->get_message_text(),
694+
sql_condition->m_row_number);
693695

694696
if (new_condition)
695697
new_condition->copy_opt_attributes(sql_condition);

sql/sql_error.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -748,7 +748,8 @@ class Warning_info
748748
*/
749749
Sql_condition *push_warning(THD *thd,
750750
const Sql_condition_identity *identity,
751-
const char* msg);
751+
const char* msg,
752+
ulong current_row_number);
752753

753754
/**
754755
Add a new SQL-condition to the current list and increment the respective
@@ -1179,10 +1180,12 @@ class Diagnostics_area: public Sql_state_errno,
11791180
const char* sqlstate,
11801181
Sql_condition::enum_warning_level level,
11811182
const Sql_user_condition_identity &ucid,
1182-
const char* msg)
1183+
const char* msg,
1184+
ulong current_row_number)
11831185
{
11841186
Sql_condition_identity tmp(sql_errno_arg, sqlstate, level, ucid);
1185-
return get_warning_info()->push_warning(thd, &tmp, msg);
1187+
return get_warning_info()->push_warning(thd, &tmp, msg,
1188+
current_row_number);
11861189
}
11871190

11881191
Sql_condition *push_warning(THD *thd,
@@ -1192,7 +1195,7 @@ class Diagnostics_area: public Sql_state_errno,
11921195
const char* msg)
11931196
{
11941197
return push_warning(thd, sqlerrno, sqlstate, level,
1195-
Sql_user_condition_identity(), msg);
1198+
Sql_user_condition_identity(), msg, 0);
11961199
}
11971200
void mark_sql_conditions_for_removal()
11981201
{ get_warning_info()->mark_sql_conditions_for_removal(); }

0 commit comments

Comments
 (0)