summaryrefslogtreecommitdiff
path: root/sql/item.cc
diff options
context:
space:
mode:
authorunknown <konstantin@mysql.com>2005-05-04 16:54:36 +0400
committerunknown <konstantin@mysql.com>2005-05-04 16:54:36 +0400
commit3c223a34cff4a375a32f3147d43b84604e19f150 (patch)
treecef249e7b30094dc245b6ffd327599e974a8b617 /sql/item.cc
parenta82865375edd3af42b77f3561fb88f62b0f2e1bf (diff)
parent39f8776f897c6eb394f3b07b09e515c9fc1c2c81 (diff)
downloadmariadb-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.cc68
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);
+ }
+}
/*