List:Commits« Previous MessageNext Message »
From:oystein.grovlen Date:January 6 2011 3:20pm
Subject:bzr commit into mysql-5.1 branch (oystein.grovlen:3536) Bug#59211
View as plain text  
#At file:///home/oysteing/mysql-new/mysql-5.1/ based on revid:saikumar.v@stripped

 3536 oystein.grovlen@stripped	2011-01-06
      Bug#59211: Select Returns Different Value for min(year) Function
      
      get_year_value() contains code to convert 2-digits year to 4-digits.
      The fix for Bug#49910 added a check on the size of the underlying
      field so that this conversion is not done for YEAR(4) values.
      (Since otherwise one would convert invalid YEAR(4) values to valid
      ones.)
      The existing check does not work when Item_cache is used, since it
      is not detected when the cache is based on a Field.  The reported
      change in behavior is due to Bug#58030 which added extra cached
      items in min/max computations.
      
      The elegant solution would be to implement Item_cache::real_item()
      to return the underlying Item.  However, some side effects are
      observed (change in explain output) that indicatse that such a change
      is not straight-forward, and definitely not appropriate for an MRU.
      
      Instead, a Item_cache::field() method has been added in order to
      get access to the underlying field.  (This field() method eliminates
      the need for Item_cache::eq_def() used in test_if_ref(), but in order
      to limit the scope of this fix, that code has been left as is.)
     @ mysql-test/r/type_year.result
        Added test case for Bug#59211
     @ mysql-test/t/type_year.test
        Added test case for Bug#59211
     @ sql/item.h
        Added function Item_cache::field() to get access to the underlying
        Field of a cached field Value.
     @ sql/item_cmpfunc.cc
        Also check underlying fields of Item_cache, not just Item_Field, when
        checking whether the value is of type YEAR(4) or not.

    modified:
      mysql-test/r/type_year.result
      mysql-test/t/type_year.test
      sql/item.h
      sql/item_cmpfunc.cc
=== modified file 'mysql-test/r/type_year.result'
--- a/mysql-test/r/type_year.result	2010-03-22 08:33:25 +0000
+++ b/mysql-test/r/type_year.result	2011-01-06 15:20:01 +0000
@@ -341,4 +341,18 @@ ta_y	s	tb_y	s
 2001	2001	2001	2001
 DROP TABLE t1;
 #
+# Bug #59211: Select Returns Different Value for min(year) Function
+#
+CREATE TABLE t1(c1 YEAR(4));
+INSERT INTO t1 VALUES (1901),(2155),(0000);
+SELECT * FROM t1;
+c1
+1901
+2155
+0000
+SELECT COUNT(*) AS total_rows, MIN(c1) AS min_value, MAX(c1) FROM t1;
+total_rows	min_value	MAX(c1)
+3	0	2155
+DROP TABLE t1;
+#
 End of 5.1 tests

=== modified file 'mysql-test/t/type_year.test'
--- a/mysql-test/t/type_year.test	2010-03-22 08:33:25 +0000
+++ b/mysql-test/t/type_year.test	2011-01-06 15:20:01 +0000
@@ -150,5 +150,15 @@ SELECT ta.y AS ta_y, ta.s, tb.y AS tb_y,
 DROP TABLE t1;
 
 --echo #
+--echo # Bug #59211: Select Returns Different Value for min(year) Function
+--echo #
+
+CREATE TABLE t1(c1 YEAR(4));
+INSERT INTO t1 VALUES (1901),(2155),(0000);
+SELECT * FROM t1;
+SELECT COUNT(*) AS total_rows, MIN(c1) AS min_value, MAX(c1) FROM t1;
+DROP TABLE t1;
+
+--echo #
 
 --echo End of 5.1 tests

=== modified file 'sql/item.h'
--- a/sql/item.h	2010-12-28 23:47:05 +0000
+++ b/sql/item.h	2011-01-06 15:20:01 +0000
@@ -2960,11 +2960,10 @@ class Item_cache: public Item_basic_cons
 protected:
   Item *example;
   table_map used_table_map;
-  /*
-    Field that this object will get value from. This is set/used by 
+  /**
+    Field that this object will get value from. This is used by 
     index-based subquery engines to detect and remove the equality injected 
     by IN->EXISTS transformation.
-    For all other uses of Item_cache, cached_field doesn't matter.
   */  
   Field *cached_field;
   enum enum_field_types cached_field_type;
@@ -3021,6 +3020,14 @@ public:
   {
     return this == item;
   }
+
+  /** 
+    If this item caches a field value, return pointer to underlying field.
+
+    @return Pointer to field, or NULL if this is not a cache for a field value.
+  */
+  Field* field() { return cached_field; }
+
   virtual void store(Item *item);
   virtual bool cache_value()= 0;
 };

=== modified file 'sql/item_cmpfunc.cc'
--- a/sql/item_cmpfunc.cc	2010-12-28 23:47:05 +0000
+++ b/sql/item_cmpfunc.cc	2011-01-06 15:20:01 +0000
@@ -1196,9 +1196,12 @@ get_year_value(THD *thd, Item ***item_ar
          value of 2000.
   */
   Item *real_item= item->real_item();
-  if (!(real_item->type() == Item::FIELD_ITEM &&
-        ((Item_field *)real_item)->field->type() == MYSQL_TYPE_YEAR &&
-        ((Item_field *)real_item)->field->field_length == 4))
+  Field *field= NULL;
+  if (real_item->type() == Item::FIELD_ITEM)
+    field= ((Item_field *)real_item)->field;
+  else if (real_item->type() == Item::CACHE_ITEM)
+    field= ((Item_cache *)real_item)->field();
+  if (!(field && field->type() == MYSQL_TYPE_YEAR && field->field_length == 4))
   {
     if (value < 70)
       value+= 100;


Attachment: [text/bzr-bundle] bzr/oystein.grovlen@sun.com-20110106152001-2jb0oy40ucn3m5pc.bundle
Thread
bzr commit into mysql-5.1 branch (oystein.grovlen:3536) Bug#59211oystein.grovlen6 Jan