At file:///home/psergey/dev/maria-5.1-table-elim-r10/
------------------------------------------------------------
revno: 2721
revision-id: psergey(a)askmonty.org-20090815060803-0yvp5mmgo87emykp
parent: psergey(a)askmonty.org-20090813211212-jghejwxsl6adtopl
committer: Sergey Petrunya <psergey(a)askmonty.org>
branch nick: maria-5.1-table-elim-r10
timestamp: Sat 2009-08-15 10:08:03 +0400
message:
MWL#17: Address 2nd post-review feedback
- Switch from uniform graph to bipartite graph with two kinds of nodes:
"values" (tables and fields) and "modules" (t.col=func(...) equalities,
multi-equalities, unique keys, inner sides of outer joins).
- Rename functions, classes, etc.
=== modified file 'sql/opt_table_elimination.cc'
--- a/sql/opt_table_elimination.cc 2009-08-13 20:44:52 +0000
+++ b/sql/opt_table_elimination.cc 2009-08-15 06:08:03 +0000
@@ -40,19 +40,78 @@
Table elimination is redone on every PS re-execution.
*/
-
-/*
- An abstract structure that represents some entity that's being dependent on
- some other entity.
-*/
-
-class Func_dep : public Sql_alloc
-{
-public:
- enum {
- FD_INVALID,
+class Value_dep
+{
+public:
+ enum {
+ VALUE_FIELD,
+ VALUE_TABLE,
+ } type; /* Type of the object */
+
+ bool bound;
+ Value_dep *next;
+};
+
+class Field_value;
+class Table_value;
+class Outer_join_module;
+class Key_module;
+
+/*
+ A table field. There is only one such object for any tblX.fieldY
+ - the field epends on its table and equalities
+ - expressions that use the field are its dependencies
+*/
+class Field_value : public Value_dep
+{
+public:
+ Field_value(Table_value *table_arg, Field *field_arg) :
+ table(table_arg), field(field_arg)
+ {
+ type= Value_dep::VALUE_FIELD;
+ }
+
+ Table_value *table; /* Table this field is from */
+ Field *field;
+
+ /*
+ Field_deps that belong to one table form a linked list. list members are
+ ordered by field_index
+ */
+ Field_value *next_table_field;
+ uint bitmap_offset; /* Offset of our part of the bitmap */
+};
+
+
+/*
+ A table.
+ - table depends on any of its unique keys
+ - has its fields and embedding outer join as dependency.
+*/
+class Table_value : public Value_dep
+{
+public:
+ Table_value(TABLE *table_arg) :
+ table(table_arg), fields(NULL), keys(NULL), outer_join_dep(NULL)
+ {
+ type= Value_dep::VALUE_TABLE;
+ }
+ TABLE *table;
+ Field_value *fields; /* Ordered list of fields that belong to this table */
+ Key_module *keys; /* Ordered list of Unique keys in this table */
+ Outer_join_module *outer_join_dep; /* Innermost eliminable outer join we're in */
+};
+
+
+/*
+ A 'module'
+*/
+
+class Module_dep : public Sql_alloc
+{
+public:
+ enum {
FD_EXPRESSION,
- FD_FIELD,
FD_MULTI_EQUALITY,
FD_UNIQUE_KEY,
FD_TABLE,
@@ -63,58 +122,26 @@
Used to make a linked list of elements that became bound and thus can
make elements that depend on them bound, too.
*/
- Func_dep *next;
- bool bound; /* TRUE<=> The entity is considered bound */
- Func_dep() : next(NULL), bound(FALSE) {}
+ Module_dep *next;
+ uint unknown_args; /* TRUE<=> The entity is considered bound */
+
+ Module_dep() : next(NULL), unknown_args(0) {}
};
-class Field_dep;
-class Table_dep;
-class Outer_join_dep;
-
/*
A "tbl.column= expr" equality dependency. tbl.column depends on fields
used in expr.
*/
-class Equality_dep : public Func_dep
+class Equality_module : public Module_dep
{
public:
- Field_dep *field;
+ Field_value *field;
Item *val;
/* Used during condition analysis only, similar to KEYUSE::level */
uint level;
-
- /* Number of fields referenced from *val that are not yet 'bound' */
- uint unknown_args;
-};
-
-
-/*
- A table field. There is only one such object for any tblX.fieldY
- - the field epends on its table and equalities
- - expressions that use the field are its dependencies
-*/
-class Field_dep : public Func_dep
-{
-public:
- Field_dep(Table_dep *table_arg, Field *field_arg) :
- table(table_arg), field(field_arg)
- {
- type= Func_dep::FD_FIELD;
- }
-
- Table_dep *table; /* Table this field is from */
- Field *field;
-
- /*
- Field_deps that belong to one table form a linked list. list members are
- ordered by field_index
- */
- Field_dep *next_table_field;
- uint bitmap_offset; /* Offset of our part of the bitmap */
};
@@ -123,41 +150,21 @@
- Unique key depends on all of its components
- Key's table is its dependency
*/
-class Key_dep: public Func_dep
+class Key_module: public Module_dep
{
public:
- Key_dep(Table_dep *table_arg, uint keyno_arg, uint n_parts_arg) :
- table(table_arg), keyno(keyno_arg), n_missing_keyparts(n_parts_arg),
- next_table_key(NULL)
+ Key_module(Table_value *table_arg, uint keyno_arg, uint n_parts_arg) :
+ table(table_arg), keyno(keyno_arg), next_table_key(NULL)
{
- type= Func_dep::FD_UNIQUE_KEY;
+ type= Module_dep::FD_UNIQUE_KEY;
+ unknown_args= n_parts_arg;
}
- Table_dep *table; /* Table this key is from */
+ Table_value *table; /* Table this key is from */
uint keyno;
- uint n_missing_keyparts;
/* Unique keys form a linked list, ordered by keyno */
- Key_dep *next_table_key;
-};
-
-
-/*
- A table.
- - table depends on any of its unique keys
- - has its fields and embedding outer join as dependency.
-*/
-class Table_dep : public Func_dep
-{
-public:
- Table_dep(TABLE *table_arg) :
- table(table_arg), fields(NULL), keys(NULL), outer_join_dep(NULL)
- {
- type= Func_dep::FD_TABLE;
- }
- TABLE *table;
- Field_dep *fields; /* Ordered list of fields that belong to this table */
- Key_dep *keys; /* Ordered list of Unique keys in this table */
- Outer_join_dep *outer_join_dep; /* Innermost eliminable outer join we're in */
-};
+ Key_module *next_table_key;
+};
+
/*
@@ -165,14 +172,14 @@
- it depends on all tables inside it
- has its parent outer join as dependency
*/
-class Outer_join_dep: public Func_dep
+class Outer_join_module: public Module_dep
{
public:
- Outer_join_dep(TABLE_LIST *table_list_arg, table_map missing_tables_arg) :
- table_list(table_list_arg), missing_tables(missing_tables_arg),
- all_tables(missing_tables_arg), parent(NULL)
+ Outer_join_module(TABLE_LIST *table_list_arg, uint n_children) :
+ table_list(table_list_arg), parent(NULL)
{
- type= Func_dep::FD_OUTER_JOIN;
+ type= Module_dep::FD_OUTER_JOIN;
+ unknown_args= n_children;
}
/*
Outer join we're representing. This can be a join nest or a one table that
@@ -184,11 +191,11 @@
Tables within this outer join (and its descendants) that are not yet known
to be functionally dependent.
*/
- table_map missing_tables;
+ table_map missing_tables; //psergey-todo: remove
/* All tables within this outer join and its descendants */
- table_map all_tables;
+ table_map all_tables; //psergey-todo: remove
/* Parent eliminable outer join, if any */
- Outer_join_dep *parent;
+ Outer_join_module *parent;
};
@@ -205,44 +212,45 @@
JOIN *join;
/* Array of equality dependencies */
- Equality_dep *equality_deps;
+ Equality_module *equality_deps;
uint n_equality_deps; /* Number of elements in the array */
- /* tablenr -> Table_dep* mapping. */
- Table_dep *table_deps[MAX_KEY];
+ /* tablenr -> Table_value* mapping. */
+ Table_value *table_deps[MAX_KEY];
/* Outer joins that are candidates for elimination */
- List<Outer_join_dep> oj_deps;
+ List<Outer_join_module> oj_deps;
/* Bitmap of how expressions depend on bits */
MY_BITMAP expr_deps;
};
-
static
-void build_eq_deps_for_cond(Table_elimination *te, Equality_dep **fdeps,
+void build_eq_deps_for_cond(Table_elimination *te, Equality_module **fdeps,
uint *and_level, Item *cond,
table_map usable_tables);
static
void add_eq_dep(Table_elimination *te,
- Equality_dep **eq_dep, uint and_level,
+ Equality_module **eq_dep, uint and_level,
Item_func *cond, Field *field,
bool eq_func, Item **value,
uint num_values, table_map usable_tables);
static
-Equality_dep *merge_func_deps(Equality_dep *start, Equality_dep *new_fields,
- Equality_dep *end, uint and_level);
-
-static Table_dep *get_table_dep(Table_elimination *te, TABLE *table);
-static Field_dep *get_field_dep(Table_elimination *te, Field *field);
-
+Equality_module *merge_func_deps(Equality_module *start, Equality_module *new_fields,
+ Equality_module *end, uint and_level);
+
+static Table_value *get_table_value(Table_elimination *te, TABLE *table);
+static Field_value *get_field_value(Table_elimination *te, Field *field);
+static
+void run_elimination_wave(Table_elimination *te, Module_dep *bound_modules);
void eliminate_tables(JOIN *join);
static void mark_as_eliminated(JOIN *join, TABLE_LIST *tbl);
+#if 0
#ifndef DBUG_OFF
static void dbug_print_deps(Table_elimination *te);
#endif
-
+#endif
/*******************************************************************************************/
/*
@@ -262,14 +270,14 @@
*/
static
-void build_eq_deps_for_cond(Table_elimination *te, Equality_dep **fdeps,
+void build_eq_deps_for_cond(Table_elimination *te, Equality_module **fdeps,
uint *and_level, Item *cond,
table_map usable_tables)
{
if (cond->type() == Item_func::COND_ITEM)
{
List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
- Equality_dep *org_key_fields= *fdeps;
+ Equality_module *org_key_fields= *fdeps;
/* AND/OR */
if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
@@ -293,7 +301,7 @@
Item *item;
while ((item=li++))
{
- Equality_dep *start_key_fields= *fdeps;
+ Equality_module *start_key_fields= *fdeps;
(*and_level)++;
build_eq_deps_for_cond(te, fdeps, and_level, item, usable_tables);
*fdeps= merge_func_deps(org_key_fields, start_key_fields, *fdeps,
@@ -432,7 +440,7 @@
/*
- Perform an OR operation on two (adjacent) Equality_dep arrays.
+ Perform an OR operation on two (adjacent) Equality_module arrays.
SYNOPSIS
merge_func_deps()
@@ -442,7 +450,7 @@
and_level AND-level.
DESCRIPTION
- This function is invoked for two adjacent arrays of Equality_dep elements:
+ This function is invoked for two adjacent arrays of Equality_module elements:
$LEFT_PART $RIGHT_PART
+-----------------------+-----------------------+
@@ -477,19 +485,19 @@
*/
static
-Equality_dep *merge_func_deps(Equality_dep *start, Equality_dep *new_fields,
- Equality_dep *end, uint and_level)
+Equality_module *merge_func_deps(Equality_module *start, Equality_module *new_fields,
+ Equality_module *end, uint and_level)
{
if (start == new_fields)
return start; // Impossible or
if (new_fields == end)
return start; // No new fields, skip all
- Equality_dep *first_free=new_fields;
+ Equality_module *first_free=new_fields;
for (; new_fields != end ; new_fields++)
{
- for (Equality_dep *old=start ; old != first_free ; old++)
+ for (Equality_module *old=start ; old != first_free ; old++)
{
/*
TODO: does it make sense to attempt to merging multiple-equalities?
@@ -534,7 +542,7 @@
Ok, the results are within the [start, first_free) range, and the useful
elements have level==and_level. Now, lets remove all unusable elements:
*/
- for (Equality_dep *old=start ; old != first_free ;)
+ for (Equality_module *old=start ; old != first_free ;)
{
if (old->level != and_level)
{ // Not used in all levels
@@ -550,14 +558,14 @@
/*
- Add an Equality_dep element for a given predicate, if applicable
+ Add an Equality_module element for a given predicate, if applicable
DESCRIPTION
This function is modeled after add_key_field().
*/
static
-void add_eq_dep(Table_elimination *te, Equality_dep **eq_dep,
+void add_eq_dep(Table_elimination *te, Equality_module **eq_dep,
uint and_level, Item_func *cond, Field *field,
bool eq_func, Item **value, uint num_values,
table_map usable_tables)
@@ -622,22 +630,21 @@
DBUG_ASSERT(eq_func);
/* Store possible eq field */
- (*eq_dep)->type= Func_dep::FD_EXPRESSION; //psergey-todo;
- (*eq_dep)->field= get_field_dep(te, field);
+ (*eq_dep)->type= Module_dep::FD_EXPRESSION; //psergey-todo;
+ (*eq_dep)->field= get_field_value(te, field);
(*eq_dep)->val= *value;
(*eq_dep)->level= and_level;
(*eq_dep)++;
}
-
/*
- Get a Table_dep object for the given table, creating it if necessary.
+ Get a Table_value object for the given table, creating it if necessary.
*/
-static Table_dep *get_table_dep(Table_elimination *te, TABLE *table)
+static Table_value *get_table_value(Table_elimination *te, TABLE *table)
{
- Table_dep *tbl_dep= new Table_dep(table);
- Key_dep **key_list= &(tbl_dep->keys);
+ Table_value *tbl_dep= new Table_value(table);
+ Key_module **key_list= &(tbl_dep->keys);
/* Add dependencies for unique keys */
for (uint i=0; i < table->s->keys; i++)
@@ -645,7 +652,7 @@
KEY *key= table->key_info + i;
if ((key->flags & (HA_NOSAME | HA_END_SPACE_KEY)) == HA_NOSAME)
{
- Key_dep *key_dep= new Key_dep(tbl_dep, i, key->key_parts);
+ Key_module *key_dep= new Key_module(tbl_dep, i, key->key_parts);
*key_list= key_dep;
key_list= &(key_dep->next_table_key);
}
@@ -655,20 +662,20 @@
/*
- Get a Field_dep object for the given field, creating it if necessary
+ Get a Field_value object for the given field, creating it if necessary
*/
-static Field_dep *get_field_dep(Table_elimination *te, Field *field)
+static Field_value *get_field_value(Table_elimination *te, Field *field)
{
TABLE *table= field->table;
- Table_dep *tbl_dep;
+ Table_value *tbl_dep;
/* First, get the table*/
if (!(tbl_dep= te->table_deps[table->tablenr]))
- tbl_dep= get_table_dep(te, table);
+ tbl_dep= get_table_value(te, table);
/* Try finding the field in field list */
- Field_dep **pfield= &(tbl_dep->fields);
+ Field_value **pfield= &(tbl_dep->fields);
while (*pfield && (*pfield)->field->field_index < field->field_index)
{
pfield= &((*pfield)->next_table_field);
@@ -677,7 +684,7 @@
return *pfield;
/* Create the field and insert it in the list */
- Field_dep *new_field= new Field_dep(tbl_dep, field);
+ Field_value *new_field= new Field_value(tbl_dep, field);
new_field->next_table_field= *pfield;
*pfield= new_field;
@@ -686,19 +693,19 @@
/*
- Create an Outer_join_dep object for the given outer join
+ Create an Outer_join_module object for the given outer join
DESCRIPTION
- Outer_join_dep objects for children (or further descendants) are always
+ Outer_join_module objects for children (or further descendants) are always
created before the parents.
*/
static
-Outer_join_dep *get_outer_join_dep(Table_elimination *te,
+Outer_join_module *get_outer_join_dep(Table_elimination *te,
TABLE_LIST *outer_join, table_map deps_map)
{
- Outer_join_dep *oj_dep;
- oj_dep= new Outer_join_dep(outer_join, deps_map);
+ Outer_join_module *oj_dep;
+ oj_dep= new Outer_join_module(outer_join, my_count_bits(deps_map));
/*
Collect a bitmap fo tables that we depend on, and also set parent pointer
@@ -708,7 +715,7 @@
int idx;
while ((idx= it.next_bit()) != Table_map_iterator::BITMAP_END)
{
- Table_dep *table_dep;
+ Table_value *table_dep;
if (!(table_dep= te->table_deps[idx]))
{
/*
@@ -727,23 +734,24 @@
}
}
DBUG_ASSERT(table);
- table_dep= get_table_dep(te, table);
+ table_dep= get_table_value(te, table);
}
/*
Walk from the table up to its embedding outer joins. The goal is to
find the least embedded outer join nest and set its parent pointer to
- point to the newly created Outer_join_dep.
+ point to the newly created Outer_join_module.
to set the pointer of its near
*/
if (!table_dep->outer_join_dep)
table_dep->outer_join_dep= oj_dep;
else
{
- Outer_join_dep *oj= table_dep->outer_join_dep;
+ Outer_join_module *oj= table_dep->outer_join_dep;
while (oj->parent)
oj= oj->parent;
- oj->parent=oj_dep;
+ if (oj != oj_dep)
+ oj->parent=oj_dep;
}
}
return oj_dep;
@@ -757,7 +765,7 @@
collect_funcdeps_for_join_list()
te Table elimination context.
join_list Join list to work on
- build_eq_deps TRUE <=> build Equality_dep elements for all
+ build_eq_deps TRUE <=> build Equality_module elements for all
members of the join list, even if they cannot
be individually eliminated
tables_used_elsewhere Bitmap of tables that are referred to from
@@ -779,7 +787,7 @@
bool build_eq_deps,
table_map tables_used_elsewhere,
table_map *eliminable_tables,
- Equality_dep **eq_dep)
+ Equality_module **eq_dep)
{
TABLE_LIST *tbl;
List_iterator<TABLE_LIST> it(*join_list);
@@ -845,10 +853,10 @@
void see_field(Field *field)
{
- Table_dep *tbl_dep;
+ Table_value *tbl_dep;
if ((tbl_dep= te->table_deps[field->table->tablenr]))
{
- for (Field_dep *field_dep= tbl_dep->fields; field_dep;
+ for (Field_value *field_dep= tbl_dep->fields; field_dep;
field_dep= field_dep->next_table_field)
{
if (field->field_index == field_dep->field->field_index)
@@ -888,21 +896,21 @@
*/
static
-bool setup_equality_deps(Table_elimination *te, Func_dep **bound_deps_list)
+bool setup_equality_deps(Table_elimination *te, Module_dep **bound_deps_list)
{
DBUG_ENTER("setup_equality_deps");
/*
- Count Field_dep objects and assign each of them a unique bitmap_offset.
+ Count Field_value objects and assign each of them a unique bitmap_offset.
*/
uint offset= 0;
- for (Table_dep **tbl_dep=te->table_deps;
+ for (Table_value **tbl_dep=te->table_deps;
tbl_dep < te->table_deps + MAX_TABLES;
tbl_dep++)
{
if (*tbl_dep)
{
- for (Field_dep *field_dep= (*tbl_dep)->fields;
+ for (Field_value *field_dep= (*tbl_dep)->fields;
field_dep;
field_dep= field_dep->next_table_field)
{
@@ -926,9 +934,9 @@
Also collect a linked list of equalities that are bound.
*/
- Func_dep *bound_dep= NULL;
+ Module_dep *bound_dep= NULL;
Field_dependency_setter deps_setter(te);
- for (Equality_dep *eq_dep= te->equality_deps;
+ for (Equality_module *eq_dep= te->equality_deps;
eq_dep < te->equality_deps + te->n_equality_deps;
eq_dep++)
{
@@ -940,12 +948,11 @@
{
eq_dep->next= bound_dep;
bound_dep= eq_dep;
- eq_dep->bound= TRUE;
}
}
*bound_deps_list= bound_dep;
- DBUG_EXECUTE("test", dbug_print_deps(te); );
+ //DBUG_EXECUTE("test", dbug_print_deps(te); );
DBUG_RETURN(FALSE);
}
@@ -1042,9 +1049,9 @@
uint m= max(thd->lex->current_select->max_equal_elems,1);
uint max_elems= ((thd->lex->current_select->cond_count+1)*2 +
thd->lex->current_select->between_count)*m + 1 + 10;
- if (!(te.equality_deps= new Equality_dep[max_elems]))
+ if (!(te.equality_deps= new Equality_module[max_elems]))
DBUG_VOID_RETURN;
- Equality_dep *eq_deps_end= te.equality_deps;
+ Equality_module *eq_deps_end= te.equality_deps;
table_map eliminable_tables= 0;
collect_funcdeps_for_join_list(&te, join->join_list,
FALSE,
@@ -1052,96 +1059,125 @@
&eliminable_tables,
&eq_deps_end);
te.n_equality_deps= eq_deps_end - te.equality_deps;
- Func_dep *bound_dep;
- setup_equality_deps(&te, &bound_dep);
-
- /*
- Run the wave.
- All Func_dep-derived objects are divided into three classes:
- - Those that have bound=FALSE
- - Those that have bound=TRUE
- - Those that have bound=TRUE and are in the list..
-
- */
- while (bound_dep)
- {
- Func_dep *next= bound_dep->next;
- //e= list.remove_first();
- switch (bound_dep->type)
+
+ Module_dep *bound_modules;
+ //Value_dep *bound_values;
+ setup_equality_deps(&te, &bound_modules);
+
+ run_elimination_wave(&te, bound_modules);
+ }
+ DBUG_VOID_RETURN;
+}
+
+
+static
+void signal_from_field_to_exprs(Table_elimination* te, Field_value *field_dep,
+ Module_dep **bound_modules)
+{
+ /* Now, expressions */
+ for (uint i=0; i < te->n_equality_deps; i++)
+ {
+ if (bitmap_is_set(&te->expr_deps, field_dep->bitmap_offset + i) &&
+ te->equality_deps[i].unknown_args &&
+ !--te->equality_deps[i].unknown_args)
+ {
+ /* Mark as bound and add to the list */
+ Equality_module* eq_dep= &te->equality_deps[i];
+ eq_dep->next= *bound_modules;
+ *bound_modules= eq_dep;
+ }
+ }
+}
+
+
+static
+void run_elimination_wave(Table_elimination *te, Module_dep *bound_modules)
+{
+ Value_dep *bound_values= NULL;
+ /*
+ Run the wave.
+ All Func_dep-derived objects are divided into three classes:
+ - Those that have bound=FALSE
+ - Those that have bound=TRUE
+ - Those that have bound=TRUE and are in the list..
+
+ */
+ while (bound_modules)
+ {
+ for (;bound_modules; bound_modules= bound_modules->next)
+ {
+ switch (bound_modules->type)
{
- case Func_dep::FD_EXPRESSION:
+ case Module_dep::FD_EXPRESSION:
{
/* It's a field=expr and we got to know the expr, so we know the field */
- Equality_dep *eq_dep= (Equality_dep*)bound_dep;
+ Equality_module *eq_dep= (Equality_module*)bound_modules;
if (!eq_dep->field->bound)
{
/* Mark as bound and add to the list */
eq_dep->field->bound= TRUE;
- eq_dep->field->next= next;
- next= eq_dep->field;
- }
- break;
- }
- case Func_dep::FD_FIELD:
+ eq_dep->field->next= bound_values;
+ bound_values= eq_dep->field;
+ }
+ break;
+ }
+ case Module_dep::FD_UNIQUE_KEY:
+ {
+ /* Unique key is known means the table is known */
+ Table_value *table_dep=((Key_module*)bound_modules)->table;
+ if (!table_dep->bound)
+ {
+ /* Mark as bound and add to the list */
+ table_dep->bound= TRUE;
+ table_dep->next= bound_values;
+ bound_values= table_dep;
+ }
+ break;
+ }
+ case Module_dep::FD_OUTER_JOIN:
+ {
+ Outer_join_module *outer_join_dep= (Outer_join_module*)bound_modules;
+ mark_as_eliminated(te->join, outer_join_dep->table_list);
+ break;
+ }
+ case Module_dep::FD_MULTI_EQUALITY:
+ default:
+ DBUG_ASSERT(0);
+ }
+ }
+
+ for (;bound_values; bound_values=bound_values->next)
+ {
+ switch (bound_values->type)
+ {
+ case Value_dep::VALUE_FIELD:
{
/*
Field became known. Check out
- unique keys we belong to
- expressions that depend on us.
*/
- Field_dep *field_dep= (Field_dep*)bound_dep;
- for (Key_dep *key_dep= field_dep->table->keys; key_dep;
+ Field_value *field_dep= (Field_value*)bound_values;
+ for (Key_module *key_dep= field_dep->table->keys; key_dep;
key_dep= key_dep->next_table_key)
{
DBUG_PRINT("info", ("key %s.%s is now bound",
key_dep->table->table->alias,
key_dep->table->table->key_info[key_dep->keyno].name));
if (field_dep->field->part_of_key.is_set(key_dep->keyno) &&
- !key_dep->bound)
- {
- if (!--key_dep->n_missing_keyparts)
- {
- /* Mark as bound and add to the list */
- key_dep->bound= TRUE;
- key_dep->next= next;
- next= key_dep;
- }
- }
- }
-
- /* Now, expressions */
- for (uint i=0; i < te.n_equality_deps; i++)
- {
- if (bitmap_is_set(&te.expr_deps, field_dep->bitmap_offset + i))
- {
- Equality_dep* eq_dep= &te.equality_deps[i];
- if (!--eq_dep->unknown_args)
- {
- /* Mark as bound and add to the list */
- eq_dep->bound= TRUE;
- eq_dep->next= next;
- next= eq_dep;
- }
- }
- }
- break;
- }
- case Func_dep::FD_UNIQUE_KEY:
- {
- /* Unique key is known means the table is known */
- Table_dep *table_dep=((Key_dep*)bound_dep)->table;
- if (!table_dep->bound)
- {
- /* Mark as bound and add to the list */
- table_dep->bound= TRUE;
- table_dep->next= next;
- next= table_dep;
- }
- break;
- }
- case Func_dep::FD_TABLE:
- {
- Table_dep *table_dep=(Table_dep*)bound_dep;
+ key_dep->unknown_args && !--key_dep->unknown_args)
+ {
+ /* Mark as bound and add to the list */
+ key_dep->next= bound_modules;
+ bound_modules= key_dep;
+ }
+ }
+ signal_from_field_to_exprs(te, field_dep, &bound_modules);
+ break;
+ }
+ case Value_dep::VALUE_TABLE:
+ {
+ Table_value *table_dep=(Table_value*)bound_values;
DBUG_PRINT("info", ("table %s is now bound",
table_dep->table->alias));
/*
@@ -1149,50 +1185,35 @@
- all its fields are known
- one more element in outer join nest is known
*/
- for (Field_dep *field_dep= table_dep->fields; field_dep;
+ for (Field_value *field_dep= table_dep->fields; field_dep;
field_dep= field_dep->next_table_field)
{
if (!field_dep->bound)
{
/* Mark as bound and add to the list */
field_dep->bound= TRUE;
- field_dep->next= next;
- next= field_dep;
- }
- }
- Outer_join_dep *outer_join_dep= table_dep->outer_join_dep;
- if (!(outer_join_dep->missing_tables &= ~table_dep->table->map))
- {
- /* Mark as bound and add to the list */
- outer_join_dep->bound= TRUE;
- outer_join_dep->next= next;
- next= outer_join_dep;
- }
- break;
- }
- case Func_dep::FD_OUTER_JOIN:
- {
- Outer_join_dep *outer_join_dep= (Outer_join_dep*)bound_dep;
- mark_as_eliminated(te.join, outer_join_dep->table_list);
- Outer_join_dep *parent= outer_join_dep->parent;
- if (parent &&
- !(parent->missing_tables &= ~outer_join_dep->all_tables))
- {
- /* Mark as bound and add to the list */
- parent->bound= TRUE;
- parent->next= next;
- next= parent;
- }
- break;
- }
- case Func_dep::FD_MULTI_EQUALITY:
- default:
+ signal_from_field_to_exprs(te, field_dep, &bound_modules);
+ }
+ }
+ for (Outer_join_module *outer_join_dep= table_dep->outer_join_dep;
+ outer_join_dep; outer_join_dep= outer_join_dep->parent)
+ {
+ //if (!(outer_join_dep->missing_tables &= ~table_dep->table->map))
+ if (outer_join_dep->unknown_args &&
+ !--outer_join_dep->unknown_args)
+ {
+ /* Mark as bound and add to the list */
+ outer_join_dep->next= bound_modules;
+ bound_modules= outer_join_dep;
+ }
+ }
+ break;
+ }
+ default:
DBUG_ASSERT(0);
}
- bound_dep= next;
}
}
- DBUG_VOID_RETURN;
}
@@ -1232,7 +1253,7 @@
}
-
+#if 0
#ifndef DBUG_OFF
static
void dbug_print_deps(Table_elimination *te)
@@ -1243,7 +1264,7 @@
fprintf(DBUG_FILE,"deps {\n");
/* Start with printing equalities */
- for (Equality_dep *eq_dep= te->equality_deps;
+ for (Equality_module *eq_dep= te->equality_deps;
eq_dep != te->equality_deps + te->n_equality_deps; eq_dep++)
{
char buf[128];
@@ -1261,13 +1282,13 @@
/* Then tables and their fields */
for (uint i=0; i < MAX_TABLES; i++)
{
- Table_dep *table_dep;
+ Table_value *table_dep;
if ((table_dep= te->table_deps[i]))
{
/* Print table */
fprintf(DBUG_FILE, " table %s\n", table_dep->table->alias);
/* Print fields */
- for (Field_dep *field_dep= table_dep->fields; field_dep;
+ for (Field_value *field_dep= table_dep->fields; field_dep;
field_dep= field_dep->next_table_field)
{
fprintf(DBUG_FILE, " field %s.%s ->", table_dep->table->alias,
@@ -1288,7 +1309,7 @@
}
#endif
-
+#endif
/**
@} (end of group Table_Elimination)
*/