summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/limit.result9
-rw-r--r--mysql-test/r/ps.result30
-rw-r--r--mysql-test/r/rpl_user_variables.result16
-rw-r--r--mysql-test/t/limit.test17
-rw-r--r--mysql-test/t/ps.test19
-rw-r--r--mysql-test/t/rpl_user_variables.test17
-rw-r--r--sql/item.cc11
-rw-r--r--sql/item.h9
-rw-r--r--sql/item_func.cc2
-rw-r--r--sql/sql_class.h2
-rw-r--r--sql/sql_yacc.yy2
11 files changed, 116 insertions, 18 deletions
diff --git a/mysql-test/r/limit.result b/mysql-test/r/limit.result
index 01d7d7ca218..2acf74162a4 100644
--- a/mysql-test/r/limit.result
+++ b/mysql-test/r/limit.result
@@ -94,6 +94,9 @@ drop table t1;
prepare s from "select 1 limit ?";
set @a='qwe';
execute s using @a;
+1
+set @a=-1;
+execute s using @a;
ERROR HY000: Incorrect arguments to EXECUTE
prepare s from "select 1 limit 1, ?";
execute s using @a;
@@ -101,4 +104,10 @@ ERROR HY000: Incorrect arguments to EXECUTE
prepare s from "select 1 limit ?, ?";
execute s using @a, @a;
ERROR HY000: Incorrect arguments to EXECUTE
+set @a=14632475938453979136;
+execute s using @a, @a;
+1
+set @a=-14632475938453979136;
+execute s using @a, @a;
+ERROR HY000: Incorrect arguments to EXECUTE
End of 5.0 tests
diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result
index 32f48a688e2..9aef58d5702 100644
--- a/mysql-test/r/ps.result
+++ b/mysql-test/r/ps.result
@@ -1861,4 +1861,34 @@ prepare stmt from "create view v1 as select * from t1";
ERROR 42S02: Table 'test.t1' doesn't exist
prepare stmt from "create view v1 as select * from `t1` `b`";
ERROR 42S02: Table 'test.t1' doesn't exist
+prepare stmt from "select ?";
+set @arg= 123456789.987654321;
+select @arg;
+@arg
+123456789.987654321
+execute stmt using @arg;
+?
+123456789.987654321
+set @arg= "string";
+select @arg;
+@arg
+string
+execute stmt using @arg;
+?
+string
+set @arg= 123456;
+select @arg;
+@arg
+123456
+execute stmt using @arg;
+?
+123456
+set @arg= cast(-12345.54321 as decimal(20, 10));
+select @arg;
+@arg
+-12345.5432100000
+execute stmt using @arg;
+?
+-12345.5432100000
+deallocate prepare stmt;
End of 5.0 tests.
diff --git a/mysql-test/r/rpl_user_variables.result b/mysql-test/r/rpl_user_variables.result
index 26ac2b26aaa..b8032a9c362 100644
--- a/mysql-test/r/rpl_user_variables.result
+++ b/mysql-test/r/rpl_user_variables.result
@@ -290,6 +290,22 @@ select * from t1;
a b
2 1
drop table t1;
+create table t1(a int);
+insert into t1 values (1),(2);
+prepare s1 from 'insert into t1 select a from t1 limit ?';
+set @x='1.1';
+execute s1 using @x;
+select * from t1;
+a
+1
+2
+1
+select * from t1;
+a
+1
+2
+1
+drop table t1;
End of 5.0 tests.
DROP FUNCTION IF EXISTS f1;
DROP FUNCTION IF EXISTS f2;
diff --git a/mysql-test/t/limit.test b/mysql-test/t/limit.test
index 286c04785ff..9cccca1adc3 100644
--- a/mysql-test/t/limit.test
+++ b/mysql-test/t/limit.test
@@ -76,15 +76,22 @@ drop table t1;
# Bug #28464: a string argument to 'limit ?' PS
#
-prepare s from "select 1 limit ?";
-set @a='qwe';
---error 1210
+prepare s from "select 1 limit ?";
+set @a='qwe';
+execute s using @a;
+set @a=-1;
+--error ER_WRONG_ARGUMENTS
execute s using @a;
prepare s from "select 1 limit 1, ?";
---error 1210
+--error ER_WRONG_ARGUMENTS
execute s using @a;
prepare s from "select 1 limit ?, ?";
---error 1210
+--error ER_WRONG_ARGUMENTS
+execute s using @a, @a;
+set @a=14632475938453979136;
+execute s using @a, @a;
+set @a=-14632475938453979136;
+--error ER_WRONG_ARGUMENTS
execute s using @a, @a;
--echo End of 5.0 tests
diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test
index 58ba901d82b..6c3f98f6a1a 100644
--- a/mysql-test/t/ps.test
+++ b/mysql-test/t/ps.test
@@ -1947,4 +1947,23 @@ prepare stmt from "create view v1 as select * from t1";
--error ER_NO_SUCH_TABLE
prepare stmt from "create view v1 as select * from `t1` `b`";
+#
+# Bug#33851: Passing UNSIGNED param to EXECUTE returns ERROR 1210
+#
+
+prepare stmt from "select ?";
+set @arg= 123456789.987654321;
+select @arg;
+execute stmt using @arg;
+set @arg= "string";
+select @arg;
+execute stmt using @arg;
+set @arg= 123456;
+select @arg;
+execute stmt using @arg;
+set @arg= cast(-12345.54321 as decimal(20, 10));
+select @arg;
+execute stmt using @arg;
+deallocate prepare stmt;
+
--echo End of 5.0 tests.
diff --git a/mysql-test/t/rpl_user_variables.test b/mysql-test/t/rpl_user_variables.test
index 8f8f0accbd1..70b708be258 100644
--- a/mysql-test/t/rpl_user_variables.test
+++ b/mysql-test/t/rpl_user_variables.test
@@ -337,6 +337,23 @@ select * from t1;
connection master;
drop table t1;
+#
+# Bug#33851: Passing UNSIGNED param to EXECUTE returns ERROR 1210
+#
+
+connection master;
+create table t1(a int);
+insert into t1 values (1),(2);
+prepare s1 from 'insert into t1 select a from t1 limit ?';
+set @x='1.1';
+execute s1 using @x;
+select * from t1;
+sync_slave_with_master;
+connection slave;
+select * from t1;
+connection master;
+drop table t1;
+
--echo End of 5.0 tests.
# This test uses a stored function that uses user-defined variables to return data
diff --git a/sql/item.cc b/sql/item.cc
index ffb18054750..a6a18e27b09 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -2385,7 +2385,7 @@ default_set_param_func(Item_param *param,
Item_param::Item_param(unsigned pos_in_query_arg) :
- strict_type(FALSE),
+ limit_clause_param(FALSE),
state(NO_VALUE),
item_result_type(STRING_RESULT),
/* Don't pretend to be a literal unless value for this item is set. */
@@ -2581,8 +2581,13 @@ bool Item_param::set_from_user_var(THD *thd, const user_var_entry *entry)
{
item_result_type= entry->type;
unsigned_flag= entry->unsigned_flag;
- if (strict_type && required_result_type != item_result_type)
- DBUG_RETURN(1);
+ if (limit_clause_param)
+ {
+ my_bool unused;
+ set_int(entry->val_int(&unused), MY_INT64_NUM_DECIMAL_DIGITS);
+ item_type= Item::INT_ITEM;
+ DBUG_RETURN(!unsigned_flag && value.integer < 0 ? 1 : 0);
+ }
switch (item_result_type) {
case REAL_RESULT:
set_double(*(double*)entry->value);
diff --git a/sql/item.h b/sql/item.h
index ae3e240778a..7dc9ed4ec10 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -1417,8 +1417,6 @@ class Item_param :public Item
char cnvbuf[MAX_FIELD_WIDTH];
String cnvstr;
Item *cnvitem;
- bool strict_type;
- enum Item_result required_result_type;
public:
enum enum_item_param_state
@@ -1548,11 +1546,8 @@ 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;
- }
+ /** Item is a argument to a limit clause. */
+ bool limit_clause_param;
};
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 639e069d24e..84dd3e3ebc6 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -3985,7 +3985,7 @@ double user_var_entry::val_real(my_bool *null_value)
/* Get the value of a variable as an integer */
-longlong user_var_entry::val_int(my_bool *null_value)
+longlong user_var_entry::val_int(my_bool *null_value) const
{
if ((*null_value= (value == 0)))
return LL(0);
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 97f2d07b1d3..4ca8947de30 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -2329,7 +2329,7 @@ class user_var_entry
bool unsigned_flag;
double val_real(my_bool *null_value);
- longlong val_int(my_bool *null_value);
+ longlong val_int(my_bool *null_value) const;
String *val_str(my_bool *null_value, String *str, uint decimals);
my_decimal *val_decimal(my_bool *null_value, my_decimal *result);
DTCollation collation;
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index a7c1060025d..04285fea227 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -6320,7 +6320,7 @@ limit_options:
limit_option:
param_marker
{
- ((Item_param *) $1)->set_strict_type(INT_RESULT);
+ ((Item_param *) $1)->limit_clause_param= TRUE;
}
| ULONGLONG_NUM { $$= new Item_uint($1.str, $1.length); }
| LONG_NUM { $$= new Item_uint($1.str, $1.length); }