List:Commits« Previous MessageNext Message »
From:Davi Arnaut Date:February 28 2008 3:34pm
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-28 11:34:08-03:00, davi@stripped +11 -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-28 11:34:04-03:00, davi@stripped +9 -0
    Update test case result.

  mysql-test/r/ps.result@stripped, 2008-02-28 11:34:04-03:00, davi@stripped +30 -0
    Add test case result for Bug#33851

  mysql-test/r/rpl_user_variables.result@stripped, 2008-02-28 11:34:04-03:00, davi@stripped
+16 -0
    Test case result for replication of prepared statement with
    limit clause.

  mysql-test/t/limit.test@stripped, 2008-02-28 11:34:04-03:00, davi@stripped +12 -5
    Test parameters to limit clause.

  mysql-test/t/ps.test@stripped, 2008-02-28 11:34:05-03:00, davi@stripped +19 -0
    Add test case for Bug#33851

  mysql-test/t/rpl_user_variables.test@stripped, 2008-02-28 11:34:05-03:00, davi@stripped +17
-0
    Test replication of a parameter which value is converted.

  sql/item.cc@stripped, 2008-02-28 11:34:05-03:00, davi@stripped +8 -3
    Convert value to integer if it's a parameter to a limit clause.

  sql/item.h@stripped, 2008-02-28 11:34:05-03:00, davi@stripped +2 -7
    Flag signal that item is a parameter to a limit clause.

  sql/item_func.cc@stripped, 2008-02-28 11:34:06-03:00, davi@stripped +1 -1
    Const member functions, object is not mutated.

  sql/sql_class.h@stripped, 2008-02-28 11:34:06-03:00, davi@stripped +1 -1
    Const member functions, object is not mutated.

  sql/sql_yacc.yy@stripped, 2008-02-28 11:34:06-03:00, davi@stripped +1 -1
    Flag that item is a parameter to a limit clause.

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-28 11:34:04 -03:00
@@ -94,11 +94,20 @@ 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;
 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 -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-28 11:34:04 -03:00
@@ -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-28 11:34:04 -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-28 11:34:04 -03:00
@@ -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 -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-28 11:34:05 -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-28 11:34:05 -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-28 11:34:05 -03:00
@@ -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 *
   {
     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 -Nrup a/sql/item.h b/sql/item.h
--- a/sql/item.h	2008-02-21 14:58:27 -03:00
+++ b/sql/item.h	2008-02-28 11:34:05 -03:00
@@ -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 -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-28 11:34:06 -03:00
@@ -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);
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-28 11:34:06 -03:00
@@ -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 -Nrup a/sql/sql_yacc.yy b/sql/sql_yacc.yy
--- a/sql/sql_yacc.yy	2008-01-23 19:04:18 -02:00
+++ b/sql/sql_yacc.yy	2008-02-28 11:34:06 -03:00
@@ -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); }
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