diff options
author | Sergei Golubchik <serg@mariadb.org> | 2017-02-10 17:01:45 +0100 |
---|---|---|
committer | Sergei Golubchik <serg@mariadb.org> | 2017-02-10 17:01:45 +0100 |
commit | 2195bb4e416232ab807ff67eecf03b1223bf6bff (patch) | |
tree | 4555af02df68cb0f26d454b1cf65086b62542875 /sql/item.cc | |
parent | 3ae038b732ce503fb839e9095355e05f5c6866f9 (diff) | |
parent | bc4686f0f4d17dc57dd727c9f5390caa3022bdca (diff) | |
download | mariadb-git-2195bb4e416232ab807ff67eecf03b1223bf6bff.tar.gz |
Merge branch '10.1' into 10.2
Diffstat (limited to 'sql/item.cc')
-rw-r--r-- | sql/item.cc | 41 |
1 files changed, 40 insertions, 1 deletions
diff --git a/sql/item.cc b/sql/item.cc index 369b2df2675..4ce0b318ed0 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1189,7 +1189,8 @@ Item *Item_cache::safe_charset_converter(THD *thd, CHARSET_INFO *tocs) if (conv == example) return this; Item_cache *cache; - if (!conv || !(cache= new (thd->mem_root) Item_cache_str(thd, conv))) + if (!conv || conv->fix_fields(thd, (Item **) NULL) || + !(cache= new (thd->mem_root) Item_cache_str(thd, conv))) return NULL; // Safe conversion is not possible, or OEM cache->setup(thd, conv); cache->fixed= false; // Make Item::fix_fields() happy @@ -2885,6 +2886,44 @@ void Item_field::fix_after_pullout(st_select_lex *new_parent, Item **ref) depended_from= NULL; if (context) { + bool need_change= false; + /* + Suppose there are nested selects: + + select_id=1 + select_id=2 + select_id=3 <----+ + select_id=4 -+ + select_id=5 --+ + + Suppose, pullout operation has moved anything that had select_id=4 or 5 + in to select_id=3. + + If this Item_field had a name resolution context pointing into select_lex + with id=4 or id=5, it needs a new name resolution context. + + However, it could also be that this object is a part of outer reference: + Item_ref(Item_field(field in select with select_id=1))). + - The Item_ref object has a context with select_id=5, and so needs a new + name resolution context. + - The Item_field object has a context with select_id=1, and doesn't need + a new name resolution context. + + So, the following loop walks from Item_field's current context upwards. + If we find that the select we've been pulled out to is up there, we + create the new name resolution context. Otherwise, we don't. + */ + for (Name_resolution_context *ct= context; ct; ct= ct->outer_context) + { + if (new_parent == ct->select_lex) + { + need_change= true; + break; + } + } + if (!need_change) + return; + Name_resolution_context *ctx= new Name_resolution_context(); if (context->select_lex == new_parent) { |