}
PDO_CONSTRUCT_CHECK;
+ if (dbh->query_stmt) {
+ RETURN_STRING(dbh->query_stmt->error_code, 1);
+ }
+
RETURN_STRING(dbh->error_code, 1);
}
/* }}} */
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);
}
}
/* }}} */
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)) {
}
}
/* 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;
}
/* }}} */
# define FALSE 0
#endif
-#define PDO_DRIVER_API 20050711
+#define PDO_DRIVER_API 20051002
enum pdo_param_type {
PDO_PARAM_NULL,
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 */
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); }
--- /dev/null
+--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