From 3444e8e9254070f836488dae12b5c825cc9c563f Mon Sep 17 00:00:00 2001
From: Sergei Golubchik <sergii@pisem.net>
Date: Wed, 29 Aug 2012 17:55:59 +0200
Subject: [PATCH] MDEV-454 Addition of a time interval reduces the resulting
 value

1. Field_newdate::get_date should refuse to return a date with zeros when
   TIME_NO_ZERO_IN_DATE is set, not when TIME_FUZZY_DATE is unset
2. Item_func_to_days and Item_date_add_interval can only work with valid dates,
   no zeros allowed.
---
 mysql-test/r/adddate_454.result | 10 ++++++++++
 mysql-test/t/adddate_454.test   |  9 +++++++++
 sql/field.cc                    |  2 +-
 sql/item_timefunc.cc            |  4 ++--
 4 files changed, 22 insertions(+), 3 deletions(-)
 create mode 100644 mysql-test/r/adddate_454.result
 create mode 100644 mysql-test/t/adddate_454.test

diff --git a/mysql-test/r/adddate_454.result b/mysql-test/r/adddate_454.result
new file mode 100644
index 00000000000..0993cdce32c
--- /dev/null
+++ b/mysql-test/r/adddate_454.result
@@ -0,0 +1,10 @@
+create table t1 (d date);
+insert into t1 values ('2012-00-00');
+select * from t1;
+d
+2012-00-00
+update t1 set d = adddate(d, interval 1 day);
+select * from t1;
+d
+NULL
+drop table t1;
diff --git a/mysql-test/t/adddate_454.test b/mysql-test/t/adddate_454.test
new file mode 100644
index 00000000000..1d69cdc9558
--- /dev/null
+++ b/mysql-test/t/adddate_454.test
@@ -0,0 +1,9 @@
+#
+# MDEV-454 Addition of a time interval reduces the resulting value
+#
+create table t1 (d date);
+insert into t1 values ('2012-00-00');
+select * from t1;
+update t1 set d = adddate(d, interval 1 day);
+select * from t1;
+drop table t1;
diff --git a/sql/field.cc b/sql/field.cc
index cf5b6cf2ff9..9b0f6a7dfcd 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -5789,7 +5789,7 @@ bool Field_newdate::get_date(MYSQL_TIME *ltime,uint fuzzydate)
   if (!tmp)
     return fuzzydate & TIME_NO_ZERO_DATE;
   if (!ltime->month || !ltime->day)
-    return !(fuzzydate & TIME_FUZZY_DATE);
+    return fuzzydate & TIME_NO_ZERO_IN_DATE;
   return 0;
 }
 
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index 2cd8b3215c4..bdad96f12ef 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -751,7 +751,7 @@ longlong Item_func_to_days::val_int()
 {
   DBUG_ASSERT(fixed == 1);
   MYSQL_TIME ltime;
-  if (get_arg0_date(&ltime, TIME_NO_ZERO_DATE))
+  if (get_arg0_date(&ltime, TIME_NO_ZERO_DATE | TIME_NO_ZERO_IN_DATE))
     return 0;
   return (longlong) calc_daynr(ltime.year,ltime.month,ltime.day);
 }
@@ -1932,7 +1932,7 @@ bool Item_date_add_interval::get_date(MYSQL_TIME *ltime, uint fuzzy_date)
 {
   INTERVAL interval;
 
-  if (args[0]->get_date(ltime, TIME_NO_ZERO_DATE | TIME_FUZZY_DATE) ||
+  if (args[0]->get_date(ltime, TIME_NO_ZERO_DATE | TIME_FUZZY_DATE | TIME_NO_ZERO_IN_DATE) ||
       get_interval_value(args[1], int_type, &value, &interval))
     return (null_value=1);
 
-- 
2.30.9