MXS-1160: Add support for LOAD DATA LOCAL INFILE

Schemarouter now supports the LOAD DATA LOCAL INFILE command.
This commit is contained in:
Markus Mäkelä
2017-03-27 23:39:00 +03:00
parent f6470c580a
commit 94ac2d89d0
2 changed files with 102 additions and 66 deletions

View File

@ -128,7 +128,8 @@ SchemaRouterSession::SchemaRouterSession(MXS_SESSION* session, SchemaRouter* rou
m_shard(m_router->m_shard_manager.get_shard(m_client->user, m_config->refresh_min_interval)),
m_state(0),
m_sent_sescmd(0),
m_replied_sescmd(0)
m_replied_sescmd(0),
m_load_target(NULL)
{
char db[MYSQL_DATABASE_MAXLEN + 1] = "";
MySQLProtocol* protocol = (MySQLProtocol*)session->client_dcb->protocol;
@ -368,6 +369,21 @@ SERVER* SchemaRouterSession::resolve_query_target(GWBUF* pPacket,
return target;
}
static bool is_empty_packet(GWBUF* pPacket)
{
bool rval = false;
uint8_t len[3];
if (gwbuf_length(pPacket) == 4 &&
gwbuf_copy_data(pPacket, 0, 3, len) == 3 &&
gw_mysql_get_byte3(len) == 0)
{
rval = true;
}
return rval;
}
int32_t SchemaRouterSession::routeQuery(GWBUF* pPacket)
{
ss_dassert(!GWBUF_IS_TYPE_UNDEFINED(pPacket));
@ -416,6 +432,19 @@ int32_t SchemaRouterSession::routeQuery(GWBUF* pPacket)
qc_query_op_t op = QUERY_OP_UNDEFINED;
enum route_target route_target = TARGET_UNDEFINED;
if (m_load_target)
{
/** A load data local infile is active */
target = m_load_target->m_backend->server;
route_target = TARGET_NAMED_SERVER;
if (is_empty_packet(pPacket))
{
m_load_target = NULL;
}
}
else
{
inspect_query(pPacket, &type, &op, &command);
/** Create the response to the SHOW DATABASES from the mapped databases */
@ -449,7 +478,7 @@ int32_t SchemaRouterSession::routeQuery(GWBUF* pPacket)
gwbuf_free(pPacket);
char errbuf[128 + MYSQL_DATABASE_MAXLEN];
snprintf(errbuf, sizeof(errbuf), "Unknown database: %s", db);
snprintf(errbuf, sizeof (errbuf), "Unknown database: %s", db);
if (m_config->debug)
{
@ -502,6 +531,7 @@ int32_t SchemaRouterSession::routeQuery(GWBUF* pPacket)
{
target = resolve_query_target(pPacket, type, command, route_target);
}
}
DCB* target_dcb = NULL;
@ -511,6 +541,11 @@ int32_t SchemaRouterSession::routeQuery(GWBUF* pPacket)
/** We know where to route this query */
Backend *bref = get_bref_from_dcb(target_dcb);
if (op == QUERY_OP_LOAD)
{
m_load_target = bref;
}
MXS_INFO("Route query to \t%s:%d <", bref->m_backend->server->name, bref->m_backend->server->port);
if (bref->m_session_commands.size() > 0)

View File

@ -207,4 +207,5 @@ private:
Stats m_stats; /**< Statistics for this router */
uint64_t m_sent_sescmd; /**< The latest session command being executed */
uint64_t m_replied_sescmd; /**< The last session command reply that was sent to the client */
Backend* m_load_target; /**< Target for LOAD DATA LOCAL INFILE */
};