List:Commits« Previous MessageNext Message »
From:<gshchepa Date:November 8 2007 10:12pm
Subject:bk commit into 5.1 tree (gshchepa:1.2607) BUG#28076
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 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-09 02:12:14+04:00, gshchepa@stripped +5 -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.

  mysql-test/include/mix1.inc@stripped, 2007-11-09 01:51:15+04:00, gshchepa@stripped +12 -0
    Added test case for bug #28076.

  mysql-test/r/innodb_mysql.result@stripped, 2007-11-09 01:51:25+04:00, gshchepa@stripped +9 -0
    Added test case for bug #28076.

  sql/item.cc@stripped, 2007-11-09 01:50:59+04:00, gshchepa@stripped +12 -2
    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.

  sql/item.h@stripped, 2007-11-09 01:51:08+04:00, gshchepa@stripped +14 -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.

  sql/item_cmpfunc.cc@stripped, 2007-11-09 01:51:13+04:00, gshchepa@stripped +11 -3
    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/include/mix1.inc b/mysql-test/include/mix1.inc
--- a/mysql-test/include/mix1.inc	2007-10-23 19:08:18 +05:00
+++ b/mysql-test/include/mix1.inc	2007-11-09 01:51:15 +04:00
@@ -1304,4 +1304,16 @@ if ($test_foreign_keys)
   DROP TABLE t1;
 }
 
+#
+# Bug #28076: inconsistent binary/varbinary comparison
+#
+
+--eval CREATE TABLE t1 (s1 BINARY(5), s2 VARBINARY(5)) ENGINE=$engine_type
+INSERT INTO t1 VALUES (0x41,0x41);
+SELECT HEX(s1), HEX(s2) FROM t1 WHERE s2 IN (SELECT s1 FROM t1);
+CREATE INDEX I1 ON t1 (s1);
+CREATE INDEX I2 ON t1 (s2);
+SELECT HEX(s1), HEX(s2) FROM t1 WHERE s2 IN (SELECT s1 FROM t1);
+DROP TABLE t1;
+
 --echo End of 5.1 tests
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-23 19:08:18 +05:00
+++ b/mysql-test/r/innodb_mysql.result	2007-11-09 01:51:25 +04:00
@@ -1535,4 +1535,13 @@ t2	CREATE TABLE `t2` (
 ) ENGINE=InnoDB DEFAULT CHARSET=latin1
 DROP TABLE t2;
 DROP TABLE t1;
+CREATE TABLE t1 (s1 BINARY(5), s2 VARBINARY(5)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (0x41,0x41);
+SELECT HEX(s1), HEX(s2) FROM t1 WHERE s2 IN (SELECT s1 FROM t1);
+HEX(s1)	HEX(s2)
+CREATE INDEX I1 ON t1 (s1);
+CREATE INDEX I2 ON t1 (s2);
+SELECT HEX(s1), HEX(s2) FROM t1 WHERE s2 IN (SELECT s1 FROM t1);
+HEX(s1)	HEX(s2)
+DROP TABLE t1;
 End of 5.1 tests
diff -Nrup a/sql/item.cc b/sql/item.cc
--- a/sql/item.cc	2007-10-28 01:23:52 +05:00
+++ b/sql/item.cc	2007-11-09 01:50:59 +04:00
@@ -6358,7 +6358,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:
@@ -6368,7 +6369,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:
@@ -6543,6 +6544,15 @@ my_decimal *Item_cache_str::val_decimal(
   else
     decimal_val= 0;
   return decimal_val;
+}
+
+
+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);
 }
 
 
diff -Nrup a/sql/item.h b/sql/item.h
--- a/sql/item.h	2007-10-21 22:47:23 +05:00
+++ b/sql/item.h	2007-11-09 01:51:08 +04:00
@@ -2637,7 +2637,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)
@@ -2699,8 +2699,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();
@@ -2709,6 +2720,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:22:32 +05:00
+++ b/sql/item_cmpfunc.cc	2007-11-09 01:51:13 +04:00
@@ -1424,9 +1424,17 @@ 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())))
-    return 1;
+  if (!args[0]->fixed && args[0]->fix_fields(thd, args) || !cache)
+  {
+    bool no_padding= FALSE;
+    if(args[0]->type() == FIELD_ITEM)
+    {
+      Field *field= ((Item_field *) args[0])->field;
+      no_padding= field->type() == MYSQL_TYPE_VARCHAR && !field->has_charset();
+    }
+    if (!(cache= Item_cache::get_cache(args[0]->result_type(), no_padding)))
+      return 1;
+  }
 
   cache->setup(args[0]);
   if (cache->cols() == 1)
Thread
bk commit into 5.1 tree (gshchepa:1.2607) BUG#28076gshchepa8 Nov