diff options
author | unknown <ramil/ram@mysql.com/ramil.myoffice.izhnet.ru> | 2007-05-18 12:08:07 +0500 |
---|---|---|
committer | unknown <ramil/ram@mysql.com/ramil.myoffice.izhnet.ru> | 2007-05-18 12:08:07 +0500 |
commit | 5b3b80b44f413925a33580bd4229a14b0d6836fa (patch) | |
tree | 1ae986c917186244ee7d08ad840caf48344d72e6 /sql | |
parent | 8ab53d5f4e9225d3d3d3509f8cd47c610406ed8e (diff) | |
download | mariadb-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.cc | 3 | ||||
-rw-r--r-- | sql/item.h | 9 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 3 |
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); } |