List:Commits« Previous MessageNext Message »
From:<gshchepa Date:November 9 2007 11:43pm
Subject:bk commit into 5.0 tree (gshchepa:1.2564) BUG#28076
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of uchum. When uchum 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, 2007-11-10 03:43:29+04:00, gshchepa@stripped +6 -0
  Fixed bug #28076: inconsistent binary/varbinary comparison.
  
  After the adding of an index the <VARBINARY> IN (SELECT <BINARY> ...)
  clause returned a wrong result: the VARBINARY value was illegally padded
  with zero bytes to the length of the BINARY column for the index search.
  (<VARBINARY>, ...) IN (SELECT <BINARY>, ... ) clauses are affected too.

  mysql-test/r/innodb_mysql.result@stripped, 2007-11-10 03:43:06+04:00, gshchepa@stripped +13 -0
    Added test case for bug #28076.

  mysql-test/t/innodb_mysql.test@stripped, 2007-11-10 03:43:05+04:00, gshchepa@stripped +18 -0
    Added test case for bug #28076.

  sql/field.h@stripped, 2007-11-10 03:43:02+04:00, gshchepa@stripped +9 -0
    Fixed bug #28076.
    The Field::no_padding method has been added to notice
    where it is not safe to store string representation of
    the field value into a CHARACTER field of the longer length.
    The Field_varstring::no_padding method has been overloaded
    to return TRUE for VARBINARY fields.

  sql/item.cc@stripped, 2007-11-10 03:43:03+04:00, gshchepa@stripped +14 -3
    Fixed bug #28076.
    An implementation of the overloaded Item_cache_str::save_in_field
    method has been added to check cached values for an illegal padding
    before the saving in a field.
    The Item_cache_row::allocate  method has been modified to
    calculate values of the padding flag
    (see Item_cache_str::error_on_padding).

  sql/item.h@stripped, 2007-11-10 03:43:04+04:00, gshchepa@stripped +21 -2
    Fixed bug #28076.
    The Item_cache_str::error_on_padding flag has been added and the
    Item_cache_str::save_in_field method has been overloaded to prevent
    cached values from an illegal padding when saving in fields.
    The Item::no_padding method has been added (shortcut to the
    Field::no_padding method).

  sql/item_cmpfunc.cc@stripped, 2007-11-10 03:43:05+04:00, gshchepa@stripped +2 -1
    Fixed bug #28076.
    The Item_in_optimizer::fix_left method has been modified to
    calculate values of the padding flag
    (see Item_cache_str::error_on_padding).

diff -Nrup a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result
--- a/mysql-test/r/innodb_mysql.result	2007-10-11 00:15:39 +05:00
+++ b/mysql-test/r/innodb_mysql.result	2007-11-10 03:43:06 +04:00
@@ -1211,4 +1211,17 @@ a	b
 3	2
 1	1
 DROP TABLE t1;
+CREATE TABLE t1 (s1 BINARY(5), s2 VARBINARY(5)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (0x41,0x41);
+SELECT s1, s2 FROM t1 WHERE s2 IN (SELECT s1 FROM t1);
+s1	s2
+SELECT s1, s2 FROM t1 WHERE (s2, 10) IN (SELECT s1, 10 FROM t1);
+s1	s2
+CREATE INDEX I1 ON t1 (s1);
+CREATE INDEX I2 ON t1 (s2);
+SELECT s1, s2 FROM t1 WHERE s2 IN (SELECT s1 FROM t1);
+s1	s2
+SELECT s1, s2 FROM t1 WHERE (s2, 10) IN (SELECT s1, 10 FROM t1);
+s1	s2
+DROP TABLE t1;
 End of 5.0 tests
diff -Nrup a/mysql-test/t/innodb_mysql.test b/mysql-test/t/innodb_mysql.test
--- a/mysql-test/t/innodb_mysql.test	2007-10-11 00:15:55 +05:00
+++ b/mysql-test/t/innodb_mysql.test	2007-11-10 03:43:05 +04:00
@@ -960,4 +960,22 @@ SELECT * FROM t1 ORDER BY b DESC, a ASC;
 
 DROP TABLE t1;
 
+#
+# Bug #28076: inconsistent binary/varbinary comparison
+#
+
+CREATE TABLE t1 (s1 BINARY(5), s2 VARBINARY(5)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (0x41,0x41);
+
+SELECT s1, s2 FROM t1 WHERE s2 IN (SELECT s1 FROM t1);
+SELECT s1, s2 FROM t1 WHERE (s2, 10) IN (SELECT s1, 10 FROM t1);
+
+CREATE INDEX I1 ON t1 (s1);
+CREATE INDEX I2 ON t1 (s2);
+
+SELECT s1, s2 FROM t1 WHERE s2 IN (SELECT s1 FROM t1);
+SELECT s1, s2 FROM t1 WHERE (s2, 10) IN (SELECT s1, 10 FROM t1);
+
+DROP TABLE t1;
+
 --echo End of 5.0 tests
diff -Nrup a/sql/field.h b/sql/field.h
--- a/sql/field.h	2007-10-10 18:26:00 +05:00
+++ b/sql/field.h	2007-11-10 03:43:02 +04:00
@@ -366,6 +366,13 @@ public:
     DBUG_ASSERT(0);
     return GEOM_GEOMETRY;
   }
+  /*
+    TRUE if a string value of this field should
+    not be padded with a padding byte/char when
+    storing to another field.
+  */
+  virtual bool no_padding() const { return FALSE; }
+
   friend bool reopen_table(THD *,struct st_table *,bool);
   friend int cre_myisam(my_string name, register TABLE *form, uint options,
 			ulonglong auto_increment_value);
@@ -1188,6 +1195,8 @@ public:
   Field *new_key_field(MEM_ROOT *root, struct st_table *new_table,
                        char *new_ptr, uchar *new_null_ptr,
                        uint new_null_bit);
+  bool no_padding() const { return !has_charset();
+  }
 };
 
 
