diff options
Diffstat (limited to 'sql/item.cc')
-rw-r--r-- | sql/item.cc | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/sql/item.cc b/sql/item.cc index a465c2d4e36..bffa7e2990d 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1179,6 +1179,42 @@ Item *Item::safe_charset_converter(CHARSET_INFO *tocs) /** + Some pieces of the code do not support changing of + Item_cache to other Item types. + + Example: + Item_singlerow_subselect has "Item_cache **row". + Creating of Item_func_conv_charset followed by THD::change_item_tree() + should not change row[i] from Item_cache directly to Item_func_conv_charset, because Item_singlerow_subselect + because Item_singlerow_subselect later calls Item_cache-specific methods, + e.g. row[i]->store() and row[i]->cache_value(). + + Let's wrap Item_func_conv_charset in a new Item_cache, + so the Item_cache-specific methods can still be used for + Item_singlerow_subselect::row[i] safely. + + As a bonus we cache the converted value, instead of converting every time + + TODO: we should eventually check all other use cases of change_item_tree(). + Perhaps some more potentially dangerous substitution examples exist. +*/ +Item *Item_cache::safe_charset_converter(CHARSET_INFO *tocs) +{ + if (!example) + return Item::safe_charset_converter(tocs); + Item *conv= example->safe_charset_converter(tocs); + if (conv == example) + return this; + Item_cache *cache; + if (!conv || !(cache= new Item_cache_str(conv))) + return NULL; // Safe conversion is not possible, or OEM + cache->setup(conv); + cache->fixed= false; // Make Item::fix_fields() happy + return cache; +} + + +/** @details Created mostly for mysql_prepare_table(). Important when a string ENUM/SET column is described with a numeric default value: @@ -9471,6 +9507,11 @@ bool Item_type_holder::join_types(THD *thd, Item *item) item_decimals= 0; decimals= MY_MAX(decimals, item_decimals); } + + if (fld_type == FIELD_TYPE_GEOMETRY) + geometry_type= + Field_geom::geometry_type_merge(geometry_type, item->get_geometry_type()); + if (Field::result_merge_type(fld_type) == DECIMAL_RESULT) { decimals= MY_MIN(MY_MAX(decimals, item->decimals), DECIMAL_MAX_SCALE); |