From a750f195cd2cb54286b237ec2bfff3cfe5753240 Mon Sep 17 00:00:00 2001 From: Wez Furlong Date: Sun, 2 Oct 2005 22:11:19 +0000 Subject: [PATCH] Fix Bug #34687; error information from query() not passed back --- ext/pdo/pdo_dbh.c | 25 ++++++++++++++++--------- ext/pdo/php_pdo_driver.h | 10 ++++++++-- ext/pdo/php_pdo_int.h | 8 +++++++- ext/pdo/tests/bug_34687.phpt | 32 ++++++++++++++++++++++++++++++++ 4 files changed, 63 insertions(+), 12 deletions(-) create mode 100644 ext/pdo/tests/bug_34687.phpt 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-- + +--FILE-- +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 -- 2.40.0