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
No known key found for this signature in database
GPG Key ID: 72D48FCE664F7B19

View File

@ -1254,6 +1254,30 @@ static std::pair<bool, mxs::Buffer::iterator> probe_number(mxs::Buffer::iterator
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)
{
std::string rval;
@ -1267,8 +1291,6 @@ char* modutil_get_new_canonical(GWBUF* querybuf)
BACKTICK
} my_state = NONE;
char prev = ' ';
for (auto it = std::next(buf.begin(), MYSQL_HEADER_LEN + 1); // Skip packet header and command
it != buf.end(); it++)
{
@ -1281,6 +1303,8 @@ char* modutil_get_new_canonical(GWBUF* querybuf)
continue;
}
char prev = rval.empty() ? ' ' : rval[rval.size() - 1];
switch (my_state)
{
case BACKTICK:
@ -1318,6 +1342,11 @@ char* modutil_get_new_canonical(GWBUF* querybuf)
if (num_end.first)
{
if (is_negation(rval))
{
// Remove the sign
rval.resize(rval.size() - 1);
}
rval += '?';
it = num_end.second;
continue;
@ -1342,8 +1371,6 @@ char* modutil_get_new_canonical(GWBUF* querybuf)
break;
}
prev = *it;
}
buf.release();