diff options
author | Sergey Petrunya <psergey@askmonty.org> | 2011-05-25 19:31:13 +0400 |
---|---|---|
committer | Sergey Petrunya <psergey@askmonty.org> | 2011-05-25 19:31:13 +0400 |
commit | 77b3b960b101a0a1dbc2fe0780d8654f4aa21f62 (patch) | |
tree | 08baa2ad4bf65d72ab765e2beec04e21a9b700d9 /sql/item_subselect.h | |
parent | 0a5026b057a9883fd947fa9ec0c5303e42115977 (diff) | |
parent | f34b421839c78ccc56db4ecc7bbb97929f309801 (diff) | |
download | mariadb-git-77b3b960b101a0a1dbc2fe0780d8654f4aa21f62.tar.gz |
Merge MWL#90 with 5.3-main
Diffstat (limited to 'sql/item_subselect.h')
-rw-r--r-- | sql/item_subselect.h | 156 |
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(); + }; |