]> granicus.if.org Git - php/commitdiff
Fix Bug #34687; error information from query() not passed back
authorWez Furlong <wez@php.net>
Sun, 2 Oct 2005 22:11:19 +0000 (22:11 +0000)
committerWez Furlong <wez@php.net>
Sun, 2 Oct 2005 22:11:19 +0000 (22:11 +0000)
ext/pdo/pdo_dbh.c
ext/pdo/php_pdo_driver.h
ext/pdo/php_pdo_int.h
ext/pdo/tests/bug_34687.phpt [new file with mode: 0644]

index c2ed2508c7ce2b8e32bf591658e781d9aae5fa86..8769a3c4fbf086c8cfec7175c094e99f0bc03617 100755 (executable)
@@ -919,6 +919,10 @@ static PHP_METHOD(PDO, errorCode)
        }
        PDO_CONSTRUCT_CHECK;
 
+       if (dbh->query_stmt) {
+               RETURN_STRING(dbh->query_stmt->error_code, 1);
+       }
+       
        RETURN_STRING(dbh->error_code, 1);
 }
 /* }}} */
@@ -935,10 +939,14 @@ static PHP_METHOD(PDO, errorInfo)
        PDO_CONSTRUCT_CHECK;
 
        array_init(return_value);
-       add_next_index_string(return_value, dbh->error_code, 1);
 
+       if (dbh->query_stmt) {
+               add_next_index_string(return_value, dbh->query_stmt->error_code, 1);
+       } else {
+               add_next_index_string(return_value, dbh->error_code, 1);
+       }
        if (dbh->methods->fetch_err) {
-               dbh->methods->fetch_err(dbh, NULL, return_value TSRMLS_CC);
+               dbh->methods->fetch_err(dbh, dbh->query_stmt, return_value TSRMLS_CC);
        }
 }
 /* }}} */
@@ -981,8 +989,6 @@ static PHP_METHOD(PDO, query)
 
        if (dbh->methods->preparer(dbh, statement, statement_len, stmt, NULL TSRMLS_CC)) {
                if (ZEND_NUM_ARGS() == 1 || SUCCESS == pdo_stmt_setup_fetch_mode(INTERNAL_FUNCTION_PARAM_PASSTHRU, stmt, 1)) {
-                       PDO_STMT_CLEAR_ERR();
-
                        /* now execute the statement */
                        PDO_STMT_CLEAR_ERR();
                        if (stmt->methods->executer(stmt TSRMLS_CC)) {
@@ -1000,13 +1006,14 @@ static PHP_METHOD(PDO, query)
                        }
                }
                /* something broke */
+               dbh->query_stmt = stmt;
+               dbh->query_stmt_zval = *return_value;
+               PDO_HANDLE_STMT_ERR();
+       } else {
+               PDO_HANDLE_DBH_ERR();
+               zval_dtor(return_value);
        }
 
-       PDO_HANDLE_STMT_ERR();
-               
-       /* kill the object handle for the stmt here */
-       zval_dtor(return_value);
-
        RETURN_FALSE;
 }
 /* }}} */
index 15efc314c8f58239a58cc4fd15626f3b460a8585..26ecdd89b2a2713ccaa42fff4afbcd38f767ffe7 100755 (executable)
@@ -44,7 +44,7 @@ PDO_API char *php_pdo_int64_to_str(pdo_int64_t i64 TSRMLS_DC);
 # define FALSE 0
 #endif
 
-#define PDO_DRIVER_API 20050711
+#define PDO_DRIVER_API 20051002
 
 enum pdo_param_type {
        PDO_PARAM_NULL,
@@ -477,8 +477,14 @@ struct _pdo_dbh_t {
        pdo_driver_t *driver;
        
        zend_class_entry *def_stmt_ce;
-       
        zval *def_stmt_ctor_args;
+
+       /* when calling PDO::query(), we need to keep the error
+        * context from the statement around until we next clear it.
+        * This will allow us to report the correct error message
+        * when PDO::query() fails */
+       pdo_stmt_t *query_stmt;
+       zval query_stmt_zval;
 };
 
 /* describes a column */
index b0b6525412b7a9d9be466c7e4ac726a7a46b2f44..e7c2487b58483f789b70a47eeb5199f7a386ea0e 100755 (executable)
@@ -57,7 +57,13 @@ extern pdo_driver_t *pdo_find_driver(const char *name, int namelen);
 
 extern void pdo_handle_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt TSRMLS_DC);
 
-#define PDO_DBH_CLEAR_ERR()            strcpy(dbh->error_code, PDO_ERR_NONE)
+#define PDO_DBH_CLEAR_ERR()            do { \
+       strcpy(dbh->error_code, PDO_ERR_NONE); \
+       if (dbh->query_stmt) { \
+               dbh->query_stmt = NULL; \
+               zend_objects_store_del_ref(&dbh->query_stmt_zval TSRMLS_CC); \
+       } \
+} while (0)
 #define PDO_STMT_CLEAR_ERR()   strcpy(stmt->error_code, PDO_ERR_NONE)
 #define PDO_HANDLE_DBH_ERR()   if (strcmp(dbh->error_code, PDO_ERR_NONE)) { pdo_handle_error(dbh, NULL TSRMLS_CC); }
 #define PDO_HANDLE_STMT_ERR()  if (strcmp(stmt->error_code, PDO_ERR_NONE)) { pdo_handle_error(stmt->dbh, stmt TSRMLS_CC); }
diff --git a/ext/pdo/tests/bug_34687.phpt b/ext/pdo/tests/bug_34687.phpt
new file mode 100644 (file)
index 0000000..3ab7818
--- /dev/null
@@ -0,0 +1,32 @@
+--TEST--
+PDO Common: PHP Bug #34687: query doesn't return error information
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) die('skip');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+require_once $dir . 'pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+$db = PDOTest::factory();
+
+$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);
+$x = $db->query("UPDATE non_existent_pdo_test_table set foo = 'bar'");
+
+var_dump($x);
+$code = $db->errorCode();
+if ($code !== '00000' && strlen($code)) {
+       echo "OK: $code\n";
+} else {
+       echo "ERR: $code\n";
+       print_r($db->errorInfo());
+}
+
+?>
+--EXPECTF--
+bool(false)
+OK: %s