At file:///home/psergey/dev/maria-5.3-subqueries-r7/ ------------------------------------------------------------ revno: 2765 revision-id: psergey@askmonty.org-20100221063223-h0f7u2low7rtjixc parent: psergey@askmonty.org-20100221033618-83dgm2h9ingzmhcc committer: Sergey Petrunya <psergey@askmonty.org> branch nick: maria-5.3-subqueries-r7 timestamp: Sun 2010-02-21 08:32:23 +0200 message: 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) === modified file 'sql/item.cc' --- a/sql/item.cc 2010-02-11 23:59:58 +0000 +++ b/sql/item.cc 2010-02-21 06:32:23 +0000 @@ -1959,7 +1959,7 @@ 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 @@ 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 @@ 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); /* === modified file 'sql/item.h' --- a/sql/item.h 2010-02-21 03:36:18 +0000 +++ b/sql/item.h 2010-02-21 06:32:23 +0000 @@ -1134,7 +1134,7 @@ class Field_enumerator { public: - virtual void visit_field(Field *field)= 0; + virtual void visit_field(Item_field *field)= 0; virtual ~Field_enumerator() {}; /* purecov: inspected */ }; === modified file 'sql/item_subselect.cc' --- a/sql/item_subselect.cc 2010-02-21 03:36:18 +0000 +++ b/sql/item_subselect.cc 2010-02-21 06:32:23 +0000 @@ -319,13 +319,13 @@ 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; // } //} === modified file 'sql/opt_table_elimination.cc' --- a/sql/opt_table_elimination.cc 2010-01-17 14:51:10 +0000 +++ b/sql/opt_table_elimination.cc 2010-02-21 06:32:23 +0000 @@ -922,8 +922,9 @@ 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])) {