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
Download (untitled) / with headers
text/plain 513b
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"
Download (untitled) / with headers
text/plain 639b
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"
Download (untitled) / with headers
text/plain 909b
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); +
Download (untitled) / with headers
text/plain 1.1k
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!


This service is sponsored and maintained by Best Practical Solutions and runs on Perl.org infrastructure.

Please report any issues with rt.cpan.org to rt-cpan-admin@bestpractical.com.