Bug #40625 | Concat fails on DOUBLE values in a Stored Procedure, while DECIMAL works | ||
---|---|---|---|
Submitted: | 10 Nov 2008 23:07 | Modified: | 21 Jun 2010 1:03 |
Reporter: | Jason Garrett | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | MySQL Server: Data Types | Severity: | S2 (Serious) |
Version: | 5.0.67-community-nt, 5.0.70, 5.1.29 | OS: | Any |
Assigned to: | Gleb Shchepa | CPU Architecture: | Any |
Tags: | concat |
[10 Nov 2008 23:07]
Jason Garrett
[10 Nov 2008 23:13]
Jason Garrett
Database Create and Populate Script, with Example Stored Procedure to demonstrate error
Attachment: 20081111 MySQL DOUBLE Error.txt (text/plain), 3.79 KiB.
[11 Nov 2008 5:07]
Valeriy Kravchuk
Thank you for a bug report. Verified just as described wiht 5.0.70: C:\Program Files\MySQL\MySQL Server 5.0\bin>mysql -uroot -proot -P3308 Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 15 Server version: 5.0.70-enterprise-gpl-nt-log MySQL Enterprise Server (GPL) Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql> CREATE DATABASE example; Query OK, 1 row affected (0.00 sec) mysql> USE example; Database changed mysql> mysql> CREATE TABLE locations ( -> locationID INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY, -> -> locationName VARCHAR(50) NOT NULL, -> -> totalPacketCount INTEGER UNSIGNED NOT NULL DEFAULT 0, -> totalVolume DOUBLE(14,3) NOT NULL DEFAULT 0, -> totalWeight DOUBLE(14,3) NOT NULL DEFAULT 0, -> -> UNIQUE INDEX idx_locations_name(locationName(50)) -> ) ENGINE = InnoDB; Query OK, 0 rows affected (0.41 sec) mysql> mysql> CREATE TABLE packets ( -> packetID INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY, -> packetNumber VARCHAR(50) NOT NULL, -> locationID INTEGER UNSIGNED NOT NULL, -> pieceCount INTEGER UNSIGNED NOT NULL DEFAULT 0, -> volume DOUBLE(14,3) NOT NULL DEFAULT 0, -> weight DOUBLE(14,3) NOT NULL DEFAULT 0, -> -> UNIQUE INDEX key_packets_packetNumber(packetNumber(50)), -> INDEX idx_packets_locationID(locationID) -> ) ENGINE = InnoDB; Query OK, 0 rows affected (0.63 sec) mysql> mysql> INSERT INTO locations VALUES (1, 'Location1', 0, 0, 0); Query OK, 1 row affected (0.06 sec) mysql> -- 486 rows of sample data mysql> INSERT INTO `packets` VALUES (1,'PPG0001174',1,132,2.534,0.000),(2,'PPG00 00674',1,132,2.534,0.000),(3,'PPG0000628',1,132,2.534,0.000),(4,'PPG0000626',1,1 32,2.534,0.000),(5,'PPG0000613',1,132,2.534,0.000),(6,'PPG0099107',1,132,2.534,0 .000),(7,'PPG0099085',1,132,2.534,0.000),(8,'PPG0000529',1,132,2.534,0.000),(9,' PPG0000566',1,132,2.534,0.000),(10,'PPG0000554',1,132,2.534,0.000),(11,'PPG00005 52',1,132,2.534,0.000),(12,'PPG0001000',1,132,2.534,0.000),(13,'PPG0000989',1,13 2,2.534,0.000),(14,'PPG0001018',1,132,2.534,0.000),(15,'PPG0001005',1,132,2.534, 0.000),(16,'PPG0001552',1,132,2.534,0.000),(17,'PPG0001542',1,132,2.534,0.000),( 18,'PPG0001535',1,132,2.534,0.000),(19,'PPG0001568',1,132,2.534,0.000),(20,'PPG0 001567',1,132,2.534,0.000),(21,'PP20309228',1,132,2.534,0.000),(22,'PPG2031547', 1,132,2.534,0.000),(23,'PPG0000987',1,132,2.534,0.000),(24,'PPG0001047',1,132,2. 534,0.000),(25,'PPG0001036',1,132,2.534,0.000),(26,'PPG0001041',1,132,2.534,0.00 0),(27,'PPG0001058',1,132,2.534,0.000),(28,'PPG0000112',1,132,2.534,0.000),(29,' PPG0000400',1,132,2.534,0.000),(30,'PPG0000661',1,132,2.534,0.000),(31,'PPG00006 87',1,132,2.534,0.000),(32,'PPG0000653',1,132,2.534,0.000),(33,'PPG0000643',1,13 2,2.534,0.000),(34,'PPG0000541',1,132,2.534,0.000),(35,'PPG0000818',1,132,2.534, 0.000),(36,'PPG0000754',1,132,2.534,0.000),(37,'PPG0000705',1,132,2.534,0.000),( 38,'PPG0000741',1,132,2.534,0.000),(39,'PPG0000530',1,132,2.534,0.000),(40,'PPG0 000853',1,132,2.534,0.000); Query OK, 40 rows affected (0.14 sec) Records: 40 Duplicates: 0 Warnings: 0 mysql> mysql> DELIMITER // mysql> DROP PROCEDURE IF EXISTS spExample1; -> CREATE PROCEDURE spExample1() SQL SECURITY INVOKER -> BEGIN -> DECLARE done INT DEFAULT 0; -> DECLARE lid INTEGER; -> DECLARE tPieces INTEGER; -> DECLARE tVolume1 DOUBLE; -> DECLARE tVolume2 DOUBLE(14,3); -> DECLARE tVolume3 DECIMAL(14,3); -> DECLARE tWeight DOUBLE(14,3); -> DECLARE cur1 CURSOR FOR -> SELECT locationID AS x, COUNT(*), SUM(volume), SUM(volume), SUM( volume), SUM(weight) -> FROM packets -> GROUP BY locationID; -> DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1; -> -> OPEN cur1; -> -> REPEAT -> FETCH cur1 INTO lid, tPieces, tVolume1, tVolume2, tVolume3, tWei ght; -> IF NOT done THEN -> SELECT lid, tPieces, tVolume1, tVolume2, tVolume3, tWeig ht; -> SET @s = CONCAT('UPDATE locations SET totalPacketCount = ' , tPieces , ', totalVolume = ', tVolume1, ', totalWeight = ', tWeight, ' WHER E locationID = ', lid); -> SELECT @s; -> SET @s = CONCAT('UPDATE locations SET totalPacketCount = ' , tPieces , ', totalVolume = ', tVolume2, ', totalWeight = ', tWeight, ' WHER E locationID = ', lid); -> SELECT @s; -> SET @s = CONCAT('UPDATE locations SET totalPacketCount = ' , tPieces , ', totalVolume = ', tVolume3, ', totalWeight = ', tWeight, ' WHER E locationID = ', lid); -> SELECT @s; -> -- PREPARE stmt FROM @s; -> -- EXECUTE stmt; -> END IF; -> UNTIL done END REPEAT; -> END; -> // Query OK, 0 rows affected, 1 warning (0.13 sec) Query OK, 0 rows affected (0.17 sec) mysql> DELIMITER ; mysql> mysql> CALL spExample1(); +------+---------+----------+----------+----------+---------+ | lid | tPieces | tVolume1 | tVolume2 | tVolume3 | tWeight | +------+---------+----------+----------+----------+---------+ | 1 | 40 | 101.36 | 101.360 | 101.360 | 0.000 | +------+---------+----------+----------+----------+---------+ 1 row in set (0.05 sec) +------------------------------------------------------------------------------- -----------------------------+ | @s | +------------------------------------------------------------------------------- -----------------------------+ | UPDATE locations SET totalPacketCount = 40, totalVolume = 101.36, totalWeight = 0.000 WHERE locationID = 1 | +------------------------------------------------------------------------------- -----------------------------+ 1 row in set (0.05 sec) +------------------------------------------------------------------------------- ------------------------------+ | @s | +------------------------------------------------------------------------------- ------------------------------+ | UPDATE locations SET totalPacketCount = 40, totalVolume = UPDATE , totalWeight = 0.000 WHERE locationID = 1 | +------------------------------------------------------------------------------- ------------------------------+ 1 row in set (0.06 sec) +------------------------------------------------------------------------------- ------------------------------+ | @s | +------------------------------------------------------------------------------- ------------------------------+ | UPDATE locations SET totalPacketCount = 40, totalVolume = 101.360, totalWeight = 0.000 WHERE locationID = 1 | +------------------------------------------------------------------------------- ------------------------------+ 1 row in set (0.08 sec) Query OK, 0 rows affected, 1 warning (0.09 sec)
[11 Nov 2008 5:08]
Valeriy Kravchuk
Same result with 5.1.29.
[23 Jul 2009 15:18]
Vasile Ceteras
Verified with 5.1.36-log 64bit on kubuntu 9.04 64bit I noticed when I run the stored procedure for the second time, it returns the correct result.
[24 Jul 2009 8:31]
Vasile Ceteras
I've tested this on 5.0.24, 5.0.45, 5.1.36, and for all these versions, the bug is reproduced only for the first call to the stored procedure after it has been created. The next calls return correct results, and if I drop the procedure and create it again, it will return bad results only for the first call. My suggested workaround is to call the stored procedure once after it's created.
[2 Apr 2010 6:21]
Gleb Shchepa
Also see similar CONCAT_WS bug #50096. Simplified test case: DELIMITER // CREATE PROCEDURE s1() BEGIN DECLARE v1 DOUBLE(10,3); SET v1= 100; SET @s = CONCAT('########################################' , 40 , v1); SELECT @s; END;// DELIMITER ; CALL s1(); CALL s1();
[2 Apr 2010 7:30]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/104954 3441 Gleb Shchepa 2010-04-02 Bug #40625: Concat fails on DOUBLE values in a Stored Procedure, while DECIMAL works Selecting of the CONCAT(...<SP variable>...) result into a user variable may return wrong data. Item_func_concat::val_str contains a number of memory allocation-saving tricks. One of them concatenates strings inplace inserting the value of one string at the beginning of the other string. However, this trick didn't care about strings those points to the same data buffer: this is possible when a CONCAT() parameter is a stored procedure variable - Item_sp_variable::val_str() uses the intermediate Item_sp_variable::str_value field, where it may store a reference to an external buffer. The Item_func_concat::val_str function has been modified to take into account val_str functions (such as Item_sp_variable::val_str) that return a pointer to an internal Item member variable that may reference to a buffer provided. @ mysql-test/r/func_concat.result Test case for the bug #40625. @ mysql-test/t/func_concat.test Test case for the bug #40625. @ sql/item_strfunc.cc Bug #40625: Concat fails on DOUBLE values in a Stored Procedure, while DECIMAL works The Item_func_concat::val_str function has been modified to take into account val_str functions (such as Item_sp_variable::val_str) that return a pointer to an internal Item member variable that may reference to a buffer provided.
[2 Apr 2010 21:08]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/104993 3442 Gleb Shchepa 2010-04-03 Bug #40625: Concat fails on DOUBLE values in a Stored Procedure, while DECIMAL works Selecting of the CONCAT(...<SP variable>...) result into a user variable may return wrong data. Item_func_concat::val_str contains a number of memory allocation-saving tricks. One of them concatenates strings inplace inserting the value of one string at the beginning of the other string. However, this trick didn't care about strings those points to the same data buffer: this is possible when a CONCAT() parameter is a stored procedure variable - Item_sp_variable::val_str() uses the intermediate Item_sp_variable::str_value field, where it may store a reference to an external buffer. The Item_func_concat::val_str function has been modified to take into account val_str functions (such as Item_sp_variable::val_str) that return a pointer to an internal Item member variable that may reference to a buffer provided. @ mysql-test/r/func_concat.result Test case for the bug #40625. @ mysql-test/t/func_concat.test Test case for the bug #40625. @ sql/item_strfunc.cc Bug #40625: Concat fails on DOUBLE values in a Stored Procedure, while DECIMAL works The Item_func_concat::val_str function has been modified to take into account val_str functions (such as Item_sp_variable::val_str) that return a pointer to an internal Item member variable that may reference to a buffer provided.
[6 Apr 2010 7:57]
Bugs System
Pushed into 5.1.46 (revid:sergey.glukhov@sun.com-20100405111026-7kz1p8qlzglqgfmu) (version source revid:gshchepa@mysql.com-20100402203022-np3uklrf7bxb6i97) (merge vers: 5.1.46) (pib:16)
[15 Apr 2010 23:19]
Paul DuBois
Noted in 5.1.46 changelog. If the arguments to a CONCAT() call included a local routine variable, selecting the return value into a user variable could produce an incorrect result. Setting report to Need Merge pending push to Celosia.
[28 May 2010 6:06]
Bugs System
Pushed into mysql-next-mr (revid:alik@sun.com-20100524190136-egaq7e8zgkwb9aqi) (version source revid:alik@sun.com-20100422150750-vp0n37kp9ywq5ghf) (pib:16)
[28 May 2010 6:34]
Bugs System
Pushed into 6.0.14-alpha (revid:alik@sun.com-20100524190941-nuudpx60if25wsvx) (version source revid:alik@sun.com-20100422150658-fkhgnwwkyugtxrmu) (merge vers: 6.0.14-alpha) (pib:16)
[28 May 2010 7:02]
Bugs System
Pushed into 5.5.5-m3 (revid:alik@sun.com-20100524185725-c8k5q7v60i5nix3t) (version source revid:alexey.kopytov@sun.com-20100411071742-a2o2anlcrj2bq14q) (merge vers: 5.5.4-m3) (pib:16)
[29 May 2010 15:05]
Paul DuBois
Noted in 5.5.5, 6.0.14 changelogs.
[17 Jun 2010 12:11]
Bugs System
Pushed into 5.1.47-ndb-7.0.16 (revid:martin.skold@mysql.com-20100617114014-bva0dy24yyd67697) (version source revid:vasil.dimov@oracle.com-20100331130613-8ja7n0vh36a80457) (merge vers: 5.1.46) (pib:16)
[17 Jun 2010 12:59]
Bugs System
Pushed into 5.1.47-ndb-6.2.19 (revid:martin.skold@mysql.com-20100617115448-idrbic6gbki37h1c) (version source revid:martin.skold@mysql.com-20100609211156-tsac5qhw951miwtt) (merge vers: 5.1.46-ndb-6.2.19) (pib:16)
[17 Jun 2010 13:39]
Bugs System
Pushed into 5.1.47-ndb-6.3.35 (revid:martin.skold@mysql.com-20100617114611-61aqbb52j752y116) (version source revid:vasil.dimov@oracle.com-20100331130613-8ja7n0vh36a80457) (merge vers: 5.1.46) (pib:16)