Preferred bug tracker

Please visit the preferred bug tracker to report your issue.

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

Report information
The Basics
Id:
29528
Status:
resolved
Priority:
Low/Low
Queue:

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

BugTracker
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!


This service runs on Request Tracker, is sponsored by The Perl Foundation, and maintained by Best Practical Solutions.

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