Commit a2839036 authored by Sergey Petrunya's avatar Sergey Petrunya

MWL#17: Table elimination

- Better comments

sql/sql_select.cc:
  MWL#17: Table elimination
  - Fix buildbot failure: do set correct value to nested_join::n_tables
parent 536754c8
...@@ -20,18 +20,15 @@ ...@@ -20,18 +20,15 @@
OVERVIEW OVERVIEW
The module has one entry point - eliminate_tables() function, which one The module has one entry point - eliminate_tables() function, which one
needs to call (once) sometime after update_ref_and_keys() but before the needs to call (once) at some point before the join optimization.
join optimization.
eliminate_tables() operates over the JOIN structures. Logically, it eliminate_tables() operates over the JOIN structures. Logically, it
removes the right sides of outer join nests. Physically, it changes the removes the right sides of outer join nests. Physically, it changes the
following members: following members:
* Eliminated tables are marked as constant and moved to the front of the * Eliminated tables are marked as constant and moved to the front of the
join order. join order.
* In addition to this, they are recorded in JOIN::eliminated_tables bitmap.
* All join nests have their NESTED_JOIN::n_tables updated to discount * In addition to this, they are recorded in JOIN::eliminated_tables bitmap.
the eliminated tables
* Items that became disused because they were in the ON expression of an * Items that became disused because they were in the ON expression of an
eliminated outer join are notified by means of the Item tree walk which eliminated outer join are notified by means of the Item tree walk which
...@@ -40,26 +37,13 @@ ...@@ -40,26 +37,13 @@
Item_subselect with its Item_subselect::eliminated flag which is used Item_subselect with its Item_subselect::eliminated flag which is used
by EXPLAIN code to check if the subquery should be shown in EXPLAIN. by EXPLAIN code to check if the subquery should be shown in EXPLAIN.
Table elimination is redone on every PS re-execution. (TODO reasons?) Table elimination is redone on every PS re-execution.
*/ */
/*
A structure that represents a functional dependency of something over
something else. This can be one of:
1. A "tbl.field = expr" equality. The field depends on the expression.
2. An Item_equal(...) multi-equality. Each participating field depends on
every other participating field. (TODO???)
3. A UNIQUE_KEY(field1, field2, fieldN). The key depends on the fields that
it is composed of.
4. A table (which is within an outer join nest). Table depends on a unique
key (value of a unique key identifies a table record)
5. An outer join nest. It depends on all tables it contains.
/*
An abstract structure that represents some entity that's being dependent on
some other entity.
*/ */
class Func_dep : public Sql_alloc class Func_dep : public Sql_alloc
...@@ -73,9 +57,14 @@ public: ...@@ -73,9 +57,14 @@ public:
FD_UNIQUE_KEY, FD_UNIQUE_KEY,
FD_TABLE, FD_TABLE,
FD_OUTER_JOIN FD_OUTER_JOIN
} type; } type; /* Type of the object */
Func_dep *next;
bool bound; /*
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) {} Func_dep() : next(NULL), bound(FALSE) {}
}; };
...@@ -84,10 +73,10 @@ class Field_dep; ...@@ -84,10 +73,10 @@ class Field_dep;
class Table_dep; class Table_dep;
class Outer_join_dep; class Outer_join_dep;
/* /*
An equality A "tbl.column= expr" equality dependency. tbl.column depends on fields
- Depends on multiple fields (those in its expression), unknown_args is a used in expr.
counter of unsatisfied dependencies.
*/ */
class Equality_dep : public Func_dep class Equality_dep : public Func_dep
{ {
...@@ -95,8 +84,11 @@ public: ...@@ -95,8 +84,11 @@ public:
Field_dep *field; Field_dep *field;
Item *val; Item *val;
uint level; /* Used during condition analysis only */ /* Used during condition analysis only, similar to KEYUSE::level */
uint unknown_args; /* Number of yet unknown arguments */ uint level;
/* Number of fields referenced from *val that are not yet 'bound' */
uint unknown_args;
}; };
...@@ -139,7 +131,7 @@ public: ...@@ -139,7 +131,7 @@ public:
type= Func_dep::FD_UNIQUE_KEY; type= Func_dep::FD_UNIQUE_KEY;
} }
Table_dep *table; /* Table this key is from */ Table_dep *table; /* Table this key is from */
uint keyno; // TODO do we care about this uint keyno;
uint n_missing_keyparts; uint n_missing_keyparts;
Key_dep *next_table_key; Key_dep *next_table_key;
}; };
......
...@@ -114,7 +114,7 @@ static COND *simplify_joins(JOIN *join, List<TABLE_LIST> *join_list, ...@@ -114,7 +114,7 @@ static COND *simplify_joins(JOIN *join, List<TABLE_LIST> *join_list,
COND *conds, bool top); COND *conds, bool top);
static bool check_interleaving_with_nj(JOIN_TAB *next); static bool check_interleaving_with_nj(JOIN_TAB *next);
static void restore_prev_nj_state(JOIN_TAB *last); static void restore_prev_nj_state(JOIN_TAB *last);
static void reset_nj_counters(JOIN *join, List<TABLE_LIST> *join_list); static uint reset_nj_counters(JOIN *join, List<TABLE_LIST> *join_list);
static uint build_bitmap_for_nested_joins(List<TABLE_LIST> *join_list, static uint build_bitmap_for_nested_joins(List<TABLE_LIST> *join_list,
uint first_unused); uint first_unused);
...@@ -8791,23 +8791,26 @@ static uint build_bitmap_for_nested_joins(List<TABLE_LIST> *join_list, ...@@ -8791,23 +8791,26 @@ static uint build_bitmap_for_nested_joins(List<TABLE_LIST> *join_list,
tables which will be ignored. tables which will be ignored.
*/ */
static void reset_nj_counters(JOIN *join, List<TABLE_LIST> *join_list) static uint reset_nj_counters(JOIN *join, List<TABLE_LIST> *join_list)
{ {
List_iterator<TABLE_LIST> li(*join_list); List_iterator<TABLE_LIST> li(*join_list);
TABLE_LIST *table; TABLE_LIST *table;
DBUG_ENTER("reset_nj_counters"); DBUG_ENTER("reset_nj_counters");
uint n=0;
while ((table= li++)) while ((table= li++))
{ {
NESTED_JOIN *nested_join; NESTED_JOIN *nested_join;
if ((nested_join= table->nested_join)) if ((nested_join= table->nested_join))
{ {
nested_join->counter= 0; nested_join->counter= 0;
nested_join->n_tables= my_count_bits(nested_join->used_tables & //nested_join->n_tables= my_count_bits(nested_join->used_tables &
~join->eliminated_tables); // ~join->eliminated_tables);
reset_nj_counters(join, &nested_join->join_list); nested_join->n_tables= reset_nj_counters(join, &nested_join->join_list);
} }
if (table->table && (table->table->map & ~join->eliminated_tables))
n++;
} }
DBUG_VOID_RETURN; DBUG_RETURN(n);
} }
......
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