MXS-2385 Fix the problem with the USE command and tpmfilter

Trying to get the type mask of the QWBUF caused debug assertion in the query
classifier when using some commands. Now type mask is checked only when the
buffer contains MXS_COM_QUERY command.
This commit is contained in:
Marko
2019-05-13 12:31:35 +03:00
parent 32c2724454
commit 17d3beba3b

View File

@ -62,6 +62,7 @@
#include <maxscale/server.hh> #include <maxscale/server.hh>
#include <maxbase/atomic.h> #include <maxbase/atomic.h>
#include <maxscale/query_classifier.hh> #include <maxscale/query_classifier.hh>
#include <maxscale/protocol/mysql.hh>
/* The maximum size for query statements in a transaction (64MB) */ /* The maximum size for query statements in a transaction (64MB) */
static size_t sql_size_limit = 64 * 1024 * 1024; static size_t sql_size_limit = 64 * 1024 * 1024;
@ -464,77 +465,83 @@ static int routeQuery(MXS_FILTER* instance, MXS_FILTER_SESSION* session, GWBUF*
{ {
if ((ptr = modutil_get_SQL(queue)) != NULL) if ((ptr = modutil_get_SQL(queue)) != NULL)
{ {
uint32_t query_type = qc_get_type_mask(queue); uint8_t* data = (uint8_t*) GWBUF_DATA(queue);
int query_len = strlen(ptr); uint8_t command = MYSQL_GET_COMMAND(data);
my_session->query_end = false;
/* check for commit and rollback */ if (command == MXS_COM_QUERY)
if (query_type & QUERY_TYPE_COMMIT)
{ {
my_session->query_end = true; uint32_t query_type = qc_get_type_mask(queue);
} int query_len = strlen(ptr);
else if (query_type & QUERY_TYPE_ROLLBACK) my_session->query_end = false;
{
my_session->query_end = true;
my_session->sql_index = 0;
}
/* for normal sql statements */ /* check for commit and rollback */
if (!my_session->query_end) if (query_type & QUERY_TYPE_COMMIT)
{
/* check and expand buffer size first. */
size_t new_sql_size = my_session->max_sql_size;
size_t len = my_session->sql_index + strlen(ptr) + my_instance->query_delimiter_size + 1;
/* if the total length of query statements exceeds the maximum limit, print an error and
* return */
if (len > sql_size_limit)
{ {
MXS_ERROR("The size of query statements exceeds the maximum buffer limit of 64MB."); my_session->query_end = true;
goto retblock; }
else if (query_type & QUERY_TYPE_ROLLBACK)
{
my_session->query_end = true;
my_session->sql_index = 0;
} }
/* double buffer size until the buffer fits the query */ /* for normal sql statements */
while (len > new_sql_size) if (!my_session->query_end)
{ {
new_sql_size *= 2; /* check and expand buffer size first. */
} size_t new_sql_size = my_session->max_sql_size;
if (new_sql_size > my_session->max_sql_size) size_t len = my_session->sql_index + strlen(ptr) + my_instance->query_delimiter_size + 1;
{
char* new_sql = (char*)MXS_CALLOC(new_sql_size, sizeof(char)); /* if the total length of query statements exceeds the maximum limit, print an error and
if (new_sql == NULL) * return */
if (len > sql_size_limit)
{ {
MXS_ERROR("Memory allocation failure."); MXS_ERROR("The size of query statements exceeds the maximum buffer limit of 64MB.");
goto retblock; goto retblock;
} }
memcpy(new_sql, my_session->sql, my_session->sql_index);
MXS_FREE(my_session->sql);
my_session->sql = new_sql;
my_session->max_sql_size = new_sql_size;
}
/* first statement */ /* double buffer size until the buffer fits the query */
if (my_session->sql_index == 0) while (len > new_sql_size)
{ {
memcpy(my_session->sql, ptr, strlen(ptr)); new_sql_size *= 2;
my_session->sql_index += strlen(ptr); }
gettimeofday(&my_session->current_start, NULL); if (new_sql_size > my_session->max_sql_size)
{
char* new_sql = (char*)MXS_CALLOC(new_sql_size, sizeof(char));
if (new_sql == NULL)
{
MXS_ERROR("Memory allocation failure.");
goto retblock;
}
memcpy(new_sql, my_session->sql, my_session->sql_index);
MXS_FREE(my_session->sql);
my_session->sql = new_sql;
my_session->max_sql_size = new_sql_size;
}
/* first statement */
if (my_session->sql_index == 0)
{
memcpy(my_session->sql, ptr, strlen(ptr));
my_session->sql_index += strlen(ptr);
gettimeofday(&my_session->current_start, NULL);
}
/* otherwise, append the statement with semicolon as a statement delimiter */
else
{
/* append a query delimiter */
memcpy(my_session->sql + my_session->sql_index,
my_instance->query_delimiter,
my_instance->query_delimiter_size);
/* append the next query statement */
memcpy(my_session->sql + my_session->sql_index + my_instance->query_delimiter_size,
ptr,
strlen(ptr));
/* set new pointer for the buffer */
my_session->sql_index += (my_instance->query_delimiter_size + strlen(ptr));
}
gettimeofday(&my_session->last_statement_start, NULL);
} }
/* otherwise, append the statement with semicolon as a statement delimiter */
else
{
/* append a query delimiter */
memcpy(my_session->sql + my_session->sql_index,
my_instance->query_delimiter,
my_instance->query_delimiter_size);
/* append the next query statement */
memcpy(my_session->sql + my_session->sql_index + my_instance->query_delimiter_size,
ptr,
strlen(ptr));
/* set new pointer for the buffer */
my_session->sql_index += (my_instance->query_delimiter_size + strlen(ptr));
}
gettimeofday(&my_session->last_statement_start, NULL);
} }
} }
} }