Skip Menu |

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

Report information
The Basics
Id: 78838
Status: resolved
Priority: 0/
Queue: DBD-ODBC

People
Owner: Nobody in particular
Requestors: phil [...] pgengler.net
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: 1.39
Fixed in: 1.40_2



Subject: bind_param does not correctly stringify blessed objects when connected to MS SQL Server
When using DBD::ODBC to connect to a Microsoft SQL Server database (via the Easysoft ODBC driver on Linux), the bind_param() method doesn't seem to properly stringify blessed objects. This was the behavior in version 1.23 and seems to have changed in 1.24, and kept that behavior through to (and including) 1.39. Here's a short example script that shows the problem: -------------------------------------------------------- use DBI; my $dbh = DBI->connect("dbi:ODBC:DSN=<DSN>;UID=<UID>;PWD=<PWD>;Database=<DB>;Trusted_Connection=No;APP=$0;MARS_Connection=No;"); my $obj = new Object(); my $sql = q( SELECT ? AS result ); my $sth = $dbh->prepare($sql); $sth->bind_param(1, $obj); $sth->execute(); while (my $row = $sth->fetchrow_hashref()) { print $row->{'result'}, "\n"; } package Object; use overload '""' => 'to_s'; sub new() { bless { }, shift }; sub to_s() { my $self = shift; ref($self) } -------------------------------------------------------- With DBD-ODBC-1.23, the output is 'Object'. With DBD-ODBC-1.24 and later, the output is something like '▒▒8▒6'. Here's the relevant trace outputs for comparison: 1.39: -> bind_param for DBD::ODBC::st (DBI::st=HASH(0x1fb2668)~0x1fb2608 1 Object=HASH(0x1fb22c0)) thr#1e85010 +dbd_bind_ph(2020348, name=1, value=Object=HASH(0x1fb22c0), attribs=, sql_type=0(unknown), is_inout=0, maxlen=0 -dbd_bind_ph=rebind_param +rebind_param 1 Object=HASH(0x1fb22c0) (size svCUR=33237088/SvLEN=0/max=0) svtype 4, value type:1 sql type:0 +get_param_type(2020348,1) Parameter 1 SQLDescribeParam failed, sv=0 bytes, defaulting to 12 07009 [Easysoft][SQL Server Driver 10.0][SQL Server]Invalid descriptor index bind 1 Object=HASH(0x1fb22c0) value_len=6 maxlen=-1 null=0) bind 1 value_type:1 VARCHAR cs=80 dd=0 bl=6 -rebind_param <- bind_param= 1 at odbc.pl line 13 1.23: -> bind_param for DBD::ODBC::st (DBI::st=HASH(0x1d126d8)~0x1d12678 1 Object=HASH(0x1f06e98)) thr#1c79010 +dbd_bind_ph(1e14348, name=1, value='Object', attribs=, sql_type=0(unknown), is_inout=0, maxlen=0 +get_param_type(1e14348,1) SQLDescribeParam failed reverting to default SQL bind type -1 07009 [Easysoft][SQL Server Driver 10.0][SQL Server]Invalid descriptor index -dbd_bind_ph=1 <- bind_param= 1 at odbc.pl line 13 Applying this patch to dbdimp.c restores the 1.23 behavior: --- DBD-ODBC-1.39-release/dbdimp.c 2012-08-07 13:44:09.000087000 -0400 +++ DBD-ODBC-1.39-modified/dbdimp.c 2012-08-07 13:42:56.000315000 -0400 @@ -6490,7 +6490,7 @@ if (!strcmp(imp_dbh->odbc_dbms_name, "Microsoft SQL Server")) { if (DBIc_TRACE(imp_dbh, CONNECTION_TRACING, 0, 0)) TRACE0(imp_dbh, "Deferring Binding\n"); - imp_dbh->odbc_defer_binding = 0; + imp_dbh->odbc_defer_binding = 1; } /* check to see if SQLMoreResults is supported */ rc = SQLGetFunctions(imp_dbh->hdbc, SQL_API_SQLMORERESULTS, &supported); Trying to set $dbh->{odbc_defer_binding} = 1 from Perl has no effect. Perl version: 5.10.1 (64-bit)
On Tue Aug 07 13:46:16 2012, pgengler wrote: Show quoted text
> When using DBD::ODBC to connect to a Microsoft SQL Server database > (via > the Easysoft ODBC driver on Linux), the bind_param() method doesn't > seem > to properly stringify blessed objects.
Appologies but I did not seem to get an email notification of this rt from the rt system and only just noticed. I'm away a lot over the next 3 weeks but I'll try and find time to look at it in the next few days. I hope your current workaround is sufficient to keep you going until then. Martin -- Martin J. Evans Wetherby, UK
On Thu Aug 09 05:09:39 2012, MJEVANS wrote: Show quoted text
> On Tue Aug 07 13:46:16 2012, pgengler wrote:
> > When using DBD::ODBC to connect to a Microsoft SQL Server database > > (via > > the Easysoft ODBC driver on Linux), the bind_param() method doesn't > > seem > > to properly stringify blessed objects.
> > Appologies but I did not seem to get an email notification of this rt > from the rt system and only just noticed. I'm away a lot over the next
3 Show quoted text
> weeks but I'll try and find time to look at it in the next few days. I > hope your current workaround is sufficient to keep you going until
then. Show quoted text
> > Martin
The change you've made causes entry into code which is no longer used (and no longer supported). I should have removed that ages ago. It appears the ptr passed to SQLBindParameter for the bound parameter (string "Object") is valid at the time SQLBindParameter is called but no longer valid when SQLExecute is called. By delaying the call to SQLBindParameter until later (as your change does) it avoids this. I don't really understand from the Perl how that happens. I also note changing $obj to "$obj" (which I tried because it forces string context make it work with the current DBD::ODBC. Until I truly understand what is going on here I'm uncertain if there really is anything wrong or whether the previous version you were using was wrong. Martin -- Martin J. Evans Wetherby, UK
Sorry, but I've been on holiday and at YAPC::EU. This should be fixed in 1.40_2 now. Martin -- Martin J. Evans Wetherby, UK