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#13011553 | Sergey Glukhov | 24 Apr |