[PATCH] Fix bind_param() bug in DBD-mysql-2.9008

Steve Hay <[email protected]>
Newsgroups gmane.comp.db.mysql.perl
Message-ID <[email protected]>
Hi all,

DBD-mysql-2.9007 introduced a fix for a bug that I had reported, in 
which non-numeric values bound to numeric types could break the SQL by 
placing arbitrary unquoted strings into the SQL.

However, the bug fix seems to have a problem of its own -- it prevents 
you from using the value "undef" in such places.  AFAIK this use of 
"undef" is a perfectly valid way of setting the value of a numeric 
column to NULL, so should not be prevented from running.

Attached is a short test program that illustrates the problem.  Using 
2.9008 this outputs

ROW 1: 1, 1
DBD::mysql::st bind_param failed: Binding non-numeric field 1, value 
undef as a numeric! at C:\Temp\dbi.pl line 29.

Attached is also a patch against 2.9008 that fixes this.  With the 
patch, the test program now correctly outputs

ROW 1: 1, 1
UPDATE affected 1 rows
Use of uninitialized value in join or string at C:\Temp\dbi.pl line 38.
ROW 1: 1,

A new release with this patch in place would be appreciated as this is 
quite an issue for me.  My database code makes frequent use of NULL'ing 
numeric columns by this means, and is completely broken with the current 
release :-(

Cheers,
- Steve


------------------------------------------------
Radan Computational Ltd.

The information contained in this message and any files transmitted with it are confidential and intended for the addressee(s) only.  If you have received this message in error or there are any problems, please notify the sender immediately.  The unauthorized use, disclosure, copying or alteration of this message is strictly forbidden.  Note that any views or opinions presented in this email are solely those of the author and do not necessarily represent those of Radan Computational Ltd.  The recipient(s) of this message should check it and any attached files for viruses: Radan Computational will accept no liability for any damage caused by any virus transmitted by this email.


-- 
MySQL Perl Mailing List
For list archives: http://lists.mysql.com/perl
To unsubscribe:    http://lists.mysql.com/[email protected]
dbi.pl (text/csv, 1.1 KB)
use strict;
use warnings;
use DBI qw(:sql_types);
my $tmp_dbh = DBI->connect(
  'dbi:mysql:database=mysql', 'root', undef,
  { AutoCommit => 1, PrintError => 0, RaiseError => 1 }
);
$tmp_dbh->do('CREATE DATABASE IF NOT EXISTS test');
$tmp_dbh->disconnect();
my $dbh = DBI->connect(
  'dbi:mysql:database=test', 'root', undef,
  { AutoCommit => 1, PrintError => 0, RaiseError => 1 }
);
$dbh->do('DROP TABLE IF EXISTS foo');
$dbh->do(qq{CREATE TABLE foo (
  id  INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  num INT
) ENGINE=InnoDB});
$dbh->do("INSERT INTO foo VALUES(NULL, 1)");
my $rows = $dbh->selectall_arrayref('SELECT * FROM foo');
my $i = 0;
foreach my $row (@$rows) {
  ++$i;
  local $" = ', ';
  print "ROW $i: @$row\n";
}
my $sql = 'UPDATE foo SET num = ? WHERE id = ?';
my $sth = $dbh->prepare($sql);
$sth->bind_param(1, undef, SQL_INTEGER);
$sth->bind_param(2, 1, SQL_INTEGER);
my $num_rows = $sth->execute();
print "UPDATE affected $num_rows rows\n";
$rows = $dbh->selectall_arrayref('SELECT * FROM foo');
$i = 0;
foreach my $row (@$rows) {
  ++$i;
  local $" = ', ';
  print "ROW $i: @$row\n";
}
$dbh->disconnect();
patch.txt (text/plain, 886 B)
--- dbdimp.c.orig	2005-04-22 23:09:56.000000000 +0100
+++ dbdimp.c	2005-06-21 16:43:48.206975300 +0100
@@ -2337,15 +2337,16 @@
 
     /* 
       This fixes the bug whereby no warning was issued upone binding a 
-      non-numeric as numeric
+      defined non-numeric as numeric
     */
-    if (sql_type == SQL_NUMERIC  ||
-        sql_type == SQL_DECIMAL  ||
-        sql_type == SQL_INTEGER  ||
-        sql_type == SQL_SMALLINT ||
-        sql_type == SQL_FLOAT    ||
-        sql_type == SQL_REAL     ||
-        sql_type == SQL_DOUBLE)
+    if (SvOK(value) &&
+        (sql_type == SQL_NUMERIC  ||
+         sql_type == SQL_DECIMAL  ||
+         sql_type == SQL_INTEGER  ||
+         sql_type == SQL_SMALLINT ||
+         sql_type == SQL_FLOAT    ||
+         sql_type == SQL_REAL     ||
+         sql_type == SQL_DOUBLE) )
     {
       if (! looks_like_number(value))
       {
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.