[MDEV-774] LP:948583 - Stored procedure doesn't not take into account ALTER TABLE, causes wrong result or replication abort Created: 2012-03-07  Updated: 2023-11-28

Status: Confirmed
Project: MariaDB Server
Component/s: Data Definition - Alter Table
Affects Version/s: 5.3.9, 5.3.12, 5.5, 10.0, 10.3, 10.4, 10.5, 10.6, 10.7, 10.8, 10.9, 10.10
Fix Version/s: 10.4, 10.5, 10.6

Type: Bug Priority: Major
Reporter: Elena Stepanova Assignee: Dmitry Shulga
Resolution: Unresolved Votes: 2
Labels: Launchpad, upstream-fixed, verified

Attachments: XML File LPexportBug948583.xml    
Issue Links:
Duplicate
duplicates MDEV-11652 SP with cursors does not work well in... Confirmed
is duplicated by MDEV-15097 Stored procedures are unaware of meta... Closed
PartOf
is part of MDEV-5242 merge 5.6 bugfixes into 10.0 Open
is part of MDEV-5816 MySQL WL#4179 - Stored programs: vali... Closed
Relates
relates to MDEV-12166 PROCEDURE using a SELECT from a tempo... Open
relates to MDEV-21234 Server crashes in in setup_on_expr up... Closed

 Description   

The problem is reproducible on all of MariaDB 5.1, 5.2, 5.3, 5.5, MySQL 5.1, 5.5, 5.6, and has also been filed as http://bugs.mysql.com/bug.php?id=64574.

A stored procedure or a trigger, having been executed once, on the second run might not take into account changes in a table structure, which causes a wrong result on the server where it is run, and also might cause SQL slave abort if the master wrongly returns OK after such a change, while the slave throws the expected error.

Below are two test cases. The first one is for the basic scenario: the initial execution of the stored procedure ends with the expected error, then the table structure gets fixed, but the procedure fails anyway, with

query 'CALL p()' failed: 1054: Unknown column 'test.t2.b' in 'field list'

The second test case is a reversed scenario – first execution of the procedure runs fine (correctly), then the table structure is altered, and the second execution must fail, but it does not on master; instead, the statement is written in the binlog with error code 0 and later fails on slave, thus causing a replication failure:

1136 Error 'Column count doesn't match value count at row 1' on query.

I found the ancient bug http://bugs.mysql.com/bug.php?id=6120 which looks similar, only for views, but it was fixed ages ago.

Test case 1 (wrong result - the last procedure call fails while it shouldn't)

CREATE TABLE t1 (a INT);
CREATE TABLE t2 (b INT, c INT);
 
--delimiter |
CREATE PROCEDURE p()
BEGIN
  INSERT INTO t1 SELECT * FROM t2;
END |
--delimiter ;
 
--error ER_WRONG_VALUE_COUNT_ON_ROW
CALL p();
ALTER TABLE t2 DROP COLUMN b;
CALL p();
 

Test case 2 (replication failure)

--source include/master-slave.inc
CREATE TABLE t1 (a INT);
CREATE TABLE t2 (b INT);
 
--delimiter |
CREATE PROCEDURE p()
BEGIN
  INSERT INTO t1 SELECT * FROM t2;
END |
--delimiter ;
 
CALL p();
ALTER TABLE t2 ADD COLUMN c INT;
CALL p();
--sync_slave_with_master
 



 Comments   
Comment by Rasmus Johansson (Inactive) [ 2012-03-12 ]

Launchpad bug id: 948583

Comment by Sergei Golubchik [ 2013-01-01 ]

fixed in mysql-5.6.6

Comment by Elena Stepanova [ 2013-05-08 ]

The upstream bug was fixed in 5.6.6. I think it's okay to have the fix in 10.0 only (after the fix from 5.6 is merged in), so I'm removing 5.x from the 'Fix versions' list.

Comment by Elena Stepanova [ 2014-11-09 ]

Still reproducible on current 10.0 (10.0.14+, revno 4471).

Upstream bug was fixed in 5.6.6, apparently as a part of http://dev.mysql.com/worklog/task/?id=4179

evno: 3857
committer: Alexander Nozdrin <alexander.nozdrin@oracle.com>
branch nick: trunk-stage.2
timestamp: Wed 2012-05-16 16:36:41 +0400
message:
  WL#4179: Stored programs: validation of stored program statements.
  
  Briefly, that's the implementation of WL#4179. The idea is to remember
  the original query for SQL-statement within a Stored Programs and re-parse
  it when meta-data has changed.

It might be too big to get it in 10.0, but maybe 10.1 is okay, since it's not a feature as such, but a big fat bugfix.

Comment by Elena Stepanova [ 2016-04-14 ]

serg, some time ago you unset 'Fix version/s' on this report, was there a reason for that – should we close it as 'Won't fix', or target for 10.2, or...?

Comment by Sergei Golubchik [ 2016-04-15 ]

We'll fix it, but 10.2 is unlikely, that's why I've unset the version.

Comment by Alexander Barkov [ 2017-03-02 ]

The same problem is repeatable with cursors:

SET sql_mode=DEFAULT;
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (a INT, b VARCHAR(10));
INSERT INTO t1 VALUES (10,20);
 
DROP PROCEDURE IF EXISTS p1;
DELIMITER $$
CREATE PROCEDURE p1()
BEGIN
  DECLARE a,b INT;
  DECLARE cur CURSOR FOR SELECT * FROM t1;
  OPEN cur;
  FETCH cur INTO a,b;
  CLOSE cur;
  SELECT a,b;
END;
$$
DELIMITER ;
CALL p1();

The above script returns:

+------+------+
| a    | b    |
+------+------+
|   10 |   20 |
+------+------+

So far so good.

Now I add a new column to the table and call the procedure again

ALTER TABLE t1 ADD c INT;
CALL p1();

Oops. It returns the result, like if the table still had 2 columns.
It should fail, because there are now 3 columns in the table.

Comment by Hartmut Holzgraefe [ 2018-01-27 ]

See also: http://alexandernozdrin.blogspot.de/2012/09/mysql-56-handling-metadata-changes-in.html

Generated at Thu Feb 08 06:31:15 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.