List:MySQL and Perl« Previous MessageNext Message »
From:Philippe M . Chiasson Date:December 5 2000 4:20pm
Subject:[Patch] bindparam.h ParseParam() doesn't differentiate Numerical/String values correctly for quoting
View as plain text  
I was currently experiencing a strange problem with queries and placeholders..

#
# create table testa (rowa varchar(64), rowb int(11));
#

my $sth = $dbh->prepare('INSERT INTO testa VALUES (?,?)');
$sth->trace(3);

my $string = "Needs::Quotes";
my $number = 4;

$sth->execute($string,$number);
	DBI::st=HASH(0x86c9544) trace level set to 3 in DBI 1.14-nothread
	-> execute for DBD::mysql::st (DBI::st=HASH(0x93dd2ac)~0x86c9544 Needs::Quotes 4)
	-> dbd_st_execute for 093d55ac
	 Binding parameters: INSERT INTO testa VALUES ('Needs::Quotes',4)
	[...]

$string == 0;  # treat the string as an integer for a second... Sv_NIOK will be true ;-(

$sth->execute($string,$number);
	DBI::st=HASH(0x86c9544) trace level set to 3 in DBI 1.14-nothread
	-> execute for DBD::mysql::st (DBI::st=HASH(0x93dd2ac)~0x86c9544 Needs::Quotes 4)
	-> dbd_st_execute for 093d55ac
	Binding parameters: INSERT INTO testa VALUES (Needs::Quotes,4)

Then BOOM, the unquoted string triggers a SQL syntax error.

Attached is a small patch to bindparam.h that inverts the logic of the check...

SvNIOK(ph->value) ? SQL_INTEGER : SQL_VARCHAR;

checks if it's a number, otherwise assume it's a string.  I replaced it with

SvPOK(ph->value) ? SQL_VARCHAR : SQL_INTEGER

checks if it's a string, otherwise assume it's a number.  I tested it and it fixes my
problem.

Pretty nasty little bug...

-- 
+-----------------------------------------------+
| Philippe M. Chiasson  <gozer@stripped> |
| SmartWorker http://www.smartworker.org        |
|     IM : gozerhbe  ICQ : gozer/18279998       |
+-----------------------------------------------+
ioctl is not implemented
: Your machine apparently doesn't implement ioctl(), which
is pretty strange for a machine that supports C. 
	-- perldiag(1)

perl -e '$$=\${gozer};{$_=unpack(P26,pack(L,$$));/^Just Another Perl
Hacker!\n$/&&print||$$++&&redo}'

--- bindparam.h.1.2215.orig	Tue Dec  5 10:50:24 2000
+++ bindparam.h	Tue Dec  5 10:50:46 2000
@@ -125,7 +125,7 @@
 	    alen += 3;  /* Erase '?', insert 'NULL' */
 	} else {
 	    if (!ph->type) {
-	        ph->type = SvNIOK(ph->value) ? SQL_INTEGER : SQL_VARCHAR;
+	        ph->type = SvPOK(ph->value) ? SQL_VARCHAR : SQL_INTEGER;
 	    }
 	    valbuf = SvPV(ph->value, vallen);
 	    alen += 2*vallen+1; /* Erase '?', insert (possibly quoted)

Attachment: [application/pgp-signature]
Attachment: [application/pgp-signature]
Thread
[Patch] bindparam.h ParseParam() doesn't differentiate Numerical/String values correctly for quotingPhilippe M . Chiasson5 Dec
  • Re: [Patch] bindparam.h ParseParam() doesn't differentiate Numerical/String values correctly for quotingJochen Wiedmann7 Dec