Browse Source

Fix Bug #34687; error information from query() not passed back

PHP-5.1
Wez Furlong 21 years ago
parent
commit
a750f195cd
  1. 25
      ext/pdo/pdo_dbh.c
  2. 10
      ext/pdo/php_pdo_driver.h
  3. 8
      ext/pdo/php_pdo_int.h
  4. 32
      ext/pdo/tests/bug_34687.phpt

25
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;
}
/* }}} */

10
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 */

8
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); }

32
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
Loading…
Cancel
Save