- make MYSQLND_ERROR_INFO a class
This commit is contained in:
Andrey Hristov 2015-10-30 11:35:58 +01:00
parent fb1b5abe31
commit 4bb784cd0d
13 changed files with 396 additions and 349 deletions

View file

@ -76,6 +76,95 @@ void
mysqlnd_upsert_status_init(MYSQLND_UPSERT_STATUS * const upsert_status) mysqlnd_upsert_status_init(MYSQLND_UPSERT_STATUS * const upsert_status)
{ {
upsert_status->m = &MYSQLND_CLASS_METHOD_TABLE_NAME(mysqlnd_upsert_status); upsert_status->m = &MYSQLND_CLASS_METHOD_TABLE_NAME(mysqlnd_upsert_status);
upsert_status->m->reset(upsert_status);
}
/* }}} */
/* {{{ mysqlnd_error_list_pdtor */
static void
mysqlnd_error_list_pdtor(void * pDest)
{
MYSQLND_ERROR_LIST_ELEMENT * element = (MYSQLND_ERROR_LIST_ELEMENT *) pDest;
DBG_ENTER("mysqlnd_error_list_pdtor");
if (element->error) {
mnd_pefree(element->error, TRUE);
}
DBG_VOID_RETURN;
}
/* }}} */
/* {{{ mysqlnd_error_info::reset */
static void
MYSQLND_METHOD(mysqlnd_error_info, reset)(MYSQLND_ERROR_INFO * const info)
{
DBG_ENTER("mysqlnd_error_info::reset")
info->error_no = 0;
info->error[0] = '\0';
memset(info->sqlstate, 0, sizeof(info->sqlstate));
if (info->error_list) {
zend_llist_clean(info->error_list);
}
DBG_VOID_RETURN;
}
/* }}} */
/* {{{ mysqlnd_error_info::set_client_error */
static void
MYSQLND_METHOD(mysqlnd_error_info, set_client_error)(MYSQLND_ERROR_INFO * const info,
const unsigned int err_no,
const char * const sqlstate,
const char * const error)
{
DBG_ENTER("mysqlnd_error_info::set_client_error")
if (err_no) {
info->error_no = err_no;
strlcpy(info->sqlstate, sqlstate, sizeof(info->sqlstate));
strlcpy(info->error, error, sizeof(info->error));
if (info->error_list) {
MYSQLND_ERROR_LIST_ELEMENT error_for_the_list = {0};
error_for_the_list.error_no = err_no;
strlcpy(error_for_the_list.sqlstate, sqlstate, sizeof(error_for_the_list.sqlstate));
error_for_the_list.error = mnd_pestrdup(error, TRUE);
if (error_for_the_list.error) {
DBG_INF_FMT("adding error [%s] to the list", error_for_the_list.error);
zend_llist_add_element(info->error_list, &error_for_the_list);
}
}
} else {
info->m->reset(info);
}
DBG_VOID_RETURN;
}
/* }}} */
MYSQLND_CLASS_METHODS_START(mysqlnd_error_info)
MYSQLND_METHOD(mysqlnd_error_info, reset),
MYSQLND_METHOD(mysqlnd_error_info, set_client_error),
MYSQLND_CLASS_METHODS_END;
/* {{{ mysqlnd_upsert_status_init */
enum_func_status
mysqlnd_error_info_init(MYSQLND_ERROR_INFO * const info, zend_bool persistent)
{
DBG_ENTER("mysqlnd_error_info_init")
info->m = &MYSQLND_CLASS_METHOD_TABLE_NAME(mysqlnd_error_info);
info->m->reset(info);
info->error_list = mnd_pecalloc(1, sizeof(zend_llist), persistent);
if (info->error_list) {
zend_llist_init(info->error_list, sizeof(MYSQLND_ERROR_LIST_ELEMENT), (llist_dtor_func_t) mysqlnd_error_list_pdtor, persistent);
}
DBG_RETURN(info->error_list? PASS:FAIL);
} }
/* }}} */ /* }}} */
@ -242,10 +331,10 @@ MYSQLND_METHOD(mysqlnd_conn_data, send_command_handle_response)(
case PROT_OK_PACKET:{ case PROT_OK_PACKET:{
MYSQLND_PACKET_OK * ok_response = conn->payload_decoder_factory->m.get_ok_packet(conn->payload_decoder_factory, FALSE); MYSQLND_PACKET_OK * ok_response = conn->payload_decoder_factory->m.get_ok_packet(conn->payload_decoder_factory, FALSE);
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))) {
if (!silent) { if (!silent) {
DBG_ERR_FMT("Error while reading %s's OK packet", mysqlnd_command_to_text[command]); DBG_ERR_FMT("Error while reading %s's OK packet", mysqlnd_command_to_text[command]);
php_error_docref(NULL, E_WARNING, "Error while reading %s's OK packet. PID=%u", php_error_docref(NULL, E_WARNING, "Error while reading %s's OK packet. PID=%u",
@ -255,7 +344,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, send_command_handle_response)(
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
@ -288,11 +377,11 @@ MYSQLND_METHOD(mysqlnd_conn_data, send_command_handle_response)(
case PROT_EOF_PACKET:{ case PROT_EOF_PACKET:{
MYSQLND_PACKET_EOF * ok_response = conn->payload_decoder_factory->m.get_eof_packet(conn->payload_decoder_factory, FALSE); MYSQLND_PACKET_EOF * ok_response = conn->payload_decoder_factory->m.get_eof_packet(conn->payload_decoder_factory, FALSE);
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))) {
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]);
@ -301,10 +390,10 @@ MYSQLND_METHOD(mysqlnd_conn_data, send_command_handle_response)(
} }
} 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);
UPSERT_STATUS_SET_AFFECTED_ROWS_TO_ERROR(conn->upsert_status); UPSERT_STATUS_SET_AFFECTED_ROWS_TO_ERROR(conn->upsert_status);
} 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, E_WARNING, "EOF packet expected, field count wasn't 0xFE but 0x%2X", php_error_docref(NULL, E_WARNING, "EOF packet expected, field count wasn't 0xFE but 0x%2X",
@ -317,7 +406,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, send_command_handle_response)(
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, E_ERROR, "Wrong response packet %u passed to the function", ok_packet); php_error_docref(NULL, E_ERROR, "Wrong response packet %u passed to the function", ok_packet);
break; break;
} }
@ -327,69 +416,6 @@ MYSQLND_METHOD(mysqlnd_conn_data, send_command_handle_response)(
/* }}} */ /* }}} */
/* {{{ mysqlnd_conn_data::send_command_do_request */
static enum_func_status
MYSQLND_METHOD(mysqlnd_conn_data, send_command_do_request)(
MYSQLND_CONN_DATA * const conn,
const enum php_mysqlnd_server_command command,
const zend_uchar * const arg, const size_t arg_len,
const zend_bool silent,
const zend_bool ignore_upsert_status)
{
enum_func_status ret = PASS;
MYSQLND_PACKET_COMMAND * cmd_packet;
DBG_ENTER("mysqlnd_conn_data::send_command_do_request");
DBG_INF_FMT("command=%s silent=%u", mysqlnd_command_to_text[command], silent);
DBG_INF_FMT("conn->server_status=%u", conn->upsert_status->server_status);
DBG_INF_FMT("sending %u bytes", arg_len + 1); /* + 1 is for the command */
switch (CONN_GET_STATE(conn)) {
case CONN_READY:
break;
case CONN_QUIT_SENT:
SET_CLIENT_ERROR(*conn->error_info, CR_SERVER_GONE_ERROR, UNKNOWN_SQLSTATE, mysqlnd_server_gone);
DBG_ERR("Server is gone");
DBG_RETURN(FAIL);
default:
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_RETURN(FAIL);
}
UPSERT_STATUS_SET_AFFECTED_ROWS_TO_ERROR(conn->upsert_status);
SET_EMPTY_ERROR(*conn->error_info);
cmd_packet = conn->payload_decoder_factory->m.get_command_packet(conn->payload_decoder_factory, FALSE);
if (!cmd_packet) {
SET_OOM_ERROR(*conn->error_info);
DBG_RETURN(FAIL);
}
cmd_packet->command = command;
if (arg && arg_len) {
cmd_packet->argument = arg;
cmd_packet->arg_len = arg_len;
}
MYSQLND_INC_CONN_STATISTIC(conn->stats, STAT_COM_QUIT + command - 1 /* because of COM_SLEEP */ );
if (! PACKET_WRITE(cmd_packet, conn)) {
if (!silent) {
DBG_ERR_FMT("Error while sending %s packet", mysqlnd_command_to_text[command]);
php_error(E_WARNING, "Error while sending %s packet. PID=%d", mysqlnd_command_to_text[command], getpid());
}
CONN_SET_STATE(conn, CONN_QUIT_SENT);
conn->m->send_close(conn);
DBG_ERR("Server is gone");
ret = FAIL;
}
PACKET_FREE(cmd_packet);
DBG_RETURN(ret);
}
/* }}} */
/* {{{ mysqlnd_conn_data::set_server_option */ /* {{{ mysqlnd_conn_data::set_server_option */
static enum_func_status static enum_func_status
MYSQLND_METHOD(mysqlnd_conn_data, set_server_option)(MYSQLND_CONN_DATA * const conn, enum_mysqlnd_server_option option) MYSQLND_METHOD(mysqlnd_conn_data, set_server_option)(MYSQLND_CONN_DATA * const conn, enum_mysqlnd_server_option option)
@ -536,7 +562,7 @@ mysqlnd_run_authentication(
if (!auth_plugin) { if (!auth_plugin) {
php_error_docref(NULL, E_WARNING, "The server requested authentication method unknown to the client [%s]", requested_protocol); php_error_docref(NULL, 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 unknown to the client"); SET_CLIENT_ERROR(conn->error_info, CR_NOT_IMPLEMENTED, UNKNOWN_SQLSTATE, "The server requested authentication method unknown to the client");
goto end; goto end;
} }
DBG_INF("plugin found"); DBG_INF("plugin found");
@ -557,7 +583,7 @@ mysqlnd_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);
@ -741,7 +767,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, connect_handshake)(MYSQLND_CONN_DATA * conn,
greet_packet = conn->payload_decoder_factory->m.get_greet_packet(conn->payload_decoder_factory, FALSE); greet_packet = conn->payload_decoder_factory->m.get_greet_packet(conn->payload_decoder_factory, FALSE);
if (!greet_packet) { if (!greet_packet) {
SET_OOM_ERROR(*conn->error_info); SET_OOM_ERROR(conn->error_info);
DBG_RETURN(FAIL); /* OOM */ DBG_RETURN(FAIL); /* OOM */
} }
@ -753,19 +779,19 @@ MYSQLND_METHOD(mysqlnd_conn_data, connect_handshake)(MYSQLND_CONN_DATA * conn,
DBG_INF_FMT("stream=%p", net->data->m.get_stream(net)); DBG_INF_FMT("stream=%p", net->data->m.get_stream(net));
if (FAIL == PACKET_READ(greet_packet, conn)) { if (FAIL == PACKET_READ(greet_packet)) {
DBG_ERR("Error while reading greeting packet"); DBG_ERR("Error while reading greeting packet");
php_error_docref(NULL, E_WARNING, "Error while reading greeting packet. PID=%d", getpid()); php_error_docref(NULL, E_WARNING, "Error while reading greeting packet. PID=%d", getpid());
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, E_WARNING, "Connecting to 3.22, 3.23 & 4.0 " php_error_docref(NULL, 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;
} }
@ -778,7 +804,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, connect_handshake)(MYSQLND_CONN_DATA * conn,
if (!conn->greet_charset) { if (!conn->greet_charset) {
php_error_docref(NULL, E_WARNING, php_error_docref(NULL, E_WARNING,
"Server sent charset (%d) unknown to the client. Please, report to the developers", greet_packet->charset_no); "Server sent charset (%d) unknown to the client. Please, report to the developers", greet_packet->charset_no);
SET_CLIENT_ERROR(*conn->error_info, CR_NOT_IMPLEMENTED, UNKNOWN_SQLSTATE, SET_CLIENT_ERROR(conn->error_info, CR_NOT_IMPLEMENTED, UNKNOWN_SQLSTATE,
"Server sent charset unknown to the client. Please, report to the developers"); "Server sent charset unknown to the client. Please, report to the developers");
goto err; goto err;
} }
@ -834,7 +860,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, connect)(MYSQLND_CONN_DATA * conn,
} }
local_tx_started = TRUE; local_tx_started = TRUE;
SET_EMPTY_ERROR(*conn->error_info); SET_EMPTY_ERROR(conn->error_info);
UPSERT_STATUS_SET_AFFECTED_ROWS_TO_ERROR(conn->upsert_status); UPSERT_STATUS_SET_AFFECTED_ROWS_TO_ERROR(conn->upsert_status);
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",
@ -921,7 +947,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, connect)(MYSQLND_CONN_DATA * 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);
@ -962,14 +988,14 @@ MYSQLND_METHOD(mysqlnd_conn_data, connect)(MYSQLND_CONN_DATA * 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_pestrndup(host, host_len, conn->persistent); conn->host = mnd_pestrndup(host, host_len, 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 = host_len; conn->host_len = host_len;
@ -977,13 +1003,13 @@ MYSQLND_METHOD(mysqlnd_conn_data, connect)(MYSQLND_CONN_DATA * 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 */
} }
} }
@ -995,20 +1021,20 @@ MYSQLND_METHOD(mysqlnd_conn_data, connect)(MYSQLND_CONN_DATA * 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, E_WARNING, "Impossible. Should be either socket or a pipe. Report a bug!"); php_error_docref(NULL, 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);
@ -1016,7 +1042,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, connect)(MYSQLND_CONN_DATA * 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 */
SET_EMPTY_ERROR(*conn->error_info); SET_EMPTY_ERROR(conn->error_info);
mysqlnd_local_infile_default(conn); mysqlnd_local_infile_default(conn);
@ -1041,7 +1067,7 @@ err:
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, E_WARNING, "[%u] %.128s (trying to connect via %s)", php_error_docref(NULL, 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);
} }
@ -1455,7 +1481,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, list_fields)(MYSQLND_CONN_DATA * conn, const c
result->unbuf = mysqlnd_result_unbuffered_init(result->field_count, FALSE, result->persistent); result->unbuf = mysqlnd_result_unbuffered_init(result->field_count, FALSE, result->persistent);
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); result->m.free_result(result, TRUE);
result = NULL; result = NULL;
break; break;
@ -1510,9 +1536,9 @@ MYSQLND_METHOD(mysqlnd_conn_data, list_method)(MYSQLND_CONN_DATA * conn, const c
/* }}} */ /* }}} */
/* {{{ mysqlnd_conn_data::errno */ /* {{{ mysqlnd_conn_data::err_no */
static unsigned int static unsigned int
MYSQLND_METHOD(mysqlnd_conn_data, errno)(const MYSQLND_CONN_DATA * const conn) MYSQLND_METHOD(mysqlnd_conn_data, err_no)(const MYSQLND_CONN_DATA * const conn)
{ {
return conn->error_info->error_no; return conn->error_info->error_no;
} }
@ -1648,7 +1674,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, select_db)(MYSQLND_CONN_DATA * const conn, con
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;
} }
} }
@ -1713,11 +1739,11 @@ MYSQLND_METHOD(mysqlnd_conn_data, statistic)(MYSQLND_CONN_DATA * conn, zend_stri
} }
stats_header = conn->payload_decoder_factory->m.get_stats_packet(conn->payload_decoder_factory, FALSE); stats_header = conn->payload_decoder_factory->m.get_stats_packet(conn->payload_decoder_factory, FALSE);
if (!stats_header) { if (!stats_header) {
SET_OOM_ERROR(*conn->error_info); SET_OOM_ERROR(conn->error_info);
break; break;
} }
if (PASS == (ret = PACKET_READ(stats_header, conn))) { if (PASS == (ret = PACKET_READ(stats_header))) {
/* will be freed by Zend, thus don't use the mnd_ allocator */ /* will be freed by Zend, thus don't use the mnd_ allocator */
*message = zend_string_init(stats_header->message, stats_header->message_len, 0); *message = zend_string_init(stats_header->message, stats_header->message_len, 0);
DBG_INF(ZSTR_VAL(*message)); DBG_INF(ZSTR_VAL(*message));
@ -1780,7 +1806,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, set_charset)(MYSQLND_CONN_DATA * const conn, c
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);
} }
@ -2138,7 +2164,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, next_result)(MYSQLND_CONN_DATA * const conn)
break; break;
} }
SET_EMPTY_ERROR(*conn->error_info); SET_EMPTY_ERROR(conn->error_info);
UPSERT_STATUS_SET_AFFECTED_ROWS_TO_ERROR(conn->upsert_status); UPSERT_STATUS_SET_AFFECTED_ROWS_TO_ERROR(conn->upsert_status);
/* /*
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
@ -2245,7 +2271,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, change_user)(MYSQLND_CONN_DATA * const conn,
goto end; goto end;
} }
SET_EMPTY_ERROR(*conn->error_info); SET_EMPTY_ERROR(conn->error_info);
UPSERT_STATUS_SET_AFFECTED_ROWS_TO_ERROR(conn->upsert_status); UPSERT_STATUS_SET_AFFECTED_ROWS_TO_ERROR(conn->upsert_status);
if (!user) { if (!user) {
@ -2351,7 +2377,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, set_client_option)(MYSQLND_CONN_DATA * const c
{ {
char * new_charset_name; char * new_charset_name;
if (!mysqlnd_find_charset_name(value)) { if (!mysqlnd_find_charset_name(value)) {
SET_CLIENT_ERROR(*conn->error_info, CR_CANT_FIND_CHARSET, UNKNOWN_SQLSTATE, "Unknown character set"); SET_CLIENT_ERROR(conn->error_info, CR_CANT_FIND_CHARSET, UNKNOWN_SQLSTATE, "Unknown character set");
ret = FAIL; ret = FAIL;
break; break;
} }
@ -2437,7 +2463,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, set_client_option)(MYSQLND_CONN_DATA * const c
conn->m->local_tx_end(conn, this_func, ret); conn->m->local_tx_end(conn, this_func, ret);
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); conn->m->local_tx_end(conn, this_func, FAIL);
end: end:
DBG_RETURN(FAIL); DBG_RETURN(FAIL);
@ -2484,7 +2510,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, set_client_option_2d)(MYSQLND_CONN_DATA * cons
conn->m->local_tx_end(conn, this_func, ret); conn->m->local_tx_end(conn, this_func, ret);
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); conn->m->local_tx_end(conn, this_func, FAIL);
end: end:
DBG_RETURN(FAIL); DBG_RETURN(FAIL);
@ -2510,7 +2536,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, use_result)(MYSQLND_CONN_DATA * const conn, co
/* 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;
} }
@ -2553,7 +2579,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, store_result)(MYSQLND_CONN_DATA * const conn,
/* 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;
} }
@ -2573,7 +2599,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, store_result)(MYSQLND_CONN_DATA * const conn,
} }
} }
if (!(f & (MYSQLND_STORE_NO_COPY | MYSQLND_STORE_COPY))) { if (!(f & (MYSQLND_STORE_NO_COPY | MYSQLND_STORE_COPY))) {
SET_CLIENT_ERROR(*conn->error_info, CR_UNKNOWN_ERROR, UNKNOWN_SQLSTATE, "Unknown fetch mode"); SET_CLIENT_ERROR(conn->error_info, CR_UNKNOWN_ERROR, UNKNOWN_SQLSTATE, "Unknown fetch mode");
DBG_ERR("Unknown fetch mode"); DBG_ERR("Unknown fetch mode");
break; break;
} }
@ -2742,7 +2768,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, tx_commit_or_rollback)(MYSQLND_CONN_DATA * con
name_esc = NULL; name_esc = NULL;
} }
if (!query) { if (!query) {
SET_OOM_ERROR(*conn->error_info); SET_OOM_ERROR(conn->error_info);
break; break;
} }
@ -2805,7 +2831,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, tx_begin)(MYSQLND_CONN_DATA * conn, const unsi
name_esc = NULL; name_esc = NULL;
} }
if (!query) { if (!query) {
SET_OOM_ERROR(*conn->error_info); SET_OOM_ERROR(conn->error_info);
break; break;
} }
ret = conn->m->query(conn, query, query_len); ret = conn->m->query(conn, query, query_len);
@ -2833,12 +2859,12 @@ MYSQLND_METHOD(mysqlnd_conn_data, tx_savepoint)(MYSQLND_CONN_DATA * conn, const
char * query; char * query;
unsigned int query_len; unsigned int query_len;
if (!name) { if (!name) {
SET_CLIENT_ERROR(*conn->error_info, CR_UNKNOWN_ERROR, UNKNOWN_SQLSTATE, "Savepoint name not provided"); SET_CLIENT_ERROR(conn->error_info, CR_UNKNOWN_ERROR, UNKNOWN_SQLSTATE, "Savepoint name not provided");
break; break;
} }
query_len = mnd_sprintf(&query, 0, "SAVEPOINT `%s`", name); query_len = mnd_sprintf(&query, 0, "SAVEPOINT `%s`", name);
if (!query) { if (!query) {
SET_OOM_ERROR(*conn->error_info); SET_OOM_ERROR(conn->error_info);
break; break;
} }
ret = conn->m->query(conn, query, query_len); ret = conn->m->query(conn, query, query_len);
@ -2865,12 +2891,12 @@ MYSQLND_METHOD(mysqlnd_conn_data, tx_savepoint_release)(MYSQLND_CONN_DATA * conn
char * query; char * query;
unsigned int query_len; unsigned int query_len;
if (!name) { if (!name) {
SET_CLIENT_ERROR(*conn->error_info, CR_UNKNOWN_ERROR, UNKNOWN_SQLSTATE, "Savepoint name not provided"); SET_CLIENT_ERROR(conn->error_info, CR_UNKNOWN_ERROR, UNKNOWN_SQLSTATE, "Savepoint name not provided");
break; break;
} }
query_len = mnd_sprintf(&query, 0, "RELEASE SAVEPOINT `%s`", name); query_len = mnd_sprintf(&query, 0, "RELEASE SAVEPOINT `%s`", name);
if (!query) { if (!query) {
SET_OOM_ERROR(*conn->error_info); SET_OOM_ERROR(conn->error_info);
break; break;
} }
ret = conn->m->query(conn, query, query_len); ret = conn->m->query(conn, query, query_len);
@ -2967,7 +2993,7 @@ MYSQLND_CLASS_METHODS_START(mysqlnd_conn_data)
MYSQLND_METHOD(mysqlnd_conn_data, dump_debug_info), MYSQLND_METHOD(mysqlnd_conn_data, dump_debug_info),
MYSQLND_METHOD(mysqlnd_conn_data, change_user), MYSQLND_METHOD(mysqlnd_conn_data, change_user),
MYSQLND_METHOD(mysqlnd_conn_data, errno), MYSQLND_METHOD(mysqlnd_conn_data, err_no),
MYSQLND_METHOD(mysqlnd_conn_data, error), MYSQLND_METHOD(mysqlnd_conn_data, error),
MYSQLND_METHOD(mysqlnd_conn_data, sqlstate), MYSQLND_METHOD(mysqlnd_conn_data, sqlstate),
MYSQLND_METHOD(mysqlnd_conn_data, thread_id), MYSQLND_METHOD(mysqlnd_conn_data, thread_id),

View file

@ -60,23 +60,23 @@ mysqlnd_auth_handshake(MYSQLND_CONN_DATA * conn,
auth_resp_packet = conn->payload_decoder_factory->m.get_auth_response_packet(conn->payload_decoder_factory, FALSE); auth_resp_packet = conn->payload_decoder_factory->m.get_auth_response_packet(conn->payload_decoder_factory, FALSE);
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->payload_decoder_factory->m.get_change_auth_response_packet(conn->payload_decoder_factory, FALSE); change_auth_resp_packet = conn->payload_decoder_factory->m.get_change_auth_response_packet(conn->payload_decoder_factory, FALSE);
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;
} }
change_auth_resp_packet->auth_data = auth_plugin_data; change_auth_resp_packet->auth_data = auth_plugin_data;
change_auth_resp_packet->auth_data_len = auth_plugin_data_len; change_auth_resp_packet->auth_data_len = auth_plugin_data_len;
if (!PACKET_WRITE(change_auth_resp_packet, conn)) { if (!PACKET_WRITE(change_auth_resp_packet)) {
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 {
@ -103,7 +103,7 @@ mysqlnd_auth_handshake(MYSQLND_CONN_DATA * conn,
auth_packet->connect_attr = conn->options->connect_attr; auth_packet->connect_attr = conn->options->connect_attr;
} }
if (!PACKET_WRITE(auth_packet, conn)) { if (!PACKET_WRITE(auth_packet)) {
goto end; goto end;
} }
} }
@ -111,12 +111,12 @@ mysqlnd_auth_handshake(MYSQLND_CONN_DATA * conn,
conn->charset = mysqlnd_find_charset_nr(auth_packet->charset_no); conn->charset = mysqlnd_find_charset_nr(auth_packet->charset_no);
} }
if (FAIL == PACKET_READ(auth_resp_packet, conn) || auth_resp_packet->response_code >= 0xFE) { if (FAIL == PACKET_READ(auth_resp_packet) || auth_resp_packet->response_code >= 0xFE) {
if (auth_resp_packet->response_code == 0xFE) { if (auth_resp_packet->response_code == 0xFE) {
/* 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;
@ -134,7 +134,7 @@ mysqlnd_auth_handshake(MYSQLND_CONN_DATA * conn,
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;
} }
@ -181,30 +181,30 @@ mysqlnd_auth_change_user(MYSQLND_CONN_DATA * const conn,
chg_user_resp = conn->payload_decoder_factory->m.get_change_user_response_packet(conn->payload_decoder_factory, FALSE); chg_user_resp = conn->payload_decoder_factory->m.get_change_user_response_packet(conn->payload_decoder_factory, FALSE);
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->payload_decoder_factory->m.get_change_auth_response_packet(conn->payload_decoder_factory, FALSE); change_auth_resp_packet = conn->payload_decoder_factory->m.get_change_auth_response_packet(conn->payload_decoder_factory, FALSE);
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;
} }
change_auth_resp_packet->auth_data = auth_plugin_data; change_auth_resp_packet->auth_data = auth_plugin_data;
change_auth_resp_packet->auth_data_len = auth_plugin_data_len; change_auth_resp_packet->auth_data_len = auth_plugin_data_len;
if (!PACKET_WRITE(change_auth_resp_packet, conn)) { if (!PACKET_WRITE(change_auth_resp_packet)) {
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->payload_decoder_factory->m.get_auth_packet(conn->payload_decoder_factory, FALSE); auth_packet = conn->payload_decoder_factory->m.get_auth_packet(conn->payload_decoder_factory, FALSE);
if (!auth_packet) { if (!auth_packet) {
SET_OOM_ERROR(*conn->error_info); SET_OOM_ERROR(conn->error_info);
goto end; goto end;
} }
@ -223,21 +223,21 @@ mysqlnd_auth_change_user(MYSQLND_CONN_DATA * const conn,
auth_packet->charset_no = conn->charset->nr; auth_packet->charset_no = conn->charset->nr;
} }
if (!PACKET_WRITE(auth_packet, conn)) { if (!PACKET_WRITE(auth_packet)) {
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);
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;
@ -262,11 +262,11 @@ mysqlnd_auth_change_user(MYSQLND_CONN_DATA * const conn,
if (conn->m->get_server_version(conn) > 50113L &&conn->m->get_server_version(conn) < 50118L) { if (conn->m->get_server_version(conn) > 50113L &&conn->m->get_server_version(conn) < 50118L) {
MYSQLND_PACKET_OK * redundant_error_packet = conn->payload_decoder_factory->m.get_ok_packet(conn->payload_decoder_factory, FALSE); MYSQLND_PACKET_OK * redundant_error_packet = conn->payload_decoder_factory->m.get_ok_packet(conn->payload_decoder_factory, FALSE);
if (redundant_error_packet) { if (redundant_error_packet) {
PACKET_READ(redundant_error_packet, conn); PACKET_READ(redundant_error_packet);
PACKET_FREE(redundant_error_packet); PACKET_FREE(redundant_error_packet);
DBG_INF_FMT("Server is %u, buggy, sends two ERR messages", conn->m->get_server_version(conn)); DBG_INF_FMT("Server is %u, buggy, sends two ERR messages", conn->m->get_server_version(conn));
} else { } else {
SET_OOM_ERROR(*conn->error_info); SET_OOM_ERROR(conn->error_info);
} }
} }
} }
@ -297,7 +297,7 @@ mysqlnd_auth_change_user(MYSQLND_CONN_DATA * 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);
@ -371,7 +371,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);
} }
@ -501,23 +501,23 @@ mysqlnd_sha256_get_rsa_key(MYSQLND_CONN_DATA * conn,
DBG_INF("requesting the public key from the server"); DBG_INF("requesting the public key from the server");
pk_req_packet = conn->payload_decoder_factory->m.get_sha256_pk_request_packet(conn->payload_decoder_factory, FALSE); pk_req_packet = conn->payload_decoder_factory->m.get_sha256_pk_request_packet(conn->payload_decoder_factory, FALSE);
if (!pk_req_packet) { if (!pk_req_packet) {
SET_OOM_ERROR(*conn->error_info); SET_OOM_ERROR(conn->error_info);
break; break;
} }
pk_resp_packet = conn->payload_decoder_factory->m.get_sha256_pk_request_response_packet(conn->payload_decoder_factory, FALSE); pk_resp_packet = conn->payload_decoder_factory->m.get_sha256_pk_request_response_packet(conn->payload_decoder_factory, FALSE);
if (!pk_resp_packet) { if (!pk_resp_packet) {
SET_OOM_ERROR(*conn->error_info); SET_OOM_ERROR(conn->error_info);
PACKET_FREE(pk_req_packet); PACKET_FREE(pk_req_packet);
break; break;
} }
if (! PACKET_WRITE(pk_req_packet, conn)) { if (! PACKET_WRITE(pk_req_packet)) {
DBG_ERR_FMT("Error while sending public key request packet"); DBG_ERR_FMT("Error while sending public key request packet");
php_error(E_WARNING, "Error while sending public key request packet. PID=%d", getpid()); php_error(E_WARNING, "Error while sending public key request packet. PID=%d", getpid());
CONN_SET_STATE(conn, CONN_QUIT_SENT); CONN_SET_STATE(conn, CONN_QUIT_SENT);
break; break;
} }
if (FAIL == PACKET_READ(pk_resp_packet, conn) || NULL == pk_resp_packet->public_key) { if (FAIL == PACKET_READ(pk_resp_packet) || NULL == pk_resp_packet->public_key) {
DBG_ERR_FMT("Error while receiving public key"); DBG_ERR_FMT("Error while receiving public key");
php_error(E_WARNING, "Error while receiving public key. PID=%d", getpid()); php_error(E_WARNING, "Error while receiving public key. PID=%d", getpid());
CONN_SET_STATE(conn, CONN_QUIT_SENT); CONN_SET_STATE(conn, CONN_QUIT_SENT);
@ -537,7 +537,7 @@ mysqlnd_sha256_get_rsa_key(MYSQLND_CONN_DATA * conn,
DBG_INF_FMT("ret=%p", ret); DBG_INF_FMT("ret=%p", ret);
DBG_RETURN(ret); DBG_RETURN(ret);
SET_CLIENT_ERROR(*conn->error_info, CR_UNKNOWN_ERROR, UNKNOWN_SQLSTATE, SET_CLIENT_ERROR(conn->error_info, CR_UNKNOWN_ERROR, UNKNOWN_SQLSTATE,
"sha256_server_public_key is not set for the connection or as mysqlnd.sha256_server_public_key"); "sha256_server_public_key is not set for the connection or as mysqlnd.sha256_server_public_key");
DBG_ERR("server_public_key is not set"); DBG_ERR("server_public_key is not set");
DBG_RETURN(NULL); DBG_RETURN(NULL);
@ -605,7 +605,7 @@ mysqlnd_sha256_auth_get_auth_data(struct st_mysqlnd_authentication_plugin * self
*/ */
if ((size_t) server_public_key_len - 41 <= passwd_len) { if ((size_t) server_public_key_len - 41 <= passwd_len) {
/* password message is to long */ /* password message is to long */
SET_CLIENT_ERROR(*conn->error_info, CR_UNKNOWN_ERROR, UNKNOWN_SQLSTATE, "password is too long"); SET_CLIENT_ERROR(conn->error_info, CR_UNKNOWN_ERROR, UNKNOWN_SQLSTATE, "password is too long");
DBG_ERR("password is too long"); DBG_ERR("password is too long");
DBG_RETURN(NULL); DBG_RETURN(NULL);
} }

