summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
Diffstat (limited to 'ext')
-rwxr-xr-xext/pdo/pdo_dbh.c25
-rwxr-xr-xext/pdo/php_pdo_driver.h10
-rwxr-xr-xext/pdo/php_pdo_int.h8
-rw-r--r--ext/pdo/tests/bug_34687.phpt32
4 files changed, 63 insertions, 12 deletions
diff --git a/ext/pdo/pdo_dbh.c b/ext/pdo/pdo_dbh.c
index c2ed2508c7..8769a3c4fb 100755
--- a/ext/pdo/pdo_dbh.c
+++ b/ext/pdo/pdo_dbh.c
@@ -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;
}
/* }}} */
diff --git a/ext/pdo/php_pdo_driver.h b/ext/pdo/php_pdo_driver.h
index 15efc314c8..26ecdd89b2 100755
--- a/ext/pdo/php_pdo_driver.h
+++ b/ext/pdo/php_pdo_driver.h
@@ -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 */
diff --git a/ext/pdo/php_pdo_int.h b/ext/pdo/php_pdo_int.h
index b0b6525412..e7c2487b58 100755
--- a/ext/pdo/php_pdo_int.h
+++ b/ext/pdo/php_pdo_int.h
@@ -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
index 0000000000..3ab78189d6
--- /dev/null
+++ b/ext/pdo/tests/bug_34687.phpt
@@ -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