List:Commits« Previous MessageNext Message »
From:Davi Arnaut Date:February 28 2008 3:59am
Subject:bk commit into 5.0 tree (davi:1.2591) BUG#33851
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of davi.  When davi does a push these changes
will be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2008-02-27 23:59:18-03:00, davi@stripped +9 -0
  Bug#33851 Passing UNSIGNED param to EXECUTE returns ERROR 1210
  
  The problem is that passing anything other than a integer to a limit
  clause in a prepared statement would fail. This limitation was introduced
  to avoid replication problems (e.g: replicating the statement with a
  string argument would cause a parse failure in the slave).
  
  The solution is to convert arguments to the limit clause to a integer
  value and use this converted value when persisting the query to the log.

  mysql-test/r/limit.result@stripped, 2008-02-27 23:59:14-03:00, davi@stripped +3 -3
    Update test case result.

  mysql-test/r/ps.result@stripped, 2008-02-27 23:59:14-03:00, davi@stripped +31 -1
    Add test case result for Bug#33851

  mysql-test/r/rpl_user_variables.result@stripped, 2008-02-27 23:59:15-03:00, davi@stripped
+16 -0
    Test case result for replication of prepared statement.

  mysql-test/t/limit.test@stripped, 2008-02-27 23:59:15-03:00, davi@stripped +0 -3
    Not a error anymore.

  mysql-test/t/ps.test@stripped, 2008-02-27 23:59:15-03:00, davi@stripped +19 -0
    Add test case for Bug#33851

  mysql-test/t/rpl_user_variables.test@stripped, 2008-02-27 23:59:16-03:00, davi@stripped +17
-0
    Test replication of a parameter which value is converted.

  sql/item.cc@stripped, 2008-02-27 23:59:16-03:00, davi@stripped +11 -12
    Convert the parameter value using the getter and setter methods
    for each type.

  sql/item_func.cc@stripped, 2008-02-27 23:59:16-03:00, davi@stripped +4 -4
    Const members functions, object is not mutated.

  sql/sql_class.h@stripped, 2008-02-27 23:59:16-03:00, davi@stripped +4 -4
    Const members functions, object is not mutated.

diff -Nrup a/mysql-test/r/limit.result b/mysql-test/r/limit.result
--- a/mysql-test/r/limit.result	2007-05-18 04:08:05 -03:00
+++ b/mysql-test/r/limit.result	2008-02-27 23:59:14 -03:00
@@ -94,11 +94,11 @@ drop table t1;
 prepare s from "select 1 limit ?";
 set @a='qwe';
 execute s using @a;
-ERROR HY000: Incorrect arguments to EXECUTE
+1
 prepare s from "select 1 limit 1, ?";
 execute s using @a;
-ERROR HY000: Incorrect arguments to EXECUTE
+1
 prepare s from "select 1 limit ?, ?";
 execute s using @a, @a;
-ERROR HY000: Incorrect arguments to EXECUTE
+1
 End of 5.0 tests
