MXS-1625 Move internal/external id map to QueryClassifier
This commit is contained in:
@ -15,6 +15,7 @@
|
|||||||
#include <maxscale/cppdefs.hh>
|
#include <maxscale/cppdefs.hh>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <tr1/memory>
|
#include <tr1/memory>
|
||||||
|
#include <tr1/unordered_map>
|
||||||
#include <tr1/unordered_set>
|
#include <tr1/unordered_set>
|
||||||
#include <maxscale/router.h>
|
#include <maxscale/router.h>
|
||||||
#include <maxscale/session.h>
|
#include <maxscale/session.h>
|
||||||
@ -156,6 +157,23 @@ public:
|
|||||||
void ps_erase(std::string id);
|
void ps_erase(std::string id);
|
||||||
void ps_erase(uint32_t id);
|
void ps_erase(uint32_t id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the internal ID for the given binary prepared statement
|
||||||
|
*
|
||||||
|
* @param buffer Buffer containing a binary protocol statement other than COM_STMT_PREPARE
|
||||||
|
*
|
||||||
|
* @return The internal ID of the prepared statement that the buffer contents refer to
|
||||||
|
*/
|
||||||
|
uint32_t ps_id_internal_get(GWBUF* pBuffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Store a mapping from an external id to the corresponding internal id
|
||||||
|
*
|
||||||
|
* @param external_id The external id as seen by the client.
|
||||||
|
* @param internal_id The corresponding internal id.
|
||||||
|
*/
|
||||||
|
void ps_id_internal_put(uint32_t external_id, uint32_t internal_id);
|
||||||
|
|
||||||
uint32_t get_route_target(uint8_t command, uint32_t qtype);
|
uint32_t get_route_target(uint8_t command, uint32_t qtype);
|
||||||
|
|
||||||
MXS_SESSION* session() const
|
MXS_SESSION* session() const
|
||||||
@ -167,6 +185,8 @@ private:
|
|||||||
class PSManager;
|
class PSManager;
|
||||||
typedef std::shared_ptr<PSManager> SPSManager;
|
typedef std::shared_ptr<PSManager> SPSManager;
|
||||||
|
|
||||||
|
typedef std::tr1::unordered_map<uint32_t, uint32_t> HandleMap;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MXS_SESSION* m_pSession;
|
MXS_SESSION* m_pSession;
|
||||||
mxs_target_t m_use_sql_variables_in;
|
mxs_target_t m_use_sql_variables_in;
|
||||||
@ -177,6 +197,7 @@ private:
|
|||||||
bool m_large_query; /**< Set to true when processing payloads >= 2^24 bytes */
|
bool m_large_query; /**< Set to true when processing payloads >= 2^24 bytes */
|
||||||
bool m_multi_statements_allowed; /**< Are multi-statements allowed */
|
bool m_multi_statements_allowed; /**< Are multi-statements allowed */
|
||||||
SPSManager m_sPs_manager;
|
SPSManager m_sPs_manager;
|
||||||
|
HandleMap m_ps_handles; /** External ID to internal ID */
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -364,5 +364,52 @@ uint32_t QueryClassifier::get_route_target(uint8_t command, uint32_t qtype)
|
|||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
// Copy of mxs_mysql_extract_ps_id() in modules/protocol/MySQL/mysql_common.cc,
|
||||||
|
// but we do not want to create a dependency from maxscale-common to that.
|
||||||
|
|
||||||
|
uint32_t mysql_extract_ps_id(GWBUF* buffer)
|
||||||
|
{
|
||||||
|
uint32_t rval = 0;
|
||||||
|
uint8_t id[MYSQL_PS_ID_SIZE];
|
||||||
|
|
||||||
|
if (gwbuf_copy_data(buffer, MYSQL_PS_ID_OFFSET, sizeof(id), id) == sizeof(id))
|
||||||
|
{
|
||||||
|
rval = gw_mysql_get_byte4(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rval;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t QueryClassifier::ps_id_internal_get(GWBUF* pBuffer)
|
||||||
|
{
|
||||||
|
uint32_t internal_id = 0;
|
||||||
|
|
||||||
|
// All COM_STMT type statements store the ID in the same place
|
||||||
|
uint32_t external_id = mysql_extract_ps_id(pBuffer);
|
||||||
|
auto it = m_ps_handles.find(external_id);
|
||||||
|
|
||||||
|
if (it != m_ps_handles.end())
|
||||||
|
{
|
||||||
|
internal_id = it->second;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MXS_WARNING("Client requests unknown prepared statement ID '%u' that "
|
||||||
|
"does not map to an internal ID", external_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return internal_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QueryClassifier::ps_id_internal_put(uint32_t external_id, uint32_t internal_id)
|
||||||
|
{
|
||||||
|
m_ps_handles[external_id] = internal_id;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -613,7 +613,7 @@ route_target_t get_target_type(RWSplitSession *rses, GWBUF *buffer,
|
|||||||
}
|
}
|
||||||
else if (mxs_mysql_is_ps_command(*command))
|
else if (mxs_mysql_is_ps_command(*command))
|
||||||
{
|
{
|
||||||
*stmt_id = get_internal_ps_id(rses, buffer);
|
*stmt_id = rses->qc().ps_id_internal_get(buffer);
|
||||||
*type = rses->qc().ps_get_type(*stmt_id);
|
*type = rses->qc().ps_get_type(*stmt_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,7 +111,7 @@ void RWSplitSession::process_sescmd_response(SRWBackend& backend, GWBUF** ppPack
|
|||||||
{
|
{
|
||||||
/** Map the returned response to the internal ID */
|
/** Map the returned response to the internal ID */
|
||||||
MXS_INFO("PS ID %u maps to internal ID %lu", resp.id, id);
|
MXS_INFO("PS ID %u maps to internal ID %lu", resp.id, id);
|
||||||
m_ps_handles[resp.id] = id;
|
m_qc.ps_id_internal_put(resp.id, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Discard any slave connections that did not return the same result
|
// Discard any slave connections that did not return the same result
|
||||||
|
@ -737,24 +737,3 @@ void RWSplitSession::handle_error_reply_client(DCB *backend_dcb, GWBUF *errmsg)
|
|||||||
m_client->func.write(m_client, gwbuf_clone(errmsg));
|
m_client->func.write(m_client, gwbuf_clone(errmsg));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t get_internal_ps_id(RWSplitSession* rses, GWBUF* buffer)
|
|
||||||
{
|
|
||||||
uint32_t rval = 0;
|
|
||||||
|
|
||||||
// All COM_STMT type statements store the ID in the same place
|
|
||||||
uint32_t id = mxs_mysql_extract_ps_id(buffer);
|
|
||||||
ClientHandleMap::iterator it = rses->m_ps_handles.find(id);
|
|
||||||
|
|
||||||
if (it != rses->m_ps_handles.end())
|
|
||||||
{
|
|
||||||
rval = it->second;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
MXS_WARNING("Client requests unknown prepared statement ID '%u' that "
|
|
||||||
"does not map to an internal ID", id);
|
|
||||||
}
|
|
||||||
|
|
||||||
return rval;
|
|
||||||
}
|
|
||||||
|
Reference in New Issue
Block a user