Skip Menu |

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

Report information
The Basics
Id: 34840
Status: rejected
Priority: 0/
Queue: DBD-Pg

People
Owner: Nobody in particular
Requestors: fenlisesi [...] gmail.com
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: 2.5.1
Fixed in: (no value)



Subject: (int4) bind type picked for varchar column.

Message body is not shown because it is too large.

Subject: Re: [rt.cpan.org #34840] (int4) bind type picked for varchar column.
Date: Thu, 10 Apr 2008 22:05:13 -0000
To: bug-DBD-Pg [...] rt.cpan.org
From: "Greg Sabino Mullane" <greg [...] turnstep.com>
-----BEGIN PGP SIGNED MESSAGE----- Hash: RIPEMD160 Show quoted text
> I am actually not sure that this is a DBD::Pg bug, but that seemed to be > the most probable case. We have seen some anomalous behaviour in a > Class::DBI::Sweet application, which we traced to (int4) bind type > getting picked for a string such as '%Brown%' that is supposed to match > a varchar column. We are using Postgres 8.3.1 and DBD::Pg 2.5.1. All
Almost certainly a Class:DBI bug. Never underestimate the ability of ORMs to mess things up for you. A quick workaround may be to turn off server-side prepares: $dbh->{pg_server_prepare} = 0; Let's look at the trace output a bit: * We split the statement into 10 placeholders: Placeholder number, fooname, id: #1 FOONAME: ((null)) ID: (146370120) #2 FOONAME: ((null)) ID: (146391432) #3 FOONAME: ((null)) ID: (146387424) #4 FOONAME: ((null)) ID: (146390280) #5 FOONAME: ((null)) ID: (146168808) #6 FOONAME: ((null)) ID: (146391768) #7 FOONAME: ((null)) ID: (146370640) #8 FOONAME: ((null)) ID: (146343648) #9 FOONAME: ((null)) ID: (146369000) #10 FOONAME: ((null)) ID: (146370880) End pg_st_split_statement Immediate prepare decision: dml=1 direct=0 server_prepare=1 prepare_now=0 PGLIBVERSION=80104 End dbd_st_prepare 1 <- prepare= DBIx::ContextualFetch::st=HASH(0x86c6100) at /usr/local/lib/perl5/site_perl/5.10.0/i686-linux/DBI.pm line 1652 via at /usr/local/lib/perl5/site_perl/5.10.0/Ima/D\BI.pm line 398 <- prepare_cached= DBIx::ContextualFetch::st=HASH(0x86c6100) at /usr/local/lib/perl5/site_perl/5.10.0/Ima/DBI.pm line 398 via at /usr/local/lib/perl5/site_perl/5.10.0/Class/\DBI/Sweet.pm line 332 -> bind_param for DBD::Pg::st * For some reason, we're now telling DBD::Pg that placeholders 5 and 6 should be bound as ints. This is the bug, and it's presumably because DBIx::Something is making explicit bind_param() calls. (DBIx::ContextualFetch::st=HASH(0x86c6100)~0x8b99070 5 undef 4) Begin dbd_bind_ph (ph_name: 5) Bind (5) (type=4) Placeholder (5) bound as type (int4) (type_id=23), length 0, value of ((null)) End dbd_bind_ph <- bind_param= 1 at /usr/local/lib/perl5/site_perl/5.10.0/Class/DBI.pm line 646 via at /usr/local/lib/perl5/site_perl/5.10.0/Class/DBI/Sweet.pm line 334 -> bind_param for DBD::Pg::st (DBIx::ContextualFetch::st=HASH(0x86c6100)~0x8b99070 6 undef 4) Begin dbd_bind_ph (ph_name: 6) Bind (6) (type=4) Placeholder (6) bound as type (int4) (type_id=23), length 0, value of ((null)) End dbd_bind_ph ... * Now we try to fetch the value of Taint, which fails because we haven't executed yet. Could be another minor bug. (DBIx::ContextualFetch::st=HASH(0x8b99070)~INNER 'Taint') Begin dbd_st_FETCH (key: Taint sth: 146362864) Cannot fetch value of Taint pre-execute * Next we execute with a list of values. -> execute for DBD::Pg::st (DBIx::ContextualFetch::st=HASH(0x86c6100)~0x8b99070 "%Allen%" '22971' '23401' '22923' "%Brown%" '22971' '23401' '22923' 10 0) Begin dbd_bind_ph (ph_name: 1) Bind (1) (type=0) Placeholder (1) bound as type (unknown) (type_id=705), length 7, value of (%Allen%) Begin dbd_bind_ph (ph_name: 5) Bind (5) (type=0) Placeholder (5) bound as type (int4) (type_id=23), length 7, value of (%Brown%) End dbd_bind_ph * Now we create a prepared statement and immediately execute it. This is where the $dbh->{pg_server_prepare} would cause an alternate path: PQexec* decision: dml=1 direct=0 server_prepare=1 numbound=2 numphs=10 default=0 PQexecPrepared Begin pg_st_prepare_statement New statement name (dbdpg_p3202_18), oldprepare is 0 PQprepare Begin pg_error (message: ERROR: operator does not exist: character varying ~~ integer at character 122 HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts. number: 7) ================END DBI TRACE(7) EXCERPT==================== Since some of the placeholders are the same: "%Allen%" '22971' '23401' '22923' "%Brown%" '22971' '23401' '22923' 10 0 you may want to use dollar-sign placeholders instead of question marks. Another "fix" would be to manually set those columns back to unknown (or text) before execute is called, but after DBIx:: sets them to i int4. I'm not sure how much control you have at that level of abstraction though. - -- Greg Sabino Mullane greg@turnstep.com PGP Key: 0x14964AC8 200804101803 http://biglumber.com/x/web?pk=2529DF6AB8F79407E94445B4BC9B906714964AC8 -----BEGIN PGP SIGNATURE----- iEYEAREDAAYFAkf+jtwACgkQvJuQZxSWSsgb1gCcCEGU8+D5ldwZ1z5coG9qmPUS rVQAmwYd/L/e5H6agSB885oc/+HiqTKw =GRuv -----END PGP SIGNATURE-----
Rejecting as not-a-DBD::Pg bug. Please re-open if this is a mistake, but be aware that some other part of your toolchain is calling $dbh->bind_param().