Bug #13665 | concat with '' produce incorrect results in SP | ||
---|---|---|---|
Submitted: | 30 Sep 2005 17:14 | Modified: | 24 Nov 2005 14:26 |
Reporter: | peter droogmans | Email Updates: | |
Status: | Can't repeat | Impact on me: | |
Category: | MySQL Server: Stored Routines | Severity: | S2 (Serious) |
Version: | 5.0.13-rc-nt | OS: | Windows (Win XP - SP 2 fully patched) |
Assigned to: | Alexander Nozdrin | CPU Architecture: | Any |
[30 Sep 2005 17:14]
peter droogmans
[30 Sep 2005 17:40]
Valeriy Kravchuk
I do not really understand, what should be changed and why. For me your code just works: mysql> use test; Database changed mysql> DELIMITER $$ mysql> mysql> DROP FUNCTION IF EXISTS `sys_Test`$$ Query OK, 0 rows affected, 1 warning (0.28 sec) mysql> CREATE FUNCTION `sys_Test`(pTable VARCHAR(50)) RETURNS varchar(20000) -> BEGIN -> -> DECLARE done INT default 0; -> DECLARE first INT default 0; -> -> DECLARE pCOLUMN_NAME VARCHAR(50); -> DECLARE pDATA_TYPE VARCHAR(50); -> DECLARE pCHARACTER_MAXIMUM_LENGTH int; -> -> DECLARE pOutput varchar(2000); -> -> DECLARE cur1 CURSOR FOR -> SELECT COLUMN_NAME, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH -> FROM INFORMATION_SCHEMA.COLUMNS -> WHERE table_name = pTable; -> -> DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1; -> -> set pOutput = ''; -> -> set done = 0; -> set first = 0; -> OPEN cur1; -> -> REPEAT -> -> FETCH cur1 INTO pCOLUMN_NAME, pDATA_TYPE, pCHARACTER_MAXIMUM_LENGTH; -> -> if not done then -> -> IF NOT first THEN -> set pOutput = CONCAT(pOutput, 'INOUT p', pCOLUMN_NAME, ' ', -> pDATA_TYPE); -> ELSEIF pCOLUMN_NAME = 'ModifiedOn' THEN -> set pOutput = CONCAT(pOutput, ', INOUT p', pCOLUMN_NAME, ' ', -> pDATA_TYPE); -> ELSEIF (pCOLUMN_NAME = 'ModifiedBy') THEN -> set pOutput = CONCAT(pOutput, ''); -> ELSE -> set pOutput = CONCAT(pOutput, ', IN p', pCOLUMN_NAME, ' ', pDATA_TYPE); -> END IF; -> -> set first = 1; -> -> end if; -> -> UNTIL done END REPEAT; -> -> CLOSE cur1; -> -> set pOutput = CONCAT(pOutput, ')', '\n'); -> set pOutput = CONCAT(pOutput, 'DONE', '\n'); -> -> return pOutput; -> -> END$$ Query OK, 0 rows affected (0.07 sec) mysql> mysql> DELIMITER ; mysql> select sys_Test('test'); +------------------------------+ | sys_Test('test') | +------------------------------+ | INOUT pField1 varchar) DONE | +------------------------------+ 1 row in set (0.30 sec) mysql> desc test; +--------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +--------+--------------+------+-----+---------+-------+ | Field1 | varchar(255) | NO | PRI | | | +--------+--------------+------+-----+---------+-------+ 1 row in set (0.01 sec) mysql> select version(); +--------------+ | version() | +--------------+ | 5.0.13-rc-nt | +--------------+ 1 row in set (0.01 sec) What results did you expect? Have you installed a fresh copy of 5.0.13-nt-rc or upgraded?
[30 Sep 2005 18:07]
peter droogmans
DROP TABLE IF EXISTS `vinov`.`klant`; CREATE TABLE `vinov`.`klant` ( `KlantId` int(11) NOT NULL auto_increment, `TypeKlant` int(11) NOT NULL, `RefId` int(11) NOT NULL, `Kaartnummer` varchar(100) NOT NULL, `TypeKaart` int(11) NOT NULL, `Betalingswijze` int(11) NOT NULL, `CreatedOn` datetime default NULL, `CreatedBy` varchar(50) default NULL, `ModifiedOn` datetime default NULL, `ModifiedBy` varchar(50) default NULL, `DeletedOn` datetime default NULL, `DeletedBy` varchar(50) default NULL, PRIMARY KEY (`KlantId`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
[30 Sep 2005 18:09]
peter droogmans
Output is the return value, I used this to create insert, update, delete and select statements. The column 'ModifiedBy' has to exist in the table otherwise it does work, see previous comment. BTW: I upgraded from the latest beta
[1 Oct 2005 8:58]
Valeriy Kravchuk
Thank you for a bug report. The problem in your code is related to the line: set pOutput = CONCAT(pOutput, ''); If you change it to: set pOutput = CONCAT(pOutput, ' '); your code will work as expected. The real bug can be repeated using much simpler test case, without any cursor (that is why I changed synopsis): mysql> delimiter // mysql> create function f2(pInput varchar(50)) returns varchar(20000) -> begin -> declare pOutput varchar(2000); -> -> set pOutput = ''; -> set pOutput = concat(pOutput, 'abc'); -> set pOutput = concat(pOutput, ''); -> -> return pOutput; -> end// Query OK, 0 rows affected (0.00 sec) mysql> select f2('abc')// +-----------+ | f2('abc') | +-----------+ | | +-----------+ 1 row in set (0.00 sec) mysql> select version()// +--------------+ | version() | +--------------+ | 5.0.13-rc-nt | +--------------+ 1 row in set (0.00 sec) Outside stored procedures CONCAT works as described in the manual ('' is not the same as NULL in MySQL): mysql> set @a=''// Query OK, 0 rows affected (0.00 sec) mysql> set @a=concat(@a, 'abc')// Query OK, 0 rows affected (0.00 sec) mysql> select @a// +------+ | @a | +------+ | abc | +------+ 1 row in set (0.00 sec) mysql> set @a=concat(@a, '')// Query OK, 0 rows affected (0.00 sec) mysql> select @a// +------+ | @a | +------+ | abc | +------+ 1 row in set (0.00 sec)
[1 Oct 2005 10:48]
peter droogmans
Thanks for the work-around, you saved my day
[24 Nov 2005 14:26]
Alexander Nozdrin
mysql> delimiter | mysql> mysql> CREATE FUNCTION f1() RETURNS VARCHAR(20000) -> BEGIN -> DECLARE var VARCHAR(2000); -> -> SET var = ''; -> SET var = CONCAT(var, 'abc'); -> SET var = CONCAT(var, ''); -> -> RETURN var; -> end| Query OK, 0 rows affected (0.00 sec) mysql> mysql> delimiter ; mysql> mysql> SELECT f1(); +------+ | f1() | +------+ | abc | +------+ 1 row in set (0.00 sec) mysql> mysql> SELECT VERSION(); +-------------------------------+ | VERSION() | +-------------------------------+ | 5.0.17-valgrind-max-debug-log | +-------------------------------+ 1 row in set (0.00 sec)
[24 Nov 2005 15:22]
Konstantin Osipov
Alik, please add a test case for this bug to the test suite (sp.test), unless you're sure the case is covered already.
[24 Nov 2005 16:00]
Alexander Nozdrin
Added into sp-vars.test.