Commit 79f5ad3d authored by unknown's avatar unknown

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

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


sql/item.cc:
  Auto merged
sql/sql_base.cc:
  Auto merged
parents e9cc39c4 ca119d39
...@@ -454,6 +454,7 @@ void Item_ident::cleanup() ...@@ -454,6 +454,7 @@ void Item_ident::cleanup()
db_name= orig_db_name; db_name= orig_db_name;
table_name= orig_table_name; table_name= orig_table_name;
field_name= orig_field_name; field_name= orig_field_name;
depended_from= 0;
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
...@@ -2359,6 +2360,71 @@ static void mark_as_dependent(THD *thd, SELECT_LEX *last, SELECT_LEX *current, ...@@ -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);
}
}
/* /*
......
...@@ -1795,6 +1795,12 @@ public: ...@@ -1795,6 +1795,12 @@ public:
static enum_field_types get_real_type(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_buff *new_Item_buff(Item *item);
extern Item_result item_cmp_type(Item_result a,Item_result b); extern Item_result item_cmp_type(Item_result a,Item_result b);
......
...@@ -122,6 +122,9 @@ public: ...@@ -122,6 +122,9 @@ public:
friend bool Item_field::fix_fields(THD *, TABLE_LIST *, Item **); friend bool Item_field::fix_fields(THD *, TABLE_LIST *, Item **);
friend bool Item_ref::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 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 */ /* single value subselect */
......
...@@ -2689,6 +2689,14 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables, ...@@ -2689,6 +2689,14 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables,
{ {
if (found == WRONG_GRANT) if (found == WRONG_GRANT)
return (Field*) 0; 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; return found;
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment