Commit bb64579d authored by Praveenkumar Hulakund's avatar Praveenkumar Hulakund

BUG#13868860 - LIMIT '5' IS EXECUTED WITHOUT ERROR WHEN '5'

               IS PLACE HOLDER AND USE SERVER-SIDE 

Analysis:
LIMIT always takes nonnegative integer constant values. 

http://dev.mysql.com/doc/refman/5.6/en/select.html

So parsing of value '5' for LIMIT in SELECT fails.

But, within prepared statement, LIMIT parameters can be
specified using '?' markers. Value for the parameter can
be supplied while executing the prepared statement.

Passing string values, float or double value for LIMIT
works well from CLI. Because, while setting the value
for the parameters from the variable list (added using
SET), if the value is for parameter LIMIT then its 
converted to integer value. 

But, when prepared statement is executed from the other
interfaces as J connectors, or C applications etc.
The value for the parameters are sent to the server
with execute command. Each item in log has value and
the data TYPE. So, While setting parameter value
from this log, value is set to all the parameters
with the same data type as passed.
But here logic to convert value to integer type
if its for LIMIT parameter is missing.
Because of this,string '5' is set to LIMIT.
And the same is logged into the binlog file too. 

Fix:
When executing prepared statement having parameter for
CLI it worked fine, as the value set for the parameter
is converted to integer. And this failed in other 
interfaces as J connector,C Applications etc as this 
conversion is missing.

So, as a fix added check while setting value for the
parameters. If the parameter is for LIMIT value then
its converted to integer value.
parent c6c8645a
...@@ -785,6 +785,14 @@ static bool insert_params_with_log(Prepared_statement *stmt, uchar *null_array, ...@@ -785,6 +785,14 @@ static bool insert_params_with_log(Prepared_statement *stmt, uchar *null_array,
param->set_param_func(param, &read_pos, (uint) (data_end - read_pos)); param->set_param_func(param, &read_pos, (uint) (data_end - read_pos));
if (param->state == Item_param::NO_VALUE) if (param->state == Item_param::NO_VALUE)
DBUG_RETURN(1); DBUG_RETURN(1);
if (param->limit_clause_param && param->item_type != Item::INT_ITEM)
{
param->set_int(param->val_int(), MY_INT64_NUM_DECIMAL_DIGITS);
param->item_type= Item::INT_ITEM;
if (!param->unsigned_flag && param->value.integer < 0)
DBUG_RETURN(1);
}
} }
} }
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment