From daafa8db5049da5a8e3c51edb7cb5b7f36dbc73f Mon Sep 17 00:00:00 2001
From: unknown <monty@hundin.mysql.fi>
Date: Tue, 7 May 2002 19:08:56 +0300
Subject: [PATCH] Fix for ISNULL()

Docs/manual.texi:
  Chagnelog
mysql-test/r/join.result:
  New tests for IS NULL
mysql-test/t/join.test:
  New tests for IS NULL
---
 Docs/manual.texi         | 7 ++++++-
 mysql-test/r/join.result | 3 +++
 mysql-test/t/join.test   | 1 +
 sql/item_cmpfunc.cc      | 2 +-
 sql/item_cmpfunc.h       | 7 +++++++
 sql/item_timefunc.h      | 2 +-
 6 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/Docs/manual.texi b/Docs/manual.texi
index 25db42c96e..fcd77bf286 100644
--- a/Docs/manual.texi
+++ b/Docs/manual.texi
@@ -46916,6 +46916,10 @@ not yet 100% confident in this code.
 @appendixsubsec Changes in release 3.23.51
 @itemize @bullet
 @item
+Removed BDB documentation.
+@item
+Fixed mit-pthreads to compile with glibc 2.2 (needed for @code{make dist}).
+@item
 Fixed the @code{FLOAT(X+1,X)} is not converted to @code{FLOAT(X+2,X)}.
 (This also affected @code{DECIMAL}, @code{DOUBLE} and @code{REAL} types)
 @item
@@ -46929,7 +46933,8 @@ Fixed that underflowed decimal fields is not zero filled.
 If we get an overflow when inserting @code{'+11111'} for
 @code{decimal(5,0) unsigned} columns, we will just drop the sign.
 @item
-Fixed bug with @code{ISNULL(expression_which_cannot_be_null)}.
+Fixed optimization bug with @code{ISNULL(expression_which_cannot_be_null)} and
+@code{ISNULL(constant_expression)}.
 @item
 Fixed host lookup bug in the glibc library that we used with the 3.23.50
 Linux-x86 binaries.
diff --git a/mysql-test/r/join.result b/mysql-test/r/join.result
index c99c63245d..39331fc68e 100644
--- a/mysql-test/r/join.result
+++ b/mysql-test/r/join.result
@@ -27,6 +27,9 @@ d	d
 0000-00-00	NULL
 d
 0000-00-00
+d
+2001-08-01
+0000-00-00
 COUNT(t1.Title)
 1
 COUNT(t1.Title)
diff --git a/mysql-test/t/join.test b/mysql-test/t/join.test
index 9db520a5ed..d31db5c483 100644
--- a/mysql-test/t/join.test
+++ b/mysql-test/t/join.test
@@ -120,6 +120,7 @@ CREATE TABLE t2 (d DATE NOT NULL);
 INSERT INTO t1 (d) VALUES ('2001-08-01'),('0000-00-00');
 SELECT * FROM t1 LEFT JOIN t2 USING (d) WHERE t2.d IS NULL;
 SELECT * from t1 WHERE t1.d IS NULL;
+SELECT * FROM t1 WHERE 1/0 IS NULL;
 DROP TABLE t1,t2;
 
 #
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 0c0eef3784..73821f8d82 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -1211,7 +1211,7 @@ longlong Item_func_isnull::val_int()
     This has to be here because of the test in update_used_tables().
   */
   if (!used_tables_cache)
-    return 0;
+    return cached_value;
   (void) args[0]->val();
   return (args[0]->null_value) ? 1 : 0;
 }
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index 5ee0687c06..e7c598808e 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -429,6 +429,7 @@ class Item_func_in :public Item_int_func
 
 class Item_func_isnull :public Item_bool_func
 {
+  longlong cached_value;
 public:
   Item_func_isnull(Item *a) :Item_bool_func(a) {}
   longlong val_int();
@@ -449,6 +450,12 @@ public:
       args[0]->update_used_tables();
       used_tables_cache=args[0]->used_tables();
     }
+    if (!used_tables_cache)
+    {
+      /* Remember if the value is always NULL or never NULL */
+      args[0]->val();
+      cached_value= args[0]->null_value ? (longlong) 1 : (longlong) 0;
+    }
   }
   optimize_type select_optimize() const { return OPTIMIZE_NULL; }
 };
diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h
index 6913d4c680..720f8ba288 100644
--- a/sql/item_timefunc.h
+++ b/sql/item_timefunc.h
@@ -47,7 +47,7 @@ public:
   Item_func_to_days(Item *a) :Item_int_func(a) {}
   longlong val_int();
   const char *func_name() const { return "to_days"; }
-  void fix_length_and_dec() { decimals=0; max_length=6; }
+  void fix_length_and_dec() { decimals=0; max_length=6; maybe_null=1; }
 };
 
 
-- 
2.30.9