]> granicus.if.org Git - php/commitdiff
Possible fixes for #35552, #35592 and #35620.
authorWez Furlong <wez@php.net>
Wed, 14 Dec 2005 04:56:22 +0000 (04:56 +0000)
committerWez Furlong <wez@php.net>
Wed, 14 Dec 2005 04:56:22 +0000 (04:56 +0000)
ext/pdo_odbc/odbc_driver.c

index 5ae45a7e64fe23c40e74e9908b1a141354a74f64..08120720beb6fcba288e2297f7ee60e3ddad1767 100755 (executable)
@@ -58,8 +58,10 @@ static int pdo_odbc_fetch_error_func(pdo_dbh_t *dbh, pdo_stmt_t *stmt, zval *inf
 
 void pdo_odbc_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, PDO_ODBC_HSTMT statement, char *what, const char *file, int line TSRMLS_DC) /* {{{ */
 {
-       RETCODE rc;
-       SWORD   errmsgsize = 0;
+       SQLRETURN rc;
+       SQLSMALLINT     errmsgsize = 0;
+       SQLHANDLE eh;
+       SQLSMALLINT htype, recno = 1;
        pdo_odbc_db_handle *H = (pdo_odbc_db_handle*)dbh->driver_data;
        pdo_odbc_errinfo *einfo = &H->einfo;
        pdo_odbc_stmt *S = NULL;
@@ -75,8 +77,19 @@ void pdo_odbc_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, PDO_ODBC_HSTMT statement,
        if (statement == SQL_NULL_HSTMT && S) {
                statement = S->stmt;
        }
-       
-       rc = SQLError(H->env, H->dbc, statement, einfo->last_state, &einfo->last_error,
+
+       if (statement) {
+               htype = SQL_HANDLE_STMT;
+               eh = statement;
+       } else if (H->dbc) {
+               htype = SQL_HANDLE_DBC;
+               eh = H->dbc;
+       } else {
+               htype = SQL_HANDLE_ENV;
+               eh = H->env;
+       }
+
+       rc = SQLGetDiagRec(htype, eh, recno++, einfo->last_state, &einfo->last_error,
                        einfo->last_err_msg, sizeof(einfo->last_err_msg)-1, &errmsgsize);
 
        if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
@@ -94,6 +107,20 @@ void pdo_odbc_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, PDO_ODBC_HSTMT statement,
                zend_throw_exception_ex(php_pdo_get_exception(), 0 TSRMLS_CC, "SQLSTATE[%s] %s: %d %s",
                                *pdo_err, what, einfo->last_error, einfo->last_err_msg);
        }
+
+       /* just like a cursor, once you start pulling, you need to keep
+        * going until the end; SQL Server (at least) will mess with the
+        * actual cursor state if you don't finish retrieving all the
+        * diagnostic records (which can be generated by PRINT statements
+        * in the query, for instance). */
+       while (rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO) {
+               char discard_state[5];
+               char discard_buf[1024];
+               SQLINTEGER code;
+               rc = SQLGetDiagRec(htype, eh, recno++, discard_state, &code,
+                               discard_buf, sizeof(discard_buf)-1, &errmsgsize);
+       }
+
 }
 /* }}} */
 
@@ -175,14 +202,12 @@ static int odbc_handle_preparer(pdo_dbh_t *dbh, const char *sql, long sql_len, p
                pdo_odbc_stmt_error("SQLPrepare");
        }
 
+       stmt->driver_data = S;
+       stmt->methods = &odbc_stmt_methods;
+
        if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
-               SQLFreeHandle(SQL_HANDLE_STMT, S->stmt);
                return 0;
        }
-
-       stmt->driver_data = S;
-       stmt->methods = &odbc_stmt_methods;
-       
        return 1;
 }