[PHP-DEV] [long] Win32 / ODBC failure From: Jon Evans (jevans <email protected>)
Date: 08/09/00

Hi,

I'm developing a site for a customer using PHP4. It will reside on an
NT server using an ODBC connection to a MS SQL datasource. I'm
testing it on NT, with a connection to a local Access database (using
ODBC) and a connection to a MySQL datasource on another box (again
using ODBC).

I'm having problems with SQL queries that have parameters. Using
Access I get nowhere at all:

Warning: SQL error: [Microsoft][ODBC Microsoft Access Driver]COUNT
field incorrect , SQL state 07001 in SQLExecute in
C:\InetPub\wwwroot\testsql.php on line 79

using MySQL I get a different error:

FATAL: emalloc(): Unable to allocate 268665117 bytes
(followed by a dump of locations where it allocated memory)
(the number of bytes is always the same)

The test script is very simple, I've attached it to this message.

I think there are problems in ext/odbc/php_odbc.c - there is no return
checking in the function PHP_FUNCTION(odbc_execute).

Here is the problem (as I see it). It helps if you look at this ODBC
dump from the NT box:

[snip]

editclient c4:ab ENTER SQLDescribeParam
    HSTMT 0x00a61a50
    UWORD 1
    SWORD * 0x0012ec2c
    UDWORD * 0x0012ec28
    SWORD * 0x0012ec24
    SWORD * 0x0012ec32
 
editclient c4:ab EXIT SQLDescribeParam with return code -1 (SQL_ERROR)
    HSTMT 0x00a61a50
    UWORD 1
    SWORD * 0x0012ec2c
    UDWORD * 0x0012ec28
    SWORD * 0x0012ec24
    SWORD * 0x0012ec32
 
    DIAG [IM001] [Microsoft][ODBC Driver Manager] Driver does not support this function (0)

editclient c4:ab ENTER SQLBindParameter
    HSTMT 0x00a61a50
    UWORD 1
    SWORD 1 <SQL_PARAM_INPUT>
    SWORD 1 <SQL_C_CHAR>
    SWORD 30592 <unknown>
    UDWORD 108
    SWORD 0
    PTR 0x00569ff0
    SDWORD 0
    SDWORD * 0x0056f6a0
 
editclient c4:ab EXIT SQLBindParameter with return code -1 (SQL_ERROR)
    HSTMT 0x00a61a50
    UWORD 1
    SWORD 1 <SQL_PARAM_INPUT>
    SWORD 1 <SQL_C_CHAR>
    SWORD 30592 <unknown>
    UDWORD 108
    SWORD 0
    PTR 0x00569ff0
    SDWORD 0
    SDWORD * 0x0056f6a0
 
    DIAG [S1004] [Microsoft][ODBC Microsoft Access Driver]Invalid SQL data type (67)

[snip]

I think that the code ignores the error from SQLDescribeParam, then
passes uninitialised variables to SQLBindParameter. If this is the
case, the following should work around this error:

--- php_odbc.c.orig Wed Aug 9 12:07:51 2000
+++ php_odbc.c Wed Aug 9 12:13:03 2000
@@ -825,8 +825,13 @@
                                 RETURN_FALSE;
                         }
                         
- SQLDescribeParam(result->stmt, (UWORD)i, &sqltype, &precision,
+ rc = SQLDescribeParam(result->stmt, (UWORD)i, &sqltype, &precision,
                                                          &scale, &nullable);
+ if (rc=SQL_ERROR){
+ /* work around servers that don't support SQLDescribeParam */
+ scale=0;
+ sqltype=SQL_CHAR; //assume char
+ }
                         params[i-1].vallen = (*tmp)->value.str.len;
                         params[i-1].fp = -1;
 

I would like to do more testing myself, but I can't get the source to
compile on NT. Is there an NT compilation HOWTO anywhere?
I could work with someone who can compile it if that would be alright,
I could debug and code, someone else could code and compile.

The error message I got from odbc->mysql leads me to believe that a
similar thing is happening there, an error return is being ignored and
an emalloc is attempted with a huge bogus size due to an uninitialised
variable, or an error code.

Jon.

-- 
Jon Evans / Red Internet Ltd. / +44 1869 337977

  • application/pgp-signature attachment: stored