View file

@ -93,22 +93,6 @@ PHPAPI void mysqlnd_library_init(void)
/* }}} */ /* }}} */
/* {{{ mysqlnd_error_list_pdtor */
static void
mysqlnd_error_list_pdtor(void * pDest)
{
MYSQLND_ERROR_LIST_ELEMENT * element = (MYSQLND_ERROR_LIST_ELEMENT *) pDest;
DBG_ENTER("mysqlnd_error_list_pdtor");
if (element->error) {
mnd_pefree(element->error, TRUE);
}
DBG_VOID_RETURN;
}
/* }}} */
/* {{{ mysqlnd_object_factory::get_connection */ /* {{{ mysqlnd_object_factory::get_connection */
static MYSQLND * static MYSQLND *
MYSQLND_METHOD(mysqlnd_object_factory, get_connection)(struct st_mysqlnd_object_factory_methods * factory, zend_bool persistent) MYSQLND_METHOD(mysqlnd_object_factory, get_connection)(struct st_mysqlnd_object_factory_methods * factory, zend_bool persistent)
@ -133,7 +117,12 @@ MYSQLND_METHOD(mysqlnd_object_factory, get_connection)(struct st_mysqlnd_object_
new_object->m = mysqlnd_conn_get_methods(); new_object->m = mysqlnd_conn_get_methods();
data = new_object->data; data = new_object->data;
data->error_info = &(data->error_info_impl); if (FAIL == mysqlnd_error_info_init(&data->error_info_impl, persistent)) {
new_object->m->dtor(new_object);
DBG_RETURN(NULL);
}
data->error_info = &data->error_info_impl;
data->options = &(data->options_impl); data->options = &(data->options_impl);
mysqlnd_upsert_status_init(&data->upsert_status_impl); mysqlnd_upsert_status_init(&data->upsert_status_impl);
@ -146,13 +135,6 @@ MYSQLND_METHOD(mysqlnd_object_factory, get_connection)(struct st_mysqlnd_object_
CONN_SET_STATE(data, CONN_ALLOCED); CONN_SET_STATE(data, CONN_ALLOCED);
data->m->get_reference(data); data->m->get_reference(data);
data->error_info->error_list = mnd_pecalloc(1, sizeof(zend_llist), persistent);
if (!data->error_info->error_list) {
new_object->m->dtor(new_object);
DBG_RETURN(NULL);
}
zend_llist_init(data->error_info->error_list, sizeof(MYSQLND_ERROR_LIST_ELEMENT), (llist_dtor_func_t)mysqlnd_error_list_pdtor, persistent);
mysqlnd_stats_init(&data->stats, STAT_LAST, persistent); mysqlnd_stats_init(&data->stats, STAT_LAST, persistent);
data->net = mysqlnd_net_init(persistent, data->stats, data->error_info); data->net = mysqlnd_net_init(persistent, data->stats, data->error_info);
@ -220,7 +202,12 @@ MYSQLND_METHOD(mysqlnd_object_factory, get_prepared_statement)(MYSQLND_CONN_DATA
break; break;
} }
stmt->persistent = persistent; stmt->persistent = persistent;
stmt->error_info = &(stmt->error_info_impl);
if (FAIL == mysqlnd_error_info_init(&stmt->error_info_impl, persistent)) {
break;
}
stmt->error_info = &stmt->error_info_impl;
mysqlnd_upsert_status_init(&stmt->upsert_status_impl); mysqlnd_upsert_status_init(&stmt->upsert_status_impl);
stmt->upsert_status = &(stmt->upsert_status_impl); stmt->upsert_status = &(stmt->upsert_status_impl);
stmt->state = MYSQLND_STMT_INITTED; stmt->state = MYSQLND_STMT_INITTED;
@ -231,12 +218,6 @@ MYSQLND_METHOD(mysqlnd_object_factory, get_prepared_statement)(MYSQLND_CONN_DATA
} }
stmt->prefetch_rows = MYSQLND_DEFAULT_PREFETCH_ROWS; stmt->prefetch_rows = MYSQLND_DEFAULT_PREFETCH_ROWS;
stmt->error_info->error_list = mnd_pecalloc(1, sizeof(zend_llist), ret->persistent);
if (!stmt->error_info->error_list) {
break;
}
zend_llist_init(stmt->error_info->error_list, sizeof(MYSQLND_ERROR_LIST_ELEMENT), (llist_dtor_func_t) mysqlnd_error_list_pdtor, persistent);
/* /*
Mark that we reference the connection, thus it won't be Mark that we reference the connection, thus it won't be
@ -248,7 +229,7 @@ MYSQLND_METHOD(mysqlnd_object_factory, get_prepared_statement)(MYSQLND_CONN_DATA
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); ret->m->dtor(ret, TRUE);
ret = NULL; ret = NULL;

View file

@ -176,7 +176,7 @@ mysqlnd_handle_local_infile(MYSQLND_CONN_DATA * conn, const char * filename, zen
*is_warning = TRUE; *is_warning = TRUE;
/* error occurred */ /* error occurred */
tmp_error_no = infile.local_infile_error(info, tmp_buf, sizeof(tmp_buf)); tmp_error_no = infile.local_infile_error(info, tmp_buf, sizeof(tmp_buf));
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->data->m.send_ex(net, empty_packet, 0, conn->stats, conn->error_info); ret = net->data->m.send_ex(net, empty_packet, 0, conn->stats, conn->error_info);
goto infile_error; goto infile_error;
@ -186,14 +186,14 @@ mysqlnd_handle_local_infile(MYSQLND_CONN_DATA * conn, const char * filename, zen
while ((bufsize = infile.local_infile_read (info, buf + MYSQLND_HEADER_SIZE, buflen - MYSQLND_HEADER_SIZE)) > 0) { while ((bufsize = infile.local_infile_read (info, buf + MYSQLND_HEADER_SIZE, buflen - MYSQLND_HEADER_SIZE)) > 0) {
if ((ret = net->data->m.send_ex(net, buf, bufsize, conn->stats, conn->error_info)) == 0) { if ((ret = net->data->m.send_ex(net, buf, bufsize, conn->stats, conn->error_info)) == 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->data->m.send_ex(net, empty_packet, 0, conn->stats, conn->error_info)) == 0) { if ((ret = net->data->m.send_ex(net, empty_packet, 0, conn->stats, conn->error_info)) == 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;
} }
@ -204,7 +204,7 @@ mysqlnd_handle_local_infile(MYSQLND_CONN_DATA * conn, const char * filename, zen
*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)); tmp_error_no = infile.local_infile_error(info, tmp_buf, sizeof(tmp_buf));
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

@ -148,7 +148,7 @@ MYSQLND_METHOD(mysqlnd_net, open_pipe)(MYSQLND_NET * const net, const char * con
streams_options |= IGNORE_URL; streams_options |= IGNORE_URL;
net_stream = php_stream_open_wrapper((char*) scheme + sizeof("pipe://") - 1, "r+", streams_options, NULL); net_stream = php_stream_open_wrapper((char*) scheme + sizeof("pipe://") - 1, "r+", streams_options, NULL);
if (!net_stream) { if (!net_stream) {
SET_CLIENT_ERROR(*error_info, CR_CONNECTION_ERROR, UNKNOWN_SQLSTATE, "Unknown errror while connecting"); SET_CLIENT_ERROR(error_info, CR_CONNECTION_ERROR, UNKNOWN_SQLSTATE, "Unknown errror while connecting");
DBG_RETURN(NULL); DBG_RETURN(NULL);
} }
/* /*
@ -211,7 +211,7 @@ MYSQLND_METHOD(mysqlnd_net, open_tcp_or_unix)(MYSQLND_NET * const net, const cha
mnd_sprintf_free(hashed_details); mnd_sprintf_free(hashed_details);
} }
errcode = CR_CONNECTION_ERROR; errcode = CR_CONNECTION_ERROR;
SET_CLIENT_ERROR(*error_info, SET_CLIENT_ERROR(error_info,
CR_CONNECTION_ERROR, CR_CONNECTION_ERROR,
UNKNOWN_SQLSTATE, UNKNOWN_SQLSTATE,
errstr? ZSTR_VAL(errstr):"Unknown error while connecting"); errstr? ZSTR_VAL(errstr):"Unknown error while connecting");
@ -310,7 +310,7 @@ MYSQLND_METHOD(mysqlnd_net, get_open_stream)(MYSQLND_NET * const net, const char
} }
if (!ret) { if (!ret) {
SET_CLIENT_ERROR(*error_info, CR_CONNECTION_ERROR, UNKNOWN_SQLSTATE, "No handler for this scheme"); SET_CLIENT_ERROR(error_info, CR_CONNECTION_ERROR, UNKNOWN_SQLSTATE, "No handler for this scheme");
} }
DBG_RETURN(ret); DBG_RETURN(ret);
@ -484,7 +484,7 @@ MYSQLND_METHOD(mysqlnd_net, send_ex)(MYSQLND_NET * const net, zend_uchar * const
/* Even for zero size payload we have to send a packet */ /* Even for zero size payload we have to send a packet */
if (!bytes_sent) { if (!bytes_sent) {
DBG_ERR_FMT("Can't %u send bytes", count); DBG_ERR_FMT("Can't %u send bytes", count);
SET_CLIENT_ERROR(*error_info, CR_SERVER_GONE_ERROR, UNKNOWN_SQLSTATE, mysqlnd_server_gone); SET_CLIENT_ERROR(error_info, CR_SERVER_GONE_ERROR, UNKNOWN_SQLSTATE, mysqlnd_server_gone);
} }
DBG_RETURN(bytes_sent); DBG_RETURN(bytes_sent);
} }

View file

@ -104,7 +104,19 @@ void mysqlnd_upsert_status_init(MYSQLND_UPSERT_STATUS * const upsert_status);
(buf_len) = 0; \ (buf_len) = 0; \
} }
enum_func_status mysqlnd_error_info_init(MYSQLND_ERROR_INFO * const info, zend_bool persistent);
#define SET_OOM_ERROR(info) SET_CLIENT_ERROR((info), CR_OUT_OF_MEMORY, UNKNOWN_SQLSTATE, mysqlnd_out_of_memory)
#define SET_EMPTY_ERROR(info) (info)->m->reset((info))
#define SET_CLIENT_ERROR(info, err_no, sqlstate, error) (info)->m->set_client_error((info), (err_no), (sqlstate), (error))
#define COPY_CLIENT_ERROR(error_info_to, error_info_from) \
{ \
SET_CLIENT_ERROR((error_info_to), (error_info_from).error_no, (error_info_from).sqlstate, (error_info_from).error); \
}
#if 0
#define SET_EMPTY_ERROR(error_info) \ #define SET_EMPTY_ERROR(error_info) \
{ \ { \
(error_info).error_no = 0; \ (error_info).error_no = 0; \
@ -115,7 +127,6 @@ void mysqlnd_upsert_status_init(MYSQLND_UPSERT_STATUS * const upsert_status);
} \ } \
} }
#define SET_CLIENT_ERROR(error_info, a, b, c) \ #define SET_CLIENT_ERROR(error_info, a, b, c) \
{ \ { \
if (0 == (a)) { \ if (0 == (a)) { \
@ -137,18 +148,10 @@ void mysqlnd_upsert_status_init(MYSQLND_UPSERT_STATUS * const upsert_status);
} \ } \
} \ } \
} }
#endif
#define COPY_CLIENT_ERROR(error_info_to, error_info_from) \ #define SET_STMT_ERROR(stmt, a, b, c) SET_CLIENT_ERROR((stmt)->error_info, a, b, c)
{ \
SET_CLIENT_ERROR((error_info_to), (error_info_from).error_no, (error_info_from).sqlstate, (error_info_from).error); \
}
#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 CONN_GET_STATE(c) (c)->m->get_state((c)) #define CONN_GET_STATE(c) (c)->m->get_state((c))
#define CONN_SET_STATE(c, s) (c)->m->set_state((c), (s)) #define CONN_SET_STATE(c, s) (c)->m->set_state((c), (s))

