#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#59211 | oystein.grovlen | 6 Jan |