diff options
author | Mattias Jonsson <mattias.jonsson@sun.com> | 2009-08-26 12:59:49 +0200 |
---|---|---|
committer | Mattias Jonsson <mattias.jonsson@sun.com> | 2009-08-26 12:59:49 +0200 |
commit | 401fb7c6fb84d1fe255fd490a0d3eb6ccb216507 (patch) | |
tree | 6186de73376dc384682a6b1c1f575d8e214c8c02 /sql/item_timefunc.cc | |
parent | 43851cb81186084f7a144fc0b47db87d3b32c4a6 (diff) | |
download | mariadb-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.cc | 21 |
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(<ime, TIME_NO_ZERO_DATE)) + int dummy; /* unused */ + if (get_arg0_date(<ime, 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(<ime, + (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) { |