MXS-2435 Refactor error message extracting

Access to the error message is needed in different contexts.
Now the extraction code itself can be shared.
This commit is contained in:
Johan Wikman
2019-04-25 13:03:17 +03:00
parent d186244261
commit d8a9405998
2 changed files with 51 additions and 11 deletions

View File

@ -423,6 +423,44 @@ std::pair<int, int> get_slave_counts(mxs::PRWBackends& backends, mxs::RWBackend*
*/ */
void close_all_connections(mxs::PRWBackends& backends); void close_all_connections(mxs::PRWBackends& backends);
/**
* Extract the SQL state from an error packet.
*
* @param pBuffer Pointer to an error packet.
* @param ppState On return will point to the state in @c pBuffer.
* @param pnState On return the pointed to value will be 6.
*/
inline void extract_error_state(uint8_t* pBuffer, uint8_t** ppState, uint16_t* pnState)
{
mxb_assert(MYSQL_IS_ERROR_PACKET(pBuffer));
// The payload starts with a one byte command followed by a two byte error code,
// followed by a 1 byte sql state marker and 5 bytes of sql state. In this context
// the marker and the state itself are combined.
*ppState = pBuffer + MYSQL_HEADER_LEN + 1 + 2;
*pnState = 6;
}
/**
* Extract the message from an error packet.
*
* @param pBuffer Pointer to an error packet.
* @param ppMessage On return will point to the start of the message in @c pBuffer.
* @param pnMessage On return the pointed to value will be the length of the message.
*/
inline void extract_error_message(uint8_t* pBuffer, uint8_t** ppMessage, uint16_t* pnMessage)
{
mxb_assert(MYSQL_IS_ERROR_PACKET(pBuffer));
int packet_len = MYSQL_HEADER_LEN + MYSQL_GET_PAYLOAD_LEN(pBuffer);
// The payload starts with a one byte command followed by a two byte error code,
// followed by a 1 byte sql state marker and 5 bytes of sql state, followed by
// a message until the end of the packet.
*ppMessage = pBuffer + MYSQL_HEADER_LEN + 1 + 2 + 1 + 5;
*pnMessage = packet_len - MYSQL_HEADER_LEN - 1 - 2 - 1 - 5;
}
/** /**
* Utility function for extracting error messages from buffers * Utility function for extracting error messages from buffers
* *

View File

@ -28,7 +28,6 @@ using namespace maxscale;
* Functions for session command handling * Functions for session command handling
*/ */
std::string extract_error(GWBUF* buffer) std::string extract_error(GWBUF* buffer)
{ {
std::string rval; std::string rval;
@ -36,17 +35,20 @@ std::string extract_error(GWBUF* buffer)
if (MYSQL_IS_ERROR_PACKET(((uint8_t*)GWBUF_DATA(buffer)))) if (MYSQL_IS_ERROR_PACKET(((uint8_t*)GWBUF_DATA(buffer))))
{ {
size_t replylen = MYSQL_GET_PAYLOAD_LEN(GWBUF_DATA(buffer)) + MYSQL_HEADER_LEN; size_t replylen = MYSQL_GET_PAYLOAD_LEN(GWBUF_DATA(buffer)) + MYSQL_HEADER_LEN;
char replybuf[replylen]; uint8_t replybuf[replylen];
gwbuf_copy_data(buffer, 0, sizeof(replybuf), (uint8_t*)replybuf); gwbuf_copy_data(buffer, 0, sizeof(replybuf), replybuf);
std::string err;
std::string msg; uint8_t* pState;
uint16_t nState;
extract_error_state(replybuf, &pState, &nState);
uint8_t* pMessage;
uint16_t nMessage;
extract_error_message(replybuf, &pMessage, &nMessage);
std::string err(reinterpret_cast<const char*>(pState), nState);
std::string msg(reinterpret_cast<const char*>(pMessage), nMessage);
/**
* The payload starts with a one byte command followed by a two byte error code, a six byte state and
* a human-readable string that spans the rest of the packet.
*/
err.append(replybuf + MYSQL_HEADER_LEN + 3, 6);
msg.append(replybuf + MYSQL_HEADER_LEN + 3 + 6, replylen - MYSQL_HEADER_LEN - 3 - 6);
rval = err + ": " + msg; rval = err + ": " + msg;
} }