summaryrefslogtreecommitdiff
path: root/sql/item_subselect.h
diff options
context:
space:
mode:
authorSergey Petrunya <psergey@askmonty.org>2011-05-25 19:31:13 +0400
committerSergey Petrunya <psergey@askmonty.org>2011-05-25 19:31:13 +0400
commit77b3b960b101a0a1dbc2fe0780d8654f4aa21f62 (patch)
tree08baa2ad4bf65d72ab765e2beec04e21a9b700d9 /sql/item_subselect.h
parent0a5026b057a9883fd947fa9ec0c5303e42115977 (diff)
parentf34b421839c78ccc56db4ecc7bbb97929f309801 (diff)
downloadmariadb-git-77b3b960b101a0a1dbc2fe0780d8654f4aa21f62.tar.gz
Merge MWL#90 with 5.3-main
Diffstat (limited to 'sql/item_subselect.h')
-rw-r--r--sql/item_subselect.h156
1 files changed, 90 insertions, 66 deletions
diff --git a/sql/item_subselect.h b/sql/item_subselect.h
index 740daeecf13..ad98949f78e 100644
--- a/sql/item_subselect.h
+++ b/sql/item_subselect.h
@@ -36,6 +36,22 @@ class Item_subselect :public Item_result_field
protected:
/* thread handler, will be assigned in fix_fields only */
THD *thd;
+ /* old engine if engine was changed */
+ subselect_engine *old_engine;
+ /* cache of used external tables */
+ table_map used_tables_cache;
+ /* allowed number of columns (1 for single value subqueries) */
+ uint max_columns;
+ /* where subquery is placed */
+ enum_parsing_place parsing_place;
+ /* work with 'substitution' */
+ bool have_to_be_excluded;
+ /* cache of constant state */
+ bool const_item_cache;
+
+ bool inside_first_fix_fields;
+ bool done_first_fix_fields;
+public:
/*
Used inside Item_subselect::fix_fields() according to this scenario:
> Item_subselect::fix_fields
@@ -46,31 +62,15 @@ protected:
< child_join->prepare
< engine->prepare
*ref= substitution;
+ substitution= NULL;
< Item_subselect::fix_fields
*/
Item *substitution;
-public:
/* unit of subquery */
st_select_lex_unit *unit;
-protected:
Item *expr_cache;
/* engine that perform execution of subselect (single select or union) */
subselect_engine *engine;
- /* old engine if engine was changed */
- subselect_engine *old_engine;
- /* cache of used external tables */
- table_map used_tables_cache;
- /* allowed number of columns (1 for single value subqueries) */
- uint max_columns;
- /* where subquery is placed */
- enum_parsing_place parsing_place;
- /* work with 'substitution' */
- bool have_to_be_excluded;
- /* cache of constant state */
- bool const_item_cache;
-
- bool inside_first_fix_fields;
- bool done_first_fix_fields;
/*
Set to TRUE if at optimization or execution time we determine that this
item's value is a constant. We need this member because it is not possible
@@ -78,7 +78,6 @@ protected:
*/
bool forced_const;
-public:
/* A reference from inside subquery predicate to somewhere outside of it */
class Ref_to_outside : public Sql_alloc
{
@@ -160,6 +159,7 @@ public:
bool mark_as_dependent(THD *thd, st_select_lex *select, Item *item);
void fix_after_pullout(st_select_lex *new_parent, Item **ref);
void recalc_used_tables(st_select_lex *new_parent, bool after_pullout);
+ //virtual int optimize(double *out_rows, double *cost);
virtual bool exec();
/*
If subquery optimization or execution determines that the subquery has
@@ -345,6 +345,8 @@ public:
};
+TABLE_LIST * const NO_JOIN_NEST=(TABLE_LIST*)0x1;
+
/*
Possible methods to execute an IN predicate. These are set by the optimizer
based on user-set optimizer switches, semantic analysis and cost comparison.
@@ -387,9 +389,11 @@ protected:
all JOIN in UNION
*/
Item *expr;
- Item_in_optimizer *optimizer;
bool was_null;
bool abort_on_null;
+public:
+ Item_in_optimizer *optimizer;
+protected:
/* Used to trigger on/off conditions that were pushed down to subselect */
bool *pushed_cond_guards;
Comp_creator *func;
@@ -413,19 +417,13 @@ public:
/*
Used by subquery optimizations to keep track about in which clause this
subquery predicate is located:
- (TABLE_LIST*) 1 - the predicate is an AND-part of the WHERE
+ NO_JOIN_NEST - the predicate is an AND-part of the WHERE
join nest pointer - the predicate is an AND-part of ON expression
of a join nest
NULL - for all other locations
See also THD::emb_on_expr_nest.
*/
TABLE_LIST *emb_on_expr_nest;
- /*
- Location of the subquery predicate. It is either
- - pointer to join nest if the subquery predicate is in the ON expression
- - (TABLE_LIST*)1 if the predicate is in the WHERE.
- */
- TABLE_LIST *expr_join_nest;
/*
Types of left_expr and subquery's select list allow to perform subquery
materialization. Currently, we set this to FALSE when it as well could
@@ -437,10 +435,31 @@ public:
Same as above, but they also allow to scan the materialized table.
*/
bool sjm_scan_allowed;
+ double jtbm_read_time;
+ double jtbm_record_count;
/* A bitmap of possible execution strategies for an IN predicate. */
uchar in_strategy;
+ bool is_jtbm_merged;
+
+ /*
+ TRUE<=>this is a flattenable semi-join, false overwise.
+ */
+ bool is_flattenable_semijoin;
+
+ /*
+ Used to determine how this subselect item is represented in the item tree,
+ in case there is a need to locate it there and replace with something else.
+ Two options are possible:
+ 1. This item is there 'as-is'.
+ 1. This item is wrapped within Item_in_optimizer.
+ */
+ Item *original_item()
+ {
+ return is_flattenable_semijoin ? (Item*)this : (Item*)optimizer;
+ }
+
bool *get_cond_guard(int i)
{
return pushed_cond_guards ? pushed_cond_guards + i : NULL;
@@ -457,8 +476,9 @@ public:
Item_in_subselect(Item * left_expr, st_select_lex *select_lex);
Item_in_subselect()
:Item_exists_subselect(), left_expr_cache(0), first_execution(TRUE),
- optimizer(0), abort_on_null(0),
+ abort_on_null(0), optimizer(0),
pushed_cond_guards(NULL), func(NULL), in_strategy(0),
+ is_jtbm_merged(FALSE),
upper_item(0)
{}
void cleanup();
@@ -494,6 +514,7 @@ public:
void set_first_execution() { if (first_execution) first_execution= FALSE; }
bool expr_cache_is_needed(THD *thd);
+ int optimize(double *out_rows, double *cost);
/*
Return the identifier that we could use to identify the subquery for the
user.
@@ -563,6 +584,7 @@ public:
THD * get_thd() { return thd; }
virtual int prepare()= 0;
virtual void fix_length_and_dec(Item_cache** row)= 0;
+ //virtual int optimize(double *out_rows, double *cost) { DBUG_ASSERT(0); return 0; }
/*
Execute the engine
@@ -793,7 +815,7 @@ inline bool Item_subselect::is_uncacheable() const
class subselect_hash_sj_engine : public subselect_engine
{
-protected:
+public:
/* The table into which the subquery is materialized. */
TABLE *tmp_table;
/* TRUE if the subquery was materialized into a temp table. */
@@ -805,63 +827,33 @@ protected:
of subselect_single_select_engine::[prepare | cols].
*/
subselect_single_select_engine *materialize_engine;
- /* The engine used to compute the IN predicate. */
- subselect_engine *lookup_engine;
/*
QEP to execute the subquery and materialize its result into a
temporary table. Created during the first call to exec().
*/
JOIN *materialize_join;
-
- /* Keyparts of the only non-NULL composite index in a rowid merge. */
- MY_BITMAP non_null_key_parts;
- /* Keyparts of the single column indexes with NULL, one keypart per index. */
- MY_BITMAP partial_match_key_parts;
- uint count_partial_match_columns;
- uint count_null_only_columns;
/*
A conjunction of all the equality condtions between all pairs of expressions
that are arguments of an IN predicate. We need these to post-filter some
IN results because index lookups sometimes match values that are actually
not equal to the search key in SQL terms.
- */
+ */
Item_cond_and *semi_join_conds;
- /* Possible execution strategies that can be used to compute hash semi-join.*/
- enum exec_strategy {
- UNDEFINED,
- COMPLETE_MATCH, /* Use regular index lookups. */
- PARTIAL_MATCH, /* Use some partial matching strategy. */
- PARTIAL_MATCH_MERGE, /* Use partial matching through index merging. */
- PARTIAL_MATCH_SCAN, /* Use partial matching through table scan. */
- IMPOSSIBLE /* Subquery materialization is not applicable. */
- };
- /* The chosen execution strategy. Computed after materialization. */
- exec_strategy strategy;
-protected:
- exec_strategy get_strategy_using_schema();
- exec_strategy get_strategy_using_data();
- ulonglong rowid_merge_buff_size(bool has_non_null_key,
- bool has_covering_null_row,
- MY_BITMAP *partial_match_key_parts);
- void choose_partial_match_strategy(bool has_non_null_key,
- bool has_covering_null_row,
- MY_BITMAP *partial_match_key_parts);
- bool make_semi_join_conds();
- subselect_uniquesubquery_engine* make_unique_engine();
-public:
subselect_hash_sj_engine(THD *thd, Item_subselect *in_predicate,
subselect_single_select_engine *old_engine)
- :subselect_engine(thd, in_predicate, NULL), tmp_table(NULL),
- is_materialized(FALSE), materialize_engine(old_engine), lookup_engine(NULL),
- materialize_join(NULL), count_partial_match_columns(0),
- count_null_only_columns(0), semi_join_conds(NULL), strategy(UNDEFINED)
+ : subselect_engine(thd, in_predicate, NULL),
+ tmp_table(NULL), is_materialized(FALSE), materialize_engine(old_engine),
+ materialize_join(NULL), semi_join_conds(NULL), lookup_engine(NULL),
+ count_partial_match_columns(0), count_null_only_columns(0),
+ strategy(UNDEFINED)
{}
~subselect_hash_sj_engine();
- bool init(List<Item> *tmp_columns);
+ bool init(List<Item> *tmp_columns, uint subquery_id);
void cleanup();
int prepare();
+ //int optimize(double *out_rows, double *cost);
int exec();
virtual void print(String *str, enum_query_type query_type);
uint cols()
@@ -881,6 +873,38 @@ public:
//=>base class
bool change_result(Item_subselect *si, select_result_interceptor *result);
bool no_tables();//=>base class
+
+protected:
+ /* The engine used to compute the IN predicate. */
+ subselect_engine *lookup_engine;
+ /* Keyparts of the only non-NULL composite index in a rowid merge. */
+ MY_BITMAP non_null_key_parts;
+ /* Keyparts of the single column indexes with NULL, one keypart per index. */
+ MY_BITMAP partial_match_key_parts;
+ uint count_partial_match_columns;
+ uint count_null_only_columns;
+ /* Possible execution strategies that can be used to compute hash semi-join.*/
+ enum exec_strategy {
+ UNDEFINED,
+ COMPLETE_MATCH, /* Use regular index lookups. */
+ PARTIAL_MATCH, /* Use some partial matching strategy. */
+ PARTIAL_MATCH_MERGE, /* Use partial matching through index merging. */
+ PARTIAL_MATCH_SCAN, /* Use partial matching through table scan. */
+ IMPOSSIBLE /* Subquery materialization is not applicable. */
+ };
+ /* The chosen execution strategy. Computed after materialization. */
+ exec_strategy strategy;
+ exec_strategy get_strategy_using_schema();
+ exec_strategy get_strategy_using_data();
+ ulonglong rowid_merge_buff_size(bool has_non_null_key,
+ bool has_covering_null_row,
+ MY_BITMAP *partial_match_key_parts);
+ void choose_partial_match_strategy(bool has_non_null_key,
+ bool has_covering_null_row,
+ MY_BITMAP *partial_match_key_parts);
+ bool make_semi_join_conds();
+ subselect_uniquesubquery_engine* make_unique_engine();
+
};