Remove MYSQLI_USE_MYSQLND constant and all the code with it

This commit is contained in:
Kamil Tekiela 2022-01-05 22:12:39 +00:00
parent 276e49c438
commit d84dfa3292
12 changed files with 31 additions and 1359 deletions

View file

@ -69,7 +69,6 @@ if test "$PHP_MYSQLI" != "no"; then
if test "$PHP_MYSQLI" = "yes" || test "$PHP_MYSQLI" = "mysqlnd"; then
PHP_ADD_EXTENSION_DEP(mysqli, mysqlnd)
AC_DEFINE([MYSQLI_USE_MYSQLND], 1, [Whether mysqlnd is enabled])
PHP_INSTALL_HEADERS([ext/mysqli/mysqli_mysqlnd.h])
fi
fi

View file

@ -21,7 +21,6 @@ if (PHP_MYSQLI != "no") {
if (PHP_MYSQLI != "no") {
EXTENSION("mysqli", mysqli_source, PHP_MYSQLI_SHARED, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1");
AC_DEFINE('MYSQLI_USE_MYSQLND', 1, 'Using MySQL native driver');
ADD_EXTENSION_DEP('mysqli', 'mysqlnd', true);
PHP_INSTALL_HEADERS("ext/mysqli", "php_mysqli_structs.h");
}

View file

@ -109,47 +109,6 @@ int php_le_pmysqli(void)
return le_pmysqli;
}
#ifndef MYSQLI_USE_MYSQLND
/* {{{ php_free_stmt_bind_buffer */
void php_free_stmt_bind_buffer(BIND_BUFFER bbuf, int type)
{
unsigned int i;
if (!bbuf.var_cnt) {
return;
}
for (i=0; i < bbuf.var_cnt; i++) {
/* free temporary bind buffer */
if (type == FETCH_RESULT && bbuf.buf[i].val) {
efree(bbuf.buf[i].val);
}
zval_ptr_dtor(&bbuf.vars[i]);
}
if (bbuf.vars) {
efree(bbuf.vars);
}
/*
Don't free bbuf.is_null for FETCH_RESULT since we have allocated
is_null and buf in one block so we free only buf, which is the beginning
of the block. When FETCH_SIMPLE then buf wasn't allocated together with
buf and we have to free it.
*/
if (type == FETCH_RESULT) {
efree(bbuf.buf);
} else if (type == FETCH_SIMPLE){
efree(bbuf.is_null);
}
bbuf.var_cnt = 0;
}
/* }}} */
#endif
/* {{{ php_clear_stmt_bind */
void php_clear_stmt_bind(MY_STMT *stmt)
{
@ -164,16 +123,6 @@ void php_clear_stmt_bind(MY_STMT *stmt)
mysqlnd keeps track of the binding and has freed its
structures in stmt_close() above
*/
#ifndef MYSQLI_USE_MYSQLND
/* Clean param bind */
php_free_stmt_bind_buffer(stmt->param, FETCH_SIMPLE);
/* Clean output bind */
php_free_stmt_bind_buffer(stmt->result, FETCH_RESULT);
if (!Z_ISUNDEF(stmt->link_handle)) {
zval_ptr_dtor(&stmt->link_handle);
}
#endif
if (stmt->query) {
efree(stmt->query);
}
@ -452,7 +401,6 @@ PHP_MYSQLI_EXPORT(zend_object *) mysqli_objects_new(zend_class_entry *class_type
}
/* }}} */
#ifdef MYSQLI_USE_MYSQLND
#include "ext/mysqlnd/mysqlnd_reverse_api.h"
static MYSQLND *mysqli_convert_zv_to_mysqlnd(zval * zv)
{
@ -475,7 +423,6 @@ static const MYSQLND_REVERSE_API mysqli_reverse_api = {
&mysqli_module_entry,
mysqli_convert_zv_to_mysqlnd
};
#endif
/* {{{ PHP_INI_BEGIN */
PHP_INI_BEGIN()
@ -527,11 +474,6 @@ static PHP_GINIT_FUNCTION(mysqli)
PHP_MINIT_FUNCTION(mysqli)
{
REGISTER_INI_ENTRIES();
#ifndef MYSQLI_USE_MYSQLND
if (mysql_server_init(0, NULL, NULL)) {
return FAILURE;
}
#endif
memcpy(&mysqli_object_handlers, &std_object_handlers, sizeof(zend_object_handlers));
mysqli_object_handlers.offset = XtOffsetOf(mysqli_object, zo);
@ -596,25 +538,15 @@ PHP_MINIT_FUNCTION(mysqli)
REGISTER_LONG_CONSTANT("MYSQLI_READ_DEFAULT_FILE", MYSQL_READ_DEFAULT_FILE, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("MYSQLI_OPT_CONNECT_TIMEOUT", MYSQL_OPT_CONNECT_TIMEOUT, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("MYSQLI_OPT_LOCAL_INFILE", MYSQL_OPT_LOCAL_INFILE, CONST_CS | CONST_PERSISTENT);
#if (MYSQL_VERSION_ID >= 80021 && !defined(MARIADB_BASE_VERSION)) || defined(MYSQLI_USE_MYSQLND)
REGISTER_LONG_CONSTANT("MYSQLI_OPT_LOAD_DATA_LOCAL_DIR", MYSQL_OPT_LOAD_DATA_LOCAL_DIR, CONST_CS | CONST_PERSISTENT);
#endif
REGISTER_LONG_CONSTANT("MYSQLI_INIT_COMMAND", MYSQL_INIT_COMMAND, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("MYSQLI_OPT_READ_TIMEOUT", MYSQL_OPT_READ_TIMEOUT, CONST_CS | CONST_PERSISTENT);
#ifdef MYSQLI_USE_MYSQLND
REGISTER_LONG_CONSTANT("MYSQLI_OPT_NET_CMD_BUFFER_SIZE", MYSQLND_OPT_NET_CMD_BUFFER_SIZE, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("MYSQLI_OPT_NET_READ_BUFFER_SIZE", MYSQLND_OPT_NET_READ_BUFFER_SIZE, CONST_CS | CONST_PERSISTENT);
#endif
#ifdef MYSQLI_USE_MYSQLND
REGISTER_LONG_CONSTANT("MYSQLI_OPT_INT_AND_FLOAT_NATIVE", MYSQLND_OPT_INT_AND_FLOAT_NATIVE, CONST_CS | CONST_PERSISTENT);
#endif
#if MYSQL_VERSION_ID < 80000 || MYSQL_VERSION_ID >= 100000 || defined(MYSQLI_USE_MYSQLND)
REGISTER_LONG_CONSTANT("MYSQLI_OPT_SSL_VERIFY_SERVER_CERT", MYSQL_OPT_SSL_VERIFY_SERVER_CERT, CONST_CS | CONST_PERSISTENT);
#endif
#if MYSQL_VERSION_ID > 50605 || defined(MYSQLI_USE_MYSQLND)
REGISTER_LONG_CONSTANT("MYSQLI_SERVER_PUBLIC_KEY", MYSQL_SERVER_PUBLIC_KEY, CONST_CS | CONST_PERSISTENT);
#endif
/* mysqli_real_connect flags */
REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_SSL", CLIENT_SSL, CONST_CS | CONST_PERSISTENT);
@ -625,22 +557,16 @@ PHP_MINIT_FUNCTION(mysqli)
REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_FOUND_ROWS", CLIENT_FOUND_ROWS, CONST_CS | CONST_PERSISTENT);
#ifdef CLIENT_SSL_VERIFY_SERVER_CERT
REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_SSL_VERIFY_SERVER_CERT", CLIENT_SSL_VERIFY_SERVER_CERT, CONST_CS | CONST_PERSISTENT);
#ifdef MYSQLI_USE_MYSQLND
REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT", CLIENT_SSL_DONT_VERIFY_SERVER_CERT, CONST_CS | CONST_PERSISTENT);
#endif
#endif
#if (MYSQL_VERSION_ID >= 50611 && defined(CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS)) || defined(MYSQLI_USE_MYSQLND)
REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS", CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("MYSQLI_OPT_CAN_HANDLE_EXPIRED_PASSWORDS", MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS, CONST_CS | CONST_PERSISTENT);
#endif
/* for mysqli_query */
REGISTER_LONG_CONSTANT("MYSQLI_STORE_RESULT", MYSQLI_STORE_RESULT, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("MYSQLI_USE_RESULT", MYSQLI_USE_RESULT, CONST_CS | CONST_PERSISTENT);
#if defined (MYSQLI_USE_MYSQLND)
REGISTER_LONG_CONSTANT("MYSQLI_ASYNC", MYSQLI_ASYNC, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("MYSQLI_STORE_RESULT_COPY_DATA", MYSQLI_STORE_RESULT_COPY_DATA, CONST_CS | CONST_PERSISTENT);
#endif
/* for mysqli_fetch_assoc */
REGISTER_LONG_CONSTANT("MYSQLI_ASSOC", MYSQLI_ASSOC, CONST_CS | CONST_PERSISTENT);
@ -676,9 +602,7 @@ PHP_MINIT_FUNCTION(mysqli)
REGISTER_LONG_CONSTANT("MYSQLI_BINARY_FLAG", BINARY_FLAG, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("MYSQLI_NO_DEFAULT_VALUE_FLAG", NO_DEFAULT_VALUE_FLAG, CONST_CS | CONST_PERSISTENT);
#if MYSQL_VERSION_ID < 60000 || MYSQL_VERSION_ID > 60003 || defined(MYSQLI_USE_MYSQLND)
REGISTER_LONG_CONSTANT("MYSQLI_ON_UPDATE_NOW_FLAG", ON_UPDATE_NOW_FLAG, CONST_CS | CONST_PERSISTENT);
#endif
REGISTER_LONG_CONSTANT("MYSQLI_TYPE_DECIMAL", FIELD_TYPE_DECIMAL, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("MYSQLI_TYPE_TINY", FIELD_TYPE_TINY, CONST_CS | CONST_PERSISTENT);
@ -729,15 +653,7 @@ PHP_MINIT_FUNCTION(mysqli)
REGISTER_LONG_CONSTANT("MYSQLI_REPORT_OFF", 0, CONST_CS | CONST_PERSISTENT);
/* We use non-nested macros with expansion, as VC has problems */
#ifdef MYSQLI_USE_MYSQLND
REGISTER_LONG_CONSTANT("MYSQLI_DEBUG_TRACE_ENABLED", MYSQLND_DBG_ENABLED, CONST_CS | CONST_PERSISTENT);
#else
#ifdef DBUG_ON
REGISTER_LONG_CONSTANT("MYSQLI_DEBUG_TRACE_ENABLED", 1, CONST_CS | CONST_PERSISTENT);
#else
REGISTER_LONG_CONSTANT("MYSQLI_DEBUG_TRACE_ENABLED", 0, CONST_CS | CONST_PERSISTENT);
#endif
#endif
REGISTER_LONG_CONSTANT("MYSQLI_SERVER_QUERY_NO_GOOD_INDEX_USED", SERVER_QUERY_NO_GOOD_INDEX_USED, CONST_CS | CONST_PERSISTENT | CONST_DEPRECATED);
REGISTER_LONG_CONSTANT("MYSQLI_SERVER_QUERY_NO_INDEX_USED", SERVER_QUERY_NO_INDEX_USED, CONST_CS | CONST_PERSISTENT | CONST_DEPRECATED);
@ -778,10 +694,7 @@ PHP_MINIT_FUNCTION(mysqli)
REGISTER_BOOL_CONSTANT("MYSQLI_IS_MARIADB", 0, CONST_CS | CONST_PERSISTENT);
#endif
#ifdef MYSQLI_USE_MYSQLND
mysqlnd_reverse_api_register_api(&mysqli_reverse_api);
#endif
return SUCCESS;
}
@ -790,21 +703,6 @@ PHP_MINIT_FUNCTION(mysqli)
/* {{{ PHP_MSHUTDOWN_FUNCTION */
PHP_MSHUTDOWN_FUNCTION(mysqli)
{
#ifndef MYSQLI_USE_MYSQLND
#ifdef PHP_WIN32
zend_ulong client_ver = mysql_get_client_version();
/*
Can't call mysql_server_end() multiple times prior to 5.0.46 on Windows.
PHP bug#41350 MySQL bug#25621
*/
if ((client_ver >= 50046 && client_ver < 50100) || client_ver > 50122) {
mysql_server_end();
}
#else
mysql_server_end();
#endif
#endif
zend_hash_destroy(&mysqli_driver_properties);
zend_hash_destroy(&mysqli_result_properties);
zend_hash_destroy(&mysqli_stmt_properties);
@ -820,11 +718,6 @@ PHP_MSHUTDOWN_FUNCTION(mysqli)
/* {{{ PHP_RINIT_FUNCTION */
PHP_RINIT_FUNCTION(mysqli)
{
#if !defined(MYSQLI_USE_MYSQLND) && defined(ZTS)
if (mysql_thread_init()) {
return FAILURE;
}
#endif
MyG(error_msg) = NULL;
MyG(error_no) = 0;
MyG(report_mode) = MYSQLI_REPORT_ERROR|MYSQLI_REPORT_STRICT;
@ -839,9 +732,6 @@ PHP_RSHUTDOWN_FUNCTION(mysqli)
{
/* check persistent connections, move used to free */
#if !defined(MYSQLI_USE_MYSQLND) && defined(ZTS)
mysql_thread_end();
#endif
if (MyG(error_msg)) {
efree(MyG(error_msg));
}
@ -865,10 +755,6 @@ PHP_MINFO_FUNCTION(mysqli)
php_info_print_table_row(2, "Inactive Persistent Links", buf);
snprintf(buf, sizeof(buf), ZEND_LONG_FMT, MyG(num_links));
php_info_print_table_row(2, "Active Links", buf);
#ifndef MYSQLI_USE_MYSQLND
php_info_print_table_row(2, "Client API header version", MYSQL_SERVER_VERSION);
php_info_print_table_row(2, "MYSQLI_SOCKET", MYSQL_UNIX_ADDR);
#endif
php_info_print_table_end();
DISPLAY_INI_ENTRIES();
@ -879,9 +765,7 @@ PHP_MINFO_FUNCTION(mysqli)
/* Dependencies */
static const zend_module_dep mysqli_deps[] = {
ZEND_MOD_REQUIRED("spl")
#ifdef MYSQLI_USE_MYSQLND
ZEND_MOD_REQUIRED("mysqlnd")
#endif
ZEND_MOD_END
};
@ -934,10 +818,6 @@ PHP_METHOD(mysqli_stmt, __construct)
RETURN_FALSE;
}
#ifndef MYSQLI_USE_MYSQLND
ZVAL_COPY(&stmt->link_handle, mysql_link);
#endif
mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
mysqli_resource->ptr = (void *)stmt;
mysqli_resource->status = MYSQLI_STATUS_INITIALIZED;
@ -1006,71 +886,6 @@ PHP_METHOD(mysqli_result, getIterator)
/* {{{ php_mysqli_fetch_into_hash_aux */
void php_mysqli_fetch_into_hash_aux(zval *return_value, MYSQL_RES * result, zend_long fetchtype)
{
#ifndef MYSQLI_USE_MYSQLND
MYSQL_ROW row;
unsigned int i, num_fields;
MYSQL_FIELD *fields;
unsigned long *field_len;
if (!(row = mysql_fetch_row(result))) {
RETURN_NULL();
}
if (fetchtype & MYSQLI_ASSOC) {
fields = mysql_fetch_fields(result);
}
array_init(return_value);
field_len = mysql_fetch_lengths(result);
num_fields = mysql_num_fields(result);
for (i = 0; i < num_fields; i++) {
if (row[i]) {
zval res;
if (mysql_fetch_field_direct(result, i)->type == MYSQL_TYPE_BIT) {
my_ulonglong llval;
char tmp[22];
switch (field_len[i]) {
case 8:llval = (my_ulonglong) bit_uint8korr(row[i]);break;
case 7:llval = (my_ulonglong) bit_uint7korr(row[i]);break;
case 6:llval = (my_ulonglong) bit_uint6korr(row[i]);break;
case 5:llval = (my_ulonglong) bit_uint5korr(row[i]);break;
case 4:llval = (my_ulonglong) bit_uint4korr(row[i]);break;
case 3:llval = (my_ulonglong) bit_uint3korr(row[i]);break;
case 2:llval = (my_ulonglong) bit_uint2korr(row[i]);break;
case 1:llval = (my_ulonglong) uint1korr(row[i]);break;
EMPTY_SWITCH_DEFAULT_CASE()
}
/* even though lval is declared as unsigned, the value
* may be negative. Therefore we cannot use MYSQLI_LLU_SPEC and must
* use MYSQLI_LL_SPEC.
*/
snprintf(tmp, sizeof(tmp), (mysql_fetch_field_direct(result, i)->flags & UNSIGNED_FLAG)? MYSQLI_LLU_SPEC : MYSQLI_LL_SPEC, llval);
ZVAL_STRING(&res, tmp);
} else {
ZVAL_STRINGL(&res, row[i], field_len[i]);
}
if (fetchtype & MYSQLI_NUM) {
add_index_zval(return_value, i, &res);
}
if (fetchtype & MYSQLI_ASSOC) {
if (fetchtype & MYSQLI_NUM && Z_REFCOUNTED(res)) {
Z_ADDREF(res);
}
add_assoc_zval(return_value, fields[i].name, &res);
}
} else {
if (fetchtype & MYSQLI_NUM) {
add_index_null(return_value, i);
}
if (fetchtype & MYSQLI_ASSOC) {
add_assoc_null(return_value, fields[i].name);
}
}
}
#else
mysqlnd_fetch_into(result, ((fetchtype & MYSQLI_NUM)? MYSQLND_FETCH_NUM:0) | ((fetchtype & MYSQLI_ASSOC)? MYSQLND_FETCH_ASSOC:0), return_value);
/* TODO: We don't have access to the connection object at this point, so we use low-level
* mysqlnd APIs to access the error information. We should try to pass through the connection
@ -1083,7 +898,6 @@ void php_mysqli_fetch_into_hash_aux(zval *return_value, MYSQL_RES * result, zend
conn->m->get_sqlstate(conn), error_no, conn->m->get_error_str(conn));
}
}
#endif
}
/* }}} */

View file

@ -214,14 +214,12 @@ class mysqli
*/
public function get_client_info(): string {}
#if defined(MYSQLI_USE_MYSQLND)
/**
* @return array<string, mixed>
* @tentative-return-type
* @alias mysqli_get_connection_stats
*/
public function get_connection_stats(): array {}
#endif
/**
* @tentative-return-type
@ -271,13 +269,11 @@ class mysqli
*/
public function ping(): bool {}
#if defined(MYSQLI_USE_MYSQLND)
/**
* @tentative-return-type
* @alias mysqli_poll
*/
public static function poll(?array &$read, ?array &$error, array &$reject, int $seconds, int $microseconds = 0): int|false {}
#endif
/**
* @tentative-return-type
@ -311,13 +307,11 @@ class mysqli
*/
public function real_escape_string(string $string): string {}
#if defined(MYSQLI_USE_MYSQLND)
/**
* @tentative-return-type
* @alias mysqli_reap_async_query
*/
public function reap_async_query(): mysqli_result|bool {}
#endif
/**
* @tentative-return-type
@ -665,13 +659,11 @@ class mysqli_stmt
*/
public function result_metadata(): mysqli_result|false {}
#if defined(MYSQLI_USE_MYSQLND)
/**
* @tentative-return-type
* @alias mysqli_stmt_more_results
*/
public function more_results(): bool {}
#endif
/**
* @tentative-return-type
@ -715,13 +707,11 @@ class mysqli_stmt
*/
public function store_result(): bool {}
#if defined(MYSQLI_USE_MYSQLND)
/**
* @tentative-return-type
* @alias mysqli_stmt_get_result
*/
public function get_result(): mysqli_result|false {}
#endif
}
final class mysqli_warning
@ -854,7 +844,6 @@ function mysqli_field_tell(mysqli_result $result): int {}
function mysqli_free_result(mysqli_result $result): void {}
#if defined(MYSQLI_USE_MYSQLND)
/**
* @return array<string, mixed>
* @refcount 1
@ -866,7 +855,6 @@ function mysqli_get_connection_stats(mysqli $mysql): array {}
* @refcount 1
*/
function mysqli_get_client_stats(): array {}
#endif
/** @refcount 1 */
function mysqli_get_charset(mysqli $mysql): ?object {}
@ -928,9 +916,7 @@ function mysqli_set_opt(mysqli $mysql, int $option, $value): bool {}
function mysqli_ping(mysqli $mysql): bool {}
#if defined(MYSQLI_USE_MYSQLND)
function mysqli_poll(?array &$read, ?array &$error, array &$reject, int $seconds, int $microseconds = 0): int|false {}
#endif
/** @refcount 1 */
function mysqli_prepare(mysqli $mysql, string $query): mysqli_stmt|false {}
@ -959,10 +945,8 @@ function mysqli_escape_string(mysqli $mysql, string $string): string {}
function mysqli_real_query(mysqli $mysql, string $query): bool {}
#if defined(MYSQLI_USE_MYSQLND)
/** @refcount 1 */
function mysqli_reap_async_query(mysqli $mysql): mysqli_result|bool {}
#endif
function mysqli_release_savepoint(mysqli $mysql, string $name): bool {}
@ -1007,10 +991,8 @@ function mysqli_stmt_field_count(mysqli_stmt $statement): int {}
function mysqli_stmt_free_result(mysqli_stmt $statement): void {}
#if defined(MYSQLI_USE_MYSQLND)
/** @refcount 1 */
function mysqli_stmt_get_result(mysqli_stmt $statement): mysqli_result|false {}
#endif
/** @refcount 1 */
function mysqli_stmt_get_warnings(mysqli_stmt $statement): mysqli_warning|false {}
@ -1021,9 +1003,7 @@ function mysqli_stmt_init(mysqli $mysql): mysqli_stmt|false {}
/** @refcount 1 */
function mysqli_stmt_insert_id(mysqli_stmt $statement): int|string {}
#if defined(MYSQLI_USE_MYSQLND)
function mysqli_stmt_more_results(mysqli_stmt $statement): bool {}
#endif
function mysqli_stmt_next_result(mysqli_stmt $statement): bool {}

View file

@ -33,108 +33,6 @@
#define ERROR_ARG_POS(arg_num) (getThis() ? (arg_num-1) : (arg_num))
#ifndef MYSQLI_USE_MYSQLND
/* {{{ mysqli_tx_cor_options_to_string */
static void mysqli_tx_cor_options_to_string(const MYSQL * const conn, smart_str * str, const uint32_t mode)
{
if (mode & TRANS_COR_AND_CHAIN && !(mode & TRANS_COR_AND_NO_CHAIN)) {
if (str->s && ZSTR_LEN(str->s)) {
smart_str_appendl(str, " ", sizeof(" ") - 1);
}
smart_str_appendl(str, "AND CHAIN", sizeof("AND CHAIN") - 1);
} else if (mode & TRANS_COR_AND_NO_CHAIN && !(mode & TRANS_COR_AND_CHAIN)) {
if (str->s && ZSTR_LEN(str->s)) {
smart_str_appendl(str, " ", sizeof(" ") - 1);
}
smart_str_appendl(str, "AND NO CHAIN", sizeof("AND NO CHAIN") - 1);
}
if (mode & TRANS_COR_RELEASE && !(mode & TRANS_COR_NO_RELEASE)) {
if (str->s && ZSTR_LEN(str->s)) {
smart_str_appendl(str, " ", sizeof(" ") - 1);
}
smart_str_appendl(str, "RELEASE", sizeof("RELEASE") - 1);
} else if (mode & TRANS_COR_NO_RELEASE && !(mode & TRANS_COR_RELEASE)) {
if (str->s && ZSTR_LEN(str->s)) {
smart_str_appendl(str, " ", sizeof(" ") - 1);
}
smart_str_appendl(str, "NO RELEASE", sizeof("NO RELEASE") - 1);
}
smart_str_0(str);
}
/* }}} */
/* {{{ mysqlnd_escape_string_for_tx_name_in_comment */
char *
mysqli_escape_string_for_tx_name_in_comment(const char * const name)
{
char * ret = NULL;
if (name) {
bool warned = false;
const char * p_orig = name;
char * p_copy;
p_copy = ret = emalloc(strlen(name) + 1 + 2 + 2 + 1); /* space, open, close, NullS */
*p_copy++ = ' ';
*p_copy++ = '/';
*p_copy++ = '*';
while (1) {
char v = *p_orig;
if (v == 0) {
break;
}
if ((v >= '0' && v <= '9') ||
(v >= 'a' && v <= 'z') ||
(v >= 'A' && v <= 'Z') ||
v == '-' ||
v == '_' ||
v == ' ' ||
v == '=')
{
*p_copy++ = v;
} else if (!warned) {
php_error_docref(NULL, E_WARNING, "Transaction name has been truncated, since it can only contain the A-Z, a-z, 0-9, \"\\\", \"-\", \"_\", and \"=\" characters");
warned = true;
}
++p_orig;
}
*p_copy++ = '*';
*p_copy++ = '/';
*p_copy++ = 0;
}
return ret;
}
/* }}} */
/* {{{ mysqli_commit_or_rollback_libmysql */
static int mysqli_commit_or_rollback_libmysql(MYSQL * conn, bool commit, const uint32_t mode, const char * const name)
{
int ret;
smart_str tmp_str = {0};
mysqli_tx_cor_options_to_string(conn, &tmp_str, mode);
smart_str_0(&tmp_str);
{
char *query;
char *name_esc = mysqli_escape_string_for_tx_name_in_comment(name);
size_t query_len;
query_len = spprintf(&query, 0,
(commit? "COMMIT%s %s":"ROLLBACK%s %s"), name_esc? name_esc:"", tmp_str.s? ZSTR_VAL(tmp_str.s):"");
smart_str_free(&tmp_str);
if (name_esc) {
efree(name_esc);
name_esc = NULL;
}
ret = mysql_real_query(conn, query, query_len);
efree(query);
}
return ret;
}
/* }}} */
#endif
/* {{{ Get number of affected rows in previous MySQL operation */
PHP_FUNCTION(mysqli_affected_rows)
{
@ -177,87 +75,6 @@ PHP_FUNCTION(mysqli_autocommit)
/* }}} */
/* {{{ mysqli_stmt_bind_param_do_bind */
#ifndef MYSQLI_USE_MYSQLND
static
int mysqli_stmt_bind_param_do_bind(MY_STMT *stmt, unsigned int num_vars, zval *args, const char * const types, unsigned int num_extra_args)
{
int i, ofs;
MYSQL_BIND *bind;
unsigned long rc;
/* prevent leak if variables are already bound */
if (stmt->param.var_cnt) {
php_free_stmt_bind_buffer(stmt->param, FETCH_SIMPLE);
}
stmt->param.is_null = ecalloc(num_vars, sizeof(char));
bind = (MYSQL_BIND *) ecalloc(num_vars, sizeof(MYSQL_BIND));
ofs = 0;
for (i = 0; i < num_vars; i++) {
zval *param;
if (Z_ISREF(args[i])) {
param = Z_REFVAL(args[i]);
} else {
param = &args[i];
}
/* set specified type */
switch (types[ofs]) {
case 'd': /* Double */
bind[ofs].buffer_type = MYSQL_TYPE_DOUBLE;
bind[ofs].buffer = &Z_DVAL_P(param);
bind[ofs].is_null = &stmt->param.is_null[ofs];
break;
case 'i': /* Integer */
#if SIZEOF_ZEND_LONG==8
bind[ofs].buffer_type = MYSQL_TYPE_LONGLONG;
#elif SIZEOF_ZEND_LONG==4
bind[ofs].buffer_type = MYSQL_TYPE_LONG;
#endif
bind[ofs].buffer = &Z_LVAL_P(param);
bind[ofs].is_null = &stmt->param.is_null[ofs];
break;
case 'b': /* Blob (send data) */
bind[ofs].buffer_type = MYSQL_TYPE_LONG_BLOB;
/* don't initialize is_null and length to 0 because we use ecalloc */
break;
case 's': /* string */
bind[ofs].buffer_type = MYSQL_TYPE_VAR_STRING;
/* don't initialize buffer and buffer_length because we use ecalloc */
bind[ofs].is_null = &stmt->param.is_null[ofs];
break;
default:
zend_argument_value_error(num_extra_args, "must only contain the \"b\", \"d\", \"i\", \"s\" type specifiers");
rc = 1;
goto end_1;
}
ofs++;
}
rc = mysql_stmt_bind_param(stmt->stmt, bind);
end_1:
if (rc) {
efree(stmt->param.is_null);
} else {
stmt->param.var_cnt = num_vars;
stmt->param.vars = safe_emalloc(num_vars, sizeof(zval), 0);
for (i = 0; i < num_vars; i++) {
if (bind[i].buffer_type != MYSQL_TYPE_LONG_BLOB) {
ZVAL_COPY(&stmt->param.vars[i], &args[i]);
} else {
ZVAL_UNDEF(&stmt->param.vars[i]);
}
}
}
efree(bind);
return rc;
}
#else
static
int mysqli_stmt_bind_param_do_bind(MY_STMT *stmt, unsigned int num_vars, zval *args, const char * const types, unsigned int num_extra_args)
{
@ -306,7 +123,6 @@ int mysqli_stmt_bind_param_do_bind(MY_STMT *stmt, unsigned int num_vars, zval *a
end:
return ret;
}
#endif
/* }}} */
/* {{{ Bind variables to a prepared statement as parameters */
@ -347,181 +163,6 @@ PHP_FUNCTION(mysqli_stmt_bind_param)
/* }}} */
/* {{{ mysqli_stmt_bind_result_do_bind */
#ifndef MYSQLI_USE_MYSQLND
/* TODO:
do_alloca, free_alloca
*/
static int
mysqli_stmt_bind_result_do_bind(MY_STMT *stmt, zval *args, unsigned int argc)
{
MYSQL_BIND *bind;
int i, ofs;
int var_cnt = argc;
zend_long col_type;
zend_ulong rc;
/* prevent leak if variables are already bound */
if (stmt->result.var_cnt) {
php_free_stmt_bind_buffer(stmt->result, FETCH_RESULT);
}
bind = (MYSQL_BIND *)ecalloc(var_cnt, sizeof(MYSQL_BIND));
{
int size;
char *p = emalloc(size= var_cnt * (sizeof(char) + sizeof(VAR_BUFFER)));
stmt->result.buf = (VAR_BUFFER *) p;
stmt->result.is_null = (my_bool *) (p + var_cnt * sizeof(VAR_BUFFER));
memset(p, 0, size);
}
for (i = 0; i < var_cnt; i++) {
ofs = i;
col_type = (stmt->stmt->fields) ? stmt->stmt->fields[ofs].type : MYSQL_TYPE_STRING;
switch (col_type) {
case MYSQL_TYPE_FLOAT:
stmt->result.buf[ofs].type = IS_DOUBLE;
stmt->result.buf[ofs].buflen = sizeof(float);
stmt->result.buf[ofs].val = (char *)emalloc(sizeof(float));
bind[ofs].buffer_type = MYSQL_TYPE_FLOAT;
bind[ofs].buffer = stmt->result.buf[ofs].val;
bind[ofs].is_null = &stmt->result.is_null[ofs];
break;
case MYSQL_TYPE_DOUBLE:
stmt->result.buf[ofs].type = IS_DOUBLE;
stmt->result.buf[ofs].buflen = sizeof(double);
/* allocate buffer for double */
stmt->result.buf[ofs].val = (char *)emalloc(sizeof(double));
bind[ofs].buffer_type = MYSQL_TYPE_DOUBLE;
bind[ofs].buffer = stmt->result.buf[ofs].val;
bind[ofs].is_null = &stmt->result.is_null[ofs];
break;
case MYSQL_TYPE_NULL:
stmt->result.buf[ofs].type = IS_NULL;
/*
don't initialize to 0 :
1. stmt->result.buf[ofs].buflen
2. bind[ofs].buffer
3. bind[ofs].buffer_length
because memory was allocated with ecalloc
*/
bind[ofs].buffer_type = MYSQL_TYPE_NULL;
bind[ofs].is_null = &stmt->result.is_null[ofs];
break;
case MYSQL_TYPE_SHORT:
case MYSQL_TYPE_TINY:
case MYSQL_TYPE_LONG:
case MYSQL_TYPE_INT24:
case MYSQL_TYPE_YEAR:
stmt->result.buf[ofs].type = IS_LONG;
/* don't set stmt->result.buf[ofs].buflen to 0, we used ecalloc */
stmt->result.buf[ofs].val = (char *)emalloc(sizeof(int));
bind[ofs].buffer_type = MYSQL_TYPE_LONG;
bind[ofs].buffer = stmt->result.buf[ofs].val;
bind[ofs].is_null = &stmt->result.is_null[ofs];
bind[ofs].is_unsigned = (stmt->stmt->fields[ofs].flags & UNSIGNED_FLAG) ? 1 : 0;
break;
case MYSQL_TYPE_LONGLONG:
case MYSQL_TYPE_BIT:
stmt->result.buf[ofs].type = IS_STRING;
stmt->result.buf[ofs].buflen = sizeof(my_ulonglong);
stmt->result.buf[ofs].val = (char *)emalloc(stmt->result.buf[ofs].buflen);
bind[ofs].buffer_type = col_type;
bind[ofs].buffer = stmt->result.buf[ofs].val;
bind[ofs].is_null = &stmt->result.is_null[ofs];
bind[ofs].buffer_length = stmt->result.buf[ofs].buflen;
bind[ofs].is_unsigned = (stmt->stmt->fields[ofs].flags & UNSIGNED_FLAG) ? 1 : 0;
bind[ofs].length = &stmt->result.buf[ofs].output_len;
break;
case MYSQL_TYPE_DATE:
case MYSQL_TYPE_TIME:
case MYSQL_TYPE_DATETIME:
case MYSQL_TYPE_NEWDATE:
case MYSQL_TYPE_VAR_STRING:
case MYSQL_TYPE_STRING:
case MYSQL_TYPE_TINY_BLOB:
case MYSQL_TYPE_BLOB:
case MYSQL_TYPE_MEDIUM_BLOB:
case MYSQL_TYPE_LONG_BLOB:
case MYSQL_TYPE_TIMESTAMP:
case MYSQL_TYPE_DECIMAL:
case MYSQL_TYPE_GEOMETRY:
#ifdef FIELD_TYPE_NEWDECIMAL
case MYSQL_TYPE_NEWDECIMAL:
#endif
{
my_bool tmp;
stmt->result.buf[ofs].type = IS_STRING;
/*
If the user has called $stmt->store_result() then we have asked
max_length to be updated. this is done only for BLOBS because we don't want to allocate
big chunkgs of memory 2^16 or 2^24
*/
if (stmt->stmt->fields[ofs].max_length == 0 &&
!mysql_stmt_attr_get(stmt->stmt, STMT_ATTR_UPDATE_MAX_LENGTH, &tmp) && !tmp)
{
/*
Allocate directly 256 because it's easier to allocate a bit more
than update max length even for text columns. Try SELECT UNION SELECT UNION with
different lengths and you will see that we get different lengths in stmt->stmt->fields[ofs].length
The just take 256 and saves us from realloc-ing.
*/
stmt->result.buf[ofs].buflen =
(stmt->stmt->fields) ? (stmt->stmt->fields[ofs].length) ? stmt->stmt->fields[ofs].length + 1: 256: 256;
} else {
/*
the user has called store_result(). if he does not there is no way to determine the
libmysql does not allow us to allocate 0 bytes for a buffer so we try 1
*/
if (!(stmt->result.buf[ofs].buflen = stmt->stmt->fields[ofs].max_length))
++stmt->result.buf[ofs].buflen;
}
stmt->result.buf[ofs].val = (char *)emalloc(stmt->result.buf[ofs].buflen);
bind[ofs].buffer_type = MYSQL_TYPE_STRING;
bind[ofs].buffer = stmt->result.buf[ofs].val;
bind[ofs].is_null = &stmt->result.is_null[ofs];
bind[ofs].buffer_length = stmt->result.buf[ofs].buflen;
bind[ofs].length = &stmt->result.buf[ofs].output_len;
break;
}
default:
php_error_docref(NULL, E_WARNING, "Server returned unknown type %ld. Probably your client library is incompatible with the server version you use!", col_type);
break;
}
}
rc = mysql_stmt_bind_result(stmt->stmt, bind);
MYSQLI_REPORT_STMT_ERROR(stmt->stmt);
if (rc) {
/* don't close the statement or subsequent usage (for example ->execute()) will lead to crash */
for (i=0; i < var_cnt ; i++) {
if (stmt->result.buf[i].val) {
efree(stmt->result.buf[i].val);
}
}
/* Don't free stmt->result.is_null because is_null & buf are one block of memory */
efree(stmt->result.buf);
} else {
stmt->result.var_cnt = var_cnt;
stmt->result.vars = safe_emalloc((var_cnt), sizeof(zval), 0);
for (i = 0; i < var_cnt; i++) {
ZVAL_COPY(&stmt->result.vars[i], &args[i]);
}
}
efree(bind);
return rc;
}
#else
static int
mysqli_stmt_bind_result_do_bind(MY_STMT *stmt, zval *args, unsigned int argc)
{
@ -535,7 +176,6 @@ mysqli_stmt_bind_result_do_bind(MY_STMT *stmt, zval *args, unsigned int argc)
}
return FAIL;
}
#endif
/* }}} */
/* {{{ Bind variables to a prepared statement for result storage */
@ -571,39 +211,18 @@ PHP_FUNCTION(mysqli_change_user)
char *user, *password, *dbname;
size_t user_len, password_len, dbname_len;
zend_ulong rc;
#ifndef MYSQLI_USE_MYSQLND
MY_CHARSET_INFO old_charset;
#endif
if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Osss!", &mysql_link, mysqli_link_class_entry, &user, &user_len, &password, &password_len, &dbname, &dbname_len) == FAILURE) {
RETURN_THROWS();
}
MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
#ifndef MYSQLI_USE_MYSQLND
mysql_get_character_set_info(mysql->mysql, &old_charset);
#endif
#ifdef MYSQLI_USE_MYSQLND
rc = mysqlnd_change_user_ex(mysql->mysql, user, password, dbname, false, (size_t) password_len);
#else
rc = mysql_change_user(mysql->mysql, user, password, dbname);
#endif
MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
if (rc) {
RETURN_FALSE;
}
#ifndef MYSQLI_USE_MYSQLND
if (mysql_get_server_version(mysql->mysql) < 50123L) {
/*
Request the current charset, or it will be reset to the system one.
5.0 doesn't support it. Support added in 5.1.23 by fixing the following bug :
Bug #30472 libmysql doesn't reset charset, insert_id after succ. mysql_change_user() call
*/
rc = mysql_set_character_set(mysql->mysql, old_charset.csname);
}
#endif
RETURN_TRUE;
}
@ -638,16 +257,10 @@ void php_mysqli_close(MY_MYSQL * mysql, int close_type, int resource_status)
if ((le = zend_hash_find_ptr(&EG(persistent_list), mysql->hash_key)) != NULL) {
if (le->type == php_le_pmysqli()) {
mysqli_plist_entry *plist = (mysqli_plist_entry *) le->ptr;
#ifdef MYSQLI_USE_MYSQLND
mysqlnd_end_psession(mysql->mysql);
#endif
if (MyG(rollback_on_cached_plink) &&
#ifndef MYSQLI_USE_MYSQLND
mysqli_commit_or_rollback_libmysql(mysql->mysql, false, TRANS_COR_NO_OPT, NULL))
#else
FAIL == mysqlnd_rollback(mysql->mysql, TRANS_COR_NO_OPT, NULL))
#endif
{
mysqli_close(mysql->mysql, close_type);
} else {
@ -700,11 +313,7 @@ PHP_FUNCTION(mysqli_commit)
}
MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
#ifndef MYSQLI_USE_MYSQLND
if (mysqli_commit_or_rollback_libmysql(mysql->mysql, true, flags, name)) {
#else
if (FAIL == mysqlnd_commit(mysql->mysql, flags, name)) {
#endif
MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
RETURN_FALSE;
}
@ -812,9 +421,6 @@ PHP_FUNCTION(mysqli_stmt_execute)
MY_STMT *stmt;
zval *mysql_stmt;
HashTable *input_params = NULL;
#ifndef MYSQLI_USE_MYSQLND
unsigned int i;
#endif
if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O|h!", &mysql_stmt, mysqli_stmt_class_entry, &input_params) == FAILURE) {
RETURN_THROWS();
@ -823,7 +429,6 @@ PHP_FUNCTION(mysqli_stmt_execute)
// bind-in-execute
if (input_params) {
#if defined(MYSQLI_USE_MYSQLND)
zval *tmp;
unsigned int index;
unsigned int hash_num_elements;
@ -856,66 +461,8 @@ PHP_FUNCTION(mysqli_stmt_execute)
MYSQLI_REPORT_STMT_ERROR(stmt->stmt);
RETVAL_FALSE;
}
#else
zend_argument_count_error("Binding parameters in execute is not supported with libmysqlclient");
RETURN_THROWS();
#endif
}
#ifndef MYSQLI_USE_MYSQLND
if (stmt->param.var_cnt) {
int j;
for (i = 0; i < stmt->param.var_cnt; i++) {
if (!Z_ISREF(stmt->param.vars[i])) {
continue;
}
for (j = i + 1; j < stmt->param.var_cnt; j++) {
/* Oops, someone binding the same variable - clone */
if (Z_ISREF(stmt->param.vars[j]) &&
Z_REFVAL(stmt->param.vars[j]) == Z_REFVAL(stmt->param.vars[i])) {
/*SEPARATE_ZVAL(&stmt->param.vars[j]);*/
Z_DELREF_P(&stmt->param.vars[j]);
ZVAL_COPY(&stmt->param.vars[j], Z_REFVAL(stmt->param.vars[j]));
break;
}
}
}
}
for (i = 0; i < stmt->param.var_cnt; i++) {
if (!Z_ISUNDEF(stmt->param.vars[i])) {
zval *param;
if (Z_ISREF(stmt->param.vars[i])) {
param = Z_REFVAL(stmt->param.vars[i]);
} else {
param = &stmt->param.vars[i];
}
if (!(stmt->param.is_null[i] = (Z_ISNULL_P(param)))) {
switch (stmt->stmt->params[i].buffer_type) {
case MYSQL_TYPE_VAR_STRING:
if (!try_convert_to_string(param)) {
RETURN_THROWS();
}
stmt->stmt->params[i].buffer = Z_STRVAL_P(param);
stmt->stmt->params[i].buffer_length = Z_STRLEN_P(param);
break;
case MYSQL_TYPE_DOUBLE:
convert_to_double(param);
stmt->stmt->params[i].buffer = &Z_DVAL_P(param);
break;
case MYSQL_TYPE_LONGLONG:
case MYSQL_TYPE_LONG:
convert_to_long(param);
stmt->stmt->params[i].buffer = &Z_LVAL_P(param);
break;
default:
break;
}
}
}
}
#endif
if (mysql_stmt_execute(stmt->stmt)) {
MYSQLI_REPORT_STMT_ERROR(stmt->stmt);
RETVAL_FALSE;
@ -929,171 +476,6 @@ PHP_FUNCTION(mysqli_stmt_execute)
}
/* }}} */
#ifndef MYSQLI_USE_MYSQLND
/* {{{ void mysqli_stmt_fetch_libmysql
Fetch results from a prepared statement into the bound variables */
void mysqli_stmt_fetch_libmysql(INTERNAL_FUNCTION_PARAMETERS)
{
MY_STMT *stmt;
zval *mysql_stmt;
unsigned int i;
zend_ulong ret;
my_ulonglong llval;
if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
RETURN_THROWS();
}
MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
/* reset buffers */
for (i = 0; i < stmt->result.var_cnt; i++) {
if (stmt->result.buf[i].type == IS_STRING) {
memset(stmt->result.buf[i].val, 0, stmt->result.buf[i].buflen);
}
}
ret = mysql_stmt_fetch(stmt->stmt);
#ifdef MYSQL_DATA_TRUNCATED
if (!ret || ret == MYSQL_DATA_TRUNCATED) {
#else
if (!ret) {
#endif
for (i = 0; i < stmt->result.var_cnt; i++) {
zval *result;
/* it must be a reference, isn't it? */
if (Z_ISREF(stmt->result.vars[i])) {
result = &stmt->result.vars[i];
} else {
continue; // but be safe ...
}
/* Even if the string is of length zero there is one byte alloced so efree() in all cases */
if (!stmt->result.is_null[i]) {
switch (stmt->result.buf[i].type) {
case IS_LONG:
if ((stmt->stmt->fields[i].type == MYSQL_TYPE_LONG)
&& (stmt->stmt->fields[i].flags & UNSIGNED_FLAG))
{
/* unsigned int (11) */
#if SIZEOF_ZEND_LONG == 4
unsigned int uval = *(unsigned int *) stmt->result.buf[i].val;
if (uval > INT_MAX) {
char *tmp, *p;
int j = 10;
tmp = emalloc(11);
p= &tmp[9];
do {
*p-- = (uval % 10) + 48;
uval = uval / 10;
} while (--j > 0);
tmp[10]= '\0';
/* unsigned int > INT_MAX is 10 digits - ALWAYS */
ZEND_TRY_ASSIGN_REF_STRINGL(result, tmp, 10);
efree(tmp);
break;
}
#endif
}
if (stmt->stmt->fields[i].flags & UNSIGNED_FLAG) {
ZEND_TRY_ASSIGN_REF_LONG(result, *(unsigned int *)stmt->result.buf[i].val);
} else {
ZEND_TRY_ASSIGN_REF_LONG(result, *(int *)stmt->result.buf[i].val);
}
break;
case IS_DOUBLE:
{
double dval;
if (stmt->stmt->bind[i].buffer_type == MYSQL_TYPE_FLOAT) {
#ifndef NOT_FIXED_DEC
# define NOT_FIXED_DEC 31
#endif
dval = mysql_float_to_double(*(float *)stmt->result.buf[i].val,
(stmt->stmt->fields[i].decimals >= NOT_FIXED_DEC) ? -1 :
stmt->stmt->fields[i].decimals);
} else {
dval = *((double *)stmt->result.buf[i].val);
}
ZEND_TRY_ASSIGN_REF_DOUBLE(result, dval);
break;
}
case IS_STRING:
if (stmt->stmt->bind[i].buffer_type == MYSQL_TYPE_LONGLONG
|| stmt->stmt->bind[i].buffer_type == MYSQL_TYPE_BIT
) {
my_bool uns = (stmt->stmt->fields[i].flags & UNSIGNED_FLAG)? 1:0;
if (stmt->stmt->bind[i].buffer_type == MYSQL_TYPE_BIT) {
switch (stmt->result.buf[i].output_len) {
case 8:llval = (my_ulonglong) bit_uint8korr(stmt->result.buf[i].val);break;
case 7:llval = (my_ulonglong) bit_uint7korr(stmt->result.buf[i].val);break;
case 6:llval = (my_ulonglong) bit_uint6korr(stmt->result.buf[i].val);break;
case 5:llval = (my_ulonglong) bit_uint5korr(stmt->result.buf[i].val);break;
case 4:llval = (my_ulonglong) bit_uint4korr(stmt->result.buf[i].val);break;
case 3:llval = (my_ulonglong) bit_uint3korr(stmt->result.buf[i].val);break;
case 2:llval = (my_ulonglong) bit_uint2korr(stmt->result.buf[i].val);break;
case 1:llval = (my_ulonglong) uint1korr(stmt->result.buf[i].val);break;
}
} else {
llval= *(my_ulonglong *) stmt->result.buf[i].val;
}
#if SIZEOF_ZEND_LONG==8
if (uns && llval > 9223372036854775807L) {
#elif SIZEOF_ZEND_LONG==4
if ((uns && llval > L64(2147483647)) ||
(!uns && (( L64(2147483647) < (my_longlong) llval) ||
(L64(-2147483648) > (my_longlong) llval))))
{
#endif
char tmp[22];
/* even though lval is declared as unsigned, the value
* may be negative. Therefore we cannot use MYSQLI_LLU_SPEC and must
* use MYSQLI_LL_SPEC.
*/
snprintf(tmp, sizeof(tmp), (stmt->stmt->fields[i].flags & UNSIGNED_FLAG)? MYSQLI_LLU_SPEC : MYSQLI_LL_SPEC, llval);
ZEND_TRY_ASSIGN_REF_STRING(result, tmp);
} else {
ZEND_TRY_ASSIGN_REF_LONG(result, llval);
}
} else {
if (ret == MYSQL_DATA_TRUNCATED && *(stmt->stmt->bind[i].error) != 0) {
/* result was truncated */
ZEND_TRY_ASSIGN_REF_STRINGL(result, stmt->result.buf[i].val, stmt->stmt->bind[i].buffer_length);
} else {
ZEND_TRY_ASSIGN_REF_STRINGL(result, stmt->result.buf[i].val, stmt->result.buf[i].output_len);
}
}
break;
default:
break;
}
} else {
ZEND_TRY_ASSIGN_REF_NULL(result);
}
}
} else {
MYSQLI_REPORT_STMT_ERROR(stmt->stmt);
}
switch (ret) {
case 0:
#ifdef MYSQL_DATA_TRUNCATED
/* according to SQL standard truncation (e.g. loss of precision is
not an error) - for detecting possible truncation you have to
check mysqli_stmt_warning
*/
case MYSQL_DATA_TRUNCATED:
#endif
RETURN_TRUE;
break;
case 1:
RETURN_FALSE;
break;
default:
RETURN_NULL();
break;
}
}
/* }}} */
#else
/* {{{ mixed mysqli_stmt_fetch_mysqlnd */
void mysqli_stmt_fetch_mysqlnd(INTERNAL_FUNCTION_PARAMETERS)
{
@ -1115,28 +497,19 @@ void mysqli_stmt_fetch_mysqlnd(INTERNAL_FUNCTION_PARAMETERS)
RETURN_NULL();
}
}
#endif
/* }}} */
/* {{{ Fetch results from a prepared statement into the bound variables */
PHP_FUNCTION(mysqli_stmt_fetch)
{
#ifndef MYSQLI_USE_MYSQLND
mysqli_stmt_fetch_libmysql(INTERNAL_FUNCTION_PARAM_PASSTHRU);
#else
mysqli_stmt_fetch_mysqlnd(INTERNAL_FUNCTION_PARAM_PASSTHRU);
#endif
}
/* }}} */
/* {{{ php_add_field_properties */
static void php_add_field_properties(zval *value, const MYSQL_FIELD *field)
{
#ifdef MYSQLI_USE_MYSQLND
add_property_str(value, "name", zend_string_copy(field->sname));
#else
add_property_stringl(value, "name",(field->name ? field->name : ""), field->name_length);
#endif
add_property_stringl(value, "orgname", (field->org_name ? field->org_name : ""), field->org_name_length);
add_property_stringl(value, "table", (field->table ? field->table : ""), field->table_length);
@ -1249,11 +622,7 @@ PHP_FUNCTION(mysqli_fetch_lengths)
MYSQL_RES *result;
zval *mysql_result;
unsigned int i, num_fields;
#ifdef MYSQLI_USE_MYSQLND
const size_t *ret;
#else
const unsigned long *ret;
#endif
if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) {
RETURN_THROWS();
@ -1400,11 +769,7 @@ PHP_FUNCTION(mysqli_get_host_info)
RETURN_THROWS();
}
MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
#ifndef MYSQLI_USE_MYSQLND
RETURN_STRING((mysql->mysql->host_info) ? mysql->mysql->host_info : "");
#else
RETURN_STRING((mysql->mysql->data->host_info) ? mysql->mysql->data->host_info : "");
#endif
}
/* }}} */
@ -1487,15 +852,11 @@ void php_mysqli_init(INTERNAL_FUNCTION_PARAMETERS, bool is_method)
mysql = (MY_MYSQL *)ecalloc(1, sizeof(MY_MYSQL));
#ifndef MYSQLI_USE_MYSQLND
if (!(mysql->mysql = mysql_init(NULL)))
#else
/*
We create always persistent, as if the user want to connect
to p:somehost, we can't convert the handle then
*/
if (!(mysql->mysql = mysqlnd_init(MYSQLND_CLIENT_NO_FLAG, true)))
#endif
{
efree(mysql);
RETURN_FALSE;
@ -1595,8 +956,7 @@ PHP_FUNCTION(mysqli_next_result) {
}
/* }}} */
/* TODO: Make these available without mysqlnd */
#if defined(MYSQLI_USE_MYSQLND)
/* {{{ check if there any more query results from a multi query */
PHP_FUNCTION(mysqli_stmt_more_results)
{
@ -1611,7 +971,6 @@ PHP_FUNCTION(mysqli_stmt_more_results)
RETURN_BOOL(mysqlnd_stmt_more_results(stmt->stmt));
}
/* }}} */
#endif
/* {{{ read next result from multi_query */
PHP_FUNCTION(mysqli_stmt_next_result) {
@ -1670,11 +1029,9 @@ PHP_FUNCTION(mysqli_num_rows)
static int mysqli_options_get_option_zval_type(int option)
{
switch (option) {
#ifdef MYSQLI_USE_MYSQLND
case MYSQLND_OPT_NET_CMD_BUFFER_SIZE:
case MYSQLND_OPT_NET_READ_BUFFER_SIZE:
case MYSQLND_OPT_INT_AND_FLOAT_NATIVE:
#endif /* MYSQLI_USE_MYSQLND */
case MYSQL_OPT_CONNECT_TIMEOUT:
#ifdef MYSQL_REPORT_DATA_TRUNCATION
case MYSQL_REPORT_DATA_TRUNCATION:
@ -1701,9 +1058,7 @@ static int mysqli_options_get_option_zval_type(int option)
#ifdef MYSQL_OPT_COMPRESS
case MYSQL_OPT_COMPRESS:
#endif /* mysqlnd @ PHP 5.3.2 */
#if (MYSQL_VERSION_ID >= 50611 && defined(CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS)) || defined(MYSQLI_USE_MYSQLND)
case MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS:
#endif
return IS_LONG;
#ifdef MYSQL_SHARED_MEMORY_BASE_NAME
@ -1717,12 +1072,8 @@ static int mysqli_options_get_option_zval_type(int option)
case MYSQL_INIT_COMMAND:
case MYSQL_SET_CHARSET_NAME:
case MYSQL_SET_CHARSET_DIR:
#if MYSQL_VERSION_ID > 50605 || defined(MYSQLI_USE_MYSQLND)
case MYSQL_SERVER_PUBLIC_KEY:
#endif
#if (MYSQL_VERSION_ID >= 80021 && !defined(MARIADB_BASE_VERSION)) || defined(MYSQLI_USE_MYSQLND)
case MYSQL_OPT_LOAD_DATA_LOCAL_DIR:
#endif
return IS_STRING;
default:
@ -1747,13 +1098,6 @@ PHP_FUNCTION(mysqli_options)
}
MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_INITIALIZED);
#ifndef MYSQLI_USE_MYSQLND
if (PG(open_basedir) && PG(open_basedir)[0] != '\0') {
if(mysql_option == MYSQL_OPT_LOCAL_INFILE) {
RETURN_FALSE;
}
}
#endif
expected_type = mysqli_options_get_option_zval_type(mysql_option);
if (expected_type != Z_TYPE_P(mysql_value)) {
switch (expected_type) {
@ -1823,44 +1167,21 @@ PHP_FUNCTION(mysqli_prepare)
}
MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
#ifndef MYSQLI_USE_MYSQLND
if (mysql->mysql->status == MYSQL_STATUS_GET_RESULT) {
php_error_docref(NULL, E_WARNING, "All data must be fetched before a new statement prepare takes place");
RETURN_FALSE;
}
#endif
stmt = (MY_STMT *)ecalloc(1,sizeof(MY_STMT));
if ((stmt->stmt = mysql_stmt_init(mysql->mysql))) {
if (mysql_stmt_prepare(stmt->stmt, query, query_len)) {
/* mysql_stmt_close() clears errors, so we have to store them temporarily */
#ifndef MYSQLI_USE_MYSQLND
char last_error[MYSQL_ERRMSG_SIZE];
char sqlstate[SQLSTATE_LENGTH+1];
unsigned int last_errno;
last_errno = stmt->stmt->last_errno;
memcpy(last_error, stmt->stmt->last_error, MYSQL_ERRMSG_SIZE);
memcpy(sqlstate, mysql->mysql->net.sqlstate, SQLSTATE_LENGTH+1);
#else
MYSQLND_ERROR_INFO error_info = *mysql->mysql->data->error_info;
mysql->mysql->data->error_info->error_list.head = NULL;
mysql->mysql->data->error_info->error_list.tail = NULL;
mysql->mysql->data->error_info->error_list.count = 0;
#endif
mysqli_stmt_close(stmt->stmt, false);
stmt->stmt = NULL;
/* restore error messages */
#ifndef MYSQLI_USE_MYSQLND
mysql->mysql->net.last_errno = last_errno;
memcpy(mysql->mysql->net.last_error, last_error, MYSQL_ERRMSG_SIZE);
memcpy(mysql->mysql->net.sqlstate, sqlstate, SQLSTATE_LENGTH+1);
#else
zend_llist_clean(&mysql->mysql->data->error_info->error_list);
*mysql->mysql->data->error_info = error_info;
#endif
}
}
@ -1878,9 +1199,6 @@ PHP_FUNCTION(mysqli_prepare)
efree(stmt);
RETURN_FALSE;
}
#ifndef MYSQLI_USE_MYSQLND
ZVAL_COPY(&stmt->link_handle, mysql_link);
#endif
mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
mysqli_resource->ptr = (void *)stmt;
@ -1928,10 +1246,8 @@ PHP_FUNCTION(mysqli_real_query)
}
/* }}} */
#if defined(MYSQLI_USE_MYSQLND) || MYSQL_VERSION_ID < 50707 || defined(MARIADB_BASE_VERSION)
# define mysql_real_escape_string_quote(mysql, to, from, length, quote) \
mysql_real_escape_string(mysql, to, from, length)
#endif
PHP_FUNCTION(mysqli_real_escape_string) {
MY_MYSQL *mysql;
@ -1966,11 +1282,8 @@ PHP_FUNCTION(mysqli_rollback)
}
MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
#ifndef MYSQLI_USE_MYSQLND
if (mysqli_commit_or_rollback_libmysql(mysql->mysql, false, flags, name)) {
#else
if (FAIL == mysqlnd_rollback(mysql->mysql, flags, name)) {
#endif
MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
RETURN_FALSE;
}
@ -2230,26 +1543,16 @@ PHP_FUNCTION(mysqli_stat)
{
MY_MYSQL *mysql;
zval *mysql_link;
#ifdef MYSQLI_USE_MYSQLND
zend_string *stat;
#else
char *stat;
#endif
if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
RETURN_THROWS();
}
MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
#ifndef MYSQLI_USE_MYSQLND
if ((stat = (char *)mysql_stat(mysql->mysql)))
{
RETURN_STRING(stat);
#else
if (mysqlnd_stat(mysql->mysql, &stat) == PASS)
{
RETURN_STR(stat);
#endif
} else {
RETURN_FALSE;
}
@ -2268,11 +1571,7 @@ PHP_FUNCTION(mysqli_refresh)
RETURN_THROWS();
}
MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_INITIALIZED);
#ifdef MYSQLI_USE_MYSQLND
RETURN_BOOL(!mysql_refresh(mysql->mysql, (uint8_t) options));
#else
RETURN_BOOL(!mysql_refresh(mysql->mysql, options));
#endif
}
/* }}} */
@ -2332,12 +1631,7 @@ PHP_FUNCTION(mysqli_stmt_attr_set)
RETURN_THROWS();
}
// TODO Can unify this?
#ifndef MYSQLI_USE_MYSQLND
if (mysql_stmt_attr_set(stmt->stmt, attr, mode_p)) {
#else
if (FAIL == mysql_stmt_attr_set(stmt->stmt, attr, mode_p)) {
#endif
MYSQLI_REPORT_STMT_ERROR(stmt->stmt);
RETURN_FALSE;
}
@ -2425,9 +1719,6 @@ PHP_FUNCTION(mysqli_stmt_init)
efree(stmt);
RETURN_FALSE;
}
#ifndef MYSQLI_USE_MYSQLND
ZVAL_COPY(&stmt->link_handle, mysql_link);
#endif
mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
mysqli_resource->status = MYSQLI_STATUS_INITIALIZED;
@ -2495,31 +1786,6 @@ PHP_FUNCTION(mysqli_stmt_store_result)
}
MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
#ifndef MYSQLI_USE_MYSQLND
{
/*
If the user wants to store the data and we have BLOBs/TEXTs we try to allocate
not the maximal length of the type (which is 16MB even for LONGBLOB) but
the maximal length of the field in the result set. If he/she has quite big
BLOB/TEXT columns after calling store_result() the memory usage of PHP will
double - but this is a known problem of the simple MySQL API ;)
*/
int i = 0;
for (i = mysql_stmt_field_count(stmt->stmt) - 1; i >=0; --i) {
if (stmt->stmt->fields && (stmt->stmt->fields[i].type == MYSQL_TYPE_BLOB ||
stmt->stmt->fields[i].type == MYSQL_TYPE_MEDIUM_BLOB ||
stmt->stmt->fields[i].type == MYSQL_TYPE_LONG_BLOB ||
stmt->stmt->fields[i].type == MYSQL_TYPE_GEOMETRY))
{
my_bool tmp = 1;
mysql_stmt_attr_set(stmt->stmt, STMT_ATTR_UPDATE_MAX_LENGTH, &tmp);
break;
}
}
}
#endif
if (mysql_stmt_store_result(stmt->stmt)){
MYSQLI_REPORT_STMT_ERROR(stmt->stmt);
RETURN_FALSE;

View file

@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead.
* Stub hash: 9ef8917aa1b4fe7420fe12c5629ef00f36df3256 */
* Stub hash: ea4a03b57cca3cf4e103d76d8e283eb853e77a75 */
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_mysqli_affected_rows, 0, 1, MAY_BE_LONG|MAY_BE_STRING)
ZEND_ARG_OBJ_INFO(0, mysql, mysqli, 0)
@ -135,16 +135,10 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_mysqli_free_result, 0, 1, IS_VOI
ZEND_ARG_OBJ_INFO(0, result, mysqli_result, 0)
ZEND_END_ARG_INFO()
#if defined(MYSQLI_USE_MYSQLND)
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_mysqli_get_connection_stats, 0, 1, IS_ARRAY, 0)
ZEND_ARG_OBJ_INFO(0, mysql, mysqli, 0)
ZEND_END_ARG_INFO()
#endif
#define arginfo_mysqli_get_connection_stats arginfo_mysqli_error_list
#if defined(MYSQLI_USE_MYSQLND)
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_mysqli_get_client_stats, 0, 0, IS_ARRAY, 0)
ZEND_END_ARG_INFO()
#endif
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_mysqli_get_charset, 0, 1, IS_OBJECT, 1)
ZEND_ARG_OBJ_INFO(0, mysql, mysqli, 0)
@ -156,8 +150,7 @@ ZEND_END_ARG_INFO()
#define arginfo_mysqli_get_client_version arginfo_mysqli_connect_errno
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_mysqli_get_links_stats, 0, 0, IS_ARRAY, 0)
ZEND_END_ARG_INFO()
#define arginfo_mysqli_get_links_stats arginfo_mysqli_get_client_stats
#define arginfo_mysqli_get_host_info arginfo_mysqli_character_set_name
@ -210,7 +203,6 @@ ZEND_END_ARG_INFO()
#define arginfo_mysqli_ping arginfo_mysqli_close
#if defined(MYSQLI_USE_MYSQLND)
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_mysqli_poll, 0, 4, MAY_BE_LONG|MAY_BE_FALSE)
ZEND_ARG_TYPE_INFO(1, read, IS_ARRAY, 1)
ZEND_ARG_TYPE_INFO(1, error, IS_ARRAY, 1)
@ -218,7 +210,6 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_mysqli_poll, 0, 4, MAY_BE_LONG|M
ZEND_ARG_TYPE_INFO(0, seconds, IS_LONG, 0)
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, microseconds, IS_LONG, 0, "0")
ZEND_END_ARG_INFO()
#endif
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_mysqli_prepare, 0, 2, mysqli_stmt, MAY_BE_FALSE)
ZEND_ARG_OBJ_INFO(0, mysql, mysqli, 0)
@ -255,11 +246,9 @@ ZEND_END_ARG_INFO()
#define arginfo_mysqli_real_query arginfo_mysqli_multi_query
#if defined(MYSQLI_USE_MYSQLND)
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_mysqli_reap_async_query, 0, 1, mysqli_result, MAY_BE_BOOL)
ZEND_ARG_OBJ_INFO(0, mysql, mysqli, 0)
ZEND_END_ARG_INFO()
#endif
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_mysqli_release_savepoint, 0, 2, _IS_BOOL, 0)
ZEND_ARG_OBJ_INFO(0, mysql, mysqli, 0)
@ -337,11 +326,9 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_mysqli_stmt_free_result, 0, 1, I
ZEND_ARG_OBJ_INFO(0, statement, mysqli_stmt, 0)
ZEND_END_ARG_INFO()
#if defined(MYSQLI_USE_MYSQLND)
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_mysqli_stmt_get_result, 0, 1, mysqli_result, MAY_BE_FALSE)
ZEND_ARG_OBJ_INFO(0, statement, mysqli_stmt, 0)
ZEND_END_ARG_INFO()
#endif
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_mysqli_stmt_get_warnings, 0, 1, mysqli_warning, MAY_BE_FALSE)
ZEND_ARG_OBJ_INFO(0, statement, mysqli_stmt, 0)
@ -353,11 +340,7 @@ ZEND_END_ARG_INFO()
#define arginfo_mysqli_stmt_insert_id arginfo_mysqli_stmt_affected_rows
#if defined(MYSQLI_USE_MYSQLND)
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_mysqli_stmt_more_results, 0, 1, _IS_BOOL, 0)
ZEND_ARG_OBJ_INFO(0, statement, mysqli_stmt, 0)
ZEND_END_ARG_INFO()
#endif
#define arginfo_mysqli_stmt_more_results arginfo_mysqli_stmt_close
#define arginfo_mysqli_stmt_next_result arginfo_mysqli_stmt_close
@ -372,9 +355,7 @@ ZEND_END_ARG_INFO()
#define arginfo_mysqli_stmt_reset arginfo_mysqli_stmt_close
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_mysqli_stmt_result_metadata, 0, 1, mysqli_result, MAY_BE_FALSE)
ZEND_ARG_OBJ_INFO(0, statement, mysqli_stmt, 0)
ZEND_END_ARG_INFO()
#define arginfo_mysqli_stmt_result_metadata arginfo_mysqli_stmt_get_result
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_mysqli_stmt_send_long_data, 0, 3, _IS_BOOL, 0)
ZEND_ARG_OBJ_INFO(0, statement, mysqli_stmt, 0)
@ -475,10 +456,8 @@ ZEND_END_ARG_INFO()
#define arginfo_class_mysqli_get_client_info arginfo_class_mysqli_character_set_name
#if defined(MYSQLI_USE_MYSQLND)
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_mysqli_get_connection_stats, 0, 0, IS_ARRAY, 0)
ZEND_END_ARG_INFO()
#endif
#define arginfo_class_mysqli_get_server_info arginfo_class_mysqli_character_set_name
@ -501,7 +480,6 @@ ZEND_END_ARG_INFO()
#define arginfo_class_mysqli_ping arginfo_class_mysqli_dump_debug_info
#if defined(MYSQLI_USE_MYSQLND)
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_MASK_EX(arginfo_class_mysqli_poll, 0, 4, MAY_BE_LONG|MAY_BE_FALSE)
ZEND_ARG_TYPE_INFO(1, read, IS_ARRAY, 1)
ZEND_ARG_TYPE_INFO(1, error, IS_ARRAY, 1)
@ -509,7 +487,6 @@ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_MASK_EX(arginfo_class_mysqli_poll, 0,
ZEND_ARG_TYPE_INFO(0, seconds, IS_LONG, 0)
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, microseconds, IS_LONG, 0, "0")
ZEND_END_ARG_INFO()
#endif
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_mysqli_prepare, 0, 1, mysqli_stmt, MAY_BE_FALSE)
ZEND_ARG_TYPE_INFO(0, query, IS_STRING, 0)
@ -534,10 +511,8 @@ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_mysqli_real_esca
ZEND_ARG_TYPE_INFO(0, string, IS_STRING, 0)
ZEND_END_ARG_INFO()
#if defined(MYSQLI_USE_MYSQLND)
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_mysqli_reap_async_query, 0, 0, mysqli_result, MAY_BE_BOOL)
ZEND_END_ARG_INFO()
#endif
#define arginfo_class_mysqli_escape_string arginfo_class_mysqli_real_escape_string
@ -610,8 +585,7 @@ ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_MASK_EX(arginfo_class_mysqli_result_fetch_field, 0, 0, MAY_BE_OBJECT|MAY_BE_FALSE)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_mysqli_result_fetch_fields, 0, 0, IS_ARRAY, 0)
ZEND_END_ARG_INFO()
#define arginfo_class_mysqli_result_fetch_fields arginfo_class_mysqli_get_connection_stats
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_MASK_EX(arginfo_class_mysqli_result_fetch_field_direct, 0, 1, MAY_BE_OBJECT|MAY_BE_FALSE)
ZEND_ARG_TYPE_INFO(0, index, IS_LONG, 0)
@ -688,10 +662,7 @@ ZEND_END_ARG_INFO()
#define arginfo_class_mysqli_stmt_result_metadata arginfo_class_mysqli_use_result
#if defined(MYSQLI_USE_MYSQLND)
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_mysqli_stmt_more_results, 0, 0, _IS_BOOL, 0)
ZEND_END_ARG_INFO()
#endif
#define arginfo_class_mysqli_stmt_more_results arginfo_class_mysqli_dump_debug_info
#define arginfo_class_mysqli_stmt_next_result arginfo_class_mysqli_dump_debug_info
@ -711,10 +682,7 @@ ZEND_END_ARG_INFO()
#define arginfo_class_mysqli_stmt_store_result arginfo_class_mysqli_dump_debug_info
#if defined(MYSQLI_USE_MYSQLND)
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_mysqli_stmt_get_result, 0, 0, mysqli_result, MAY_BE_FALSE)
ZEND_END_ARG_INFO()
#endif
#define arginfo_class_mysqli_stmt_get_result arginfo_class_mysqli_use_result
#define arginfo_class_mysqli_warning___construct arginfo_class_mysqli_close
@ -755,12 +723,8 @@ ZEND_FUNCTION(mysqli_field_count);
ZEND_FUNCTION(mysqli_field_seek);
ZEND_FUNCTION(mysqli_field_tell);
ZEND_FUNCTION(mysqli_free_result);
#if defined(MYSQLI_USE_MYSQLND)
ZEND_FUNCTION(mysqli_get_connection_stats);
#endif
#if defined(MYSQLI_USE_MYSQLND)
ZEND_FUNCTION(mysqli_get_client_stats);
#endif
ZEND_FUNCTION(mysqli_get_charset);
ZEND_FUNCTION(mysqli_get_client_info);
ZEND_FUNCTION(mysqli_get_client_version);
@ -781,18 +745,14 @@ ZEND_FUNCTION(mysqli_num_fields);
ZEND_FUNCTION(mysqli_num_rows);
ZEND_FUNCTION(mysqli_options);
ZEND_FUNCTION(mysqli_ping);
#if defined(MYSQLI_USE_MYSQLND)
ZEND_FUNCTION(mysqli_poll);
#endif
ZEND_FUNCTION(mysqli_prepare);
ZEND_FUNCTION(mysqli_report);
ZEND_FUNCTION(mysqli_query);
ZEND_FUNCTION(mysqli_real_connect);
ZEND_FUNCTION(mysqli_real_escape_string);
ZEND_FUNCTION(mysqli_real_query);
#if defined(MYSQLI_USE_MYSQLND)
ZEND_FUNCTION(mysqli_reap_async_query);
#endif
ZEND_FUNCTION(mysqli_release_savepoint);
ZEND_FUNCTION(mysqli_rollback);
ZEND_FUNCTION(mysqli_savepoint);
@ -811,15 +771,11 @@ ZEND_FUNCTION(mysqli_stmt_error_list);
ZEND_FUNCTION(mysqli_stmt_fetch);
ZEND_FUNCTION(mysqli_stmt_field_count);
ZEND_FUNCTION(mysqli_stmt_free_result);
#if defined(MYSQLI_USE_MYSQLND)
ZEND_FUNCTION(mysqli_stmt_get_result);
#endif
ZEND_FUNCTION(mysqli_stmt_get_warnings);
ZEND_FUNCTION(mysqli_stmt_init);
ZEND_FUNCTION(mysqli_stmt_insert_id);
#if defined(MYSQLI_USE_MYSQLND)
ZEND_FUNCTION(mysqli_stmt_more_results);
#endif
ZEND_FUNCTION(mysqli_stmt_next_result);
ZEND_FUNCTION(mysqli_stmt_num_rows);
ZEND_FUNCTION(mysqli_stmt_param_count);
@ -881,12 +837,8 @@ static const zend_function_entry ext_functions[] = {
ZEND_FE(mysqli_field_seek, arginfo_mysqli_field_seek)
ZEND_FE(mysqli_field_tell, arginfo_mysqli_field_tell)
ZEND_FE(mysqli_free_result, arginfo_mysqli_free_result)
#if defined(MYSQLI_USE_MYSQLND)
ZEND_FE(mysqli_get_connection_stats, arginfo_mysqli_get_connection_stats)
#endif
#if defined(MYSQLI_USE_MYSQLND)
ZEND_FE(mysqli_get_client_stats, arginfo_mysqli_get_client_stats)
#endif
ZEND_FE(mysqli_get_charset, arginfo_mysqli_get_charset)
ZEND_FE(mysqli_get_client_info, arginfo_mysqli_get_client_info)
ZEND_FE(mysqli_get_client_version, arginfo_mysqli_get_client_version)
@ -908,9 +860,7 @@ static const zend_function_entry ext_functions[] = {
ZEND_FE(mysqli_options, arginfo_mysqli_options)
ZEND_FALIAS(mysqli_set_opt, mysqli_options, arginfo_mysqli_set_opt)
ZEND_FE(mysqli_ping, arginfo_mysqli_ping)
#if defined(MYSQLI_USE_MYSQLND)
ZEND_FE(mysqli_poll, arginfo_mysqli_poll)
#endif
ZEND_FE(mysqli_prepare, arginfo_mysqli_prepare)
ZEND_FE(mysqli_report, arginfo_mysqli_report)
ZEND_FE(mysqli_query, arginfo_mysqli_query)
@ -918,9 +868,7 @@ static const zend_function_entry ext_functions[] = {
ZEND_FE(mysqli_real_escape_string, arginfo_mysqli_real_escape_string)
ZEND_FALIAS(mysqli_escape_string, mysqli_real_escape_string, arginfo_mysqli_escape_string)
ZEND_FE(mysqli_real_query, arginfo_mysqli_real_query)
#if defined(MYSQLI_USE_MYSQLND)
ZEND_FE(mysqli_reap_async_query, arginfo_mysqli_reap_async_query)
#endif
ZEND_FE(mysqli_release_savepoint, arginfo_mysqli_release_savepoint)
ZEND_FE(mysqli_rollback, arginfo_mysqli_rollback)
ZEND_FE(mysqli_savepoint, arginfo_mysqli_savepoint)
@ -939,15 +887,11 @@ static const zend_function_entry ext_functions[] = {
ZEND_FE(mysqli_stmt_fetch, arginfo_mysqli_stmt_fetch)
ZEND_FE(mysqli_stmt_field_count, arginfo_mysqli_stmt_field_count)
ZEND_FE(mysqli_stmt_free_result, arginfo_mysqli_stmt_free_result)
#if defined(MYSQLI_USE_MYSQLND)
ZEND_FE(mysqli_stmt_get_result, arginfo_mysqli_stmt_get_result)
#endif
ZEND_FE(mysqli_stmt_get_warnings, arginfo_mysqli_stmt_get_warnings)
ZEND_FE(mysqli_stmt_init, arginfo_mysqli_stmt_init)
ZEND_FE(mysqli_stmt_insert_id, arginfo_mysqli_stmt_insert_id)
#if defined(MYSQLI_USE_MYSQLND)
ZEND_FE(mysqli_stmt_more_results, arginfo_mysqli_stmt_more_results)
#endif
ZEND_FE(mysqli_stmt_next_result, arginfo_mysqli_stmt_next_result)
ZEND_FE(mysqli_stmt_num_rows, arginfo_mysqli_stmt_num_rows)
ZEND_FE(mysqli_stmt_param_count, arginfo_mysqli_stmt_param_count)
@ -988,9 +932,7 @@ static const zend_function_entry class_mysqli_methods[] = {
ZEND_ME_MAPPING(debug, mysqli_debug, arginfo_class_mysqli_debug, ZEND_ACC_PUBLIC)
ZEND_ME_MAPPING(get_charset, mysqli_get_charset, arginfo_class_mysqli_get_charset, ZEND_ACC_PUBLIC)
ZEND_ME_MAPPING(get_client_info, mysqli_get_client_info, arginfo_class_mysqli_get_client_info, ZEND_ACC_PUBLIC|ZEND_ACC_DEPRECATED)
#if defined(MYSQLI_USE_MYSQLND)
ZEND_ME_MAPPING(get_connection_stats, mysqli_get_connection_stats, arginfo_class_mysqli_get_connection_stats, ZEND_ACC_PUBLIC)
#endif
ZEND_ME_MAPPING(get_server_info, mysqli_get_server_info, arginfo_class_mysqli_get_server_info, ZEND_ACC_PUBLIC)
ZEND_ME_MAPPING(get_warnings, mysqli_get_warnings, arginfo_class_mysqli_get_warnings, ZEND_ACC_PUBLIC)
ZEND_ME(mysqli, init, arginfo_class_mysqli_init, ZEND_ACC_PUBLIC|ZEND_ACC_DEPRECATED)
@ -999,16 +941,12 @@ static const zend_function_entry class_mysqli_methods[] = {
ZEND_ME_MAPPING(more_results, mysqli_more_results, arginfo_class_mysqli_more_results, ZEND_ACC_PUBLIC)
ZEND_ME_MAPPING(next_result, mysqli_next_result, arginfo_class_mysqli_next_result, ZEND_ACC_PUBLIC)
ZEND_ME_MAPPING(ping, mysqli_ping, arginfo_class_mysqli_ping, ZEND_ACC_PUBLIC)
#if defined(MYSQLI_USE_MYSQLND)
ZEND_ME_MAPPING(poll, mysqli_poll, arginfo_class_mysqli_poll, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
#endif
ZEND_ME_MAPPING(prepare, mysqli_prepare, arginfo_class_mysqli_prepare, ZEND_ACC_PUBLIC)
ZEND_ME_MAPPING(query, mysqli_query, arginfo_class_mysqli_query, ZEND_ACC_PUBLIC)
ZEND_ME_MAPPING(real_connect, mysqli_real_connect, arginfo_class_mysqli_real_connect, ZEND_ACC_PUBLIC)
ZEND_ME_MAPPING(real_escape_string, mysqli_real_escape_string, arginfo_class_mysqli_real_escape_string, ZEND_ACC_PUBLIC)
#if defined(MYSQLI_USE_MYSQLND)
ZEND_ME_MAPPING(reap_async_query, mysqli_reap_async_query, arginfo_class_mysqli_reap_async_query, ZEND_ACC_PUBLIC)
#endif
ZEND_ME_MAPPING(escape_string, mysqli_real_escape_string, arginfo_class_mysqli_escape_string, ZEND_ACC_PUBLIC)
ZEND_ME_MAPPING(real_query, mysqli_real_query, arginfo_class_mysqli_real_query, ZEND_ACC_PUBLIC)
ZEND_ME_MAPPING(release_savepoint, mysqli_release_savepoint, arginfo_class_mysqli_release_savepoint, ZEND_ACC_PUBLIC)
@ -1062,9 +1000,7 @@ static const zend_function_entry class_mysqli_stmt_methods[] = {
ZEND_ME_MAPPING(fetch, mysqli_stmt_fetch, arginfo_class_mysqli_stmt_fetch, ZEND_ACC_PUBLIC)
ZEND_ME_MAPPING(get_warnings, mysqli_stmt_get_warnings, arginfo_class_mysqli_stmt_get_warnings, ZEND_ACC_PUBLIC)
ZEND_ME_MAPPING(result_metadata, mysqli_stmt_result_metadata, arginfo_class_mysqli_stmt_result_metadata, ZEND_ACC_PUBLIC)
#if defined(MYSQLI_USE_MYSQLND)
ZEND_ME_MAPPING(more_results, mysqli_stmt_more_results, arginfo_class_mysqli_stmt_more_results, ZEND_ACC_PUBLIC)
#endif
ZEND_ME_MAPPING(next_result, mysqli_stmt_next_result, arginfo_class_mysqli_stmt_next_result, ZEND_ACC_PUBLIC)
ZEND_ME_MAPPING(num_rows, mysqli_stmt_num_rows, arginfo_class_mysqli_stmt_num_rows, ZEND_ACC_PUBLIC)
ZEND_ME_MAPPING(send_long_data, mysqli_stmt_send_long_data, arginfo_class_mysqli_stmt_send_long_data, ZEND_ACC_PUBLIC)
@ -1072,9 +1008,7 @@ static const zend_function_entry class_mysqli_stmt_methods[] = {
ZEND_ME_MAPPING(reset, mysqli_stmt_reset, arginfo_class_mysqli_stmt_reset, ZEND_ACC_PUBLIC)
ZEND_ME_MAPPING(prepare, mysqli_stmt_prepare, arginfo_class_mysqli_stmt_prepare, ZEND_ACC_PUBLIC)
ZEND_ME_MAPPING(store_result, mysqli_stmt_store_result, arginfo_class_mysqli_stmt_store_result, ZEND_ACC_PUBLIC)
#if defined(MYSQLI_USE_MYSQLND)
ZEND_ME_MAPPING(get_result, mysqli_stmt_get_result, arginfo_class_mysqli_stmt_get_result, ZEND_ACC_PUBLIC)
#endif
ZEND_FE_END
};

View file

@ -112,11 +112,6 @@ void mysqli_common_connect(INTERNAL_FUNCTION_PARAMETERS, bool is_real_connect, b
flags |= CLIENT_MULTI_RESULTS; /* needed for mysql_multi_query() */
/* remove some insecure options */
flags &= ~CLIENT_MULTI_STATEMENTS; /* don't allow multi_queries via connect parameter */
#ifndef MYSQLI_USE_MYSQLND
if (PG(open_basedir) && PG(open_basedir)[0] != '\0') {
flags &= ~CLIENT_LOCAL_FILES;
}
#endif
}
if (!socket_len || !socket) {
@ -179,9 +174,7 @@ void mysqli_common_connect(INTERNAL_FUNCTION_PARAMETERS, bool is_real_connect, b
#else
if (!mysql_ping(mysql->mysql)) {
#endif
#ifdef MYSQLI_USE_MYSQLND
mysqlnd_restart_psession(mysql->mysql);
#endif
MyG(num_active_persistent)++;
/* clear error */
@ -189,7 +182,6 @@ void mysqli_common_connect(INTERNAL_FUNCTION_PARAMETERS, bool is_real_connect, b
goto end;
} else {
#ifdef MYSQLI_USE_MYSQLND
if (mysql->mysql->data->vio->data->ssl) {
/* copy over pre-existing ssl settings so we can reuse them when reconnecting */
ssl = true;
@ -200,22 +192,7 @@ void mysqli_common_connect(INTERNAL_FUNCTION_PARAMETERS, bool is_real_connect, b
ssl_capath = mysql->mysql->data->vio->data->options.ssl_capath ? estrdup(mysql->mysql->data->vio->data->options.ssl_capath) : NULL;
ssl_cipher = mysql->mysql->data->vio->data->options.ssl_cipher ? estrdup(mysql->mysql->data->vio->data->options.ssl_cipher) : NULL;
}
#else
if (mysql->mysql->options.ssl_key
|| mysql->mysql->options.ssl_cert
|| mysql->mysql->options.ssl_ca
|| mysql->mysql->options.ssl_capath
|| mysql->mysql->options.ssl_cipher) {
/* copy over pre-existing ssl settings so we can reuse them when reconnecting */
ssl = true;
ssl_key = mysql->mysql->options.ssl_key ? estrdup(mysql->mysql->options.ssl_key) : NULL;
ssl_cert = mysql->mysql->options.ssl_cert ? estrdup(mysql->mysql->options.ssl_cert) : NULL;
ssl_ca = mysql->mysql->options.ssl_ca ? estrdup(mysql->mysql->options.ssl_ca) : NULL;
ssl_capath = mysql->mysql->options.ssl_capath ? estrdup(mysql->mysql->options.ssl_capath) : NULL;
ssl_cipher = mysql->mysql->options.ssl_cipher ? estrdup(mysql->mysql->options.ssl_cipher) : NULL;
}
#endif
mysqli_close(mysql->mysql, MYSQLI_CLOSE_IMPLICIT);
mysql->mysql = NULL;
}
@ -243,46 +220,12 @@ void mysqli_common_connect(INTERNAL_FUNCTION_PARAMETERS, bool is_real_connect, b
goto err;
}
if (!mysql->mysql) {
#ifndef MYSQLI_USE_MYSQLND
if (!(mysql->mysql = mysql_init(NULL))) {
#else
if (!(mysql->mysql = mysqlnd_init(MYSQLND_CLIENT_NO_FLAG, persistent))) {
#endif
goto err;
}
new_connection = true;
}
#ifndef MYSQLI_USE_MYSQLND
/* BC for prior to bug fix #53425 */
flags |= CLIENT_MULTI_RESULTS;
if (ssl) {
/* if we're here, this means previous conn was ssl, repopulate settings */
mysql_ssl_set(mysql->mysql, ssl_key, ssl_cert, ssl_ca, ssl_capath, ssl_cipher);
if (ssl_key) {
efree(ssl_key);
}
if (ssl_cert) {
efree(ssl_cert);
}
if (ssl_ca) {
efree(ssl_ca);
}
if (ssl_capath) {
efree(ssl_capath);
}
if (ssl_cipher) {
efree(ssl_cipher);
}
}
if (mysql_real_connect(mysql->mysql, hostname, username, passwd, dbname, port, socket, flags) == NULL)
#else
if (ssl) {
/* if we're here, this means previous conn was ssl, repopulate settings */
mysql_ssl_set(mysql->mysql, ssl_key, ssl_cert, ssl_ca, ssl_capath, ssl_cipher);
@ -309,7 +252,6 @@ void mysqli_common_connect(INTERNAL_FUNCTION_PARAMETERS, bool is_real_connect, b
}
if (mysqlnd_connect(mysql->mysql, hostname, username, passwd, passwd_len, dbname, dbname_len,
port, socket, flags, MYSQLND_CLIENT_NO_FLAG) == NULL)
#endif
{
/* Save error messages - for mysqli_connect_error() & mysqli_connect_errno() */
php_mysqli_set_error(mysql_errno(mysql->mysql), (char *) mysql_error(mysql->mysql));
@ -326,18 +268,12 @@ void mysqli_common_connect(INTERNAL_FUNCTION_PARAMETERS, bool is_real_connect, b
/* clear error */
php_mysqli_set_error(mysql_errno(mysql->mysql), (char *) mysql_error(mysql->mysql));
#ifndef MYSQLI_USE_MYSQLND
char reconnect = MyG(reconnect);
mysql_options(mysql->mysql, MYSQL_OPT_RECONNECT, (char *)&reconnect);
#endif
unsigned int allow_local_infile = MyG(allow_local_infile);
mysql_options(mysql->mysql, MYSQL_OPT_LOCAL_INFILE, (char *)&allow_local_infile);
#if (MYSQL_VERSION_ID >= 80021 && !defined(MARIADB_BASE_VERSION)) || defined(MYSQLI_USE_MYSQLND)
if (MyG(local_infile_directory) && !php_check_open_basedir(MyG(local_infile_directory))) {
mysql_options(mysql->mysql, MYSQL_OPT_LOAD_DATA_LOCAL_DIR, MyG(local_infile_directory));
}
#endif
end:
if (!mysqli_resource) {
@ -500,7 +436,6 @@ PHP_FUNCTION(mysqli_fetch_all)
}
/* }}} */
#ifdef MYSQLI_USE_MYSQLND
/* {{{ Returns statistics about the zval cache */
PHP_FUNCTION(mysqli_get_client_stats)
{
@ -525,7 +460,6 @@ PHP_FUNCTION(mysqli_get_connection_stats)
mysqlnd_get_connection_stats(mysql->mysql, return_value);
}
#endif
/* }}} */
/* {{{ Fetches all client errors */
@ -538,8 +472,7 @@ PHP_FUNCTION(mysqli_error_list)
RETURN_THROWS();
}
MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
#ifdef MYSQLI_USE_MYSQLND
if (1) {
MYSQLND_ERROR_LIST_ELEMENT * message;
zend_llist_position pos;
array_init(return_value);
@ -554,22 +487,6 @@ PHP_FUNCTION(mysqli_error_list)
add_assoc_string_ex(&single_error, "error", sizeof("error") - 1, message->error);
add_next_index_zval(return_value, &single_error);
}
} else {
RETURN_EMPTY_ARRAY();
}
#else
if (mysql_errno(mysql->mysql)) {
zval single_error;
array_init(return_value);
array_init(&single_error);
add_assoc_long_ex(&single_error, "errno", sizeof("errno") - 1, mysql_errno(mysql->mysql));
add_assoc_string_ex(&single_error, "sqlstate", sizeof("sqlstate") - 1, mysql_sqlstate(mysql->mysql));
add_assoc_string_ex(&single_error, "error", sizeof("error") - 1, mysql_error(mysql->mysql));
add_next_index_zval(return_value, &single_error);
} else {
RETURN_EMPTY_ARRAY();
}
#endif
}
/* }}} */
@ -583,7 +500,6 @@ PHP_FUNCTION(mysqli_stmt_error_list)
RETURN_THROWS();
}
MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_INITIALIZED);
#ifdef MYSQLI_USE_MYSQLND
if (stmt->stmt && stmt->stmt->data && stmt->stmt->data->error_info) {
MYSQLND_ERROR_LIST_ELEMENT * message;
zend_llist_position pos;
@ -602,19 +518,6 @@ PHP_FUNCTION(mysqli_stmt_error_list)
} else {
RETURN_EMPTY_ARRAY();
}
#else
if (mysql_stmt_errno(stmt->stmt)) {
zval single_error;
array_init(return_value);
array_init(&single_error);
add_assoc_long_ex(&single_error, "errno", sizeof("errno") - 1, mysql_stmt_errno(stmt->stmt));
add_assoc_string_ex(&single_error, "sqlstate", sizeof("sqlstate") - 1, mysql_stmt_sqlstate(stmt->stmt));
add_assoc_string_ex(&single_error, "error", sizeof("error") - 1, mysql_stmt_error(stmt->stmt));
add_next_index_zval(return_value, &single_error);
} else {
RETURN_EMPTY_ARRAY();
}
#endif
}
/* }}} */
@ -640,32 +543,15 @@ PHP_FUNCTION(mysqli_multi_query)
MYSQLI_ENABLE_MQ;
if (mysql_real_query(mysql->mysql, query, query_len)) {
#ifndef MYSQLI_USE_MYSQLND
char s_error[MYSQL_ERRMSG_SIZE], s_sqlstate[SQLSTATE_LENGTH+1];
unsigned int s_errno;
/* we have to save error information, cause
MYSQLI_DISABLE_MQ will reset error information */
strcpy(s_error, mysql_error(mysql->mysql));
strcpy(s_sqlstate, mysql_sqlstate(mysql->mysql));
s_errno = mysql_errno(mysql->mysql);
#else
MYSQLND_ERROR_INFO error_info = *mysql->mysql->data->error_info;
mysql->mysql->data->error_info->error_list.head = NULL;
mysql->mysql->data->error_info->error_list.tail = NULL;
mysql->mysql->data->error_info->error_list.count = 0;
#endif
MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
MYSQLI_DISABLE_MQ;
#ifndef MYSQLI_USE_MYSQLND
/* restore error information */
strcpy(mysql->mysql->net.last_error, s_error);
strcpy(mysql->mysql->net.sqlstate, s_sqlstate);
mysql->mysql->net.last_errno = s_errno;
#else
zend_llist_clean(&mysql->mysql->data->error_info->error_list);
*mysql->mysql->data->error_info = error_info;
#endif
RETURN_FALSE;
}
RETURN_TRUE;
@ -694,11 +580,7 @@ PHP_FUNCTION(mysqli_query)
if ((resultmode & ~MYSQLI_ASYNC) != MYSQLI_USE_RESULT &&
MYSQLI_STORE_RESULT != (resultmode & ~(MYSQLI_ASYNC | MYSQLI_STORE_RESULT_COPY_DATA))
) {
zend_argument_value_error(ERROR_ARG_POS(3), "must be either MYSQLI_USE_RESULT or MYSQLI_STORE_RESULT"
#ifdef MYSQLI_USE_MYSQLND
" with MYSQLI_ASYNC as an optional bitmask flag"
#endif
);
zend_argument_value_error(ERROR_ARG_POS(3), "must be either MYSQLI_USE_RESULT or MYSQLI_STORE_RESULT with MYSQLI_ASYNC as an optional bitmask flag");
RETURN_THROWS();
}
@ -707,7 +589,6 @@ PHP_FUNCTION(mysqli_query)
MYSQLI_DISABLE_MQ;
#ifdef MYSQLI_USE_MYSQLND
if (resultmode & MYSQLI_ASYNC) {
if (mysqli_async_query(mysql->mysql, query, query_len)) {
MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
@ -716,7 +597,6 @@ PHP_FUNCTION(mysqli_query)
mysql->async_result_fetch_type = resultmode & ~MYSQLI_ASYNC;
RETURN_TRUE;
}
#endif
if (mysql_real_query(mysql->mysql, query, query_len)) {
MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
@ -731,11 +611,7 @@ PHP_FUNCTION(mysqli_query)
RETURN_TRUE;
}
#ifdef MYSQLI_USE_MYSQLND
switch (resultmode & ~(MYSQLI_ASYNC | MYSQLI_STORE_RESULT_COPY_DATA)) {
#else
switch (resultmode & ~MYSQLI_ASYNC) {
#endif
case MYSQLI_STORE_RESULT:
result = mysql_store_result(mysql->mysql);
break;
@ -760,7 +636,6 @@ PHP_FUNCTION(mysqli_query)
}
/* }}} */
#ifdef MYSQLI_USE_MYSQLND
#include "php_network.h"
/* {{{ mysqlnd_zval_array_to_mysqlnd_array functions */
static int mysqlnd_zval_array_to_mysqlnd_array(zval *in_array, MYSQLND ***out_array)
@ -1018,7 +893,6 @@ PHP_FUNCTION(mysqli_stmt_get_result)
MYSQLI_RETVAL_RESOURCE(mysqli_resource, mysqli_result_class_entry);
}
/* }}} */
#endif
/* {{{ */
PHP_FUNCTION(mysqli_get_warnings)
@ -1034,11 +908,7 @@ PHP_FUNCTION(mysqli_get_warnings)
MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
if (mysql_warning_count(mysql->mysql)) {
#ifdef MYSQLI_USE_MYSQLND
w = php_get_warnings(mysql->mysql->data);
#else
w = php_get_warnings(mysql->mysql);
#endif
}
if (!w) {
RETURN_FALSE;
@ -1104,11 +974,7 @@ PHP_FUNCTION(mysqli_get_charset)
zval *mysql_link;
const char *name = NULL, *collation = NULL, *dir = NULL, *comment = NULL;
uint32_t minlength, maxlength, number, state;
#ifndef MYSQLI_USE_MYSQLND
MY_CHARSET_INFO cs;
#else
const MYSQLND_CHARSET *cs;
#endif
if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
RETURN_THROWS();
@ -1116,17 +982,6 @@ PHP_FUNCTION(mysqli_get_charset)
MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
#ifndef MYSQLI_USE_MYSQLND
mysql_get_character_set_info(mysql->mysql, &cs);
name = (char *)cs.csname;
collation = (char *)cs.name;
dir = (char *)cs.dir;
minlength = cs.mbminlen;
maxlength = cs.mbmaxlen;
number = cs.number;
state = cs.state;
comment = cs.comment;
#else
cs = mysql->mysql->data->charset;
if (!cs) {
php_error_docref(NULL, E_WARNING, "The connection has no charset associated");
@ -1139,7 +994,6 @@ PHP_FUNCTION(mysqli_get_charset)
number = cs->nr;
comment = cs->comment;
state = 1; /* all charsets are compiled in */
#endif
object_init(return_value);
add_property_string(return_value, "charset", (name) ? (char *)name : "");
@ -1153,56 +1007,6 @@ PHP_FUNCTION(mysqli_get_charset)
}
/* }}} */
#ifndef MYSQLI_USE_MYSQLND
extern char * mysqli_escape_string_for_tx_name_in_comment(const char * const name);
/* {{{ */
static int mysqli_begin_transaction_libmysql(MYSQL * conn, const unsigned int mode, const char * const name)
{
int ret;
smart_str tmp_str = {0};
char * name_esc;
char * query;
unsigned int query_len;
if (mode & TRANS_START_WITH_CONSISTENT_SNAPSHOT) {
if (tmp_str.s) {
smart_str_appendl(&tmp_str, ", ", sizeof(", ") - 1);
}
smart_str_appendl(&tmp_str, "WITH CONSISTENT SNAPSHOT", sizeof("WITH CONSISTENT SNAPSHOT") - 1);
}
if (mode & TRANS_START_READ_WRITE) {
if (tmp_str.s) {
smart_str_appendl(&tmp_str, ", ", sizeof(", ") - 1);
}
smart_str_appendl(&tmp_str, "READ WRITE", sizeof("READ WRITE") - 1);
} else if (mode & TRANS_START_READ_ONLY) {
if (tmp_str.s) {
smart_str_appendl(&tmp_str, ", ", sizeof(", ") - 1);
}
smart_str_appendl(&tmp_str, "READ ONLY", sizeof("READ ONLY") - 1);
}
smart_str_0(&tmp_str);
name_esc = mysqli_escape_string_for_tx_name_in_comment(name);
query_len = spprintf(&query, 0, "START TRANSACTION%s %s",
name_esc? name_esc:"", tmp_str.s? ZSTR_VAL(tmp_str.s):"");
smart_str_free(&tmp_str);
if (name_esc) {
efree(name_esc);
}
ret = mysql_real_query(conn, query, query_len);
efree(query);
if (ret && mode & (TRANS_START_READ_WRITE | TRANS_START_READ_ONLY) && mysql_errno(conn) == 1064) {
php_error_docref(NULL, E_WARNING, "This server version doesn't support 'READ WRITE' and 'READ ONLY'. Minimum 5.6.5 is required");
}
return ret;
}
/* }}} */
#endif
/* {{{ Starts a transaction */
PHP_FUNCTION(mysqli_begin_transaction)
{
@ -1225,33 +1029,13 @@ PHP_FUNCTION(mysqli_begin_transaction)
RETURN_THROWS();
}
#ifndef MYSQLI_USE_MYSQLND
if (mysqli_begin_transaction_libmysql(mysql->mysql, flags, name)) {
RETURN_FALSE;
}
#else
if (FAIL == mysqlnd_begin_transaction(mysql->mysql, flags, name)) {
RETURN_FALSE;
}
#endif
RETURN_TRUE;
}
/* }}} */
#ifndef MYSQLI_USE_MYSQLND
/* {{{ */
static int mysqli_savepoint_libmysql(MYSQL * conn, const char * const name, bool release)
{
int ret;
char * query;
unsigned int query_len = spprintf(&query, 0, release? "RELEASE SAVEPOINT `%s`":"SAVEPOINT `%s`", name);
ret = mysql_real_query(conn, query, query_len);
efree(query);
return ret;
}
/* }}} */
#endif
/* {{{ Starts a transaction */
PHP_FUNCTION(mysqli_savepoint)
{
@ -1269,11 +1053,7 @@ PHP_FUNCTION(mysqli_savepoint)
RETURN_THROWS();
}
#ifndef MYSQLI_USE_MYSQLND
if (mysqli_savepoint_libmysql(mysql->mysql, name, false)) {
#else
if (FAIL == mysqlnd_savepoint(mysql->mysql, name)) {
#endif
RETURN_FALSE;
}
RETURN_TRUE;
@ -1296,11 +1076,7 @@ PHP_FUNCTION(mysqli_release_savepoint)
zend_argument_value_error(ERROR_ARG_POS(2), "cannot be empty");
RETURN_THROWS();
}
#ifndef MYSQLI_USE_MYSQLND
if (mysqli_savepoint_libmysql(mysql->mysql, name, true)) {
#else
if (FAIL == mysqlnd_release_savepoint(mysql->mysql, name)) {
#endif
RETURN_FALSE;
}
RETURN_TRUE;

View file

@ -52,11 +52,7 @@ extern void php_mysqli_close(MY_MYSQL * mysql, int close_type, int resource_stat
extern void php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAMETERS, int override_flag, int into_object);
extern void php_clear_stmt_bind(MY_STMT *stmt);
extern void php_clear_mysql(MY_MYSQL *);
#ifdef MYSQLI_USE_MYSQLND
extern MYSQLI_WARNING *php_get_warnings(MYSQLND_CONN_DATA * mysql);
#else
extern MYSQLI_WARNING *php_get_warnings(MYSQL * mysql);
#endif
extern void php_clear_warnings(MYSQLI_WARNING *w);
extern void php_free_stmt_bind_buffer(BIND_BUFFER bbuf, int type);
@ -91,14 +87,8 @@ PHP_MYSQLI_EXPORT(zend_object *) mysqli_objects_new(zend_class_entry *);
#define MYSQLI_STORE_RESULT 0
#define MYSQLI_USE_RESULT 1
#ifdef MYSQLI_USE_MYSQLND
#define MYSQLI_ASYNC 8
#define MYSQLI_STORE_RESULT_COPY_DATA 16
#else
/* libmysql */
#define MYSQLI_ASYNC 0
#define MYSQLI_STORE_RESULT_COPY_DATA 0
#endif
/* for mysqli_fetch_assoc */
#define MYSQLI_ASSOC 1

View file

@ -204,8 +204,6 @@ static int link_error_list_read(mysqli_object *obj, zval *retval, bool quiet)
if (mysql) {
array_init(retval);
#ifdef MYSQLI_USE_MYSQLND
if (1) {
MYSQLND_ERROR_LIST_ELEMENT * message;
zend_llist_position pos;
for (message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_first_ex(&mysql->mysql->data->error_info->error_list, &pos);
@ -219,17 +217,6 @@ static int link_error_list_read(mysqli_object *obj, zval *retval, bool quiet)
add_assoc_string_ex(&single_error, "error", sizeof("error") - 1, message->error);
add_next_index_zval(retval, &single_error);
}
}
#else
if (mysql_errno(mysql->mysql)) {
zval single_error;
array_init(&single_error);
add_assoc_long_ex(&single_error, "errno", sizeof("errno") - 1, mysql_errno(mysql->mysql));
add_assoc_string_ex(&single_error, "sqlstate", sizeof("sqlstate") - 1, mysql_sqlstate(mysql->mysql));
add_assoc_string_ex(&single_error, "error", sizeof("error") - 1, mysql_error(mysql->mysql));
add_next_index_zval(retval, &single_error);
}
#endif
} else {
ZVAL_EMPTY_ARRAY(retval);
}
@ -273,11 +260,7 @@ static int result_type_read(mysqli_object *obj, zval *retval, bool quiet)
static int result_lengths_read(mysqli_object *obj, zval *retval, bool quiet)
{
MYSQL_RES *p;
#ifdef MYSQLI_USE_MYSQLND
const size_t *ret;
#else
const unsigned long *ret;
#endif
uint32_t field_count;
CHECK_STATUS(MYSQLI_STATUS_VALID, quiet);
@ -359,7 +342,6 @@ static int stmt_error_list_read(mysqli_object *obj, zval *retval, bool quiet)
stmt = (MY_STMT *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr;
if (stmt && stmt->stmt) {
array_init(retval);
#ifdef MYSQLI_USE_MYSQLND
if (stmt->stmt->data && stmt->stmt->data->error_info) {
MYSQLND_ERROR_LIST_ELEMENT * message;
zend_llist_position pos;
@ -375,16 +357,6 @@ static int stmt_error_list_read(mysqli_object *obj, zval *retval, bool quiet)
add_next_index_zval(retval, &single_error);
}
}
#else
if (mysql_stmt_errno(stmt->stmt)) {
zval single_error;
array_init(&single_error);
add_assoc_long_ex(&single_error, "errno", sizeof("errno") - 1, mysql_stmt_errno(stmt->stmt));
add_assoc_string_ex(&single_error, "sqlstate", sizeof("sqlstate") - 1, mysql_stmt_sqlstate(stmt->stmt));
add_assoc_string_ex(&single_error, "error", sizeof("error") - 1, mysql_stmt_error(stmt->stmt));
add_next_index_zval(retval, &single_error);
}
#endif
} else {
ZVAL_EMPTY_ARRAY(retval);
}

View file

@ -119,11 +119,7 @@ static void php_mysqli_result_iterator_rewind(zend_object_iterator *iter)
MYSQLI_FETCH_RESOURCE_BY_OBJ(result, MYSQL_RES *, intern, "mysqli_result", MYSQLI_STATUS_VALID);
if (mysqli_result_is_unbuffered(result)) {
#ifdef MYSQLI_USE_MYSQLND
if (result->unbuf->eof_reached) {
#else
if (result->eof) {
#endif
php_error_docref(NULL, E_WARNING, "Data fetched with MYSQLI_USE_RESULT can be iterated only once");
return;
}

View file

@ -48,53 +48,6 @@ void php_clear_warnings(MYSQLI_WARNING *w)
}
/* }}} */
#ifndef MYSQLI_USE_MYSQLND
/* {{{ MYSQLI_WARNING *php_new_warning */
static
MYSQLI_WARNING *php_new_warning(const char *reason, int errorno)
{
MYSQLI_WARNING *w;
w = (MYSQLI_WARNING *)ecalloc(1, sizeof(MYSQLI_WARNING));
ZVAL_UTF8_STRING(&(w->reason), reason, ZSTR_DUPLICATE);
ZVAL_UTF8_STRINGL(&(w->sqlstate), "HY000", sizeof("HY000") - 1, ZSTR_DUPLICATE);
w->errorno = errorno;
return w;
}
/* }}} */
/* {{{ MYSQLI_WARNING *php_get_warnings(MYSQL *mysql) */
MYSQLI_WARNING *php_get_warnings(MYSQL *mysql)
{
MYSQLI_WARNING *w, *first = NULL, *prev = NULL;
MYSQL_RES *result;
MYSQL_ROW row;
if (mysql_real_query(mysql, "SHOW WARNINGS", 13)) {
return NULL;
}
result = mysql_store_result(mysql);
while ((row = mysql_fetch_row(result))) {
w = php_new_warning(row[2], atoi(row[1]));
if (!first) {
first = w;
}
if (prev) {
prev->next = w;
}
prev = w;
}
mysql_free_result(result);
return first;
}
/* }}} */
#else
/* {{{ MYSQLI_WARNING *php_new_warning */
static
MYSQLI_WARNING *php_new_warning(zval * reason, int errorno)
@ -169,7 +122,6 @@ MYSQLI_WARNING * php_get_warnings(MYSQLND_CONN_DATA * mysql)
return first;
}
/* }}} */
#endif
/* {{{ bool mysqli_warning::next() */
PHP_METHOD(mysqli_warning, next)

View file

@ -57,10 +57,6 @@ typedef struct {
BIND_BUFFER param;
BIND_BUFFER result;
char *query;
#ifndef MYSQLI_USE_MYSQLND
/* used to manage refcount with libmysql (already implement in mysqlnd) */
zval link_handle;
#endif
} MY_STMT;
typedef struct {
@ -70,9 +66,7 @@ typedef struct {
php_stream *li_stream;
unsigned int multi_query;
bool persistent;
#ifdef MYSQLI_USE_MYSQLND
int async_result_fetch_type;
#endif
} MY_MYSQL;
typedef struct {