Skip Menu |

This queue is for tickets about the DBD-mysql CPAN distribution.

Report information
The Basics
Id: 29528
Status: resolved
Priority: 0/
Queue: DBD-mysql

People
Owner: CAPTTOFU [...] cpan.org
Requestors: KAZUHO [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: 4.005
Fixed in: (no value)



Subject: bind_param(..., SQL_FLOAT) ignores exponents
bind_param(..., SQL_FLOAT) does not recognize the exponents of suppiled values. For example, the code below should print 1e16 but shows "1" instead. It seems that the parse_number function in dbdimp.c is simply ignoring the "eXX" portion of the floating point representation. my $sth = $dbh->prepare('select ?') or die $dbh->errstr; $sth->bind_param(1, 1e16, SQL_FLOAT) or die $dbh->errstr; $sth->execute() or die $dbh->errstr; print $sth->fetchrow_arrayref()->[0], "\n"; # should print 1e16, but shows "1"
Thank you for your bug report! I'll look into this. On Thu Sep 20 20:49:56 2007, KAZUHO wrote: Show quoted text
> bind_param(..., SQL_FLOAT) does not recognize the exponents of suppiled > values. > > For example, the code below should print 1e16 but shows "1" instead. It > seems that the parse_number function in dbdimp.c is simply ignoring the > "eXX" portion of the floating point representation. > > > my $sth = $dbh->prepare('select ?') or die $dbh->errstr; > $sth->bind_param(1, 1e16, SQL_FLOAT) or die $dbh->errstr; > $sth->execute() or die $dbh->errstr; > > print $sth->fetchrow_arrayref()->[0], "\n"; # should print 1e16, but > shows "1"
DBD::mysql cannot handles very large number(e.g. 10**19) and very small number(e.g. 10**-19). This is parse_number()'s problem. I've write patch for this problem, and attached. On 金曜日 9月 21 10:21:33 2007, CAPTTOFU wrote: Show quoted text
> Thank you for your bug report! I'll look into this. > > On Thu Sep 20 20:49:56 2007, KAZUHO wrote:
> > bind_param(..., SQL_FLOAT) does not recognize the exponents of suppiled > > values. > > > > For example, the code below should print 1e16 but shows "1" instead. It > > seems that the parse_number function in dbdimp.c is simply ignoring the > > "eXX" portion of the floating point representation. > > > > > > my $sth = $dbh->prepare('select ?') or die $dbh->errstr; > > $sth->bind_param(1, 1e16, SQL_FLOAT) or die $dbh->errstr; > > $sth->execute() or die $dbh->errstr; > > > > print $sth->fetchrow_arrayref()->[0], "\n"; # should print 1e16, but > > shows "1"
> >
=== dbdimp.c ================================================================== --- dbdimp.c (revision 25104) +++ dbdimp.c (local) @@ -4591,10 +4591,14 @@ { int seen_neg; int seen_dec; + int seen_e; + int seen_plus; char *cp; - seen_neg= 0; - seen_dec= 0; + seen_neg = 0; + seen_dec = 0; + seen_e = 0; + seen_plus= 0; if (len <= 0) { len= strlen(string); @@ -4610,17 +4614,12 @@ { if ('-' == *cp) { - if (seen_neg) + if (seen_neg >= 2) { - /* second '-' */ + /* third '-'. number can contains two '-'. because -1e-10 is valid number */ break; } - else if (cp > string) - { - /* '-' after digit(s) */ - break; - } - seen_neg= 1; + seen_neg += 1; } else if ('.' == *cp) { @@ -4631,6 +4630,24 @@ } seen_dec= 1; } + else if ('e' == *cp) + { + if (seen_e) + { + /* second 'e' */ + break; + } + seen_e= 1; + } + else if ('+' == *cp) + { + if (seen_plus) + { + /* second '+' */ + break; + } + seen_plus= 1; + } else if (!isdigit(*cp)) { break; === t/90bind_bugs.t ================================================================== --- t/90bind_bugs.t (revision 25104) +++ t/90bind_bugs.t (local) @@ -0,0 +1,35 @@ +#!perl -w +# vim: ft=perl + +use Test::More; +use DBI; +use strict; +use lib 't', '.'; +require 'lib.pl'; +$|= 1; + +use vars qw($table $test_dsn $test_user $test_password); +my $dbh; +eval {$dbh= DBI->connect($test_dsn, $test_user, $test_password, + { RaiseError => 1, PrintError => 1, AutoCommit => 0 });}; + +if ($@) { + plan skip_all => "ERROR: $DBI::errstr. Can't continue test"; +} +plan tests => 3; + +sub do_test { + my $number = shift; + my $sth = $dbh->prepare('select ?') or die $dbh->errstr; + $sth->bind_param(1, $number, DBI::SQL_FLOAT) or die $dbh->errstr; + $sth->execute() or die $dbh->errstr; + + is $sth->fetchrow_arrayref()->[0], $number; + + $dbh->rollback(); +} + +do_test(10**19); +do_test(10**-19); +do_test(-10**-19); +
Tokuhiro, Thank you (Domo ara-gato) very much for the patch - I will test it and add it to the next release, coming out soon. Kind regards, Patrick On Wed Aug 06 21:40:54 2008, TOKUHIROM wrote: Show quoted text
> DBD::mysql cannot handles very large number(e.g. 10**19) and very small > number(e.g. 10**-19). > This is parse_number()'s problem. > I've write patch for this problem, and attached. > > On 金曜日 9月 21 10:21:33 2007, CAPTTOFU wrote:
> > Thank you for your bug report! I'll look into this. > > > > On Thu Sep 20 20:49:56 2007, KAZUHO wrote:
> > > bind_param(..., SQL_FLOAT) does not recognize the exponents of
suppiled Show quoted text
> > > values. > > > > > > For example, the code below should print 1e16 but shows "1"
instead. It Show quoted text
> > > seems that the parse_number function in dbdimp.c is simply
ignoring the Show quoted text
> > > "eXX" portion of the floating point representation. > > > > > > > > > my $sth = $dbh->prepare('select ?') or die $dbh->errstr; > > > $sth->bind_param(1, 1e16, SQL_FLOAT) or die $dbh->errstr; > > > $sth->execute() or die $dbh->errstr; > > > > > > print $sth->fetchrow_arrayref()->[0], "\n"; # should print 1e16, but > > > shows "1"
> > > >
> >
Fixed! Added to upcoming 4.008 release. Thank you Tohuhiro!