MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:eugene Date:August 20 2006 8:24pm
Subject:bk commit into 5.0 tree (evgen:1.2263) BUG#21475
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of evgen. When evgen 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, 2006-08-21 00:23:57+04:00, evgen@stripped +6 -0
  Fixed bug#21475: Wrongly applied constant propagation leads to a false comparison.
  
  A date can be represented as an int (like 20060101) and as a string (like
  "2006.01.01"). When a DATE/TIME field is compared in one SELECT against both
  representations the constant propagation mechanism leads to comparison
  of DATE as a string and DATE as an int. In this example it compares 2006 and
  20060101 integers. Obviously it fails comparison although they represents the
  same date.
  
  
  Now the Item_bool_func2::fix_length_and_dec() function sets the comparison
  context for items being compared. I.e. if items compared as strings the
  comparison context is STRING.
  The constant propagation mechanism now doesn't mix items used in different
  comparison contexts. The context check is done in the
  Item_field::equal_fields_propagator() and in the change_cond_ref_to_const() 
  functions.
  
  Also the better fix for bug 21159 is introduced.

  mysql-test/r/type_datetime.result@stripped, 2006-08-21 00:12:37+04:00, evgen@stripped +11 -0
    Added a test case for bug#21475: Wrongly applied constant propagation leads to a false comparison.

  mysql-test/t/type_datetime.test@stripped, 2006-08-21 00:12:09+04:00, evgen@stripped +11 -0
    Added a test case for bug#21475: Wrongly applied constant propagation leads to a false comparison.

  sql/item.cc@stripped, 2006-08-21 00:20:43+04:00, evgen@stripped +12 -1
    Fixed bug#21475: Wrongly applied constant propagation leads to a false comparison.
    The constant propagation mechanism now doesn't mix items used in different
    comparison contexts. The context check is done in the
    Item_field::equal_fields_propagator() function.

  sql/item.h@stripped, 2006-08-21 00:18:57+04:00, evgen@stripped +1 -1
    Fixed bug#21475: Wrongly applied constant propagation leads to a false comparison.
    To the Item class a new field called cmp_context is added.
    It represents the comparison context of an item.

  sql/item_cmpfunc.cc@stripped, 2006-08-21 00:18:20+04:00, evgen@stripped +4 -1
    Fixed bug#21475: Wrongly applied constant propagation leads to a false comparison.
    Now the Item_bool_func2::fix_length_and_dec() function sets the comparison
    context for items being compared.

  sql/sql_select.cc@stripped, 2006-08-21 00:16:44+04:00, evgen@stripped +4 -16
    Fixed bug#21475: Wrongly applied constant propagation leads to a false comparison.
    The constant propagation mechanism now doesn't mix items used in different
    comparison contexts. The check is done in the change_cond_ref_to_const() function.

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	evgen
# Host:	moonbone.local
# Root:	/work/21475-bug-5.0-opt-mysql

--- 1.230/sql/item.cc	2006-08-21 00:24:01 +04:00
+++ 1.231/sql/item.cc	2006-08-21 00:24:01 +04:00
@@ -3777,7 +3777,18 @@
   Item *item= 0;
   if (item_equal)
     item= item_equal->get_const();
-  if (!item)
+  /*
+    Disable const propagation for items used in different comparison contexts.
+    This must be done because, for example, Item_hex_string->val_int() is not
+    the same as (Item_hex_string->val_str() in BINARY column)->val_int().
+    We cannot simply disable the replacement in a particular context (
+    e.g. <bin_col> = <int_col> AND <bin_col> = <hex_string>) since
+    Items don't know the context they are in and there are functions like 
+    IF (<hex_string>, 'yes', 'no').
+    The same problem occurs when comparing a DATE/TIME field with a
+    DATE/TIME represented as an int and as a string.
+  */
+  if (!item || item->cmp_context != cmp_context)
     item= this;
   return item;
 }

--- 1.205/sql/item.h	2006-08-21 00:24:01 +04:00
+++ 1.206/sql/item.h	2006-08-21 00:24:01 +04:00
@@ -465,7 +465,7 @@
   my_bool with_subselect;               /* If this item is a subselect or some
                                            of its arguments is or contains a
                                            subselect */
