From: Andrey Hristov Date: Mon, 2 Nov 2015 13:16:18 +0000 (+0100) Subject: MNDR: X-Git-Tag: php-7.1.0alpha1~781 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7e6f9a84cb8693ec24ec44d902c15d99300d3641;p=php MNDR: - split handle_response() into handle_OK and handle_EOF --- 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); }