diff --git a/sql/item.cc b/sql/item.cc index 3ee8985c779..8cb898e310f 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -3787,7 +3787,7 @@ bool Item_param::set_from_item(THD *thd, Item *item) } } struct st_value tmp; - if (!item->store(&tmp, 0)) + if (!item->save_in_value(&tmp)) { unsigned_flag= item->unsigned_flag; switch (item->cmp_type()) { diff --git a/sql/item.h b/sql/item.h index a6c3ac1b686..440905b51f6 100644 --- a/sql/item.h +++ b/sql/item.h @@ -676,54 +676,9 @@ public: */ virtual inline void quick_fix_field() { fixed= 1; } - bool store(struct st_value *value, ulonglong fuzzydate) + bool save_in_value(struct st_value *value) { - switch (cmp_type()) { - case INT_RESULT: - { - value->m_type= unsigned_flag ? DYN_COL_UINT : DYN_COL_INT; - value->value.m_longlong= val_int(); - break; - } - case REAL_RESULT: - { - value->m_type= DYN_COL_DOUBLE; - value->value.m_double= val_real(); - break; - } - case DECIMAL_RESULT: - { - value->m_type= DYN_COL_DECIMAL; - my_decimal *dec= val_decimal(&value->m_decimal); - if (dec != &value->m_decimal && !null_value) - my_decimal2decimal(dec, &value->m_decimal); - break; - } - case STRING_RESULT: - { - value->m_type= DYN_COL_STRING; - String *str= val_str(&value->m_string); - if (str != &value->m_string && !null_value) - value->m_string.set(str->ptr(), str->length(), str->charset()); - break; - } - case TIME_RESULT: - { - value->m_type= DYN_COL_DATETIME; - get_date(&value->value.m_time, fuzzydate); - break; - } - case ROW_RESULT: - DBUG_ASSERT(false); - null_value= true; - break; - } - if (null_value) - { - value->m_type= DYN_COL_NULL; - return true; - } - return false; + return type_handler()->Item_save_in_value(this, value); } /* Function returns 1 on overflow and -1 on fatal errors */ diff --git a/sql/sql_type.cc b/sql/sql_type.cc index 8245d0993be..ad9059ecd57 100644 --- a/sql/sql_type.cc +++ b/sql/sql_type.cc @@ -3808,4 +3808,91 @@ Type_handler_olddecimal::type_handler_for_union(const Item *item) const } +/***************************************************************************/ + +bool Type_handler::check_null(const Item *item, st_value *value) const +{ + if (item->null_value) + { + value->m_type= DYN_COL_NULL; + return true; + } + return false; +} + + +bool Type_handler_null:: + Item_save_in_value(Item *item, st_value *value) const +{ + value->m_type= DYN_COL_NULL; + return true; +} + + +bool Type_handler_row:: + Item_save_in_value(Item *item, st_value *value) const +{ + DBUG_ASSERT(0); + value->m_type= DYN_COL_NULL; + return true; +} + + +bool Type_handler_int_result:: + Item_save_in_value(Item *item, st_value *value) const +{ + value->m_type= item->unsigned_flag ? DYN_COL_UINT : DYN_COL_INT; + value->value.m_longlong= item->val_int(); + return check_null(item, value); +} + + +bool Type_handler_real_result:: + Item_save_in_value(Item *item, st_value *value) const +{ + value->m_type= DYN_COL_DOUBLE; + value->value.m_double= item->val_real(); + return check_null(item, value); +} + + +bool Type_handler_decimal_result:: + Item_save_in_value(Item *item, st_value *value) const +{ + value->m_type= DYN_COL_DECIMAL; + my_decimal *dec= item->val_decimal(&value->m_decimal); + if (dec != &value->m_decimal && !item->null_value) + my_decimal2decimal(dec, &value->m_decimal); + return check_null(item, value); +} + + +bool Type_handler_string_result:: + Item_save_in_value(Item *item, st_value *value) const +{ + value->m_type= DYN_COL_STRING; + String *str= item->val_str(&value->m_string); + if (str != &value->m_string && !item->null_value) + value->m_string.set(str->ptr(), str->length(), str->charset()); + return check_null(item, value); +} + + +bool Type_handler_temporal_with_date:: + Item_save_in_value(Item *item, st_value *value) const +{ + value->m_type= DYN_COL_DATETIME; + item->get_date(&value->value.m_time, sql_mode_for_dates(current_thd)); + return check_null(item, value); +} + + +bool Type_handler_time_common:: + Item_save_in_value(Item *item, st_value *value) const +{ + value->m_type= DYN_COL_DATETIME; + item->get_time(&value->value.m_time); + return check_null(item, value); +} + /***************************************************************************/ diff --git a/sql/sql_type.h b/sql/sql_type.h index abd8463ec17..d9694c98cb8 100644 --- a/sql/sql_type.h +++ b/sql/sql_type.h @@ -63,6 +63,7 @@ class in_vector; class Type_std_attributes; class Sort_param; class Arg_comparator; +struct st_value; struct TABLE; struct SORT_FIELD_ATTR; @@ -403,6 +404,7 @@ protected: Item_func_or_sum_illegal_param(const char *name) const; bool Item_func_or_sum_illegal_param(const Item_func_or_sum *) const; + bool check_null(const Item *item, st_value *value) const; public: static const Type_handler *blob_type_handler(uint max_octet_length); static const Type_handler *string_type_handler(uint max_octet_length); @@ -537,6 +539,7 @@ public: SORT_FIELD_ATTR *attr) const= 0; virtual uint32 max_display_length(const Item *item) const= 0; + virtual bool Item_save_in_value(Item *item, st_value *value) const= 0; virtual int Item_save_in_field(Item *item, Field *field, bool no_conversions) const= 0; @@ -752,6 +755,7 @@ public: DBUG_ASSERT(0); return 0; } + bool Item_save_in_value(Item *item, st_value *value) const; int Item_save_in_field(Item *item, Field *field, bool no_conversions) const { DBUG_ASSERT(0); @@ -960,6 +964,7 @@ public: void sortlength(THD *thd, const Type_std_attributes *item, SORT_FIELD_ATTR *attr) const; + bool Item_save_in_value(Item *item, st_value *value) const; int Item_save_in_field(Item *item, Field *field, bool no_conversions) const; Item_cache *Item_get_cache(THD *thd, const Item *item) const; bool set_comparator_func(Arg_comparator *cmp) const; @@ -1019,6 +1024,7 @@ public: const Type_std_attributes *item, SORT_FIELD_ATTR *attr) const; uint32 max_display_length(const Item *item) const; + bool Item_save_in_value(Item *item, st_value *value) const; int Item_save_in_field(Item *item, Field *field, bool no_conversions) const; Item_cache *Item_get_cache(THD *thd, const Item *item) const; bool set_comparator_func(Arg_comparator *cmp) const; @@ -1074,6 +1080,7 @@ public: void sortlength(THD *thd, const Type_std_attributes *item, SORT_FIELD_ATTR *attr) const; + bool Item_save_in_value(Item *item, st_value *value) const; int Item_save_in_field(Item *item, Field *field, bool no_conversions) const; Item_cache *Item_get_cache(THD *thd, const Item *item) const; bool set_comparator_func(Arg_comparator *cmp) const; @@ -1202,6 +1209,7 @@ public: { return Item_temporal_precision(item, false); } + bool Item_save_in_value(Item *item, st_value *value) const; int Item_save_in_field(Item *item, Field *field, bool no_conversions) const; String *print_item_value(THD *thd, Item *item, String *str) const { @@ -1459,6 +1467,7 @@ public: return Item_divisor_precision_increment_with_seconds(item); } const Type_handler *type_handler_for_comparison() const; + bool Item_save_in_value(Item *item, st_value *value) const; int Item_save_in_field(Item *item, Field *field, bool no_conversions) const; String *print_item_value(THD *thd, Item *item, String *str) const; bool Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func, @@ -1500,6 +1509,7 @@ class Type_handler_temporal_with_date: public Type_handler_temporal_result public: virtual ~Type_handler_temporal_with_date() {} const Type_handler *type_handler_for_comparison() const; + bool Item_save_in_value(Item *item, st_value *value) const; int Item_save_in_field(Item *item, Field *field, bool no_conversions) const; cmp_item *make_cmp_item(THD *thd, CHARSET_INFO *cs) const; in_vector *make_in_vector(THD *, const Item_func_in *, uint nargs) const; @@ -1698,6 +1708,7 @@ public: const Type_handler *type_handler_for_tmp_table(const Item *item) const; const Type_handler *type_handler_for_union(const Item *) const; uint32 max_display_length(const Item *item) const { return 0; } + bool Item_save_in_value(Item *item, st_value *value) const; Field *make_conversion_table_field(TABLE *, uint metadata, const Field *target) const; Field *make_table_field(const LEX_CSTRING *name,