-
+  Item_result cmp_context;              /* Comparison context */
   // alloc & destruct is done as start of select using sql_alloc
   Item();
   /*

--- 1.214/sql/item_cmpfunc.cc	2006-08-21 00:24:01 +04:00
+++ 1.215/sql/item_cmpfunc.cc	2006-08-21 00:24:01 +04:00
@@ -405,7 +405,8 @@
       agg_arg_charsets(coll, args, 2, MY_COLL_CMP_CONV, 1))
     return;
     
- 
+  args[0]->cmp_context= args[1]->cmp_context=
+    item_cmp_type(args[0]->result_type(), args[1]->result_type());
   // Make a special case of compare with fields to get nicer DATE comparisons
 
   if (functype() == LIKE_FUNC)  // Disable conversion in case of LIKE function.
@@ -426,6 +427,7 @@
         {
           cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
                            INT_RESULT);		// Works for all types.
+          args[0]->cmp_context= args[1]->cmp_context= INT_RESULT;
           return;
         }
       }
@@ -440,6 +442,7 @@
         {
           cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
                            INT_RESULT); // Works for all types.
+          args[0]->cmp_context= args[1]->cmp_context= INT_RESULT;
           return;
         }
       }

--- 1.444/sql/sql_select.cc	2006-08-21 00:24:01 +04:00
+++ 1.445/sql/sql_select.cc	2006-08-21 00:24:01 +04:00
@@ -6516,23 +6516,9 @@
         field_item= (Item_field*) right_item;
         const_item= left_item;
       }
-      /* 
-        Disable const propagation for Item_hex_string.
-        This must be done because Item_hex_string->val_int() is not
-        the same as (Item_hex_string->val_str() in BINARY column)->val_int().
-        We cannot simply disable the replacement in a particular context (
-        e.g. <bin_col> = <int_col> AND <bin_col> = <hex_string>) since
-        Items don't know the context they are in and there are functions like 
-        IF (<hex_string>, 'yes', 'no').
-        Note that this will disable some valid cases as well 
-        (e.g. : <bin_col> = <hex_string> AND <bin_col2> = <bin_col>) but 
-        there's no way to distinguish the valid cases without having the
-        Item's parent say something like : Item->set_context(Item::STRING_RESULT)
-        and have all the Items that contain other Items do that consistently.
-      */
+
       if (const_item &&
-          field_item->result_type() == const_item->result_type() &&
-          const_item->type() != Item::VARBIN_ITEM)
+          field_item->result_type() == const_item->result_type())
       {
         bool copyfl;
 
@@ -7188,6 +7174,7 @@
   Item_func::Functype functype=  func->functype();
 
   if (right_item->eq(field,0) && left_item != value &&
+      right_item->cmp_context == field->cmp_context &&
       (left_item->result_type() != STRING_RESULT ||
        value->result_type() != STRING_RESULT ||
        left_item->collation.collation == value->collation.collation))
@@ -7209,6 +7196,7 @@
     }
   }
   else if (left_item->eq(field,0) && right_item != value &&
+           left_item->cmp_context == field->cmp_context &&
            (right_item->result_type() != STRING_RESULT ||
             value->result_type() != STRING_RESULT ||
             right_item->collation.collation == value->collation.collation))

--- 1.31/mysql-test/r/type_datetime.result	2006-08-21 00:24:01 +04:00
+++ 1.32/mysql-test/r/type_datetime.result	2006-08-21 00:24:01 +04:00
@@ -168,3 +168,14 @@
 0000-00-00 00:00:00
 0000-00-00 00:00:00
 drop table t1;
+CREATE TABLE t1(a DATETIME NOT NULL);
+INSERT INTO t1 VALUES ('20060606155555');
+SELECT a FROM t1 WHERE a=(SELECT MAX(a) FROM t1) AND (a="20060606155555");
+a
+2006-06-06 15:55:55
+PREPARE s FROM 'SELECT a FROM t1 WHERE a=(SELECT MAX(a) FROM t1) AND (a="20060606155555")';
+EXECUTE s;
+a
+2006-06-06 15:55:55
+DROP PREPARE s;
+DROP TABLE t1;

--- 1.18/mysql-test/t/type_datetime.test	2006-08-21 00:24:01 +04:00
+++ 1.19/mysql-test/t/type_datetime.test	2006-08-21 00:24:01 +04:00
@@ -114,3 +114,14 @@
 drop table t1;
 
 # End of 4.1 tests
+
+#
+# Bug#21475: Wrongly applied constant propagation leads to a false comparison.
+#
+CREATE TABLE t1(a DATETIME NOT NULL);
+INSERT INTO t1 VALUES ('20060606155555');
+SELECT a FROM t1 WHERE a=(SELECT MAX(a) FROM t1) AND (a="20060606155555");
+PREPARE s FROM 'SELECT a FROM t1 WHERE a=(SELECT MAX(a) FROM t1) AND (a="20060606155555")';
+EXECUTE s;
+DROP PREPARE s;
+DROP TABLE t1;
Thread
bk commit into 5.0 tree (evgen:1.2263) BUG#21475eugene20 Aug