List:Commits« Previous MessageNext Message »
From:Sergey Glukhov Date:April 24 2012 8:05am
Subject:bzr push into mysql-trunk branch (sergey.glukhov:3732 to 3733) Bug#13011553
View as plain text  
 3733 Sergey Glukhov	2012-04-24
      Bug#13011553 CRASH IN SORTCMP OR CACHED_ITEM_STR::CMP IF GROUP BY SUBQUERY WITH ROLLUP
      During of comparing of grouped values
      DATETIME values are compared as STRING
      rather than INT. It leads to crash in the
      case of NULL value comparison because val_str()
      method could return zero pointer to the string
      and further comparison fails. The fix is to
      compare DATETIME grouped values for ROLLAUP as INT.
     @ mysql-test/r/olap.result
        test case
     @ mysql-test/t/olap.test
        test case
     @ sql/item.h
        added new class Cached_item_temporal
     @ sql/item_buff.cc
        use Cached_item_temporal object if item is DATE/TIME/DATETIME
     @ sql/item_func.h
        oveloaded field_type() method for Item_func_rollup_const class

    modified:
      mysql-test/r/olap.result
      mysql-test/t/olap.test
      sql/item.h
      sql/item_buff.cc
      sql/item_func.h
 3732 Marko Mäkelä	2012-04-24
      Catch Bug#13992653 a little earlier in debug builds.

    modified:
      storage/innobase/btr/btr0cur.cc
=== modified file 'mysql-test/r/olap.result'
--- a/mysql-test/r/olap.result	2011-07-19 15:11:15 +0000
+++ b/mysql-test/r/olap.result	2012-04-24 08:04:39 +0000
@@ -766,3 +766,31 @@ b
 NULL
 DROP TABLE t1, t2;
 End of 5.0 tests
+#
+# Bug#13011553 CRASH IN SORTCMP OR CACHED_ITEM_STR::CMP IF GROUP BY SUBQUERY WITH ROLLUP
+#
+CREATE TABLE t1 (f1 DATETIME) ENGINE = MyISAM;
+INSERT INTO  t1 VALUES ('2012-12-20 00:00:00'), (NULL);
+SELECT f1 FROM t1 GROUP BY
+(SELECT f1 FROM t1 HAVING f1 < '2012-12-21 00:00:00') WITH ROLLUP;
+f1
+2012-12-20 00:00:00
+2012-12-20 00:00:00
+DROP TABLE t1;
+CREATE TABLE t1 (f1 DATE) ENGINE = MyISAM;
+INSERT INTO  t1 VALUES ('2012-12-20'), (NULL);
+SELECT f1 FROM t1 GROUP BY
+(SELECT f1 FROM t1 HAVING f1 < '2012-12-21') WITH ROLLUP;
+f1
+2012-12-20
+2012-12-20
+DROP TABLE t1;
+CREATE TABLE t1 (f1 TIME) ENGINE = MyISAM;
+INSERT INTO  t1 VALUES ('11:11:11'), (NULL);
+SELECT f1 FROM t1 GROUP BY
+(SELECT f1 FROM t1 HAVING f1 < '12:12:12') WITH ROLLUP;
+f1
+11:11:11
+11:11:11
+DROP TABLE t1;
+End of 5.5 tests

=== modified file 'mysql-test/t/olap.test'
--- a/mysql-test/t/olap.test	2010-02-26 13:16:46 +0000
+++ b/mysql-test/t/olap.test	2012-04-24 08:04:39 +0000
@@ -404,3 +404,33 @@ SELECT DISTINCT b FROM t1, t2 GROUP BY a
 DROP TABLE t1, t2;
 
 --echo End of 5.0 tests
