3805 Norvald H. Ryeng 2012-03-20
Bug#13626019 DIFFERENCE IN OUTPUT BETWEEN 5.1 & 5.5 FOR A LAST_DAY IS
NULL SELECT QUERY
Problem: Some LAST_DAY expressions that should evaluate to NULL do not
satisfy IS NULL.
There are two bugs in the code that can lead to this problem,
depending on circumstances:
1. In make_join_select(), constant conditions are replaced with
Item::COND_FALSE or Item::COND_TRUE. When the IS NULL expression is
evaluated, Item_func_isnull::val_int() checks if the value of its
argument is NULL by calling is_null(). The default implementation,
Item::is_null(), always returns false, and all items that may return
NULL must overload this function. For Item_func_last_day, this is done
in Item_func::is_null(). However, the argument to Item_func_isnull may
in some cases be an Item_cache_datetime, for which there is no
overloading is_null(), which means that Item::is_null() is called and
always returns false.
2. In 5.1 and 5.5 there is a related problem where maybe_null is not
set for Item_func_last_day, which makes Item_func_isnull::val_int()
reason that there is no need to call is_null() on its argument since
it already knows it can't be NULL. This is the cause for erroneous
results in 5.1. The bug has already been fixed in trunk by
revid:alexander.barkov@stripped.
Bug 2 has been fixed in trunk, and bug 1 is masked: The
Item_cache_datetime object is constructed as part of
JOIN::cache_const_exprs(), which is called from JOIN::optimize(). In
5.1 and 5.5 this call happens before the call to
make_join_select(). In trunk, the order is reversed and the bug is
masked. The erroneous result can't occur in trunk, but the behavior of
is_null() is still wrong and should be fixed.
Fix: Item_cache::is_null() should return the cached null_value or, if
no value has been cached, example->is_null().
@ mysql-test/r/type_date.result
Add test case for bug #13626019.
@ mysql-test/t/type_date.test
Add test case for bug #13626019.
@ sql/item.h
Add Item_cache::is_null().
modified:
mysql-test/r/type_date.result
mysql-test/t/type_date.test
sql/item.h
3804 Tor Didriksen 2012-03-20
BUG#11748924 PARTITIONS: TOO-LONG COMMENT CAUSES NO WARNING
Post-push fix: remove memory leak, and fix indentation.
modified:
sql/sql_table.cc
sql/unireg.cc
=== modified file 'mysql-test/r/type_date.result'
--- a/mysql-test/r/type_date.result 2012-03-19 17:59:14 +0000
+++ b/mysql-test/r/type_date.result 2012-03-20 12:26:25 +0000
@@ -481,6 +481,28 @@ DATE(MIN(a))
DROP TABLE t1;
SET timestamp=DEFAULT;
#
+# Bug #13626019 DIFFERENCE IN OUTPUT BETWEEN 5.1 & 5.5 FOR A LAST_DAY IS
+# NULL SELECT QUERY
+#
+CREATE TABLE t1(a INT) ENGINE=InnoDB;
+CREATE TABLE t2(b CHAR(19));
+INSERT INTO t1 VALUES(1);
+INSERT INTO t2 VALUES('0000-00-00 00:00:00');
+SELECT * FROM t1 WHERE LAST_DAY('0000-00-00 00:00:00') IS NULL;
+a
+1
+Warnings:
+Warning 1292 Incorrect datetime value: '0000-00-00'
+Warning 1292 Incorrect datetime value: '0000-00-00'
+Warning 1292 Incorrect datetime value: '0000-00-00'
+SELECT * FROM t1 WHERE
+LAST_DAY((SELECT b FROM t2 WHERE b = '0000-00-00 00:00:00')) IS NULL;
+a
+1
+Warnings:
+Warning 1292 Incorrect datetime value: '0000-00-00'
+DROP TABLE t1,t2;
+#
# Test for bug#11747847 - 34280: create table fails if NO_ZERO_DATE
# or NO_ZERO_IN_DATE SQL mode is set.
DROP TABLE IF EXISTS t1, t2, t3;
=== modified file 'mysql-test/t/type_date.test'
--- a/mysql-test/t/type_date.test 2012-03-19 17:59:14 +0000
+++ b/mysql-test/t/type_date.test 2012-03-20 12:26:25 +0000
@@ -399,6 +399,20 @@ DROP TABLE t1;
SET timestamp=DEFAULT;
--echo #
+--echo # Bug #13626019 DIFFERENCE IN OUTPUT BETWEEN 5.1 & 5.5 FOR A LAST_DAY IS
+--echo # NULL SELECT QUERY
+--echo #
+
+CREATE TABLE t1(a INT) ENGINE=InnoDB;
+CREATE TABLE t2(b CHAR(19));
+INSERT INTO t1 VALUES(1);
+INSERT INTO t2 VALUES('0000-00-00 00:00:00');
+SELECT * FROM t1 WHERE LAST_DAY('0000-00-00 00:00:00') IS NULL;
+SELECT * FROM t1 WHERE
+LAST_DAY((SELECT b FROM t2 WHERE b = '0000-00-00 00:00:00')) IS NULL;
+DROP TABLE t1,t2;
+
+--echo #
--echo # Test for bug#11747847 - 34280: create table fails if NO_ZERO_DATE
--echo # or NO_ZERO_IN_DATE SQL mode is set.
=== modified file 'sql/item.h'
--- a/sql/item.h 2012-03-15 14:41:06 +0000
+++ b/sql/item.h 2012-03-20 12:26:25 +0000
@@ -3902,6 +3902,7 @@ public:
{ return test(example && example->basic_const_item());}
bool walk (Item_processor processor, bool walk_subquery, uchar *argument);
virtual void clear() { null_value= TRUE; value_cached= FALSE; }
+ bool is_null() { return value_cached ? null_value : example->is_null(); }
Item_result result_type() const
{
if (!example)
No bundle (reason: useless for push emails).
| Thread |
|---|
| • bzr push into mysql-trunk branch (norvald.ryeng:3804 to 3805) Bug#13626019 | Norvald H. Ryeng | 20 Mar |