Index: dbdimp.c =================================================================== --- dbdimp.c (revision 7995) +++ dbdimp.c (working copy) @@ -140,7 +140,6 @@ SV *value; char *key; I32 keylen; - SV *inner = 0; Safefree(imp_sth->fbh); Safefree(imp_sth->ColNames); @@ -382,11 +381,9 @@ /* don't fail if the query timeout can't be set. */ } ret = SQLExecDirect(stmt, (SQLCHAR *)statement, SQL_NTS); - if (ODBC_TRACE_LEVEL(imp_dbh) >= 2) { + if (ODBC_TRACE_LEVEL(imp_dbh) >= 2) PerlIO_printf(DBIc_LOGPIO(imp_dbh), " dbd_db_execdirect (rc = %d)...\n", ret); - PerlIO_flush(DBIc_LOGPIO(imp_dbh)); - } if (!SQL_ok(ret) && ret != SQL_NO_DATA) { dbd_error2( dbh, ret, "Execute immediate failed", imp_dbh->henv, imp_dbh->hdbc, stmt ); if (ret < 0) { @@ -430,10 +427,8 @@ /* Nothing in imp_dbh to be freed */ DBIc_IMPSET_off(imp_dbh); - if (ODBC_TRACE_LEVEL(imp_dbh) >= 8) { + if (ODBC_TRACE_LEVEL(imp_dbh) >= 8) PerlIO_printf(DBIc_LOGPIO(imp_dbh), " DBD::ODBC Disconnected!\n"); - PerlIO_flush(DBIc_LOGPIO(imp_dbh)); - } } @@ -744,7 +739,7 @@ rc = SQLGetFunctions(imp_dbh->hdbc, SQL_API_SQLMORERESULTS, &supported); if (ODBC_TRACE_LEVEL(imp_dbh) >= 3) - PerlIO_printf(DBIc_LOGPIO(imp_dbh), " SQLGetFunctions - SQL_MoreResults supported: %d\n", + PerlIO_printf(DBIc_LOGPIO(imp_dbh), " SQLGetFunctions - SQLMoreResults supported: %d\n", supported); if (SQL_ok(rc)) { imp_dbh->odbc_sqlmoreresults_supported = supported ? 1 : 0; @@ -766,6 +761,9 @@ /* flag to see if SQLDescribeParam is supported */ rc = SQLGetFunctions(imp_dbh->hdbc, SQL_API_SQLDESCRIBEPARAM, &supported); + if (ODBC_TRACE_LEVEL(imp_dbh) >= 3) + PerlIO_printf(DBIc_LOGPIO(imp_dbh), " SQLGetFunctions - SQLDescribeParam supported: %d\n", + supported); if (SQL_ok(rc)) { imp_dbh->odbc_sqldescribeparam_supported = supported ? 1 : 0; } else { @@ -1263,7 +1261,8 @@ if (imp_sth->all_params_hv) { DBIc_NUM_PARAMS(imp_sth) = (int)HvKEYS(imp_sth->all_params_hv); if (ODBC_TRACE_LEVEL(imp_sth) >= 2) - PerlIO_printf(DBIc_LOGPIO(imp_sth), " dbd_preparse scanned %d distinct placeholders\n", + PerlIO_printf(DBIc_LOGPIO(imp_sth), + " dbd_preparse scanned %d distinct placeholders\n", (int)DBIc_NUM_PARAMS(imp_sth)); } } @@ -1624,11 +1623,10 @@ if (imp_sth->done_desc) return 1; /* success, already done it */ - if (ODBC_TRACE_LEVEL(imp_sth) >= 5) { - PerlIO_printf(DBIc_LOGPIO(imp_sth), " dbd_describe %d getting num fields\n", + if (ODBC_TRACE_LEVEL(imp_sth) >= 5) + PerlIO_printf(DBIc_LOGPIO(imp_sth), + " dbd_describe %d getting num fields\n", imp_sth->hstmt); - PerlIO_flush(DBIc_LOGPIO(imp_sth)); - } rc = SQLNumResultCols(imp_sth->hstmt, &num_fields); if (!SQL_ok(rc)) { @@ -1647,10 +1645,9 @@ while (num_fields == 0 && imp_dbh->odbc_sqlmoreresults_supported == 1) { rc = SQLMoreResults(imp_sth->hstmt); - if (ODBC_TRACE_LEVEL(imp_sth) >= 8) { - PerlIO_printf(DBIc_LOGPIO(imp_sth), "Numfields == 0, SQLMoreResults == %d\n", rc); - PerlIO_flush(DBIc_LOGPIO(imp_sth)); - } + if (ODBC_TRACE_LEVEL(imp_sth) >= 8) + PerlIO_printf(DBIc_LOGPIO(imp_sth), + "Numfields == 0, SQLMoreResults == %d\n", rc); if (rc == SQL_SUCCESS_WITH_INFO) { AllODBCErrors(imp_sth->henv, imp_sth->hdbc, imp_sth->hstmt, ODBC_TRACE_LEVEL(imp_sth) >= 8, DBIc_LOGPIO(imp_dbh)); } @@ -1663,10 +1660,9 @@ if (!SQL_ok(rc)) break; imp_sth->odbc_force_rebind = 1; /* force future executes to rebind automatically */ rc = SQLNumResultCols(imp_sth->hstmt, &num_fields); - if (ODBC_TRACE_LEVEL(imp_sth) >= 8) { - PerlIO_printf(DBIc_LOGPIO(imp_dbh), "Numfields == 0, SQLNumResultCols == %d\n", rc); - PerlIO_flush(DBIc_LOGPIO(imp_dbh)); - } + if (ODBC_TRACE_LEVEL(imp_sth) >= 8) + PerlIO_printf(DBIc_LOGPIO(imp_dbh), + "Numfields == 0, SQLNumResultCols == %d\n", rc); if (!SQL_ok(rc)) { dbd_error(h, rc, "dbd_describe/SQLNumResultCols"); return 0; @@ -1714,11 +1710,11 @@ t_cbufl += fbh->ColNameLen + 1; - if (ODBC_TRACE_LEVEL(imp_sth) >= 8) { - PerlIO_printf(DBIc_LOGPIO(imp_dbh), " colname %d = %s len = %d (%d)\n", i+1, ColName, fbh->ColNameLen, + if (ODBC_TRACE_LEVEL(imp_sth) >= 8) + PerlIO_printf(DBIc_LOGPIO(imp_dbh), + " colname %d = %s len = %d (%d)\n", + i+1, ColName, fbh->ColNameLen, t_cbufl); - PerlIO_flush(DBIc_LOGPIO(imp_dbh)); - } #ifdef SQL_COLUMN_DISPLAY_SIZE rc = SQLColAttributes(imp_sth->hstmt,i+1,SQL_COLUMN_DISPLAY_SIZE, @@ -1809,10 +1805,9 @@ } /* allocate a buffer to hold all the column names */ - if (ODBC_TRACE_LEVEL(imp_sth) >= 8) { - PerlIO_printf(DBIc_LOGPIO(imp_dbh), " colname buffer size = %d\n", t_cbufl + num_fields); - PerlIO_flush(DBIc_LOGPIO(imp_dbh)); - } + if (ODBC_TRACE_LEVEL(imp_sth) >= 8) + PerlIO_printf(DBIc_LOGPIO(imp_dbh), + " colname buffer size = %d\n", t_cbufl + num_fields); /* quick fix for FoxPro: allocate extra 255 bytes as Foxpro seems * to clear out the buffer during SQLDescribeCol, as we are passing @@ -1871,11 +1866,11 @@ "\t\t post SQLDescribeCol col %2d: '%s' (%x)\n", 0, imp_sth->fbh[0].ColName, imp_sth->fbh[0].ColName); - if (ODBC_TRACE_LEVEL(imp_sth) >= 8) { - PerlIO_printf(DBIc_LOGPIO(imp_dbh), " colname %d = %s, len = %d (sp = %d)\n", i+1, fbh->ColName, fbh->ColNameLen, - cbuf_ptr - imp_sth->ColNames); - PerlIO_flush(DBIc_LOGPIO(imp_dbh)); - } + if (ODBC_TRACE_LEVEL(imp_sth) >= 8) + PerlIO_printf(DBIc_LOGPIO(imp_dbh), + " colname %d = %s, len = %d (sp = %d)\n", + i+1, fbh->ColName, fbh->ColNameLen, + cbuf_ptr - imp_sth->ColNames); cbuf_ptr += fbh->ColNameLen+1; @@ -2008,12 +2003,10 @@ } - if (debug >= 2) { + if (debug >= 2) PerlIO_printf(DBIc_LOGPIO(imp_dbh), " dbd_st_execute (for hstmt %d before)...\n", imp_sth->hstmt); - PerlIO_flush(DBIc_LOGPIO(imp_dbh)); - } if (imp_sth->odbc_exec_direct) { /* statement ready for SQLExecDirect */ @@ -2021,12 +2014,10 @@ } else { rc = SQLExecute(imp_sth->hstmt); } - if (debug >= 8) { + if (debug >= 8) PerlIO_printf(DBIc_LOGPIO(imp_dbh), " dbd_st_execute (for hstmt %d after, rc = %d)...\n", imp_sth->hstmt, rc); - PerlIO_flush(DBIc_LOGPIO(imp_dbh)); - } /* * If asynchronous execution has been enabled, SQLExecute will * return SQL_STILL_EXECUTING until it has finished. @@ -2048,12 +2039,10 @@ STRLEN len; UCHAR* ptr; - if (debug >= 5) { + if (debug >= 5) PerlIO_printf(DBIc_LOGPIO(imp_dbh), " dbd_st_execute (NEED DATA)...\n", imp_sth->hstmt); - PerlIO_flush(DBIc_LOGPIO(imp_dbh)); - } if ((rc = SQLParamData(imp_sth->hstmt, (PTR*) &phs)) != SQL_NEED_DATA) { break; @@ -2127,11 +2116,9 @@ /* SQL_NO_DATA returned, must have no rows :) */ /* seem to need to reset the done_desc, but not sure if this is * what we want yet */ - if (debug >= 7) { + if (debug >= 7) PerlIO_printf(DBIc_LOGPIO(imp_dbh), " dbd_st_execute SQL_NO_DATA...resetting done_desc!\n"); - PerlIO_flush(DBIc_LOGPIO(imp_dbh)); - } imp_sth->done_desc = 0; imp_sth->RowCount = 0; } @@ -2231,9 +2218,9 @@ if (imp_dbh->odbc_sqlmoreresults_supported == 1) { rc = SQLMoreResults(imp_sth->hstmt); /* Check for multiple results */ - if (ODBC_TRACE_LEVEL(imp_sth) > 5) { - PerlIO_printf(DBIc_LOGPIO(imp_dbh), "Getting more results: %d\n", rc); - } + if (ODBC_TRACE_LEVEL(imp_sth) > 5) + PerlIO_printf(DBIc_LOGPIO(imp_dbh), + "Getting more results: %d\n", rc); if (rc == SQL_SUCCESS_WITH_INFO || rc == SQL_NO_DATA) { dbd_error(sth, rc, "st_fetch/SQLMoreResults"); @@ -2265,10 +2252,9 @@ } if (!dbd_describe(sth, imp_sth, 1)) { - if (ODBC_TRACE_LEVEL(imp_sth) > 0) { - PerlIO_printf(DBIc_LOGPIO(imp_dbh), "MORE Results dbd_describe failed...!\n"); - } - + if (ODBC_TRACE_LEVEL(imp_sth) > 0) + PerlIO_printf(DBIc_LOGPIO(imp_dbh), + "MORE Results dbd_describe failed...!\n"); return Nullav; /* dbd_describe already called dbd_error() */ } @@ -2414,7 +2400,6 @@ dTHR; D_imp_dbh_from_sth; RETCODE rc; - int ret = 0; /* Cancel further fetches from this cursor. */ /* We don't close the cursor till DESTROY (dbd_st_destroy). */ @@ -2482,10 +2467,10 @@ rc = SQLFreeHandle(SQL_HANDLE_STMT,imp_sth->hstmt); /* rc = SQLFreeStmt(imp_sth->hstmt, SQL_DROP);*/ /* TBD: 3.0 update */ - if (ODBC_TRACE_LEVEL(imp_sth) >= 5) { - PerlIO_printf(DBIc_LOGPIO(imp_dbh), " SQLFreeStmt called, returned %d.\n", rc); - PerlIO_flush(DBIc_LOGPIO(imp_dbh)); - } + if (ODBC_TRACE_LEVEL(imp_sth) >= 5) + PerlIO_printf(DBIc_LOGPIO(imp_dbh), + " SQLFreeStmt called, returned %d.\n", + rc); if (!SQL_ok(rc)) { dbd_error(sth, rc, "st_destroy/SQLFreeStmt(SQL_DROP)"); @@ -2517,7 +2502,6 @@ SWORD fSqlType; if (phs->sql_type == 0) { - if (imp_dbh->odbc_sqldescribeparam_supported == 1) { if (ODBC_TRACE_LEVEL(imp_sth) >= 3) { PerlIO_printf(DBIc_LOGPIO(imp_dbh), "SQLDescribeParam idx = %d.\n", phs->idx); @@ -2531,16 +2515,18 @@ phs->sql_type = ODBC_BACKUP_BIND_TYPE_VALUE; /* dbd_error(sth, rc, "_rebind_ph/SQLDescribeParam"); */ if (ODBC_TRACE_LEVEL(imp_sth) > 0) - PerlIO_printf(DBIc_LOGPIO(imp_dbh), "SQLDescribeParam failed reverting to default type for this parameter: "); + PerlIO_printf(DBIc_LOGPIO(imp_dbh), "SQLDescribeParam failed reverting to default type for this parameter: \n"); AllODBCErrors(imp_sth->henv, imp_sth->hdbc, imp_sth->hstmt, (ODBC_TRACE_LEVEL(imp_sth) > 0), DBIc_LOGPIO(imp_sth)); /* fall through */ /* return 0; */ } else { - if (ODBC_TRACE_LEVEL(imp_sth) >=5) + if (ODBC_TRACE_LEVEL(imp_sth) >=5) PerlIO_printf(DBIc_LOGPIO(imp_dbh), - " SQLDescribeParam %s: SqlType=%s, ColDef=%d\n", - phs->name, S_SqlTypeToString(fSqlType), dp_cbColDef); + " SQLDescribeParam %s: SqlType=%s, ColDef=%d " + "Scale=%d Nullable=%d\n", + phs->name, S_SqlTypeToString(fSqlType), dp_cbColDef, + ibScale, fNullable); /* for non-integral numeric types, let the driver/database handle the @@ -2552,7 +2538,7 @@ case SQL_FLOAT: case SQL_REAL: case SQL_DOUBLE: - if (ODBC_TRACE_LEVEL(imp_sth) >=5) + if (ODBC_TRACE_LEVEL(imp_sth) >=5) PerlIO_printf(DBIc_LOGPIO(imp_dbh), " (DBD::ODBC SQLDescribeParam NUMERIC FIXUP %s: SqlType=%s, ColDef=%d\n", phs->name, S_SqlTypeToString(fSqlType), dp_cbColDef); @@ -2574,8 +2560,8 @@ /* ==================================================================== */ -static int - _dbd_rebind_ph(SV *sth, imp_sth_t *imp_sth, phs_t *phs) +static int + _dbd_rebind_ph(SV *sth, imp_sth_t *imp_sth, phs_t *phs) { dTHR; D_imp_dbh_from_sth; @@ -2596,7 +2582,6 @@ "bind %s <== %s (size %d/%d/%ld, ptype %ld, otype %d, sqltype %d)\n", phs->name, text, SvOK(phs->sv) ? SvCUR(phs->sv) : -1, SvOK(phs->sv) ? SvLEN(phs->sv) : -1 ,phs->maxlen, SvTYPE(phs->sv), phs->ftype, phs->sql_type); - PerlIO_flush(DBIc_LOGPIO(imp_dbh)); } /* At the moment we always do sv_setsv() and rebind. */ @@ -2633,12 +2618,11 @@ phs->sv_type = SvTYPE(phs->sv); /* part of mutation check */ phs->maxlen = SvLEN(phs->sv)-1; /* avail buffer space */ - if (ODBC_TRACE_LEVEL(imp_sth) >= 3) { - PerlIO_printf(DBIc_LOGPIO(imp_dbh), "bind %s <== '%.100s' (len %ld/%ld, null %d)\n", + if (ODBC_TRACE_LEVEL(imp_sth) >= 3) + PerlIO_printf(DBIc_LOGPIO(imp_dbh), + "bind %s <== '%.100s' (len %ld/%ld, null %d)\n", phs->name, SvOK(phs->sv) ? phs->sv_buf : "(null)", (long)value_len,(long)phs->maxlen, SvOK(phs->sv)?0:1); - PerlIO_flush(DBIc_LOGPIO(imp_dbh)); - } /* ---------------------------------------------------------------- */ @@ -2660,7 +2644,7 @@ * with Oracle. Need to test on other platforms to ensure this * does not cause a problem. */ - fParamType = phs->is_inout ? SQL_PARAM_INPUT_OUTPUT : SQL_PARAM_INPUT; + fParamType = phs->is_inout ? SQL_PARAM_INPUT_OUTPUT : SQL_PARAM_INPUT; fCType = phs->ftype; ibScale = value_len; cbColDef = phs->is_inout ? phs->maxlen : value_len; @@ -2670,7 +2654,7 @@ */ cbValueMax = phs->is_inout ? phs->maxlen : value_len; - /* When we fill a LONGVARBINARY, the CTYPE must be set + /* When we fill a LONGVARBINARY, the CTYPE must be set * to SQL_C_BINARY. */ if (fCType == SQL_C_CHAR) { /* could be changed by bind_plh */ @@ -2767,7 +2751,8 @@ rgbValue = phs->sv_buf; /* patch for binding undef inout params on sql server */ ibScale = 1; - phs->cbValue = 1; + rgbValue = phs->sv_buf; + phs->cbValue = SQL_NULL_DATA; } else { rgbValue = NULL; phs->cbValue = SQL_NULL_DATA; @@ -2881,12 +2866,15 @@ #endif - if (ODBC_TRACE_LEVEL(imp_sth) >= 2) { - PerlIO_printf(DBIc_LOGPIO(imp_dbh), "bind %s <== '%.200s' (attribs: %s), type %d\n", - name, SvPV(newvalue,na), attribs ? SvPV(attribs,na) : "", sql_type ); - PerlIO_flush(DBIc_LOGPIO(imp_dbh)); - } + if (ODBC_TRACE_LEVEL(imp_sth) >= 2) + PerlIO_printf(DBIc_LOGPIO(imp_dbh), + "bind %s <== '%.200s' (attribs: %s), type %d\n", + name, SvOK(newvalue) ? SvPV_nolen(newvalue) : "undef", + attribs ? SvPV_nolen(attribs) : "", sql_type ); + /* + * all_params_hv created during dbd_preparse. + */ phs_svp = hv_fetch(imp_sth->all_params_hv, name, name_len, 0); if (phs_svp == NULL) croak("Can't bind unknown placeholder '%s'", name); @@ -2901,7 +2889,6 @@ */ phs->sql_type = (sql_type) ? sql_type : imp_sth->odbc_default_bind_type; - phs->maxlen = maxlen; /* 0 if not inout */ phs->is_inout = is_inout; if (is_inout) { @@ -2911,7 +2898,6 @@ if (!imp_sth->out_params_av) imp_sth->out_params_av = newAV(); av_push(imp_sth->out_params_av, SvREFCNT_inc(*phs_svp)); - /* croak("Can't bind output values (currently)"); /* XXX */ } /* some types require the trailing null included in the length. */ @@ -2925,10 +2911,10 @@ * } * */ else if (is_inout != phs->is_inout) { - croak("Can't rebind or change param %s in/out mode after first bind (%d => %d)", - phs->name, phs->is_inout, is_inout); + 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); } @@ -2950,6 +2936,7 @@ } /* fall through for "immediate" binding */ #endif + return _dbd_rebind_ph(sth, imp_sth, phs); } @@ -3569,18 +3556,15 @@ int j; PerlIO_printf(DBIc_LOGPIO(imp_sth), " dbd_st_FETCH_attrib NAMES %d\n", i); - for (j = 0; j < i; j++) { - PerlIO_printf(DBIc_LOGPIO(imp_sth), "\t%s\n", imp_sth->fbh[j].ColName); - PerlIO_flush(DBIc_LOGPIO(imp_sth)); - } - PerlIO_flush(DBIc_LOGPIO(imp_sth)); + for (j = 0; j < i; j++) + PerlIO_printf(DBIc_LOGPIO(imp_sth), + "\t%s\n", imp_sth->fbh[j].ColName); } while(--i >= 0) { - if (ODBC_TRACE_LEVEL(imp_sth) > 8) { - PerlIO_printf(DBIc_LOGPIO(imp_sth), " Colname %d => %s\n", + if (ODBC_TRACE_LEVEL(imp_sth) > 8) + PerlIO_printf(DBIc_LOGPIO(imp_sth), + " Colname %d => %s\n", i, imp_sth->fbh[i].ColName); - PerlIO_flush(DBIc_LOGPIO(imp_sth)); - } av_store(av, i, newSVpv(imp_sth->fbh[i].ColName, 0)); } break; Index: dbdimp.h =================================================================== --- dbdimp.h (revision 7995) +++ dbdimp.h (working copy) @@ -22,7 +22,7 @@ int connects; /* connect count */ }; -/* Define dbh implementor data structure +/* Define dbh implementor data structure This holds everything to describe the database connection. */ struct imp_dbh_st { @@ -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; }; @@ -128,11 +128,11 @@ SV *sv; /* the scalar holding the value */ int sv_type; /* original sv type at time of bind */ int biggestparam; /* if sv_type is VARCHAR, size of biggest so far */ - int scale; + int scale; /* MJE NEVER USED */ bool is_inout; IV maxlen; /* max possible len (=allocated buffer) */ char *sv_buf; /* pointer to sv's data buffer */ - int alen_incnull; + int alen_incnull; /* MJE NEVER USED */ SWORD ftype; /* external field type */ SWORD sql_type; /* the sql type the placeholder should have in SQL */ Index: README =================================================================== --- README (revision 7995) +++ README (working copy) @@ -41,7 +41,10 @@ make install (if the tests look okay) Note that the tests currently all pass when using the Microsoft SQL - server driver. See the known compatibility list below. + server driver up to SQL Server 2000. In later SQL Server versions + (2005 and Express) it is possible you will see errors in tests + 20SqlServer, 28, 31, 32 and 33 (patches welcome). + See the known compatibility list below. If the tests from t/09bind.t fail, that is an indication of lack of ODBC Level 2 functionality. This does not (necessarily) mean that @@ -82,6 +85,7 @@ Driver Version Platform tested Microsoft SQL Server v 2.65.0240 NT 4.0 +Microsoft SQL Server v 2000.80.528.00 Windows 2000 Intersolv Oracle7 Driver* v 3.00.0000 NT 4.0 *full support is optional, via configuration of DSN -- Advanced page. Index: Changes =================================================================== --- Changes (revision 7995) +++ Changes (working copy) @@ -24,6 +24,25 @@ Fix bug reported where ping crashes after disconnect thanks to Steffen Goeldner. +Fix bug in dbd_bind_ph which leads to the error +Can't change param 1 maxlen (51->50) after first bind +in the 20SqlServer test. This is caused by svGROW in Perl 5.8.8 being changed +to possibly grow by more than you asked (e.g. up to the next longword boundary). + +Fix problem with binding undef as an output parameter. Reported by Stephen More +with IBM's ODBC driver for iSeries. + +Removed comment delimiters in comments in dbdimp.h leading to warnings. + +Removed some unused variable declarations leading to warnings. + +Removed PerlIO_flush calls as it is believed they are not required. + +Add logging for whether SQLDescribeParam is supported. + +Fixed use of unitialised variable in dbd_bind_ph where an undef is bound + and tracing is enabled. + =head2 Changes in DBD::ODBC 1.13 November 8, 2004 Fix inconsistency/bug with odbc_exec_direct vs. odbc_execdirect settings. Now made consistent with