Commit 7b4374f6 authored by unknown's avatar unknown
Browse files

Merge book.sanja.is.com.ua:/Users/bell/mysql/bk/mysql-5.0

into book.sanja.is.com.ua:/Users/bell/mysql/bk/work-test-5.0


BitKeeper/etc/logging_ok:
  Logging to logging@openlogging.org accepted
parents 9724795f 371b26e1
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ bar@mysql.com
bar@noter.intranet.mysql.r18.ru
bell@51.0.168.192.in-addr.arpa
bell@52.0.168.192.in-addr.arpa
bell@book.sanja.is.com.ua
bell@laptop.sanja.is.com.ua
bell@sanja.is.com.ua
bk@admin.bk
+67 −1
Original line number Diff line number Diff line
@@ -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;
}

@@ -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
    last_select   - select where resolved_item was resolved
    current_sel   - current select (select where resolved_item was placed)
    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 *last_select,
                                    SELECT_LEX *current_sel,
                                    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);
  }
}


/*
+6 −0
Original line number Diff line number Diff line
@@ -1800,6 +1800,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 *last_select,
                                    st_select_lex *current_sel,
                                    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);
+3 −0
Original line number Diff line number Diff line
@@ -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 */
+11 −0
Original line number Diff line number Diff line
@@ -2689,6 +2689,17 @@ 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;
        /*
          If the field was an outer referencee, mark all selects using this
          sub query as dependent of the outer query
        */
        if (current_sel != last_select)
          mark_select_range_as_dependent(thd, last_select, current_sel,
                                         found, *ref, item);
      }
      return found;
    }
  }