Commit 71a2047d authored by Sergey Petrunya's avatar Sergey Petrunya

Change Field_enumerator to enumerate Item_field-s not Field-s.

In Item_ref::fix_fields() do invoke mark_as_dependent() for outside 
references in all cases (see email for more details)

sql/item.cc:
  In Item_ref::fix_fields() do invoke mark_as_dependent() for outside references in all cases.
sql/item.h:
  Change Field_enumerator to enumerate Item_field-s not Field-s.
sql/item_subselect.cc:
  Change Field_enumerator to enumerate Item_field-s not Field-s.
sql/opt_table_elimination.cc:
  Change Field_enumerator to enumerate Item_field-s not Field-s.
parent 2419ef96
......@@ -1959,7 +1959,7 @@ void Item_field::reset_field(Field *f)
bool Item_field::enumerate_field_refs_processor(uchar *arg)
{
Field_enumerator *fe= (Field_enumerator*)arg;
fe->visit_field(field);
fe->visit_field(this);
return FALSE;
}
......@@ -5779,6 +5779,35 @@ Item_ref::Item_ref(Name_resolution_context *context_arg,
set_properties();
}
/*
A Field_enumerator-compatible class that invokes mark_as_dependent() for
each field that is a reference to some ancestor of current_select.
*/
class Dependency_marker: public Field_enumerator
{
public:
THD *thd;
st_select_lex *current_select;
virtual void visit_field(Item_field *item)
{
// Find which select the field is in. This is achieved by walking up
// the select tree and looking for the table of interest.
st_select_lex *sel;
for (sel= current_select; sel; sel= sel->outer_select())
{
TABLE_LIST *tbl;
for (tbl= sel->leaf_tables; tbl; tbl= tbl->next_leaf)
{
if (tbl->table == item->field->table)
{
if (sel != current_select)
mark_as_dependent(thd, sel, current_select, item, item);
return;
}
}
}
}
};
/**
Resolve the name of a reference to a column reference.
......@@ -6038,6 +6067,20 @@ bool Item_ref::fix_fields(THD *thd, Item **reference)
last_checked_context->select_lex->nest_level);
}
}
else
{
;
/*
It could be that we're referring to something that's in ancestor selects.
We must make an appropriate mark_as_dependent() call for each such
outside reference.
*/
Dependency_marker dep_marker;
dep_marker.current_select= current_sel;
dep_marker.thd= thd;
(*ref)->walk(&Item::enumerate_field_refs_processor, FALSE,
(uchar*)&dep_marker);
}
DBUG_ASSERT(*ref);
/*
......
......@@ -1134,7 +1134,7 @@ public:
class Field_enumerator
{
public:
virtual void visit_field(Field *field)= 0;
virtual void visit_field(Item_field *field)= 0;
virtual ~Field_enumerator() {}; /* purecov: inspected */
};
......
......@@ -319,13 +319,13 @@ class Field_fixer: public Field_enumerator
public:
table_map used_tables; /* Collect used_tables here */
st_select_lex *new_parent; /* Select we're in */
virtual void visit_field(Field *field)
virtual void visit_field(Item_field *item)
{
//for (TABLE_LIST *tbl= new_parent->leaf_tables; tbl; tbl= tbl->next_local)
//{
// if (tbl->table == field->table)
// {
used_tables|= field->table->map;
used_tables|= item->field->table->map;
// return;
// }
//}
......
......@@ -922,8 +922,9 @@ public:
Field_dependency_recorder(Dep_analysis_context *ctx_arg): ctx(ctx_arg)
{}
void visit_field(Field *field)
void visit_field(Item_field *item)
{
Field *field= item->field;
Dep_value_table *tbl_dep;
if ((tbl_dep= ctx->table_deps[field->table->tablenr]))
{
......
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