Skip to content

Commit

Permalink
MNDR:
Browse files Browse the repository at this point in the history
- split handle_response() into handle_OK and handle_EOF
  • Loading branch information
faizshukri committed Nov 12, 2015
1 parent aa4966d commit 7e6f9a8
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 184 deletions.
103 changes: 0 additions & 103 deletions ext/mysqlnd/mysqlnd.c
Original file line number Diff line number Diff line change
Expand Up @@ -356,109 +356,6 @@ MYSQLND_METHOD_PRIVATE(mysqlnd_conn_data, dtor)(MYSQLND_CONN_DATA * conn)
}
/* }}} */

#if 0
/* {{{ mysqlnd_conn_data::send_command_handle_response */
static enum_func_status
MYSQLND_METHOD(mysqlnd_conn_data, send_command_handle_response)(
MYSQLND_CONN_DATA * const conn,
const enum mysqlnd_packet_type ok_packet,
const zend_bool silent,
const enum php_mysqlnd_server_command command,
const zend_bool ignore_upsert_status)
{
enum_func_status ret = FAIL;

DBG_ENTER("mysqlnd_conn_data::send_command_handle_response");
DBG_INF_FMT("silent=%u packet=%u command=%s", silent, ok_packet, mysqlnd_command_to_text[command]);

switch (ok_packet) {
case PROT_OK_PACKET:{
MYSQLND_PACKET_OK * ok_response = conn->payload_decoder_factory->m.get_ok_packet(conn->payload_decoder_factory, FALSE);
if (!ok_response) {
SET_OOM_ERROR(conn->error_info);
break;
}
if (FAIL == (ret = PACKET_READ(ok_response))) {
if (!silent) {
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",
mysqlnd_command_to_text[command], getpid());
}
} else {
DBG_INF_FMT("OK from server");
if (0xFF == ok_response->field_count) {
/* The server signalled error. Set the error */
SET_CLIENT_ERROR(conn->error_info, ok_response->error_no, ok_response->sqlstate, ok_response->error);
ret = FAIL;
/*
Cover a protocol design error: error packet does not
contain the server status. Therefore, the client has no way
to find out whether there are more result sets of
a multiple-result-set statement pending. Luckily, in 5.0 an
error always aborts execution of a statement, wherever it is
a multi-statement or a stored procedure, so it should be
safe to unconditionally turn off the flag here.
*/
conn->upsert_status->server_status &= ~SERVER_MORE_RESULTS_EXISTS;
UPSERT_STATUS_SET_AFFECTED_ROWS_TO_ERROR(conn->upsert_status);
} else {
SET_NEW_MESSAGE(conn->last_message, conn->last_message_len,
ok_response->message, ok_response->message_len,
conn->persistent);

if (!ignore_upsert_status) {
UPSERT_STATUS_RESET(conn->upsert_status);
conn->upsert_status->warning_count = ok_response->warning_count;
conn->upsert_status->server_status = ok_response->server_status;
conn->upsert_status->affected_rows = ok_response->affected_rows;
conn->upsert_status->last_insert_id = ok_response->last_insert_id;
}
}
}
PACKET_FREE(ok_response);
break;
}
case PROT_EOF_PACKET:{
MYSQLND_PACKET_EOF * ok_response = conn->payload_decoder_factory->m.get_eof_packet(conn->payload_decoder_factory, FALSE);
if (!ok_response) {
SET_OOM_ERROR(conn->error_info);
break;
}
if (FAIL == (ret = PACKET_READ(ok_response))) {
SET_CLIENT_ERROR(conn->error_info, CR_MALFORMED_PACKET, UNKNOWN_SQLSTATE,
"Malformed packet");
if (!silent) {
DBG_ERR_FMT("Error while reading %s's EOF packet", mysqlnd_command_to_text[command]);
php_error_docref(NULL, E_WARNING, "Error while reading %s's EOF packet. PID=%d",
mysqlnd_command_to_text[command], getpid());
}
} else if (0xFF == ok_response->field_count) {
/* The server signalled error. Set the 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);
} else if (0xFE != ok_response->field_count) {
SET_CLIENT_ERROR(conn->error_info, CR_MALFORMED_PACKET, UNKNOWN_SQLSTATE, "Malformed packet");
if (!silent) {
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",
ok_response->field_count);
}
} else {
DBG_INF_FMT("OK from server");
}
PACKET_FREE(ok_response);
break;
}
default:
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);
break;
}
DBG_INF(ret == PASS ? "PASS":"FAIL");
DBG_RETURN(ret);
}
/* }}} */
#endif

/* {{{ mysqlnd_conn_data::set_server_option */
static enum_func_status
Expand Down
8 changes: 6 additions & 2 deletions ext/mysqlnd/mysqlnd_loaddata.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ mysqlnd_local_infile_default(MYSQLND_CONN_DATA * conn)
/* }}} */


static const char *lost_conn = "Lost connection to MySQL server during LOAD DATA of local file";
static const char *lost_conn = "Lost connection to MySQL server during LOAD DATA of a local file";


/* {{{ mysqlnd_handle_local_infile */
Expand Down Expand Up @@ -213,7 +213,11 @@ mysqlnd_handle_local_infile(MYSQLND_CONN_DATA * conn, const char * const filenam
infile_error:
/* get response from server and update upsert values */
if (FAIL == send_command_handle_response(PROT_OK_PACKET, FALSE, COM_QUERY, FALSE,
conn->error_info, conn->upsert_status, conn->payload_decoder_factory, &conn->last_message, conn->persistent)) {
conn->error_info,
conn->upsert_status,
conn->payload_decoder_factory,
&conn->last_message,
conn->persistent)) {
result = FAIL;
}

Expand Down
4 changes: 2 additions & 2 deletions ext/mysqlnd/mysqlnd_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,8 @@

void mysqlnd_upsert_status_init(MYSQLND_UPSERT_STATUS * const upsert_status);

#define UPSERT_STATUS_SET_AFFECTED_ROWS_TO_ERROR(status) (status)->m->set_affected_rows_to_error((status))
#define UPSERT_STATUS_RESET(status) (status)->m->reset((status))
#define UPSERT_STATUS_SET_AFFECTED_ROWS_TO_ERROR(status) (status)->m->set_affected_rows_to_error((status))
#define UPSERT_STATUS_RESET(status) (status)->m->reset((status))

/* Error handling */
#define SET_NEW_MESSAGE(buf, buf_len, message, len, persistent) \
Expand Down
186 changes: 109 additions & 77 deletions ext/mysqlnd/mysqlnd_wireprotocol.c
Original file line number Diff line number Diff line change
Expand Up @@ -2730,13 +2730,113 @@ send_command(
/* }}} */


/* {{{ send_command_handle_OK */
static enum_func_status
send_command_handle_OK(MYSQLND_ERROR_INFO * const error_info,
MYSQLND_UPSERT_STATUS * const upsert_status,
MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * const payload_decoder_factory,
const zend_bool ignore_upsert_status, /* actually used only by LOAD DATA. COM_QUERY and COM_EXECUTE handle the responses themselves */
MYSQLND_STRING * const last_message,
const zend_bool last_message_persistent)
{
enum_func_status ret = FAIL;
MYSQLND_PACKET_OK * ok_response = payload_decoder_factory->m.get_ok_packet(payload_decoder_factory, FALSE);

DBG_ENTER("send_command_handle_OK");
if (!ok_response) {
SET_OOM_ERROR(error_info);
DBG_RETURN(FAIL);
}
if (FAIL == (ret = PACKET_READ(ok_response))) {
DBG_INF("Error while reading OK packet");
SET_CLIENT_ERROR(error_info, CR_MALFORMED_PACKET, UNKNOWN_SQLSTATE, "Malformed packet");
goto end;
}
DBG_INF_FMT("OK from server");
if (0xFF == ok_response->field_count) {
/* The server signalled error. Set the error */
SET_CLIENT_ERROR(error_info, ok_response->error_no, ok_response->sqlstate, ok_response->error);
ret = FAIL;
/*
Cover a protocol design error: error packet does not
contain the server status. Therefore, the client has no way
to find out whether there are more result sets of
a multiple-result-set statement pending. Luckily, in 5.0 an
error always aborts execution of a statement, wherever it is
a multi-statement or a stored procedure, so it should be
safe to unconditionally turn off the flag here.
*/
upsert_status->server_status &= ~SERVER_MORE_RESULTS_EXISTS;
UPSERT_STATUS_SET_AFFECTED_ROWS_TO_ERROR(upsert_status);
} else {
SET_NEW_MESSAGE(last_message->s, last_message->l,
ok_response->message, ok_response->message_len,
last_message_persistent);
if (!ignore_upsert_status) {
UPSERT_STATUS_RESET(upsert_status);
upsert_status->warning_count = ok_response->warning_count;
upsert_status->server_status = ok_response->server_status;
upsert_status->affected_rows = ok_response->affected_rows;
upsert_status->last_insert_id = ok_response->last_insert_id;
} else {
/* LOAD DATA */
}
}
end:
PACKET_FREE(ok_response);
DBG_INF(ret == PASS ? "PASS":"FAIL");
DBG_RETURN(ret);
}
/* }}} */


/* {{{ send_command_handle_EOF */
enum_func_status
send_command_handle_EOF(MYSQLND_ERROR_INFO * const error_info,
MYSQLND_UPSERT_STATUS * const upsert_status,
MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * const payload_decoder_factory)
{
enum_func_status ret = FAIL;
MYSQLND_PACKET_EOF * response = payload_decoder_factory->m.get_eof_packet(payload_decoder_factory, FALSE);

DBG_ENTER("send_command_handle_EOF");

if (!response) {
SET_OOM_ERROR(error_info);
DBG_RETURN(FAIL);
}
if (FAIL == (ret = PACKET_READ(response))) {
DBG_INF("Error while reading EOF packet");
SET_CLIENT_ERROR(error_info, CR_MALFORMED_PACKET, UNKNOWN_SQLSTATE, "Malformed packet");
} else if (0xFF == response->field_count) {
/* The server signalled error. Set the error */
DBG_INF_FMT("Error_no=%d SQLstate=%s Error=%s", response->error_no, response->sqlstate, response->error);

SET_CLIENT_ERROR(error_info, response->error_no, response->sqlstate, response->error);

UPSERT_STATUS_SET_AFFECTED_ROWS_TO_ERROR(upsert_status);
} else if (0xFE != response->field_count) {
SET_CLIENT_ERROR(error_info, CR_MALFORMED_PACKET, UNKNOWN_SQLSTATE, "Malformed packet");
DBG_ERR_FMT("EOF packet expected, field count wasn't 0xFE but 0x%2X", response->field_count);
php_error_docref(NULL, E_WARNING, "EOF packet expected, field count wasn't 0xFE but 0x%2X", response->field_count);
} else {
DBG_INF_FMT("EOF from server");
}
PACKET_FREE(response);

DBG_INF(ret == PASS ? "PASS":"FAIL");
DBG_RETURN(ret);
}
/* }}} */


/* {{{ send_command_handle_response */
enum_func_status
send_command_handle_response(
const enum mysqlnd_packet_type ok_packet,
const zend_bool silent,
const enum php_mysqlnd_server_command command,
const zend_bool ignore_upsert_status,
const zend_bool ignore_upsert_status, /* actually used only by LOAD DATA. COM_QUERY and COM_EXECUTE handle the responses themselves */

MYSQLND_ERROR_INFO * error_info,
MYSQLND_UPSERT_STATUS * upsert_status,
Expand All @@ -2751,88 +2851,20 @@ send_command_handle_response(
DBG_INF_FMT("silent=%u packet=%u command=%s", silent, ok_packet, mysqlnd_command_to_text[command]);

switch (ok_packet) {
case PROT_OK_PACKET:{
MYSQLND_PACKET_OK * ok_response = payload_decoder_factory->m.get_ok_packet(payload_decoder_factory, FALSE);
if (!ok_response) {
SET_OOM_ERROR(error_info);
break;
}
if (FAIL == (ret = PACKET_READ(ok_response))) {
if (!silent) {
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",
mysqlnd_command_to_text[command], getpid());
}
} else {
DBG_INF_FMT("OK from server");
if (0xFF == ok_response->field_count) {
/* The server signalled error. Set the error */
SET_CLIENT_ERROR(error_info, ok_response->error_no, ok_response->sqlstate, ok_response->error);
ret = FAIL;
/*
Cover a protocol design error: error packet does not
contain the server status. Therefore, the client has no way
to find out whether there are more result sets of
a multiple-result-set statement pending. Luckily, in 5.0 an
error always aborts execution of a statement, wherever it is
a multi-statement or a stored procedure, so it should be
safe to unconditionally turn off the flag here.
*/
upsert_status->server_status &= ~SERVER_MORE_RESULTS_EXISTS;
UPSERT_STATUS_SET_AFFECTED_ROWS_TO_ERROR(upsert_status);
} else {
SET_NEW_MESSAGE(last_message->s, last_message->l,
ok_response->message, ok_response->message_len,
last_message_persistent);

if (!ignore_upsert_status) {
UPSERT_STATUS_RESET(upsert_status);
upsert_status->warning_count = ok_response->warning_count;
upsert_status->server_status = ok_response->server_status;
upsert_status->affected_rows = ok_response->affected_rows;
upsert_status->last_insert_id = ok_response->last_insert_id;
}
}
}
PACKET_FREE(ok_response);
case PROT_OK_PACKET:
ret = send_command_handle_OK(error_info, upsert_status, payload_decoder_factory, ignore_upsert_status, last_message, last_message_persistent);
break;
}
case PROT_EOF_PACKET:{
MYSQLND_PACKET_EOF * ok_response = payload_decoder_factory->m.get_eof_packet(payload_decoder_factory, FALSE);
if (!ok_response) {
SET_OOM_ERROR(error_info);
break;
}
if (FAIL == (ret = PACKET_READ(ok_response))) {
SET_CLIENT_ERROR(error_info, CR_MALFORMED_PACKET, UNKNOWN_SQLSTATE,
"Malformed packet");
if (!silent) {
DBG_ERR_FMT("Error while reading %s's EOF packet", mysqlnd_command_to_text[command]);
php_error_docref(NULL, E_WARNING, "Error while reading %s's EOF packet. PID=%d",
mysqlnd_command_to_text[command], getpid());
}
} else if (0xFF == ok_response->field_count) {
/* The server signalled error. Set the error */
SET_CLIENT_ERROR(error_info, ok_response->error_no, ok_response->sqlstate, ok_response->error);
UPSERT_STATUS_SET_AFFECTED_ROWS_TO_ERROR(upsert_status);
} else if (0xFE != ok_response->field_count) {
SET_CLIENT_ERROR(error_info, CR_MALFORMED_PACKET, UNKNOWN_SQLSTATE, "Malformed packet");
if (!silent) {
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",
ok_response->field_count);
}
} else {
DBG_INF_FMT("OK from server");
}
PACKET_FREE(ok_response);
case PROT_EOF_PACKET:
ret = send_command_handle_EOF(error_info, upsert_status, payload_decoder_factory);
break;
}
default:
SET_CLIENT_ERROR(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);
break;
}
if (!silent && error_info->error_no == CR_MALFORMED_PACKET) {
php_error_docref(NULL, E_WARNING, "Error while reading %s's response packet. PID=%d", mysqlnd_command_to_text[command], getpid());
}
DBG_INF(ret == PASS ? "PASS":"FAIL");
DBG_RETURN(ret);
}
Expand Down Expand Up @@ -2942,7 +2974,7 @@ mysqlnd_com_debug_run(void *cmd)
conn->m->send_close,
conn);
if (PASS == ret) {
ret = send_command_handle_response(PROT_EOF_PACKET, COM_DEBUG, COM_DEBUG, TRUE,
ret = send_command_handle_response(PROT_EOF_PACKET, FALSE, COM_DEBUG, TRUE,
conn->error_info, conn->upsert_status, conn->payload_decoder_factory, &conn->last_message, conn->persistent);
}

Expand Down

0 comments on commit 7e6f9a8

Please sign in to comment.