MXS-1702: Canonicalize negative numbers

The new canonicalization function now processes negative numbers
correctly. It uses a look-behind operation to detect whether the operation
is a negation of a number or a subtraction from another value.
This commit is contained in:
Markus Mäkelä
2018-03-16 08:48:48 +02:00
parent 75fadd711a
commit 8d3f02b8a4

View File

@ -1254,6 +1254,30 @@ static std::pair<bool, mxs::Buffer::iterator> probe_number(mxs::Buffer::iterator
return rval; return rval;
} }
bool is_negation(const std::string& str)
{
bool rval = false;
if (!str.empty() && str[str.size() - 1] == '-')
{
// Possibly a negative number
rval = true;
for (auto it = std::next(str.rbegin()); it != str.rend(); it++)
{
if (!isspace(*it))
{
/** If we find a previously converted value, we know that it
* is not a negation but a subtraction. */
rval = *it != '?';
break;
}
}
}
return rval;
}
char* modutil_get_new_canonical(GWBUF* querybuf) char* modutil_get_new_canonical(GWBUF* querybuf)
{ {
std::string rval; std::string rval;
@ -1267,8 +1291,6 @@ char* modutil_get_new_canonical(GWBUF* querybuf)
BACKTICK BACKTICK
} my_state = NONE; } my_state = NONE;
char prev = ' ';
for (auto it = std::next(buf.begin(), MYSQL_HEADER_LEN + 1); // Skip packet header and command for (auto it = std::next(buf.begin(), MYSQL_HEADER_LEN + 1); // Skip packet header and command
it != buf.end(); it++) it != buf.end(); it++)
{ {
@ -1281,6 +1303,8 @@ char* modutil_get_new_canonical(GWBUF* querybuf)
continue; continue;
} }
char prev = rval.empty() ? ' ' : rval[rval.size() - 1];
switch (my_state) switch (my_state)
{ {
case BACKTICK: case BACKTICK:
@ -1318,6 +1342,11 @@ char* modutil_get_new_canonical(GWBUF* querybuf)
if (num_end.first) if (num_end.first)
{ {
if (is_negation(rval))
{
// Remove the sign
rval.resize(rval.size() - 1);
}
rval += '?'; rval += '?';
it = num_end.second; it = num_end.second;
continue; continue;
@ -1342,8 +1371,6 @@ char* modutil_get_new_canonical(GWBUF* querybuf)
break; break;
} }
prev = *it;
} }
buf.release(); buf.release();