diff options
author | Praveenkumar Hulakund <praveenkumar.hulakund@oracle.com> | 2012-07-26 23:44:43 +0530 |
---|---|---|
committer | Praveenkumar Hulakund <praveenkumar.hulakund@oracle.com> | 2012-07-26 23:44:43 +0530 |
commit | 44cd81da86e41c6ac7114ef8dbd31c738eba095d (patch) | |
tree | 14220368ff99901cc53d16a698cd299cd1ea1635 /sql/sql_prepare.cc | |
parent | b6ecca263cc0b1bc974b2917e61b66793276396c (diff) | |
download | mariadb-git-44cd81da86e41c6ac7114ef8dbd31c738eba095d.tar.gz |
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.
Diffstat (limited to 'sql/sql_prepare.cc')
-rw-r--r-- | sql/sql_prepare.cc | 8 |
1 files changed, 8 insertions, 0 deletions
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 27e70aaf843..2afd4085c51 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -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)); if (param->state == Item_param::NO_VALUE) 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); + } } } /* |