summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <ramil/ram@mysql.com/ramil.myoffice.izhnet.ru>2007-05-18 12:08:07 +0500
committerunknown <ramil/ram@mysql.com/ramil.myoffice.izhnet.ru>2007-05-18 12:08:07 +0500
commit5b3b80b44f413925a33580bd4229a14b0d6836fa (patch)
tree1ae986c917186244ee7d08ad840caf48344d72e6 /sql
parent8ab53d5f4e9225d3d3d3509f8cd47c610406ed8e (diff)
downloadmariadb-git-5b3b80b44f413925a33580bd4229a14b0d6836fa.tar.gz
Fix for bug #28464: a string argument to 'limit ?' PS - replication fails
Problem: we may get syntactically incorrect queries in the binary log if we use a string value user variable executing a PS which contains '... limit ?' clause, e.g. prepare s from "select 1 limit ?"; set @a='qwe'; execute s using @a; Fix: raise an error in such cases. mysql-test/r/limit.result: Fix for bug #28464: a string argument to 'limit ?' PS - replication fails - test result mysql-test/t/limit.test: Fix for bug #28464: a string argument to 'limit ?' PS - replication fails - test case sql/item.cc: Fix for bug #28464: a string argument to 'limit ?' PS - replication fails - if Item_param::strict_type is set, check given and required types, return an error if not equal. sql/item.h: Fix for bug #28464: a string argument to 'limit ?' PS - replication fails - bool strict_type introduced, which indicates that a parameter value must be of the required_result_type type. - set_strict_type() function introduced to set required type. sql/sql_yacc.yy: Fix for bug #28464: a string argument to 'limit ?' PS - replication fails - as we accept only INTs in the 'limit' clause set parameter's required type.
Diffstat (limited to 'sql')
-rw-r--r--sql/item.cc3
-rw-r--r--sql/item.h9
-rw-r--r--sql/sql_yacc.yy3
3 files changed, 14 insertions, 1 deletions
diff --git a/sql/item.cc b/sql/item.cc
index 827c872adbc..155b2a962c8 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -2312,6 +2312,7 @@ default_set_param_func(Item_param *param,
Item_param::Item_param(unsigned pos_in_query_arg) :
+ strict_type(FALSE),
state(NO_VALUE),
item_result_type(STRING_RESULT),
/* Don't pretend to be a literal unless value for this item is set. */
@@ -2506,6 +2507,8 @@ bool Item_param::set_from_user_var(THD *thd, const user_var_entry *entry)
if (entry && entry->value)
{
item_result_type= entry->type;
+ if (strict_type && required_result_type != item_result_type)
+ DBUG_RETURN(1);
switch (entry->type) {
case REAL_RESULT:
set_double(*(double*)entry->value);
diff --git a/sql/item.h b/sql/item.h
index f38ce2f5db0..ced7586f099 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -1358,8 +1358,10 @@ class Item_param :public Item
char cnvbuf[MAX_FIELD_WIDTH];
String cnvstr;
Item *cnvitem;
-public:
+ bool strict_type;
+ enum Item_result required_result_type;
+public:
enum enum_item_param_state
{
NO_VALUE, NULL_VALUE, INT_VALUE, REAL_VALUE,
@@ -1487,6 +1489,11 @@ public:
Otherwise return FALSE.
*/
bool eq(const Item *item, bool binary_cmp) const;
+ void set_strict_type(enum Item_result result_type_arg)
+ {
+ strict_type= TRUE;
+ required_result_type= result_type_arg;
+ }
};
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 4a50a602121..7c45d692d95 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -6216,6 +6216,9 @@ limit_options:
;
limit_option:
param_marker
+ {
+ ((Item_param *) $1)->set_strict_type(INT_RESULT);
+ }
| ULONGLONG_NUM { $$= new Item_uint($1.str, $1.length); }
| LONG_NUM { $$= new Item_uint($1.str, $1.length); }
| NUM { $$= new Item_uint($1.str, $1.length); }