Subject: | bug in dbdimp.c when running under perl 5.8.8 or later (svGrow has changed) |
The symptom can be seen during a make test to SQL Server when running
with Perl 5.8.8 or later:
Can't change param 1 maxlen (51->50) after first bind at t/20SqlServer.t
line 180.
The problem is
svGrow(phs->sv, 50+1)
followed by
SvLEN(phs->sv)
returns 52!
The dbdimp.c code relies on SvLen returning exactly what svGrow was
passed. In Perl 5.8.8 this is no longer true as svGrow can allocate a
little more (up to a longword boundary I think). The fix is trivial:
Index: dbdimp.c
===================================================================
--- dbdimp.c (revision 7847)
+++ dbdimp.c (working copy)
@@ -2928,7 +2928,7 @@
croak("Can't rebind or change param %s in/out mode after first
bind (%d => %d)",
phs->name, phs->is_inout, is_inout);
}
- else if (maxlen && maxlen != phs->maxlen) {
+ else if (maxlen && maxlen > phs->maxlen) {
croak("Can't change param %s maxlen (%ld->%ld) after first bind",
phs->name, phs->maxlen, maxlen);
}
BTW, whilst I'm here there are still quite a number of comments in
comments in dbdimp.h - the following fixes those:
--- dbdimp.h (revision 7847)
+++ dbdimp.h (working copy)
@@ -37,8 +37,8 @@
int odbc_sqlmoreresults_supported; /* flag to see if
SQLMoreResults is supported */
int odbc_defer_binding; /* flag to work around SQLServer bug and
defer binding until */
/* last possible moment */
- int odbc_force_rebind; /* force rebinding the output columns after
each execute to
- /* resolve some issues where certain stored procs can return
+ int odbc_force_rebind; /* force rebinding the output columns after
each execute to */
+ /* resolve some issues where certain stored procs can return */
/* multiple result sets */
int odbc_query_timeout;
int odbc_async_exec; /* flag to set asynchronous execution */
@@ -86,8 +86,8 @@
int odbc_ignore_named_placeholders; /* flag to ignore named
parameters */
int odbc_default_bind_type; /* flag to set default binding type
(experimental) */
int odbc_exec_direct; /* flag for executing SQLExecDirect instead
of SQLPrepare and SQLExecute. Magic happens at SQLExecute() */
- int odbc_force_rebind; /* force rebinding the output columns after
each execute to
- /* resolve some issues where certain stored procs can return
+ int odbc_force_rebind; /* force rebinding the output columns after
each execute to */
+ /* resolve some issues where certain stored procs can return */
/* multiple result sets */
int odbc_query_timeout;
};