}
/* }}} */
-static zval * pdo_stmt_instantiate(zval *object, zend_class_entry *dbstmt_ce, zval *ctor_args TSRMLS_DC) /* {{{ */
+static zval *pdo_stmt_instantiate(pdo_dbh_t *dbh, zval *object, zend_class_entry *dbstmt_ce, zval *ctor_args TSRMLS_DC) /* {{{ */
{
if (ctor_args) {
if (Z_TYPE_P(ctor_args) != IS_ARRAY) {
- zend_throw_exception_ex(php_pdo_get_exception(), 0 TSRMLS_CC, "Parameter ctor_args must be an array");
+ pdo_raise_impl_error(dbh, NULL, "HY000", "constructor arguments must be passed as an array" TSRMLS_CC);
return NULL;
}
if (!dbstmt_ce->constructor) {
- zend_throw_exception_ex(php_pdo_get_exception(), 0 TSRMLS_CC, "Statement object's constructor does not take any arguments", dbstmt_ce->name);
+ pdo_raise_impl_error(dbh, NULL, "HY000", "user-supplied statement does not accept constructor arguments" TSRMLS_CC);
return NULL;
}
}
|| Z_TYPE_PP(item) != IS_STRING
|| zend_lookup_class(Z_STRVAL_PP(item), Z_STRLEN_PP(item), &pce TSRMLS_CC) == FAILURE
) {
- zend_throw_exception_ex(php_pdo_get_exception(), 0 TSRMLS_CC, "PDO_ATTR_STATEMENT_CLASS requires format array(classname, ctor_args) and classname must be a string specifying an existing class");
+ pdo_raise_impl_error(dbh, NULL, "HY000",
+ "PDO_ATTR_STATEMENT_CLASS requires format array(classname, ctor_args); "
+ "the classname must be a string specifying an existing class"
+ TSRMLS_CC);
+ PDO_HANDLE_DBH_ERR();
RETURN_FALSE;
}
dbstmt_ce = *pce;
if (!instanceof_function(dbstmt_ce, pdo_dbstmt_ce TSRMLS_CC)) {
- zend_throw_exception_ex(php_pdo_get_exception(), 0 TSRMLS_CC, "The provided statement class must be derived from %s", pdo_dbstmt_ce->name);
+ pdo_raise_impl_error(dbh, NULL, "HY000",
+ "user-supplied statement class must be derived from PDOStatement" TSRMLS_CC);
+ PDO_HANDLE_DBH_ERR();
RETURN_FALSE;
}
if (dbstmt_ce->constructor && !(dbstmt_ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) {
- zend_throw_exception_ex(php_pdo_get_exception(), 0 TSRMLS_CC, "The provided statement class %s must not have a protected or public constructor", dbstmt_ce->name);
+ pdo_raise_impl_error(dbh, NULL, "HY000",
+ "user-supplied statement class must have a public constructor" TSRMLS_CC);
+ PDO_HANDLE_DBH_ERR();
RETURN_FALSE;
}
if (zend_hash_index_find(Z_ARRVAL_PP(opt), 1, (void**)&item) == SUCCESS) {
if (Z_TYPE_PP(item) != IS_ARRAY) {
- zend_throw_exception_ex(php_pdo_get_exception(), 0 TSRMLS_CC, "PDO_ATTR_STATEMENT_CLASS requires format array(classname, ctor_args) and ctor args must be an array");
+ pdo_raise_impl_error(dbh, NULL, "HY000",
+ "PDO_ATTR_STATEMENT_CLASS requires format array(classname, ctor_args); "
+ "ctor_args must be an array"
+ TSRMLS_CC);
+ PDO_HANDLE_DBH_ERR();
RETURN_FALSE;
}
ctor_args = *item;
ctor_args = NULL;
}
- if (!pdo_stmt_instantiate(return_value, dbstmt_ce, ctor_args TSRMLS_CC)) {
- zend_throw_exception_ex(php_pdo_get_exception(), 0 TSRMLS_CC, "Failed to instantiate statement class %s", dbstmt_ce->name);
- return;
+ if (!pdo_stmt_instantiate(dbh, return_value, dbstmt_ce, ctor_args TSRMLS_CC)) {
+ pdo_raise_impl_error(dbh, NULL, "HY000",
+ "failed to instantiate user-supplied statement class"
+ TSRMLS_CC);
+ PDO_HANDLE_DBH_ERR();
+ RETURN_FALSE;
}
stmt = (pdo_stmt_t*)zend_object_store_get_object(return_value TSRMLS_CC);
dbh->error_mode = Z_LVAL_P(value);
RETURN_TRUE;
default:
- zend_throw_exception_ex(php_pdo_get_exception(), 0 TSRMLS_CC, "Error mode %d is invalid", Z_LVAL_P(value));
+ pdo_raise_impl_error(dbh, NULL, "HY000", "invalid error mode" TSRMLS_CC);
+ PDO_HANDLE_DBH_ERR();
+ RETURN_FALSE;
}
RETURN_FALSE;
dbh->desired_case = Z_LVAL_P(value);
RETURN_TRUE;
default:
- zend_throw_exception_ex(php_pdo_get_exception(), 0 TSRMLS_CC, "Case folding mode %d is invalid", Z_LVAL_P(value));
+ pdo_raise_impl_error(dbh, NULL, "HY000", "invalid case folding mode" TSRMLS_CC);
+ PDO_HANDLE_DBH_ERR();
+ RETURN_FALSE;
}
RETURN_FALSE;
PDO_DBH_CLEAR_ERR();
- if (!pdo_stmt_instantiate(return_value, pdo_dbstmt_ce, NULL TSRMLS_CC)) {
- zend_throw_exception_ex(php_pdo_get_exception(), 0 TSRMLS_CC, "Failed to instantiate statement class %s", pdo_dbstmt_ce->name);
+ if (!pdo_stmt_instantiate(dbh, return_value, pdo_dbstmt_ce, NULL TSRMLS_CC)) {
+ pdo_raise_impl_error(dbh, NULL, "HY000", "failed to instantiate user supplied statement class" TSRMLS_CC);
return;
}
stmt = (pdo_stmt_t*)zend_object_store_get_object(return_value TSRMLS_CC);
fcc->calling_scope = EG(scope);
return 1;
} else if (stmt->fetch.cls.ctor_args) {
- zend_throw_exception_ex(pdo_exception_ce, 0 TSRMLS_CC, "Class %s does not have a constructor, use NULL for parameter ctor_params or omit it", ce->name);
+ pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "user-supplied class does not have a constructor, use NULL for the ctor_params parameter, or simply omit it" TSRMLS_CC);
return 0;
} else {
return 1; /* no ctor no args is also ok */
}
/* }}} */
-static int make_callable_ex(zval *callable, zend_fcall_info * fci, zend_fcall_info_cache * fcc, int num_args 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;
if (Z_TYPE_P(callable) == IS_ARRAY) {
if (Z_ARRVAL_P(callable)->nNumOfElements < 2) {
- zend_throw_exception_ex(pdo_exception_ce, 0 TSRMLS_CC, "Argument function must be a valid function name or an array specifying object or class and method name");
+ pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "user-supplied function must be a valid callback" TSRMLS_CC);
return 0;
}
object = (zval**)Z_ARRVAL_P(callable)->pListHead->pData;
} else if (Z_TYPE_PP(object) == IS_OBJECT) { /* object call */
ce = Z_OBJCE_PP(object);
} else {
- zend_throw_exception_ex(pdo_exception_ce, 0 TSRMLS_CC, "Argument function may be an array but the provided array did neither contain a class name nor an object as first member");
+ pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "user-supplied function must be a valid callback; bogus object/class name" TSRMLS_CC);
return 0;
}
if (Z_TYPE_PP(method) != IS_STRING) {
- zend_throw_exception_ex(pdo_exception_ce, 0 TSRMLS_CC, "Argument function may be an array but the provided array did not contain a method name as second member");
+ pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "user-supplied function must be a valid callback; bogus method name" TSRMLS_CC);
+ return 0;
}
}
if (!zend_is_callable(callable, 0, &fname)) {
- zend_throw_exception_ex(pdo_exception_ce, 0 TSRMLS_CC, "Argument function must contain something callable");
+ pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "user-supplied function must be a valid callback" TSRMLS_CC);
return 0;
}
}
if (cname) {
if (zend_lookup_class(cname, strlen(cname), &pce TSRMLS_CC) == FAILURE) {
- zend_throw_exception_ex(pdo_exception_ce, 0 TSRMLS_CC, "Argument function references non existing class %s", cname);
+ pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "user-supplied class does not exist" TSRMLS_CC);
+ return 0;
} else {
if (ce) {
/* pce must be base of ce or ce itself */
if (ce != *pce && !instanceof_function(ce, *pce TSRMLS_CC)) {
- zend_throw_exception_ex(pdo_exception_ce, 0 TSRMLS_CC, "Argument function would result in calling %s::%s but class %s is not base of %s", (*pce)->name, fname, (*pce)->name, ce->name);
+ pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "user-supplied class has bogus lineage" TSRMLS_CC);
+ return 0;
}
}
ce = *pce;
fci->function_table = ce ? &ce->function_table : EG(function_table);
if (zend_hash_find(fci->function_table, fname, strlen(fname)+1, (void **)&function_handler) == FAILURE) {
- zend_throw_exception_ex(pdo_exception_ce, 0 TSRMLS_CC, "Argument function '%s%s%s' not found", cname ? cname : "", cname ? "::" : "", fname);
- efree(cname ? cname : fname);
+ pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "user-supplied function does not exist" TSRMLS_CC);
return 0;
}
efree(cname ? cname : fname);
zend_fcall_info * fci = &stmt->fetch.cls.fci;
zend_fcall_info_cache * fcc = &stmt->fetch.cls.fcc;
- if (!make_callable_ex(stmt->fetch.func.function, fci, fcc, stmt->column_count TSRMLS_CC)) {
+ if (!make_callable_ex(stmt, stmt->fetch.func.function, fci, fcc, stmt->column_count TSRMLS_CC)) {
return 0;
} else {
stmt->fetch.func.values = safe_emalloc(sizeof(zval*), stmt->column_count, 0);
PHP_VAR_UNSERIALIZE_INIT(var_hash);
if (php_var_unserialize(&return_value, (const unsigned char**)&Z_STRVAL_P(val), Z_STRVAL_P(val)+Z_STRLEN_P(val), NULL TSRMLS_CC) == FAILURE) {
- zend_throw_exception_ex(pdo_exception_ce, 0 TSRMLS_CC, "Cannot unserialize data");
+ pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "cannot unserialize data" TSRMLS_CC);
PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
return 0;
}
#endif
#if PHP_MAJOR_VERSION > 5 || PHP_MINOR_VERSION >= 1
if (!ce->unserialize) {
- zend_throw_exception_ex(pdo_exception_ce, 0 TSRMLS_CC, "Class %s cannot be unserialized", ce->name);
+ pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "cannot unserialize class" TSRMLS_CC);
return 0;
} else if (ce->unserialize(&return_value, ce, Z_TYPE_P(val) == IS_STRING ? Z_STRVAL_P(val) : "", Z_TYPE_P(val) == IS_STRING ? Z_STRLEN_P(val) : 0, NULL TSRMLS_CC) == FAILURE) {
- zend_throw_exception_ex(pdo_exception_ce, 0 TSRMLS_CC, "Class %s cannot be unserialized", ce->name);
+ pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "cannot unserialize class" TSRMLS_CC);
zval_dtor(return_value);
ZVAL_NULL(return_value);
+ return 0;
}
#endif
}
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) {
- zend_throw_exception_ex(pdo_exception_ce, 0 TSRMLS_CC, "Could not execute %s::%s()", ce->name, ce->constructor->common.function_name);
+ pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "could not call class constructor" TSRMLS_CC);
return 0;
} else {
if (stmt->fetch.cls.retval_ptr) {
stmt->fetch.func.fci.param_count = idx;
stmt->fetch.func.fci.retval_ptr_ptr = &retval;
if (zend_call_function(&stmt->fetch.func.fci, &stmt->fetch.func.fcc TSRMLS_CC) == FAILURE) {
- zend_throw_exception_ex(pdo_exception_ce, 0 TSRMLS_CC, "Could not execute %s%s%s()", ce->name, ce->constructor->common.function_name);
+ pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "could not call user-supplied function" TSRMLS_CC);
return 0;
} else {
if (return_all) {
#if PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION < 1
if ((flags & PDO_FETCH_SERIALIZE) == PDO_FETCH_SERIALIZE) {
- zend_throw_exception(pdo_exception_ce, "Fetch flag PDO_FETCH_SERIALIZE only allowed in PHP version 5.1 and higher", 0 TSRMLS_CC);
+ pdo_raise_impl_error(stmt->dbh, stmt, "IM001", "PDO_FETCH_SERIALIZE is not supported in this PHP version" TSRMLS_CC);
return 0;
}
#endif
switch(mode) {
case PDO_FETCH_FUNC:
if (!fetch_all) {
- zend_throw_exception(pdo_exception_ce, "Fetch mode PDO_FETCH_FUNC is only allowed in PDOStatement::fetchAll()", 0 TSRMLS_CC);
+ pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "PDO_FETCH_FUNC is only allowed in PDOStatement::fetchAll()" TSRMLS_CC);
return 0;
}
return 1;
default:
if ((flags & PDO_FETCH_SERIALIZE) == PDO_FETCH_SERIALIZE) {
- zend_throw_exception_ex(pdo_exception_ce, 0 TSRMLS_CC, "Fetch mode flag PDO_FETCH_SERIALIZE requires mode PDO_FETCH_CLASS", mode);
+ pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "PDO_FETCH_SERIALIZE can only be used together with PDO_FETCH_CLASS" TSRMLS_CC);
return 0;
}
if ((flags & PDO_FETCH_CLASSTYPE) == PDO_FETCH_CLASSTYPE) {
- zend_throw_exception_ex(pdo_exception_ce, 0 TSRMLS_CC, "Fetch mode flag PDO_FETCH_CLASSTYPE requires mode PDO_FETCH_CLASS", mode);
+ pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "PDO_FETCH_CLASSTYPE can only be used together with PDO_FETCH_CLASS" TSRMLS_CC);
return 0;
}
if (mode >= PDO_FETCH__MAX) {
- zend_throw_exception_ex(pdo_exception_ce, 0 TSRMLS_CC, "Fetch mode %d is invalid", mode);
+ pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "invalid fetch mode" TSRMLS_CC);
return 0;
}
/* no break; */
break;
case 2:
if (Z_TYPE_P(ctor_args) != IS_NULL && Z_TYPE_P(ctor_args) != IS_ARRAY) {
- zend_throw_exception(pdo_exception_ce, "Parameter ctor_args must either be NULL or an array ", 0 TSRMLS_CC);
+ pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "ctor_args must be either NULL or an array" TSRMLS_CC);
error = 1;
break;
}
stmt->fetch.cls.ce = zend_fetch_class(class_name, class_name_len, ZEND_FETCH_CLASS_AUTO TSRMLS_CC);
if (!stmt->fetch.cls.ce) {
- zend_throw_exception_ex(pdo_exception_ce, 0 TSRMLS_CC, "Could not find class '%s'", class_name);
+ pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "Could not find user-supplied class" TSRMLS_CC);
error = 1;
break;
}
if (!error && !do_fetch(stmt, TRUE, return_value, how, ori, off, 0 TSRMLS_CC)) {
error = 1;
+ }
+ if (error) {
PDO_HANDLE_STMT_ERR();
}
do_fetch_opt_finish(stmt, 1 TSRMLS_CC);
break;
case 3:
if (Z_TYPE_P(ctor_args) != IS_NULL && Z_TYPE_P(ctor_args) != IS_ARRAY) {
- zend_throw_exception(pdo_exception_ce, "Parameter ctor_args must either be NULL or an array ", 0 TSRMLS_CC);
+ pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "ctor_args must be either NULL or an array" TSRMLS_CC);
error = 1;
break;
}
case 2:
stmt->fetch.cls.ctor_args = ctor_args; /* we're not going to free these */
if (Z_TYPE_P(arg2) != IS_STRING) {
- zend_throw_exception_ex(pdo_exception_ce, 0 TSRMLS_CC, "In fetch mode PDO_FETCH_CLASS the 2nd parameter must be a class name string", Z_TYPE_P(arg2));
+ pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "Invalid class name (should be a string)" TSRMLS_CC);
error = 1;
break;
} else {
stmt->fetch.cls.ce = zend_fetch_class(Z_STRVAL_P(arg2), Z_STRLEN_P(arg2), ZEND_FETCH_CLASS_AUTO TSRMLS_CC);
if (!stmt->fetch.cls.ce) {
- zend_throw_exception_ex(pdo_exception_ce, 0 TSRMLS_CC, "Could not find class '%s'", Z_TYPE_P(arg2));
+ pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "could not find user-specified class" TSRMLS_CC);
error = 1;
break;
}
}
}
- do_fetch_class_prepare(stmt TSRMLS_CC);
+ if (!error) {
+ do_fetch_class_prepare(stmt TSRMLS_CC);
+ }
break;
case PDO_FETCH_FUNC:
stmt->fetch.column = Z_LVAL_P(arg2);
break;
case 3:
- zend_throw_exception_ex(pdo_exception_ce, 0 TSRMLS_CC, "Third parameter not allowed for specified fetch mode");
+ pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "Third parameter not allowed for PDO_FETCH_COLUMN" TSRMLS_CC);
error = 1;
}
break;
default:
if (ZEND_NUM_ARGS() > 1) {
- zend_throw_exception_ex(pdo_exception_ce, 0 TSRMLS_CC, "Additional parameters not allowed for specified fetch mode");
+ pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "Extraneous additional parameters" TSRMLS_CC);
error = 1;
}
}
}
if (!do_fetch(stmt, TRUE, data, how, PDO_FETCH_ORI_NEXT, 0, return_all TSRMLS_CC)) {
FREE_ZVAL(data);
- PDO_HANDLE_STMT_ERR();
zval_dtor(return_value);
error = 1;
}
stmt->fetch.cls.fci.param_count = old_arg_count;
if (error) {
+ PDO_HANDLE_STMT_ERR();
RETURN_FALSE;
}
}
stmt->fetch.cls.ctor_args = NULL;
if (stmt->dbh->is_persistent) {
+ /* TODO: CRITICAL for final release */
php_error_docref(NULL TSRMLS_CC, E_WARNING, "PHP might crash if you don't call $stmt->setFetchMode() to reset to defaults on this persistent statement. This will be fixed in a later release");
}
if (argc == 3) {
if (Z_TYPE_PP(args[skip+2]) != IS_NULL && Z_TYPE_PP(args[skip+2]) != IS_ARRAY) {
- zend_throw_exception(pdo_exception_ce, "Parameter ctor_args must either be NULL or an array ", 0 TSRMLS_CC);
+ pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "ctor_args must be either NULL or an array" TSRMLS_CC);
} else if (Z_TYPE_PP(args[skip+2]) == IS_ARRAY && zend_hash_num_elements(Z_ARRVAL_PP(args[skip+2]))) {
ALLOC_ZVAL(stmt->fetch.cls.ctor_args);
*stmt->fetch.cls.ctor_args = **args[skip+2];