diff options
Diffstat (limited to 'sql/item_timefunc.cc')
-rw-r--r-- | sql/item_timefunc.cc | 43 |
1 files changed, 32 insertions, 11 deletions
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 9cf56148994..91b7ffbec71 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -1952,7 +1952,10 @@ String *Item_func_date_format::val_str(String *str) { String *res; if (!(res=args[0]->val_str(str)) || - (str_to_time_with_warn(res->ptr(), res->length(), &l_time))) + (str_to_time_with_warn(res->ptr(), res->length(), &l_time, + current_thd->variables.sql_mode & + (MODE_NO_ZERO_DATE | MODE_NO_ZERO_IN_DATE | + MODE_INVALID_DATES)))) goto null_date; l_time.year=l_time.month=l_time.day=0; @@ -2322,7 +2325,11 @@ longlong Item_extract::val_int() char buf[40]; String value(buf, sizeof(buf), &my_charset_bin);; String *res= args[0]->val_str(&value); - if (!res || str_to_time_with_warn(res->ptr(), res->length(), <ime)) + if (!res || + str_to_time_with_warn(res->ptr(), res->length(), <ime, + current_thd->variables.sql_mode & + (MODE_NO_ZERO_DATE | MODE_NO_ZERO_IN_DATE | + MODE_INVALID_DATES))) { null_value=1; return 0; @@ -2461,10 +2468,15 @@ String *Item_char_typecast::val_str(String *str) } else { - // Convert character set if differ + /* + Convert character set if differ + from_cs is 0 in the case where the result set may vary between calls, + for example with dynamic columns. + */ uint dummy_errors; if (!(res= args[0]->val_str(str)) || - tmp_value.copy(res->ptr(), res->length(), from_cs, + tmp_value.copy(res->ptr(), res->length(), + from_cs ? from_cs : res->charset(), cast_cs, &dummy_errors)) { null_value= 1; @@ -2542,15 +2554,19 @@ void Item_char_typecast::fix_length_and_dec() and thus avoid unnecessary character set conversion. - If the argument is not a number, then from_cs is set to the argument's charset. + - If argument has a dynamic collation (can change from call to call) + we set from_cs to 0 as a marker that we have to take the collation + from the result string. Note (TODO): we could use repertoire technique here. */ - from_cs= (args[0]->result_type() == INT_RESULT || - args[0]->result_type() == DECIMAL_RESULT || - args[0]->result_type() == REAL_RESULT) ? - (cast_cs->mbminlen == 1 ? cast_cs : &my_charset_latin1) : - args[0]->collation.collation; - charset_conversion= (cast_cs->mbmaxlen > 1) || + from_cs= ((args[0]->result_type() == INT_RESULT || + args[0]->result_type() == DECIMAL_RESULT || + args[0]->result_type() == REAL_RESULT) ? + (cast_cs->mbminlen == 1 ? cast_cs : &my_charset_latin1) : + args[0]->dynamic_result() ? 0 : + args[0]->collation.collation); + charset_conversion= !from_cs || (cast_cs->mbmaxlen > 1) || (!my_charset_same(from_cs, cast_cs) && from_cs != &my_charset_bin && cast_cs != &my_charset_bin); @@ -2604,6 +2620,11 @@ bool Item_time_typecast::get_time(MYSQL_TIME *ltime) return res; } +bool Item_time_typecast::get_date(MYSQL_TIME *ltime, uint fuzzy_date) +{ + return get_time(ltime); +} + longlong Item_time_typecast::val_int() { @@ -2621,7 +2642,7 @@ String *Item_time_typecast::val_str(String *str) DBUG_ASSERT(fixed == 1); MYSQL_TIME ltime; - if (!get_arg0_time(<ime) && + if (!get_time(<ime) && !make_datetime(ltime.second_part ? TIME_MICROSECOND : TIME_ONLY, <ime, str)) return str; |