From a7ff7918a055a8dbae10c59279b2d9ee7f5c07e0 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 18 Apr 2011 21:01:49 +0200 Subject: [PATCH] lp:750117 Bogus warning with aggregate and datetime column implement Item_cache_int::getdate() and Item_cache_int::save_in_field() that handle the case of the cached packed datetime value. --- mysql-test/r/range.result | 6 +++++ mysql-test/t/range.test | 9 +++++++ sql/item.cc | 54 ++++++++++++++++++++++++++++++++++++--- sql/item.h | 2 ++ sql/mysql_priv.h | 13 ++++++++++ 5 files changed, 80 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/range.result b/mysql-test/r/range.result index 8ece431eee2..a472772a7e9 100644 --- a/mysql-test/r/range.result +++ b/mysql-test/r/range.result @@ -1659,3 +1659,9 @@ c_key c_notkey 3 3 DROP TABLE t1; End of 5.1 tests +create table t1 (f1 datetime, key (f1)); +insert into t1 values ('2000-03-09 15:56:59'),('2000-05-05 23:24:28'),('2000-06-13 13:12:06'); +select min(f1) from t1 where f1 >= '2006-05-25 07:00:20' and f1 between '2003-11-23 10:00:09' and '2010-01-01 01:01:01' and f1 > '2001-01-01 01:01:01'; +min(f1) +NULL +drop table t1; diff --git a/mysql-test/t/range.test b/mysql-test/t/range.test index 0ad3d3e8504..8f8c8c08619 100644 --- a/mysql-test/t/range.test +++ b/mysql-test/t/range.test @@ -1326,3 +1326,12 @@ SELECT * FROM t1 WHERE 2 NOT BETWEEN c_notkey AND c_key; DROP TABLE t1; --echo End of 5.1 tests + +# +# lp:750117 Bogus warning with aggregate and datetime column +# +create table t1 (f1 datetime, key (f1)); +insert into t1 values ('2000-03-09 15:56:59'),('2000-05-05 23:24:28'),('2000-06-13 13:12:06'); +select min(f1) from t1 where f1 >= '2006-05-25 07:00:20' and f1 between '2003-11-23 10:00:09' and '2010-01-01 01:01:01' and f1 > '2001-01-01 01:01:01'; +drop table t1; + diff --git a/sql/item.cc b/sql/item.cc index f28b14725c3..cce985fe80d 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -999,11 +999,9 @@ bool Item::get_date(MYSQL_TIME *ltime,uint fuzzydate) int was_cut; if (number_to_datetime(value, ltime, fuzzydate, &was_cut) == LL(-1)) { - char buff[22], *end; - end= longlong10_to_str(value, buff, -10); + Lazy_string_num str(value); make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, - buff, (int) (end-buff), MYSQL_TIMESTAMP_NONE, - NullS); + &str, MYSQL_TIMESTAMP_NONE, NullS); goto err; } } @@ -7190,6 +7188,54 @@ longlong Item_cache_int::val_int() return value; } +bool Item_cache_int::get_date(MYSQL_TIME *ltime, uint fuzzydate) +{ + if (!value_cached && !cache_value()) + goto err; + + if (cmp_type() == TIME_RESULT) + { + unpack_time(value, ltime); + ltime->time_type= mysql_type_to_time_type(field_type()); + } + else + { + int was_cut; + if (number_to_datetime(value, ltime, fuzzydate, &was_cut) == -1LL) + { + Lazy_string_num str(value); + make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, + &str, MYSQL_TIMESTAMP_NONE, NullS); + goto err; + } + } + return 0; + +err: + bzero((char*) ltime,sizeof(*ltime)); + return 1; +} + +int Item_cache_int::save_in_field(Field *field, bool no_conversions) +{ + int error; + if (!value_cached && !cache_value()) + return set_field_to_null_with_conversions(field, no_conversions); + + field->set_notnull(); + if (cmp_type() == TIME_RESULT) + { + MYSQL_TIME ltime; + unpack_time(value, <ime); + ltime.time_type= mysql_type_to_time_type(field_type()); + error= field->store_time(<ime, ltime.time_type); + } + else + error= field->store(value, unsigned_flag); + + return error ? error : field->table->in_use->is_error() ? 1 : 0; +} + bool Item_cache_real::cache_value() { if (!example) diff --git a/sql/item.h b/sql/item.h index 866b3fcb4fc..275b876f521 100644 --- a/sql/item.h +++ b/sql/item.h @@ -3035,6 +3035,8 @@ public: my_decimal *val_decimal(my_decimal *); enum Item_result result_type() const { return INT_RESULT; } bool cache_value(); + bool get_date(MYSQL_TIME *ltime, uint fuzzydate); + int save_in_field(Field *field, bool no_conversions); Item *clone_item() { Item_cache_int *item= new Item_cache_int(cached_field_type); diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 2ac2318f242..acdbac4ff68 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -2257,6 +2257,19 @@ int my_time_compare(MYSQL_TIME *a, MYSQL_TIME *b); longlong get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg, Item *warn_item, bool *is_null); +static inline enum enum_mysql_timestamp_type +mysql_type_to_time_type(enum enum_field_types mysql_type) +{ + switch(mysql_type) { + case MYSQL_TYPE_TIME: return MYSQL_TIMESTAMP_TIME; + case MYSQL_TYPE_TIMESTAMP: + case MYSQL_TYPE_DATETIME: return MYSQL_TIMESTAMP_DATETIME; + case MYSQL_TYPE_NEWDATE: + case MYSQL_TYPE_DATE: return MYSQL_TIMESTAMP_DATE; + default: return MYSQL_TIMESTAMP_ERROR; + } +} + int test_if_number(char *str,int *res,bool allow_wildcards); void change_byte(uchar *,uint,char,char); void init_read_record(READ_RECORD *info, THD *thd, TABLE *reg_form,