View file

@ -74,15 +74,15 @@ MYSQLND_METHOD(mysqlnd_stmt, store_result)(MYSQLND_STMT * const s)
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(*conn->error_info); SET_EMPTY_ERROR(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;
@ -91,7 +91,7 @@ MYSQLND_METHOD(mysqlnd_stmt, store_result)(MYSQLND_STMT * const s)
result->stored_data = (MYSQLND_RES_BUFFERED *) mysqlnd_result_buffered_zval_init(result->field_count, TRUE, result->persistent); result->stored_data = (MYSQLND_RES_BUFFERED *) mysqlnd_result_buffered_zval_init(result->field_count, TRUE, result->persistent);
if (!result->stored_data) { if (!result->stored_data) {
SET_OOM_ERROR(*conn->error_info); SET_OOM_ERROR(conn->error_info);
DBG_RETURN(NULL); DBG_RETURN(NULL);
} }
@ -106,13 +106,13 @@ MYSQLND_METHOD(mysqlnd_stmt, store_result)(MYSQLND_STMT * const s)
if (result->stored_data->row_count) { if (result->stored_data->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 (result->stored_data->row_count * result->meta->field_count * sizeof(zval *) > SIZE_MAX) { if (result->stored_data->row_count * result->meta->field_count * sizeof(zval *) > SIZE_MAX) {
SET_OOM_ERROR(*conn->error_info); SET_OOM_ERROR(conn->error_info);
DBG_RETURN(NULL); DBG_RETURN(NULL);
} }
/* 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)(result->stored_data->row_count * result->meta->field_count * sizeof(zval))); set->data = mnd_emalloc((size_t)(result->stored_data->row_count * result->meta->field_count * sizeof(zval)));
if (!set->data) { if (!set->data) {
SET_OOM_ERROR(*conn->error_info); SET_OOM_ERROR(conn->error_info);
DBG_RETURN(NULL); DBG_RETURN(NULL);
} }
memset(set->data, 0, (size_t)(result->stored_data->row_count * result->meta->field_count * sizeof(zval))); memset(set->data, 0, (size_t)(result->stored_data->row_count * result->meta->field_count * sizeof(zval)));
@ -128,7 +128,7 @@ MYSQLND_METHOD(mysqlnd_stmt, store_result)(MYSQLND_STMT * const s)
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); stmt->result->m.free_result_contents(stmt->result);
mnd_efree(stmt->result); mnd_efree(stmt->result);
stmt->result = NULL; stmt->result = NULL;
@ -168,25 +168,25 @@ MYSQLND_METHOD(mysqlnd_stmt, get_result)(MYSQLND_STMT * const s)
/* 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(*conn->error_info); SET_EMPTY_ERROR(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); result = conn->m->result_init(stmt->result->field_count, stmt->persistent);
if (!result) { if (!result) {
SET_OOM_ERROR(*conn->error_info); SET_OOM_ERROR(conn->error_info);
break; break;
} }
result->meta = stmt->result->meta->m->clone_metadata(stmt->result->meta, FALSE); result->meta = stmt->result->meta->m->clone_metadata(stmt->result->meta, FALSE);
if (!result->meta) { if (!result->meta) {
SET_OOM_ERROR(*conn->error_info); SET_OOM_ERROR(conn->error_info);
break; break;
} }
@ -195,7 +195,7 @@ MYSQLND_METHOD(mysqlnd_stmt, get_result)(MYSQLND_STMT * const s)
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;
} }
@ -272,13 +272,13 @@ mysqlnd_stmt_skip_metadata(MYSQLND_STMT * s)
field_packet = stmt->conn->payload_decoder_factory->m.get_result_field_packet(stmt->conn->payload_decoder_factory, FALSE); field_packet = stmt->conn->payload_decoder_factory->m.get_result_field_packet(stmt->conn->payload_decoder_factory, FALSE);
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;
for (;i < stmt->param_count; i++) { for (;i < stmt->param_count; i++) {
if (FAIL == PACKET_READ(field_packet, stmt->conn)) { if (FAIL == PACKET_READ(field_packet)) {
ret = FAIL; ret = FAIL;
break; break;
} }
@ -307,18 +307,18 @@ mysqlnd_stmt_read_prepare_response(MYSQLND_STMT * s)
prepare_resp = stmt->conn->payload_decoder_factory->m.get_prepare_response_packet(stmt->conn->payload_decoder_factory, FALSE); prepare_resp = stmt->conn->payload_decoder_factory->m.get_prepare_response_packet(stmt->conn->payload_decoder_factory, FALSE);
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;
} }
if (FAIL == PACKET_READ(prepare_resp, stmt->conn)) { if (FAIL == PACKET_READ(prepare_resp)) {
goto done; goto done;
} }
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;
@ -351,10 +351,10 @@ mysqlnd_stmt_prepare_read_eof(MYSQLND_STMT * s)
fields_eof = stmt->conn->payload_decoder_factory->m.get_eof_packet(stmt->conn->payload_decoder_factory, FALSE); fields_eof = stmt->conn->payload_decoder_factory->m.get_eof_packet(stmt->conn->payload_decoder_factory, FALSE);
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))) {
if (stmt->result) { if (stmt->result) {
stmt->result->m.free_result_contents(stmt->result); stmt->result->m.free_result_contents(stmt->result);
mnd_efree(stmt->result); mnd_efree(stmt->result);
@ -397,8 +397,8 @@ MYSQLND_METHOD(mysqlnd_stmt, prepare)(MYSQLND_STMT * const s, const char * const
UPSERT_STATUS_SET_AFFECTED_ROWS_TO_ERROR(stmt->upsert_status); UPSERT_STATUS_SET_AFFECTED_ROWS_TO_ERROR(stmt->upsert_status);
UPSERT_STATUS_SET_AFFECTED_ROWS_TO_ERROR(stmt->conn->upsert_status); UPSERT_STATUS_SET_AFFECTED_ROWS_TO_ERROR(stmt->conn->upsert_status);
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 */
@ -455,7 +455,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); MYSQLND_RES * result = stmt->conn->m->result_init(stmt_to_prepare->field_count, stmt_to_prepare->persistent);
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 */
@ -520,7 +520,7 @@ mysqlnd_stmt_execute_parse_response(MYSQLND_STMT * const s, enum_mysqlnd_parse_e
ret = stmt->conn->m->query_read_result_set_header(stmt->conn, s); ret = stmt->conn->m->query_read_result_set_header(stmt->conn, s);
if (ret == FAIL) { if (ret == FAIL) {
COPY_CLIENT_ERROR(*stmt->error_info, *conn->error_info); COPY_CLIENT_ERROR(stmt->error_info, *conn->error_info);
UPSERT_STATUS_RESET(stmt->upsert_status); UPSERT_STATUS_RESET(stmt->upsert_status);
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) {
@ -536,8 +536,8 @@ mysqlnd_stmt_execute_parse_response(MYSQLND_STMT * const s, enum_mysqlnd_parse_e
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; /* copy 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) {
@ -704,7 +704,7 @@ MYSQLND_METHOD(mysqlnd_stmt, send_execute)(MYSQLND_STMT * const s, enum_mysqlnd_
stmt->state = MYSQLND_STMT_PREPARED; stmt->state = MYSQLND_STMT_PREPARED;
} 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");
@ -754,7 +754,7 @@ MYSQLND_METHOD(mysqlnd_stmt, send_execute)(MYSQLND_STMT * const s, enum_mysqlnd_
} }
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);
} }
@ -886,7 +886,7 @@ mysqlnd_stmt_fetch_row_unbuffered(MYSQLND_RES * result, void * param, unsigned i
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);
@ -902,7 +902,7 @@ mysqlnd_stmt_fetch_row_unbuffered(MYSQLND_RES * result, void * param, unsigned i
If we skip rows (stmt == NULL || stmt->result_bind == NULL) we have to If we skip rows (stmt == NULL || stmt->result_bind == NULL) we have to
result->unbuf->m.free_last_data() before it. The function returns always true. result->unbuf->m.free_last_data() before it. The function returns always true.
*/ */
if (PASS == (ret = PACKET_READ(row_packet, result->conn)) && !row_packet->eof) { if (PASS == (ret = PACKET_READ(row_packet)) && !row_packet->eof) {
unsigned int i, field_count = result->field_count; unsigned int i, field_count = result->field_count;
if (!row_packet->skip_extraction) { if (!row_packet->skip_extraction) {
@ -966,8 +966,8 @@ mysqlnd_stmt_fetch_row_unbuffered(MYSQLND_RES * result, void * param, unsigned i
*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 */
@ -1016,13 +1016,13 @@ MYSQLND_METHOD(mysqlnd_stmt, use_result)(MYSQLND_STMT * s)
(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;
@ -1059,7 +1059,7 @@ mysqlnd_fetch_stmt_row_cursor(MYSQLND_RES * result, void * param, unsigned int f
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);
@ -1068,8 +1068,8 @@ mysqlnd_fetch_stmt_row_cursor(MYSQLND_RES * result, void * param, unsigned int f
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 + MYSQLND_STMT_ID_LENGTH, 1); /* for now fetch only one row */ int4store(buf + MYSQLND_STMT_ID_LENGTH, 1); /* for now fetch only one row */
@ -1082,7 +1082,7 @@ mysqlnd_fetch_stmt_row_cursor(MYSQLND_RES * result, void * param, unsigned int f
ret = command->run(command); ret = command->run(command);
command->free_command(command); command->free_command(command);
if (ret == FAIL) { if (ret == FAIL) {
COPY_CLIENT_ERROR(*stmt->error_info, *stmt->conn->error_info); COPY_CLIENT_ERROR(stmt->error_info, *stmt->conn->error_info);
} }
} }
if (FAIL == ret) { if (FAIL == ret) {
@ -1094,7 +1094,7 @@ mysqlnd_fetch_stmt_row_cursor(MYSQLND_RES * result, void * param, unsigned int f
if (FAIL == stmt->conn->m->send_command(stmt->conn, COM_STMT_FETCH, buf, sizeof(buf), if (FAIL == stmt->conn->m->send_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)) { FALSE, TRUE)) {
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);
} }
#endif #endif
@ -1102,7 +1102,7 @@ mysqlnd_fetch_stmt_row_cursor(MYSQLND_RES * result, void * param, unsigned int f
row_packet->skip_extraction = stmt->result_bind? FALSE:TRUE; row_packet->skip_extraction = stmt->result_bind? FALSE:TRUE;
UPSERT_STATUS_RESET(stmt->upsert_status); UPSERT_STATUS_RESET(stmt->upsert_status);
if (PASS == (ret = PACKET_READ(row_packet, result->conn)) && !row_packet->eof) { if (PASS == (ret = PACKET_READ(row_packet)) && !row_packet->eof) {
const MYSQLND_RES_METADATA * const meta = result->meta; const MYSQLND_RES_METADATA * const meta = result->meta;
unsigned int i, field_count = result->field_count; unsigned int i, field_count = result->field_count;
@ -1165,7 +1165,7 @@ mysqlnd_fetch_stmt_row_cursor(MYSQLND_RES * result, void * param, unsigned int f
row_packet->row_buffer = NULL; row_packet->row_buffer = NULL;
} }
/* We asked for one row, the next one should be EOF, eat it */ /* We asked for one row, the next one should be EOF, eat it */
ret = PACKET_READ(row_packet, result->conn); ret = PACKET_READ(row_packet);
if (row_packet->row_buffer) { if (row_packet->row_buffer) {
row_packet->row_buffer->free_chunk(row_packet->row_buffer); row_packet->row_buffer->free_chunk(row_packet->row_buffer);
row_packet->row_buffer = NULL; row_packet->row_buffer = NULL;
@ -1228,8 +1228,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);
/* /*
@ -1272,8 +1272,8 @@ MYSQLND_METHOD(mysqlnd_stmt, reset)(MYSQLND_STMT * const s)
} }
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_DATA * conn = stmt->conn; MYSQLND_CONN_DATA * conn = stmt->conn;
@ -1307,7 +1307,7 @@ MYSQLND_METHOD(mysqlnd_stmt, reset)(MYSQLND_STMT * const s)
if (ret == PASS) { if (ret == PASS) {
ret = conn->m->send_command_handle_response(conn, PROT_OK_PACKET, FALSE, COM_STMT_RESET, TRUE); ret = conn->m->send_command_handle_response(conn, PROT_OK_PACKET, FALSE, COM_STMT_RESET, TRUE);
} else { } else {
COPY_CLIENT_ERROR(*stmt->error_info, *conn->error_info); COPY_CLIENT_ERROR(stmt->error_info, *conn->error_info);
} }
} }
} }
@ -1375,8 +1375,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);
@ -1428,7 +1428,7 @@ MYSQLND_METHOD(mysqlnd_stmt, send_long_data)(MYSQLND_STMT * const s, unsigned in
ret = command->run(command); ret = command->run(command);
command->free_command(command); command->free_command(command);
if (ret == FAIL) { if (ret == FAIL) {
COPY_CLIENT_ERROR(*stmt->error_info, *conn->error_info); COPY_CLIENT_ERROR(stmt->error_info, *conn->error_info);
} }
} }
} }
@ -1436,8 +1436,8 @@ MYSQLND_METHOD(mysqlnd_stmt, send_long_data)(MYSQLND_STMT * const s, unsigned in
mnd_efree(cmd_buf); mnd_efree(cmd_buf);
} 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
@ -1497,8 +1497,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;
@ -1568,8 +1568,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) {
@ -1617,8 +1617,8 @@ MYSQLND_METHOD(mysqlnd_stmt, refresh_bind_param)(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->param_count) { if (stmt->param_count) {
stmt->send_types_to_server = 1; stmt->send_types_to_server = 1;
@ -1649,8 +1649,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;
@ -1708,8 +1708,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); mysqlnd_stmt_separate_one_result_bind(s, param_no);
@ -1911,7 +1911,7 @@ MYSQLND_METHOD(mysqlnd_stmt, result_metadata)(MYSQLND_STMT * const s)
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); result->m.free_result(result, TRUE);
} }
@ -2217,8 +2217,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()
@ -2255,7 +2255,7 @@ MYSQLND_METHOD_PRIVATE(mysqlnd_stmt, net_close)(MYSQLND_STMT * const s, zend_boo
command->free_command(command); command->free_command(command);
if (ret == FAIL) { if (ret == FAIL) {
COPY_CLIENT_ERROR(*stmt->error_info, *conn->error_info); COPY_CLIENT_ERROR(stmt->error_info, *conn->error_info);
} }
} }
if (ret == FAIL) { if (ret == FAIL) {

View file

@ -587,7 +587,7 @@ mysqlnd_stmt_execute_prepare_param_types(MYSQLND_STMT_DATA * stmt, zval ** copie
if (Z_TYPE_P(parameter) != IS_LONG && if (Z_TYPE_P(parameter) != IS_LONG &&
PASS != mysqlnd_stmt_copy_it(copies_param, parameter, stmt->param_count, i)) PASS != mysqlnd_stmt_copy_it(copies_param, parameter, stmt->param_count, i))
{ {
SET_OOM_ERROR(*stmt->error_info); SET_OOM_ERROR(stmt->error_info);
goto end; goto end;
} }
/* /*
@ -695,7 +695,7 @@ mysqlnd_stmt_execute_calculate_param_values_size(MYSQLND_STMT_DATA * stmt, zval
/* Double binding of the same zval, make a copy */ /* Double binding of the same zval, make a copy */
if (!*copies_param || Z_ISUNDEF((*copies_param)[i])) { if (!*copies_param || Z_ISUNDEF((*copies_param)[i])) {
if (PASS != mysqlnd_stmt_copy_it(copies_param, the_var, stmt->param_count, i)) { if (PASS != mysqlnd_stmt_copy_it(copies_param, the_var, stmt->param_count, i)) {
SET_OOM_ERROR(*stmt->error_info); SET_OOM_ERROR(stmt->error_info);
goto end; goto end;
} }
} }
@ -710,7 +710,7 @@ mysqlnd_stmt_execute_calculate_param_values_size(MYSQLND_STMT_DATA * stmt, zval
if (Z_TYPE_P(the_var) != IS_DOUBLE) { if (Z_TYPE_P(the_var) != IS_DOUBLE) {
if (!*copies_param || Z_ISUNDEF((*copies_param)[i])) { if (!*copies_param || Z_ISUNDEF((*copies_param)[i])) {
if (PASS != mysqlnd_stmt_copy_it(copies_param, the_var, stmt->param_count, i)) { if (PASS != mysqlnd_stmt_copy_it(copies_param, the_var, stmt->param_count, i)) {
SET_OOM_ERROR(*stmt->error_info); SET_OOM_ERROR(stmt->error_info);
goto end; goto end;
} }
} }
@ -745,7 +745,7 @@ use_string:
if (Z_TYPE_P(the_var) != IS_STRING) { if (Z_TYPE_P(the_var) != IS_STRING) {
if (!*copies_param || Z_ISUNDEF((*copies_param)[i])) { if (!*copies_param || Z_ISUNDEF((*copies_param)[i])) {
if (PASS != mysqlnd_stmt_copy_it(copies_param, the_var, stmt->param_count, i)) { if (PASS != mysqlnd_stmt_copy_it(copies_param, the_var, stmt->param_count, i)) {
SET_OOM_ERROR(*stmt->error_info); SET_OOM_ERROR(stmt->error_info);
goto end; goto end;
} }
} }
@ -845,7 +845,7 @@ mysqlnd_stmt_execute_store_params(MYSQLND_STMT * s, zend_uchar **buf, zend_uchar
{ {
unsigned int null_count = (stmt->param_count + 7) / 8; unsigned int null_count = (stmt->param_count + 7) / 8;
if (FAIL == mysqlnd_stmt_execute_check_n_enlarge_buffer(buf, p, buf_len, provided_buffer, null_count)) { if (FAIL == mysqlnd_stmt_execute_check_n_enlarge_buffer(buf, p, buf_len, provided_buffer, null_count)) {
SET_OOM_ERROR(*stmt->error_info); SET_OOM_ERROR(stmt->error_info);
goto end; goto end;
} }
/* put `null` bytes */ /* put `null` bytes */
@ -871,7 +871,7 @@ mysqlnd_stmt_execute_store_params(MYSQLND_STMT * s, zend_uchar **buf, zend_uchar
if (stmt->send_types_to_server) { if (stmt->send_types_to_server) {
if (FAIL == mysqlnd_stmt_execute_check_n_enlarge_buffer(buf, p, buf_len, provided_buffer, stmt->param_count * 2)) { if (FAIL == mysqlnd_stmt_execute_check_n_enlarge_buffer(buf, p, buf_len, provided_buffer, stmt->param_count * 2)) {
SET_OOM_ERROR(*stmt->error_info); SET_OOM_ERROR(stmt->error_info);
goto end; goto end;
} }
mysqlnd_stmt_execute_store_types(stmt, copies, p); mysqlnd_stmt_execute_store_types(stmt, copies, p);
@ -887,7 +887,7 @@ mysqlnd_stmt_execute_store_params(MYSQLND_STMT * s, zend_uchar **buf, zend_uchar
/* 2.2 Enlarge the buffer, if needed */ /* 2.2 Enlarge the buffer, if needed */
if (FAIL == mysqlnd_stmt_execute_check_n_enlarge_buffer(buf, p, buf_len, provided_buffer, data_size)) { if (FAIL == mysqlnd_stmt_execute_check_n_enlarge_buffer(buf, p, buf_len, provided_buffer, data_size)) {
SET_OOM_ERROR(*stmt->error_info); SET_OOM_ERROR(stmt->error_info);
goto end; goto end;
} }

View file

@ -371,7 +371,7 @@ MYSQLND_METHOD(mysqlnd_res, read_result_metadata)(MYSQLND_RES * result, MYSQLND_
result->meta = result->m.result_meta_init(result->field_count, result->persistent); result->meta = result->m.result_meta_init(result->field_count, result->persistent);
if (!result->meta) { if (!result->meta) {
SET_OOM_ERROR(*conn->error_info); SET_OOM_ERROR(conn->error_info);
DBG_RETURN(FAIL); DBG_RETURN(FAIL);
} }
@ -413,14 +413,14 @@ mysqlnd_query_read_result_set_header(MYSQLND_CONN_DATA * conn, MYSQLND_STMT * s)
do { do {
rset_header = conn->payload_decoder_factory->m.get_rset_header_packet(conn->payload_decoder_factory, FALSE); rset_header = conn->payload_decoder_factory->m.get_rset_header_packet(conn->payload_decoder_factory, FALSE);
if (!rset_header) { if (!rset_header) {
SET_OOM_ERROR(*conn->error_info); SET_OOM_ERROR(conn->error_info);
ret = FAIL; ret = FAIL;
break; break;
} }
UPSERT_STATUS_SET_AFFECTED_ROWS_TO_ERROR(conn->upsert_status); UPSERT_STATUS_SET_AFFECTED_ROWS_TO_ERROR(conn->upsert_status);
if (FAIL == (ret = PACKET_READ(rset_header, conn))) { if (FAIL == (ret = PACKET_READ(rset_header))) {
php_error_docref(NULL, E_WARNING, "Error reading result set's header"); php_error_docref(NULL, E_WARNING, "Error reading result set's header");
break; break;
} }
@ -440,7 +440,7 @@ mysqlnd_query_read_result_set_header(MYSQLND_CONN_DATA * conn, MYSQLND_STMT * s)
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 */
@ -526,7 +526,7 @@ mysqlnd_query_read_result_set_header(MYSQLND_CONN_DATA * conn, MYSQLND_STMT * s)
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;
} }
@ -544,11 +544,11 @@ mysqlnd_query_read_result_set_header(MYSQLND_CONN_DATA * conn, MYSQLND_STMT * s)
/* Check for SERVER_STATUS_MORE_RESULTS if needed */ /* Check for SERVER_STATUS_MORE_RESULTS if needed */
fields_eof = conn->payload_decoder_factory->m.get_eof_packet(conn->payload_decoder_factory, FALSE); fields_eof = conn->payload_decoder_factory->m.get_eof_packet(conn->payload_decoder_factory, FALSE);
if (!fields_eof) { if (!fields_eof) {
SET_OOM_ERROR(*conn->error_info); SET_OOM_ERROR(conn->error_info);
ret = FAIL; ret = FAIL;
break; break;
} }
if (FAIL == (ret = PACKET_READ(fields_eof, conn))) { if (FAIL == (ret = PACKET_READ(fields_eof))) {
DBG_ERR("Error occurred while reading the EOF packet"); DBG_ERR("Error occurred while reading the EOF packet");
result->m.free_result_contents(result); result->m.free_result_contents(result);
mnd_efree(result); mnd_efree(result);
@ -696,7 +696,7 @@ MYSQLND_METHOD(mysqlnd_result_unbuffered, fetch_row_c)(MYSQLND_RES * result, voi
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) {
@ -710,7 +710,7 @@ MYSQLND_METHOD(mysqlnd_result_unbuffered, fetch_row_c)(MYSQLND_RES * result, voi
If we skip rows (row == NULL) we have to If we skip rows (row == NULL) we have to
result->m.unbuffered_free_last_data() before it. The function returns always true. result->m.unbuffered_free_last_data() before it. The function returns always true.
*/ */
if (PASS == (ret = PACKET_READ(row_packet, result->conn)) && !row_packet->eof) { if (PASS == (ret = PACKET_READ(row_packet)) && !row_packet->eof) {
result->unbuf->m.free_last_data(result->unbuf, result->conn? result->conn->stats : NULL); result->unbuf->m.free_last_data(result->unbuf, result->conn? result->conn->stats : NULL);
result->unbuf->last_row_data = row_packet->fields; result->unbuf->last_row_data = row_packet->fields;
@ -760,7 +760,7 @@ MYSQLND_METHOD(mysqlnd_result_unbuffered, fetch_row_c)(MYSQLND_RES * result, voi
} }
} }
} else { } else {
SET_OOM_ERROR(*result->conn->error_info); SET_OOM_ERROR(result->conn->error_info);
} }
} }
} }
@ -768,7 +768,7 @@ MYSQLND_METHOD(mysqlnd_result_unbuffered, fetch_row_c)(MYSQLND_RES * result, voi
*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(*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);
@ -816,7 +816,7 @@ MYSQLND_METHOD(mysqlnd_result_unbuffered, fetch_row)(MYSQLND_RES * result, void
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) {
@ -830,7 +830,7 @@ MYSQLND_METHOD(mysqlnd_result_unbuffered, fetch_row)(MYSQLND_RES * result, void
If we skip rows (row == NULL) we have to If we skip rows (row == NULL) we have to
result->m.unbuffered_free_last_data() before it. The function returns always true. result->m.unbuffered_free_last_data() before it. The function returns always true.
*/ */
if (PASS == (ret = PACKET_READ(row_packet, result->conn)) && !row_packet->eof) { if (PASS == (ret = PACKET_READ(row_packet)) && !row_packet->eof) {
result->unbuf->m.free_last_data(result->unbuf, result->conn? result->conn->stats : NULL); result->unbuf->m.free_last_data(result->unbuf, result->conn? result->conn->stats : NULL);
result->unbuf->last_row_data = row_packet->fields; result->unbuf->last_row_data = row_packet->fields;
@ -895,7 +895,7 @@ MYSQLND_METHOD(mysqlnd_result_unbuffered, fetch_row)(MYSQLND_RES * result, void
*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(*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);
@ -932,7 +932,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;
@ -964,7 +964,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);
} }
/* }}} */ /* }}} */
@ -1036,7 +1036,7 @@ MYSQLND_METHOD(mysqlnd_result_buffered, fetch_row_c)(MYSQLND_RES * result, void
set->data_cursor += field_count; set->data_cursor += field_count;
MYSQLND_INC_GLOBAL_STATISTIC(STAT_ROWS_FETCHED_FROM_CLIENT_NORMAL_BUF); MYSQLND_INC_GLOBAL_STATISTIC(STAT_ROWS_FETCHED_FROM_CLIENT_NORMAL_BUF);
} else { } else {
SET_OOM_ERROR(*result->conn->error_info); SET_OOM_ERROR(result->conn->error_info);
} }
/* END difference between normal normal fetch and _c */ /* END difference between normal normal fetch and _c */
@ -1170,7 +1170,7 @@ MYSQLND_METHOD(mysqlnd_result_buffered_c, fetch_row)(MYSQLND_RES * result, void
current_row = mnd_emalloc(field_count * sizeof(zval)); current_row = mnd_emalloc(field_count * sizeof(zval));
if (!current_row) { if (!current_row) {
SET_OOM_ERROR(*result->conn->error_info); SET_OOM_ERROR(result->conn->error_info);
DBG_RETURN(FAIL); DBG_RETURN(FAIL);
} }
@ -1294,7 +1294,7 @@ MYSQLND_METHOD(mysqlnd_res, store_result_fetch_data)(MYSQLND_CONN_DATA * const c
if (free_rows) { if (free_rows) {
*row_buffers = mnd_pemalloc((size_t)(free_rows * sizeof(MYSQLND_MEMORY_POOL_CHUNK *)), 0); *row_buffers = mnd_pemalloc((size_t)(free_rows * sizeof(MYSQLND_MEMORY_POOL_CHUNK *)), 0);
if (!*row_buffers) { if (!*row_buffers) {
SET_OOM_ERROR(*conn->error_info); SET_OOM_ERROR(conn->error_info);
ret = FAIL; ret = FAIL;
goto end; goto end;
} }
@ -1304,7 +1304,7 @@ MYSQLND_METHOD(mysqlnd_res, store_result_fetch_data)(MYSQLND_CONN_DATA * const c
/* non-persistent */ /* non-persistent */
row_packet = conn->payload_decoder_factory->m.get_row_packet(conn->payload_decoder_factory, FALSE); row_packet = conn->payload_decoder_factory->m.get_row_packet(conn->payload_decoder_factory, FALSE);
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;
} }
@ -1317,7 +1317,7 @@ MYSQLND_METHOD(mysqlnd_res, store_result_fetch_data)(MYSQLND_CONN_DATA * const c
row_packet->skip_extraction = TRUE; /* let php_mysqlnd_rowp_read() not allocate row_packet->fields, we will do it */ row_packet->skip_extraction = TRUE; /* let php_mysqlnd_rowp_read() not allocate row_packet->fields, we will do it */
while (FAIL != (ret = PACKET_READ(row_packet, conn)) && !row_packet->eof) { while (FAIL != (ret = PACKET_READ(row_packet)) && !row_packet->eof) {
if (!free_rows) { if (!free_rows) {
uint64_t total_allocated_rows = free_rows = next_extend = next_extend * 11 / 10; /* extend with 10% */ uint64_t total_allocated_rows = free_rows = next_extend = next_extend * 11 / 10; /* extend with 10% */
MYSQLND_MEMORY_POOL_CHUNK ** new_row_buffers; MYSQLND_MEMORY_POOL_CHUNK ** new_row_buffers;
@ -1325,13 +1325,13 @@ MYSQLND_METHOD(mysqlnd_res, store_result_fetch_data)(MYSQLND_CONN_DATA * const c
/* 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_perealloc(*row_buffers, (size_t)(total_allocated_rows * sizeof(MYSQLND_MEMORY_POOL_CHUNK *)), 0); new_row_buffers = mnd_perealloc(*row_buffers, (size_t)(total_allocated_rows * sizeof(MYSQLND_MEMORY_POOL_CHUNK *)), 0);
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;
} }
@ -1369,7 +1369,7 @@ MYSQLND_METHOD(mysqlnd_res, store_result_fetch_data)(MYSQLND_CONN_DATA * const c
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;
} }
@ -1383,7 +1383,7 @@ MYSQLND_METHOD(mysqlnd_res, store_result_fetch_data)(MYSQLND_CONN_DATA * const c
} }
if (ret == FAIL) { if (ret == FAIL) {
COPY_CLIENT_ERROR(set->error_info, row_packet->error_info); COPY_CLIENT_ERROR(&set->error_info, row_packet->error_info);
} else { } else {
/* 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;
@ -1419,14 +1419,14 @@ MYSQLND_METHOD(mysqlnd_res, store_result)(MYSQLND_RES * result,
if (flags & MYSQLND_STORE_NO_COPY) { if (flags & MYSQLND_STORE_NO_COPY) {
result->stored_data = (MYSQLND_RES_BUFFERED *) mysqlnd_result_buffered_zval_init(result->field_count, flags & MYSQLND_STORE_PS, result->persistent); result->stored_data = (MYSQLND_RES_BUFFERED *) mysqlnd_result_buffered_zval_init(result->field_count, flags & MYSQLND_STORE_PS, result->persistent);
if (!result->stored_data) { if (!result->stored_data) {
SET_OOM_ERROR(*conn->error_info); SET_OOM_ERROR(conn->error_info);
DBG_RETURN(NULL); DBG_RETURN(NULL);
} }
row_buffers = &result->stored_data->row_buffers; row_buffers = &result->stored_data->row_buffers;
} else if (flags & MYSQLND_STORE_COPY) { } else if (flags & MYSQLND_STORE_COPY) {
result->stored_data = (MYSQLND_RES_BUFFERED *) mysqlnd_result_buffered_c_init(result->field_count, flags & MYSQLND_STORE_PS, result->persistent); result->stored_data = (MYSQLND_RES_BUFFERED *) mysqlnd_result_buffered_c_init(result->field_count, flags & MYSQLND_STORE_PS, result->persistent);
if (!result->stored_data) { if (!result->stored_data) {
SET_OOM_ERROR(*conn->error_info); SET_OOM_ERROR(conn->error_info);
DBG_RETURN(NULL); DBG_RETURN(NULL);
} }
row_buffers = &result->stored_data->row_buffers; row_buffers = &result->stored_data->row_buffers;
@ -1435,9 +1435,9 @@ MYSQLND_METHOD(mysqlnd_res, store_result)(MYSQLND_RES * result,
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);
} else { } else {
@ -1448,13 +1448,13 @@ MYSQLND_METHOD(mysqlnd_res, store_result)(MYSQLND_RES * result,
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);
DBG_RETURN(NULL); DBG_RETURN(NULL);
} }
/* 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);
DBG_RETURN(NULL); DBG_RETURN(NULL);
} }
memset(set->data, 0, (size_t)(set->row_count * meta->field_count * sizeof(zval))); memset(set->data, 0, (size_t)(set->row_count * meta->field_count * sizeof(zval)));
@ -1791,7 +1791,7 @@ MYSQLND_METHOD(mysqlnd_res, fetch_all)(MYSQLND_RES * result, const unsigned int
if ((!result->unbuf && !set)) { if ((!result->unbuf && !set)) {
php_error_docref(NULL, E_WARNING, "fetch_all can be used only with buffered sets"); php_error_docref(NULL, 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

@ -59,7 +59,7 @@ MYSQLND_METHOD(mysqlnd_res_meta, read_metadata)(MYSQLND_RES_METADATA * const met
field_packet = conn->payload_decoder_factory->m.get_result_field_packet(conn->payload_decoder_factory, FALSE); field_packet = conn->payload_decoder_factory->m.get_result_field_packet(conn->payload_decoder_factory, FALSE);
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;
@ -73,12 +73,12 @@ MYSQLND_METHOD(mysqlnd_res_meta, read_metadata)(MYSQLND_RES_METADATA * const met
} }
field_packet->metadata = &(meta->fields[i]); field_packet->metadata = &(meta->fields[i]);
if (FAIL == PACKET_READ(field_packet, conn)) { if (FAIL == PACKET_READ(field_packet)) {
PACKET_FREE(field_packet); PACKET_FREE(field_packet);
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

@ -120,13 +120,27 @@ struct st_mysqlnd_upsert_status
}; };
typedef struct st_mysqlnd_error_info
typedef struct st_mysqlnd_error_info MYSQLND_ERROR_INFO;
typedef void (*func_mysqlnd_error_info__reset)(MYSQLND_ERROR_INFO * const info);
typedef void (*func_mysqlnd_error_info__set_client_error)(MYSQLND_ERROR_INFO * const info, const unsigned int err_no, const char * const sqlstate, const char * const error);
MYSQLND_CLASS_METHOD_TABLE_NAME_DECL(mysqlnd_error_info)
{
func_mysqlnd_error_info__reset reset;
func_mysqlnd_error_info__set_client_error set_client_error;
};
struct st_mysqlnd_error_info
{ {
char error[MYSQLND_ERRMSG_SIZE+1]; char error[MYSQLND_ERRMSG_SIZE+1];
char sqlstate[MYSQLND_SQLSTATE_LENGTH + 1]; char sqlstate[MYSQLND_SQLSTATE_LENGTH + 1];
unsigned int error_no; unsigned int error_no;
zend_llist * error_list; zend_llist * error_list;
} MYSQLND_ERROR_INFO;
MYSQLND_CLASS_METHOD_TABLE_NAME_DECL(mysqlnd_error_info) *m;
};
typedef struct st_mysqlnd_error_list_element typedef struct st_mysqlnd_error_list_element

View file

@ -296,7 +296,7 @@ mysqlnd_read_packet_header_and_body(MYSQLND_PACKET_HEADER * packet_header, MYSQL
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)) { if (FAIL == mysqlnd_read_header(conn->net, packet_header, conn->stats, conn->error_info)) {
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, E_WARNING, "%s", mysqlnd_server_gone); php_error_docref(NULL, 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);
@ -308,7 +308,7 @@ mysqlnd_read_packet_header_and_body(MYSQLND_PACKET_HEADER * packet_header, MYSQL
} }
if (FAIL == conn->net->data->m.receive_ex(conn->net, buf, packet_header->size, conn->stats, conn->error_info)) { if (FAIL == conn->net->data->m.receive_ex(conn->net, buf, packet_header->size, conn->stats, conn->error_info)) {
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, E_WARNING, "%s", mysqlnd_server_gone); php_error_docref(NULL, 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);
@ -528,7 +528,7 @@ size_t php_mysqlnd_auth_write(void * _packet)
if (packet->auth_data_len > 0xFF) { if (packet->auth_data_len > 0xFF) {
const char * const msg = "Authentication data too long. " const char * const msg = "Authentication data too long. "
"Won't fit into the buffer and will be truncated. Authentication will thus fail"; "Won't fit into the buffer and will be truncated. Authentication will thus fail";
SET_CLIENT_ERROR(*conn->error_info, CR_UNKNOWN_ERROR, UNKNOWN_SQLSTATE, msg); SET_CLIENT_ERROR(conn->error_info, CR_UNKNOWN_ERROR, UNKNOWN_SQLSTATE, msg);
php_error_docref(NULL, E_WARNING, "%s", msg); php_error_docref(NULL, E_WARNING, "%s", msg);
DBG_RETURN(0); DBG_RETURN(0);
} }
@ -1167,7 +1167,7 @@ php_mysqlnd_rset_header_read(void * _packet)
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;
@ -1194,7 +1194,7 @@ php_mysqlnd_rset_header_read(void * _packet)
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;
} }
} }
@ -1376,7 +1376,7 @@ php_mysqlnd_rset_field_read(void * _packet)
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);
@ -1387,7 +1387,7 @@ php_mysqlnd_rset_field_read(void * _packet)
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);
} }
@ -1520,7 +1520,7 @@ php_mysqlnd_read_row_ex(MYSQLND_CONN_DATA * conn, MYSQLND_MEMORY_POOL * result_s
We have to realloc the buffer. We have to realloc the buffer.
*/ */
if (FAIL == (*buffer)->resize_chunk((*buffer), *data_size)) { if (FAIL == (*buffer)->resize_chunk((*buffer), *data_size)) {
SET_OOM_ERROR(*conn->error_info); SET_OOM_ERROR(conn->error_info);
ret = FAIL; ret = FAIL;
break; break;
} }
@ -2667,36 +2667,41 @@ send_command_do_request(
const enum php_mysqlnd_server_command command, const enum php_mysqlnd_server_command command,
const zend_uchar * const arg, const size_t arg_len, const zend_uchar * const arg, const size_t arg_len,
const zend_bool silent, const zend_bool silent,
const zend_bool ignore_upsert_status) const zend_bool ignore_upsert_status,
enum mysqlnd_connection_state conn_state,
MYSQLND_ERROR_INFO * error_info,
MYSQLND_UPSERT_STATUS * upsert_status,
MYSQLND_STATS * stats,
MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * payload_decoder_factory
)
{ {
enum_func_status ret = PASS; enum_func_status ret = PASS;
MYSQLND_PACKET_COMMAND * cmd_packet = NULL; MYSQLND_PACKET_COMMAND * cmd_packet = NULL;
enum mysqlnd_connection_state conn_state = CONN_GET_STATE(conn); DBG_ENTER("send_command_do_request");
MYSQLND_ERROR_INFO * error_info = conn->error_info;
DBG_ENTER("mysqlnd_conn_data::send_command_do_request");
DBG_INF_FMT("command=%s silent=%u", mysqlnd_command_to_text[command], silent); DBG_INF_FMT("command=%s silent=%u", mysqlnd_command_to_text[command], silent);
DBG_INF_FMT("conn->server_status=%u", conn->upsert_status->server_status); DBG_INF_FMT("server_status=%u", upsert_status->server_status);
DBG_INF_FMT("sending %u bytes", arg_len + 1); /* + 1 is for the command */ DBG_INF_FMT("sending %u bytes", arg_len + 1); /* + 1 is for the command */
switch (conn_state) { switch (conn_state) {
case CONN_READY: case CONN_READY:
break; break;
case CONN_QUIT_SENT: case CONN_QUIT_SENT:
SET_CLIENT_ERROR(*error_info, CR_SERVER_GONE_ERROR, UNKNOWN_SQLSTATE, mysqlnd_server_gone); SET_CLIENT_ERROR(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(*error_info, CR_COMMANDS_OUT_OF_SYNC, UNKNOWN_SQLSTATE, mysqlnd_out_of_sync); SET_CLIENT_ERROR(error_info, CR_COMMANDS_OUT_OF_SYNC, UNKNOWN_SQLSTATE, mysqlnd_out_of_sync);
DBG_ERR_FMT("Command out of sync. State=%u", conn_state); DBG_ERR_FMT("Command out of sync. State=%u", conn_state);
DBG_RETURN(FAIL); DBG_RETURN(FAIL);
} }
UPSERT_STATUS_SET_AFFECTED_ROWS_TO_ERROR(conn->upsert_status); UPSERT_STATUS_SET_AFFECTED_ROWS_TO_ERROR(upsert_status);
SET_EMPTY_ERROR(*conn->error_info); SET_EMPTY_ERROR(error_info);
cmd_packet = conn->payload_decoder_factory->m.get_command_packet(conn->payload_decoder_factory, FALSE); cmd_packet = payload_decoder_factory->m.get_command_packet(payload_decoder_factory, FALSE);
if (!cmd_packet) { if (!cmd_packet) {
SET_OOM_ERROR(*conn->error_info); SET_OOM_ERROR(error_info);
DBG_RETURN(FAIL); DBG_RETURN(FAIL);
} }
@ -2706,9 +2711,9 @@ send_command_do_request(
cmd_packet->arg_len = arg_len; cmd_packet->arg_len = arg_len;
} }
MYSQLND_INC_CONN_STATISTIC(conn->stats, STAT_COM_QUIT + command - 1 /* because of COM_SLEEP */ ); MYSQLND_INC_CONN_STATISTIC(stats, STAT_COM_QUIT + command - 1 /* because of COM_SLEEP */ );
if (! PACKET_WRITE(cmd_packet, conn)) { if (! PACKET_WRITE(cmd_packet)) {
if (!silent) { if (!silent) {
DBG_ERR_FMT("Error while sending %s packet", mysqlnd_command_to_text[command]); DBG_ERR_FMT("Error while sending %s packet", mysqlnd_command_to_text[command]);
php_error(E_WARNING, "Error while sending %s packet. PID=%d", mysqlnd_command_to_text[command], getpid()); php_error(E_WARNING, "Error while sending %s packet. PID=%d", mysqlnd_command_to_text[command], getpid());
@ -2772,7 +2777,8 @@ mysqlnd_com_set_option_run(void *cmd)
DBG_ENTER("mysqlnd_com_set_option_run"); DBG_ENTER("mysqlnd_com_set_option_run");
int2store(buffer, (unsigned int) option); int2store(buffer, (unsigned int) option);
ret = send_command_do_request(conn, COM_SET_OPTION, buffer, sizeof(buffer), FALSE, TRUE); ret = send_command_do_request(conn, COM_SET_OPTION, buffer, sizeof(buffer), FALSE, TRUE,
CONN_GET_STATE(conn), conn->error_info, conn->upsert_status, conn->stats, conn->payload_decoder_factory);
if (PASS == ret) { if (PASS == ret) {
ret = conn->m->send_command_handle_response(conn, PROT_EOF_PACKET, FALSE, COM_SET_OPTION, TRUE); ret = conn->m->send_command_handle_response(conn, PROT_EOF_PACKET, FALSE, COM_SET_OPTION, TRUE);
} }
@ -2813,7 +2819,8 @@ mysqlnd_com_debug_run(void *cmd)
DBG_ENTER("mysqlnd_com_debug_run"); DBG_ENTER("mysqlnd_com_debug_run");
ret = send_command_do_request(conn, COM_DEBUG, NULL, 0, FALSE, TRUE); ret = send_command_do_request(conn, COM_DEBUG, NULL, 0, FALSE, TRUE,
CONN_GET_STATE(conn), conn->error_info, conn->upsert_status, conn->stats, conn->payload_decoder_factory);
if (PASS == ret) { if (PASS == ret) {
ret = conn->m->send_command_handle_response(conn, PROT_EOF_PACKET, COM_DEBUG, COM_DEBUG, TRUE); ret = conn->m->send_command_handle_response(conn, PROT_EOF_PACKET, COM_DEBUG, COM_DEBUG, TRUE);
} }
@ -2864,7 +2871,8 @@ mysqlnd_com_init_db_run(void *cmd)
DBG_ENTER("mysqlnd_com_init_db_run"); DBG_ENTER("mysqlnd_com_init_db_run");
ret = send_command_do_request(conn, COM_INIT_DB, (zend_uchar*) command->context.db.s, command->context.db.l, FALSE, TRUE); ret = send_command_do_request(conn, COM_INIT_DB, (zend_uchar*) command->context.db.s, command->context.db.l, FALSE, TRUE,
CONN_GET_STATE(conn), conn->error_info, conn->upsert_status, conn->stats, conn->payload_decoder_factory);
if (PASS == ret) { if (PASS == ret) {
ret = conn->m->send_command_handle_response(conn, PROT_OK_PACKET, FALSE, COM_INIT_DB, TRUE); ret = conn->m->send_command_handle_response(conn, PROT_OK_PACKET, FALSE, COM_INIT_DB, TRUE);
} }
@ -2905,7 +2913,8 @@ mysqlnd_com_ping_run(void *cmd)
DBG_ENTER("mysqlnd_com_ping_run"); DBG_ENTER("mysqlnd_com_ping_run");
ret = send_command_do_request(conn, COM_PING, NULL, 0, TRUE, TRUE); ret = send_command_do_request(conn, COM_PING, NULL, 0, TRUE, TRUE,
CONN_GET_STATE(conn), conn->error_info, conn->upsert_status, conn->stats, conn->payload_decoder_factory);
if (PASS == ret) { if (PASS == ret) {
ret = conn->m->send_command_handle_response(conn, PROT_OK_PACKET, TRUE, COM_PING, TRUE); ret = conn->m->send_command_handle_response(conn, PROT_OK_PACKET, TRUE, COM_PING, TRUE);
} }
@ -2972,7 +2981,8 @@ mysqlnd_com_field_list_run(void *cmd)
*p++ = '\0'; *p++ = '\0';
} }
ret = send_command_do_request(conn, COM_FIELD_LIST, buff, p - buff, FALSE, TRUE); ret = send_command_do_request(conn, COM_FIELD_LIST, buff, p - buff, FALSE, TRUE,
CONN_GET_STATE(conn), conn->error_info, conn->upsert_status, conn->stats, conn->payload_decoder_factory);
DBG_RETURN(ret); DBG_RETURN(ret);
} }
@ -3011,7 +3021,8 @@ mysqlnd_com_statistics_run(void *cmd)
DBG_ENTER("mysqlnd_com_statistics_run"); DBG_ENTER("mysqlnd_com_statistics_run");
ret = send_command_do_request(conn, COM_STATISTICS, NULL, 0, FALSE, TRUE); ret = send_command_do_request(conn, COM_STATISTICS, NULL, 0, FALSE, TRUE,
CONN_GET_STATE(conn), conn->error_info, conn->upsert_status, conn->stats, conn->payload_decoder_factory);
DBG_RETURN(ret); DBG_RETURN(ret);
} }
@ -3061,7 +3072,8 @@ mysqlnd_com_process_kill_run(void *cmd)
DBG_ENTER("mysqlnd_com_process_kill_run"); DBG_ENTER("mysqlnd_com_process_kill_run");
int4store(buff, command->context.process_id); int4store(buff, command->context.process_id);
ret = send_command_do_request(conn, COM_PROCESS_KILL, buff, 4, FALSE, TRUE); ret = send_command_do_request(conn, COM_PROCESS_KILL, buff, 4, FALSE, TRUE,
CONN_GET_STATE(conn), conn->error_info, conn->upsert_status, conn->stats, conn->payload_decoder_factory);
if (PASS == ret && command->context.read_response) { if (PASS == ret && command->context.read_response) {
ret = conn->m->send_command_handle_response(conn, PROT_OK_PACKET, FALSE, COM_PROCESS_KILL, TRUE); ret = conn->m->send_command_handle_response(conn, PROT_OK_PACKET, FALSE, COM_PROCESS_KILL, TRUE);
} }
@ -3115,7 +3127,8 @@ mysqlnd_com_refresh_run(void *cmd)
DBG_ENTER("mysqlnd_com_refresh_run"); DBG_ENTER("mysqlnd_com_refresh_run");
int1store(bits, command->context.options); int1store(bits, command->context.options);
ret = send_command_do_request(conn, COM_REFRESH, bits, 1, FALSE, TRUE); ret = send_command_do_request(conn, COM_REFRESH, bits, 1, FALSE, TRUE,
CONN_GET_STATE(conn), conn->error_info, conn->upsert_status, conn->stats, conn->payload_decoder_factory);
if (PASS == ret) { if (PASS == ret) {
ret = conn->m->send_command_handle_response(conn, PROT_OK_PACKET, FALSE, COM_REFRESH, TRUE); ret = conn->m->send_command_handle_response(conn, PROT_OK_PACKET, FALSE, COM_REFRESH, TRUE);
} }
@ -3169,7 +3182,8 @@ mysqlnd_com_shutdown_run(void *cmd)
DBG_ENTER("mysqlnd_com_shutdown_run"); DBG_ENTER("mysqlnd_com_shutdown_run");
int1store(bits, command->context.level); int1store(bits, command->context.level);
ret = send_command_do_request(conn, COM_SHUTDOWN, bits, 1, FALSE, TRUE); ret = send_command_do_request(conn, COM_SHUTDOWN, bits, 1, FALSE, TRUE,
CONN_GET_STATE(conn), conn->error_info, conn->upsert_status, conn->stats, conn->payload_decoder_factory);
if (PASS == ret) { if (PASS == ret) {
ret = conn->m->send_command_handle_response(conn, PROT_OK_PACKET, FALSE, COM_SHUTDOWN, TRUE); ret = conn->m->send_command_handle_response(conn, PROT_OK_PACKET, FALSE, COM_SHUTDOWN, TRUE);
} }
@ -3220,7 +3234,8 @@ mysqlnd_com_quit_run(void *cmd)
DBG_ENTER("mysqlnd_com_quit_run"); DBG_ENTER("mysqlnd_com_quit_run");
ret = send_command_do_request(conn, COM_QUIT, NULL, 0, TRUE, TRUE); ret = send_command_do_request(conn, COM_QUIT, NULL, 0, TRUE, TRUE,
CONN_GET_STATE(conn), conn->error_info, conn->upsert_status, conn->stats, conn->payload_decoder_factory);
DBG_RETURN(ret); DBG_RETURN(ret);
} }
@ -3267,7 +3282,8 @@ mysqlnd_com_query_run(void *cmd)
DBG_ENTER("mysqlnd_com_query_run"); DBG_ENTER("mysqlnd_com_query_run");
ret = send_command_do_request(conn, COM_QUERY, (zend_uchar*) command->context.query.s, command->context.query.l, FALSE, FALSE); ret = send_command_do_request(conn, COM_QUERY, (zend_uchar*) command->context.query.s, command->context.query.l, FALSE, FALSE,
CONN_GET_STATE(conn), conn->error_info, conn->upsert_status, conn->stats, conn->payload_decoder_factory);
if (PASS == ret) { if (PASS == ret) {
CONN_SET_STATE(conn, CONN_QUERY_SENT); CONN_SET_STATE(conn, CONN_QUERY_SENT);
@ -3320,7 +3336,8 @@ mysqlnd_com_change_user_run(void *cmd)
DBG_ENTER("mysqlnd_com_change_user_run"); DBG_ENTER("mysqlnd_com_change_user_run");
ret = send_command_do_request(conn, COM_CHANGE_USER, (zend_uchar*) command->context.payload.s, command->context.payload.l, command->context.silent, TRUE); ret = send_command_do_request(conn, COM_CHANGE_USER, (zend_uchar*) command->context.payload.s, command->context.payload.l, command->context.silent, TRUE,
CONN_GET_STATE(conn), conn->error_info, conn->upsert_status, conn->stats, conn->payload_decoder_factory);
DBG_RETURN(ret); DBG_RETURN(ret);
} }
@ -3422,7 +3439,8 @@ mysqlnd_com_stmt_prepare_run(void *cmd)
DBG_ENTER("mysqlnd_com_stmt_prepare_run"); DBG_ENTER("mysqlnd_com_stmt_prepare_run");
ret = send_command_do_request(conn, COM_STMT_PREPARE, (zend_uchar*) command->context.query.s, command->context.query.l, FALSE, TRUE); ret = send_command_do_request(conn, COM_STMT_PREPARE, (zend_uchar*) command->context.query.s, command->context.query.l, FALSE, TRUE,
CONN_GET_STATE(conn), conn->error_info, conn->upsert_status, conn->stats, conn->payload_decoder_factory);
DBG_RETURN(ret); DBG_RETURN(ret);
} }
@ -3471,7 +3489,8 @@ mysqlnd_com_stmt_execute_run(void *cmd)
DBG_ENTER("mysqlnd_com_stmt_execute_run"); DBG_ENTER("mysqlnd_com_stmt_execute_run");
ret = send_command_do_request(conn, COM_STMT_EXECUTE, (zend_uchar*) command->context.payload.s, command->context.payload.l, FALSE, FALSE); ret = send_command_do_request(conn, COM_STMT_EXECUTE, (zend_uchar*) command->context.payload.s, command->context.payload.l, FALSE, FALSE,
CONN_GET_STATE(conn), conn->error_info, conn->upsert_status, conn->stats, conn->payload_decoder_factory);
DBG_RETURN(ret); DBG_RETURN(ret);
} }
@ -3520,7 +3539,8 @@ mysqlnd_com_stmt_fetch_run(void *cmd)
DBG_ENTER("mysqlnd_com_stmt_fetch_run"); DBG_ENTER("mysqlnd_com_stmt_fetch_run");
ret = send_command_do_request(conn, COM_STMT_FETCH, (zend_uchar*) command->context.payload.s, command->context.payload.l, FALSE, TRUE); ret = send_command_do_request(conn, COM_STMT_FETCH, (zend_uchar*) command->context.payload.s, command->context.payload.l, FALSE, TRUE,
CONN_GET_STATE(conn), conn->error_info, conn->upsert_status, conn->stats, conn->payload_decoder_factory);
DBG_RETURN(ret); DBG_RETURN(ret);
} }
@ -3571,7 +3591,8 @@ mysqlnd_com_stmt_reset_run(void *cmd)
DBG_ENTER("mysqlnd_com_stmt_reset_run"); DBG_ENTER("mysqlnd_com_stmt_reset_run");
int4store(cmd_buf, command->context.stmt_id); int4store(cmd_buf, command->context.stmt_id);
ret = send_command_do_request(conn, COM_STMT_RESET, cmd_buf, sizeof(cmd_buf), FALSE, TRUE); ret = send_command_do_request(conn, COM_STMT_RESET, cmd_buf, sizeof(cmd_buf), FALSE, TRUE,
CONN_GET_STATE(conn), conn->error_info, conn->upsert_status, conn->stats, conn->payload_decoder_factory);
DBG_RETURN(ret); DBG_RETURN(ret);
} }
@ -3620,7 +3641,8 @@ mysqlnd_com_stmt_send_long_data_run(void *cmd)
DBG_ENTER("mysqlnd_com_stmt_send_long_data_run"); DBG_ENTER("mysqlnd_com_stmt_send_long_data_run");
ret = send_command_do_request(conn, COM_STMT_SEND_LONG_DATA, (zend_uchar*) command->context.payload.s, command->context.payload.l, FALSE, TRUE); ret = send_command_do_request(conn, COM_STMT_SEND_LONG_DATA, (zend_uchar*) command->context.payload.s, command->context.payload.l, FALSE, TRUE,
CONN_GET_STATE(conn), conn->error_info, conn->upsert_status, conn->stats, conn->payload_decoder_factory);
DBG_RETURN(ret); DBG_RETURN(ret);
} }
@ -3671,7 +3693,8 @@ mysqlnd_com_stmt_close_run(void *cmd)
DBG_ENTER("mysqlnd_com_stmt_close_run"); DBG_ENTER("mysqlnd_com_stmt_close_run");
int4store(cmd_buf, command->context.stmt_id); int4store(cmd_buf, command->context.stmt_id);
ret = send_command_do_request(conn, COM_STMT_CLOSE, cmd_buf, sizeof(cmd_buf), FALSE, TRUE); ret = send_command_do_request(conn, COM_STMT_CLOSE, cmd_buf, sizeof(cmd_buf), FALSE, TRUE,
CONN_GET_STATE(conn), conn->error_info, conn->upsert_status, conn->stats, conn->payload_decoder_factory);
DBG_RETURN(ret); DBG_RETURN(ret);
} }
@ -3753,7 +3776,7 @@ mysqlnd_com_enable_ssl_run(void *cmd)
auth_packet = conn->payload_decoder_factory->m.get_auth_packet(conn->payload_decoder_factory, FALSE); auth_packet = conn->payload_decoder_factory->m.get_auth_packet(conn->payload_decoder_factory, FALSE);
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 = client_capabilities; auth_packet->client_flags = client_capabilities;
@ -3773,7 +3796,7 @@ mysqlnd_com_enable_ssl_run(void *cmd)
MYSQLND_SSL_PEER_DONT_VERIFY: MYSQLND_SSL_PEER_DONT_VERIFY:
MYSQLND_SSL_PEER_DEFAULT); MYSQLND_SSL_PEER_DEFAULT);
DBG_INF("Switching to SSL"); DBG_INF("Switching to SSL");
if (!PACKET_WRITE(auth_packet, conn)) { if (!PACKET_WRITE(auth_packet)) {
goto close_conn; goto close_conn;
} }
@ -3786,7 +3809,7 @@ mysqlnd_com_enable_ssl_run(void *cmd)
} }
#else #else
auth_packet->client_flags &= ~CLIENT_SSL; auth_packet->client_flags &= ~CLIENT_SSL;
if (!PACKET_WRITE(auth_packet, conn)) { if (!PACKET_WRITE(auth_packet)) {
goto close_conn; goto close_conn;
} }
#endif #endif
@ -3798,7 +3821,7 @@ end:
close_conn: close_conn:
CONN_SET_STATE(conn, CONN_QUIT_SENT); CONN_SET_STATE(conn, CONN_QUIT_SENT);
conn->m->send_close(conn); conn->m->send_close(conn);
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);
PACKET_FREE(auth_packet); PACKET_FREE(auth_packet);
DBG_RETURN(ret); DBG_RETURN(ret);
} }

View file

@ -36,8 +36,8 @@ PHPAPI extern const char mysqlnd_read_body_name[];
/* Packet handling */ /* Packet handling */
#define PACKET_WRITE(packet, conn) ((packet)->header.m->write_to_net((packet))) #define PACKET_WRITE(packet) ((packet)->header.m->write_to_net((packet)))
#define PACKET_READ(packet, conn) ((packet)->header.m->read_from_net((packet))) #define PACKET_READ(packet) ((packet)->header.m->read_from_net((packet)))
#define PACKET_FREE(packet) \ #define PACKET_FREE(packet) \
do { \ do { \
DBG_INF_FMT("PACKET_FREE(%p)", packet); \ DBG_INF_FMT("PACKET_FREE(%p)", packet); \