Move from directly referencing an aggregated structure to using a

pointer to a structure. The structure is still aggregated but we add
a level of indirection for possible plugins to overwrite the storage
This commit is contained in:
Andrey Hristov 2011-10-25 23:01:49 +00:00
parent 5e8bcbb08a
commit 845d8fa10c
26 changed files with 430 additions and 406 deletions

View file

@ -530,6 +530,7 @@ static PHP_GINIT_FUNCTION(mysql)
/* }}} */ /* }}} */
#ifdef MYSQL_USE_MYSQLND #ifdef MYSQL_USE_MYSQLND
#include "ext/mysqlnd/mysqlnd_reverse_api.h"
static MYSQLND * mysql_convert_zv_to_mysqlnd(zval * zv TSRMLS_DC) static MYSQLND * mysql_convert_zv_to_mysqlnd(zval * zv TSRMLS_DC)
{ {
php_mysql_conn *mysql; php_mysql_conn *mysql;

View file

@ -528,6 +528,7 @@ PHP_MYSQLI_EXPORT(zend_object_value) mysqli_objects_new(zend_class_entry *class_
/* }}} */ /* }}} */
#ifdef MYSQLI_USE_MYSQLND #ifdef MYSQLI_USE_MYSQLND
#include "ext/mysqlnd/mysqlnd_reverse_api.h"
static MYSQLND *mysqli_convert_zv_to_mysqlnd(zval * zv TSRMLS_DC) static MYSQLND *mysqli_convert_zv_to_mysqlnd(zval * zv TSRMLS_DC)
{ {
if (Z_TYPE_P(zv) == IS_OBJECT && Z_OBJCE_P(zv) == mysqli_link_class_entry) { if (Z_TYPE_P(zv) == IS_OBJECT && Z_OBJCE_P(zv) == mysqli_link_class_entry) {

View file

@ -1804,7 +1804,7 @@ PHP_FUNCTION(mysqli_prepare)
memcpy(last_error, stmt->stmt->last_error, MYSQL_ERRMSG_SIZE); memcpy(last_error, stmt->stmt->last_error, MYSQL_ERRMSG_SIZE);
memcpy(sqlstate, mysql->mysql->net.sqlstate, SQLSTATE_LENGTH+1); memcpy(sqlstate, mysql->mysql->net.sqlstate, SQLSTATE_LENGTH+1);
#else #else
MYSQLND_ERROR_INFO error_info = mysql->mysql->error_info; MYSQLND_ERROR_INFO error_info = *mysql->mysql->error_info;
#endif #endif
mysqli_stmt_close(stmt->stmt, FALSE); mysqli_stmt_close(stmt->stmt, FALSE);
stmt->stmt = NULL; stmt->stmt = NULL;
@ -1815,7 +1815,7 @@ PHP_FUNCTION(mysqli_prepare)
memcpy(mysql->mysql->net.last_error, last_error, MYSQL_ERRMSG_SIZE); memcpy(mysql->mysql->net.last_error, last_error, MYSQL_ERRMSG_SIZE);
memcpy(mysql->mysql->net.sqlstate, sqlstate, SQLSTATE_LENGTH+1); memcpy(mysql->mysql->net.sqlstate, sqlstate, SQLSTATE_LENGTH+1);
#else #else
mysql->mysql->error_info = error_info; *mysql->mysql->error_info = error_info;
#endif #endif
} }
} }

View file

@ -32,7 +32,7 @@
#define mysqli_result_is_unbuffered(r) ((r)->unbuf) #define mysqli_result_is_unbuffered(r) ((r)->unbuf)
#define mysqli_result_is_unbuffered_and_not_everything_is_fetched(r) ((r)->unbuf && !(r)->unbuf->eof_reached) #define mysqli_result_is_unbuffered_and_not_everything_is_fetched(r) ((r)->unbuf && !(r)->unbuf->eof_reached)
#define mysqli_server_status(c) (c)->upsert_status.server_status #define mysqli_server_status(c) mysqlnd_get_server_status((c))
#define mysqli_stmt_get_id(s) ((s)->data->stmt_id) #define mysqli_stmt_get_id(s) ((s)->data->stmt_id)
#define mysqli_stmt_warning_count(s) mysqlnd_stmt_warning_count((s)) #define mysqli_stmt_warning_count(s) mysqlnd_stmt_warning_count((s))
#define mysqli_stmt_server_status(s) mysqlnd_stmt_server_status((s)) #define mysqli_stmt_server_status(s) mysqlnd_stmt_server_status((s))

View file

@ -431,12 +431,12 @@ PHP_FUNCTION(mysqli_error_list)
MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID); MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
array_init(return_value); array_init(return_value);
#if defined(MYSQLI_USE_MYSQLND) #if defined(MYSQLI_USE_MYSQLND)
if (mysql->mysql->error_info.error_list) { if (mysql->mysql->error_info->error_list) {
MYSQLND_ERROR_LIST_ELEMENT * message; MYSQLND_ERROR_LIST_ELEMENT * message;
zend_llist_position pos; zend_llist_position pos;
for (message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_first_ex(mysql->mysql->error_info.error_list, &pos); for (message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_first_ex(mysql->mysql->error_info->error_list, &pos);
message; message;
message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_next_ex(mysql->mysql->error_info.error_list, &pos)) message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_next_ex(mysql->mysql->error_info->error_list, &pos))
{ {
zval * single_error; zval * single_error;
MAKE_STD_ZVAL(single_error); MAKE_STD_ZVAL(single_error);
@ -475,12 +475,12 @@ PHP_FUNCTION(mysqli_stmt_error_list)
MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_INITIALIZED); MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_INITIALIZED);
array_init(return_value); array_init(return_value);
#if defined(MYSQLI_USE_MYSQLND) #if defined(MYSQLI_USE_MYSQLND)
if (stmt->stmt && stmt->stmt->data && stmt->stmt->data->error_info.error_list) { if (stmt->stmt && stmt->stmt->data && stmt->stmt->data->error_info->error_list) {
MYSQLND_ERROR_LIST_ELEMENT * message; MYSQLND_ERROR_LIST_ELEMENT * message;
zend_llist_position pos; zend_llist_position pos;
for (message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_first_ex(stmt->stmt->data->error_info.error_list, &pos); for (message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_first_ex(stmt->stmt->data->error_info->error_list, &pos);
message; message;
message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_next_ex(stmt->stmt->data->error_info.error_list, &pos)) message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_next_ex(stmt->stmt->data->error_info->error_list, &pos))
{ {
zval * single_error; zval * single_error;
MAKE_STD_ZVAL(single_error); MAKE_STD_ZVAL(single_error);
@ -539,7 +539,7 @@ PHP_FUNCTION(mysqli_multi_query)
strcpy(s_sqlstate, mysql_sqlstate(mysql->mysql)); strcpy(s_sqlstate, mysql_sqlstate(mysql->mysql));
s_errno = mysql_errno(mysql->mysql); s_errno = mysql_errno(mysql->mysql);
#else #else
MYSQLND_ERROR_INFO error_info = mysql->mysql->error_info; MYSQLND_ERROR_INFO error_info = *mysql->mysql->error_info;
#endif #endif
MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql); MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
MYSQLI_DISABLE_MQ; MYSQLI_DISABLE_MQ;
@ -550,7 +550,7 @@ PHP_FUNCTION(mysqli_multi_query)
strcpy(mysql->mysql->net.sqlstate, s_sqlstate); strcpy(mysql->mysql->net.sqlstate, s_sqlstate);
mysql->mysql->net.last_errno = s_errno; mysql->mysql->net.last_errno = s_errno;
#else #else
mysql->mysql->error_info = error_info; *mysql->mysql->error_info = error_info;
#endif #endif
RETURN_FALSE; RETURN_FALSE;
} }

View file

@ -13,6 +13,7 @@
| license@php.net so we can mail you a copy immediately. | | license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
| Author: Georg Richter <georg@php.net> | | Author: Georg Richter <georg@php.net> |
| Andrey Hristov <andrey@php.net> |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
$Id$ $Id$
@ -204,12 +205,12 @@ static int link_error_list_read(mysqli_object *obj, zval **retval TSRMLS_DC)
array_init(*retval); array_init(*retval);
if (mysql) { if (mysql) {
#if defined(MYSQLI_USE_MYSQLND) #if defined(MYSQLI_USE_MYSQLND)
if (mysql->mysql->error_info.error_list) { if (mysql->mysql->error_info->error_list) {
MYSQLND_ERROR_LIST_ELEMENT * message; MYSQLND_ERROR_LIST_ELEMENT * message;
zend_llist_position pos; zend_llist_position pos;
for (message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_first_ex(mysql->mysql->error_info.error_list, &pos); for (message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_first_ex(mysql->mysql->error_info->error_list, &pos);
message; message;
message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_next_ex(mysql->mysql->error_info.error_list, &pos)) message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_next_ex(mysql->mysql->error_info->error_list, &pos))
{ {
zval * single_error; zval * single_error;
MAKE_STD_ZVAL(single_error); MAKE_STD_ZVAL(single_error);
@ -397,12 +398,12 @@ static int stmt_error_list_read(mysqli_object *obj, zval **retval TSRMLS_DC)
array_init(*retval); array_init(*retval);
if (stmt && stmt->stmt) { if (stmt && stmt->stmt) {
#if defined(MYSQLI_USE_MYSQLND) #if defined(MYSQLI_USE_MYSQLND)
if (stmt->stmt->data && stmt->stmt->data->error_info.error_list) { if (stmt->stmt->data && stmt->stmt->data->error_info->error_list) {
MYSQLND_ERROR_LIST_ELEMENT * message; MYSQLND_ERROR_LIST_ELEMENT * message;
zend_llist_position pos; zend_llist_position pos;
for (message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_first_ex(stmt->stmt->data->error_info.error_list, &pos); for (message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_first_ex(stmt->stmt->data->error_info->error_list, &pos);
message; message;
message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_next_ex(stmt->stmt->data->error_info.error_list, &pos)) message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_next_ex(stmt->stmt->data->error_info->error_list, &pos))
{ {
zval * single_error; zval * single_error;
MAKE_STD_ZVAL(single_error); MAKE_STD_ZVAL(single_error);

View file

@ -69,30 +69,30 @@ MYSQLND_METHOD(mysqlnd_conn, free_options)(MYSQLND * conn TSRMLS_DC)
{ {
zend_bool pers = conn->persistent; zend_bool pers = conn->persistent;
if (conn->options.charset_name) { if (conn->options->charset_name) {
mnd_pefree(conn->options.charset_name, pers); mnd_pefree(conn->options->charset_name, pers);
conn->options.charset_name = NULL; conn->options->charset_name = NULL;
} }
if (conn->options.auth_protocol) { if (conn->options->auth_protocol) {
mnd_pefree(conn->options.auth_protocol, pers); mnd_pefree(conn->options->auth_protocol, pers);
conn->options.auth_protocol = NULL; conn->options->auth_protocol = NULL;
} }
if (conn->options.num_commands) { if (conn->options->num_commands) {
unsigned int i; unsigned int i;
for (i = 0; i < conn->options.num_commands; i++) { for (i = 0; i < conn->options->num_commands; i++) {
/* allocated with pestrdup */ /* allocated with pestrdup */
mnd_pefree(conn->options.init_commands[i], pers); mnd_pefree(conn->options->init_commands[i], pers);
} }
mnd_pefree(conn->options.init_commands, pers); mnd_pefree(conn->options->init_commands, pers);
conn->options.init_commands = NULL; conn->options->init_commands = NULL;
} }
if (conn->options.cfg_file) { if (conn->options->cfg_file) {
mnd_pefree(conn->options.cfg_file, pers); mnd_pefree(conn->options->cfg_file, pers);
conn->options.cfg_file = NULL; conn->options->cfg_file = NULL;
} }
if (conn->options.cfg_section) { if (conn->options->cfg_section) {
mnd_pefree(conn->options.cfg_section, pers); mnd_pefree(conn->options->cfg_section, pers);
conn->options.cfg_section = NULL; conn->options->cfg_section = NULL;
} }
} }
/* }}} */ /* }}} */
@ -159,10 +159,10 @@ MYSQLND_METHOD(mysqlnd_conn, free_contents)(MYSQLND * conn TSRMLS_DC)
mnd_pefree(conn->last_message, pers); mnd_pefree(conn->last_message, pers);
conn->last_message = NULL; conn->last_message = NULL;
} }
if (conn->error_info.error_list) { if (conn->error_info->error_list) {
zend_llist_clean(conn->error_info.error_list); zend_llist_clean(conn->error_info->error_list);
mnd_pefree(conn->error_info.error_list, pers); mnd_pefree(conn->error_info->error_list, pers);
conn->error_info.error_list = NULL; conn->error_info->error_list = NULL;
} }
conn->charset = NULL; conn->charset = NULL;
conn->greet_charset = NULL; conn->greet_charset = NULL;
@ -183,7 +183,7 @@ MYSQLND_METHOD_PRIVATE(mysqlnd_conn, dtor)(MYSQLND * conn TSRMLS_DC)
conn->m->free_options(conn TSRMLS_CC); conn->m->free_options(conn TSRMLS_CC);
if (conn->net) { if (conn->net) {
mysqlnd_net_free(conn->net, conn->stats, &conn->error_info TSRMLS_CC); mysqlnd_net_free(conn->net, conn->stats, conn->error_info TSRMLS_CC);
conn->net = NULL; conn->net = NULL;
} }
@ -218,7 +218,7 @@ MYSQLND_METHOD(mysqlnd_conn, simple_command_handle_response)(MYSQLND * conn, enu
case PROT_OK_PACKET:{ case PROT_OK_PACKET:{
MYSQLND_PACKET_OK * ok_response = conn->protocol->m.get_ok_packet(conn->protocol, FALSE TSRMLS_CC); MYSQLND_PACKET_OK * ok_response = conn->protocol->m.get_ok_packet(conn->protocol, FALSE TSRMLS_CC);
if (!ok_response) { if (!ok_response) {
SET_OOM_ERROR(conn->error_info); SET_OOM_ERROR(*conn->error_info);
break; break;
} }
if (FAIL == (ret = PACKET_READ(ok_response, conn))) { if (FAIL == (ret = PACKET_READ(ok_response, conn))) {
@ -231,7 +231,7 @@ MYSQLND_METHOD(mysqlnd_conn, simple_command_handle_response)(MYSQLND * conn, enu
DBG_INF_FMT("OK from server"); DBG_INF_FMT("OK from server");
if (0xFF == ok_response->field_count) { if (0xFF == ok_response->field_count) {
/* The server signalled error. Set the error */ /* The server signalled error. Set the error */
SET_CLIENT_ERROR(conn->error_info, ok_response->error_no, ok_response->sqlstate, ok_response->error); SET_CLIENT_ERROR(*conn->error_info, ok_response->error_no, ok_response->sqlstate, ok_response->error);
ret = FAIL; ret = FAIL;
/* /*
Cover a protocol design error: error packet does not Cover a protocol design error: error packet does not
@ -242,7 +242,7 @@ MYSQLND_METHOD(mysqlnd_conn, simple_command_handle_response)(MYSQLND * conn, enu
a multi-statement or a stored procedure, so it should be a multi-statement or a stored procedure, so it should be
safe to unconditionally turn off the flag here. safe to unconditionally turn off the flag here.
*/ */
conn->upsert_status.server_status &= ~SERVER_MORE_RESULTS_EXISTS; conn->upsert_status->server_status &= ~SERVER_MORE_RESULTS_EXISTS;
SET_ERROR_AFF_ROWS(conn); SET_ERROR_AFF_ROWS(conn);
} else { } else {
SET_NEW_MESSAGE(conn->last_message, conn->last_message_len, SET_NEW_MESSAGE(conn->last_message, conn->last_message_len,
@ -250,10 +250,10 @@ MYSQLND_METHOD(mysqlnd_conn, simple_command_handle_response)(MYSQLND * conn, enu
conn->persistent); conn->persistent);
if (!ignore_upsert_status) { if (!ignore_upsert_status) {
conn->upsert_status.warning_count = ok_response->warning_count; conn->upsert_status->warning_count = ok_response->warning_count;
conn->upsert_status.server_status = ok_response->server_status; conn->upsert_status->server_status = ok_response->server_status;
conn->upsert_status.affected_rows = ok_response->affected_rows; conn->upsert_status->affected_rows = ok_response->affected_rows;
conn->upsert_status.last_insert_id = ok_response->last_insert_id; conn->upsert_status->last_insert_id = ok_response->last_insert_id;
} }
} }
} }
@ -263,11 +263,11 @@ MYSQLND_METHOD(mysqlnd_conn, simple_command_handle_response)(MYSQLND * conn, enu
case PROT_EOF_PACKET:{ case PROT_EOF_PACKET:{
MYSQLND_PACKET_EOF * ok_response = conn->protocol->m.get_eof_packet(conn->protocol, FALSE TSRMLS_CC); MYSQLND_PACKET_EOF * ok_response = conn->protocol->m.get_eof_packet(conn->protocol, FALSE TSRMLS_CC);
if (!ok_response) { if (!ok_response) {
SET_OOM_ERROR(conn->error_info); SET_OOM_ERROR(*conn->error_info);
break; break;
} }
if (FAIL == (ret = PACKET_READ(ok_response, conn))) { if (FAIL == (ret = PACKET_READ(ok_response, conn))) {
SET_CLIENT_ERROR(conn->error_info, CR_MALFORMED_PACKET, UNKNOWN_SQLSTATE, SET_CLIENT_ERROR(*conn->error_info, CR_MALFORMED_PACKET, UNKNOWN_SQLSTATE,
"Malformed packet"); "Malformed packet");
if (!silent) { if (!silent) {
DBG_ERR_FMT("Error while reading %s's EOF packet", mysqlnd_command_to_text[command]); DBG_ERR_FMT("Error while reading %s's EOF packet", mysqlnd_command_to_text[command]);
@ -276,10 +276,10 @@ MYSQLND_METHOD(mysqlnd_conn, simple_command_handle_response)(MYSQLND * conn, enu
} }
} else if (0xFF == ok_response->field_count) { } else if (0xFF == ok_response->field_count) {
/* The server signalled error. Set the error */ /* The server signalled error. Set the error */
SET_CLIENT_ERROR(conn->error_info, ok_response->error_no, ok_response->sqlstate, ok_response->error); SET_CLIENT_ERROR(*conn->error_info, ok_response->error_no, ok_response->sqlstate, ok_response->error);
SET_ERROR_AFF_ROWS(conn); SET_ERROR_AFF_ROWS(conn);
} else if (0xFE != ok_response->field_count) { } else if (0xFE != ok_response->field_count) {
SET_CLIENT_ERROR(conn->error_info, CR_MALFORMED_PACKET, UNKNOWN_SQLSTATE, "Malformed packet"); SET_CLIENT_ERROR(*conn->error_info, CR_MALFORMED_PACKET, UNKNOWN_SQLSTATE, "Malformed packet");
if (!silent) { if (!silent) {
DBG_ERR_FMT("EOF packet expected, field count wasn't 0xFE but 0x%2X", ok_response->field_count); DBG_ERR_FMT("EOF packet expected, field count wasn't 0xFE but 0x%2X", ok_response->field_count);
php_error_docref(NULL TSRMLS_CC, E_WARNING, "EOF packet expected, field count wasn't 0xFE but 0x%2X", php_error_docref(NULL TSRMLS_CC, E_WARNING, "EOF packet expected, field count wasn't 0xFE but 0x%2X",
@ -292,7 +292,7 @@ MYSQLND_METHOD(mysqlnd_conn, simple_command_handle_response)(MYSQLND * conn, enu
break; break;
} }
default: default:
SET_CLIENT_ERROR(conn->error_info, CR_MALFORMED_PACKET, UNKNOWN_SQLSTATE, "Malformed packet"); SET_CLIENT_ERROR(*conn->error_info, CR_MALFORMED_PACKET, UNKNOWN_SQLSTATE, "Malformed packet");
php_error_docref(NULL TSRMLS_CC, E_ERROR, "Wrong response packet %u passed to the function", ok_packet); php_error_docref(NULL TSRMLS_CC, E_ERROR, "Wrong response packet %u passed to the function", ok_packet);
break; break;
} }
@ -318,25 +318,25 @@ MYSQLND_METHOD(mysqlnd_conn, simple_command)(MYSQLND * conn, enum php_mysqlnd_se
case CONN_READY: case CONN_READY:
break; break;
case CONN_QUIT_SENT: case CONN_QUIT_SENT:
SET_CLIENT_ERROR(conn->error_info, CR_SERVER_GONE_ERROR, UNKNOWN_SQLSTATE, mysqlnd_server_gone); SET_CLIENT_ERROR(*conn->error_info, CR_SERVER_GONE_ERROR, UNKNOWN_SQLSTATE, mysqlnd_server_gone);
DBG_ERR("Server is gone"); DBG_ERR("Server is gone");
DBG_RETURN(FAIL); DBG_RETURN(FAIL);
default: default:
SET_CLIENT_ERROR(conn->error_info, CR_COMMANDS_OUT_OF_SYNC, UNKNOWN_SQLSTATE, mysqlnd_out_of_sync); SET_CLIENT_ERROR(*conn->error_info, CR_COMMANDS_OUT_OF_SYNC, UNKNOWN_SQLSTATE, mysqlnd_out_of_sync);
DBG_ERR_FMT("Command out of sync. State=%u", CONN_GET_STATE(conn)); DBG_ERR_FMT("Command out of sync. State=%u", CONN_GET_STATE(conn));
DBG_RETURN(FAIL); DBG_RETURN(FAIL);
} }
/* clean UPSERT info */ /* clean UPSERT info */
if (!ignore_upsert_status) { if (!ignore_upsert_status) {
memset(&conn->upsert_status, 0, sizeof(conn->upsert_status)); memset(conn->upsert_status, 0, sizeof(*conn->upsert_status));
} }
SET_ERROR_AFF_ROWS(conn); SET_ERROR_AFF_ROWS(conn);
SET_EMPTY_ERROR(conn->error_info); SET_EMPTY_ERROR(*conn->error_info);
cmd_packet = conn->protocol->m.get_command_packet(conn->protocol, FALSE TSRMLS_CC); cmd_packet = conn->protocol->m.get_command_packet(conn->protocol, FALSE TSRMLS_CC);
if (!cmd_packet) { if (!cmd_packet) {
SET_OOM_ERROR(conn->error_info); SET_OOM_ERROR(*conn->error_info);
DBG_RETURN(FAIL); DBG_RETURN(FAIL);
} }
@ -430,7 +430,7 @@ mysqlnd_switch_to_ssl_if_needed(
auth_packet = conn->protocol->m.get_auth_packet(conn->protocol, FALSE TSRMLS_CC); auth_packet = conn->protocol->m.get_auth_packet(conn->protocol, FALSE TSRMLS_CC);
if (!auth_packet) { if (!auth_packet) {
SET_OOM_ERROR(conn->error_info); SET_OOM_ERROR(*conn->error_info);
goto end; goto end;
} }
auth_packet->client_flags = mysql_flags; auth_packet->client_flags = mysql_flags;
@ -452,7 +452,7 @@ mysqlnd_switch_to_ssl_if_needed(
DBG_INF("Switching to SSL"); DBG_INF("Switching to SSL");
if (!PACKET_WRITE(auth_packet, conn)) { if (!PACKET_WRITE(auth_packet, conn)) {
CONN_SET_STATE(conn, CONN_QUIT_SENT); CONN_SET_STATE(conn, CONN_QUIT_SENT);
SET_CLIENT_ERROR(conn->error_info, CR_SERVER_GONE_ERROR, UNKNOWN_SQLSTATE, mysqlnd_server_gone); SET_CLIENT_ERROR(*conn->error_info, CR_SERVER_GONE_ERROR, UNKNOWN_SQLSTATE, mysqlnd_server_gone);
goto end; goto end;
} }
@ -526,7 +526,7 @@ mysqlnd_connect_run_authentication(
if (!auth_plugin) { if (!auth_plugin) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "The server requested authentication method unknown to the client [%s]", requested_protocol); php_error_docref(NULL TSRMLS_CC, E_WARNING, "The server requested authentication method unknown to the client [%s]", requested_protocol);
SET_CLIENT_ERROR(conn->error_info, CR_NOT_IMPLEMENTED, UNKNOWN_SQLSTATE, "The server requested authentication method umknown to the client"); SET_CLIENT_ERROR(*conn->error_info, CR_NOT_IMPLEMENTED, UNKNOWN_SQLSTATE, "The server requested authentication method umknown to the client");
break; break;
} }
} }
@ -548,7 +548,7 @@ mysqlnd_connect_run_authentication(
conn->auth_plugin_data_len = plugin_data_len; conn->auth_plugin_data_len = plugin_data_len;
conn->auth_plugin_data = mnd_pemalloc(conn->auth_plugin_data_len, conn->persistent); conn->auth_plugin_data = mnd_pemalloc(conn->auth_plugin_data_len, conn->persistent);
if (!conn->auth_plugin_data) { if (!conn->auth_plugin_data) {
SET_OOM_ERROR(conn->error_info); SET_OOM_ERROR(*conn->error_info);
goto end; goto end;
} }
memcpy(conn->auth_plugin_data, plugin_data, plugin_data_len); memcpy(conn->auth_plugin_data, plugin_data, plugin_data_len);
@ -582,8 +582,8 @@ mysqlnd_connect_run_authentication(
plugin_data_len = switch_to_auth_protocol_data_len; plugin_data_len = switch_to_auth_protocol_data_len;
plugin_data = switch_to_auth_protocol_data; plugin_data = switch_to_auth_protocol_data;
} }
DBG_INF_FMT("conn->error_info.error_no = %d", conn->error_info.error_no); DBG_INF_FMT("conn->error_info->error_no = %d", conn->error_info->error_no);
} while (ret == FAIL && conn->error_info.error_no == 0 && switch_to_auth_protocol != NULL); } while (ret == FAIL && conn->error_info->error_no == 0 && switch_to_auth_protocol != NULL);
if (plugin_data) { if (plugin_data) {
mnd_efree(plugin_data); mnd_efree(plugin_data);
} }
@ -631,7 +631,7 @@ MYSQLND_METHOD(mysqlnd_conn, connect)(MYSQLND * conn,
} }
local_tx_started = TRUE; local_tx_started = TRUE;
SET_EMPTY_ERROR(conn->error_info); SET_EMPTY_ERROR(*conn->error_info);
SET_ERROR_AFF_ROWS(conn); SET_ERROR_AFF_ROWS(conn);
DBG_INF_FMT("host=%s user=%s db=%s port=%u flags=%u persistent=%u state=%u", DBG_INF_FMT("host=%s user=%s db=%s port=%u flags=%u persistent=%u state=%u",
@ -713,7 +713,7 @@ MYSQLND_METHOD(mysqlnd_conn, connect)(MYSQLND * conn,
transport_len = mnd_sprintf(&transport, 0, "tcp://%s:%u", host, port); transport_len = mnd_sprintf(&transport, 0, "tcp://%s:%u", host, port);
} }
if (!transport) { if (!transport) {
SET_OOM_ERROR(conn->error_info); SET_OOM_ERROR(*conn->error_info);
goto err; /* OOM */ goto err; /* OOM */
} }
DBG_INF_FMT("transport=%s conn->scheme=%s", transport, conn->scheme); DBG_INF_FMT("transport=%s conn->scheme=%s", transport, conn->scheme);
@ -728,12 +728,12 @@ MYSQLND_METHOD(mysqlnd_conn, connect)(MYSQLND * conn,
greet_packet = conn->protocol->m.get_greet_packet(conn->protocol, FALSE TSRMLS_CC); greet_packet = conn->protocol->m.get_greet_packet(conn->protocol, FALSE TSRMLS_CC);
if (!greet_packet) { if (!greet_packet) {
SET_OOM_ERROR(conn->error_info); SET_OOM_ERROR(*conn->error_info);
goto err; /* OOM */ goto err; /* OOM */
} }
if (FAIL == conn->net->m.connect_ex(conn->net, conn->scheme, conn->scheme_len, conn->persistent, if (FAIL == conn->net->m.connect_ex(conn->net, conn->scheme, conn->scheme_len, conn->persistent,
conn->stats, &conn->error_info TSRMLS_CC)) conn->stats, conn->error_info TSRMLS_CC))
{ {
goto err; goto err;
} }
@ -746,13 +746,13 @@ MYSQLND_METHOD(mysqlnd_conn, connect)(MYSQLND * conn,
goto err; goto err;
} else if (greet_packet->error_no) { } else if (greet_packet->error_no) {
DBG_ERR_FMT("errorno=%u error=%s", greet_packet->error_no, greet_packet->error); DBG_ERR_FMT("errorno=%u error=%s", greet_packet->error_no, greet_packet->error);
SET_CLIENT_ERROR(conn->error_info, greet_packet->error_no, greet_packet->sqlstate, greet_packet->error); SET_CLIENT_ERROR(*conn->error_info, greet_packet->error_no, greet_packet->sqlstate, greet_packet->error);
goto err; goto err;
} else if (greet_packet->pre41) { } else if (greet_packet->pre41) {
DBG_ERR_FMT("Connecting to 3.22, 3.23 & 4.0 is not supported. Server is %-.32s", greet_packet->server_version); DBG_ERR_FMT("Connecting to 3.22, 3.23 & 4.0 is not supported. Server is %-.32s", greet_packet->server_version);
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Connecting to 3.22, 3.23 & 4.0 " php_error_docref(NULL TSRMLS_CC, E_WARNING, "Connecting to 3.22, 3.23 & 4.0 "
" is not supported. Server is %-.32s", greet_packet->server_version); " is not supported. Server is %-.32s", greet_packet->server_version);
SET_CLIENT_ERROR(conn->error_info, CR_NOT_IMPLEMENTED, UNKNOWN_SQLSTATE, SET_CLIENT_ERROR(*conn->error_info, CR_NOT_IMPLEMENTED, UNKNOWN_SQLSTATE,
"Connecting to 3.22, 3.23 & 4.0 servers is not supported"); "Connecting to 3.22, 3.23 & 4.0 servers is not supported");
goto err; goto err;
} }
@ -795,7 +795,7 @@ MYSQLND_METHOD(mysqlnd_conn, connect)(MYSQLND * conn,
#endif #endif
if (FAIL == mysqlnd_connect_run_authentication(conn, user, passwd, db, db_len, (size_t) passwd_len, if (FAIL == mysqlnd_connect_run_authentication(conn, user, passwd, db, db_len, (size_t) passwd_len,
greet_packet, &conn->options, mysql_flags TSRMLS_CC)) greet_packet, conn->options, mysql_flags TSRMLS_CC))
{ {
goto err; goto err;
} }
@ -822,14 +822,14 @@ MYSQLND_METHOD(mysqlnd_conn, connect)(MYSQLND * conn,
conn->connect_or_select_db_len = db_len; conn->connect_or_select_db_len = db_len;
if (!conn->user || !conn->passwd || !conn->connect_or_select_db) { if (!conn->user || !conn->passwd || !conn->connect_or_select_db) {
SET_OOM_ERROR(conn->error_info); SET_OOM_ERROR(*conn->error_info);
goto err; /* OOM */ goto err; /* OOM */
} }
if (!unix_socket && !named_pipe) { if (!unix_socket && !named_pipe) {
conn->host = mnd_pestrdup(host, conn->persistent); conn->host = mnd_pestrdup(host, conn->persistent);
if (!conn->host) { if (!conn->host) {
SET_OOM_ERROR(conn->error_info); SET_OOM_ERROR(*conn->error_info);
goto err; /* OOM */ goto err; /* OOM */
} }
conn->host_len = strlen(conn->host); conn->host_len = strlen(conn->host);
@ -837,13 +837,13 @@ MYSQLND_METHOD(mysqlnd_conn, connect)(MYSQLND * conn,
char *p; char *p;
mnd_sprintf(&p, 0, "%s via TCP/IP", conn->host); mnd_sprintf(&p, 0, "%s via TCP/IP", conn->host);
if (!p) { if (!p) {
SET_OOM_ERROR(conn->error_info); SET_OOM_ERROR(*conn->error_info);
goto err; /* OOM */ goto err; /* OOM */
} }
conn->host_info = mnd_pestrdup(p, conn->persistent); conn->host_info = mnd_pestrdup(p, conn->persistent);
mnd_sprintf_free(p); mnd_sprintf_free(p);
if (!conn->host_info) { if (!conn->host_info) {
SET_OOM_ERROR(conn->error_info); SET_OOM_ERROR(*conn->error_info);
goto err; /* OOM */ goto err; /* OOM */
} }
} }
@ -855,20 +855,20 @@ MYSQLND_METHOD(mysqlnd_conn, connect)(MYSQLND * conn,
char *p; char *p;
mnd_sprintf(&p, 0, "%s via named pipe", conn->unix_socket); mnd_sprintf(&p, 0, "%s via named pipe", conn->unix_socket);
if (!p) { if (!p) {
SET_OOM_ERROR(conn->error_info); SET_OOM_ERROR(*conn->error_info);
goto err; /* OOM */ goto err; /* OOM */
} }
conn->host_info = mnd_pestrdup(p, conn->persistent); conn->host_info = mnd_pestrdup(p, conn->persistent);
mnd_sprintf_free(p); mnd_sprintf_free(p);
if (!conn->host_info) { if (!conn->host_info) {
SET_OOM_ERROR(conn->error_info); SET_OOM_ERROR(*conn->error_info);
goto err; /* OOM */ goto err; /* OOM */
} }
} else { } else {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Impossible. Should be either socket or a pipe. Report a bug!"); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Impossible. Should be either socket or a pipe. Report a bug!");
} }
if (!conn->unix_socket || !conn->host_info) { if (!conn->unix_socket || !conn->host_info) {
SET_OOM_ERROR(conn->error_info); SET_OOM_ERROR(*conn->error_info);
goto err; /* OOM */ goto err; /* OOM */
} }
conn->unix_socket_len = strlen(conn->unix_socket); conn->unix_socket_len = strlen(conn->unix_socket);
@ -877,11 +877,11 @@ MYSQLND_METHOD(mysqlnd_conn, connect)(MYSQLND * conn,
conn->max_packet_size = MYSQLND_ASSEMBLED_PACKET_MAX_SIZE; conn->max_packet_size = MYSQLND_ASSEMBLED_PACKET_MAX_SIZE;
/* todo: check if charset is available */ /* todo: check if charset is available */
conn->server_capabilities = greet_packet->server_capabilities; conn->server_capabilities = greet_packet->server_capabilities;
conn->upsert_status.warning_count = 0; conn->upsert_status->warning_count = 0;
conn->upsert_status.server_status = greet_packet->server_status; conn->upsert_status->server_status = greet_packet->server_status;
conn->upsert_status.affected_rows = 0; conn->upsert_status->affected_rows = 0;
SET_EMPTY_ERROR(conn->error_info); SET_EMPTY_ERROR(*conn->error_info);
mysqlnd_local_infile_default(conn); mysqlnd_local_infile_default(conn);
@ -892,10 +892,10 @@ MYSQLND_METHOD(mysqlnd_conn, connect)(MYSQLND * conn,
DBG_INF("unicode set"); DBG_INF("unicode set");
} }
#endif #endif
if (conn->options.init_commands) { if (conn->options->init_commands) {
unsigned int current_command = 0; unsigned int current_command = 0;
for (; current_command < conn->options.num_commands; ++current_command) { for (; current_command < conn->options->num_commands; ++current_command) {
const char * const command = conn->options.init_commands[current_command]; const char * const command = conn->options->init_commands[current_command];
if (command) { if (command) {
MYSQLND_INC_CONN_STATISTIC(conn->stats, STAT_INIT_COMMAND_EXECUTED_COUNT); MYSQLND_INC_CONN_STATISTIC(conn->stats, STAT_INIT_COMMAND_EXECUTED_COUNT);
if (PASS != conn->m->query(conn, command, strlen(command) TSRMLS_CC)) { if (PASS != conn->m->query(conn, command, strlen(command) TSRMLS_CC)) {
@ -931,11 +931,11 @@ MYSQLND_METHOD(mysqlnd_conn, connect)(MYSQLND * conn,
err: err:
PACKET_FREE(greet_packet); PACKET_FREE(greet_packet);
DBG_ERR_FMT("[%u] %.128s (trying to connect via %s)", conn->error_info.error_no, conn->error_info.error, conn->scheme); DBG_ERR_FMT("[%u] %.128s (trying to connect via %s)", conn->error_info->error_no, conn->error_info->error, conn->scheme);
if (!conn->error_info.error_no) { if (!conn->error_info->error_no) {
SET_CLIENT_ERROR(conn->error_info, CR_CONNECTION_ERROR, UNKNOWN_SQLSTATE, conn->error_info.error? conn->error_info.error:"Unknown error"); SET_CLIENT_ERROR(*conn->error_info, CR_CONNECTION_ERROR, UNKNOWN_SQLSTATE, conn->error_info->error? conn->error_info->error:"Unknown error");
php_error_docref(NULL TSRMLS_CC, E_WARNING, "[%u] %.128s (trying to connect via %s)", php_error_docref(NULL TSRMLS_CC, E_WARNING, "[%u] %.128s (trying to connect via %s)",
conn->error_info.error_no, conn->error_info.error, conn->scheme); conn->error_info->error_no, conn->error_info->error, conn->scheme);
} }
conn->m->free_contents(conn TSRMLS_CC); conn->m->free_contents(conn TSRMLS_CC);
@ -992,7 +992,7 @@ PHPAPI MYSQLND * mysqlnd_connect(MYSQLND * conn,
/* {{{ mysqlnd_conn::query */ /* {{{ mysqlnd_conn::query */
/* /*
If conn->error_info.error_no is not zero, then we had an error. If conn->error_info->error_no is not zero, then we had an error.
Still the result from the query is PASS Still the result from the query is PASS
*/ */
static enum_func_status static enum_func_status
@ -1008,8 +1008,8 @@ MYSQLND_METHOD(mysqlnd_conn, query)(MYSQLND * conn, const char * query, unsigned
PASS == conn->m->reap_query(conn TSRMLS_CC)) PASS == conn->m->reap_query(conn TSRMLS_CC))
{ {
ret = PASS; ret = PASS;
if (conn->last_query_type == QUERY_UPSERT && conn->upsert_status.affected_rows) { if (conn->last_query_type == QUERY_UPSERT && conn->upsert_status->affected_rows) {
MYSQLND_INC_CONN_STATISTIC_W_VALUE(conn->stats, STAT_ROWS_AFFECTED_NORMAL, conn->upsert_status.affected_rows); MYSQLND_INC_CONN_STATISTIC_W_VALUE(conn->stats, STAT_ROWS_AFFECTED_NORMAL, conn->upsert_status->affected_rows);
} }
} }
conn->m->local_tx_end(conn, this_func, ret TSRMLS_CC); conn->m->local_tx_end(conn, this_func, ret TSRMLS_CC);
@ -1311,7 +1311,7 @@ MYSQLND_METHOD(mysqlnd_conn, list_fields)(MYSQLND * conn, const char *table, con
result->unbuf = mnd_ecalloc(1, sizeof(MYSQLND_RES_UNBUFFERED)); result->unbuf = mnd_ecalloc(1, sizeof(MYSQLND_RES_UNBUFFERED));
if (!result->unbuf) { if (!result->unbuf) {
/* OOM */ /* OOM */
SET_OOM_ERROR(conn->error_info); SET_OOM_ERROR(*conn->error_info);
result->m.free_result(result, TRUE TSRMLS_CC); result->m.free_result(result, TRUE TSRMLS_CC);
result = NULL; result = NULL;
break; break;
@ -1370,7 +1370,7 @@ MYSQLND_METHOD(mysqlnd_conn, list_method)(MYSQLND * conn, const char * query, co
static unsigned int static unsigned int
MYSQLND_METHOD(mysqlnd_conn, errno)(const MYSQLND * const conn TSRMLS_DC) MYSQLND_METHOD(mysqlnd_conn, errno)(const MYSQLND * const conn TSRMLS_DC)
{ {
return conn->error_info.error_no; return conn->error_info->error_no;
} }
/* }}} */ /* }}} */
@ -1379,7 +1379,7 @@ MYSQLND_METHOD(mysqlnd_conn, errno)(const MYSQLND * const conn TSRMLS_DC)
static const char * static const char *
MYSQLND_METHOD(mysqlnd_conn, error)(const MYSQLND * const conn TSRMLS_DC) MYSQLND_METHOD(mysqlnd_conn, error)(const MYSQLND * const conn TSRMLS_DC)
{ {
return conn->error_info.error; return conn->error_info->error;
} }
/* }}} */ /* }}} */
@ -1388,7 +1388,7 @@ MYSQLND_METHOD(mysqlnd_conn, error)(const MYSQLND * const conn TSRMLS_DC)
static const char * static const char *
MYSQLND_METHOD(mysqlnd_conn, sqlstate)(const MYSQLND * const conn TSRMLS_DC) MYSQLND_METHOD(mysqlnd_conn, sqlstate)(const MYSQLND * const conn TSRMLS_DC)
{ {
return conn->error_info.sqlstate[0] ? conn->error_info.sqlstate:MYSQLND_SQLSTATE_NULL; return conn->error_info->sqlstate[0] ? conn->error_info->sqlstate:MYSQLND_SQLSTATE_NULL;
} }
/* }}} */ /* }}} */
@ -1433,7 +1433,7 @@ MYSQLND_METHOD(mysqlnd_conn, escape_string)(MYSQLND * const conn, char *newstr,
DBG_INF_FMT("conn=%llu", conn->thread_id); DBG_INF_FMT("conn=%llu", conn->thread_id);
if (PASS == conn->m->local_tx_start(conn, this_func TSRMLS_CC)) { if (PASS == conn->m->local_tx_start(conn, this_func TSRMLS_CC)) {
if (conn->upsert_status.server_status & SERVER_STATUS_NO_BACKSLASH_ESCAPES) { if (conn->upsert_status->server_status & SERVER_STATUS_NO_BACKSLASH_ESCAPES) {
ret = mysqlnd_cset_escape_quotes(conn->charset, newstr, escapestr, escapestr_len TSRMLS_CC); ret = mysqlnd_cset_escape_quotes(conn->charset, newstr, escapestr, escapestr_len TSRMLS_CC);
} else { } else {
ret = mysqlnd_cset_escape_slashes(conn->charset, newstr, escapestr, escapestr_len TSRMLS_CC); ret = mysqlnd_cset_escape_slashes(conn->charset, newstr, escapestr, escapestr_len TSRMLS_CC);
@ -1489,7 +1489,7 @@ MYSQLND_METHOD(mysqlnd_conn, select_db)(MYSQLND * const conn, const char * const
conn->connect_or_select_db_len = db_len; conn->connect_or_select_db_len = db_len;
if (!conn->connect_or_select_db) { if (!conn->connect_or_select_db) {
/* OOM */ /* OOM */
SET_OOM_ERROR(conn->error_info); SET_OOM_ERROR(*conn->error_info);
ret = FAIL; ret = FAIL;
} }
} }
@ -1545,7 +1545,7 @@ MYSQLND_METHOD(mysqlnd_conn, statistic)(MYSQLND * conn, char **message, unsigned
} }
stats_header = conn->protocol->m.get_stats_packet(conn->protocol, FALSE TSRMLS_CC); stats_header = conn->protocol->m.get_stats_packet(conn->protocol, FALSE TSRMLS_CC);
if (!stats_header) { if (!stats_header) {
SET_OOM_ERROR(conn->error_info); SET_OOM_ERROR(*conn->error_info);
break; break;
} }
@ -1610,7 +1610,7 @@ MYSQLND_METHOD(mysqlnd_conn, set_charset)(MYSQLND * const conn, const char * con
DBG_INF_FMT("conn=%llu cs=%s", conn->thread_id, csname); DBG_INF_FMT("conn=%llu cs=%s", conn->thread_id, csname);
if (!charset) { if (!charset) {
SET_CLIENT_ERROR(conn->error_info, CR_CANT_FIND_CHARSET, UNKNOWN_SQLSTATE, SET_CLIENT_ERROR(*conn->error_info, CR_CANT_FIND_CHARSET, UNKNOWN_SQLSTATE,
"Invalid characterset or character set not supported"); "Invalid characterset or character set not supported");
DBG_RETURN(ret); DBG_RETURN(ret);
} }
@ -1621,7 +1621,7 @@ MYSQLND_METHOD(mysqlnd_conn, set_charset)(MYSQLND * const conn, const char * con
if (FAIL == (ret = conn->m->query(conn, query, query_len TSRMLS_CC))) { if (FAIL == (ret = conn->m->query(conn, query, query_len TSRMLS_CC))) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error executing query"); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error executing query");
} else if (conn->error_info.error_no) { } else if (conn->error_info->error_no) {
ret = FAIL; ret = FAIL;
} else { } else {
conn->charset = charset; conn->charset = charset;
@ -1841,11 +1841,20 @@ MYSQLND_METHOD(mysqlnd_conn, field_count)(const MYSQLND * const conn TSRMLS_DC)
/* }}} */ /* }}} */
/* {{{ mysqlnd_conn::server_status */
static unsigned int
MYSQLND_METHOD(mysqlnd_conn, server_status)(const MYSQLND * const conn TSRMLS_DC)
{
return conn->upsert_status->server_status;
}
/* }}} */
/* {{{ mysqlnd_conn::insert_id */ /* {{{ mysqlnd_conn::insert_id */
static uint64_t static uint64_t
MYSQLND_METHOD(mysqlnd_conn, insert_id)(const MYSQLND * const conn TSRMLS_DC) MYSQLND_METHOD(mysqlnd_conn, insert_id)(const MYSQLND * const conn TSRMLS_DC)
{ {
return conn->upsert_status.last_insert_id; return conn->upsert_status->last_insert_id;
} }
/* }}} */ /* }}} */
@ -1854,7 +1863,7 @@ MYSQLND_METHOD(mysqlnd_conn, insert_id)(const MYSQLND * const conn TSRMLS_DC)
static uint64_t static uint64_t
MYSQLND_METHOD(mysqlnd_conn, affected_rows)(const MYSQLND * const conn TSRMLS_DC) MYSQLND_METHOD(mysqlnd_conn, affected_rows)(const MYSQLND * const conn TSRMLS_DC)
{ {
return conn->upsert_status.affected_rows; return conn->upsert_status->affected_rows;
} }
/* }}} */ /* }}} */
@ -1863,7 +1872,7 @@ MYSQLND_METHOD(mysqlnd_conn, affected_rows)(const MYSQLND * const conn TSRMLS_DC
static unsigned int static unsigned int
MYSQLND_METHOD(mysqlnd_conn, warning_count)(const MYSQLND * const conn TSRMLS_DC) MYSQLND_METHOD(mysqlnd_conn, warning_count)(const MYSQLND * const conn TSRMLS_DC)
{ {
return conn->upsert_status.warning_count; return conn->upsert_status->warning_count;
} }
/* }}} */ /* }}} */
@ -1966,7 +1975,7 @@ MYSQLND_METHOD(mysqlnd_conn, more_results)(const MYSQLND * const conn TSRMLS_DC)
{ {
DBG_ENTER("mysqlnd_conn::more_results"); DBG_ENTER("mysqlnd_conn::more_results");
/* (conn->state == CONN_NEXT_RESULT_PENDING) too */ /* (conn->state == CONN_NEXT_RESULT_PENDING) too */
DBG_RETURN(conn->upsert_status.server_status & SERVER_MORE_RESULTS_EXISTS? TRUE:FALSE); DBG_RETURN(conn->upsert_status->server_status & SERVER_MORE_RESULTS_EXISTS? TRUE:FALSE);
} }
/* }}} */ /* }}} */
@ -1987,7 +1996,7 @@ MYSQLND_METHOD(mysqlnd_conn, next_result)(MYSQLND * const conn TSRMLS_DC)
break; break;
} }
SET_EMPTY_ERROR(conn->error_info); SET_EMPTY_ERROR(*conn->error_info);
SET_ERROR_AFF_ROWS(conn); SET_ERROR_AFF_ROWS(conn);
/* /*
We are sure that there is a result set, since conn->state is set accordingly We are sure that there is a result set, since conn->state is set accordingly
@ -1998,17 +2007,17 @@ MYSQLND_METHOD(mysqlnd_conn, next_result)(MYSQLND * const conn TSRMLS_DC)
There can be an error in the middle of a multi-statement, which will cancel the multi-statement. There can be an error in the middle of a multi-statement, which will cancel the multi-statement.
So there are no more results and we should just return FALSE, error_no has been set So there are no more results and we should just return FALSE, error_no has been set
*/ */
if (!conn->error_info.error_no) { if (!conn->error_info->error_no) {
DBG_ERR_FMT("Serious error. %s::%u", __FILE__, __LINE__); DBG_ERR_FMT("Serious error. %s::%u", __FILE__, __LINE__);
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Serious error. PID=%d", getpid()); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Serious error. PID=%d", getpid());
CONN_SET_STATE(conn, CONN_QUIT_SENT); CONN_SET_STATE(conn, CONN_QUIT_SENT);
} else { } else {
DBG_INF_FMT("Error from the server : (%u) %s", conn->error_info.error_no, conn->error_info.error); DBG_INF_FMT("Error from the server : (%u) %s", conn->error_info->error_no, conn->error_info->error);
} }
break; break;
} }
if (conn->last_query_type == QUERY_UPSERT && conn->upsert_status.affected_rows) { if (conn->last_query_type == QUERY_UPSERT && conn->upsert_status->affected_rows) {
MYSQLND_INC_CONN_STATISTIC_W_VALUE(conn->stats, STAT_ROWS_AFFECTED_NORMAL, conn->upsert_status.affected_rows); MYSQLND_INC_CONN_STATISTIC_W_VALUE(conn->stats, STAT_ROWS_AFFECTED_NORMAL, conn->upsert_status->affected_rows);
} }
} while (0); } while (0);
conn->m->local_tx_end(conn, this_func, ret TSRMLS_CC); conn->m->local_tx_end(conn, this_func, ret TSRMLS_CC);
@ -2098,7 +2107,7 @@ MYSQLND_METHOD(mysqlnd_conn, change_user)(MYSQLND * const conn,
} }
local_tx_started = TRUE; local_tx_started = TRUE;
SET_EMPTY_ERROR(conn->error_info); SET_EMPTY_ERROR(*conn->error_info);
SET_ERROR_AFF_ROWS(conn); SET_ERROR_AFF_ROWS(conn);
if (!user) { if (!user) {
@ -2127,7 +2136,7 @@ MYSQLND_METHOD(mysqlnd_conn, change_user)(MYSQLND * const conn,
} }
memcpy(plugin_data, conn->auth_plugin_data, plugin_data_len); memcpy(plugin_data, conn->auth_plugin_data, plugin_data_len);
requested_protocol = mnd_pestrdup(conn->options.auth_protocol? conn->options.auth_protocol:"mysql_native_password", FALSE); requested_protocol = mnd_pestrdup(conn->options->auth_protocol? conn->options->auth_protocol:"mysql_native_password", FALSE);
if (!requested_protocol) { if (!requested_protocol) {
ret = FAIL; ret = FAIL;
goto end; goto end;
@ -2146,7 +2155,7 @@ MYSQLND_METHOD(mysqlnd_conn, change_user)(MYSQLND * const conn,
if (!auth_plugin) { if (!auth_plugin) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "The server requested authentication method unknown to the client [%s]", requested_protocol); php_error_docref(NULL TSRMLS_CC, E_WARNING, "The server requested authentication method unknown to the client [%s]", requested_protocol);
SET_CLIENT_ERROR(conn->error_info, CR_NOT_IMPLEMENTED, UNKNOWN_SQLSTATE, "The server requested authentication method umknown to the client"); SET_CLIENT_ERROR(*conn->error_info, CR_NOT_IMPLEMENTED, UNKNOWN_SQLSTATE, "The server requested authentication method umknown to the client");
break; break;
} }
} }
@ -2168,7 +2177,7 @@ MYSQLND_METHOD(mysqlnd_conn, change_user)(MYSQLND * const conn,
conn->auth_plugin_data_len = plugin_data_len; conn->auth_plugin_data_len = plugin_data_len;
conn->auth_plugin_data = mnd_pemalloc(conn->auth_plugin_data_len, conn->persistent); conn->auth_plugin_data = mnd_pemalloc(conn->auth_plugin_data_len, conn->persistent);
if (!conn->auth_plugin_data) { if (!conn->auth_plugin_data) {
SET_OOM_ERROR(conn->error_info); SET_OOM_ERROR(*conn->error_info);
ret = FAIL; ret = FAIL;
goto end; goto end;
} }
@ -2205,8 +2214,8 @@ MYSQLND_METHOD(mysqlnd_conn, change_user)(MYSQLND * const conn,
plugin_data_len = switch_to_auth_protocol_data_len; plugin_data_len = switch_to_auth_protocol_data_len;
plugin_data = switch_to_auth_protocol_data; plugin_data = switch_to_auth_protocol_data;
} }
DBG_INF_FMT("conn->error_info.error_no = %d", conn->error_info.error_no); DBG_INF_FMT("conn->error_info->error_no = %d", conn->error_info->error_no);
} while (ret == FAIL && conn->error_info.error_no == 0 && switch_to_auth_protocol != NULL); } while (ret == FAIL && conn->error_info->error_no == 0 && switch_to_auth_protocol != NULL);
if (plugin_data) { if (plugin_data) {
mnd_efree(plugin_data); mnd_efree(plugin_data);
} }
@ -2265,19 +2274,19 @@ MYSQLND_METHOD(mysqlnd_conn, set_client_option)(MYSQLND * const conn,
break; break;
#if MYSQLND_UNICODE #if MYSQLND_UNICODE
case MYSQLND_OPT_NUMERIC_AND_DATETIME_AS_UNICODE: case MYSQLND_OPT_NUMERIC_AND_DATETIME_AS_UNICODE:
conn->options.numeric_and_datetime_as_unicode = *(unsigned int*) value; conn->options->numeric_and_datetime_as_unicode = *(unsigned int*) value;
break; break;
#endif #endif
#ifdef MYSQLND_STRING_TO_INT_CONVERSION #ifdef MYSQLND_STRING_TO_INT_CONVERSION
case MYSQLND_OPT_INT_AND_FLOAT_NATIVE: case MYSQLND_OPT_INT_AND_FLOAT_NATIVE:
conn->options.int_and_float_native = *(unsigned int*) value; conn->options->int_and_float_native = *(unsigned int*) value;
break; break;
#endif #endif
case MYSQL_OPT_LOCAL_INFILE: case MYSQL_OPT_LOCAL_INFILE:
if (!value || (*(unsigned int*) value) ? 1 : 0) { if (!value || (*(unsigned int*) value) ? 1 : 0) {
conn->options.flags |= CLIENT_LOCAL_FILES; conn->options->flags |= CLIENT_LOCAL_FILES;
} else { } else {
conn->options.flags &= ~CLIENT_LOCAL_FILES; conn->options->flags &= ~CLIENT_LOCAL_FILES;
} }
break; break;
case MYSQL_INIT_COMMAND: case MYSQL_INIT_COMMAND:
@ -2285,18 +2294,18 @@ MYSQLND_METHOD(mysqlnd_conn, set_client_option)(MYSQLND * const conn,
char ** new_init_commands; char ** new_init_commands;
char * new_command; char * new_command;
/* when num_commands is 0, then realloc will be effectively a malloc call, internally */ /* when num_commands is 0, then realloc will be effectively a malloc call, internally */
/* Don't assign to conn->options.init_commands because in case of OOM we will lose the pointer and leak */ /* Don't assign to conn->options->init_commands because in case of OOM we will lose the pointer and leak */
new_init_commands = mnd_perealloc(conn->options.init_commands, sizeof(char *) * (conn->options.num_commands + 1), conn->persistent); new_init_commands = mnd_perealloc(conn->options->init_commands, sizeof(char *) * (conn->options->num_commands + 1), conn->persistent);
if (!new_init_commands) { if (!new_init_commands) {
goto oom; goto oom;
} }
conn->options.init_commands = new_init_commands; conn->options->init_commands = new_init_commands;
new_command = mnd_pestrdup(value, conn->persistent); new_command = mnd_pestrdup(value, conn->persistent);
if (!new_command) { if (!new_command) {
goto oom; goto oom;
} }
conn->options.init_commands[conn->options.num_commands] = new_command; conn->options->init_commands[conn->options->num_commands] = new_command;
++conn->options.num_commands; ++conn->options->num_commands;
break; break;
} }
case MYSQL_READ_DEFAULT_FILE: case MYSQL_READ_DEFAULT_FILE:
@ -2313,19 +2322,19 @@ MYSQLND_METHOD(mysqlnd_conn, set_client_option)(MYSQLND * const conn,
if (!new_charset_name) { if (!new_charset_name) {
goto oom; goto oom;
} }
if (conn->options.charset_name) { if (conn->options->charset_name) {
mnd_pefree(conn->options.charset_name, conn->persistent); mnd_pefree(conn->options->charset_name, conn->persistent);
} }
conn->options.charset_name = new_charset_name; conn->options->charset_name = new_charset_name;
DBG_INF_FMT("charset=%s", conn->options.charset_name); DBG_INF_FMT("charset=%s", conn->options->charset_name);
break; break;
} }
case MYSQL_OPT_NAMED_PIPE: case MYSQL_OPT_NAMED_PIPE:
conn->options.protocol = MYSQL_PROTOCOL_PIPE; conn->options->protocol = MYSQL_PROTOCOL_PIPE;
break; break;
case MYSQL_OPT_PROTOCOL: case MYSQL_OPT_PROTOCOL:
if (*(unsigned int*) value < MYSQL_PROTOCOL_LAST) { if (*(unsigned int*) value < MYSQL_PROTOCOL_LAST) {
conn->options.protocol = *(unsigned int*) value; conn->options->protocol = *(unsigned int*) value;
} }
break; break;
#ifdef WHEN_SUPPORTED_BY_MYSQLI #ifdef WHEN_SUPPORTED_BY_MYSQLI
@ -2342,7 +2351,7 @@ MYSQLND_METHOD(mysqlnd_conn, set_client_option)(MYSQLND * const conn,
#endif #endif
case MYSQLND_OPT_MAX_ALLOWED_PACKET: case MYSQLND_OPT_MAX_ALLOWED_PACKET:
if (*(unsigned int*) value > (1<<16)) { if (*(unsigned int*) value > (1<<16)) {
conn->options.max_allowed_packet = *(unsigned int*) value; conn->options->max_allowed_packet = *(unsigned int*) value;
} }
break; break;
case MYSQLND_OPT_AUTH_PROTOCOL: case MYSQLND_OPT_AUTH_PROTOCOL:
@ -2351,11 +2360,11 @@ MYSQLND_METHOD(mysqlnd_conn, set_client_option)(MYSQLND * const conn,
if (value && !new_auth_protocol) { if (value && !new_auth_protocol) {
goto oom; goto oom;
} }
if (conn->options.auth_protocol) { if (conn->options->auth_protocol) {
mnd_pefree(conn->options.auth_protocol, conn->persistent); mnd_pefree(conn->options->auth_protocol, conn->persistent);
} }
conn->options.auth_protocol = new_auth_protocol; conn->options->auth_protocol = new_auth_protocol;
DBG_INF_FMT("auth_protocol=%s", conn->options.auth_protocol); DBG_INF_FMT("auth_protocol=%s", conn->options->auth_protocol);
break; break;
} }
#ifdef WHEN_SUPPORTED_BY_MYSQLI #ifdef WHEN_SUPPORTED_BY_MYSQLI
@ -2370,7 +2379,7 @@ MYSQLND_METHOD(mysqlnd_conn, set_client_option)(MYSQLND * const conn,
conn->m->local_tx_end(conn, this_func, ret TSRMLS_CC); conn->m->local_tx_end(conn, this_func, ret TSRMLS_CC);
DBG_RETURN(ret); DBG_RETURN(ret);
oom: oom:
SET_OOM_ERROR(conn->error_info); SET_OOM_ERROR(*conn->error_info);
conn->m->local_tx_end(conn, this_func, FAIL TSRMLS_CC); conn->m->local_tx_end(conn, this_func, FAIL TSRMLS_CC);
end: end:
DBG_RETURN(FAIL); DBG_RETURN(FAIL);
@ -2396,7 +2405,7 @@ MYSQLND_METHOD(mysqlnd_conn, use_result)(MYSQLND * const conn TSRMLS_DC)
/* Nothing to store for UPSERT/LOAD DATA */ /* Nothing to store for UPSERT/LOAD DATA */
if (conn->last_query_type != QUERY_SELECT || CONN_GET_STATE(conn) != CONN_FETCHING_DATA) { if (conn->last_query_type != QUERY_SELECT || CONN_GET_STATE(conn) != CONN_FETCHING_DATA) {
SET_CLIENT_ERROR(conn->error_info, CR_COMMANDS_OUT_OF_SYNC, UNKNOWN_SQLSTATE, mysqlnd_out_of_sync); SET_CLIENT_ERROR(*conn->error_info, CR_COMMANDS_OUT_OF_SYNC, UNKNOWN_SQLSTATE, mysqlnd_out_of_sync);
DBG_ERR("Command out of sync"); DBG_ERR("Command out of sync");
break; break;
} }
@ -2438,7 +2447,7 @@ MYSQLND_METHOD(mysqlnd_conn, store_result)(MYSQLND * const conn TSRMLS_DC)
/* Nothing to store for UPSERT/LOAD DATA*/ /* Nothing to store for UPSERT/LOAD DATA*/
if (conn->last_query_type != QUERY_SELECT || CONN_GET_STATE(conn) != CONN_FETCHING_DATA) { if (conn->last_query_type != QUERY_SELECT || CONN_GET_STATE(conn) != CONN_FETCHING_DATA) {
SET_CLIENT_ERROR(conn->error_info, CR_COMMANDS_OUT_OF_SYNC, UNKNOWN_SQLSTATE, mysqlnd_out_of_sync); SET_CLIENT_ERROR(*conn->error_info, CR_COMMANDS_OUT_OF_SYNC, UNKNOWN_SQLSTATE, mysqlnd_out_of_sync);
DBG_ERR("Command out of sync"); DBG_ERR("Command out of sync");
break; break;
} }
@ -2555,7 +2564,7 @@ MYSQLND_METHOD(mysqlnd_conn, init)(MYSQLND * conn TSRMLS_DC)
mysqlnd_stats_init(&conn->stats, STAT_LAST); mysqlnd_stats_init(&conn->stats, STAT_LAST);
SET_ERROR_AFF_ROWS(conn); SET_ERROR_AFF_ROWS(conn);
conn->net = mysqlnd_net_init(conn->persistent, conn->stats, &conn->error_info TSRMLS_CC); conn->net = mysqlnd_net_init(conn->persistent, conn->stats, conn->error_info TSRMLS_CC);
conn->protocol = mysqlnd_protocol_init(conn->persistent TSRMLS_CC); conn->protocol = mysqlnd_protocol_init(conn->persistent TSRMLS_CC);
DBG_RETURN(conn->stats && conn->net && conn->protocol? PASS:FAIL); DBG_RETURN(conn->stats && conn->net && conn->protocol? PASS:FAIL);
@ -2612,6 +2621,8 @@ MYSQLND_CLASS_METHODS_START(mysqlnd_conn)
MYSQLND_METHOD(mysqlnd_conn, warning_count), MYSQLND_METHOD(mysqlnd_conn, warning_count),
MYSQLND_METHOD(mysqlnd_conn, field_count), MYSQLND_METHOD(mysqlnd_conn, field_count),
MYSQLND_METHOD(mysqlnd_conn, server_status),
MYSQLND_METHOD(mysqlnd_conn, set_server_option), MYSQLND_METHOD(mysqlnd_conn, set_server_option),
MYSQLND_METHOD(mysqlnd_conn, set_client_option), MYSQLND_METHOD(mysqlnd_conn, set_client_option),
MYSQLND_METHOD(mysqlnd_conn, free_contents), MYSQLND_METHOD(mysqlnd_conn, free_contents),

View file

@ -147,6 +147,7 @@ PHPAPI enum_func_status _mysqlnd_poll(MYSQLND **r_array, MYSQLND **e_array, MYSQ
#define mysqlnd_get_host_info(conn) (conn)->m->get_host_information((conn) TSRMLS_CC) #define mysqlnd_get_host_info(conn) (conn)->m->get_host_information((conn) TSRMLS_CC)
#define mysqlnd_get_proto_info(conn) (conn)->m->get_protocol_information((conn) TSRMLS_CC) #define mysqlnd_get_proto_info(conn) (conn)->m->get_protocol_information((conn) TSRMLS_CC)
#define mysqlnd_thread_id(conn) (conn)->m->get_thread_id((conn) TSRMLS_CC) #define mysqlnd_thread_id(conn) (conn)->m->get_thread_id((conn) TSRMLS_CC)
#define mysqlnd_get_server_status(conn) (conn)->m->get_server_status((conn) TSRMLS_CC)
#define mysqlnd_num_rows(result) (result)->m.num_rows((result) TSRMLS_CC) #define mysqlnd_num_rows(result) (result)->m.num_rows((result) TSRMLS_CC)
#define mysqlnd_num_fields(result) (result)->m.num_fields((result) TSRMLS_CC) #define mysqlnd_num_fields(result) (result)->m.num_fields((result) TSRMLS_CC)

View file

@ -61,14 +61,14 @@ mysqlnd_auth_handshake(MYSQLND * conn,
auth_resp_packet = conn->protocol->m.get_auth_response_packet(conn->protocol, FALSE TSRMLS_CC); auth_resp_packet = conn->protocol->m.get_auth_response_packet(conn->protocol, FALSE TSRMLS_CC);
if (!auth_resp_packet) { if (!auth_resp_packet) {
SET_OOM_ERROR(conn->error_info); SET_OOM_ERROR(*conn->error_info);
goto end; goto end;
} }
if (use_full_blown_auth_packet != TRUE) { if (use_full_blown_auth_packet != TRUE) {
change_auth_resp_packet = conn->protocol->m.get_change_auth_response_packet(conn->protocol, FALSE TSRMLS_CC); change_auth_resp_packet = conn->protocol->m.get_change_auth_response_packet(conn->protocol, FALSE TSRMLS_CC);
if (!change_auth_resp_packet) { if (!change_auth_resp_packet) {
SET_OOM_ERROR(conn->error_info); SET_OOM_ERROR(*conn->error_info);
goto end; goto end;
} }
@ -77,7 +77,7 @@ mysqlnd_auth_handshake(MYSQLND * conn,
if (!PACKET_WRITE(change_auth_resp_packet, conn)) { if (!PACKET_WRITE(change_auth_resp_packet, conn)) {
CONN_SET_STATE(conn, CONN_QUIT_SENT); CONN_SET_STATE(conn, CONN_QUIT_SENT);
SET_CLIENT_ERROR(conn->error_info, CR_SERVER_GONE_ERROR, UNKNOWN_SQLSTATE, mysqlnd_server_gone); SET_CLIENT_ERROR(*conn->error_info, CR_SERVER_GONE_ERROR, UNKNOWN_SQLSTATE, mysqlnd_server_gone);
goto end; goto end;
} }
} else { } else {
@ -117,7 +117,7 @@ mysqlnd_auth_handshake(MYSQLND * conn,
/* old authentication with new server !*/ /* old authentication with new server !*/
if (!auth_resp_packet->new_auth_protocol) { if (!auth_resp_packet->new_auth_protocol) {
DBG_ERR(mysqlnd_old_passwd); DBG_ERR(mysqlnd_old_passwd);
SET_CLIENT_ERROR(conn->error_info, CR_UNKNOWN_ERROR, UNKNOWN_SQLSTATE, mysqlnd_old_passwd); SET_CLIENT_ERROR(*conn->error_info, CR_UNKNOWN_ERROR, UNKNOWN_SQLSTATE, mysqlnd_old_passwd);
} else { } else {
*switch_to_auth_protocol = mnd_pestrndup(auth_resp_packet->new_auth_protocol, auth_resp_packet->new_auth_protocol_len, FALSE); *switch_to_auth_protocol = mnd_pestrndup(auth_resp_packet->new_auth_protocol, auth_resp_packet->new_auth_protocol_len, FALSE);
*switch_to_auth_protocol_len = auth_resp_packet->new_auth_protocol_len; *switch_to_auth_protocol_len = auth_resp_packet->new_auth_protocol_len;
@ -132,10 +132,10 @@ mysqlnd_auth_handshake(MYSQLND * conn,
} }
} else if (auth_resp_packet->response_code == 0xFF) { } else if (auth_resp_packet->response_code == 0xFF) {
if (auth_resp_packet->sqlstate[0]) { if (auth_resp_packet->sqlstate[0]) {
strlcpy(conn->error_info.sqlstate, auth_resp_packet->sqlstate, sizeof(conn->error_info.sqlstate)); strlcpy(conn->error_info->sqlstate, auth_resp_packet->sqlstate, sizeof(conn->error_info->sqlstate));
DBG_ERR_FMT("ERROR:%u [SQLSTATE:%s] %s", auth_resp_packet->error_no, auth_resp_packet->sqlstate, auth_resp_packet->error); DBG_ERR_FMT("ERROR:%u [SQLSTATE:%s] %s", auth_resp_packet->error_no, auth_resp_packet->sqlstate, auth_resp_packet->error);
} }
SET_CLIENT_ERROR(conn->error_info, auth_resp_packet->error_no, UNKNOWN_SQLSTATE, auth_resp_packet->error); SET_CLIENT_ERROR(*conn->error_info, auth_resp_packet->error_no, UNKNOWN_SQLSTATE, auth_resp_packet->error);
} }
goto end; goto end;
} }
@ -182,14 +182,14 @@ mysqlnd_auth_change_user(MYSQLND * const conn,
chg_user_resp = conn->protocol->m.get_change_user_response_packet(conn->protocol, FALSE TSRMLS_CC); chg_user_resp = conn->protocol->m.get_change_user_response_packet(conn->protocol, FALSE TSRMLS_CC);
if (!chg_user_resp) { if (!chg_user_resp) {
SET_OOM_ERROR(conn->error_info); SET_OOM_ERROR(*conn->error_info);
goto end; goto end;
} }
if (use_full_blown_auth_packet != TRUE) { if (use_full_blown_auth_packet != TRUE) {
change_auth_resp_packet = conn->protocol->m.get_change_auth_response_packet(conn->protocol, FALSE TSRMLS_CC); change_auth_resp_packet = conn->protocol->m.get_change_auth_response_packet(conn->protocol, FALSE TSRMLS_CC);
if (!change_auth_resp_packet) { if (!change_auth_resp_packet) {
SET_OOM_ERROR(conn->error_info); SET_OOM_ERROR(*conn->error_info);
goto end; goto end;
} }
@ -198,14 +198,14 @@ mysqlnd_auth_change_user(MYSQLND * const conn,
if (!PACKET_WRITE(change_auth_resp_packet, conn)) { if (!PACKET_WRITE(change_auth_resp_packet, conn)) {
CONN_SET_STATE(conn, CONN_QUIT_SENT); CONN_SET_STATE(conn, CONN_QUIT_SENT);
SET_CLIENT_ERROR(conn->error_info, CR_SERVER_GONE_ERROR, UNKNOWN_SQLSTATE, mysqlnd_server_gone); SET_CLIENT_ERROR(*conn->error_info, CR_SERVER_GONE_ERROR, UNKNOWN_SQLSTATE, mysqlnd_server_gone);
goto end; goto end;
} }
} else { } else {
auth_packet = conn->protocol->m.get_auth_packet(conn->protocol, FALSE TSRMLS_CC); auth_packet = conn->protocol->m.get_auth_packet(conn->protocol, FALSE TSRMLS_CC);
if (!auth_packet) { if (!auth_packet) {
SET_OOM_ERROR(conn->error_info); SET_OOM_ERROR(*conn->error_info);
goto end; goto end;
} }
@ -226,19 +226,19 @@ mysqlnd_auth_change_user(MYSQLND * const conn,
if (!PACKET_WRITE(auth_packet, conn)) { if (!PACKET_WRITE(auth_packet, conn)) {
CONN_SET_STATE(conn, CONN_QUIT_SENT); CONN_SET_STATE(conn, CONN_QUIT_SENT);
SET_CLIENT_ERROR(conn->error_info, CR_SERVER_GONE_ERROR, UNKNOWN_SQLSTATE, mysqlnd_server_gone); SET_CLIENT_ERROR(*conn->error_info, CR_SERVER_GONE_ERROR, UNKNOWN_SQLSTATE, mysqlnd_server_gone);
goto end; goto end;
} }
} }
ret = PACKET_READ(chg_user_resp, conn); ret = PACKET_READ(chg_user_resp, conn);
COPY_CLIENT_ERROR(conn->error_info, chg_user_resp->error_info); COPY_CLIENT_ERROR(*conn->error_info, chg_user_resp->error_info);
if (0xFE == chg_user_resp->response_code) { if (0xFE == chg_user_resp->response_code) {
ret = FAIL; ret = FAIL;
if (!chg_user_resp->new_auth_protocol) { if (!chg_user_resp->new_auth_protocol) {
DBG_ERR(mysqlnd_old_passwd); DBG_ERR(mysqlnd_old_passwd);
SET_CLIENT_ERROR(conn->error_info, CR_UNKNOWN_ERROR, UNKNOWN_SQLSTATE, mysqlnd_old_passwd); SET_CLIENT_ERROR(*conn->error_info, CR_UNKNOWN_ERROR, UNKNOWN_SQLSTATE, mysqlnd_old_passwd);
} else { } else {
*switch_to_auth_protocol = mnd_pestrndup(chg_user_resp->new_auth_protocol, chg_user_resp->new_auth_protocol_len, FALSE); *switch_to_auth_protocol = mnd_pestrndup(chg_user_resp->new_auth_protocol, chg_user_resp->new_auth_protocol_len, FALSE);
*switch_to_auth_protocol_len = chg_user_resp->new_auth_protocol_len; *switch_to_auth_protocol_len = chg_user_resp->new_auth_protocol_len;
@ -253,7 +253,7 @@ mysqlnd_auth_change_user(MYSQLND * const conn,
} }
} }
if (conn->error_info.error_no) { if (conn->error_info->error_no) {
ret = FAIL; ret = FAIL;
/* /*
COM_CHANGE_USER is broken in 5.1. At least in 5.1.15 and 5.1.14, 5.1.11 is immune. COM_CHANGE_USER is broken in 5.1. At least in 5.1.15 and 5.1.14, 5.1.11 is immune.
@ -267,7 +267,7 @@ mysqlnd_auth_change_user(MYSQLND * const conn,
PACKET_FREE(redundant_error_packet); PACKET_FREE(redundant_error_packet);
DBG_INF_FMT("Server is %u, buggy, sends two ERR messages", mysqlnd_get_server_version(conn)); DBG_INF_FMT("Server is %u, buggy, sends two ERR messages", mysqlnd_get_server_version(conn));
} else { } else {
SET_OOM_ERROR(conn->error_info); SET_OOM_ERROR(*conn->error_info);
} }
} }
} }
@ -290,7 +290,7 @@ mysqlnd_auth_change_user(MYSQLND * const conn,
mnd_pefree(conn->last_message, conn->persistent); mnd_pefree(conn->last_message, conn->persistent);
conn->last_message = NULL; conn->last_message = NULL;
} }
memset(&conn->upsert_status, 0, sizeof(conn->upsert_status)); memset(conn->upsert_status, 0, sizeof(*conn->upsert_status));
/* set charset for old servers */ /* set charset for old servers */
if (mysqlnd_get_server_version(conn) < 50123) { if (mysqlnd_get_server_version(conn) < 50123) {
ret = conn->m->set_charset(conn, old_cs->name TSRMLS_CC); ret = conn->m->set_charset(conn, old_cs->name TSRMLS_CC);
@ -298,7 +298,7 @@ mysqlnd_auth_change_user(MYSQLND * const conn,
} else if (ret == FAIL && chg_user_resp->server_asked_323_auth == TRUE) { } else if (ret == FAIL && chg_user_resp->server_asked_323_auth == TRUE) {
/* old authentication with new server !*/ /* old authentication with new server !*/
DBG_ERR(mysqlnd_old_passwd); DBG_ERR(mysqlnd_old_passwd);
SET_CLIENT_ERROR(conn->error_info, CR_UNKNOWN_ERROR, UNKNOWN_SQLSTATE, mysqlnd_old_passwd); SET_CLIENT_ERROR(*conn->error_info, CR_UNKNOWN_ERROR, UNKNOWN_SQLSTATE, mysqlnd_old_passwd);
} }
end: end:
PACKET_FREE(change_auth_resp_packet); PACKET_FREE(change_auth_resp_packet);
@ -370,7 +370,7 @@ mysqlnd_native_auth_get_auth_data(struct st_mysqlnd_authentication_plugin * self
/* 5.5.x reports 21 as scramble length because it needs to show the length of the data before the plugin name */ /* 5.5.x reports 21 as scramble length because it needs to show the length of the data before the plugin name */
if (auth_plugin_data_len < SCRAMBLE_LENGTH) { if (auth_plugin_data_len < SCRAMBLE_LENGTH) {
/* mysql_native_password only works with SCRAMBLE_LENGTH scramble */ /* mysql_native_password only works with SCRAMBLE_LENGTH scramble */
SET_CLIENT_ERROR(conn->error_info, CR_MALFORMED_PACKET, UNKNOWN_SQLSTATE, "The server sent wrong length for scramble"); SET_CLIENT_ERROR(*conn->error_info, CR_MALFORMED_PACKET, UNKNOWN_SQLSTATE, "The server sent wrong length for scramble");
DBG_ERR_FMT("The server sent wrong length for scramble %u. Expected %u", auth_plugin_data_len, SCRAMBLE_LENGTH); DBG_ERR_FMT("The server sent wrong length for scramble %u. Expected %u", auth_plugin_data_len, SCRAMBLE_LENGTH);
DBG_RETURN(NULL); DBG_RETURN(NULL);
} }

View file

@ -111,7 +111,7 @@ static MYSQLND *
MYSQLND_METHOD(mysqlnd_object_factory, get_connection)(zend_bool persistent TSRMLS_DC) MYSQLND_METHOD(mysqlnd_object_factory, get_connection)(zend_bool persistent TSRMLS_DC)
{ {
size_t alloc_size = sizeof(MYSQLND) + mysqlnd_plugin_count() * sizeof(void *); size_t alloc_size = sizeof(MYSQLND) + mysqlnd_plugin_count() * sizeof(void *);
MYSQLND *ret; MYSQLND * ret;
DBG_ENTER("mysqlnd_driver::get_connection"); DBG_ENTER("mysqlnd_driver::get_connection");
DBG_INF_FMT("persistent=%u", persistent); DBG_INF_FMT("persistent=%u", persistent);
@ -120,6 +120,10 @@ MYSQLND_METHOD(mysqlnd_object_factory, get_connection)(zend_bool persistent TSRM
DBG_RETURN(NULL); DBG_RETURN(NULL);
} }
ret->error_info = &(ret->error_info_impl);
ret->options = &(ret->options_impl);
ret->upsert_status = &(ret->upsert_status_impl);
ret->persistent = persistent; ret->persistent = persistent;
ret->m = mysqlnd_conn_get_methods(); ret->m = mysqlnd_conn_get_methods();
CONN_SET_STATE(ret, CONN_ALLOCED); CONN_SET_STATE(ret, CONN_ALLOCED);
@ -127,15 +131,15 @@ MYSQLND_METHOD(mysqlnd_object_factory, get_connection)(zend_bool persistent TSRM
if (PASS != ret->m->init(ret TSRMLS_CC)) { if (PASS != ret->m->init(ret TSRMLS_CC)) {
ret->m->dtor(ret TSRMLS_CC); ret->m->dtor(ret TSRMLS_CC);
ret = NULL; DBG_RETURN(NULL);
} }
ret->error_info.error_list = mnd_pecalloc(1, sizeof(zend_llist), persistent); ret->error_info->error_list = mnd_pecalloc(1, sizeof(zend_llist), persistent);
if (!ret->error_info.error_list) { if (!ret->error_info->error_list) {
ret->m->dtor(ret TSRMLS_CC); ret->m->dtor(ret TSRMLS_CC);
ret = NULL; DBG_RETURN(NULL);
} else { } else {
zend_llist_init(ret->error_info.error_list, sizeof(MYSQLND_ERROR_LIST_ELEMENT), (llist_dtor_func_t)mysqlnd_error_list_pdtor, persistent); zend_llist_init(ret->error_info->error_list, sizeof(MYSQLND_ERROR_LIST_ELEMENT), (llist_dtor_func_t)mysqlnd_error_list_pdtor, persistent);
} }
DBG_RETURN(ret); DBG_RETURN(ret);
@ -165,6 +169,8 @@ MYSQLND_METHOD(mysqlnd_object_factory, get_prepared_statement)(MYSQLND * const c
break; break;
} }
stmt->persistent = conn->persistent; stmt->persistent = conn->persistent;
stmt->error_info = &(stmt->error_info_impl);
stmt->upsert_status = &(stmt->upsert_status_impl);
stmt->state = MYSQLND_STMT_INITTED; stmt->state = MYSQLND_STMT_INITTED;
stmt->execute_cmd_buffer.length = 4096; stmt->execute_cmd_buffer.length = 4096;
stmt->execute_cmd_buffer.buffer = mnd_pemalloc(stmt->execute_cmd_buffer.length, stmt->persistent); stmt->execute_cmd_buffer.buffer = mnd_pemalloc(stmt->execute_cmd_buffer.length, stmt->persistent);
@ -179,16 +185,17 @@ MYSQLND_METHOD(mysqlnd_object_factory, get_prepared_statement)(MYSQLND * const c
or normal query result will close it then. or normal query result will close it then.
*/ */
stmt->conn = conn->m->get_reference(conn TSRMLS_CC); stmt->conn = conn->m->get_reference(conn TSRMLS_CC);
stmt->error_info.error_list = mnd_pecalloc(1, sizeof(zend_llist), ret->persistent); stmt->error_info->error_list = mnd_pecalloc(1, sizeof(zend_llist), ret->persistent);
if (!stmt->error_info.error_list) { if (!stmt->error_info->error_list) {
break; break;
} }
zend_llist_init(stmt->error_info.error_list, sizeof(MYSQLND_ERROR_LIST_ELEMENT), (llist_dtor_func_t) mysqlnd_error_list_pdtor, conn->persistent);
zend_llist_init(stmt->error_info->error_list, sizeof(MYSQLND_ERROR_LIST_ELEMENT), (llist_dtor_func_t) mysqlnd_error_list_pdtor, conn->persistent);
DBG_RETURN(ret); DBG_RETURN(ret);
} while (0); } while (0);
SET_OOM_ERROR(conn->error_info); SET_OOM_ERROR(*conn->error_info);
if (ret) { if (ret) {
ret->m->dtor(ret, TRUE TSRMLS_CC); ret->m->dtor(ret, TRUE TSRMLS_CC);
ret = NULL; ret = NULL;

View file

@ -12,9 +12,9 @@
| obtain it through the world-wide-web, please send a note to | | obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. | | license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
| Authors: Georg Richter <georg@mysql.com> | | Authors: Andrey Hristov <andrey@mysql.com> |
| Andrey Hristov <andrey@mysql.com> |
| Ulf Wendel <uwendel@mysql.com> | | Ulf Wendel <uwendel@mysql.com> |
| Georg Richter <georg@mysql.com> |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
*/ */

View file

@ -12,9 +12,9 @@
| obtain it through the world-wide-web, please send a note to | | obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. | | license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
| Authors: Georg Richter <georg@mysql.com> | | Authors: Andrey Hristov <andrey@mysql.com> |
| Andrey Hristov <andrey@mysql.com> |
| Ulf Wendel <uwendel@mysql.com> | | Ulf Wendel <uwendel@mysql.com> |
| Georg Richter <georg@mysql.com> |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
*/ */
@ -166,10 +166,10 @@ mysqlnd_handle_local_infile(MYSQLND *conn, const char *filename, zend_bool *is_w
DBG_ENTER("mysqlnd_handle_local_infile"); DBG_ENTER("mysqlnd_handle_local_infile");
if (!(conn->options.flags & CLIENT_LOCAL_FILES)) { if (!(conn->options->flags & CLIENT_LOCAL_FILES)) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "LOAD DATA LOCAL INFILE forbidden"); php_error_docref(NULL TSRMLS_CC, E_WARNING, "LOAD DATA LOCAL INFILE forbidden");
/* write empty packet to server */ /* write empty packet to server */
ret = net->m.send_ex(net, empty_packet, 0, conn->stats, &conn->error_info TSRMLS_CC); ret = net->m.send_ex(net, empty_packet, 0, conn->stats, conn->error_info TSRMLS_CC);
*is_warning = TRUE; *is_warning = TRUE;
goto infile_error; goto infile_error;
} }
@ -182,40 +182,40 @@ mysqlnd_handle_local_infile(MYSQLND *conn, const char *filename, zend_bool *is_w
/* init handler: allocate read buffer and open file */ /* init handler: allocate read buffer and open file */
if (infile.local_infile_init(&info, (char *)filename, conn->infile.userdata TSRMLS_CC)) { if (infile.local_infile_init(&info, (char *)filename, conn->infile.userdata TSRMLS_CC)) {
char tmp_buf[sizeof(conn->error_info.error)]; char tmp_buf[sizeof(conn->error_info->error)];
int tmp_error_no; int tmp_error_no;
*is_warning = TRUE; *is_warning = TRUE;
/* error occured */ /* error occured */
tmp_error_no = infile.local_infile_error(info, tmp_buf, sizeof(tmp_buf) TSRMLS_CC); tmp_error_no = infile.local_infile_error(info, tmp_buf, sizeof(tmp_buf) TSRMLS_CC);
SET_CLIENT_ERROR(conn->error_info, tmp_error_no, UNKNOWN_SQLSTATE, tmp_buf); SET_CLIENT_ERROR(*conn->error_info, tmp_error_no, UNKNOWN_SQLSTATE, tmp_buf);
/* write empty packet to server */ /* write empty packet to server */
ret = net->m.send_ex(net, empty_packet, 0, conn->stats, &conn->error_info TSRMLS_CC); ret = net->m.send_ex(net, empty_packet, 0, conn->stats, conn->error_info TSRMLS_CC);
goto infile_error; goto infile_error;
} }
/* read data */ /* read data */
while ((bufsize = infile.local_infile_read (info, buf + MYSQLND_HEADER_SIZE, buflen - MYSQLND_HEADER_SIZE TSRMLS_CC)) > 0) { while ((bufsize = infile.local_infile_read (info, buf + MYSQLND_HEADER_SIZE, buflen - MYSQLND_HEADER_SIZE TSRMLS_CC)) > 0) {
if ((ret = net->m.send_ex(net, buf, bufsize, conn->stats, &conn->error_info TSRMLS_CC)) == 0) { if ((ret = net->m.send_ex(net, buf, bufsize, conn->stats, conn->error_info TSRMLS_CC)) == 0) {
DBG_ERR_FMT("Error during read : %d %s %s", CR_SERVER_LOST, UNKNOWN_SQLSTATE, lost_conn); DBG_ERR_FMT("Error during read : %d %s %s", CR_SERVER_LOST, UNKNOWN_SQLSTATE, lost_conn);
SET_CLIENT_ERROR(conn->error_info, CR_SERVER_LOST, UNKNOWN_SQLSTATE, lost_conn); SET_CLIENT_ERROR(*conn->error_info, CR_SERVER_LOST, UNKNOWN_SQLSTATE, lost_conn);
goto infile_error; goto infile_error;
} }
} }
/* send empty packet for eof */ /* send empty packet for eof */
if ((ret = net->m.send_ex(net, empty_packet, 0, conn->stats, &conn->error_info TSRMLS_CC)) == 0) { if ((ret = net->m.send_ex(net, empty_packet, 0, conn->stats, conn->error_info TSRMLS_CC)) == 0) {
SET_CLIENT_ERROR(conn->error_info, CR_SERVER_LOST, UNKNOWN_SQLSTATE, lost_conn); SET_CLIENT_ERROR(*conn->error_info, CR_SERVER_LOST, UNKNOWN_SQLSTATE, lost_conn);
goto infile_error; goto infile_error;
} }
/* error during read occured */ /* error during read occured */
if (bufsize < 0) { if (bufsize < 0) {
char tmp_buf[sizeof(conn->error_info.error)]; char tmp_buf[sizeof(conn->error_info->error)];
int tmp_error_no; int tmp_error_no;
*is_warning = TRUE; *is_warning = TRUE;
DBG_ERR_FMT("Bufsize < 0, warning, %d %s %s", CR_SERVER_LOST, UNKNOWN_SQLSTATE, lost_conn); DBG_ERR_FMT("Bufsize < 0, warning, %d %s %s", CR_SERVER_LOST, UNKNOWN_SQLSTATE, lost_conn);
tmp_error_no = infile.local_infile_error(info, tmp_buf, sizeof(tmp_buf) TSRMLS_CC); tmp_error_no = infile.local_infile_error(info, tmp_buf, sizeof(tmp_buf) TSRMLS_CC);
SET_CLIENT_ERROR(conn->error_info, tmp_error_no, UNKNOWN_SQLSTATE, tmp_buf); SET_CLIENT_ERROR(*conn->error_info, tmp_error_no, UNKNOWN_SQLSTATE, tmp_buf);
goto infile_error; goto infile_error;
} }

View file

@ -12,9 +12,9 @@
| obtain it through the world-wide-web, please send a note to | | obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. | | license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
| Authors: Georg Richter <georg@mysql.com> | | Authors: Andrey Hristov <andrey@mysql.com> |
| Andrey Hristov <andrey@mysql.com> |
| Ulf Wendel <uwendel@mysql.com> | | Ulf Wendel <uwendel@mysql.com> |
| Georg Richter <georg@mysql.com> |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
*/ */

View file

@ -99,7 +99,7 @@
#define MAX_CHARSET_LEN 32 #define MAX_CHARSET_LEN 32
#define SET_ERROR_AFF_ROWS(s) (s)->upsert_status.affected_rows = (uint64_t) ~0 #define SET_ERROR_AFF_ROWS(s) (s)->upsert_status->affected_rows = (uint64_t) ~0
/* Error handling */ /* Error handling */
#define SET_NEW_MESSAGE(buf, buf_len, message, len, persistent) \ #define SET_NEW_MESSAGE(buf, buf_len, message, len, persistent) \
@ -168,7 +168,7 @@
#define SET_OOM_ERROR(error_info) SET_CLIENT_ERROR((error_info), CR_OUT_OF_MEMORY, UNKNOWN_SQLSTATE, mysqlnd_out_of_memory) #define SET_OOM_ERROR(error_info) SET_CLIENT_ERROR((error_info), CR_OUT_OF_MEMORY, UNKNOWN_SQLSTATE, mysqlnd_out_of_memory)
#define SET_STMT_ERROR(stmt, a, b, c) SET_CLIENT_ERROR((stmt)->error_info, a, b, c) #define SET_STMT_ERROR(stmt, a, b, c) SET_CLIENT_ERROR(*(stmt)->error_info, a, b, c)
#ifdef ZTS #ifdef ZTS

View file

@ -82,15 +82,15 @@ MYSQLND_METHOD(mysqlnd_stmt, store_result)(MYSQLND_STMT * const s TSRMLS_DC)
if (CONN_GET_STATE(conn) != CONN_FETCHING_DATA || if (CONN_GET_STATE(conn) != CONN_FETCHING_DATA ||
stmt->state != MYSQLND_STMT_WAITING_USE_OR_STORE) stmt->state != MYSQLND_STMT_WAITING_USE_OR_STORE)
{ {
SET_CLIENT_ERROR(conn->error_info, CR_COMMANDS_OUT_OF_SYNC, SET_CLIENT_ERROR(*conn->error_info, CR_COMMANDS_OUT_OF_SYNC,
UNKNOWN_SQLSTATE, mysqlnd_out_of_sync); UNKNOWN_SQLSTATE, mysqlnd_out_of_sync);
DBG_RETURN(NULL); DBG_RETURN(NULL);
} }
stmt->default_rset_handler = s->m->store_result; stmt->default_rset_handler = s->m->store_result;
SET_EMPTY_ERROR(stmt->error_info); SET_EMPTY_ERROR(*stmt->error_info);
SET_EMPTY_ERROR(stmt->conn->error_info); SET_EMPTY_ERROR(*stmt->conn->error_info);
MYSQLND_INC_CONN_STATISTIC(conn->stats, STAT_PS_BUFFERED_SETS); MYSQLND_INC_CONN_STATISTIC(conn->stats, STAT_PS_BUFFERED_SETS);
result = stmt->result; result = stmt->result;
@ -105,11 +105,11 @@ MYSQLND_METHOD(mysqlnd_stmt, store_result)(MYSQLND_STMT * const s TSRMLS_DC)
if (PASS == ret) { if (PASS == ret) {
/* libmysql API docs say it should be so for SELECT statements */ /* libmysql API docs say it should be so for SELECT statements */
stmt->upsert_status.affected_rows = stmt->result->stored_data->row_count; stmt->upsert_status->affected_rows = stmt->result->stored_data->row_count;
stmt->state = MYSQLND_STMT_USE_OR_STORE_CALLED; stmt->state = MYSQLND_STMT_USE_OR_STORE_CALLED;
} else { } else {
COPY_CLIENT_ERROR(conn->error_info, result->stored_data->error_info); COPY_CLIENT_ERROR(*conn->error_info, result->stored_data->error_info);
stmt->result->m.free_result_contents(stmt->result TSRMLS_CC); stmt->result->m.free_result_contents(stmt->result TSRMLS_CC);
mnd_efree(stmt->result); mnd_efree(stmt->result);
stmt->result = NULL; stmt->result = NULL;
@ -149,34 +149,34 @@ MYSQLND_METHOD(mysqlnd_stmt, get_result)(MYSQLND_STMT * const s TSRMLS_DC)
/* Nothing to store for UPSERT/LOAD DATA*/ /* Nothing to store for UPSERT/LOAD DATA*/
if (CONN_GET_STATE(conn) != CONN_FETCHING_DATA || stmt->state != MYSQLND_STMT_WAITING_USE_OR_STORE) { if (CONN_GET_STATE(conn) != CONN_FETCHING_DATA || stmt->state != MYSQLND_STMT_WAITING_USE_OR_STORE) {
SET_CLIENT_ERROR(conn->error_info, CR_COMMANDS_OUT_OF_SYNC, SET_CLIENT_ERROR(*conn->error_info, CR_COMMANDS_OUT_OF_SYNC,
UNKNOWN_SQLSTATE, mysqlnd_out_of_sync); UNKNOWN_SQLSTATE, mysqlnd_out_of_sync);
DBG_RETURN(NULL); DBG_RETURN(NULL);
} }
SET_EMPTY_ERROR(stmt->error_info); SET_EMPTY_ERROR(*stmt->error_info);
SET_EMPTY_ERROR(stmt->conn->error_info); SET_EMPTY_ERROR(*stmt->conn->error_info);
MYSQLND_INC_CONN_STATISTIC(conn->stats, STAT_BUFFERED_SETS); MYSQLND_INC_CONN_STATISTIC(conn->stats, STAT_BUFFERED_SETS);
do { do {
result = conn->m->result_init(stmt->result->field_count, stmt->persistent TSRMLS_CC); result = conn->m->result_init(stmt->result->field_count, stmt->persistent TSRMLS_CC);
if (!result) { if (!result) {
SET_OOM_ERROR(stmt->conn->error_info); SET_OOM_ERROR(*stmt->conn->error_info);
break; break;
} }
result->meta = stmt->result->meta->m->clone_metadata(stmt->result->meta, FALSE TSRMLS_CC); result->meta = stmt->result->meta->m->clone_metadata(stmt->result->meta, FALSE TSRMLS_CC);
if (!result->meta) { if (!result->meta) {
SET_OOM_ERROR(stmt->conn->error_info); SET_OOM_ERROR(*stmt->conn->error_info);
break; break;
} }
if ((result = result->m.store_result(result, conn, TRUE TSRMLS_CC))) { if ((result = result->m.store_result(result, conn, TRUE TSRMLS_CC))) {
stmt->upsert_status.affected_rows = result->stored_data->row_count; stmt->upsert_status->affected_rows = result->stored_data->row_count;
stmt->state = MYSQLND_STMT_PREPARED; stmt->state = MYSQLND_STMT_PREPARED;
result->type = MYSQLND_RES_PS_BUF; result->type = MYSQLND_RES_PS_BUF;
} else { } else {
COPY_CLIENT_ERROR(stmt->error_info, conn->error_info); COPY_CLIENT_ERROR(*stmt->error_info, *conn->error_info);
stmt->state = MYSQLND_STMT_PREPARED; stmt->state = MYSQLND_STMT_PREPARED;
break; break;
} }
@ -198,7 +198,7 @@ MYSQLND_METHOD(mysqlnd_stmt, more_results)(const MYSQLND_STMT * s TSRMLS_DC)
MYSQLND_STMT_DATA * stmt = s? s->data:NULL; MYSQLND_STMT_DATA * stmt = s? s->data:NULL;
DBG_ENTER("mysqlnd_stmt::more_results"); DBG_ENTER("mysqlnd_stmt::more_results");
/* (conn->state == CONN_NEXT_RESULT_PENDING) too */ /* (conn->state == CONN_NEXT_RESULT_PENDING) too */
DBG_RETURN((stmt && stmt->conn && (stmt->conn->upsert_status.server_status & DBG_RETURN((stmt && stmt->conn && (stmt->conn->upsert_status->server_status &
SERVER_MORE_RESULTS_EXISTS))? SERVER_MORE_RESULTS_EXISTS))?
TRUE: TRUE:
FALSE); FALSE);
@ -220,11 +220,11 @@ MYSQLND_METHOD(mysqlnd_stmt, next_result)(MYSQLND_STMT * s TSRMLS_DC)
conn = stmt->conn; conn = stmt->conn;
DBG_INF_FMT("stmt=%lu", stmt->stmt_id); DBG_INF_FMT("stmt=%lu", stmt->stmt_id);
if (CONN_GET_STATE(conn) != CONN_NEXT_RESULT_PENDING || !(conn->upsert_status.server_status & SERVER_MORE_RESULTS_EXISTS)) { if (CONN_GET_STATE(conn) != CONN_NEXT_RESULT_PENDING || !(conn->upsert_status->server_status & SERVER_MORE_RESULTS_EXISTS)) {
DBG_RETURN(FAIL); DBG_RETURN(FAIL);
} }
DBG_INF_FMT("server_status=%u cursor=%u", stmt->upsert_status.server_status, stmt->upsert_status.server_status & SERVER_STATUS_CURSOR_EXISTS); DBG_INF_FMT("server_status=%u cursor=%u", stmt->upsert_status->server_status, stmt->upsert_status->server_status & SERVER_STATUS_CURSOR_EXISTS);
/* Free space for next result */ /* Free space for next result */
s->m->free_stmt_content(s TSRMLS_CC); s->m->free_stmt_content(s TSRMLS_CC);
@ -254,8 +254,8 @@ mysqlnd_stmt_skip_metadata(MYSQLND_STMT * s TSRMLS_DC)
field_packet = stmt->conn->protocol->m.get_result_field_packet(stmt->conn->protocol, FALSE TSRMLS_CC); field_packet = stmt->conn->protocol->m.get_result_field_packet(stmt->conn->protocol, FALSE TSRMLS_CC);
if (!field_packet) { if (!field_packet) {
SET_OOM_ERROR(stmt->error_info); SET_OOM_ERROR(*stmt->error_info);
SET_OOM_ERROR(stmt->conn->error_info); SET_OOM_ERROR(*stmt->conn->error_info);
} else { } else {
ret = PASS; ret = PASS;
field_packet->skip_parsing = TRUE; field_packet->skip_parsing = TRUE;
@ -289,8 +289,8 @@ mysqlnd_stmt_read_prepare_response(MYSQLND_STMT * s TSRMLS_DC)
prepare_resp = stmt->conn->protocol->m.get_prepare_response_packet(stmt->conn->protocol, FALSE TSRMLS_CC); prepare_resp = stmt->conn->protocol->m.get_prepare_response_packet(stmt->conn->protocol, FALSE TSRMLS_CC);
if (!prepare_resp) { if (!prepare_resp) {
SET_OOM_ERROR(stmt->error_info); SET_OOM_ERROR(*stmt->error_info);
SET_OOM_ERROR(stmt->conn->error_info); SET_OOM_ERROR(*stmt->conn->error_info);
goto done; goto done;
} }
@ -299,13 +299,13 @@ mysqlnd_stmt_read_prepare_response(MYSQLND_STMT * s TSRMLS_DC)
} }
if (0xFF == prepare_resp->error_code) { if (0xFF == prepare_resp->error_code) {
COPY_CLIENT_ERROR(stmt->error_info, prepare_resp->error_info); COPY_CLIENT_ERROR(*stmt->error_info, prepare_resp->error_info);
COPY_CLIENT_ERROR(stmt->conn->error_info, prepare_resp->error_info); COPY_CLIENT_ERROR(*stmt->conn->error_info, prepare_resp->error_info);
goto done; goto done;
} }
ret = PASS; ret = PASS;
stmt->stmt_id = prepare_resp->stmt_id; stmt->stmt_id = prepare_resp->stmt_id;
stmt->warning_count = stmt->conn->upsert_status.warning_count = prepare_resp->warning_count; stmt->warning_count = stmt->conn->upsert_status->warning_count = prepare_resp->warning_count;
stmt->field_count = stmt->conn->field_count = prepare_resp->field_count; stmt->field_count = stmt->conn->field_count = prepare_resp->field_count;
stmt->param_count = prepare_resp->param_count; stmt->param_count = prepare_resp->param_count;
done: done:
@ -332,8 +332,8 @@ mysqlnd_stmt_prepare_read_eof(MYSQLND_STMT * s TSRMLS_DC)
fields_eof = stmt->conn->protocol->m.get_eof_packet(stmt->conn->protocol, FALSE TSRMLS_CC); fields_eof = stmt->conn->protocol->m.get_eof_packet(stmt->conn->protocol, FALSE TSRMLS_CC);
if (!fields_eof) { if (!fields_eof) {
SET_OOM_ERROR(stmt->error_info); SET_OOM_ERROR(*stmt->error_info);
SET_OOM_ERROR(stmt->conn->error_info); SET_OOM_ERROR(*stmt->conn->error_info);
} else { } else {
if (FAIL == (ret = PACKET_READ(fields_eof, stmt->conn))) { if (FAIL == (ret = PACKET_READ(fields_eof, stmt->conn))) {
if (stmt->result) { if (stmt->result) {
@ -343,8 +343,8 @@ mysqlnd_stmt_prepare_read_eof(MYSQLND_STMT * s TSRMLS_DC)
stmt->state = MYSQLND_STMT_INITTED; stmt->state = MYSQLND_STMT_INITTED;
} }
} else { } else {
stmt->upsert_status.server_status = fields_eof->server_status; stmt->upsert_status->server_status = fields_eof->server_status;
stmt->upsert_status.warning_count = fields_eof->warning_count; stmt->upsert_status->warning_count = fields_eof->warning_count;
stmt->state = MYSQLND_STMT_PREPARED; stmt->state = MYSQLND_STMT_PREPARED;
} }
PACKET_FREE(fields_eof); PACKET_FREE(fields_eof);
@ -373,8 +373,8 @@ MYSQLND_METHOD(mysqlnd_stmt, prepare)(MYSQLND_STMT * const s, const char * const
SET_ERROR_AFF_ROWS(stmt); SET_ERROR_AFF_ROWS(stmt);
SET_ERROR_AFF_ROWS(stmt->conn); SET_ERROR_AFF_ROWS(stmt->conn);
SET_EMPTY_ERROR(stmt->error_info); SET_EMPTY_ERROR(*stmt->error_info);
SET_EMPTY_ERROR(stmt->conn->error_info); SET_EMPTY_ERROR(*stmt->conn->error_info);
if (stmt->state > MYSQLND_STMT_INITTED) { if (stmt->state > MYSQLND_STMT_INITTED) {
/* See if we have to clean the wire */ /* See if we have to clean the wire */
@ -420,7 +420,7 @@ MYSQLND_METHOD(mysqlnd_stmt, prepare)(MYSQLND_STMT * const s, const char * const
if (stmt_to_prepare->field_count) { if (stmt_to_prepare->field_count) {
MYSQLND_RES * result = stmt->conn->m->result_init(stmt_to_prepare->field_count, stmt_to_prepare->persistent TSRMLS_CC); MYSQLND_RES * result = stmt->conn->m->result_init(stmt_to_prepare->field_count, stmt_to_prepare->persistent TSRMLS_CC);
if (!result) { if (!result) {
SET_OOM_ERROR(stmt->conn->error_info); SET_OOM_ERROR(*stmt->conn->error_info);
goto fail; goto fail;
} }
/* Allocate the result now as it is needed for the reading of metadata */ /* Allocate the result now as it is needed for the reading of metadata */
@ -485,8 +485,8 @@ mysqlnd_stmt_execute_parse_response(MYSQLND_STMT * const s TSRMLS_DC)
ret = mysqlnd_query_read_result_set_header(stmt->conn, s TSRMLS_CC); ret = mysqlnd_query_read_result_set_header(stmt->conn, s TSRMLS_CC);
if (ret == FAIL) { if (ret == FAIL) {
COPY_CLIENT_ERROR(stmt->error_info, conn->error_info); COPY_CLIENT_ERROR(*stmt->error_info, *conn->error_info);
stmt->upsert_status.affected_rows = conn->upsert_status.affected_rows; stmt->upsert_status->affected_rows = conn->upsert_status->affected_rows;
if (CONN_GET_STATE(conn) == CONN_QUIT_SENT) { if (CONN_GET_STATE(conn) == CONN_QUIT_SENT) {
/* close the statement here, the connection has been closed */ /* close the statement here, the connection has been closed */
} }
@ -500,9 +500,9 @@ mysqlnd_stmt_execute_parse_response(MYSQLND_STMT * const s TSRMLS_DC)
value is > LONG_MAX or < LONG_MIN, there is string conversion and we have value is > LONG_MAX or < LONG_MIN, there is string conversion and we have
to resend the types. Next execution will also need to resend the type. to resend the types. Next execution will also need to resend the type.
*/ */
SET_EMPTY_ERROR(stmt->error_info); SET_EMPTY_ERROR(*stmt->error_info);
SET_EMPTY_ERROR(stmt->conn->error_info); SET_EMPTY_ERROR(*stmt->conn->error_info);
stmt->upsert_status = conn->upsert_status; *stmt->upsert_status = *conn->upsert_status; /* copy status */
stmt->state = MYSQLND_STMT_EXECUTED; stmt->state = MYSQLND_STMT_EXECUTED;
if (conn->last_query_type == QUERY_UPSERT || conn->last_query_type == QUERY_LOAD_LOCAL) { if (conn->last_query_type == QUERY_UPSERT || conn->last_query_type == QUERY_LOAD_LOCAL) {
DBG_INF("PASS"); DBG_INF("PASS");
@ -528,10 +528,10 @@ mysqlnd_stmt_execute_parse_response(MYSQLND_STMT * const s TSRMLS_DC)
use_result() or store_result() and we should be able to scrap the use_result() or store_result() and we should be able to scrap the
data on the line, if he just decides to close the statement. data on the line, if he just decides to close the statement.
*/ */
DBG_INF_FMT("server_status=%u cursor=%u", stmt->upsert_status.server_status, DBG_INF_FMT("server_status=%u cursor=%u", stmt->upsert_status->server_status,
stmt->upsert_status.server_status & SERVER_STATUS_CURSOR_EXISTS); stmt->upsert_status->server_status & SERVER_STATUS_CURSOR_EXISTS);
if (stmt->upsert_status.server_status & SERVER_STATUS_CURSOR_EXISTS) { if (stmt->upsert_status->server_status & SERVER_STATUS_CURSOR_EXISTS) {
DBG_INF("cursor exists"); DBG_INF("cursor exists");
stmt->cursor_exists = TRUE; stmt->cursor_exists = TRUE;
CONN_SET_STATE(conn, CONN_READY); CONN_SET_STATE(conn, CONN_READY);
@ -562,7 +562,7 @@ mysqlnd_stmt_execute_parse_response(MYSQLND_STMT * const s TSRMLS_DC)
} }
} }
#ifndef MYSQLND_DONT_SKIP_OUT_PARAMS_RESULTSET #ifndef MYSQLND_DONT_SKIP_OUT_PARAMS_RESULTSET
if (stmt->upsert_status.server_status & SERVER_PS_OUT_PARAMS) { if (stmt->upsert_status->server_status & SERVER_PS_OUT_PARAMS) {
s->m->free_stmt_content(s TSRMLS_CC); s->m->free_stmt_content(s TSRMLS_CC);
DBG_INF("PS OUT Variable RSet, skipping"); DBG_INF("PS OUT Variable RSet, skipping");
/* OUT params result set. Skip for now to retain compatibility */ /* OUT params result set. Skip for now to retain compatibility */
@ -639,7 +639,7 @@ MYSQLND_METHOD(mysqlnd_stmt, execute)(MYSQLND_STMT * const s TSRMLS_DC)
stmt->result->m.free_result_buffers(stmt->result TSRMLS_CC); stmt->result->m.free_result_buffers(stmt->result TSRMLS_CC);
} else if (stmt->state < MYSQLND_STMT_PREPARED) { } else if (stmt->state < MYSQLND_STMT_PREPARED) {
/* Only initted - error */ /* Only initted - error */
SET_CLIENT_ERROR(conn->error_info, CR_COMMANDS_OUT_OF_SYNC, UNKNOWN_SQLSTATE, SET_CLIENT_ERROR(*conn->error_info, CR_COMMANDS_OUT_OF_SYNC, UNKNOWN_SQLSTATE,
mysqlnd_out_of_sync); mysqlnd_out_of_sync);
SET_STMT_ERROR(stmt, CR_COMMANDS_OUT_OF_SYNC, UNKNOWN_SQLSTATE, mysqlnd_out_of_sync); SET_STMT_ERROR(stmt, CR_COMMANDS_OUT_OF_SYNC, UNKNOWN_SQLSTATE, mysqlnd_out_of_sync);
DBG_INF("FAIL"); DBG_INF("FAIL");
@ -686,7 +686,7 @@ MYSQLND_METHOD(mysqlnd_stmt, execute)(MYSQLND_STMT * const s TSRMLS_DC)
} }
if (ret == FAIL) { if (ret == FAIL) {
COPY_CLIENT_ERROR(stmt->error_info, conn->error_info); COPY_CLIENT_ERROR(*stmt->error_info, *conn->error_info);
DBG_INF("FAIL"); DBG_INF("FAIL");
DBG_RETURN(FAIL); DBG_RETURN(FAIL);
} }
@ -694,10 +694,10 @@ MYSQLND_METHOD(mysqlnd_stmt, execute)(MYSQLND_STMT * const s TSRMLS_DC)
ret = s->m->parse_execute_response(s TSRMLS_CC); ret = s->m->parse_execute_response(s TSRMLS_CC);
DBG_INF_FMT("server_status=%u cursor=%u", stmt->upsert_status.server_status, stmt->upsert_status.server_status & SERVER_STATUS_CURSOR_EXISTS); DBG_INF_FMT("server_status=%u cursor=%u", stmt->upsert_status->server_status, stmt->upsert_status->server_status & SERVER_STATUS_CURSOR_EXISTS);
if (ret == PASS && conn->last_query_type == QUERY_UPSERT && stmt->upsert_status.affected_rows) { if (ret == PASS && conn->last_query_type == QUERY_UPSERT && stmt->upsert_status->affected_rows) {
MYSQLND_INC_CONN_STATISTIC_W_VALUE(conn->stats, STAT_ROWS_AFFECTED_PS, stmt->upsert_status.affected_rows); MYSQLND_INC_CONN_STATISTIC_W_VALUE(conn->stats, STAT_ROWS_AFFECTED_PS, stmt->upsert_status->affected_rows);
} }
DBG_RETURN(ret); DBG_RETURN(ret);
} }
@ -733,8 +733,8 @@ mysqlnd_stmt_fetch_row_buffered(MYSQLND_RES *result, void *param, unsigned int f
current_row, current_row,
meta->field_count, meta->field_count,
meta->fields, meta->fields,
result->conn->options.numeric_and_datetime_as_unicode, result->conn->options->numeric_and_datetime_as_unicode,
result->conn->options.int_and_float_native, result->conn->options->int_and_float_native,
result->conn->stats TSRMLS_CC); result->conn->stats TSRMLS_CC);
if (PASS != rc) { if (PASS != rc) {
DBG_RETURN(FAIL); DBG_RETURN(FAIL);
@ -821,7 +821,7 @@ mysqlnd_stmt_fetch_row_unbuffered(MYSQLND_RES *result, void *param, unsigned int
DBG_RETURN(PASS); DBG_RETURN(PASS);
} }
if (CONN_GET_STATE(result->conn) != CONN_FETCHING_DATA) { if (CONN_GET_STATE(result->conn) != CONN_FETCHING_DATA) {
SET_CLIENT_ERROR(result->conn->error_info, CR_COMMANDS_OUT_OF_SYNC, SET_CLIENT_ERROR(*result->conn->error_info, CR_COMMANDS_OUT_OF_SYNC,
UNKNOWN_SQLSTATE, mysqlnd_out_of_sync); UNKNOWN_SQLSTATE, mysqlnd_out_of_sync);
DBG_ERR("command out of sync"); DBG_ERR("command out of sync");
DBG_RETURN(FAIL); DBG_RETURN(FAIL);
@ -852,8 +852,8 @@ mysqlnd_stmt_fetch_row_unbuffered(MYSQLND_RES *result, void *param, unsigned int
result->unbuf->last_row_data, result->unbuf->last_row_data,
row_packet->field_count, row_packet->field_count,
row_packet->fields_metadata, row_packet->fields_metadata,
result->conn->options.numeric_and_datetime_as_unicode, result->conn->options->numeric_and_datetime_as_unicode,
result->conn->options.int_and_float_native, result->conn->options->int_and_float_native,
result->conn->stats TSRMLS_CC)) result->conn->stats TSRMLS_CC))
{ {
DBG_RETURN(FAIL); DBG_RETURN(FAIL);
@ -903,8 +903,8 @@ mysqlnd_stmt_fetch_row_unbuffered(MYSQLND_RES *result, void *param, unsigned int
*fetched_anything = TRUE; *fetched_anything = TRUE;
} else if (ret == FAIL) { } else if (ret == FAIL) {
if (row_packet->error_info.error_no) { if (row_packet->error_info.error_no) {
COPY_CLIENT_ERROR(stmt->conn->error_info, row_packet->error_info); COPY_CLIENT_ERROR(*stmt->conn->error_info, row_packet->error_info);
COPY_CLIENT_ERROR(stmt->error_info, row_packet->error_info); COPY_CLIENT_ERROR(*stmt->error_info, row_packet->error_info);
} }
CONN_SET_STATE(result->conn, CONN_READY); CONN_SET_STATE(result->conn, CONN_READY);
result->unbuf->eof_reached = TRUE; /* so next time we won't get an error */ result->unbuf->eof_reached = TRUE; /* so next time we won't get an error */
@ -912,13 +912,13 @@ mysqlnd_stmt_fetch_row_unbuffered(MYSQLND_RES *result, void *param, unsigned int
DBG_INF("EOF"); DBG_INF("EOF");
/* Mark the connection as usable again */ /* Mark the connection as usable again */
result->unbuf->eof_reached = TRUE; result->unbuf->eof_reached = TRUE;
result->conn->upsert_status.warning_count = row_packet->warning_count; result->conn->upsert_status->warning_count = row_packet->warning_count;
result->conn->upsert_status.server_status = row_packet->server_status; result->conn->upsert_status->server_status = row_packet->server_status;
/* /*
result->row_packet will be cleaned when result->row_packet will be cleaned when
destroying the result object destroying the result object
*/ */
if (result->conn->upsert_status.server_status & SERVER_MORE_RESULTS_EXISTS) { if (result->conn->upsert_status->server_status & SERVER_MORE_RESULTS_EXISTS) {
CONN_SET_STATE(result->conn, CONN_NEXT_RESULT_PENDING); CONN_SET_STATE(result->conn, CONN_NEXT_RESULT_PENDING);
} else { } else {
CONN_SET_STATE(result->conn, CONN_READY); CONN_SET_STATE(result->conn, CONN_READY);
@ -952,13 +952,13 @@ MYSQLND_METHOD(mysqlnd_stmt, use_result)(MYSQLND_STMT * s TSRMLS_DC)
(stmt->cursor_exists && CONN_GET_STATE(conn) != CONN_READY) || (stmt->cursor_exists && CONN_GET_STATE(conn) != CONN_READY) ||
(stmt->state != MYSQLND_STMT_WAITING_USE_OR_STORE)) (stmt->state != MYSQLND_STMT_WAITING_USE_OR_STORE))
{ {
SET_CLIENT_ERROR(conn->error_info, CR_COMMANDS_OUT_OF_SYNC, SET_CLIENT_ERROR(*conn->error_info, CR_COMMANDS_OUT_OF_SYNC,
UNKNOWN_SQLSTATE, mysqlnd_out_of_sync); UNKNOWN_SQLSTATE, mysqlnd_out_of_sync);
DBG_ERR("command out of sync"); DBG_ERR("command out of sync");
DBG_RETURN(NULL); DBG_RETURN(NULL);
} }
SET_EMPTY_ERROR(stmt->error_info); SET_EMPTY_ERROR(*stmt->error_info);
MYSQLND_INC_CONN_STATISTIC(stmt->conn->stats, STAT_PS_UNBUFFERED_SETS); MYSQLND_INC_CONN_STATISTIC(stmt->conn->stats, STAT_PS_UNBUFFERED_SETS);
result = stmt->result; result = stmt->result;
@ -997,7 +997,7 @@ mysqlnd_fetch_stmt_row_cursor(MYSQLND_RES *result, void *param, unsigned int fla
if (stmt->state < MYSQLND_STMT_USER_FETCHING) { if (stmt->state < MYSQLND_STMT_USER_FETCHING) {
/* Only initted - error */ /* Only initted - error */
SET_CLIENT_ERROR(stmt->conn->error_info, CR_COMMANDS_OUT_OF_SYNC, UNKNOWN_SQLSTATE, SET_CLIENT_ERROR(*stmt->conn->error_info, CR_COMMANDS_OUT_OF_SYNC, UNKNOWN_SQLSTATE,
mysqlnd_out_of_sync); mysqlnd_out_of_sync);
DBG_ERR("command out of sync"); DBG_ERR("command out of sync");
DBG_RETURN(FAIL); DBG_RETURN(FAIL);
@ -1006,8 +1006,8 @@ mysqlnd_fetch_stmt_row_cursor(MYSQLND_RES *result, void *param, unsigned int fla
DBG_RETURN(FAIL); DBG_RETURN(FAIL);
} }
SET_EMPTY_ERROR(stmt->error_info); SET_EMPTY_ERROR(*stmt->error_info);
SET_EMPTY_ERROR(stmt->conn->error_info); SET_EMPTY_ERROR(*stmt->conn->error_info);
int4store(buf, stmt->stmt_id); int4store(buf, stmt->stmt_id);
int4store(buf + STMT_ID_LENGTH, 1); /* for now fetch only one row */ int4store(buf + STMT_ID_LENGTH, 1); /* for now fetch only one row */
@ -1015,7 +1015,7 @@ mysqlnd_fetch_stmt_row_cursor(MYSQLND_RES *result, void *param, unsigned int fla
if (FAIL == stmt->conn->m->simple_command(stmt->conn, COM_STMT_FETCH, buf, sizeof(buf), if (FAIL == stmt->conn->m->simple_command(stmt->conn, COM_STMT_FETCH, buf, sizeof(buf),
PROT_LAST /* we will handle the response packet*/, PROT_LAST /* we will handle the response packet*/,
FALSE, TRUE TSRMLS_CC)) { FALSE, TRUE TSRMLS_CC)) {
COPY_CLIENT_ERROR(stmt->error_info, stmt->conn->error_info); COPY_CLIENT_ERROR(*stmt->error_info, *stmt->conn->error_info);
DBG_RETURN(FAIL); DBG_RETURN(FAIL);
} }
@ -1036,8 +1036,8 @@ mysqlnd_fetch_stmt_row_cursor(MYSQLND_RES *result, void *param, unsigned int fla
result->unbuf->last_row_data, result->unbuf->last_row_data,
row_packet->field_count, row_packet->field_count,
row_packet->fields_metadata, row_packet->fields_metadata,
result->conn->options.numeric_and_datetime_as_unicode, result->conn->options->numeric_and_datetime_as_unicode,
result->conn->options.int_and_float_native, result->conn->options->int_and_float_native,
result->conn->stats TSRMLS_CC)) result->conn->stats TSRMLS_CC))
{ {
DBG_RETURN(FAIL); DBG_RETURN(FAIL);
@ -1096,21 +1096,21 @@ mysqlnd_fetch_stmt_row_cursor(MYSQLND_RES *result, void *param, unsigned int fla
} else { } else {
*fetched_anything = FALSE; *fetched_anything = FALSE;
stmt->upsert_status.warning_count = stmt->upsert_status->warning_count =
stmt->conn->upsert_status.warning_count = stmt->conn->upsert_status->warning_count =
row_packet->warning_count; row_packet->warning_count;
stmt->upsert_status.server_status = stmt->upsert_status->server_status =
stmt->conn->upsert_status.server_status = stmt->conn->upsert_status->server_status =
row_packet->server_status; row_packet->server_status;
result->unbuf->eof_reached = row_packet->eof; result->unbuf->eof_reached = row_packet->eof;
} }
stmt->upsert_status.warning_count = stmt->upsert_status->warning_count =
stmt->conn->upsert_status.warning_count = stmt->conn->upsert_status->warning_count =
row_packet->warning_count; row_packet->warning_count;
stmt->upsert_status.server_status = stmt->upsert_status->server_status =
stmt->conn->upsert_status.server_status = stmt->conn->upsert_status->server_status =
row_packet->server_status; row_packet->server_status;
DBG_INF_FMT("ret=%s fetched=%u server_status=%u warnings=%u eof=%u", DBG_INF_FMT("ret=%s fetched=%u server_status=%u warnings=%u eof=%u",
@ -1147,8 +1147,8 @@ MYSQLND_METHOD(mysqlnd_stmt, fetch)(MYSQLND_STMT * const s, zend_bool * const fe
} }
stmt->state = MYSQLND_STMT_USER_FETCHING; stmt->state = MYSQLND_STMT_USER_FETCHING;
SET_EMPTY_ERROR(stmt->error_info); SET_EMPTY_ERROR(*stmt->error_info);
SET_EMPTY_ERROR(stmt->conn->error_info); SET_EMPTY_ERROR(*stmt->conn->error_info);
DBG_INF_FMT("result_bind=%p separated_once=%u", stmt->result_bind, stmt->result_zvals_separated_once); DBG_INF_FMT("result_bind=%p separated_once=%u", stmt->result_bind, stmt->result_zvals_separated_once);
/* /*
@ -1190,8 +1190,8 @@ MYSQLND_METHOD(mysqlnd_stmt, reset)(MYSQLND_STMT * const s TSRMLS_DC)
} }
DBG_INF_FMT("stmt=%lu", stmt->stmt_id); DBG_INF_FMT("stmt=%lu", stmt->stmt_id);
SET_EMPTY_ERROR(stmt->error_info); SET_EMPTY_ERROR(*stmt->error_info);
SET_EMPTY_ERROR(stmt->conn->error_info); SET_EMPTY_ERROR(*stmt->conn->error_info);
if (stmt->stmt_id) { if (stmt->stmt_id) {
MYSQLND * conn = stmt->conn; MYSQLND * conn = stmt->conn;
@ -1219,9 +1219,9 @@ MYSQLND_METHOD(mysqlnd_stmt, reset)(MYSQLND_STMT * const s TSRMLS_DC)
FAIL == (ret = conn->m->simple_command(conn, COM_STMT_RESET, cmd_buf, FAIL == (ret = conn->m->simple_command(conn, COM_STMT_RESET, cmd_buf,
sizeof(cmd_buf), PROT_OK_PACKET, sizeof(cmd_buf), PROT_OK_PACKET,
FALSE, TRUE TSRMLS_CC))) { FALSE, TRUE TSRMLS_CC))) {
COPY_CLIENT_ERROR(stmt->error_info, conn->error_info); COPY_CLIENT_ERROR(*stmt->error_info, *conn->error_info);
} }
stmt->upsert_status = conn->upsert_status; *stmt->upsert_status = *conn->upsert_status;
stmt->state = MYSQLND_STMT_PREPARED; stmt->state = MYSQLND_STMT_PREPARED;
} }
@ -1290,8 +1290,8 @@ MYSQLND_METHOD(mysqlnd_stmt, send_long_data)(MYSQLND_STMT * const s, unsigned in
conn = stmt->conn; conn = stmt->conn;
SET_EMPTY_ERROR(stmt->error_info); SET_EMPTY_ERROR(*stmt->error_info);
SET_EMPTY_ERROR(stmt->conn->error_info); SET_EMPTY_ERROR(*stmt->conn->error_info);
if (stmt->state < MYSQLND_STMT_PREPARED) { if (stmt->state < MYSQLND_STMT_PREPARED) {
SET_STMT_ERROR(stmt, CR_NO_PREPARE_STMT, UNKNOWN_SQLSTATE, mysqlnd_stmt_not_prepared); SET_STMT_ERROR(stmt, CR_NO_PREPARE_STMT, UNKNOWN_SQLSTATE, mysqlnd_stmt_not_prepared);
@ -1338,12 +1338,12 @@ MYSQLND_METHOD(mysqlnd_stmt, send_long_data)(MYSQLND_STMT * const s, unsigned in
ret = conn->m->simple_command(conn, cmd, cmd_buf, packet_len, PROT_LAST , FALSE, TRUE TSRMLS_CC); ret = conn->m->simple_command(conn, cmd, cmd_buf, packet_len, PROT_LAST , FALSE, TRUE TSRMLS_CC);
mnd_efree(cmd_buf); mnd_efree(cmd_buf);
if (FAIL == ret) { if (FAIL == ret) {
COPY_CLIENT_ERROR(stmt->error_info, conn->error_info); COPY_CLIENT_ERROR(*stmt->error_info, *conn->error_info);
} }
} else { } else {
ret = FAIL; ret = FAIL;
SET_OOM_ERROR(stmt->error_info); SET_OOM_ERROR(*stmt->error_info);
SET_OOM_ERROR(conn->error_info); SET_OOM_ERROR(*conn->error_info);
} }
/* /*
Cover protocol error: COM_STMT_SEND_LONG_DATA was designed to be quick and not Cover protocol error: COM_STMT_SEND_LONG_DATA was designed to be quick and not
@ -1403,8 +1403,8 @@ MYSQLND_METHOD(mysqlnd_stmt, bind_parameters)(MYSQLND_STMT * const s, MYSQLND_PA
DBG_RETURN(FAIL); DBG_RETURN(FAIL);
} }
SET_EMPTY_ERROR(stmt->error_info); SET_EMPTY_ERROR(*stmt->error_info);
SET_EMPTY_ERROR(stmt->conn->error_info); SET_EMPTY_ERROR(*stmt->conn->error_info);
if (stmt->param_count) { if (stmt->param_count) {
unsigned int i = 0; unsigned int i = 0;
@ -1476,8 +1476,8 @@ MYSQLND_METHOD(mysqlnd_stmt, bind_one_parameter)(MYSQLND_STMT * const s, unsigne
DBG_ERR("invalid param_no"); DBG_ERR("invalid param_no");
DBG_RETURN(FAIL); DBG_RETURN(FAIL);
} }
SET_EMPTY_ERROR(stmt->error_info); SET_EMPTY_ERROR(*stmt->error_info);
SET_EMPTY_ERROR(stmt->conn->error_info); SET_EMPTY_ERROR(*stmt->conn->error_info);
if (stmt->param_count) { if (stmt->param_count) {
if (!stmt->param_bind) { if (!stmt->param_bind) {
@ -1527,8 +1527,8 @@ MYSQLND_METHOD(mysqlnd_stmt, refresh_bind_param)(MYSQLND_STMT * const s TSRMLS_D
DBG_RETURN(FAIL); DBG_RETURN(FAIL);
} }
SET_EMPTY_ERROR(stmt->error_info); SET_EMPTY_ERROR(*stmt->error_info);
SET_EMPTY_ERROR(stmt->conn->error_info); SET_EMPTY_ERROR(*stmt->conn->error_info);
if (stmt->param_count) { if (stmt->param_count) {
stmt->send_types_to_server = 1; stmt->send_types_to_server = 1;
@ -1559,8 +1559,8 @@ MYSQLND_METHOD(mysqlnd_stmt, bind_result)(MYSQLND_STMT * const s,
DBG_RETURN(FAIL); DBG_RETURN(FAIL);
} }
SET_EMPTY_ERROR(stmt->error_info); SET_EMPTY_ERROR(*stmt->error_info);
SET_EMPTY_ERROR(stmt->conn->error_info); SET_EMPTY_ERROR(*stmt->conn->error_info);
if (stmt->field_count) { if (stmt->field_count) {
unsigned int i = 0; unsigned int i = 0;
@ -1616,8 +1616,8 @@ MYSQLND_METHOD(mysqlnd_stmt, bind_one_result)(MYSQLND_STMT * const s, unsigned i
DBG_RETURN(FAIL); DBG_RETURN(FAIL);
} }
SET_EMPTY_ERROR(stmt->error_info); SET_EMPTY_ERROR(*stmt->error_info);
SET_EMPTY_ERROR(stmt->conn->error_info); SET_EMPTY_ERROR(*stmt->conn->error_info);
if (stmt->field_count) { if (stmt->field_count) {
mysqlnd_stmt_separate_one_result_bind(s, param_no TSRMLS_CC); mysqlnd_stmt_separate_one_result_bind(s, param_no TSRMLS_CC);
@ -1649,7 +1649,7 @@ static uint64_t
MYSQLND_METHOD(mysqlnd_stmt, insert_id)(const MYSQLND_STMT * const s TSRMLS_DC) MYSQLND_METHOD(mysqlnd_stmt, insert_id)(const MYSQLND_STMT * const s TSRMLS_DC)
{ {
MYSQLND_STMT_DATA * stmt = s? s->data:NULL; MYSQLND_STMT_DATA * stmt = s? s->data:NULL;
return stmt? stmt->upsert_status.last_insert_id : 0; return stmt? stmt->upsert_status->last_insert_id : 0;
} }
/* }}} */ /* }}} */
@ -1659,7 +1659,7 @@ static uint64_t
MYSQLND_METHOD(mysqlnd_stmt, affected_rows)(const MYSQLND_STMT * const s TSRMLS_DC) MYSQLND_METHOD(mysqlnd_stmt, affected_rows)(const MYSQLND_STMT * const s TSRMLS_DC)
{ {
MYSQLND_STMT_DATA * stmt = s? s->data:NULL; MYSQLND_STMT_DATA * stmt = s? s->data:NULL;
return stmt? stmt->upsert_status.affected_rows : 0; return stmt? stmt->upsert_status->affected_rows : 0;
} }
/* }}} */ /* }}} */
@ -1679,7 +1679,7 @@ static unsigned int
MYSQLND_METHOD(mysqlnd_stmt, warning_count)(const MYSQLND_STMT * const s TSRMLS_DC) MYSQLND_METHOD(mysqlnd_stmt, warning_count)(const MYSQLND_STMT * const s TSRMLS_DC)
{ {
MYSQLND_STMT_DATA * stmt = s? s->data:NULL; MYSQLND_STMT_DATA * stmt = s? s->data:NULL;
return stmt? stmt->upsert_status.warning_count : 0; return stmt? stmt->upsert_status->warning_count : 0;
} }
/* }}} */ /* }}} */
@ -1689,7 +1689,7 @@ static unsigned int
MYSQLND_METHOD(mysqlnd_stmt, server_status)(const MYSQLND_STMT * const s TSRMLS_DC) MYSQLND_METHOD(mysqlnd_stmt, server_status)(const MYSQLND_STMT * const s TSRMLS_DC)
{ {
MYSQLND_STMT_DATA * stmt = s? s->data:NULL; MYSQLND_STMT_DATA * stmt = s? s->data:NULL;
return stmt? stmt->upsert_status.server_status : 0; return stmt? stmt->upsert_status->server_status : 0;
} }
/* }}} */ /* }}} */
@ -1719,7 +1719,7 @@ static unsigned int
MYSQLND_METHOD(mysqlnd_stmt, errno)(const MYSQLND_STMT * const s TSRMLS_DC) MYSQLND_METHOD(mysqlnd_stmt, errno)(const MYSQLND_STMT * const s TSRMLS_DC)
{ {
MYSQLND_STMT_DATA * stmt = s? s->data:NULL; MYSQLND_STMT_DATA * stmt = s? s->data:NULL;
return stmt? stmt->error_info.error_no : 0; return stmt? stmt->error_info->error_no : 0;
} }
/* }}} */ /* }}} */
@ -1729,7 +1729,7 @@ static const char *
MYSQLND_METHOD(mysqlnd_stmt, error)(const MYSQLND_STMT * const s TSRMLS_DC) MYSQLND_METHOD(mysqlnd_stmt, error)(const MYSQLND_STMT * const s TSRMLS_DC)
{ {
MYSQLND_STMT_DATA * stmt = s? s->data:NULL; MYSQLND_STMT_DATA * stmt = s? s->data:NULL;
return stmt? stmt->error_info.error : 0; return stmt? stmt->error_info->error : 0;
} }
/* }}} */ /* }}} */
@ -1739,7 +1739,7 @@ static const char *
MYSQLND_METHOD(mysqlnd_stmt, sqlstate)(const MYSQLND_STMT * const s TSRMLS_DC) MYSQLND_METHOD(mysqlnd_stmt, sqlstate)(const MYSQLND_STMT * const s TSRMLS_DC)
{ {
MYSQLND_STMT_DATA * stmt = s? s->data:NULL; MYSQLND_STMT_DATA * stmt = s? s->data:NULL;
return stmt && stmt->error_info.sqlstate[0] ? stmt->error_info.sqlstate:MYSQLND_SQLSTATE_NULL; return stmt && stmt->error_info->sqlstate[0] ? stmt->error_info->sqlstate:MYSQLND_SQLSTATE_NULL;
} }
/* }}} */ /* }}} */
@ -1819,7 +1819,7 @@ MYSQLND_METHOD(mysqlnd_stmt, result_metadata)(MYSQLND_STMT * const s TSRMLS_DC)
DBG_RETURN(result); DBG_RETURN(result);
} while (0); } while (0);
SET_OOM_ERROR(stmt->conn->error_info); SET_OOM_ERROR(*stmt->conn->error_info);
if (result) { if (result) {
result->m.free_result(result, TRUE TSRMLS_CC); result->m.free_result(result, TRUE TSRMLS_CC);
} }
@ -2118,10 +2118,10 @@ MYSQLND_METHOD(mysqlnd_stmt, free_stmt_content)(MYSQLND_STMT * const s TSRMLS_DC
stmt->result->m.free_result_internal(stmt->result TSRMLS_CC); stmt->result->m.free_result_internal(stmt->result TSRMLS_CC);
stmt->result = NULL; stmt->result = NULL;
} }
if (stmt->error_info.error_list) { if (stmt->error_info->error_list) {
zend_llist_clean(stmt->error_info.error_list); zend_llist_clean(stmt->error_info->error_list);
mnd_pefree(stmt->error_info.error_list, s->persistent); mnd_pefree(stmt->error_info->error_list, s->persistent);
stmt->error_info.error_list = NULL; stmt->error_info->error_list = NULL;
} }
DBG_VOID_RETURN; DBG_VOID_RETURN;
@ -2146,8 +2146,8 @@ MYSQLND_METHOD_PRIVATE(mysqlnd_stmt, net_close)(MYSQLND_STMT * const s, zend_boo
conn = stmt->conn; conn = stmt->conn;
SET_EMPTY_ERROR(stmt->error_info); SET_EMPTY_ERROR(*stmt->error_info);
SET_EMPTY_ERROR(stmt->conn->error_info); SET_EMPTY_ERROR(*stmt->conn->error_info);
/* /*
If the user decided to close the statement right after execute() If the user decided to close the statement right after execute()
@ -2180,7 +2180,7 @@ MYSQLND_METHOD_PRIVATE(mysqlnd_stmt, net_close)(MYSQLND_STMT * const s, zend_boo
FAIL == conn->m->simple_command(conn, COM_STMT_CLOSE, cmd_buf, sizeof(cmd_buf), FAIL == conn->m->simple_command(conn, COM_STMT_CLOSE, cmd_buf, sizeof(cmd_buf),
PROT_LAST /* COM_STMT_CLOSE doesn't send an OK packet*/, PROT_LAST /* COM_STMT_CLOSE doesn't send an OK packet*/,
FALSE, TRUE TSRMLS_CC)) { FALSE, TRUE TSRMLS_CC)) {
COPY_CLIENT_ERROR(stmt->error_info, conn->error_info); COPY_CLIENT_ERROR(*stmt->error_info, *conn->error_info);
DBG_RETURN(FAIL); DBG_RETURN(FAIL);
} }
} }

View file

@ -12,9 +12,9 @@
| obtain it through the world-wide-web, please send a note to | | obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. | | license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
| Authors: Georg Richter <georg@mysql.com> | | Authors: Andrey Hristov <andrey@mysql.com> |
| Andrey Hristov <andrey@mysql.com> |
| Ulf Wendel <uwendel@mysql.com> | | Ulf Wendel <uwendel@mysql.com> |
| Georg Richter <georg@mysql.com> |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
*/ */
@ -608,7 +608,7 @@ mysqlnd_stmt_execute_store_params(MYSQLND_STMT * s, zend_uchar **buf, zend_uchar
*buf_len = offset + null_count + 20; *buf_len = offset + null_count + 20;
tmp_buf = mnd_emalloc(*buf_len); tmp_buf = mnd_emalloc(*buf_len);
if (!tmp_buf) { if (!tmp_buf) {
SET_OOM_ERROR(stmt->error_info); SET_OOM_ERROR(*stmt->error_info);
goto end; goto end;
} }
memcpy(tmp_buf, *buf, offset); memcpy(tmp_buf, *buf, offset);
@ -642,7 +642,7 @@ mysqlnd_stmt_execute_store_params(MYSQLND_STMT * s, zend_uchar **buf, zend_uchar
if (Z_TYPE_P(stmt->param_bind[i].zv) != IS_LONG && if (Z_TYPE_P(stmt->param_bind[i].zv) != IS_LONG &&
PASS != mysqlnd_stmt_copy_it(&copies, stmt->param_bind[i].zv, stmt->param_count, i TSRMLS_CC)) PASS != mysqlnd_stmt_copy_it(&copies, stmt->param_bind[i].zv, stmt->param_count, i TSRMLS_CC))
{ {
SET_OOM_ERROR(stmt->error_info); SET_OOM_ERROR(*stmt->error_info);
goto end; goto end;
} }
/* /*
@ -670,7 +670,7 @@ mysqlnd_stmt_execute_store_params(MYSQLND_STMT * s, zend_uchar **buf, zend_uchar
*buf_len = offset + stmt->param_count * 2 + 20; *buf_len = offset + stmt->param_count * 2 + 20;
tmp_buf = mnd_emalloc(*buf_len); tmp_buf = mnd_emalloc(*buf_len);
if (!tmp_buf) { if (!tmp_buf) {
SET_OOM_ERROR(stmt->error_info); SET_OOM_ERROR(*stmt->error_info);
goto end; goto end;
} }
memcpy(tmp_buf, *buf, offset); memcpy(tmp_buf, *buf, offset);
@ -733,7 +733,7 @@ mysqlnd_stmt_execute_store_params(MYSQLND_STMT * s, zend_uchar **buf, zend_uchar
/* Double binding of the same zval, make a copy */ /* Double binding of the same zval, make a copy */
if (!copies || !copies[i]) { if (!copies || !copies[i]) {
if (PASS != mysqlnd_stmt_copy_it(&copies, the_var, stmt->param_count, i TSRMLS_CC)) { if (PASS != mysqlnd_stmt_copy_it(&copies, the_var, stmt->param_count, i TSRMLS_CC)) {
SET_OOM_ERROR(stmt->error_info); SET_OOM_ERROR(*stmt->error_info);
goto end; goto end;
} }
} }
@ -747,7 +747,7 @@ mysqlnd_stmt_execute_store_params(MYSQLND_STMT * s, zend_uchar **buf, zend_uchar
if (Z_TYPE_P(the_var) != IS_DOUBLE) { if (Z_TYPE_P(the_var) != IS_DOUBLE) {
if (!copies || !copies[i]) { if (!copies || !copies[i]) {
if (PASS != mysqlnd_stmt_copy_it(&copies, the_var, stmt->param_count, i TSRMLS_CC)) { if (PASS != mysqlnd_stmt_copy_it(&copies, the_var, stmt->param_count, i TSRMLS_CC)) {
SET_OOM_ERROR(stmt->error_info); SET_OOM_ERROR(*stmt->error_info);
goto end; goto end;
} }
} }
@ -794,7 +794,7 @@ use_string:
{ {
if (!copies || !copies[i]) { if (!copies || !copies[i]) {
if (PASS != mysqlnd_stmt_copy_it(&copies, the_var, stmt->param_count, i TSRMLS_CC)) { if (PASS != mysqlnd_stmt_copy_it(&copies, the_var, stmt->param_count, i TSRMLS_CC)) {
SET_OOM_ERROR(stmt->error_info); SET_OOM_ERROR(*stmt->error_info);
goto end; goto end;
} }
} }
@ -819,7 +819,7 @@ use_string:
*buf_len = offset + data_size + 10; /* Allocate + 10 for safety */ *buf_len = offset + data_size + 10; /* Allocate + 10 for safety */
tmp_buf = mnd_emalloc(*buf_len); tmp_buf = mnd_emalloc(*buf_len);
if (!tmp_buf) { if (!tmp_buf) {
SET_OOM_ERROR(stmt->error_info); SET_OOM_ERROR(*stmt->error_info);
goto end; goto end;
} }
memcpy(tmp_buf, *buf, offset); memcpy(tmp_buf, *buf, offset);

View file

@ -55,8 +55,8 @@ MYSQLND_METHOD(mysqlnd_res, initialize_result_set_rest)(MYSQLND_RES * const resu
data_cursor, data_cursor,
result->meta->field_count, result->meta->field_count,
result->meta->fields, result->meta->fields,
result->conn->options.numeric_and_datetime_as_unicode, result->conn->options->numeric_and_datetime_as_unicode,
result->conn->options.int_and_float_native, result->conn->options->int_and_float_native,
result->conn->stats TSRMLS_CC); result->conn->stats TSRMLS_CC);
if (rc != PASS) { if (rc != PASS) {
ret = FAIL; ret = FAIL;
@ -332,7 +332,7 @@ MYSQLND_METHOD(mysqlnd_res, read_result_metadata)(MYSQLND_RES * result, MYSQLND
result->meta = result->m.result_meta_init(result->field_count, result->persistent TSRMLS_CC); result->meta = result->m.result_meta_init(result->field_count, result->persistent TSRMLS_CC);
if (!result->meta) { if (!result->meta) {
SET_OOM_ERROR(conn->error_info); SET_OOM_ERROR(*conn->error_info);
DBG_RETURN(FAIL); DBG_RETURN(FAIL);
} }
@ -374,7 +374,7 @@ mysqlnd_query_read_result_set_header(MYSQLND *conn, MYSQLND_STMT * s TSRMLS_DC)
do { do {
rset_header = conn->protocol->m.get_rset_header_packet(conn->protocol, FALSE TSRMLS_CC); rset_header = conn->protocol->m.get_rset_header_packet(conn->protocol, FALSE TSRMLS_CC);
if (!rset_header) { if (!rset_header) {
SET_OOM_ERROR(conn->error_info); SET_OOM_ERROR(*conn->error_info);
ret = FAIL; ret = FAIL;
break; break;
} }
@ -396,19 +396,19 @@ mysqlnd_query_read_result_set_header(MYSQLND *conn, MYSQLND_STMT * s TSRMLS_DC)
a multi-statement or a stored procedure, so it should be a multi-statement or a stored procedure, so it should be
safe to unconditionally turn off the flag here. safe to unconditionally turn off the flag here.
*/ */
conn->upsert_status.server_status &= ~SERVER_MORE_RESULTS_EXISTS; conn->upsert_status->server_status &= ~SERVER_MORE_RESULTS_EXISTS;
/* /*
This will copy the error code and the messages, as they This will copy the error code and the messages, as they
are buffers in the struct are buffers in the struct
*/ */
COPY_CLIENT_ERROR(conn->error_info, rset_header->error_info); COPY_CLIENT_ERROR(*conn->error_info, rset_header->error_info);
ret = FAIL; ret = FAIL;
DBG_ERR_FMT("error=%s", rset_header->error_info.error); DBG_ERR_FMT("error=%s", rset_header->error_info.error);
/* Return back from CONN_QUERY_SENT */ /* Return back from CONN_QUERY_SENT */
CONN_SET_STATE(conn, CONN_READY); CONN_SET_STATE(conn, CONN_READY);
break; break;
} }
conn->error_info.error_no = 0; conn->error_info->error_no = 0;
switch (rset_header->field_count) { switch (rset_header->field_count) {
case MYSQLND_NULL_LENGTH: { /* LOAD DATA LOCAL INFILE */ case MYSQLND_NULL_LENGTH: { /* LOAD DATA LOCAL INFILE */
@ -426,15 +426,15 @@ mysqlnd_query_read_result_set_header(MYSQLND *conn, MYSQLND_STMT * s TSRMLS_DC)
DBG_INF("UPSERT"); DBG_INF("UPSERT");
conn->last_query_type = QUERY_UPSERT; conn->last_query_type = QUERY_UPSERT;
conn->field_count = rset_header->field_count; conn->field_count = rset_header->field_count;
conn->upsert_status.warning_count = rset_header->warning_count; conn->upsert_status->warning_count = rset_header->warning_count;
conn->upsert_status.server_status = rset_header->server_status; conn->upsert_status->server_status = rset_header->server_status;
conn->upsert_status.affected_rows = rset_header->affected_rows; conn->upsert_status->affected_rows = rset_header->affected_rows;
conn->upsert_status.last_insert_id = rset_header->last_insert_id; conn->upsert_status->last_insert_id = rset_header->last_insert_id;
SET_NEW_MESSAGE(conn->last_message, conn->last_message_len, SET_NEW_MESSAGE(conn->last_message, conn->last_message_len,
rset_header->info_or_local_file, rset_header->info_or_local_file_len, rset_header->info_or_local_file, rset_header->info_or_local_file_len,
conn->persistent); conn->persistent);
/* Result set can follow UPSERT statement, check server_status */ /* Result set can follow UPSERT statement, check server_status */
if (conn->upsert_status.server_status & SERVER_MORE_RESULTS_EXISTS) { if (conn->upsert_status->server_status & SERVER_MORE_RESULTS_EXISTS) {
CONN_SET_STATE(conn, CONN_NEXT_RESULT_PENDING); CONN_SET_STATE(conn, CONN_NEXT_RESULT_PENDING);
} else { } else {
CONN_SET_STATE(conn, CONN_READY); CONN_SET_STATE(conn, CONN_READY);
@ -450,7 +450,7 @@ mysqlnd_query_read_result_set_header(MYSQLND *conn, MYSQLND_STMT * s TSRMLS_DC)
SET_EMPTY_MESSAGE(conn->last_message, conn->last_message_len, conn->persistent); SET_EMPTY_MESSAGE(conn->last_message, conn->last_message_len, conn->persistent);
MYSQLND_INC_CONN_STATISTIC(conn->stats, STAT_RSET_QUERY); MYSQLND_INC_CONN_STATISTIC(conn->stats, STAT_RSET_QUERY);
memset(&conn->upsert_status, 0, sizeof(conn->upsert_status)); memset(conn->upsert_status, 0, sizeof(*conn->upsert_status));
/* restore after zeroing */ /* restore after zeroing */
SET_ERROR_AFF_ROWS(conn); SET_ERROR_AFF_ROWS(conn);
@ -486,7 +486,7 @@ mysqlnd_query_read_result_set_header(MYSQLND *conn, MYSQLND_STMT * s TSRMLS_DC)
result = stmt->result; result = stmt->result;
} }
if (!result) { if (!result) {
SET_OOM_ERROR(conn->error_info); SET_OOM_ERROR(*conn->error_info);
ret = FAIL; ret = FAIL;
break; break;
} }
@ -504,7 +504,7 @@ mysqlnd_query_read_result_set_header(MYSQLND *conn, MYSQLND_STMT * s TSRMLS_DC)
/* Check for SERVER_STATUS_MORE_RESULTS if needed */ /* Check for SERVER_STATUS_MORE_RESULTS if needed */
fields_eof = conn->protocol->m.get_eof_packet(conn->protocol, FALSE TSRMLS_CC); fields_eof = conn->protocol->m.get_eof_packet(conn->protocol, FALSE TSRMLS_CC);
if (!fields_eof) { if (!fields_eof) {
SET_OOM_ERROR(conn->error_info); SET_OOM_ERROR(*conn->error_info);
ret = FAIL; ret = FAIL;
break; break;
} }
@ -523,7 +523,7 @@ mysqlnd_query_read_result_set_header(MYSQLND *conn, MYSQLND_STMT * s TSRMLS_DC)
unsigned int to_log = MYSQLND_G(log_mask); unsigned int to_log = MYSQLND_G(log_mask);
to_log &= fields_eof->server_status; to_log &= fields_eof->server_status;
DBG_INF_FMT("warnings=%u server_status=%u", fields_eof->warning_count, fields_eof->server_status); DBG_INF_FMT("warnings=%u server_status=%u", fields_eof->warning_count, fields_eof->server_status);
conn->upsert_status.warning_count = fields_eof->warning_count; conn->upsert_status->warning_count = fields_eof->warning_count;
/* /*
If SERVER_MORE_RESULTS_EXISTS is set then this is either MULTI_QUERY or a CALL() If SERVER_MORE_RESULTS_EXISTS is set then this is either MULTI_QUERY or a CALL()
The first packet after sending the query/com_execute has the bit set only The first packet after sending the query/com_execute has the bit set only
@ -531,7 +531,7 @@ mysqlnd_query_read_result_set_header(MYSQLND *conn, MYSQLND_STMT * s TSRMLS_DC)
will include many result sets. What actually matters are the bits set at the end will include many result sets. What actually matters are the bits set at the end
of every result set (the EOF packet). of every result set (the EOF packet).
*/ */
conn->upsert_status.server_status = fields_eof->server_status; conn->upsert_status->server_status = fields_eof->server_status;
if (fields_eof->server_status & SERVER_QUERY_NO_GOOD_INDEX_USED) { if (fields_eof->server_status & SERVER_QUERY_NO_GOOD_INDEX_USED) {
statistic = STAT_BAD_INDEX_USED; statistic = STAT_BAD_INDEX_USED;
} else if (fields_eof->server_status & SERVER_QUERY_NO_INDEX_USED) { } else if (fields_eof->server_status & SERVER_QUERY_NO_INDEX_USED) {
@ -634,7 +634,7 @@ mysqlnd_fetch_row_unbuffered_c(MYSQLND_RES * result TSRMLS_DC)
DBG_RETURN(retrow); DBG_RETURN(retrow);
} }
if (CONN_GET_STATE(result->conn) != CONN_FETCHING_DATA) { if (CONN_GET_STATE(result->conn) != CONN_FETCHING_DATA) {
SET_CLIENT_ERROR(result->conn->error_info, CR_COMMANDS_OUT_OF_SYNC, SET_CLIENT_ERROR(*result->conn->error_info, CR_COMMANDS_OUT_OF_SYNC,
UNKNOWN_SQLSTATE, mysqlnd_out_of_sync); UNKNOWN_SQLSTATE, mysqlnd_out_of_sync);
DBG_RETURN(retrow); DBG_RETURN(retrow);
} }
@ -669,8 +669,8 @@ mysqlnd_fetch_row_unbuffered_c(MYSQLND_RES * result TSRMLS_DC)
result->unbuf->last_row_data, result->unbuf->last_row_data,
row_packet->field_count, row_packet->field_count,
row_packet->fields_metadata, row_packet->fields_metadata,
result->conn->options.numeric_and_datetime_as_unicode, result->conn->options->numeric_and_datetime_as_unicode,
result->conn->options.int_and_float_native, result->conn->options->int_and_float_native,
result->conn->stats TSRMLS_CC); result->conn->stats TSRMLS_CC);
if (PASS != rc) { if (PASS != rc) {
DBG_RETURN(retrow); DBG_RETURN(retrow);
@ -700,12 +700,12 @@ mysqlnd_fetch_row_unbuffered_c(MYSQLND_RES * result TSRMLS_DC)
} }
} }
} else { } else {
SET_OOM_ERROR(result->conn->error_info); SET_OOM_ERROR(*result->conn->error_info);
} }
} }
} else if (ret == FAIL) { } else if (ret == FAIL) {
if (row_packet->error_info.error_no) { if (row_packet->error_info.error_no) {
COPY_CLIENT_ERROR(result->conn->error_info, row_packet->error_info); COPY_CLIENT_ERROR(*result->conn->error_info, row_packet->error_info);
DBG_ERR_FMT("errorno=%u error=%s", row_packet->error_info.error_no, row_packet->error_info.error); DBG_ERR_FMT("errorno=%u error=%s", row_packet->error_info.error_no, row_packet->error_info.error);
} }
CONN_SET_STATE(result->conn, CONN_READY); CONN_SET_STATE(result->conn, CONN_READY);
@ -714,13 +714,13 @@ mysqlnd_fetch_row_unbuffered_c(MYSQLND_RES * result TSRMLS_DC)
/* Mark the connection as usable again */ /* Mark the connection as usable again */
DBG_INF_FMT("warnings=%u server_status=%u", row_packet->warning_count, row_packet->server_status); DBG_INF_FMT("warnings=%u server_status=%u", row_packet->warning_count, row_packet->server_status);
result->unbuf->eof_reached = TRUE; result->unbuf->eof_reached = TRUE;
result->conn->upsert_status.warning_count = row_packet->warning_count; result->conn->upsert_status->warning_count = row_packet->warning_count;
result->conn->upsert_status.server_status = row_packet->server_status; result->conn->upsert_status->server_status = row_packet->server_status;
/* /*
result->row_packet will be cleaned when result->row_packet will be cleaned when
destroying the result object destroying the result object
*/ */
if (result->conn->upsert_status.server_status & SERVER_MORE_RESULTS_EXISTS) { if (result->conn->upsert_status->server_status & SERVER_MORE_RESULTS_EXISTS) {
CONN_SET_STATE(result->conn, CONN_NEXT_RESULT_PENDING); CONN_SET_STATE(result->conn, CONN_NEXT_RESULT_PENDING);
} else { } else {
CONN_SET_STATE(result->conn, CONN_READY); CONN_SET_STATE(result->conn, CONN_READY);
@ -749,7 +749,7 @@ mysqlnd_fetch_row_unbuffered(MYSQLND_RES * result, void *param, unsigned int fla
DBG_RETURN(PASS); DBG_RETURN(PASS);
} }
if (CONN_GET_STATE(result->conn) != CONN_FETCHING_DATA) { if (CONN_GET_STATE(result->conn) != CONN_FETCHING_DATA) {
SET_CLIENT_ERROR(result->conn->error_info, CR_COMMANDS_OUT_OF_SYNC, UNKNOWN_SQLSTATE, mysqlnd_out_of_sync); SET_CLIENT_ERROR(*result->conn->error_info, CR_COMMANDS_OUT_OF_SYNC, UNKNOWN_SQLSTATE, mysqlnd_out_of_sync);
DBG_RETURN(FAIL); DBG_RETURN(FAIL);
} }
if (!row_packet) { if (!row_packet) {
@ -784,8 +784,8 @@ mysqlnd_fetch_row_unbuffered(MYSQLND_RES * result, void *param, unsigned int fla
result->unbuf->last_row_data, result->unbuf->last_row_data,
field_count, field_count,
row_packet->fields_metadata, row_packet->fields_metadata,
result->conn->options.numeric_and_datetime_as_unicode, result->conn->options->numeric_and_datetime_as_unicode,
result->conn->options.int_and_float_native, result->conn->options->int_and_float_native,
result->conn->stats TSRMLS_CC); result->conn->stats TSRMLS_CC);
if (PASS != rc) { if (PASS != rc) {
DBG_RETURN(FAIL); DBG_RETURN(FAIL);
@ -840,7 +840,7 @@ mysqlnd_fetch_row_unbuffered(MYSQLND_RES * result, void *param, unsigned int fla
result->unbuf->row_count++; result->unbuf->row_count++;
} else if (ret == FAIL) { } else if (ret == FAIL) {
if (row_packet->error_info.error_no) { if (row_packet->error_info.error_no) {
COPY_CLIENT_ERROR(result->conn->error_info, row_packet->error_info); COPY_CLIENT_ERROR(*result->conn->error_info, row_packet->error_info);
DBG_ERR_FMT("errorno=%u error=%s", row_packet->error_info.error_no, row_packet->error_info.error); DBG_ERR_FMT("errorno=%u error=%s", row_packet->error_info.error_no, row_packet->error_info.error);
} }
CONN_SET_STATE(result->conn, CONN_READY); CONN_SET_STATE(result->conn, CONN_READY);
@ -849,13 +849,13 @@ mysqlnd_fetch_row_unbuffered(MYSQLND_RES * result, void *param, unsigned int fla
/* Mark the connection as usable again */ /* Mark the connection as usable again */
DBG_INF_FMT("warnings=%u server_status=%u", row_packet->warning_count, row_packet->server_status); DBG_INF_FMT("warnings=%u server_status=%u", row_packet->warning_count, row_packet->server_status);
result->unbuf->eof_reached = TRUE; result->unbuf->eof_reached = TRUE;
result->conn->upsert_status.warning_count = row_packet->warning_count; result->conn->upsert_status->warning_count = row_packet->warning_count;
result->conn->upsert_status.server_status = row_packet->server_status; result->conn->upsert_status->server_status = row_packet->server_status;
/* /*
result->row_packet will be cleaned when result->row_packet will be cleaned when
destroying the result object destroying the result object
*/ */
if (result->conn->upsert_status.server_status & SERVER_MORE_RESULTS_EXISTS) { if (result->conn->upsert_status->server_status & SERVER_MORE_RESULTS_EXISTS) {
CONN_SET_STATE(result->conn, CONN_NEXT_RESULT_PENDING); CONN_SET_STATE(result->conn, CONN_NEXT_RESULT_PENDING);
} else { } else {
CONN_SET_STATE(result->conn, CONN_READY); CONN_SET_STATE(result->conn, CONN_READY);
@ -875,8 +875,7 @@ MYSQLND_METHOD(mysqlnd_res, use_result)(MYSQLND_RES * const result, zend_bool ps
{ {
DBG_ENTER("mysqlnd_res::use_result"); DBG_ENTER("mysqlnd_res::use_result");
SET_EMPTY_ERROR(result->conn->error_info); SET_EMPTY_ERROR(*result->conn->error_info);
if (ps == FALSE) { if (ps == FALSE) {
result->type = MYSQLND_RES_NORMAL; result->type = MYSQLND_RES_NORMAL;
@ -921,7 +920,7 @@ MYSQLND_METHOD(mysqlnd_res, use_result)(MYSQLND_RES * const result, zend_bool ps
DBG_RETURN(result); DBG_RETURN(result);
oom: oom:
SET_OOM_ERROR(result->conn->error_info); SET_OOM_ERROR(*result->conn->error_info);
DBG_RETURN(NULL); DBG_RETURN(NULL);
} }
/* }}} */ /* }}} */
@ -951,8 +950,8 @@ mysqlnd_fetch_row_buffered_c(MYSQLND_RES * result TSRMLS_DC)
current_row, current_row,
result->meta->field_count, result->meta->field_count,
result->meta->fields, result->meta->fields,
result->conn->options.numeric_and_datetime_as_unicode, result->conn->options->numeric_and_datetime_as_unicode,
result->conn->options.int_and_float_native, result->conn->options->int_and_float_native,
result->conn->stats TSRMLS_CC); result->conn->stats TSRMLS_CC);
if (rc != PASS) { if (rc != PASS) {
DBG_RETURN(ret); DBG_RETURN(ret);
@ -1024,8 +1023,8 @@ mysqlnd_fetch_row_buffered(MYSQLND_RES * result, void *param, unsigned int flags
current_row, current_row,
result->meta->field_count, result->meta->field_count,
result->meta->fields, result->meta->fields,
result->conn->options.numeric_and_datetime_as_unicode, result->conn->options->numeric_and_datetime_as_unicode,
result->conn->options.int_and_float_native, result->conn->options->int_and_float_native,
result->conn->stats TSRMLS_CC); result->conn->stats TSRMLS_CC);
if (rc != PASS) { if (rc != PASS) {
DBG_RETURN(FAIL); DBG_RETURN(FAIL);
@ -1116,14 +1115,14 @@ MYSQLND_METHOD(mysqlnd_res, store_result_fetch_data)(MYSQLND * const conn, MYSQL
result->stored_data = set = mnd_ecalloc(1, sizeof(MYSQLND_RES_BUFFERED)); result->stored_data = set = mnd_ecalloc(1, sizeof(MYSQLND_RES_BUFFERED));
if (!set) { if (!set) {
SET_OOM_ERROR(conn->error_info); SET_OOM_ERROR(*conn->error_info);
ret = FAIL; ret = FAIL;
goto end; goto end;
} }
if (free_rows) { if (free_rows) {
set->row_buffers = mnd_emalloc((size_t)(free_rows * sizeof(MYSQLND_MEMORY_POOL_CHUNK *))); set->row_buffers = mnd_emalloc((size_t)(free_rows * sizeof(MYSQLND_MEMORY_POOL_CHUNK *)));
if (!set->row_buffers) { if (!set->row_buffers) {
SET_OOM_ERROR(conn->error_info); SET_OOM_ERROR(*conn->error_info);
ret = FAIL; ret = FAIL;
goto end; goto end;
} }
@ -1133,7 +1132,7 @@ MYSQLND_METHOD(mysqlnd_res, store_result_fetch_data)(MYSQLND * const conn, MYSQL
/* non-persistent */ /* non-persistent */
row_packet = conn->protocol->m.get_row_packet(conn->protocol, FALSE TSRMLS_CC); row_packet = conn->protocol->m.get_row_packet(conn->protocol, FALSE TSRMLS_CC);
if (!row_packet) { if (!row_packet) {
SET_OOM_ERROR(conn->error_info); SET_OOM_ERROR(*conn->error_info);
ret = FAIL; ret = FAIL;
goto end; goto end;
} }
@ -1154,13 +1153,13 @@ MYSQLND_METHOD(mysqlnd_res, store_result_fetch_data)(MYSQLND * const conn, MYSQL
/* don't try to allocate more than possible - mnd_XXalloc expects size_t, and it can have narrower range than uint64_t */ /* don't try to allocate more than possible - mnd_XXalloc expects size_t, and it can have narrower range than uint64_t */
if (total_allocated_rows * sizeof(MYSQLND_MEMORY_POOL_CHUNK *) > SIZE_MAX) { if (total_allocated_rows * sizeof(MYSQLND_MEMORY_POOL_CHUNK *) > SIZE_MAX) {
SET_OOM_ERROR(conn->error_info); SET_OOM_ERROR(*conn->error_info);
ret = FAIL; ret = FAIL;
goto end; goto end;
} }
new_row_buffers = mnd_erealloc(set->row_buffers, (size_t)(total_allocated_rows * sizeof(MYSQLND_MEMORY_POOL_CHUNK *))); new_row_buffers = mnd_erealloc(set->row_buffers, (size_t)(total_allocated_rows * sizeof(MYSQLND_MEMORY_POOL_CHUNK *)));
if (!new_row_buffers) { if (!new_row_buffers) {
SET_OOM_ERROR(conn->error_info); SET_OOM_ERROR(*conn->error_info);
ret = FAIL; ret = FAIL;
goto end; goto end;
} }
@ -1186,14 +1185,14 @@ MYSQLND_METHOD(mysqlnd_res, store_result_fetch_data)(MYSQLND * const conn, MYSQL
if (set->row_count) { if (set->row_count) {
/* don't try to allocate more than possible - mnd_XXalloc expects size_t, and it can have narrower range than uint64_t */ /* don't try to allocate more than possible - mnd_XXalloc expects size_t, and it can have narrower range than uint64_t */
if (set->row_count * meta->field_count * sizeof(zval *) > SIZE_MAX) { if (set->row_count * meta->field_count * sizeof(zval *) > SIZE_MAX) {
SET_OOM_ERROR(conn->error_info); SET_OOM_ERROR(*conn->error_info);
ret = FAIL; ret = FAIL;
goto end; goto end;
} }
/* if pecalloc is used valgrind barks gcc version 4.3.1 20080507 (prerelease) [gcc-4_3-branch revision 135036] (SUSE Linux) */ /* if pecalloc is used valgrind barks gcc version 4.3.1 20080507 (prerelease) [gcc-4_3-branch revision 135036] (SUSE Linux) */
set->data = mnd_emalloc((size_t)(set->row_count * meta->field_count * sizeof(zval *))); set->data = mnd_emalloc((size_t)(set->row_count * meta->field_count * sizeof(zval *)));
if (!set->data) { if (!set->data) {
SET_OOM_ERROR(conn->error_info); SET_OOM_ERROR(*conn->error_info);
ret = FAIL; ret = FAIL;
goto end; goto end;
} }
@ -1207,21 +1206,21 @@ MYSQLND_METHOD(mysqlnd_res, store_result_fetch_data)(MYSQLND * const conn, MYSQL
/* Finally clean */ /* Finally clean */
if (row_packet->eof) { if (row_packet->eof) {
conn->upsert_status.warning_count = row_packet->warning_count; conn->upsert_status->warning_count = row_packet->warning_count;
conn->upsert_status.server_status = row_packet->server_status; conn->upsert_status->server_status = row_packet->server_status;
} }
/* save some memory */ /* save some memory */
if (free_rows) { if (free_rows) {
/* don't try to allocate more than possible - mnd_XXalloc expects size_t, and it can have narrower range than uint64_t */ /* don't try to allocate more than possible - mnd_XXalloc expects size_t, and it can have narrower range than uint64_t */
if (set->row_count * sizeof(MYSQLND_MEMORY_POOL_CHUNK *) > SIZE_MAX) { if (set->row_count * sizeof(MYSQLND_MEMORY_POOL_CHUNK *) > SIZE_MAX) {
SET_OOM_ERROR(conn->error_info); SET_OOM_ERROR(*conn->error_info);
ret = FAIL; ret = FAIL;
goto end; goto end;
} }
set->row_buffers = mnd_erealloc(set->row_buffers, (size_t) (set->row_count * sizeof(MYSQLND_MEMORY_POOL_CHUNK *))); set->row_buffers = mnd_erealloc(set->row_buffers, (size_t) (set->row_count * sizeof(MYSQLND_MEMORY_POOL_CHUNK *)));
} }
if (conn->upsert_status.server_status & SERVER_MORE_RESULTS_EXISTS) { if (conn->upsert_status->server_status & SERVER_MORE_RESULTS_EXISTS) {
CONN_SET_STATE(conn, CONN_NEXT_RESULT_PENDING); CONN_SET_STATE(conn, CONN_NEXT_RESULT_PENDING);
} else { } else {
CONN_SET_STATE(conn, CONN_READY); CONN_SET_STATE(conn, CONN_READY);
@ -1234,10 +1233,10 @@ MYSQLND_METHOD(mysqlnd_res, store_result_fetch_data)(MYSQLND * const conn, MYSQL
set->data_cursor = set->data; set->data_cursor = set->data;
/* libmysql's documentation says it should be so for SELECT statements */ /* libmysql's documentation says it should be so for SELECT statements */
conn->upsert_status.affected_rows = set->row_count; conn->upsert_status->affected_rows = set->row_count;
} }
DBG_INF_FMT("ret=%s row_count=%u warnings=%u server_status=%u", DBG_INF_FMT("ret=%s row_count=%u warnings=%u server_status=%u",
ret == PASS? "PASS":"FAIL", (uint) set->row_count, conn->upsert_status.warning_count, conn->upsert_status.server_status); ret == PASS? "PASS":"FAIL", (uint) set->row_count, conn->upsert_status->warning_count, conn->upsert_status->server_status);
end: end:
PACKET_FREE(row_packet); PACKET_FREE(row_packet);
@ -1268,7 +1267,7 @@ MYSQLND_METHOD(mysqlnd_res, store_result)(MYSQLND_RES * result,
result->lengths = mnd_ecalloc(result->field_count, sizeof(unsigned long)); result->lengths = mnd_ecalloc(result->field_count, sizeof(unsigned long));
if (!result->result_set_memory_pool || !result->lengths) { if (!result->result_set_memory_pool || !result->lengths) {
SET_OOM_ERROR(conn->error_info); SET_OOM_ERROR(*conn->error_info);
DBG_RETURN(NULL); DBG_RETURN(NULL);
} }
@ -1277,14 +1276,14 @@ MYSQLND_METHOD(mysqlnd_res, store_result)(MYSQLND_RES * result,
ret = result->m.store_result_fetch_data(conn, result, result->meta, ps_protocol TSRMLS_CC); ret = result->m.store_result_fetch_data(conn, result, result->meta, ps_protocol TSRMLS_CC);
if (FAIL == ret) { if (FAIL == ret) {
if (result->stored_data) { if (result->stored_data) {
COPY_CLIENT_ERROR(conn->error_info, result->stored_data->error_info); COPY_CLIENT_ERROR(*conn->error_info, result->stored_data->error_info);
} else { } else {
SET_OOM_ERROR(conn->error_info); SET_OOM_ERROR(*conn->error_info);
} }
DBG_RETURN(NULL); DBG_RETURN(NULL);
} }
/* libmysql's documentation says it should be so for SELECT statements */ /* libmysql's documentation says it should be so for SELECT statements */
conn->upsert_status.affected_rows = result->stored_data->row_count; conn->upsert_status->affected_rows = result->stored_data->row_count;
DBG_RETURN(result); DBG_RETURN(result);
} }
@ -1567,7 +1566,7 @@ MYSQLND_METHOD(mysqlnd_res, fetch_all)(MYSQLND_RES * result, unsigned int flags,
if ((!result->unbuf && !set)) { if ((!result->unbuf && !set)) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "fetch_all can be used only with buffered sets"); php_error_docref(NULL TSRMLS_CC, E_WARNING, "fetch_all can be used only with buffered sets");
if (result->conn) { if (result->conn) {
SET_CLIENT_ERROR(result->conn->error_info, CR_NOT_IMPLEMENTED, UNKNOWN_SQLSTATE, "fetch_all can be used only with buffered sets"); SET_CLIENT_ERROR(*result->conn->error_info, CR_NOT_IMPLEMENTED, UNKNOWN_SQLSTATE, "fetch_all can be used only with buffered sets");
} }
RETVAL_NULL(); RETVAL_NULL();
DBG_VOID_RETURN; DBG_VOID_RETURN;

View file

@ -12,9 +12,9 @@
| obtain it through the world-wide-web, please send a note to | | obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. | | license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
| Authors: Georg Richter <georg@mysql.com> | | Authors: Andrey Hristov <andrey@mysql.com> |
| Andrey Hristov <andrey@mysql.com> |
| Ulf Wendel <uwendel@mysql.com> | | Ulf Wendel <uwendel@mysql.com> |
| Georg Richter <georg@mysql.com> |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
*/ */
@ -138,7 +138,7 @@ mysqlnd_unicode_is_key_numeric(UChar *key, size_t length, long *idx)
/* {{{ mysqlnd_res_meta::read_metadata */ /* {{{ mysqlnd_res_meta::read_metadata */
static enum_func_status static enum_func_status
MYSQLND_METHOD(mysqlnd_res_meta, read_metadata)(MYSQLND_RES_METADATA * const meta, MYSQLND *conn TSRMLS_DC) MYSQLND_METHOD(mysqlnd_res_meta, read_metadata)(MYSQLND_RES_METADATA * const meta, MYSQLND * conn TSRMLS_DC)
{ {
unsigned int i = 0; unsigned int i = 0;
MYSQLND_PACKET_RES_FIELD * field_packet; MYSQLND_PACKET_RES_FIELD * field_packet;
@ -151,7 +151,7 @@ MYSQLND_METHOD(mysqlnd_res_meta, read_metadata)(MYSQLND_RES_METADATA * const met
field_packet = conn->protocol->m.get_result_field_packet(conn->protocol, FALSE TSRMLS_CC); field_packet = conn->protocol->m.get_result_field_packet(conn->protocol, FALSE TSRMLS_CC);
if (!field_packet) { if (!field_packet) {
SET_OOM_ERROR(conn->error_info); SET_OOM_ERROR(*conn->error_info);
DBG_RETURN(FAIL); DBG_RETURN(FAIL);
} }
field_packet->persistent_alloc = meta->persistent; field_packet->persistent_alloc = meta->persistent;
@ -170,7 +170,7 @@ MYSQLND_METHOD(mysqlnd_res_meta, read_metadata)(MYSQLND_RES_METADATA * const met
DBG_RETURN(FAIL); DBG_RETURN(FAIL);
} }
if (field_packet->error_info.error_no) { if (field_packet->error_info.error_no) {
COPY_CLIENT_ERROR(conn->error_info, field_packet->error_info); COPY_CLIENT_ERROR(*conn->error_info, field_packet->error_info);
/* Return back from CONN_QUERY_SENT */ /* Return back from CONN_QUERY_SENT */
PACKET_FREE(field_packet); PACKET_FREE(field_packet);
DBG_RETURN(FAIL); DBG_RETURN(FAIL);

View file

@ -12,9 +12,9 @@
| obtain it through the world-wide-web, please send a note to | | obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. | | license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
| Authors: Georg Richter <georg@mysql.com> | | Authors: Andrey Hristov <andrey@mysql.com> |
| Andrey Hristov <andrey@mysql.com> |
| Ulf Wendel <uwendel@mysql.com> | | Ulf Wendel <uwendel@mysql.com> |
| Georg Richter <georg@mysql.com> |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
*/ */

View file

@ -13,20 +13,17 @@
| license@php.net so we can mail you a copy immediately. | | license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
| Authors: Andrey Hristov <andrey@mysql.com> | | Authors: Andrey Hristov <andrey@mysql.com> |
| Georg Richter <georg@mysql.com> |
| Ulf Wendel <uwendel@mysql.com> | | Ulf Wendel <uwendel@mysql.com> |
| Georg Richter <georg@mysql.com> |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
*/ */
/* $Id: mysqlnd.c 317989 2011-10-10 20:49:28Z andrey $ */ /* $Id: mysqlnd.c 317989 2011-10-10 20:49:28Z andrey $ */
#include "php.h" #include "php.h"
#include "mysqlnd.h" #include "mysqlnd.h"
#include "mysqlnd_wireprotocol.h"
#include "mysqlnd_priv.h" #include "mysqlnd_priv.h"
#include "mysqlnd_result.h"
#include "mysqlnd_statistics.h"
#include "mysqlnd_charset.h"
#include "mysqlnd_debug.h" #include "mysqlnd_debug.h"
#include "mysqlnd_reverse_api.h"
static HashTable mysqlnd_api_ext_ht; static HashTable mysqlnd_api_ext_ht;
@ -52,7 +49,7 @@ mysqlnd_reverse_api_end(TSRMLS_D)
/* {{{ myslqnd_get_api_extensions */ /* {{{ myslqnd_get_api_extensions */
PHPAPI HashTable * PHPAPI HashTable *
mysqlnd_reverse_api_get_api_list(TSRLMLS_D) mysqlnd_reverse_api_get_api_list(TSRMLS_D)
{ {
return &mysqlnd_api_ext_ht; return &mysqlnd_api_ext_ht;
} }

View file

@ -13,22 +13,27 @@
| license@php.net so we can mail you a copy immediately. | | license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
| Authors: Andrey Hristov <andrey@mysql.com> | | Authors: Andrey Hristov <andrey@mysql.com> |
| Georg Richter <georg@mysql.com> |
| Ulf Wendel <uwendel@mysql.com> | | Ulf Wendel <uwendel@mysql.com> |
| Georg Richter <georg@mysql.com> |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
*/ */
/* $Id: mysqlnd.h 318051 2011-10-12 16:18:02Z andrey $ */ /* $Id: mysqlnd.h 318051 2011-10-12 16:18:02Z andrey $ */
#ifndef MYSQLND_REVERSE_API_H #ifndef MYSQLND_REVERSE_API_H
#define MYSQLND_REVERSE_API_H #define MYSQLND_REVERSE_API_H
struct st_mysqlnd_api_extension; typedef struct st_mysqlnd_reverse_api
{
zend_module_entry * module;
MYSQLND *(*conversion_cb)(zval * zv TSRMLS_DC);
} MYSQLND_REVERSE_API;
PHPAPI void mysqlnd_reverse_api_init(TSRMLS_D); PHPAPI void mysqlnd_reverse_api_init(TSRMLS_D);
PHPAPI void mysqlnd_reverse_api_end(TSRMLS_D); PHPAPI void mysqlnd_reverse_api_end(TSRMLS_D);
PHPAPI HashTable * mysqlnd_reverse_api_get_api_list(TSRMLS_D); PHPAPI HashTable * mysqlnd_reverse_api_get_api_list(TSRMLS_D);
PHPAPI void mysqlnd_reverse_api_register_api(struct st_mysqlnd_api_extension * apiext TSRMLS_DC); PHPAPI void mysqlnd_reverse_api_register_api(MYSQLND_REVERSE_API * apiext TSRMLS_DC);
PHPAPI MYSQLND * zval_to_mysqlnd(zval * zv TSRMLS_DC); PHPAPI MYSQLND * zval_to_mysqlnd(zval * zv TSRMLS_DC);

View file

@ -433,6 +433,7 @@ typedef unsigned int (*func_mysqlnd_conn__get_warning_count)(const MYSQLND * co
typedef unsigned int (*func_mysqlnd_conn__get_field_count)(const MYSQLND * const conn TSRMLS_DC); typedef unsigned int (*func_mysqlnd_conn__get_field_count)(const MYSQLND * const conn TSRMLS_DC);
typedef unsigned int (*func_mysqlnd_conn__get_server_status)(const MYSQLND * const conn TSRMLS_DC);
typedef enum_func_status (*func_mysqlnd_conn__set_server_option)(MYSQLND * const conn, enum_mysqlnd_server_option option TSRMLS_DC); typedef enum_func_status (*func_mysqlnd_conn__set_server_option)(MYSQLND * const conn, enum_mysqlnd_server_option option TSRMLS_DC);
typedef enum_func_status (*func_mysqlnd_conn__set_client_option)(MYSQLND * const conn, enum_mysqlnd_option option, const char * const value TSRMLS_DC); typedef enum_func_status (*func_mysqlnd_conn__set_client_option)(MYSQLND * const conn, enum_mysqlnd_option option, const char * const value TSRMLS_DC);
typedef void (*func_mysqlnd_conn__free_contents)(MYSQLND *conn TSRMLS_DC); /* private */ typedef void (*func_mysqlnd_conn__free_contents)(MYSQLND *conn TSRMLS_DC); /* private */
@ -513,6 +514,8 @@ struct st_mysqlnd_conn_methods
func_mysqlnd_conn__get_field_count get_field_count; func_mysqlnd_conn__get_field_count get_field_count;
func_mysqlnd_conn__get_server_status get_server_status;
func_mysqlnd_conn__set_server_option set_server_option; func_mysqlnd_conn__set_server_option set_server_option;
func_mysqlnd_conn__set_client_option set_client_option; func_mysqlnd_conn__set_client_option set_client_option;
func_mysqlnd_conn__free_contents free_contents; func_mysqlnd_conn__free_contents free_contents;
@ -821,12 +824,14 @@ struct st_mysqlnd_connection
unsigned long server_capabilities; unsigned long server_capabilities;
/* For UPSERT queries */ /* For UPSERT queries */
MYSQLND_UPSERT_STATUS upsert_status; MYSQLND_UPSERT_STATUS * upsert_status;
MYSQLND_UPSERT_STATUS upsert_status_impl;
char *last_message; char *last_message;
unsigned int last_message_len; unsigned int last_message_len;
/* If error packet, we use these */ /* If error packet, we use these */
MYSQLND_ERROR_INFO error_info; MYSQLND_ERROR_INFO * error_info;
MYSQLND_ERROR_INFO error_info_impl;
/* /*
To prevent queries during unbuffered fetches. Also to To prevent queries during unbuffered fetches. Also to
@ -853,7 +858,8 @@ struct st_mysqlnd_connection
zend_bool persistent; zend_bool persistent;
/* options */ /* options */
MYSQLND_OPTIONS options; MYSQLND_OPTIONS * options;
MYSQLND_OPTIONS options_impl;
/* stats */ /* stats */
MYSQLND_STATS * stats; MYSQLND_STATS * stats;
@ -971,9 +977,11 @@ struct st_mysqlnd_stmt_data
zend_bool result_zvals_separated_once; zend_bool result_zvals_separated_once;
zend_bool persistent; zend_bool persistent;
MYSQLND_UPSERT_STATUS upsert_status; MYSQLND_UPSERT_STATUS * upsert_status;
MYSQLND_UPSERT_STATUS upsert_status_impl;
MYSQLND_ERROR_INFO error_info; MYSQLND_ERROR_INFO * error_info;
MYSQLND_ERROR_INFO error_info_impl;
zend_bool update_max_length; zend_bool update_max_length;
unsigned long prefetch_rows; unsigned long prefetch_rows;
@ -1053,11 +1061,4 @@ struct st_mysqlnd_authentication_plugin
}; };
typedef struct st_mysqlnd_reverse_api
{
zend_module_entry * module;
MYSQLND *(*conversion_cb)(zval * zv TSRMLS_DC);
} MYSQLND_REVERSE_API;
#endif /* MYSQLND_STRUCTS_H */ #endif /* MYSQLND_STRUCTS_H */

View file

@ -35,9 +35,9 @@
#define PACKET_READ_HEADER_AND_BODY(packet, conn, buf, buf_size, packet_type_as_text, packet_type) \ #define PACKET_READ_HEADER_AND_BODY(packet, conn, buf, buf_size, packet_type_as_text, packet_type) \
{ \ { \
DBG_INF_FMT("buf=%p size=%u", (buf), (buf_size)); \ DBG_INF_FMT("buf=%p size=%u", (buf), (buf_size)); \
if (FAIL == mysqlnd_read_header((conn)->net, &((packet)->header), (conn)->stats, &((conn)->error_info) TSRMLS_CC)) {\ if (FAIL == mysqlnd_read_header((conn)->net, &((packet)->header), (conn)->stats, ((conn)->error_info) TSRMLS_CC)) {\
CONN_SET_STATE(conn, CONN_QUIT_SENT); \ CONN_SET_STATE(conn, CONN_QUIT_SENT); \
SET_CLIENT_ERROR(conn->error_info, CR_SERVER_GONE_ERROR, UNKNOWN_SQLSTATE, mysqlnd_server_gone);\ SET_CLIENT_ERROR(*conn->error_info, CR_SERVER_GONE_ERROR, UNKNOWN_SQLSTATE, mysqlnd_server_gone);\
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", mysqlnd_server_gone); \ php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", mysqlnd_server_gone); \
DBG_ERR_FMT("Can't read %s's header", (packet_type_as_text)); \ DBG_ERR_FMT("Can't read %s's header", (packet_type_as_text)); \
DBG_RETURN(FAIL);\ DBG_RETURN(FAIL);\
@ -47,9 +47,9 @@
(buf_size), (packet)->header.size, (packet)->header.size - (buf_size)); \ (buf_size), (packet)->header.size, (packet)->header.size - (buf_size)); \
DBG_RETURN(FAIL); \ DBG_RETURN(FAIL); \
}\ }\
if (FAIL == conn->net->m.receive_ex((conn)->net, (buf), (packet)->header.size, (conn)->stats, &((conn)->error_info) TSRMLS_CC)) { \ if (FAIL == conn->net->m.receive_ex((conn)->net, (buf), (packet)->header.size, (conn)->stats, ((conn)->error_info) TSRMLS_CC)) { \
CONN_SET_STATE(conn, CONN_QUIT_SENT); \ CONN_SET_STATE(conn, CONN_QUIT_SENT); \
SET_CLIENT_ERROR(conn->error_info, CR_SERVER_GONE_ERROR, UNKNOWN_SQLSTATE, mysqlnd_server_gone);\ SET_CLIENT_ERROR(*conn->error_info, CR_SERVER_GONE_ERROR, UNKNOWN_SQLSTATE, mysqlnd_server_gone);\
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", mysqlnd_server_gone); \ php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", mysqlnd_server_gone); \
DBG_ERR_FMT("Empty '%s' packet body", (packet_type_as_text)); \ DBG_ERR_FMT("Empty '%s' packet body", (packet_type_as_text)); \
DBG_RETURN(FAIL);\ DBG_RETURN(FAIL);\
@ -541,7 +541,7 @@ size_t php_mysqlnd_auth_write(void * _packet, MYSQLND * conn TSRMLS_DC)
} }
DBG_RETURN(p - buffer - MYSQLND_HEADER_SIZE); DBG_RETURN(p - buffer - MYSQLND_HEADER_SIZE);
} else { } else {
size_t sent = conn->net->m.send_ex(conn->net, buffer, p - buffer - MYSQLND_HEADER_SIZE, conn->stats, &conn->error_info TSRMLS_CC); size_t sent = conn->net->m.send_ex(conn->net, buffer, p - buffer - MYSQLND_HEADER_SIZE, conn->stats, conn->error_info TSRMLS_CC);
if (!sent) { if (!sent) {
CONN_SET_STATE(conn, CONN_QUIT_SENT); CONN_SET_STATE(conn, CONN_QUIT_SENT);
} }
@ -701,7 +701,7 @@ php_mysqlnd_change_auth_response_write(void * _packet, MYSQLND * conn TSRMLS_DC)
} }
{ {
size_t sent = conn->net->m.send_ex(conn->net, buffer, p - buffer - MYSQLND_HEADER_SIZE, conn->stats, &conn->error_info TSRMLS_CC); size_t sent = conn->net->m.send_ex(conn->net, buffer, p - buffer - MYSQLND_HEADER_SIZE, conn->stats, conn->error_info TSRMLS_CC);
if (buffer != conn->net->cmd_buffer.buffer) { if (buffer != conn->net->cmd_buffer.buffer) {
mnd_efree(buffer); mnd_efree(buffer);
} }
@ -922,7 +922,7 @@ size_t php_mysqlnd_cmd_write(void * _packet, MYSQLND * conn TSRMLS_DC)
zend_uchar buffer[MYSQLND_HEADER_SIZE + 1]; zend_uchar buffer[MYSQLND_HEADER_SIZE + 1];
int1store(buffer + MYSQLND_HEADER_SIZE, packet->command); int1store(buffer + MYSQLND_HEADER_SIZE, packet->command);
sent = net->m.send_ex(net, buffer, 1, conn->stats, &conn->error_info TSRMLS_CC); sent = net->m.send_ex(net, buffer, 1, conn->stats, conn->error_info TSRMLS_CC);
} else { } else {
size_t tmp_len = packet->arg_len + 1 + MYSQLND_HEADER_SIZE; size_t tmp_len = packet->arg_len + 1 + MYSQLND_HEADER_SIZE;
zend_uchar *tmp, *p; zend_uchar *tmp, *p;
@ -937,7 +937,7 @@ size_t php_mysqlnd_cmd_write(void * _packet, MYSQLND * conn TSRMLS_DC)
memcpy(p, packet->argument, packet->arg_len); memcpy(p, packet->argument, packet->arg_len);
sent = net->m.send_ex(net, tmp, tmp_len - MYSQLND_HEADER_SIZE, conn->stats, &conn->error_info TSRMLS_CC); sent = net->m.send_ex(net, tmp, tmp_len - MYSQLND_HEADER_SIZE, conn->stats, conn->error_info TSRMLS_CC);
if (tmp != net->cmd_buffer.buffer) { if (tmp != net->cmd_buffer.buffer) {
MYSQLND_INC_CONN_STATISTIC(conn->stats, STAT_CMD_BUFFER_TOO_SMALL); MYSQLND_INC_CONN_STATISTIC(conn->stats, STAT_CMD_BUFFER_TOO_SMALL);
mnd_efree(tmp); mnd_efree(tmp);
@ -1020,7 +1020,7 @@ php_mysqlnd_rset_header_read(void * _packet, MYSQLND * conn TSRMLS_DC)
packet->info_or_local_file[len] = '\0'; packet->info_or_local_file[len] = '\0';
packet->info_or_local_file_len = len; packet->info_or_local_file_len = len;
} else { } else {
SET_OOM_ERROR(conn->error_info); SET_OOM_ERROR(*conn->error_info);
ret = FAIL; ret = FAIL;
} }
break; break;
@ -1047,7 +1047,7 @@ php_mysqlnd_rset_header_read(void * _packet, MYSQLND * conn TSRMLS_DC)
packet->info_or_local_file[len] = '\0'; packet->info_or_local_file[len] = '\0';
packet->info_or_local_file_len = len; packet->info_or_local_file_len = len;
} else { } else {
SET_OOM_ERROR(conn->error_info); SET_OOM_ERROR(*conn->error_info);
ret = FAIL; ret = FAIL;
} }
} }
@ -1220,7 +1220,7 @@ php_mysqlnd_rset_field_read(void * _packet, MYSQLND * conn TSRMLS_DC)
DBG_INF_FMT("Def found, length %lu, persistent=%u", len, packet->persistent_alloc); DBG_INF_FMT("Def found, length %lu, persistent=%u", len, packet->persistent_alloc);
meta->def = mnd_pemalloc(len + 1, packet->persistent_alloc); meta->def = mnd_pemalloc(len + 1, packet->persistent_alloc);
if (!meta->def) { if (!meta->def) {
SET_OOM_ERROR(conn->error_info); SET_OOM_ERROR(*conn->error_info);
DBG_RETURN(FAIL); DBG_RETURN(FAIL);
} }
memcpy(meta->def, p, len); memcpy(meta->def, p, len);
@ -1232,7 +1232,7 @@ php_mysqlnd_rset_field_read(void * _packet, MYSQLND * conn TSRMLS_DC)
DBG_INF_FMT("allocing root. persistent=%u", packet->persistent_alloc); DBG_INF_FMT("allocing root. persistent=%u", packet->persistent_alloc);
root_ptr = meta->root = mnd_pemalloc(total_len, packet->persistent_alloc); root_ptr = meta->root = mnd_pemalloc(total_len, packet->persistent_alloc);
if (!root_ptr) { if (!root_ptr) {
SET_OOM_ERROR(conn->error_info); SET_OOM_ERROR(*conn->error_info);
DBG_RETURN(FAIL); DBG_RETURN(FAIL);
} }
@ -1336,7 +1336,7 @@ php_mysqlnd_read_row_ex(MYSQLND * conn, MYSQLND_MEMORY_POOL * result_set_memory_
*data_size = prealloc_more_bytes; *data_size = prealloc_more_bytes;
while (1) { while (1) {
if (FAIL == mysqlnd_read_header(conn->net, &header, conn->stats, &conn->error_info TSRMLS_CC)) { if (FAIL == mysqlnd_read_header(conn->net, &header, conn->stats, conn->error_info TSRMLS_CC)) {
ret = FAIL; ret = FAIL;
break; break;
} }
@ -1368,7 +1368,7 @@ php_mysqlnd_read_row_ex(MYSQLND * conn, MYSQLND_MEMORY_POOL * result_set_memory_
to be able to implement read-only variables. to be able to implement read-only variables.
*/ */
if (FAIL == (*buffer)->resize_chunk((*buffer), *data_size + 1 TSRMLS_CC)) { if (FAIL == (*buffer)->resize_chunk((*buffer), *data_size + 1 TSRMLS_CC)) {
SET_OOM_ERROR(conn->error_info); SET_OOM_ERROR(*conn->error_info);
ret = FAIL; ret = FAIL;
break; break;
} }
@ -1376,7 +1376,7 @@ php_mysqlnd_read_row_ex(MYSQLND * conn, MYSQLND_MEMORY_POOL * result_set_memory_
p = (*buffer)->ptr + (*data_size - header.size); p = (*buffer)->ptr + (*data_size - header.size);
} }
if (PASS != (ret = conn->net->m.receive_ex(conn->net, p, header.size, conn->stats, &conn->error_info TSRMLS_CC))) { if (PASS != (ret = conn->net->m.receive_ex(conn->net, p, header.size, conn->stats, conn->error_info TSRMLS_CC))) {
DBG_ERR("Empty row packet body"); DBG_ERR("Empty row packet body");
php_error(E_WARNING, "Empty row packet body"); php_error(E_WARNING, "Empty row packet body");
break; break;

View file

@ -12,9 +12,9 @@
| obtain it through the world-wide-web, please send a note to | | obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. | | license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
| Authors: Georg Richter <georg@mysql.com> | | Authors: Andrey Hristov <andrey@mysql.com> |
| Andrey Hristov <andrey@mysql.com> |
| Ulf Wendel <uwendel@mysql.com> | | Ulf Wendel <uwendel@mysql.com> |
| Georg Richter <georg@mysql.com> |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
*/ */

View file

@ -12,9 +12,9 @@
| obtain it through the world-wide-web, please send a note to | | obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. | | license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
| Authors: Georg Richter <georg@mysql.com> | | Authors: Andrey Hristov <andrey@mysql.com> |
| Andrey Hristov <andrey@mysql.com> |
| Ulf Wendel <uwendel@mysql.com> | | Ulf Wendel <uwendel@mysql.com> |
| Georg Richter <georg@mysql.com> |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
*/ */

View file

@ -12,9 +12,9 @@
| obtain it through the world-wide-web, please send a note to | | obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. | | license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
| Authors: Georg Richter <georg@php.net> | | Authors: Andrey Hristov <andrey@mysql.com> |
| Andrey Hristov <andrey@php.net> | | Ulf Wendel <uwendel@mysql.com> |
| Ulf Wendel <uw@php.net> | | Georg Richter <georg@mysql.com> |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
$Id$ $Id$