+
+--echo #
+--echo # Bug#13011553 CRASH IN SORTCMP OR CACHED_ITEM_STR::CMP IF GROUP BY SUBQUERY WITH ROLLUP
+--echo #
+
+CREATE TABLE t1 (f1 DATETIME) ENGINE = MyISAM;
+INSERT INTO  t1 VALUES ('2012-12-20 00:00:00'), (NULL);
+
+SELECT f1 FROM t1 GROUP BY
+(SELECT f1 FROM t1 HAVING f1 < '2012-12-21 00:00:00') WITH ROLLUP;
+
+DROP TABLE t1;
+
+CREATE TABLE t1 (f1 DATE) ENGINE = MyISAM;
+INSERT INTO  t1 VALUES ('2012-12-20'), (NULL);
+
+SELECT f1 FROM t1 GROUP BY
+(SELECT f1 FROM t1 HAVING f1 < '2012-12-21') WITH ROLLUP;
+
+DROP TABLE t1;
+
+CREATE TABLE t1 (f1 TIME) ENGINE = MyISAM;
+INSERT INTO  t1 VALUES ('11:11:11'), (NULL);
+
+SELECT f1 FROM t1 GROUP BY
+(SELECT f1 FROM t1 HAVING f1 < '12:12:12') WITH ROLLUP;
+
+DROP TABLE t1;
+
+--echo End of 5.5 tests

=== modified file 'sql/item.h'
--- a/sql/item.h	2012-04-20 06:48:15 +0000
+++ b/sql/item.h	2012-04-24 08:04:39 +0000
@@ -3811,6 +3811,15 @@ public:
   bool cmp(void);
 };
 
+class Cached_item_temporal :public Cached_item
+{
+  Item *item;
+  longlong value;
+public:
+  Cached_item_temporal(Item *item_par) :item(item_par), value(0) {}
+  bool cmp(void);
+};
+
 
 class Cached_item_decimal :public Cached_item
 {

=== modified file 'sql/item_buff.cc'
--- a/sql/item_buff.cc	2011-12-09 21:08:37 +0000
+++ b/sql/item_buff.cc	2012-04-24 08:04:39 +0000
@@ -49,6 +49,8 @@ Cached_item *new_Cached_item(THD *thd, I
   }
   switch (item->result_type()) {
   case STRING_RESULT:
+    if (item->is_temporal())
+      return new Cached_item_temporal((Item_field *) item);
     return new Cached_item_str(thd, (Item_field *) item);
   case INT_RESULT:
     return new Cached_item_int((Item_field *) item);
@@ -84,6 +86,7 @@ bool Cached_item_str::cmp(void)
   bool tmp;
 
   DBUG_ENTER("Cached_item_str::cmp");
+  DBUG_ASSERT(!item->is_temporal());
   if ((res=item->val_str(&tmp_value)))
     res->length(min(res->length(), value_max_length));
   DBUG_PRINT("info", ("old: %s, new: %s",
@@ -137,6 +140,21 @@ bool Cached_item_int::cmp(void)
 }
 
 
+bool Cached_item_temporal::cmp(void)
+{
+  DBUG_ENTER("Cached_item_temporal::cmp");
+  longlong nr= item->val_temporal_by_field_type();
+  DBUG_PRINT("info", ("old: %lld, new: %lld", value, nr)); 
+  if (null_value != item->null_value || nr != value)
+  {
+    null_value= item->null_value;
+    value= nr;
+    DBUG_RETURN(TRUE);
+  }
+  DBUG_RETURN(FALSE);
+}
+
+
 bool Cached_item_field::cmp(void)
 {
   DBUG_ENTER("Cached_item_field::cmp");

=== modified file 'sql/item_func.h'
--- a/sql/item_func.h	2012-04-24 07:35:13 +0000
+++ b/sql/item_func.h	2012-04-24 08:04:39 +0000
@@ -1037,6 +1037,7 @@ public:
     /* The item could be a NULL constant. */
     null_value= args[0]->is_null();
   }
+  enum_field_types field_type() const { return args[0]->field_type(); }
 };
 
 

No bundle (reason: useless for push emails).
Thread
bzr push into mysql-trunk branch (sergey.glukhov:3732 to 3733) Bug#13011553Sergey Glukhov24 Apr