diff options
author | unknown <konstantin@mysql.com> | 2005-05-04 16:54:36 +0400 |
---|---|---|
committer | unknown <konstantin@mysql.com> | 2005-05-04 16:54:36 +0400 |
commit | 3c223a34cff4a375a32f3147d43b84604e19f150 (patch) | |
tree | cef249e7b30094dc245b6ffd327599e974a8b617 /sql/item.cc | |
parent | a82865375edd3af42b77f3561fb88f62b0f2e1bf (diff) | |
parent | 39f8776f897c6eb394f3b07b09e515c9fc1c2c81 (diff) | |
download | mariadb-git-3c223a34cff4a375a32f3147d43b84604e19f150.tar.gz |
Merge bk-internal.mysql.com:/home/bk/mysql-5.0
into mysql.com:/opt/local/work/mysql-5.0-root
sql/item.cc:
Auto merged
sql/item.h:
Auto merged
Diffstat (limited to 'sql/item.cc')
-rw-r--r-- | sql/item.cc | 68 |
1 files changed, 67 insertions, 1 deletions
diff --git a/sql/item.cc b/sql/item.cc index 44a39872138..5a49124fc43 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -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; } @@ -2423,7 +2424,7 @@ bool Item_ref_null_helper::get_date(TIME *ltime, uint fuzzydate) */ static void mark_as_dependent(THD *thd, SELECT_LEX *last, SELECT_LEX *current, - Item_ident *resolved_item, + Item_ident *resolved_item, Item_ident *mark_item) { const char *db_name= (resolved_item->db_name ? @@ -2448,6 +2449,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); + } +} /* |