Fix to multi-statement processing
Renamed is_mysql_comment_start to is_mysql_statement_end because it checks whether a statement truly ends instead of just checking comment block starts. The calculations for buffer length in readwritesplit now use the payload size instead of the buffer size.
This commit is contained in:
parent
8b6595aa68
commit
76f06572ed
@ -893,39 +893,53 @@ char* strnchr_esc_mysql(char* ptr, char c, int len)
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the start of the token is the start of a MySQL style comment block
|
||||
* @param ptr String with at least two non-null characters in it
|
||||
* @return True if the token starts a comment block
|
||||
* @brief Check if the string is the final part of a valid SQL statement
|
||||
*
|
||||
* This function checks whether the string pointed by @p start contains any
|
||||
* tokens that are interpreted as executable commands.
|
||||
* @param start String containing the statement
|
||||
* @param len Length of the string
|
||||
* @return True if statement contains no executable parts
|
||||
*/
|
||||
bool is_mysql_comment_start(const char* start, int len)
|
||||
bool is_mysql_statement_end(const char* start, int len)
|
||||
{
|
||||
const char *ptr = start;
|
||||
bool rval = false;
|
||||
|
||||
while (ptr < start + len && (isspace(*ptr) || *ptr == ';'))
|
||||
{
|
||||
ptr++;
|
||||
}
|
||||
|
||||
switch (*ptr)
|
||||
if (ptr < start + len)
|
||||
{
|
||||
case '-':
|
||||
if (*(ptr + 1) == '-' && isspace(*(ptr + 2)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
switch (*ptr)
|
||||
{
|
||||
case '-':
|
||||
if (ptr < start + len - 2 && *(ptr + 1) == '-' && isspace(*(ptr + 2)))
|
||||
{
|
||||
rval = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case '#':
|
||||
return true;
|
||||
case '#':
|
||||
rval = true;
|
||||
break;
|
||||
|
||||
case '/':
|
||||
if (*(ptr + 1) == '*')
|
||||
{
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case '/':
|
||||
if (ptr < start + len - 1 && *(ptr + 1) == '*')
|
||||
{
|
||||
rval = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
else
|
||||
{
|
||||
rval = true;
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -71,7 +71,7 @@ mxs_pcre2_result_t modutil_mysql_wildcard_match(const char* pattern, const char*
|
||||
/** Character and token searching functions */
|
||||
char* strnchr_esc(char* ptr, char c, int len);
|
||||
char* strnchr_esc_mysql(char* ptr, char c, int len);
|
||||
bool is_mysql_comment_start(const char* start, int len);
|
||||
bool is_mysql_statement_end(const char* start, int len);
|
||||
bool is_mysql_sp_end(const char* start, int len);
|
||||
|
||||
#endif
|
||||
|
@ -5362,7 +5362,8 @@ static void check_for_multi_stmt(ROUTER_CLIENT_SES* rses, GWBUF *buf,
|
||||
packet_type == MYSQL_COM_QUERY && rses->forced_node != rses->rses_master_ref)
|
||||
{
|
||||
char *ptr, *data = GWBUF_DATA(buf) + 5;
|
||||
int buflen = GWBUF_LENGTH(buf) - 5;
|
||||
/** Payload size without command byte */
|
||||
int buflen = gw_mysql_get_byte3((uint8_t*)GWBUF_DATA(buf)) - 1;
|
||||
|
||||
if ((ptr = strnchr_esc_mysql(data, ';', buflen)))
|
||||
{
|
||||
@ -5374,7 +5375,7 @@ static void check_for_multi_stmt(ROUTER_CLIENT_SES* rses, GWBUF *buf,
|
||||
|
||||
if (ptr)
|
||||
{
|
||||
if (ptr < data + buflen && !is_mysql_comment_start(ptr, ptr - data))
|
||||
if (ptr < data + buflen && !is_mysql_statement_end(ptr, buflen - (ptr - data)))
|
||||
{
|
||||
rses->forced_node = rses->rses_master_ref;
|
||||
MXS_INFO("Multi-statement query, routing all future queries to master.");
|
||||
|
Loading…
x
Reference in New Issue
Block a user