Bug #65351 | power(a,b) fails in some cases for no obvious reason | ||
---|---|---|---|
Submitted: | 17 May 2012 12:46 | Modified: | 4 Mar 2013 14:50 |
Reporter: | Volker Raab | Email Updates: | |
Status: | Won't fix | Impact on me: | |
Category: | MySQL Server: Data Types | Severity: | S2 (Serious) |
Version: | 5.5.22-0ubuntu1, 5.5.26, 5.6.6 | OS: | Linux |
Assigned to: | Tor Didriksen | CPU Architecture: | Any |
Tags: | double, ERROR 1690, pow() |
[17 May 2012 12:46]
Volker Raab
[17 May 2012 16:14]
Valeriy Kravchuk
It would be nice to get the output of SHOW CREATE TABLE for both tables used, the results of EXPLAIN for the query and also exact values in that a.irr and b.laufzeit columns for the row in the result set that satisfies the query.
[17 May 2012 19:00]
Volker Raab
T3Irr is a table. However, V3IrrOutput is a view. So the query cascades through a whole bunch of other tables... mysql> show create table T3Irr; CREATE TABLE `T3Irr` ( `Depot` int(11) NOT NULL, `Posten` int(11) DEFAULT NULL, `wpid` int(11) NOT NULL, `nam` varchar(30) NOT NULL, `Wert` decimal(30,2) DEFAULT NULL, `Dividende` decimal(30,2) DEFAULT NULL, `Saldo` decimal(30,2) DEFAULT NULL, `IRR` float DEFAULT '3', `dirr` float DEFAULT '1' ) ENGINE=MyISAM DEFAULT CHARSET=latin1 | mysql> show create table V3IrrOutput; CREATE ALGORITHM=UNDEFINED DEFINER=`volker`@`%` SQL SECURITY DEFINER VIEW `V3IrrOutput` AS select `a`.`Depot` AS `Depot`,`a`.`Posten` AS `Posten`,`a`.`wpid` AS `wpid`,`a`.`Nam` AS `Nam`,`a`.`Wert` AS `Wert`,(to_days(`b`.`mdat`) - to_days(`a`.`Datum`)) AS `Laufzeit`,`b`.`mdat` AS `mdat` from (`T3IrrBelegeNext` `a` left join `V3IrrOutTmp` `b` on(((`a`.`Depot` = `b`.`Depot`) and (`a`.`Posten` = `b`.`Posten`)))) order by `a`.`Depot`,`a`.`Posten`,`a`.`Datum` | utf8 | utf8_general_ci | mysql> explain select @aaa:=1.0+a.irr/100, @bbb:=b.laufzeit/365., abs(@aaa), abs(@bbb), pow(@aaa,@bbb) from T3Irr as a, V3IrrOutput as b where a.depot = b.depot and a.posten = b.posten and a.wpid = b.wpid limit 1; +----+-------------+-----------------+------+---------------+------+---------+------+------+---------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-----------------+------+---------------+------+---------+------+------+---------------------------------+ | 1 | PRIMARY | a | ALL | NULL | NULL | NULL | NULL | 629 | Using temporary; Using filesort | | 1 | PRIMARY | a | ALL | NULL | NULL | NULL | NULL | 101 | Using where; Using join buffer | | 1 | PRIMARY | <derived3> | ALL | NULL | NULL | NULL | NULL | 106 | | | 3 | DERIVED | T3IrrBelegeNext | ALL | NULL | NULL | NULL | NULL | 629 | Using temporary; Using filesort | +----+-------------+-----------------+------+---------------+------+---------+------+------+---------------------------------+ 4 rows in set (0.00 sec) I, then, tried to be "smart" and first select the data into an intermediate table named `burgreqest`. But out of that it works as expected: mysql> create table bugrequest select @aaa:=1.0+a.irr/100 as aaa, @bbb:=b.laufzeit/365. as bbb, abs(@aaa) as abs_aaa, abs(@bbb) as abs_bbb, pow(abs(@aaa),@bbb) as pow_abs from T3Irr as a, V3IrrOutput as b where a.depot = b.depot and a.posten = b.posten and a.wpid = b.wpid limit 5; Query OK, 5 rows affected (0.15 sec) Records: 5 Duplicates: 0 Warnings: 0 mysql> select *, pow(aaa,bbb) from bugrequest -> ; +--------------------+--------+--------------------+----------------------------------+--------------------+--------------------+ | aaa | bbb | abs_aaa | abs_bbb | pow_abs | pow(aaa,bbb) | +--------------------+--------+--------------------+----------------------------------+--------------------+--------------------+ | 1.4556840133666993 | 2.9068 | 1.4556840133666993 | 2.906849315000000000000000000000 | 2.978595467533429 | 2.9785403146007075 | | 1.4556840133666993 | 2.5041 | 1.4556840133666993 | 2.504109589000000000000000000000 | 2.5605774711606353 | 2.5605682519757056 | | 1.4556840133666993 | 1.4795 | 1.4556840133666993 | 1.479452054000000000000000000000 | 1.742809724543602 | 1.7428410998759312 | | 1.4556840133666993 | 0.5014 | 1.4556840133666993 | 0.501369863000000000000000000000 | 1.20713803998827 | 1.2071516996983231 | | 1.4556840133666993 | 0.0000 | 1.4556840133666993 | 0.000000000000000000000000000000 | 1 | 1 | +--------------------+--------+--------------------+----------------------------------+--------------------+--------------------+ 5 rows in set (0.00 sec) mysql> select *, pow(aaa,bbb) from bugrequest; +--------------------+--------+--------------------+----------------------------------+--------------------+--------------------+ | aaa | bbb | abs_aaa | abs_bbb | pow_abs | pow(aaa,bbb) | +--------------------+--------+--------------------+----------------------------------+--------------------+--------------------+ | 1.4556840133666993 | 2.9068 | 1.4556840133666993 | 2.906849315000000000000000000000 | 2.978595467533429 | 2.9785403146007075 | | 1.4556840133666993 | 2.5041 | 1.4556840133666993 | 2.504109589000000000000000000000 | 2.5605774711606353 | 2.5605682519757056 | | 1.4556840133666993 | 1.4795 | 1.4556840133666993 | 1.479452054000000000000000000000 | 1.742809724543602 | 1.7428410998759312 | | 1.4556840133666993 | 0.5014 | 1.4556840133666993 | 0.501369863000000000000000000000 | 1.20713803998827 | 1.2071516996983231 | | 1.4556840133666993 | 0.0000 | 1.4556840133666993 | 0.000000000000000000000000000000 | 1 | 1 | +--------------------+--------+--------------------+----------------------------------+--------------------+--------------------+ 5 rows in set (0.00 sec) So, if this does not work, then how can I get 'exact' values out of the tables? (Unfortunately this table contains sensitive private data. Otherwise I would have just sent you the whole thing.)
[17 May 2012 19:06]
Volker Raab
Hi Valeriy, going over my last comment again I notice two things: (a) I accidentally pasted the last table twice. Sorry 'bout that! (b) The values in columns `pow_abs` and pow(aaa,bbb) deviate considerably! Cheers, Volker
[30 May 2012 12:29]
Sveta Smirnova
Thank you for the feedback. Please also send output of select a.irr, b.laufzeit from T3Irr as a, V3IrrOutput as b where a.depot = b.depot and a.posten = b.posten and a.wpid = b.wpid limit 1;
[30 May 2012 13:18]
Volker Raab
Hi Sveta, please find appended the requested output. I hope it helps. Cheers Volker mysql> select a.irr, b.laufzeit from T3Irr as a, -> V3IrrOutput as b where a.depot = b.depot and a.posten = -> b.posten and a.wpid = b.wpid limit 4; +---------+----------+ | irr | Laufzeit | +---------+----------+ | 45.5684 | 1061 | | 45.5684 | 914 | | 45.5684 | 540 | | 45.5684 | 183 | +---------+----------+ 4 rows in set (0.02 sec)
[30 May 2012 18:16]
Sveta Smirnova
Thank you for the feedback. I can not repeat described behavior. Please try with current version 5.5.24, available from http://dev.mysql.com/downloads, and if problem still exists indicate if you have not empty SQL Mode.
[30 May 2012 19:25]
Volker Raab
Finally I managed to reduce the table to its essence and (hopefully) remove the bulk of private data (see file pow-bug.sql.bz2) If I create a new database and read its contents it still fails with the same message. Maybe you can reproduce it now. Thanks a lot for all the effort!
[31 May 2012 12:37]
Sveta Smirnova
Thank you for the test case. Verified as described. Source of issue is GROUP BY and ORDER BY in view definitions. I uploaded even smaller test case which uses only tables. Problem with my test case first query runs successfully, then following fail. In version 5.6 ORDER BY issue seems to be resolved.
[4 Mar 2013 14:50]
Tor Didriksen
The error message 1690: DOUBLE value is out of range in 'pow((@`aaa`),(@`bbb`))' is caused by the fix for http://bugs.mysql.com/bug.php?id=8433 Overflow must be an error Previous to that fix, MySQL would silently ignore NaN errors from pow() and return zero/NULL. There are no "sequence points" in SQL, as there are in C/C++ and the variables are indeed read many times, before they are assigned new values. At some point we evaluate pow(-0.36304992675781245, 3.446575342) MySQL 5.1 will return 0.0, MySQL 5.5 and up will report value out of range. My previous suggestion, reset variables to zero, sort-of-works, the query does not fail. The result is however undefined. The correct solution is to avoid reading/writing of the same user variable in one statement.