diff -Nrup a/mysql-test/r/ps.result b/mysql-test/r/ps.result
--- a/mysql-test/r/ps.result	2008-02-21 14:58:27 -03:00
+++ b/mysql-test/r/ps.result	2008-02-27 23:59:14 -03:00
@@ -1690,7 +1690,7 @@ execute stmt using @a;
 show create table t1;
 Table	Create Table
 t1	CREATE TABLE `t1` (
-  `?` decimal(2,1) default NULL
+  `?` decimal(2,1) NOT NULL default '0.0'
 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
 drop table t1;
 drop table if exists t1;
@@ -1861,4 +1861,34 @@ prepare stmt from "create view v1 as sel
 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 -Nrup a/mysql-test/r/rpl_user_variables.result
b/mysql-test/r/rpl_user_variables.result
--- a/mysql-test/r/rpl_user_variables.result	2007-05-24 07:35:42 -03:00
+++ b/mysql-test/r/rpl_user_variables.result	2008-02-27 23:59:15 -03:00
@@ -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 -Nrup a/mysql-test/t/limit.test b/mysql-test/t/limit.test
--- a/mysql-test/t/limit.test	2007-05-18 04:08:05 -03:00
+++ b/mysql-test/t/limit.test	2008-02-27 23:59:15 -03:00
@@ -78,13 +78,10 @@ drop table t1;
 
 prepare s from "select 1 limit ?"; 
 set @a='qwe'; 
---error 1210
 execute s using @a;
 prepare s from "select 1 limit 1, ?";
---error 1210
 execute s using @a;
 prepare s from "select 1 limit ?, ?";
---error 1210
 execute s using @a, @a;
 
 --echo End of 5.0 tests
diff -Nrup a/mysql-test/t/ps.test b/mysql-test/t/ps.test
--- a/mysql-test/t/ps.test	2008-02-21 14:58:27 -03:00
+++ b/mysql-test/t/ps.test	2008-02-27 23:59:15 -03:00
@@ -1947,4 +1947,23 @@ prepare stmt from "create view v1 as sel
 --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 -Nrup a/mysql-test/t/rpl_user_variables.test b/mysql-test/t/rpl_user_variables.test
--- a/mysql-test/t/rpl_user_variables.test	2007-05-24 07:35:42 -03:00
+++ b/mysql-test/t/rpl_user_variables.test	2008-02-27 23:59:16 -03:00
@@ -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 -Nrup a/sql/item.cc b/sql/item.cc
--- a/sql/item.cc	2008-02-08 08:55:54 -02:00
+++ b/sql/item.cc	2008-02-27 23:59:16 -03:00
@@ -2576,20 +2576,19 @@ bool Item_param::set_longdata(const char
 
 bool Item_param::set_from_user_var(THD *thd, const user_var_entry *entry)
 {
+  my_bool tmp;
   DBUG_ENTER("Item_param::set_from_user_var");
   if (entry && entry->value)
   {
-    item_result_type= entry->type;
+    item_result_type= strict_type ? required_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) {
     case REAL_RESULT:
-      set_double(*(double*)entry->value);
+      set_double(entry->val_real(&tmp));
       item_type= Item::REAL_ITEM;
       break;
     case INT_RESULT:
-      set_int(*(longlong*)entry->value, MY_INT64_NUM_DECIMAL_DIGITS);
+      set_int(entry->val_int(&tmp), MY_INT64_NUM_DECIMAL_DIGITS);
       item_type= Item::INT_ITEM;
       break;
     case STRING_RESULT:
@@ -2597,6 +2596,7 @@ bool Item_param::set_from_user_var(THD *
       CHARSET_INFO *fromcs= entry->collation.collation;
       CHARSET_INFO *tocs= thd->variables.collation_connection;
       uint32 dummy_offset;
+      String str;
 
       value.cs_info.character_set_of_placeholder= fromcs;
       /*
@@ -2613,18 +2613,17 @@ bool Item_param::set_from_user_var(THD *
       */
       item_type= Item::STRING_ITEM;
 
-      if (set_str((const char *)entry->value, entry->length))
+      entry->val_str(&tmp, &str, NOT_FIXED_DEC);
+      if (set_str(str.ptr(), str.length()))
         DBUG_RETURN(1);
       break;
     }
     case DECIMAL_RESULT:
     {
-      const my_decimal *ent_value= (const my_decimal *)entry->value;
-      my_decimal2decimal(ent_value, &decimal_value);
-      state= DECIMAL_VALUE;
-      decimals= ent_value->frac;
-      max_length= my_decimal_precision_to_length(ent_value->precision(),
-                                                 decimals, unsigned_flag);
+      String str;
+      const my_decimal *dval= (const my_decimal *) entry->value;
+      entry->val_str(&tmp, &str, dval->frac);
+      set_decimal(str.ptr(), str.length());
       item_type= Item::DECIMAL_ITEM;
       break;
     }
diff -Nrup a/sql/item_func.cc b/sql/item_func.cc
--- a/sql/item_func.cc	2008-01-17 15:13:30 -02:00
+++ b/sql/item_func.cc	2008-02-27 23:59:16 -03:00
@@ -3957,7 +3957,7 @@ Item_func_set_user_var::update_hash(void
 
 /* Get the value of a variable as a double */
 
-double user_var_entry::val_real(my_bool *null_value)
+double user_var_entry::val_real(my_bool *null_value) const
 {
   if ((*null_value= (value == 0)))
     return 0.0;
@@ -3985,7 +3985,7 @@ double user_var_entry::val_real(my_bool 
 
 /* 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);
@@ -4017,7 +4017,7 @@ longlong user_var_entry::val_int(my_bool
 /* Get the value of a variable as a string */
 
 String *user_var_entry::val_str(my_bool *null_value, String *str,
-				uint decimals)
+				uint decimals) const
 {
   if ((*null_value= (value == 0)))
     return (String*) 0;
@@ -4047,7 +4047,7 @@ String *user_var_entry::val_str(my_bool 
 
 /* Get the value of a variable as a decimal */
 
-my_decimal *user_var_entry::val_decimal(my_bool *null_value, my_decimal *val)
+my_decimal *user_var_entry::val_decimal(my_bool *null_value, my_decimal *val) const
 {
   if ((*null_value= (value == 0)))
     return 0;
diff -Nrup a/sql/sql_class.h b/sql/sql_class.h
--- a/sql/sql_class.h	2007-12-15 09:04:58 -02:00
+++ b/sql/sql_class.h	2008-02-27 23:59:16 -03:00
@@ -2328,10 +2328,10 @@ class user_var_entry
   Item_result type;
   bool unsigned_flag;
 
-  double val_real(my_bool *null_value);
-  longlong val_int(my_bool *null_value);
-  String *val_str(my_bool *null_value, String *str, uint decimals);
-  my_decimal *val_decimal(my_bool *null_value, my_decimal *result);
+  double val_real(my_bool *null_value) const;
+  longlong val_int(my_bool *null_value) const;
+  String *val_str(my_bool *null_value, String *str, uint decimals) const;
+  my_decimal *val_decimal(my_bool *null_value, my_decimal *result) const;
   DTCollation collation;
 };
 
Thread
bk commit into 5.0 tree (davi:1.2591) BUG#33851Davi Arnaut28 Feb
  • Re: bk commit into 5.0 tree (davi:1.2591) BUG#33851Konstantin Osipov28 Feb