summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey Hristov <andrey@php.net>2015-11-02 14:16:18 +0100
committerAndrey Hristov <andrey@php.net>2015-11-12 16:19:16 +0100
commit7e6f9a84cb8693ec24ec44d902c15d99300d3641 (patch)
tree4a9e401838d2bb5012e01370c7db624bf4c47e9c
parentaa4966d4e37076ed560ba0a10f0758863d8af389 (diff)
downloadphp-git-7e6f9a84cb8693ec24ec44d902c15d99300d3641.tar.gz
MNDR:
- split handle_response() into handle_OK and handle_EOF
-rw-r--r--ext/mysqlnd/mysqlnd.c103
-rw-r--r--ext/mysqlnd/mysqlnd_loaddata.c8
-rw-r--r--ext/mysqlnd/mysqlnd_priv.h4
-rw-r--r--ext/mysqlnd/mysqlnd_wireprotocol.c186
4 files changed, 117 insertions, 184 deletions
diff --git a/ext/mysqlnd/mysqlnd.c b/ext/mysqlnd/mysqlnd.c
index fd41cd4bb1..13eb7af57c 100644
--- a/ext/mysqlnd/mysqlnd.c
+++ b/ext/mysqlnd/mysqlnd.c
@@ -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
diff --git a/ext/mysqlnd/mysqlnd_loaddata.c b/ext/mysqlnd/mysqlnd_loaddata.c
index b43607443e..51e887c128 100644
--- a/ext/mysqlnd/mysqlnd_loaddata.c
+++ b/ext/mysqlnd/mysqlnd_loaddata.c
@@ -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 */
@@ -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;
}
diff --git a/ext/mysqlnd/mysqlnd_priv.h b/ext/mysqlnd/mysqlnd_priv.h
index 0451812fd0..bff0098e3c 100644
--- a/ext/mysqlnd/mysqlnd_priv.h
+++ b/ext/mysqlnd/mysqlnd_priv.h
@@ -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) \
diff --git a/ext/mysqlnd/mysqlnd_wireprotocol.c b/ext/mysqlnd/mysqlnd_wireprotocol.c
index 21508614ed..3ab85c4d0e 100644
--- a/ext/mysqlnd/mysqlnd_wireprotocol.c
+++ b/ext/mysqlnd/mysqlnd_wireprotocol.c
@@ -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,
@@ -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);
}
@@ -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);
}