diff --git a/sql/field.h b/sql/field.h index cdb80a5973a..1d6039d3cdf 100644 --- a/sql/field.h +++ b/sql/field.h @@ -1289,6 +1289,7 @@ public: uint fill_cache_field(struct st_cache_field *copy); virtual bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate); bool get_time(MYSQL_TIME *ltime) { return get_date(ltime, TIME_TIME_ONLY); } + virtual TYPELIB *get_typelib() const { return NULL; } virtual CHARSET_INFO *charset(void) const { return &my_charset_bin; } virtual CHARSET_INFO *charset_for_protocol(void) const { return binary() ? &my_charset_bin : charset(); } @@ -3547,6 +3548,7 @@ public: /* enum and set are sorted as integers */ CHARSET_INFO *sort_charset(void) const { return &my_charset_bin; } uint decimals() const { return 0; } + TYPELIB *get_typelib() const { return typelib; } virtual uchar *pack(uchar *to, const uchar *from, uint max_length); virtual const uchar *unpack(uchar *to, const uchar *from, diff --git a/sql/item.cc b/sql/item.cc index 3ecca83ea17..20945027dbc 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -9986,21 +9986,14 @@ void Item_type_holder::get_full_info(Item *item) if (Item_type_holder::real_type_handler() == &type_handler_enum || Item_type_holder::real_type_handler() == &type_handler_set) { - if (item->type() == Item::SUM_FUNC_ITEM && - (((Item_sum*)item)->sum_func() == Item_sum::MAX_FUNC || - ((Item_sum*)item)->sum_func() == Item_sum::MIN_FUNC)) - item = ((Item_sum*)item)->get_arg(0); + TYPELIB *item_typelib= item->get_typelib(); /* We can have enum/set type after merging only if we have one enum|set field (or MIN|MAX(enum|set field)) and number of NULL fields */ - DBUG_ASSERT((enum_set_typelib && - item->real_type_handler() == &type_handler_null) || - (!enum_set_typelib && - item->real_item()->type() == Item::FIELD_ITEM && - (item->real_type_handler() == &type_handler_enum || - item->real_type_handler() == &type_handler_set) && - ((Field_enum*)((Item_field *) item->real_item())->field)->typelib)); + DBUG_ASSERT(item->real_type_handler() == &type_handler_null || + (enum_set_typelib && !item_typelib) || + (!enum_set_typelib && item_typelib)); if (!enum_set_typelib) { enum_set_typelib= ((Field_enum*)((Item_field *) item->real_item())->field)->typelib; diff --git a/sql/item.h b/sql/item.h index c81f4833ebd..4ef23755f94 100644 --- a/sql/item.h +++ b/sql/item.h @@ -787,6 +787,7 @@ public: { return type_handler()->max_display_length(this); } + virtual TYPELIB *get_typelib() const { return NULL; } Item_cache* get_cache(THD *thd) const { return type_handler()->Item_get_cache(thd, this); @@ -2682,6 +2683,7 @@ public: return &type_handler_null; return field->type_handler(); } + TYPELIB *get_typelib() const { return field->get_typelib(); } enum_monotonicity_info get_monotonicity_info() const { return MONOTONIC_STRICT_INCREASING; @@ -4321,6 +4323,11 @@ public: { return ref ? (*ref)->real_item() : this; } + TYPELIB *get_typelib() const + { + return ref ? (*ref)->get_typelib() : NULL; + } + bool walk(Item_processor processor, bool walk_subquery, void *arg) { if (ref && *ref) diff --git a/sql/item_sum.h b/sql/item_sum.h index dee480ccf0a..c1485738b11 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -1044,6 +1044,7 @@ protected: } const Type_handler *type_handler() const { return Type_handler_hybrid_field_type::type_handler(); } + TYPELIB *get_typelib() const { return args[0]->get_typelib(); } void update_field(); void min_max_update_str_field(); void min_max_update_real_field();