summaryrefslogtreecommitdiff
path: root/sql/item_timefunc.cc
diff options
context:
space:
mode:
authorMattias Jonsson <mattias.jonsson@sun.com>2009-08-26 12:59:49 +0200
committerMattias Jonsson <mattias.jonsson@sun.com>2009-08-26 12:59:49 +0200
commit401fb7c6fb84d1fe255fd490a0d3eb6ccb216507 (patch)
tree6186de73376dc384682a6b1c1f575d8e214c8c02 /sql/item_timefunc.cc
parent43851cb81186084f7a144fc0b47db87d3b32c4a6 (diff)
downloadmariadb-git-401fb7c6fb84d1fe255fd490a0d3eb6ccb216507.tar.gz
Bug#20577: Partitions: use of to_days() function leads to selection failures
Problem was that the partition containing NULL values was pruned away, since '2001-01-01' < '2001-02-00' but TO_DAYS('2001-02-00') is NULL. Added the NULL partition for RANGE/LIST partitioning on TO_DAYS() function to be scanned too. Also fixed a bug that added ALLOW_INVALID_DATES to sql_mode (SELECT * FROM t WHERE date_col < '1999-99-99' on a RANGE/LIST partitioned table would add it).
Diffstat (limited to 'sql/item_timefunc.cc')
-rw-r--r--sql/item_timefunc.cc21
1 files changed, 18 insertions, 3 deletions
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index d79b0b02998..eefe47232ae 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -960,9 +960,9 @@ enum_monotonicity_info Item_func_to_days::get_monotonicity_info() const
if (args[0]->type() == Item::FIELD_ITEM)
{
if (args[0]->field_type() == MYSQL_TYPE_DATE)
- return MONOTONIC_STRICT_INCREASING;
+ return MONOTONIC_STRICT_INCREASING_NOT_NULL;
if (args[0]->field_type() == MYSQL_TYPE_DATETIME)
- return MONOTONIC_INCREASING;
+ return MONOTONIC_INCREASING_NOT_NULL;
}
return NON_MONOTONIC;
}
@@ -973,12 +973,27 @@ longlong Item_func_to_days::val_int_endpoint(bool left_endp, bool *incl_endp)
DBUG_ASSERT(fixed == 1);
MYSQL_TIME ltime;
longlong res;
- if (get_arg0_date(&ltime, TIME_NO_ZERO_DATE))
+ int dummy; /* unused */
+ if (get_arg0_date(&ltime, TIME_FUZZY_DATE))
{
/* got NULL, leave the incl_endp intact */
return LONGLONG_MIN;
}
res=(longlong) calc_daynr(ltime.year,ltime.month,ltime.day);
+ /* Set to NULL if invalid date, but keep the value */
+ null_value= check_date(&ltime,
+ (ltime.year || ltime.month || ltime.day),
+ (TIME_NO_ZERO_IN_DATE | TIME_NO_ZERO_DATE),
+ &dummy);
+ if (null_value)
+ {
+ /*
+ Even if the evaluation return NULL, the calc_daynr is useful for pruning
+ */
+ if (args[0]->field_type() != MYSQL_TYPE_DATE)
+ *incl_endp= TRUE;
+ return res;
+ }
if (args[0]->field_type() == MYSQL_TYPE_DATE)
{