diff --git a/mysql-test/r/binlog.result b/mysql-test/r/binlog.result index 0a199c87545..e6c5e3222de 100644 --- a/mysql-test/r/binlog.result +++ b/mysql-test/r/binlog.result @@ -567,4 +567,19 @@ master-bin.000001 36585 Rotate 1 36629 master-bin.000002;pos=4 drop table t1; set global binlog_cache_size=@bcs; set session autocommit = @ac; +drop table if exists t1; +reset master; +create table t1 (a bigint unsigned, b bigint(20) unsigned); +prepare stmt from "insert into t1 values (?,?)"; +set @a= 9999999999999999; +set @b= 14632475938453979136; +execute stmt using @a, @b; +deallocate prepare stmt; +drop table t1; +show binlog events from 0; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 4 Format_desc 1 98 Server version, Binlog ver: 4 +master-bin.000001 98 Query 1 219 use `test`; create table t1 (a bigint unsigned, b bigint(20) unsigned) +master-bin.000001 219 Query 1 343 use `test`; insert into t1 values (9999999999999999,14632475938453979136) +master-bin.000001 343 Query 1 419 use `test`; drop table t1 End of 5.0 tests diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index f547654bed1..8845f011971 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -1693,4 +1693,20 @@ t1 CREATE TABLE `t1` ( `?` decimal(2,1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; +drop table if exists t1; +create table t1 (a bigint unsigned, b bigint(20) unsigned); +prepare stmt from "insert into t1 values (?,?)"; +set @a= 9999999999999999; +set @b= 14632475938453979136; +insert into t1 values (@a, @b); +select * from t1 where a = @a and b = @b; +a b +9999999999999999 14632475938453979136 +execute stmt using @a, @b; +select * from t1 where a = @a and b = @b; +a b +9999999999999999 14632475938453979136 +9999999999999999 14632475938453979136 +deallocate prepare stmt; +drop table t1; End of 5.0 tests. diff --git a/mysql-test/t/binlog.test b/mysql-test/t/binlog.test index 5d1399925c3..b35c81b3b18 100644 --- a/mysql-test/t/binlog.test +++ b/mysql-test/t/binlog.test @@ -106,4 +106,21 @@ drop table t1; set global binlog_cache_size=@bcs; set session autocommit = @ac; +# +# Bug#33798: prepared statements improperly handle large unsigned ints +# +--disable_warnings +drop table if exists t1; +--enable_warnings +reset master; +create table t1 (a bigint unsigned, b bigint(20) unsigned); +prepare stmt from "insert into t1 values (?,?)"; +set @a= 9999999999999999; +set @b= 14632475938453979136; +execute stmt using @a, @b; +deallocate prepare stmt; +drop table t1; +--replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/ /Server ver: [^,]*,/Server version,/ +show binlog events from 0; + --echo End of 5.0 tests diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test index c1505ffd645..3f4b37f13f4 100644 --- a/mysql-test/t/ps.test +++ b/mysql-test/t/ps.test @@ -1807,4 +1807,21 @@ execute stmt using @a; show create table t1; drop table t1; +# +# Bug#33798: prepared statements improperly handle large unsigned ints +# +--disable_warnings +drop table if exists t1; +--enable_warnings +create table t1 (a bigint unsigned, b bigint(20) unsigned); +prepare stmt from "insert into t1 values (?,?)"; +set @a= 9999999999999999; +set @b= 14632475938453979136; +insert into t1 values (@a, @b); +select * from t1 where a = @a and b = @b; +execute stmt using @a, @b; +select * from t1 where a = @a and b = @b; +deallocate prepare stmt; +drop table t1; + --echo End of 5.0 tests. diff --git a/sql/item.cc b/sql/item.cc index 713e7709bcb..ffb18054750 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -2580,6 +2580,7 @@ bool Item_param::set_from_user_var(THD *thd, const user_var_entry *entry) if (entry && entry->value) { item_result_type= entry->type; + unsigned_flag= entry->unsigned_flag; if (strict_type && required_result_type != item_result_type) DBUG_RETURN(1); switch (item_result_type) { @@ -2875,7 +2876,10 @@ const String *Item_param::query_val_str(String* str) const { switch (state) { case INT_VALUE: - str->set(value.integer, &my_charset_bin); + if (unsigned_flag) + str->set((ulonglong) value.integer, &my_charset_bin); + else + str->set(value.integer, &my_charset_bin); break; case REAL_VALUE: str->set(value.real, NOT_FIXED_DEC, &my_charset_bin);