mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
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.
This commit is contained in:
@@ -40,19 +40,78 @@
|
|||||||
Table elimination is redone on every PS re-execution.
|
Table elimination is redone on every PS re-execution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
class Value_dep
|
||||||
/*
|
{
|
||||||
An abstract structure that represents some entity that's being dependent on
|
public:
|
||||||
some other entity.
|
enum {
|
||||||
*/
|
VALUE_FIELD,
|
||||||
|
VALUE_TABLE,
|
||||||
class Func_dep : public Sql_alloc
|
} 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:
|
public:
|
||||||
enum {
|
enum {
|
||||||
FD_INVALID,
|
|
||||||
FD_EXPRESSION,
|
FD_EXPRESSION,
|
||||||
FD_FIELD,
|
|
||||||
FD_MULTI_EQUALITY,
|
FD_MULTI_EQUALITY,
|
||||||
FD_UNIQUE_KEY,
|
FD_UNIQUE_KEY,
|
||||||
FD_TABLE,
|
FD_TABLE,
|
||||||
@@ -63,58 +122,26 @@ public:
|
|||||||
Used to make a linked list of elements that became bound and thus can
|
Used to make a linked list of elements that became bound and thus can
|
||||||
make elements that depend on them bound, too.
|
make elements that depend on them bound, too.
|
||||||
*/
|
*/
|
||||||
Func_dep *next;
|
Module_dep *next;
|
||||||
bool bound; /* TRUE<=> The entity is considered bound */
|
uint unknown_args; /* TRUE<=> The entity is considered bound */
|
||||||
Func_dep() : next(NULL), bound(FALSE) {}
|
|
||||||
|
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
|
A "tbl.column= expr" equality dependency. tbl.column depends on fields
|
||||||
used in expr.
|
used in expr.
|
||||||
*/
|
*/
|
||||||
class Equality_dep : public Func_dep
|
class Equality_module : public Module_dep
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Field_dep *field;
|
Field_value *field;
|
||||||
Item *val;
|
Item *val;
|
||||||
|
|
||||||
/* Used during condition analysis only, similar to KEYUSE::level */
|
/* Used during condition analysis only, similar to KEYUSE::level */
|
||||||
uint 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,56 +150,36 @@ public:
|
|||||||
- Unique key depends on all of its components
|
- Unique key depends on all of its components
|
||||||
- Key's table is its dependency
|
- Key's table is its dependency
|
||||||
*/
|
*/
|
||||||
class Key_dep: public Func_dep
|
class Key_module: public Module_dep
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Key_dep(Table_dep *table_arg, uint keyno_arg, uint n_parts_arg) :
|
Key_module(Table_value *table_arg, uint keyno_arg, uint n_parts_arg) :
|
||||||
table(table_arg), keyno(keyno_arg), n_missing_keyparts(n_parts_arg),
|
table(table_arg), keyno(keyno_arg), next_table_key(NULL)
|
||||||
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 keyno;
|
||||||
uint n_missing_keyparts;
|
|
||||||
/* Unique keys form a linked list, ordered by keyno */
|
/* Unique keys form a linked list, ordered by keyno */
|
||||||
Key_dep *next_table_key;
|
Key_module *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 */
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
An outer join nest that is subject to elimination
|
An outer join nest that is subject to elimination
|
||||||
- it depends on all tables inside it
|
- it depends on all tables inside it
|
||||||
- has its parent outer join as dependency
|
- has its parent outer join as dependency
|
||||||
*/
|
*/
|
||||||
class Outer_join_dep: public Func_dep
|
class Outer_join_module: public Module_dep
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Outer_join_dep(TABLE_LIST *table_list_arg, table_map missing_tables_arg) :
|
Outer_join_module(TABLE_LIST *table_list_arg, uint n_children) :
|
||||||
table_list(table_list_arg), missing_tables(missing_tables_arg),
|
table_list(table_list_arg), parent(NULL)
|
||||||
all_tables(missing_tables_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
|
Outer join we're representing. This can be a join nest or a one table that
|
||||||
@@ -184,11 +191,11 @@ public:
|
|||||||
Tables within this outer join (and its descendants) that are not yet known
|
Tables within this outer join (and its descendants) that are not yet known
|
||||||
to be functionally dependent.
|
to be functionally dependent.
|
||||||
*/
|
*/
|
||||||
table_map missing_tables;
|
table_map missing_tables; //psergey-todo: remove
|
||||||
/* All tables within this outer join and its descendants */
|
/* 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 */
|
/* Parent eliminable outer join, if any */
|
||||||
Outer_join_dep *parent;
|
Outer_join_module *parent;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -205,44 +212,45 @@ public:
|
|||||||
|
|
||||||
JOIN *join;
|
JOIN *join;
|
||||||
/* Array of equality dependencies */
|
/* Array of equality dependencies */
|
||||||
Equality_dep *equality_deps;
|
Equality_module *equality_deps;
|
||||||
uint n_equality_deps; /* Number of elements in the array */
|
uint n_equality_deps; /* Number of elements in the array */
|
||||||
|
|
||||||
/* tablenr -> Table_dep* mapping. */
|
/* tablenr -> Table_value* mapping. */
|
||||||
Table_dep *table_deps[MAX_KEY];
|
Table_value *table_deps[MAX_KEY];
|
||||||
|
|
||||||
/* Outer joins that are candidates for elimination */
|
/* 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 */
|
/* Bitmap of how expressions depend on bits */
|
||||||
MY_BITMAP expr_deps;
|
MY_BITMAP expr_deps;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static
|
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,
|
uint *and_level, Item *cond,
|
||||||
table_map usable_tables);
|
table_map usable_tables);
|
||||||
static
|
static
|
||||||
void add_eq_dep(Table_elimination *te,
|
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,
|
Item_func *cond, Field *field,
|
||||||
bool eq_func, Item **value,
|
bool eq_func, Item **value,
|
||||||
uint num_values, table_map usable_tables);
|
uint num_values, table_map usable_tables);
|
||||||
static
|
static
|
||||||
Equality_dep *merge_func_deps(Equality_dep *start, Equality_dep *new_fields,
|
Equality_module *merge_func_deps(Equality_module *start, Equality_module *new_fields,
|
||||||
Equality_dep *end, uint and_level);
|
Equality_module *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);
|
|
||||||
|
|
||||||
|
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);
|
void eliminate_tables(JOIN *join);
|
||||||
static void mark_as_eliminated(JOIN *join, TABLE_LIST *tbl);
|
static void mark_as_eliminated(JOIN *join, TABLE_LIST *tbl);
|
||||||
|
|
||||||
|
#if 0
|
||||||
#ifndef DBUG_OFF
|
#ifndef DBUG_OFF
|
||||||
static void dbug_print_deps(Table_elimination *te);
|
static void dbug_print_deps(Table_elimination *te);
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
/*******************************************************************************************/
|
/*******************************************************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -262,14 +270,14 @@ static void dbug_print_deps(Table_elimination *te);
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
static
|
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,
|
uint *and_level, Item *cond,
|
||||||
table_map usable_tables)
|
table_map usable_tables)
|
||||||
{
|
{
|
||||||
if (cond->type() == Item_func::COND_ITEM)
|
if (cond->type() == Item_func::COND_ITEM)
|
||||||
{
|
{
|
||||||
List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
|
List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
|
||||||
Equality_dep *org_key_fields= *fdeps;
|
Equality_module *org_key_fields= *fdeps;
|
||||||
|
|
||||||
/* AND/OR */
|
/* AND/OR */
|
||||||
if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
|
if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
|
||||||
@@ -293,7 +301,7 @@ void build_eq_deps_for_cond(Table_elimination *te, Equality_dep **fdeps,
|
|||||||
Item *item;
|
Item *item;
|
||||||
while ((item=li++))
|
while ((item=li++))
|
||||||
{
|
{
|
||||||
Equality_dep *start_key_fields= *fdeps;
|
Equality_module *start_key_fields= *fdeps;
|
||||||
(*and_level)++;
|
(*and_level)++;
|
||||||
build_eq_deps_for_cond(te, fdeps, and_level, item, usable_tables);
|
build_eq_deps_for_cond(te, fdeps, and_level, item, usable_tables);
|
||||||
*fdeps= merge_func_deps(org_key_fields, start_key_fields, *fdeps,
|
*fdeps= merge_func_deps(org_key_fields, start_key_fields, *fdeps,
|
||||||
@@ -432,7 +440,7 @@ void build_eq_deps_for_cond(Table_elimination *te, Equality_dep **fdeps,
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Perform an OR operation on two (adjacent) Equality_dep arrays.
|
Perform an OR operation on two (adjacent) Equality_module arrays.
|
||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
merge_func_deps()
|
merge_func_deps()
|
||||||
@@ -442,7 +450,7 @@ void build_eq_deps_for_cond(Table_elimination *te, Equality_dep **fdeps,
|
|||||||
and_level AND-level.
|
and_level AND-level.
|
||||||
|
|
||||||
DESCRIPTION
|
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
|
$LEFT_PART $RIGHT_PART
|
||||||
+-----------------------+-----------------------+
|
+-----------------------+-----------------------+
|
||||||
@@ -477,19 +485,19 @@ void build_eq_deps_for_cond(Table_elimination *te, Equality_dep **fdeps,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
static
|
static
|
||||||
Equality_dep *merge_func_deps(Equality_dep *start, Equality_dep *new_fields,
|
Equality_module *merge_func_deps(Equality_module *start, Equality_module *new_fields,
|
||||||
Equality_dep *end, uint and_level)
|
Equality_module *end, uint and_level)
|
||||||
{
|
{
|
||||||
if (start == new_fields)
|
if (start == new_fields)
|
||||||
return start; // Impossible or
|
return start; // Impossible or
|
||||||
if (new_fields == end)
|
if (new_fields == end)
|
||||||
return start; // No new fields, skip all
|
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 (; 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?
|
TODO: does it make sense to attempt to merging multiple-equalities?
|
||||||
@@ -534,7 +542,7 @@ Equality_dep *merge_func_deps(Equality_dep *start, Equality_dep *new_fields,
|
|||||||
Ok, the results are within the [start, first_free) range, and the useful
|
Ok, the results are within the [start, first_free) range, and the useful
|
||||||
elements have level==and_level. Now, lets remove all unusable elements:
|
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)
|
if (old->level != and_level)
|
||||||
{ // Not used in all levels
|
{ // Not used in all levels
|
||||||
@@ -550,14 +558,14 @@ Equality_dep *merge_func_deps(Equality_dep *start, Equality_dep *new_fields,
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Add an Equality_dep element for a given predicate, if applicable
|
Add an Equality_module element for a given predicate, if applicable
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
This function is modeled after add_key_field().
|
This function is modeled after add_key_field().
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static
|
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,
|
uint and_level, Item_func *cond, Field *field,
|
||||||
bool eq_func, Item **value, uint num_values,
|
bool eq_func, Item **value, uint num_values,
|
||||||
table_map usable_tables)
|
table_map usable_tables)
|
||||||
@@ -622,22 +630,21 @@ void add_eq_dep(Table_elimination *te, Equality_dep **eq_dep,
|
|||||||
|
|
||||||
DBUG_ASSERT(eq_func);
|
DBUG_ASSERT(eq_func);
|
||||||
/* Store possible eq field */
|
/* Store possible eq field */
|
||||||
(*eq_dep)->type= Func_dep::FD_EXPRESSION; //psergey-todo;
|
(*eq_dep)->type= Module_dep::FD_EXPRESSION; //psergey-todo;
|
||||||
(*eq_dep)->field= get_field_dep(te, field);
|
(*eq_dep)->field= get_field_value(te, field);
|
||||||
(*eq_dep)->val= *value;
|
(*eq_dep)->val= *value;
|
||||||
(*eq_dep)->level= and_level;
|
(*eq_dep)->level= and_level;
|
||||||
(*eq_dep)++;
|
(*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);
|
Table_value *tbl_dep= new Table_value(table);
|
||||||
Key_dep **key_list= &(tbl_dep->keys);
|
Key_module **key_list= &(tbl_dep->keys);
|
||||||
|
|
||||||
/* Add dependencies for unique keys */
|
/* Add dependencies for unique keys */
|
||||||
for (uint i=0; i < table->s->keys; i++)
|
for (uint i=0; i < table->s->keys; i++)
|
||||||
@@ -645,7 +652,7 @@ static Table_dep *get_table_dep(Table_elimination *te, TABLE *table)
|
|||||||
KEY *key= table->key_info + i;
|
KEY *key= table->key_info + i;
|
||||||
if ((key->flags & (HA_NOSAME | HA_END_SPACE_KEY)) == HA_NOSAME)
|
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;
|
||||||
key_list= &(key_dep->next_table_key);
|
key_list= &(key_dep->next_table_key);
|
||||||
}
|
}
|
||||||
@@ -655,20 +662,20 @@ static Table_dep *get_table_dep(Table_elimination *te, TABLE *table)
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
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 *table= field->table;
|
||||||
Table_dep *tbl_dep;
|
Table_value *tbl_dep;
|
||||||
|
|
||||||
/* First, get the table*/
|
/* First, get the table*/
|
||||||
if (!(tbl_dep= te->table_deps[table->tablenr]))
|
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 */
|
/* 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)
|
while (*pfield && (*pfield)->field->field_index < field->field_index)
|
||||||
{
|
{
|
||||||
pfield= &((*pfield)->next_table_field);
|
pfield= &((*pfield)->next_table_field);
|
||||||
@@ -677,7 +684,7 @@ static Field_dep *get_field_dep(Table_elimination *te, Field *field)
|
|||||||
return *pfield;
|
return *pfield;
|
||||||
|
|
||||||
/* Create the field and insert it in the list */
|
/* 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;
|
new_field->next_table_field= *pfield;
|
||||||
*pfield= new_field;
|
*pfield= new_field;
|
||||||
|
|
||||||
@@ -686,19 +693,19 @@ static Field_dep *get_field_dep(Table_elimination *te, Field *field)
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Create an Outer_join_dep object for the given outer join
|
Create an Outer_join_module object for the given outer join
|
||||||
|
|
||||||
DESCRIPTION
|
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.
|
created before the parents.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static
|
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)
|
TABLE_LIST *outer_join, table_map deps_map)
|
||||||
{
|
{
|
||||||
Outer_join_dep *oj_dep;
|
Outer_join_module *oj_dep;
|
||||||
oj_dep= new Outer_join_dep(outer_join, deps_map);
|
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
|
Collect a bitmap fo tables that we depend on, and also set parent pointer
|
||||||
@@ -708,7 +715,7 @@ Outer_join_dep *get_outer_join_dep(Table_elimination *te,
|
|||||||
int idx;
|
int idx;
|
||||||
while ((idx= it.next_bit()) != Table_map_iterator::BITMAP_END)
|
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]))
|
if (!(table_dep= te->table_deps[idx]))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@@ -727,22 +734,23 @@ Outer_join_dep *get_outer_join_dep(Table_elimination *te,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
DBUG_ASSERT(table);
|
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
|
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
|
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
|
to set the pointer of its near
|
||||||
*/
|
*/
|
||||||
if (!table_dep->outer_join_dep)
|
if (!table_dep->outer_join_dep)
|
||||||
table_dep->outer_join_dep= oj_dep;
|
table_dep->outer_join_dep= oj_dep;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Outer_join_dep *oj= table_dep->outer_join_dep;
|
Outer_join_module *oj= table_dep->outer_join_dep;
|
||||||
while (oj->parent)
|
while (oj->parent)
|
||||||
oj= oj->parent;
|
oj= oj->parent;
|
||||||
|
if (oj != oj_dep)
|
||||||
oj->parent=oj_dep;
|
oj->parent=oj_dep;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -757,7 +765,7 @@ Outer_join_dep *get_outer_join_dep(Table_elimination *te,
|
|||||||
collect_funcdeps_for_join_list()
|
collect_funcdeps_for_join_list()
|
||||||
te Table elimination context.
|
te Table elimination context.
|
||||||
join_list Join list to work on
|
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
|
members of the join list, even if they cannot
|
||||||
be individually eliminated
|
be individually eliminated
|
||||||
tables_used_elsewhere Bitmap of tables that are referred to from
|
tables_used_elsewhere Bitmap of tables that are referred to from
|
||||||
@@ -779,7 +787,7 @@ collect_funcdeps_for_join_list(Table_elimination *te,
|
|||||||
bool build_eq_deps,
|
bool build_eq_deps,
|
||||||
table_map tables_used_elsewhere,
|
table_map tables_used_elsewhere,
|
||||||
table_map *eliminable_tables,
|
table_map *eliminable_tables,
|
||||||
Equality_dep **eq_dep)
|
Equality_module **eq_dep)
|
||||||
{
|
{
|
||||||
TABLE_LIST *tbl;
|
TABLE_LIST *tbl;
|
||||||
List_iterator<TABLE_LIST> it(*join_list);
|
List_iterator<TABLE_LIST> it(*join_list);
|
||||||
@@ -845,10 +853,10 @@ public:
|
|||||||
|
|
||||||
void see_field(Field *field)
|
void see_field(Field *field)
|
||||||
{
|
{
|
||||||
Table_dep *tbl_dep;
|
Table_value *tbl_dep;
|
||||||
if ((tbl_dep= te->table_deps[field->table->tablenr]))
|
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)
|
field_dep= field_dep->next_table_field)
|
||||||
{
|
{
|
||||||
if (field->field_index == field_dep->field->field_index)
|
if (field->field_index == field_dep->field->field_index)
|
||||||
@@ -888,21 +896,21 @@ public:
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
static
|
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");
|
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;
|
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 < te->table_deps + MAX_TABLES;
|
||||||
tbl_dep++)
|
tbl_dep++)
|
||||||
{
|
{
|
||||||
if (*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= field_dep->next_table_field)
|
field_dep= field_dep->next_table_field)
|
||||||
{
|
{
|
||||||
@@ -926,9 +934,9 @@ bool setup_equality_deps(Table_elimination *te, Func_dep **bound_deps_list)
|
|||||||
|
|
||||||
Also collect a linked list of equalities that are bound.
|
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);
|
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 < te->equality_deps + te->n_equality_deps;
|
||||||
eq_dep++)
|
eq_dep++)
|
||||||
{
|
{
|
||||||
@@ -940,12 +948,11 @@ bool setup_equality_deps(Table_elimination *te, Func_dep **bound_deps_list)
|
|||||||
{
|
{
|
||||||
eq_dep->next= bound_dep;
|
eq_dep->next= bound_dep;
|
||||||
bound_dep= eq_dep;
|
bound_dep= eq_dep;
|
||||||
eq_dep->bound= TRUE;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*bound_deps_list= bound_dep;
|
*bound_deps_list= bound_dep;
|
||||||
|
|
||||||
DBUG_EXECUTE("test", dbug_print_deps(te); );
|
//DBUG_EXECUTE("test", dbug_print_deps(te); );
|
||||||
DBUG_RETURN(FALSE);
|
DBUG_RETURN(FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1042,9 +1049,9 @@ void eliminate_tables(JOIN *join)
|
|||||||
uint m= max(thd->lex->current_select->max_equal_elems,1);
|
uint m= max(thd->lex->current_select->max_equal_elems,1);
|
||||||
uint max_elems= ((thd->lex->current_select->cond_count+1)*2 +
|
uint max_elems= ((thd->lex->current_select->cond_count+1)*2 +
|
||||||
thd->lex->current_select->between_count)*m + 1 + 10;
|
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;
|
DBUG_VOID_RETURN;
|
||||||
Equality_dep *eq_deps_end= te.equality_deps;
|
Equality_module *eq_deps_end= te.equality_deps;
|
||||||
table_map eliminable_tables= 0;
|
table_map eliminable_tables= 0;
|
||||||
collect_funcdeps_for_join_list(&te, join->join_list,
|
collect_funcdeps_for_join_list(&te, join->join_list,
|
||||||
FALSE,
|
FALSE,
|
||||||
@@ -1052,9 +1059,41 @@ void eliminate_tables(JOIN *join)
|
|||||||
&eliminable_tables,
|
&eliminable_tables,
|
||||||
&eq_deps_end);
|
&eq_deps_end);
|
||||||
te.n_equality_deps= eq_deps_end - te.equality_deps;
|
te.n_equality_deps= eq_deps_end - te.equality_deps;
|
||||||
Func_dep *bound_dep;
|
|
||||||
setup_equality_deps(&te, &bound_dep);
|
|
||||||
|
|
||||||
|
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.
|
Run the wave.
|
||||||
All Func_dep-derived objects are divided into three classes:
|
All Func_dep-derived objects are divided into three classes:
|
||||||
@@ -1063,85 +1102,82 @@ void eliminate_tables(JOIN *join)
|
|||||||
- Those that have bound=TRUE and are in the list..
|
- Those that have bound=TRUE and are in the list..
|
||||||
|
|
||||||
*/
|
*/
|
||||||
while (bound_dep)
|
while (bound_modules)
|
||||||
{
|
{
|
||||||
Func_dep *next= bound_dep->next;
|
for (;bound_modules; bound_modules= bound_modules->next)
|
||||||
//e= list.remove_first();
|
|
||||||
switch (bound_dep->type)
|
|
||||||
{
|
{
|
||||||
case Func_dep::FD_EXPRESSION:
|
switch (bound_modules->type)
|
||||||
|
{
|
||||||
|
case Module_dep::FD_EXPRESSION:
|
||||||
{
|
{
|
||||||
/* It's a field=expr and we got to know the expr, so we know the field */
|
/* 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)
|
if (!eq_dep->field->bound)
|
||||||
{
|
{
|
||||||
/* Mark as bound and add to the list */
|
/* Mark as bound and add to the list */
|
||||||
eq_dep->field->bound= TRUE;
|
eq_dep->field->bound= TRUE;
|
||||||
eq_dep->field->next= next;
|
eq_dep->field->next= bound_values;
|
||||||
next= eq_dep->field;
|
bound_values= eq_dep->field;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Func_dep::FD_FIELD:
|
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
|
Field became known. Check out
|
||||||
- unique keys we belong to
|
- unique keys we belong to
|
||||||
- expressions that depend on us.
|
- expressions that depend on us.
|
||||||
*/
|
*/
|
||||||
Field_dep *field_dep= (Field_dep*)bound_dep;
|
Field_value *field_dep= (Field_value*)bound_values;
|
||||||
for (Key_dep *key_dep= field_dep->table->keys; key_dep;
|
for (Key_module *key_dep= field_dep->table->keys; key_dep;
|
||||||
key_dep= key_dep->next_table_key)
|
key_dep= key_dep->next_table_key)
|
||||||
{
|
{
|
||||||
DBUG_PRINT("info", ("key %s.%s is now bound",
|
DBUG_PRINT("info", ("key %s.%s is now bound",
|
||||||
key_dep->table->table->alias,
|
key_dep->table->table->alias,
|
||||||
key_dep->table->table->key_info[key_dep->keyno].name));
|
key_dep->table->table->key_info[key_dep->keyno].name));
|
||||||
if (field_dep->field->part_of_key.is_set(key_dep->keyno) &&
|
if (field_dep->field->part_of_key.is_set(key_dep->keyno) &&
|
||||||
!key_dep->bound)
|
key_dep->unknown_args && !--key_dep->unknown_args)
|
||||||
{
|
|
||||||
if (!--key_dep->n_missing_keyparts)
|
|
||||||
{
|
{
|
||||||
/* Mark as bound and add to the list */
|
/* Mark as bound and add to the list */
|
||||||
key_dep->bound= TRUE;
|
key_dep->next= bound_modules;
|
||||||
key_dep->next= next;
|
bound_modules= key_dep;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
signal_from_field_to_exprs(te, field_dep, &bound_modules);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Func_dep::FD_UNIQUE_KEY:
|
case Value_dep::VALUE_TABLE:
|
||||||
{
|
{
|
||||||
/* Unique key is known means the table is known */
|
Table_value *table_dep=(Table_value*)bound_values;
|
||||||
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;
|
|
||||||
DBUG_PRINT("info", ("table %s is now bound",
|
DBUG_PRINT("info", ("table %s is now bound",
|
||||||
table_dep->table->alias));
|
table_dep->table->alias));
|
||||||
/*
|
/*
|
||||||
@@ -1149,50 +1185,35 @@ void eliminate_tables(JOIN *join)
|
|||||||
- all its fields are known
|
- all its fields are known
|
||||||
- one more element in outer join nest is 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)
|
field_dep= field_dep->next_table_field)
|
||||||
{
|
{
|
||||||
if (!field_dep->bound)
|
if (!field_dep->bound)
|
||||||
{
|
{
|
||||||
/* Mark as bound and add to the list */
|
/* Mark as bound and add to the list */
|
||||||
field_dep->bound= TRUE;
|
field_dep->bound= TRUE;
|
||||||
field_dep->next= next;
|
signal_from_field_to_exprs(te, field_dep, &bound_modules);
|
||||||
next= field_dep;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Outer_join_dep *outer_join_dep= table_dep->outer_join_dep;
|
for (Outer_join_module *outer_join_dep= table_dep->outer_join_dep;
|
||||||
if (!(outer_join_dep->missing_tables &= ~table_dep->table->map))
|
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 */
|
/* Mark as bound and add to the list */
|
||||||
outer_join_dep->bound= TRUE;
|
outer_join_dep->next= bound_modules;
|
||||||
outer_join_dep->next= next;
|
bound_modules= outer_join_dep;
|
||||||
next= outer_join_dep;
|
}
|
||||||
}
|
}
|
||||||
break;
|
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:
|
default:
|
||||||
DBUG_ASSERT(0);
|
DBUG_ASSERT(0);
|
||||||
}
|
}
|
||||||
bound_dep= next;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DBUG_VOID_RETURN;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1232,7 +1253,7 @@ static void mark_as_eliminated(JOIN *join, TABLE_LIST *tbl)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
#ifndef DBUG_OFF
|
#ifndef DBUG_OFF
|
||||||
static
|
static
|
||||||
void dbug_print_deps(Table_elimination *te)
|
void dbug_print_deps(Table_elimination *te)
|
||||||
@@ -1243,7 +1264,7 @@ void dbug_print_deps(Table_elimination *te)
|
|||||||
fprintf(DBUG_FILE,"deps {\n");
|
fprintf(DBUG_FILE,"deps {\n");
|
||||||
|
|
||||||
/* Start with printing equalities */
|
/* 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++)
|
eq_dep != te->equality_deps + te->n_equality_deps; eq_dep++)
|
||||||
{
|
{
|
||||||
char buf[128];
|
char buf[128];
|
||||||
@@ -1261,13 +1282,13 @@ void dbug_print_deps(Table_elimination *te)
|
|||||||
/* Then tables and their fields */
|
/* Then tables and their fields */
|
||||||
for (uint i=0; i < MAX_TABLES; i++)
|
for (uint i=0; i < MAX_TABLES; i++)
|
||||||
{
|
{
|
||||||
Table_dep *table_dep;
|
Table_value *table_dep;
|
||||||
if ((table_dep= te->table_deps[i]))
|
if ((table_dep= te->table_deps[i]))
|
||||||
{
|
{
|
||||||
/* Print table */
|
/* Print table */
|
||||||
fprintf(DBUG_FILE, " table %s\n", table_dep->table->alias);
|
fprintf(DBUG_FILE, " table %s\n", table_dep->table->alias);
|
||||||
/* Print fields */
|
/* 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)
|
field_dep= field_dep->next_table_field)
|
||||||
{
|
{
|
||||||
fprintf(DBUG_FILE, " field %s.%s ->", table_dep->table->alias,
|
fprintf(DBUG_FILE, " field %s.%s ->", table_dep->table->alias,
|
||||||
@@ -1288,7 +1309,7 @@ void dbug_print_deps(Table_elimination *te)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
/**
|
/**
|
||||||
@} (end of group Table_Elimination)
|
@} (end of group Table_Elimination)
|
||||||
*/
|
*/
|
||||||
|
Reference in New Issue
Block a user