Loading sql/item.cc +67 −1 Original line number Diff line number Diff line Loading @@ -454,6 +454,7 @@ void Item_ident::cleanup() db_name= orig_db_name; table_name= orig_table_name; field_name= orig_field_name; depended_from= 0; DBUG_VOID_RETURN; } Loading Loading @@ -2359,6 +2360,71 @@ static void mark_as_dependent(THD *thd, SELECT_LEX *last, SELECT_LEX *current, } /* Mark range of selects and resolved identifier (field/reference) item as dependent SYNOPSIS mark_select_range_as_dependent() thd - thread handler current_sel - current select (select where resolved_item was placed) last_select - select where resolved_item was resolved found_field - field which was found during resolving found_item - Item which was found during resolving (if resolved identifier belongs to VIEW) resolved_item - Identifier which was resolved NOTE: We have to mark all items between current_sel (including) and last_select (excluding) as dependend (select before last_select should be marked with actual table mask used by resolved item, all other with OUTER_REF_TABLE_BIT) and also write dependence information to Item of resolved identifier. */ void mark_select_range_as_dependent(THD *thd, SELECT_LEX *current_sel, SELECT_LEX *last_select, Field *found_field, Item *found_item, Item_ident *resolved_item) { /* Go from current SELECT to SELECT where field was resolved (it have to be reachable from current SELECT, because it was already done once when we resolved this field and cached result of resolving) */ SELECT_LEX *previous_select= current_sel; for(; previous_select->outer_select() != last_select; previous_select= previous_select->outer_select()) { Item_subselect *prev_subselect_item= previous_select->master_unit()->item; prev_subselect_item->used_tables_cache|= OUTER_REF_TABLE_BIT; prev_subselect_item->const_item_cache= 0; } { Item_subselect *prev_subselect_item= previous_select->master_unit()->item; Item_ident *dependent= resolved_item; if (found_field == view_ref_found) { Item::Type type= found_item->type(); prev_subselect_item->used_tables_cache|= found_item->used_tables(); dependent= ((type == Item::REF_ITEM || type == Item::FIELD_ITEM) ? (Item_ident*) found_item : 0); } else prev_subselect_item->used_tables_cache|= found_field->table->map; prev_subselect_item->const_item_cache= 0; mark_as_dependent(thd, last_select, current_sel, resolved_item, dependent); } } /* Loading sql/item.h +6 −0 Original line number Diff line number Diff line Loading @@ -1795,6 +1795,12 @@ class Item_type_holder: public Item static enum_field_types get_real_type(Item *); }; class st_select_lex; void mark_select_range_as_dependent(THD *thd, st_select_lex *current_sel, st_select_lex *last_select, Field *found_field, Item *found_item, Item_ident *resolved_item); extern Item_buff *new_Item_buff(Item *item); extern Item_result item_cmp_type(Item_result a,Item_result b); Loading sql/item_subselect.h +3 −0 Original line number Diff line number Diff line Loading @@ -122,6 +122,9 @@ class Item_subselect :public Item_result_field friend bool Item_field::fix_fields(THD *, TABLE_LIST *, Item **); friend bool Item_ref::fix_fields(THD *, TABLE_LIST *, Item **); friend bool Item_param::fix_fields(THD *, TABLE_LIST *, Item **); friend void mark_select_range_as_dependent(THD*, st_select_lex*, st_select_lex*, Field*, Item*, Item_ident*); }; /* single value subselect */ Loading sql/sql_base.cc +8 −0 Original line number Diff line number Diff line Loading @@ -2689,6 +2689,14 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables, { if (found == WRONG_GRANT) return (Field*) 0; { SELECT_LEX *current_sel= thd->lex->current_select; SELECT_LEX *last_select= item->cached_table->select_lex; /* check that field was resolved in outer query */ if (current_sel != last_select) mark_select_range_as_dependent(thd, current_sel, last_select, found, *ref, item); } return found; } } Loading Loading
sql/item.cc +67 −1 Original line number Diff line number Diff line Loading @@ -454,6 +454,7 @@ void Item_ident::cleanup() db_name= orig_db_name; table_name= orig_table_name; field_name= orig_field_name; depended_from= 0; DBUG_VOID_RETURN; } Loading Loading @@ -2359,6 +2360,71 @@ static void mark_as_dependent(THD *thd, SELECT_LEX *last, SELECT_LEX *current, } /* Mark range of selects and resolved identifier (field/reference) item as dependent SYNOPSIS mark_select_range_as_dependent() thd - thread handler current_sel - current select (select where resolved_item was placed) last_select - select where resolved_item was resolved found_field - field which was found during resolving found_item - Item which was found during resolving (if resolved identifier belongs to VIEW) resolved_item - Identifier which was resolved NOTE: We have to mark all items between current_sel (including) and last_select (excluding) as dependend (select before last_select should be marked with actual table mask used by resolved item, all other with OUTER_REF_TABLE_BIT) and also write dependence information to Item of resolved identifier. */ void mark_select_range_as_dependent(THD *thd, SELECT_LEX *current_sel, SELECT_LEX *last_select, Field *found_field, Item *found_item, Item_ident *resolved_item) { /* Go from current SELECT to SELECT where field was resolved (it have to be reachable from current SELECT, because it was already done once when we resolved this field and cached result of resolving) */ SELECT_LEX *previous_select= current_sel; for(; previous_select->outer_select() != last_select; previous_select= previous_select->outer_select()) { Item_subselect *prev_subselect_item= previous_select->master_unit()->item; prev_subselect_item->used_tables_cache|= OUTER_REF_TABLE_BIT; prev_subselect_item->const_item_cache= 0; } { Item_subselect *prev_subselect_item= previous_select->master_unit()->item; Item_ident *dependent= resolved_item; if (found_field == view_ref_found) { Item::Type type= found_item->type(); prev_subselect_item->used_tables_cache|= found_item->used_tables(); dependent= ((type == Item::REF_ITEM || type == Item::FIELD_ITEM) ? (Item_ident*) found_item : 0); } else prev_subselect_item->used_tables_cache|= found_field->table->map; prev_subselect_item->const_item_cache= 0; mark_as_dependent(thd, last_select, current_sel, resolved_item, dependent); } } /* Loading
sql/item.h +6 −0 Original line number Diff line number Diff line Loading @@ -1795,6 +1795,12 @@ class Item_type_holder: public Item static enum_field_types get_real_type(Item *); }; class st_select_lex; void mark_select_range_as_dependent(THD *thd, st_select_lex *current_sel, st_select_lex *last_select, Field *found_field, Item *found_item, Item_ident *resolved_item); extern Item_buff *new_Item_buff(Item *item); extern Item_result item_cmp_type(Item_result a,Item_result b); Loading
sql/item_subselect.h +3 −0 Original line number Diff line number Diff line Loading @@ -122,6 +122,9 @@ class Item_subselect :public Item_result_field friend bool Item_field::fix_fields(THD *, TABLE_LIST *, Item **); friend bool Item_ref::fix_fields(THD *, TABLE_LIST *, Item **); friend bool Item_param::fix_fields(THD *, TABLE_LIST *, Item **); friend void mark_select_range_as_dependent(THD*, st_select_lex*, st_select_lex*, Field*, Item*, Item_ident*); }; /* single value subselect */ Loading
sql/sql_base.cc +8 −0 Original line number Diff line number Diff line Loading @@ -2689,6 +2689,14 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables, { if (found == WRONG_GRANT) return (Field*) 0; { SELECT_LEX *current_sel= thd->lex->current_select; SELECT_LEX *last_select= item->cached_table->select_lex; /* check that field was resolved in outer query */ if (current_sel != last_select) mark_select_range_as_dependent(thd, current_sel, last_select, found, *ref, item); } return found; } } Loading