diff options
Diffstat (limited to 'sql/item.cc')
-rw-r--r-- | sql/item.cc | 88 |
1 files changed, 54 insertions, 34 deletions
diff --git a/sql/item.cc b/sql/item.cc index 28729e9936f..a5dfa0db6b6 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -270,7 +270,7 @@ my_decimal *Item::val_decimal_from_string(my_decimal *decimal_value) my_decimal *Item::val_decimal_from_date(my_decimal *decimal_value) { DBUG_ASSERT(fixed == 1); - TIME ltime; + MYSQL_TIME ltime; if (get_date(<ime, TIME_FUZZY_DATE)) { my_decimal_set_zero(decimal_value); @@ -283,7 +283,7 @@ my_decimal *Item::val_decimal_from_date(my_decimal *decimal_value) my_decimal *Item::val_decimal_from_time(my_decimal *decimal_value) { DBUG_ASSERT(fixed == 1); - TIME ltime; + MYSQL_TIME ltime; if (get_time(<ime)) { my_decimal_set_zero(decimal_value); @@ -318,7 +318,7 @@ longlong Item::val_int_from_decimal() int Item::save_time_in_field(Field *field) { - TIME ltime; + MYSQL_TIME ltime; if (get_time(<ime)) return set_field_to_null(field); field->set_notnull(); @@ -328,7 +328,7 @@ int Item::save_time_in_field(Field *field) int Item::save_date_in_field(Field *field) { - TIME ltime; + MYSQL_TIME ltime; if (get_date(<ime, TIME_FUZZY_DATE)) return set_field_to_null(field); field->set_notnull(); @@ -836,22 +836,40 @@ bool Item_string::eq(const Item *item, bool binary_cmp) const /* - Get the value of the function as a TIME structure. + Get the value of the function as a MYSQL_TIME structure. As a extra convenience the time structure is reset on error! */ -bool Item::get_date(TIME *ltime,uint fuzzydate) +bool Item::get_date(MYSQL_TIME *ltime,uint fuzzydate) { - char buff[40]; - String tmp(buff,sizeof(buff), &my_charset_bin),*res; - if (!(res=val_str(&tmp)) || - str_to_datetime_with_warn(res->ptr(), res->length(), - ltime, fuzzydate) <= MYSQL_TIMESTAMP_ERROR) + if (result_type() == STRING_RESULT) { - bzero((char*) ltime,sizeof(*ltime)); - return 1; + char buff[40]; + String tmp(buff,sizeof(buff), &my_charset_bin),*res; + if (!(res=val_str(&tmp)) || + str_to_datetime_with_warn(res->ptr(), res->length(), + ltime, fuzzydate) <= MYSQL_TIMESTAMP_ERROR) + goto err; + } + else + { + longlong value= val_int(); + 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); + make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, + buff, (int) (end-buff), MYSQL_TIMESTAMP_NONE, + NullS); + goto err; + } } return 0; + +err: + bzero((char*) ltime,sizeof(*ltime)); + return 1; } /* @@ -859,7 +877,7 @@ bool Item::get_date(TIME *ltime,uint fuzzydate) As a extra convenience the time structure is reset on error! */ -bool Item::get_time(TIME *ltime) +bool Item::get_time(MYSQL_TIME *ltime) { char buff[40]; String tmp(buff,sizeof(buff),&my_charset_bin),*res; @@ -1011,6 +1029,7 @@ Item_splocal::Item_splocal(const LEX_STRING &sp_var_name, maybe_null= TRUE; m_type= sp_map_item_type(sp_var_type); + m_field_type= sp_var_type; m_result_type= sp_map_result_type(sp_var_type); } @@ -1837,7 +1856,7 @@ String *Item_field::str_result(String *str) return result_field->val_str(str,&str_value); } -bool Item_field::get_date(TIME *ltime,uint fuzzydate) +bool Item_field::get_date(MYSQL_TIME *ltime,uint fuzzydate) { if ((null_value=field->is_null()) || field->get_date(ltime,fuzzydate)) { @@ -1847,7 +1866,7 @@ bool Item_field::get_date(TIME *ltime,uint fuzzydate) return 0; } -bool Item_field::get_date_result(TIME *ltime,uint fuzzydate) +bool Item_field::get_date_result(MYSQL_TIME *ltime,uint fuzzydate) { if ((null_value=result_field->is_null()) || result_field->get_date(ltime,fuzzydate)) @@ -1858,7 +1877,7 @@ bool Item_field::get_date_result(TIME *ltime,uint fuzzydate) return 0; } -bool Item_field::get_time(TIME *ltime) +bool Item_field::get_time(MYSQL_TIME *ltime) { if ((null_value=field->is_null()) || field->get_time(ltime)) { @@ -2294,6 +2313,7 @@ default_set_param_func(Item_param *param, Item_param::Item_param(unsigned pos_in_query_arg) : + strict_type(FALSE), state(NO_VALUE), item_result_type(STRING_RESULT), /* Don't pretend to be a literal unless value for this item is set. */ @@ -2385,7 +2405,7 @@ void Item_param::set_decimal(const char *str, ulong length) /* - Set parameter value from TIME value. + Set parameter value from MYSQL_TIME value. SYNOPSIS set_time() @@ -2399,7 +2419,7 @@ void Item_param::set_decimal(const char *str, ulong length) the fact that even wrong value sent over binary protocol fits into MAX_DATE_STRING_REP_LENGTH buffer. */ -void Item_param::set_time(TIME *tm, timestamp_type time_type, +void Item_param::set_time(MYSQL_TIME *tm, timestamp_type time_type, uint32 max_length_arg) { DBUG_ENTER("Item_param::set_time"); @@ -2414,7 +2434,8 @@ void Item_param::set_time(TIME *tm, timestamp_type time_type, { char buff[MAX_DATE_STRING_REP_LENGTH]; uint length= my_TIME_to_str(&value.time, buff); - make_truncated_value_warning(current_thd, buff, length, time_type, 0); + make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, + buff, length, time_type, 0); set_zero_time(&value.time, MYSQL_TIMESTAMP_ERROR); } @@ -2487,16 +2508,16 @@ bool Item_param::set_from_user_var(THD *thd, const user_var_entry *entry) if (entry && entry->value) { item_result_type= entry->type; - switch (entry->type) { + if (strict_type && required_result_type != item_result_type) + DBUG_RETURN(1); + switch (item_result_type) { case REAL_RESULT: set_double(*(double*)entry->value); item_type= Item::REAL_ITEM; - item_result_type= REAL_RESULT; break; case INT_RESULT: set_int(*(longlong*)entry->value, MY_INT64_NUM_DECIMAL_DIGITS); item_type= Item::INT_ITEM; - item_result_type= INT_RESULT; break; case STRING_RESULT: { @@ -2518,7 +2539,6 @@ bool Item_param::set_from_user_var(THD *thd, const user_var_entry *entry) charset of connection, so we have to set it later. */ item_type= Item::STRING_ITEM; - item_result_type= STRING_RESULT; if (set_str((const char *)entry->value, entry->length)) DBUG_RETURN(1); @@ -2532,6 +2552,7 @@ bool Item_param::set_from_user_var(THD *thd, const user_var_entry *entry) decimals= ent_value->frac; max_length= my_decimal_precision_to_length(ent_value->precision(), decimals, unsigned_flag); + item_type= Item::DECIMAL_ITEM; break; } default: @@ -2615,7 +2636,7 @@ int Item_param::save_in_field(Field *field, bool no_conversions) } -bool Item_param::get_time(TIME *res) +bool Item_param::get_time(MYSQL_TIME *res) { if (state == TIME_VALUE) { @@ -2630,7 +2651,7 @@ bool Item_param::get_time(TIME *res) } -bool Item_param::get_date(TIME *res, uint fuzzydate) +bool Item_param::get_date(MYSQL_TIME *res, uint fuzzydate) { if (state == TIME_VALUE) { @@ -3056,7 +3077,7 @@ String* Item_ref_null_helper::val_str(String* s) } -bool Item_ref_null_helper::get_date(TIME *ltime, uint fuzzydate) +bool Item_ref_null_helper::get_date(MYSQL_TIME *ltime, uint fuzzydate) { return (owner->was_null|= null_value= (*ref)->get_date(ltime, fuzzydate)); } @@ -3502,7 +3523,8 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference) prev_subselect_item->const_item_cache= 0; set_field(*from_field); if (!last_checked_context->select_lex->having_fix_field && - select->group_list.elements) + select->group_list.elements && + (place == SELECT_LIST || place == IN_HAVING)) { Item_outer_ref *rf; /* @@ -4621,7 +4643,6 @@ inline uint char_val(char X) Item_hex_string::Item_hex_string(const char *str, uint str_length) { - name=(char*) str-2; // Lex makes this start with 0x max_length=(str_length+1)/2; char *ptr=(char*) sql_alloc(max_length+1); if (!ptr) @@ -4732,7 +4753,6 @@ Item_bin_string::Item_bin_string(const char *str, uint str_length) uchar bits= 0; uint power= 1; - name= (char*) str - 2; max_length= (str_length + 7) >> 3; char *ptr= (char*) sql_alloc(max_length + 1); if (!ptr) @@ -4852,7 +4872,7 @@ bool Item::send(Protocol *protocol, String *buffer) case MYSQL_TYPE_DATE: case MYSQL_TYPE_TIMESTAMP: { - TIME tm; + MYSQL_TIME tm; get_date(&tm, TIME_FUZZY_DATE); if (!null_value) { @@ -4865,7 +4885,7 @@ bool Item::send(Protocol *protocol, String *buffer) } case MYSQL_TYPE_TIME: { - TIME tm; + MYSQL_TIME tm; get_time(&tm); if (!null_value) result= protocol->store_time(&tm); @@ -5437,7 +5457,7 @@ bool Item_ref::is_null() } -bool Item_ref::get_date(TIME *ltime,uint fuzzydate) +bool Item_ref::get_date(MYSQL_TIME *ltime,uint fuzzydate) { return (null_value=(*ref)->get_date_result(ltime,fuzzydate)); } @@ -5536,7 +5556,7 @@ bool Item_direct_ref::is_null() } -bool Item_direct_ref::get_date(TIME *ltime,uint fuzzydate) +bool Item_direct_ref::get_date(MYSQL_TIME *ltime,uint fuzzydate) { return (null_value=(*ref)->get_date(ltime,fuzzydate)); } |