diff -Nrup a/sql/item.cc b/sql/item.cc
--- a/sql/item.cc	2007-10-23 20:51:36 +05:00
+++ b/sql/item.cc	2007-11-10 03:43:03 +04:00
@@ -6259,7 +6259,8 @@ bool field_is_equal_to_item(Field *field
   return result == field->val_real();
 }
 
-Item_cache* Item_cache::get_cache(Item_result type)
+Item_cache* Item_cache::get_cache(Item_result type,
+                                  bool error_on_padding/*= FALSE*/)
 {
   switch (type) {
   case INT_RESULT:
@@ -6269,7 +6270,7 @@ Item_cache* Item_cache::get_cache(Item_r
   case DECIMAL_RESULT:
     return new Item_cache_decimal();
   case STRING_RESULT:
-    return new Item_cache_str();
+    return new Item_cache_str(error_on_padding);
   case ROW_RESULT:
     return new Item_cache_row();
   default:
@@ -6447,6 +6448,15 @@ my_decimal *Item_cache_str::val_decimal(
 }
 
 
+int Item_cache_str::save_in_field(Field *field, bool no_conversions)
+{
+  if (error_on_padding && field->type() == MYSQL_TYPE_STRING &&
+      value->length() < field->field_length)
+    return 1;
+  return Item_cache::save_in_field(field, no_conversions);
+}
+
+
 bool Item_cache_row::allocate(uint num)
 {
   item_count= num;
@@ -6465,7 +6475,8 @@ bool Item_cache_row::setup(Item * item)
   {
     Item *el= item->element_index(i);
     Item_cache *tmp;
-    if (!(tmp= values[i]= Item_cache::get_cache(el->result_type())))
+    if (!(tmp= values[i]= Item_cache::get_cache(el->result_type(),
+                                                el->no_padding())))
       return 1;
     tmp->setup(el);
   }
diff -Nrup a/sql/item.h b/sql/item.h
--- a/sql/item.h	2007-11-08 12:46:55 +04:00
+++ b/sql/item.h	2007-11-10 03:43:04 +04:00
@@ -873,6 +873,12 @@ public:
   virtual Field::geometry_type get_geometry_type() const
     { return Field::GEOM_GEOMETRY; };
   String *check_well_formed_result(String *str, bool send_error= 0);
+  /*
+    TRUE if a string value of this field should
+    not be padded with a padding byte/char when
+    storing to a field.
+  */
+  virtual bool no_padding() const { return FALSE; }
 };
 
 
@@ -1345,6 +1351,7 @@ public:
     DBUG_ASSERT(field_type() == MYSQL_TYPE_GEOMETRY);
     return field->get_geometry_type();
   }
+  bool no_padding() const { return field->no_padding(); }
   friend class Item_default_value;
   friend class Item_insert_value;
   friend class st_select_lex_unit;
@@ -2469,7 +2476,7 @@ public:
   };
   virtual void store(Item *)= 0;
   enum Type type() const { return CACHE_ITEM; }
-  static Item_cache* get_cache(Item_result type);
+  static Item_cache* get_cache(Item_result type, bool error_on_padding= FALSE);
   table_map used_tables() const { return used_table_map; }
   virtual void keep_array() {}
   // to prevent drop fixed flag (no need parent cleanup call)
@@ -2531,8 +2538,19 @@ class Item_cache_str: public Item_cache
 {
   char buffer[STRING_BUFFER_USUAL_SIZE];
   String *value, value_buff;
+  /*
+    Item_cache_str may be used as a temporary storage for key values.
+    error_on_padding means whether this key may be padded by a padding
+    character or not.
+    For example, a VARBINARY column value may be used as a key for an
+    index search through a BINARY column. The error_on_padding value
+    prevents cached value from padding of VARBINARY to a length of
+    the BINARY column.
+  */
+  bool error_on_padding;
 public:
-  Item_cache_str(): Item_cache(), value(0) { }
+  explicit Item_cache_str(bool error_on_padding= FALSE):
+    Item_cache(), value(0), error_on_padding(error_on_padding) {}
 
   void store(Item *item);
   double val_real();
@@ -2541,6 +2559,7 @@ public:
   my_decimal *val_decimal(my_decimal *);
   enum Item_result result_type() const { return STRING_RESULT; }
   CHARSET_INFO *charset() const { return value->charset(); };
+  int save_in_field(Field *field, bool no_conversions);
 };
 
 class Item_cache_row: public Item_cache
diff -Nrup a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
--- a/sql/item_cmpfunc.cc	2007-10-13 11:12:12 +05:00
+++ b/sql/item_cmpfunc.cc	2007-11-10 03:43:05 +04:00
@@ -1373,7 +1373,8 @@ longlong Item_func_truth::val_int()
 bool Item_in_optimizer::fix_left(THD *thd, Item **ref)
 {
   if (!args[0]->fixed && args[0]->fix_fields(thd, args) ||
-      !cache && !(cache= Item_cache::get_cache(args[0]->result_type())))
+      !cache && !(cache= Item_cache::get_cache(args[0]->result_type(),
+                                               args[0]->no_padding())))
     return 1;
 
   cache->setup(args[0]);
Thread
bk commit into 5.0 tree (gshchepa:1.2564) BUG#28076gshchepa10 Nov