summaryrefslogtreecommitdiff
path: root/ext/pdo
diff options
context:
space:
mode:
Diffstat (limited to 'ext/pdo')
-rwxr-xr-xext/pdo/config.m44
-rwxr-xr-xext/pdo/pdo.c73
-rwxr-xr-xext/pdo/pdo_dbh.c174
-rwxr-xr-xext/pdo/pdo_stmt.c80
-rwxr-xr-xext/pdo/php_pdo.h17
-rwxr-xr-xext/pdo/php_pdo_driver.h19
-rwxr-xr-xext/pdo/php_pdo_int.h4
-rwxr-xr-xext/pdo/tests/bug_36428.phpt33
-rw-r--r--ext/pdo/tests/bug_38253.phpt47
-rw-r--r--ext/pdo/tests/bug_38394.phpt51
-rw-r--r--ext/pdo/tests/pdo_017.phpt9
-rw-r--r--ext/pdo/tests/pdo_026.phpt2
-rwxr-xr-xext/pdo/tests/pdo_029.phpt2
-rwxr-xr-xext/pdo/tests/pdo_030.phpt37
-rwxr-xr-xext/pdo/tests/pdo_031.phpt2
-rw-r--r--ext/pdo/tests/pdo_033.phpt39
-rw-r--r--ext/pdo/tests/pdo_test.inc6
17 files changed, 417 insertions, 182 deletions
diff --git a/ext/pdo/config.m4 b/ext/pdo/config.m4
index e275fecf6..9497f12da 100755
--- a/ext/pdo/config.m4
+++ b/ext/pdo/config.m4
@@ -1,4 +1,4 @@
-dnl $Id: config.m4,v 1.15.2.3 2005/11/24 21:38:09 wez Exp $
+dnl $Id: config.m4,v 1.15.2.3.2.1 2006/08/24 16:00:43 tony2001 Exp $
dnl config.m4 for extension pdo
dnl vim:se ts=2 sw=2 et:
@@ -37,7 +37,6 @@ if test "$PHP_PDO" != "no"; then
if test "$ext_shared" = "yes" ; then
case $host_alias in
*darwin*)
- if test "$pdo_running_under_pear" = "1"; then
AC_MSG_ERROR([
Due to the way that loadable modules work on OSX/Darwin, you need to
compile the PDO package statically into the PHP core.
@@ -45,7 +44,6 @@ compile the PDO package statically into the PHP core.
Please follow the instructions at: http://netevil.org/node.php?nid=202
for more detail on this issue.
])
- fi
ext_shared=no
;;
esac
diff --git a/ext/pdo/pdo.c b/ext/pdo/pdo.c
index 10ece60c7..d6786c4c8 100755
--- a/ext/pdo/pdo.c
+++ b/ext/pdo/pdo.c
@@ -18,7 +18,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: pdo.c,v 1.57.2.17 2006/01/01 12:50:11 sniper Exp $ */
+/* $Id: pdo.c,v 1.57.2.17.2.7 2006/10/14 15:06:11 bjori Exp $ */
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -36,6 +36,7 @@
static zend_class_entry *spl_ce_RuntimeException;
ZEND_DECLARE_MODULE_GLOBALS(pdo)
+static PHP_GINIT_FUNCTION(pdo);
/* True global resources - no need for thread safety here */
@@ -53,11 +54,23 @@ int php_pdo_list_entry(void)
/* for exceptional circumstances */
zend_class_entry *pdo_exception_ce;
-PDO_API zend_class_entry *php_pdo_get_exception(void)
+PDO_API zend_class_entry *php_pdo_get_dbh_ce()
+{
+ return pdo_dbh_ce;
+}
+
+PDO_API zend_class_entry *php_pdo_get_exception()
{
return pdo_exception_ce;
}
+PDO_API char *php_pdo_str_tolower_dup(const char *src, int len)
+{
+ char *dest = emalloc(len + 1);
+ zend_str_tolower_copy(dest, src, len);
+ return dest;
+}
+
PDO_API zend_class_entry *php_pdo_get_exception_base(int root TSRMLS_DC)
{
#if can_handle_soft_dependency_on_SPL && defined(HAVE_SPL) && ((PHP_MAJOR_VERSION > 5) || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 1))
@@ -74,7 +87,7 @@ PDO_API zend_class_entry *php_pdo_get_exception_base(int root TSRMLS_DC)
}
}
#endif
-#if (PHP_MAJOR_VERSION < 6)
+#if (PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION < 2)
return zend_exception_get_default();
#else
return zend_exception_get_default(TSRMLS_C);
@@ -83,7 +96,7 @@ PDO_API zend_class_entry *php_pdo_get_exception_base(int root TSRMLS_DC)
zend_class_entry *pdo_dbh_ce, *pdo_dbstmt_ce, *pdo_row_ce;
-/* proto array pdo_drivers()
+/* {{{ proto array pdo_drivers()
Return array of available PDO drivers */
PHP_FUNCTION(pdo_drivers)
{
@@ -130,26 +143,27 @@ zend_module_entry pdo_module_entry = {
pdo_functions,
PHP_MINIT(pdo),
PHP_MSHUTDOWN(pdo),
- PHP_RINIT(pdo),
- PHP_RSHUTDOWN(pdo),
+ NULL,
+ NULL,
PHP_MINFO(pdo),
- "1.0.3",
- STANDARD_MODULE_PROPERTIES
+ "1.0.4dev",
+ PHP_MODULE_GLOBALS(pdo),
+ PHP_GINIT(pdo),
+ NULL,
+ NULL,
+ STANDARD_MODULE_PROPERTIES_EX
};
/* }}} */
+/* TODO: visit persistent handles: for each persistent statement handle,
+ * remove bound parameter associations */
+
#ifdef COMPILE_DL_PDO
ZEND_GET_MODULE(pdo)
#endif
-/* {{{ PHP_INI */
-PHP_INI_BEGIN()
- STD_PHP_INI_ENTRY("pdo.global_value", "42", PHP_INI_ALL, OnUpdateLong, global_value, zend_pdo_globals, pdo_globals)
-PHP_INI_END()
-/* }}} */
-
-/* {{{ php_pdo_init_globals */
-static void php_pdo_init_globals(zend_pdo_globals *pdo_globals)
+/* {{{ PHP_GINIT_FUNCTION */
+static PHP_GINIT_FUNCTION(pdo)
{
pdo_globals->global_value = 0;
}
@@ -303,11 +317,8 @@ PDO_API char *php_pdo_int64_to_str(pdo_int64_t i64 TSRMLS_DC)
PHP_MINIT_FUNCTION(pdo)
{
zend_class_entry ce;
-
- spl_ce_RuntimeException = NULL;
- ZEND_INIT_MODULE_GLOBALS(pdo, php_pdo_init_globals, NULL);
- REGISTER_INI_ENTRIES();
+ spl_ce_RuntimeException = NULL;
if (FAILURE == pdo_sqlstate_init_error_table()) {
return FAILURE;
@@ -334,29 +345,12 @@ PHP_MINIT_FUNCTION(pdo)
/* {{{ PHP_MSHUTDOWN_FUNCTION */
PHP_MSHUTDOWN_FUNCTION(pdo)
{
- UNREGISTER_INI_ENTRIES();
zend_hash_destroy(&pdo_driver_hash);
pdo_sqlstate_fini_error_table();
return SUCCESS;
}
/* }}} */
-/* {{{ PHP_RINIT_FUNCTION */
-PHP_RINIT_FUNCTION(pdo)
-{
- return SUCCESS;
-}
-/* }}} */
-
-/* {{{ PHP_RSHUTDOWN_FUNCTION */
-PHP_RSHUTDOWN_FUNCTION(pdo)
-{
- /* TODO: visit persistent handles: for each persistent statement handle,
- * remove bound parameter associations */
- return SUCCESS;
-}
-/* }}} */
-
/* {{{ PHP_MINFO_FUNCTION */
PHP_MINFO_FUNCTION(pdo)
{
@@ -379,13 +373,12 @@ PHP_MINFO_FUNCTION(pdo)
if (drivers) {
efree(drivers);
+ } else {
+ efree(ldrivers);
}
php_info_print_table_end();
-#if 0
- DISPLAY_INI_ENTRIES();
-#endif
}
/* }}} */
diff --git a/ext/pdo/pdo_dbh.c b/ext/pdo/pdo_dbh.c
index cbf443bc9..ec6d88041 100755
--- a/ext/pdo/pdo_dbh.c
+++ b/ext/pdo/pdo_dbh.c
@@ -18,7 +18,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: pdo_dbh.c,v 1.82.2.31 2006/05/03 21:58:38 pollita Exp $ */
+/* $Id: pdo_dbh.c,v 1.82.2.31.2.7 2006/08/21 16:53:50 iliaa Exp $ */
/* The PDO Database Handle Class */
@@ -36,12 +36,13 @@
#include "zend_object_handlers.h"
#include "zend_hash.h"
-void pdo_raise_impl_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, const char *sqlstate, const char *supp TSRMLS_DC)
+static int pdo_dbh_attribute_set(pdo_dbh_t *dbh, long attr, zval *value TSRMLS_DC);
+
+void pdo_raise_impl_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, const char *sqlstate, const char *supp TSRMLS_DC) /* {{{ */
{
pdo_error_type *pdo_err = &dbh->error_code;
char *message = NULL;
const char *msg;
-
if (dbh->error_mode == PDO_ERRMODE_SILENT) {
#if 0
@@ -98,8 +99,9 @@ void pdo_raise_impl_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, const char *sqlstate
efree(message);
}
}
+/* }}} */
-void pdo_handle_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt TSRMLS_DC)
+void pdo_handle_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt TSRMLS_DC) /* {{{ */
{
pdo_error_type *pdo_err = &dbh->error_code;
const char *msg = "<<Unknown>>";
@@ -178,8 +180,9 @@ void pdo_handle_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt TSRMLS_DC)
efree(supp);
}
}
+/* }}} */
-static char *dsn_from_uri(char *uri, char *buf, size_t buflen TSRMLS_DC)
+static char *dsn_from_uri(char *uri, char *buf, size_t buflen TSRMLS_DC) /* {{{ */
{
php_stream *stream;
char *dsn = NULL;
@@ -191,6 +194,7 @@ static char *dsn_from_uri(char *uri, char *buf, size_t buflen TSRMLS_DC)
}
return dsn;
}
+/* }}} */
/* {{{ proto void PDO::__construct(string dsn, string username, string passwd [, array options])
*/
@@ -270,7 +274,7 @@ static PHP_METHOD(PDO, dbh_constructor)
/* is this supposed to be a persistent connection ? */
if (options) {
zval **v;
- int plen;
+ int plen = 0;
char *hashkey = NULL;
zend_rsrc_list_entry *le;
pdo_dbh_t *pdbh = NULL;
@@ -338,7 +342,9 @@ static PHP_METHOD(PDO, dbh_constructor)
/* switch over to the persistent one */
dbh = pdbh;
zend_object_store_set_object(object, dbh TSRMLS_CC);
- dbh->refcount++;
+ if (!call_factory) {
+ dbh->refcount++;
+ }
}
if (hashkey) {
@@ -350,6 +356,7 @@ static PHP_METHOD(PDO, dbh_constructor)
dbh->data_source = (const char*)pestrdup(colon + 1, is_persistent);
dbh->username = username ? pestrdup(username, is_persistent) : NULL;
dbh->password = password ? pestrdup(password, is_persistent) : NULL;
+ dbh->default_fetch_type = PDO_FETCH_BOTH;
dbh->auto_commit = pdo_attr_lval(options, PDO_ATTR_AUTOCOMMIT, 1 TSRMLS_CC);
@@ -383,6 +390,21 @@ static PHP_METHOD(PDO, dbh_constructor)
}
dbh->driver = driver;
+
+ if (options) {
+ zval **attr_value;
+ char *str_key;
+ long long_key;
+
+ zend_hash_internal_pointer_reset(Z_ARRVAL_P(options));
+ while (SUCCESS == zend_hash_get_current_data(Z_ARRVAL_P(options), (void**)&attr_value)
+ && HASH_KEY_IS_LONG == zend_hash_get_current_key(Z_ARRVAL_P(options), &str_key, &long_key, 0)) {
+
+ pdo_dbh_attribute_set(dbh, long_key, *attr_value TSRMLS_CC);
+ zend_hash_move_forward(Z_ARRVAL_P(options));
+ }
+ }
+
return;
}
@@ -497,7 +519,7 @@ static PHP_METHOD(PDO, prepare)
|| zend_lookup_class(Z_STRVAL_PP(item), Z_STRLEN_PP(item), &pce TSRMLS_CC) == FAILURE
) {
pdo_raise_impl_error(dbh, NULL, "HY000",
- "PDO::ATTR_STATEMENT_CLASS requires format array(classname, ctor_args); "
+ "PDO::ATTR_STATEMENT_CLASS requires format array(classname, array(ctor_args)); "
"the classname must be a string specifying an existing class"
TSRMLS_CC);
PDO_HANDLE_DBH_ERR();
@@ -546,10 +568,11 @@ static PHP_METHOD(PDO, prepare)
/* unconditionally keep this for later reference */
stmt->query_string = estrndup(statement, statement_len);
stmt->query_stringlen = statement_len;
- stmt->default_fetch_type = PDO_FETCH_BOTH;
+ stmt->default_fetch_type = dbh->default_fetch_type;
stmt->dbh = dbh;
/* give it a reference to me */
zend_objects_store_add_ref(getThis() TSRMLS_CC);
+ php_pdo_dbh_addref(dbh TSRMLS_CC);
stmt->database_object_handle = *getThis();
/* we haven't created a lazy object yet */
ZVAL_NULL(&stmt->lazy_object_ref);
@@ -644,20 +667,8 @@ static PHP_METHOD(PDO, rollBack)
}
/* }}} */
-/* {{{ proto bool PDO::setAttribute(long attribute, mixed value)
- Set an attribute */
-static PHP_METHOD(PDO, setAttribute)
+static int pdo_dbh_attribute_set(pdo_dbh_t *dbh, long attr, zval *value TSRMLS_DC) /* {{{ */
{
- pdo_dbh_t *dbh = zend_object_store_get_object(getThis() TSRMLS_CC);
- long attr;
- zval *value = NULL;
-
- if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lz!", &attr, &value)) {
- RETURN_FALSE;
- }
-
- PDO_CONSTRUCT_CHECK;
-
switch (attr) {
case PDO_ATTR_ERRMODE:
convert_to_long(value);
@@ -666,13 +677,13 @@ static PHP_METHOD(PDO, setAttribute)
case PDO_ERRMODE_WARNING:
case PDO_ERRMODE_EXCEPTION:
dbh->error_mode = Z_LVAL_P(value);
- RETURN_TRUE;
+ return SUCCESS;
default:
pdo_raise_impl_error(dbh, NULL, "HY000", "invalid error mode" TSRMLS_CC);
PDO_HANDLE_DBH_ERR();
- RETURN_FALSE;
+ return FAILURE;
}
- RETURN_FALSE;
+ return FAILURE;
case PDO_ATTR_CASE:
convert_to_long(value);
@@ -681,23 +692,32 @@ static PHP_METHOD(PDO, setAttribute)
case PDO_CASE_UPPER:
case PDO_CASE_LOWER:
dbh->desired_case = Z_LVAL_P(value);
- RETURN_TRUE;
+ return SUCCESS;
default:
pdo_raise_impl_error(dbh, NULL, "HY000", "invalid case folding mode" TSRMLS_CC);
PDO_HANDLE_DBH_ERR();
- RETURN_FALSE;
+ return FAILURE;
}
- RETURN_FALSE;
+ return FAILURE;
case PDO_ATTR_ORACLE_NULLS:
convert_to_long(value);
dbh->oracle_nulls = Z_LVAL_P(value);
- RETURN_TRUE;
+ return SUCCESS;
+
+ case PDO_ATTR_DEFAULT_FETCH_MODE:
+ convert_to_long(value);
+ if (Z_LVAL_P(value) == PDO_FETCH_USE_DEFAULT) {
+ pdo_raise_impl_error(dbh, NULL, "HY000", "invalid fetch mode type" TSRMLS_CC);
+ return FAILURE;
+ }
+ dbh->default_fetch_type = Z_LVAL_P(value);
+ return SUCCESS;
case PDO_ATTR_STRINGIFY_FETCHES:
convert_to_long(value);
dbh->stringify = Z_LVAL_P(value) ? 1 : 0;
- RETURN_TRUE;
+ return SUCCESS;
case PDO_ATTR_STATEMENT_CLASS: {
/* array(string classname, array(mixed ctor_args)) */
@@ -709,7 +729,7 @@ static PHP_METHOD(PDO, setAttribute)
"PDO::ATTR_STATEMENT_CLASS cannot be used with persistent PDO instances"
TSRMLS_CC);
PDO_HANDLE_DBH_ERR();
- RETURN_FALSE;
+ return FAILURE;
}
if (Z_TYPE_P(value) != IS_ARRAY
|| zend_hash_index_find(Z_ARRVAL_P(value), 0, (void**)&item) == FAILURE
@@ -721,19 +741,19 @@ static PHP_METHOD(PDO, setAttribute)
"the classname must be a string specifying an existing class"
TSRMLS_CC);
PDO_HANDLE_DBH_ERR();
- RETURN_FALSE;
+ return FAILURE;
}
if (!instanceof_function(*pce, pdo_dbstmt_ce TSRMLS_CC)) {
pdo_raise_impl_error(dbh, NULL, "HY000",
"user-supplied statement class must be derived from PDOStatement" TSRMLS_CC);
PDO_HANDLE_DBH_ERR();
- RETURN_FALSE;
+ return FAILURE;
}
if ((*pce)->constructor && !((*pce)->constructor->common.fn_flags & (ZEND_ACC_PRIVATE|ZEND_ACC_PROTECTED))) {
pdo_raise_impl_error(dbh, NULL, "HY000",
"user-supplied statement class cannot have a public constructor" TSRMLS_CC);
PDO_HANDLE_DBH_ERR();
- RETURN_FALSE;
+ return FAILURE;
}
dbh->def_stmt_ce = *pce;
if (dbh->def_stmt_ctor_args) {
@@ -747,12 +767,12 @@ static PHP_METHOD(PDO, setAttribute)
"ctor_args must be an array"
TSRMLS_CC);
PDO_HANDLE_DBH_ERR();
- RETURN_FALSE;
+ return FAILURE;
}
(*item)->refcount++;
dbh->def_stmt_ctor_args = *item;
}
- RETURN_TRUE;
+ return SUCCESS;
}
default:
@@ -765,7 +785,7 @@ static PHP_METHOD(PDO, setAttribute)
PDO_DBH_CLEAR_ERR();
if (dbh->methods->set_attribute(dbh, attr, value TSRMLS_CC)) {
- RETURN_TRUE;
+ return SUCCESS;
}
fail:
@@ -776,7 +796,28 @@ fail:
} else {
PDO_HANDLE_DBH_ERR();
}
- RETURN_FALSE;
+ return FAILURE;
+}
+/* }}} */
+
+/* {{{ proto bool PDO::setAttribute(long attribute, mixed value)
+ Set an attribute */
+static PHP_METHOD(PDO, setAttribute)
+{
+ pdo_dbh_t *dbh = zend_object_store_get_object(getThis() TSRMLS_CC);
+ long attr;
+ zval *value = NULL;
+
+ if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lz!", &attr, &value)) {
+ RETURN_FALSE;
+ }
+
+ PDO_CONSTRUCT_CHECK;
+
+ if (pdo_dbh_attribute_set(dbh, attr, value TSRMLS_CC)) {
+ RETURN_TRUE;
+ }
+ RETURN_FALSE;
}
/* }}} */
@@ -819,6 +860,9 @@ static PHP_METHOD(PDO, getAttribute)
add_next_index_zval(return_value, dbh->def_stmt_ctor_args);
}
return;
+ case PDO_ATTR_DEFAULT_FETCH_MODE:
+ RETURN_LONG(dbh->default_fetch_type);
+
}
if (!dbh->methods->get_attribute) {
@@ -968,18 +1012,22 @@ static PHP_METHOD(PDO, query)
/* unconditionally keep this for later reference */
stmt->query_string = estrndup(statement, statement_len);
stmt->query_stringlen = statement_len;
- stmt->default_fetch_type = PDO_FETCH_BOTH;
+
+ stmt->default_fetch_type = dbh->default_fetch_type;
stmt->active_query_string = stmt->query_string;
stmt->active_query_stringlen = statement_len;
stmt->dbh = dbh;
/* give it a reference to me */
zend_objects_store_add_ref(getThis() TSRMLS_CC);
+ php_pdo_dbh_addref(dbh TSRMLS_CC);
stmt->database_object_handle = *getThis();
/* we haven't created a lazy object yet */
ZVAL_NULL(&stmt->lazy_object_ref);
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)) {
@@ -1075,8 +1123,8 @@ static PHP_METHOD(PDO, getAvailableDrivers)
zend_function_entry pdo_dbh_functions[] = {
ZEND_MALIAS(PDO, __construct, dbh_constructor, NULL, ZEND_ACC_PUBLIC)
- PHP_ME(PDO, prepare, NULL, ZEND_ACC_PUBLIC)
- PHP_ME(PDO, beginTransaction,NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(PDO, prepare, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(PDO, beginTransaction, NULL, ZEND_ACC_PUBLIC)
PHP_ME(PDO, commit, NULL, ZEND_ACC_PUBLIC)
PHP_ME(PDO, rollBack, NULL, ZEND_ACC_PUBLIC)
PHP_ME(PDO, setAttribute, NULL, ZEND_ACC_PUBLIC)
@@ -1202,33 +1250,14 @@ static int dbh_compare(zval *object1, zval *object2 TSRMLS_DC)
return -1;
}
-static zend_object_handlers pdo_dbh_object_handlers;
-
-PDO_API void php_pdo_declare_stringl_constant(const char *const_name,
- size_t name_len, const char *value, size_t value_len TSRMLS_DC)
+static zend_object_value dbh_ze1_clone_obj(zval *object TSRMLS_DC)
{
-#if PHP_MAJOR_VERSION > 5 || PHP_MINOR_VERSION >= 1
- zend_declare_class_constant_stringl(pdo_dbh_ce, (char*)const_name, name_len, (char*)value, value_len TSRMLS_CC);
-#else
- zval *constant = malloc(sizeof(*constant));
- ZVAL_STRINGL(constant, zend_strndup(value, value_len), value_len, 0);
- INIT_PZVAL(constant);
- zend_hash_update(&pdo_dbh_ce->constants_table, (char*)const_name, name_len+1, &constant, sizeof(zval*), NULL);
-#endif
+ php_error(E_ERROR, "Cannot clone object of class %s due to 'zend.ze1_compatibility_mode'", Z_OBJCE_P(object)->name);
+ return object->value.obj;
}
-PDO_API void php_pdo_declare_long_constant(const char *const_name,
- size_t name_len, long value TSRMLS_DC)
-{
-#if PHP_MAJOR_VERSION > 5 || PHP_MINOR_VERSION >= 1
- zend_declare_class_constant_long(pdo_dbh_ce, (char*)const_name, name_len, value TSRMLS_CC);
-#else
- zval *constant = malloc(sizeof(*constant));
- ZVAL_LONG(constant, value);
- INIT_PZVAL(constant);
- zend_hash_update(&pdo_dbh_ce->constants_table, (char*)const_name, name_len+1, &constant, sizeof(zval*), NULL);
-#endif
-}
+static zend_object_handlers pdo_dbh_object_handlers;
+static zend_object_handlers pdo_dbh_object_handlers_ze1;
void pdo_dbh_init(TSRMLS_D)
{
@@ -1241,6 +1270,11 @@ void pdo_dbh_init(TSRMLS_D)
memcpy(&pdo_dbh_object_handlers, &std_object_handlers, sizeof(zend_object_handlers));
pdo_dbh_object_handlers.get_method = dbh_method_get;
pdo_dbh_object_handlers.compare_objects = dbh_compare;
+
+ memcpy(&pdo_dbh_object_handlers_ze1, &std_object_handlers, sizeof(zend_object_handlers));
+ pdo_dbh_object_handlers_ze1.get_method = dbh_method_get;
+ pdo_dbh_object_handlers_ze1.compare_objects = dbh_compare;
+ pdo_dbh_object_handlers_ze1.clone_obj = dbh_ze1_clone_obj;
REGISTER_PDO_CLASS_CONST_LONG("PARAM_BOOL", (long)PDO_PARAM_BOOL);
REGISTER_PDO_CLASS_CONST_LONG("PARAM_NULL", (long)PDO_PARAM_NULL);
@@ -1274,6 +1308,7 @@ void pdo_dbh_init(TSRMLS_D)
#if PHP_MAJOR_VERSION > 5 || PHP_MINOR_VERSION >= 1
REGISTER_PDO_CLASS_CONST_LONG("FETCH_SERIALIZE",(long)PDO_FETCH_SERIALIZE);
#endif
+ REGISTER_PDO_CLASS_CONST_LONG("FETCH_PROPS_LATE",(long)PDO_FETCH_PROPS_LATE);
REGISTER_PDO_CLASS_CONST_LONG("FETCH_NAMED",(long)PDO_FETCH_NAMED);
REGISTER_PDO_CLASS_CONST_LONG("ATTR_AUTOCOMMIT", (long)PDO_ATTR_AUTOCOMMIT);
@@ -1296,6 +1331,7 @@ void pdo_dbh_init(TSRMLS_D)
REGISTER_PDO_CLASS_CONST_LONG("ATTR_STRINGIFY_FETCHES",(long)PDO_ATTR_STRINGIFY_FETCHES);
REGISTER_PDO_CLASS_CONST_LONG("ATTR_MAX_COLUMN_LEN",(long)PDO_ATTR_MAX_COLUMN_LEN);
REGISTER_PDO_CLASS_CONST_LONG("ATTR_EMULATE_PREPARES",(long)PDO_ATTR_EMULATE_PREPARES);
+ REGISTER_PDO_CLASS_CONST_LONG("ATTR_DEFAULT_FETCH_MODE",(long)PDO_ATTR_DEFAULT_FETCH_MODE);
REGISTER_PDO_CLASS_CONST_LONG("ERRMODE_SILENT", (long)PDO_ERRMODE_SILENT);
REGISTER_PDO_CLASS_CONST_LONG("ERRMODE_WARNING", (long)PDO_ERRMODE_WARNING);
@@ -1339,7 +1375,7 @@ void pdo_dbh_init(TSRMLS_D)
static void dbh_free(pdo_dbh_t *dbh TSRMLS_DC)
{
int i;
-
+
if (--dbh->refcount)
return;
@@ -1361,6 +1397,10 @@ static void dbh_free(pdo_dbh_t *dbh TSRMLS_DC)
if (dbh->password) {
pefree(dbh->password, dbh->is_persistent);
}
+
+ if (dbh->persistent_id) {
+ pefree((char *)dbh->persistent_id, dbh->is_persistent);
+ }
if (dbh->def_stmt_ctor_args) {
zval_ptr_dtor(&dbh->def_stmt_ctor_args);
@@ -1422,7 +1462,7 @@ zend_object_value pdo_dbh_new(zend_class_entry *ce TSRMLS_DC)
dbh->def_stmt_ce = pdo_dbstmt_ce;
retval.handle = zend_objects_store_put(dbh, (zend_objects_store_dtor_t)zend_objects_destroy_object, (zend_objects_free_object_storage_t)pdo_dbh_free_storage, NULL TSRMLS_CC);
- retval.handlers = &pdo_dbh_object_handlers;
+ retval.handlers = EG(ze1_compatibility_mode) ? &pdo_dbh_object_handlers_ze1 : &pdo_dbh_object_handlers;
return retval;
}
diff --git a/ext/pdo/pdo_stmt.c b/ext/pdo/pdo_stmt.c
index a9f65e28d..a837a14f0 100755
--- a/ext/pdo/pdo_stmt.c
+++ b/ext/pdo/pdo_stmt.c
@@ -18,7 +18,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: pdo_stmt.c,v 1.118.2.38 2006/04/22 19:10:53 tony2001 Exp $ */
+/* $Id: pdo_stmt.c,v 1.118.2.38.2.8 2006/08/23 19:15:57 tony2001 Exp $ */
/* The PDO Statement Handle Class */
@@ -392,6 +392,12 @@ static PHP_METHOD(PDOStatement, execute)
zval **tmp;
uint str_length;
ulong num_index;
+
+ if (stmt->bound_params) {
+ zend_hash_destroy(stmt->bound_params);
+ FREE_HASHTABLE(stmt->bound_params);
+ stmt->bound_params = NULL;
+ }
zend_hash_internal_pointer_reset(Z_ARRVAL_P(input_params));
while (SUCCESS == zend_hash_get_current_data(Z_ARRVAL_P(input_params), (void*)&tmp)) {
@@ -703,8 +709,8 @@ static int do_fetch_class_prepare(pdo_stmt_t *stmt TSRMLS_DC) /* {{{ */
static int make_callable_ex(pdo_stmt_t *stmt, zval *callable, zend_fcall_info * fci, zend_fcall_info_cache * fcc, int num_args TSRMLS_DC) /* {{{ */
{
- zval **object = NULL, **method;
- char *fname, *cname;
+ zval **object = NULL, **method = NULL;
+ char *fname = NULL, *cname;
zend_class_entry * ce = NULL, **pce;
zend_function *function_handler;
@@ -717,6 +723,12 @@ static int make_callable_ex(pdo_stmt_t *stmt, zval *callable, zend_fcall_info *
method = (zval**)Z_ARRVAL_P(callable)->pListHead->pListNext->pData;
if (Z_TYPE_PP(object) == IS_STRING) { /* static call */
+ if (zend_lookup_class(Z_STRVAL_PP(object), Z_STRLEN_PP(object), &pce TSRMLS_CC) == FAILURE) {
+ pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "user-supplied class does not exist" TSRMLS_CC);
+ return 0;
+ } else {
+ ce = *pce;
+ }
object = NULL;
} else if (Z_TYPE_PP(object) == IS_OBJECT) { /* object call */
ce = Z_OBJCE_PP(object);
@@ -729,10 +741,15 @@ static int make_callable_ex(pdo_stmt_t *stmt, zval *callable, zend_fcall_info *
pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "user-supplied function must be a valid callback; bogus method name" TSRMLS_CC);
return 0;
}
+ } else if (Z_TYPE_P(callable) == IS_STRING) {
+ method = &callable;
}
- if (!zend_is_callable(callable, 0, &fname)) {
+ if (!method || !zend_is_callable(callable, 0, &fname)) {
pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "user-supplied function must be a valid callback" TSRMLS_CC);
+ if (fname) {
+ efree(fname);
+ }
return 0;
}
@@ -825,9 +842,9 @@ static int do_fetch_opt_finish(pdo_stmt_t *stmt, int free_ctor_agrs TSRMLS_DC) /
static int do_fetch(pdo_stmt_t *stmt, int do_bind, zval *return_value,
enum pdo_fetch_type how, enum pdo_fetch_orientation ori, long offset, zval *return_all TSRMLS_DC) /* {{{ */
{
- int flags = how & PDO_FETCH_FLAGS, idx, old_arg_count;
- zend_class_entry * ce, * old_ce;
- zval grp_val, *grp, **pgrp, *retval, *old_ctor_args;
+ int flags = how & PDO_FETCH_FLAGS, idx, old_arg_count = 0;
+ zend_class_entry *ce = NULL, *old_ce = NULL;
+ zval grp_val, *grp, **pgrp, *retval, *old_ctor_args = NULL;
how = how & ~PDO_FETCH_FLAGS;
if (how == PDO_FETCH_USE_DEFAULT) {
@@ -854,13 +871,14 @@ static int do_fetch(pdo_stmt_t *stmt, int do_bind, zval *return_value,
RETVAL_FALSE;
switch (how) {
+ case PDO_FETCH_USE_DEFAULT:
case PDO_FETCH_ASSOC:
case PDO_FETCH_BOTH:
case PDO_FETCH_NUM:
case PDO_FETCH_NAMED:
if (!return_all) {
ALLOC_HASHTABLE(return_value->value.ht);
- zend_hash_init(return_value->value.ht, stmt->column_count, NULL, ZVAL_PTR_DTOR, 0);
+ zend_hash_init(return_value->value.ht, stmt->column_count, NULL, ZVAL_PTR_DTOR, 0);
Z_TYPE_P(return_value) = IS_ARRAY;
} else {
array_init(return_value);
@@ -907,6 +925,10 @@ static int do_fetch(pdo_stmt_t *stmt, int do_bind, zval *return_value,
zval_dtor(&val);
}
ce = stmt->fetch.cls.ce;
+ if (!ce) {
+ pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "No fetch class specified" TSRMLS_CC);
+ return 0;
+ }
if ((flags & PDO_FETCH_SERIALIZE) == 0) {
object_init_ex(return_value, ce);
if (!stmt->fetch.cls.fci.size) {
@@ -915,6 +937,18 @@ static int do_fetch(pdo_stmt_t *stmt, int do_bind, zval *return_value,
return 0;
}
}
+ if (ce->constructor && (flags & PDO_FETCH_PROPS_LATE)) {
+ stmt->fetch.cls.fci.object_pp = &return_value;
+ stmt->fetch.cls.fcc.object_pp = &return_value;
+ if (zend_call_function(&stmt->fetch.cls.fci, &stmt->fetch.cls.fcc TSRMLS_CC) == FAILURE) {
+ pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "could not call class constructor" TSRMLS_CC);
+ return 0;
+ } else {
+ if (stmt->fetch.cls.retval_ptr) {
+ zval_ptr_dtor(&stmt->fetch.cls.retval_ptr);
+ }
+ }
+ }
}
break;
@@ -936,6 +970,10 @@ static int do_fetch(pdo_stmt_t *stmt, int do_bind, zval *return_value,
break;
case PDO_FETCH_FUNC:
+ if (!stmt->fetch.func.function) {
+ pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "No fetch function specified" TSRMLS_CC);
+ return 0;
+ }
if (!stmt->fetch.func.fci.size) {
if (!do_fetch_func_prepare(stmt TSRMLS_CC))
{
@@ -971,6 +1009,7 @@ static int do_fetch(pdo_stmt_t *stmt, int do_bind, zval *return_value,
add_assoc_zval(return_value, stmt->columns[i].name, val);
break;
+ case PDO_FETCH_USE_DEFAULT:
case PDO_FETCH_BOTH:
add_assoc_zval(return_value, stmt->columns[i].name, val);
ZVAL_ADDREF(val);
@@ -1077,7 +1116,7 @@ static int do_fetch(pdo_stmt_t *stmt, int do_bind, zval *return_value,
switch (how) {
case PDO_FETCH_CLASS:
- if (ce->constructor) {
+ if (ce->constructor && !(flags & PDO_FETCH_PROPS_LATE)) {
stmt->fetch.cls.fci.object_pp = &return_value;
stmt->fetch.cls.fcc.object_pp = &return_value;
if (zend_call_function(&stmt->fetch.cls.fci, &stmt->fetch.cls.fcc TSRMLS_CC) == FAILURE) {
@@ -1505,7 +1544,11 @@ static int register_bound_param(INTERNAL_FUNCTION_PARAMETERS, pdo_stmt_t *stmt,
}
ZVAL_ADDREF(param.parameter);
- return really_register_bound_param(&param, stmt, is_param TSRMLS_CC);
+ if (!really_register_bound_param(&param, stmt, is_param TSRMLS_CC)) {
+ zval_ptr_dtor(&(param.parameter));
+ return 0;
+ }
+ return 1;
} /* }}} */
/* {{{ proto bool PDOStatement::bindValue(mixed $paramno, mixed $param [, int $type ])
@@ -1517,7 +1560,7 @@ static PHP_METHOD(PDOStatement, bindValue)
param.paramno = -1;
param.param_type = PDO_PARAM_STR;
-
+
if (FAILURE == zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC,
"lz/|l", &param.paramno, &param.parameter, &param.param_type)) {
if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz/|l", &param.name,
@@ -1534,7 +1577,11 @@ static PHP_METHOD(PDOStatement, bindValue)
}
ZVAL_ADDREF(param.parameter);
- RETURN_BOOL(really_register_bound_param(&param, stmt, TRUE TSRMLS_CC));
+ if (!really_register_bound_param(&param, stmt, TRUE TSRMLS_CC)) {
+ zval_ptr_dtor(&(param.parameter));
+ RETURN_FALSE;
+ }
+ RETURN_TRUE;
}
/* }}} */
@@ -2225,6 +2272,9 @@ static void free_statement(pdo_stmt_t *stmt TSRMLS_DC)
do_fetch_opt_finish(stmt, 1 TSRMLS_CC);
zend_objects_store_del_ref(&stmt->database_object_handle TSRMLS_CC);
+ if (stmt->dbh) {
+ php_pdo_dbh_delref(stmt->dbh TSRMLS_CC);
+ }
efree(stmt);
}
@@ -2357,11 +2407,15 @@ static zend_object_iterator_funcs pdo_stmt_iter_funcs = {
NULL
};
-zend_object_iterator *pdo_stmt_iter_get(zend_class_entry *ce, zval *object TSRMLS_DC)
+zend_object_iterator *pdo_stmt_iter_get(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC)
{
pdo_stmt_t *stmt = (pdo_stmt_t*)zend_object_store_get_object(object TSRMLS_CC);
struct php_pdo_iterator *I;
+ if (by_ref) {
+ zend_error(E_ERROR, "An iterator cannot be used with foreach by reference");
+ }
+
I = ecalloc(1, sizeof(*I));
I->iter.funcs = &pdo_stmt_iter_funcs;
I->iter.data = I;
diff --git a/ext/pdo/php_pdo.h b/ext/pdo/php_pdo.h
index 74078b4de..31c610c54 100755
--- a/ext/pdo/php_pdo.h
+++ b/ext/pdo/php_pdo.h
@@ -16,7 +16,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: php_pdo.h,v 1.7.2.5 2006/01/01 12:50:11 sniper Exp $ */
+/* $Id: php_pdo.h,v 1.7.2.5.2.2 2006/06/07 21:09:52 rasmus Exp $ */
#ifndef PHP_PDO_H
#define PHP_PDO_H
@@ -48,8 +48,6 @@ extern zend_module_entry pdo_module_entry;
PHP_MINIT_FUNCTION(pdo);
PHP_MSHUTDOWN_FUNCTION(pdo);
-PHP_RINIT_FUNCTION(pdo);
-PHP_RSHUTDOWN_FUNCTION(pdo);
PHP_MINFO_FUNCTION(pdo);
ZEND_BEGIN_MODULE_GLOBALS(pdo)
@@ -62,14 +60,17 @@ ZEND_END_MODULE_GLOBALS(pdo)
# define PDOG(v) (pdo_globals.v)
#endif
-PDO_API void php_pdo_declare_long_constant(const char *const_name, size_t name_len, long value TSRMLS_DC);
-PDO_API void php_pdo_declare_stringl_constant(const char *const_name, size_t name_len, const char *value, size_t value_len TSRMLS_DC);
-
#define REGISTER_PDO_CLASS_CONST_LONG(const_name, value) \
- php_pdo_declare_long_constant(const_name, sizeof(const_name)-1, (long)value TSRMLS_CC);
+ zend_declare_class_constant_long(php_pdo_get_dbh_ce(), const_name, sizeof(const_name)-1, (long)value TSRMLS_CC);
+
+#define REGISTER_PDO_CONST_LONG(const_name, value) { \
+ zend_class_entry **pce; \
+ if (zend_hash_find(CG(class_table), "pdo", sizeof("pdo"), (void **) &pce) != FAILURE) \
+ zend_declare_class_constant_long(*pce, const_name, sizeof(const_name)-1, (long)value TSRMLS_CC); \
+} \
#define REGISTER_PDO_CLASS_CONST_STRING(const_name, value) \
- php_pdo_declare_stringl_constant(const_name, sizeof(const_name)-1, value, sizeof(value)-1 TSRMLS_CC);
+ zend_declare_class_constant_stringl(php_pdo_get_dbh_ce(), const_name, sizeof(const_name)-1, value, sizeof(value)-1 TSRMLS_CC);
#define PDO_CONSTRUCT_CHECK \
if (!dbh->driver) { \
diff --git a/ext/pdo/php_pdo_driver.h b/ext/pdo/php_pdo_driver.h
index 451778109..e87650b1b 100755
--- a/ext/pdo/php_pdo_driver.h
+++ b/ext/pdo/php_pdo_driver.h
@@ -16,7 +16,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: php_pdo_driver.h,v 1.66.2.11 2006/04/09 08:05:01 wez Exp $ */
+/* $Id: php_pdo_driver.h,v 1.66.2.11.2.3 2006/09/28 23:27:59 tony2001 Exp $ */
#ifndef PHP_PDO_DRIVER_H
#define 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 20060409
+#define PDO_DRIVER_API 20060511
enum pdo_param_type {
PDO_PARAM_NULL,
@@ -98,6 +98,7 @@ enum pdo_fetch_type {
#define PDO_FETCH_UNIQUE 0x00030000 /* fetch into groups assuming first col is unique */
#define PDO_FETCH_CLASSTYPE 0x00040000 /* fetch class gets its class name from 1st column */
#define PDO_FETCH_SERIALIZE 0x00080000 /* fetch class instances by calling serialize */
+#define PDO_FETCH_PROPS_LATE 0x00100000 /* fetch props after calling ctor */
/* fetch orientation for scrollable cursors */
enum pdo_fetch_orientation {
@@ -129,6 +130,7 @@ enum pdo_attribute_type {
PDO_ATTR_DRIVER_NAME, /* name of the driver (as used in the constructor) */
PDO_ATTR_STRINGIFY_FETCHES, /* converts integer/float types to strings during fetch */
PDO_ATTR_MAX_COLUMN_LEN, /* make database calculate maximum length of data found in a column */
+ PDO_ATTR_DEFAULT_FETCH_MODE, /* Set the default fetch mode */
PDO_ATTR_EMULATE_PREPARES, /* use query emulation rather than native */
/* this defines the start of the range for driver specific options.
@@ -340,7 +342,7 @@ enum pdo_param_event {
PDO_PARAM_EVT_EXEC_POST,
PDO_PARAM_EVT_FETCH_PRE,
PDO_PARAM_EVT_FETCH_POST,
- PDO_PARAM_EVT_NORMALIZE
+ PDO_PARAM_EVT_NORMALIZE,
};
typedef int (*pdo_stmt_param_hook_func)(pdo_stmt_t *stmt, struct pdo_bound_param_data *param, enum pdo_param_event event_type TSRMLS_DC);
@@ -489,6 +491,7 @@ 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
@@ -497,12 +500,15 @@ struct _pdo_dbh_t {
* when PDO::query() fails */
pdo_stmt_t *query_stmt;
zval query_stmt_zval;
+
+ /* defaults for fetches */
+ enum pdo_fetch_type default_fetch_type;
};
/* describes a column */
struct pdo_column_data {
char *name;
- long namelen;
+ int namelen;
unsigned long maxlen;
enum pdo_param_type param_type;
unsigned long precision;
@@ -515,7 +521,7 @@ struct pdo_column_data {
struct pdo_bound_param_data {
long paramno; /* if -1, then it has a name, and we don't know the index *yet* */
char *name;
- long namelen;
+ int namelen;
long max_value_len; /* as a hint for pre-allocation */
@@ -639,7 +645,8 @@ PDO_API int php_pdo_parse_data_source(const char *data_source,
unsigned long data_source_len, struct pdo_data_src_parser *parsed,
int nparams);
-PDO_API zend_class_entry *php_pdo_get_exception(void);
+PDO_API zend_class_entry *php_pdo_get_dbh_ce();
+PDO_API zend_class_entry *php_pdo_get_exception();
PDO_API int pdo_parse_params(pdo_stmt_t *stmt, char *inquery, int inquery_len,
char **outquery, int *outquery_len TSRMLS_DC);
diff --git a/ext/pdo/php_pdo_int.h b/ext/pdo/php_pdo_int.h
index fb567af8c..c489903dd 100755
--- a/ext/pdo/php_pdo_int.h
+++ b/ext/pdo/php_pdo_int.h
@@ -18,7 +18,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: php_pdo_int.h,v 1.17.2.6 2006/01/01 12:50:11 sniper Exp $ */
+/* $Id: php_pdo_int.h,v 1.17.2.6.2.1 2006/05/11 22:43:44 helly Exp $ */
/* Stuff private to the PDO extension and not for consumption by PDO drivers
* */
@@ -40,7 +40,7 @@ extern zend_object_value pdo_dbstmt_new(zend_class_entry *ce TSRMLS_DC);
extern zend_function_entry pdo_dbstmt_functions[];
extern zend_class_entry *pdo_dbstmt_ce;
void pdo_dbstmt_free_storage(pdo_stmt_t *stmt TSRMLS_DC);
-zend_object_iterator *pdo_stmt_iter_get(zend_class_entry *ce, zval *object TSRMLS_DC);
+zend_object_iterator *pdo_stmt_iter_get(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC);
extern zend_object_handlers pdo_dbstmt_object_handlers;
int pdo_stmt_describe_columns(pdo_stmt_t *stmt TSRMLS_DC);
int pdo_stmt_setup_fetch_mode(INTERNAL_FUNCTION_PARAMETERS, pdo_stmt_t *stmt, int skip_first_arg);
diff --git a/ext/pdo/tests/bug_36428.phpt b/ext/pdo/tests/bug_36428.phpt
new file mode 100755
index 000000000..6abba6bd7
--- /dev/null
+++ b/ext/pdo/tests/bug_36428.phpt
@@ -0,0 +1,33 @@
+--TEST--
+PDO Common: PHP Bug #36428: Incorrect error message for PDO::fetchAll
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) die('skip');
+if (!extension_loaded('simplexml')) die('skip SimpleXML not loaded');
+$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_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+
+$db = PDOTest::factory();
+$db->exec("CREATE TABLE test (a VARCHAR(10))");
+$db->exec("INSERT INTO test (a) VALUES ('xyz')");
+$res = $db->query("SELECT a FROM test");
+var_dump($res->fetchAll(PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE, 'SimpleXMLElement', array('<root/>')));
+
+?>
+===DONE===
+--EXPECTF--
+array(1) {
+ [0]=>
+ object(SimpleXMLElement)#%d (1) {
+ ["a"]=>
+ string(3) "xyz"
+ }
+}
+===DONE===
diff --git a/ext/pdo/tests/bug_38253.phpt b/ext/pdo/tests/bug_38253.phpt
new file mode 100644
index 000000000..6dfdab8df
--- /dev/null
+++ b/ext/pdo/tests/bug_38253.phpt
@@ -0,0 +1,47 @@
+--TEST--
+PDO Common: PHP Bug #38253: PDO produces segfault with default fetch mode
+--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_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+$pdo = PDOTest::factory();
+
+$pdo->exec ("create table test (id integer primary key, n text)");
+$pdo->exec ("INSERT INTO test (id, n) VALUES (1, 'hi')");
+
+$pdo->setAttribute (PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_CLASS);
+$stmt = $pdo->prepare ("SELECT * FROM test");
+$stmt->execute();
+var_dump($stmt->fetchAll());
+
+$pdo = PDOTest::factory();
+
+$pdo->exec ("create table test2 (id integer primary key, n text)");
+$pdo->exec ("INSERT INTO test2 (id, n) VALUES (1,'hi')");
+
+$pdo->setAttribute (PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_FUNC);
+$stmt = $pdo->prepare ("SELECT * FROM test2");
+$stmt->execute();
+var_dump($stmt->fetchAll());
+
+?>
+--EXPECTF--
+Warning: PDOStatement::fetchAll(): SQLSTATE[HY000]: General error: No fetch class specified in %s on line %d
+
+Warning: PDOStatement::fetchAll(): SQLSTATE[HY000]: General error%s on line %d
+array(0) {
+}
+
+Warning: PDOStatement::fetchAll(): SQLSTATE[HY000]: General error: No fetch function specified in %s on line %d
+
+Warning: PDOStatement::fetchAll(): SQLSTATE[HY000]: General error%s on line %d
+array(0) {
+}
diff --git a/ext/pdo/tests/bug_38394.phpt b/ext/pdo/tests/bug_38394.phpt
new file mode 100644
index 000000000..38ce9bc36
--- /dev/null
+++ b/ext/pdo/tests/bug_38394.phpt
@@ -0,0 +1,51 @@
+--TEST--
+PDO Common: PHP Bug #38394: Prepared statement error stops subsequent statements
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) die('skip');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+if (!strncasecmp(getenv('PDOTEST_DSN'), 'sqlite2', strlen('sqlite2'))) die('skip not relevant for pdo_sqlite2 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_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+
+$db = PDOTest::factory();
+$db->exec("CREATE TABLE test (a INT, b INT, c INT)");
+$s = $db->prepare("INSERT INTO test (a,b,c) VALUES (:a,:b,:c)");
+
+$s->execute(array('a' => 1, 'b' => 2, 'c' => 3));
+
+@$s->execute(array('a' => 5, 'b' => 6, 'c' => 7, 'd' => 8));
+
+$s->execute(array('a' => 9, 'b' => 10, 'c' => 11));
+
+var_dump($db->query("SELECT * FROM test")->fetchAll(PDO::FETCH_ASSOC));
+?>
+===DONE===
+--EXPECTF--
+array(2) {
+ [0]=>
+ array(3) {
+ ["a"]=>
+ string(1) "1"
+ ["b"]=>
+ string(1) "2"
+ ["c"]=>
+ string(1) "3"
+ }
+ [1]=>
+ array(3) {
+ ["a"]=>
+ string(1) "9"
+ ["b"]=>
+ string(2) "10"
+ ["c"]=>
+ string(2) "11"
+ }
+}
+===DONE===
diff --git a/ext/pdo/tests/pdo_017.phpt b/ext/pdo/tests/pdo_017.phpt
index f1bfb97f6..651ee2860 100644
--- a/ext/pdo/tests/pdo_017.phpt
+++ b/ext/pdo/tests/pdo_017.phpt
@@ -56,8 +56,17 @@ $db->rollBack();
echo countRows('rollback');
+$db->beginTransaction();
+$delete->execute();
+echo countRows('delete');
+$db->commit();
+
+echo countRows('commit');
+
?>
--EXPECT--
Counted 3 rows after insert.
Counted 0 rows after delete.
Counted 3 rows after rollback.
+Counted 0 rows after delete.
+Counted 0 rows after commit.
diff --git a/ext/pdo/tests/pdo_026.phpt b/ext/pdo/tests/pdo_026.phpt
index a0891bedf..d993f3244 100644
--- a/ext/pdo/tests/pdo_026.phpt
+++ b/ext/pdo/tests/pdo_026.phpt
@@ -107,5 +107,5 @@ array(3) {
string(3) "tsr"
}
===DONE===
-PDODatabase::__destruct()
PDOStatementX::__destruct()
+PDODatabase::__destruct()
diff --git a/ext/pdo/tests/pdo_029.phpt b/ext/pdo/tests/pdo_029.phpt
index c0b674cd4..a5847149c 100755
--- a/ext/pdo/tests/pdo_029.phpt
+++ b/ext/pdo/tests/pdo_029.phpt
@@ -121,5 +121,5 @@ array(3) {
string(3) "tsr"
}
===DONE===
-PDODatabase::__destruct()
PDOStatementX::__destruct()
+PDODatabase::__destruct()
diff --git a/ext/pdo/tests/pdo_030.phpt b/ext/pdo/tests/pdo_030.phpt
index e9d547540..b6482d69d 100755
--- a/ext/pdo/tests/pdo_030.phpt
+++ b/ext/pdo/tests/pdo_030.phpt
@@ -135,42 +135,5 @@ array(3) {
string(3) "tsr"
}
===DONE===
-PDODatabase::__destruct()
PDOStatementX::__destruct()
---UEXPECT--
-unicode(11) "PDODatabase"
-unicode(12) "PDOStatement"
-===QUERY===
-PDODatabase::query()
-PDOStatementX::__construct()
-PDOStatementX::execute()
-unicode(13) "PDOStatementX"
-unicode(11) "PDODatabase"
-===FOREACH===
-array(3) {
- [u"id"]=>
- unicode(2) "10"
- [u"val"]=>
- unicode(3) "Abc"
- [u"val2"]=>
- unicode(3) "zxy"
-}
-array(3) {
- [u"id"]=>
- unicode(2) "20"
- [u"val"]=>
- unicode(3) "Def"
- [u"val2"]=>
- unicode(3) "wvu"
-}
-array(3) {
- [u"id"]=>
- unicode(2) "30"
- [u"val"]=>
- unicode(3) "Ghi"
- [u"val2"]=>
- unicode(3) "tsr"
-}
-===DONE===
PDODatabase::__destruct()
-PDOStatementX::__destruct()
diff --git a/ext/pdo/tests/pdo_031.phpt b/ext/pdo/tests/pdo_031.phpt
index 79f6b4252..9065ce971 100755
--- a/ext/pdo/tests/pdo_031.phpt
+++ b/ext/pdo/tests/pdo_031.phpt
@@ -3,7 +3,7 @@ PDO Common: PDOStatement SPL iterator
--SKIPIF--
<?php # vim:ft=php
if (!extension_loaded('pdo')) die('skip');
-if (!extension_loaded('SPL')) die ('skip SPL not available');
+if (!extension_loaded('SPL')) die('skip SPL not available');
$dir = getenv('REDIR_TEST_DIR');
if (false == $dir) die('skip no driver');
require_once $dir . 'pdo_test.inc';
diff --git a/ext/pdo/tests/pdo_033.phpt b/ext/pdo/tests/pdo_033.phpt
new file mode 100644
index 000000000..9739c0e0e
--- /dev/null
+++ b/ext/pdo/tests/pdo_033.phpt
@@ -0,0 +1,39 @@
+--TEST--
+PDO Common: PDO::quote()
+--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_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+$db = PDOTest::factory();
+
+$unquoted = ' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~';
+
+$quoted = $db->quote($unquoted);
+
+$db->query("CREATE TABLE test (t char(100))");
+$db->query("INSERT INTO test (t) VALUES($quoted)");
+
+$stmt = $db->prepare('SELECT * from test');
+$stmt->execute();
+
+print_r($stmt->fetchAll(PDO::FETCH_ASSOC));
+
+
+?>
+--EXPECT--
+Array
+(
+ [0] => Array
+ (
+ [t] => !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
+ )
+
+)
diff --git a/ext/pdo/tests/pdo_test.inc b/ext/pdo/tests/pdo_test.inc
index a023fd89b..4d14f32d4 100644
--- a/ext/pdo/tests/pdo_test.inc
+++ b/ext/pdo/tests/pdo_test.inc
@@ -65,9 +65,9 @@ class PDOTest {
}
static function detect_transactional_mysql_engine($db) {
- foreach ($db->query('show engines') as $row) {
- if ($row[1] == 'YES' && ($row[0] == 'INNOBASE' || $row[0] == 'BDB')) {
- return $row[0];
+ foreach ($db->query("show variables like 'have%'") as $row) {
+ if ($row[1] == 'YES' && ($row[0] == 'have_innodb' || $row[0] == 'have_bdb')) {
+ return str_replace("have_", "", $row[0]);
}
}
return false;