diff options
Diffstat (limited to 'sql/sql_select.h')
-rw-r--r-- | sql/sql_select.h | 171 |
1 files changed, 111 insertions, 60 deletions
diff --git a/sql/sql_select.h b/sql/sql_select.h index 54138712da4..80b5e3c4e68 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -2,7 +2,7 @@ #define SQL_SELECT_INCLUDED /* Copyright (c) 2000, 2013, Oracle and/or its affiliates. - Copyright (c) 2008, 2013, Monty Program Ab. + Copyright (c) 2008, 2015, MariaDB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -29,33 +29,10 @@ #endif #include "procedure.h" -#include <myisam.h> #include "sql_array.h" /* Array */ #include "records.h" /* READ_RECORD */ #include "opt_range.h" /* SQL_SELECT, QUICK_SELECT_I */ - -#if defined(WITH_ARIA_STORAGE_ENGINE) -#include <maria.h> -#endif -#if defined(USE_ARIA_FOR_TMP_TABLES) -#define TMP_ENGINE_HTON maria_hton -inline uint tmp_table_max_key_length() { - return maria_max_key_length(); -} - -inline uint tmp_table_max_key_parts() { - return maria_max_key_segments(); -} -#else -#define TMP_ENGINE_HTON myisam_hton -inline uint tmp_table_max_key_length() { - return MI_MAX_KEY_LENGTH; -} -inline uint tmp_table_max_key_parts() { - return MI_MAX_KEY_SEG; -} -#endif /* Values in optimize */ #define KEY_OPTIMIZE_EXISTS 1 #define KEY_OPTIMIZE_REF_OR_NULL 2 @@ -114,6 +91,13 @@ typedef struct st_table_ref uchar *key_buff; ///< value to look for with key uchar *key_buff2; ///< key_buff+key_length store_key **key_copy; // + + /* + Bitmap of key parts which refer to constants. key_copy only has copiers for + non-const key parts. + */ + key_part_map const_ref_part_map; + Item **items; ///< val()'s for each keypart /* Array of pointers to trigger variables. Some/all of the pointers may be @@ -204,6 +188,12 @@ int rr_sequential(READ_RECORD *info); int rr_sequential_and_unpack(READ_RECORD *info); +#include "sql_explain.h" + +/************************************************************************************** + * New EXPLAIN structures END + *************************************************************************************/ + class JOIN_CACHE; class SJ_TMP_TABLE; class JOIN_TAB_RANGE; @@ -258,7 +248,8 @@ typedef struct st_join_table { JOIN_TAB_RANGE *bush_children; /* Special content for EXPLAIN 'Extra' column or NULL if none */ - const char *info; + enum explain_extra_tag info; + /* Bitmap of TAB_INFO_* bits that encodes special line for EXPLAIN 'Extra' column, or 0 if there is no info. @@ -295,8 +286,11 @@ typedef struct st_join_table { */ double read_time; - /* psergey-todo: make the below have type double, like POSITION::records_read? */ - ha_rows records_read; + /* Copy of POSITION::records_read, set by get_best_combination() */ + double records_read; + + /* The selectivity of the conditions that can be pushed to the table */ + double cond_selectivity; /* Startup cost for execution */ double startup_cost; @@ -529,7 +523,7 @@ typedef struct st_join_table { ha_rows get_examined_rows(); bool preread_init(); - bool is_sjm_nest() { return test(bush_children); } + bool is_sjm_nest() { return MY_TEST(bush_children); } bool access_from_tables_is_allowed(table_map used_tables, table_map sjm_lookup_tables) @@ -542,6 +536,7 @@ typedef struct st_join_table { bool keyuse_is_valid_for_access_in_chosen_plan(JOIN *join, KEYUSE *keyuse); + void remove_redundant_bnl_scan_conds(); } JOIN_TAB; @@ -723,8 +718,7 @@ public: struct st_position *pos, struct st_position *loose_scan_pos); friend bool get_best_combination(JOIN *join); - friend int setup_semijoin_dups_elimination(JOIN *join, ulonglong options, - uint no_jbuf_after); + friend int setup_semijoin_loosescan(JOIN *join); friend void fix_semijoin_strategies_for_picked_join_order(JOIN *join); }; @@ -781,6 +775,9 @@ typedef struct st_position :public Sql_alloc */ double records_read; + /* The selectivity of the pushed down conditions */ + double cond_selectivity; + /* Cost accessing the table in course of the entire complete join execution, i.e. cost of one access method use (e.g. 'range' or 'ref' scan ) times @@ -789,7 +786,7 @@ typedef struct st_position :public Sql_alloc double read_time; /* Cumulative cost and record count for the join prefix */ - COST_VECT prefix_cost; + Cost_estimate prefix_cost; double prefix_record_count; /* @@ -913,7 +910,7 @@ protected: enum enum_reopt_result { REOPT_NEW_PLAN, /* there is a new reoptimized plan */ REOPT_OLD_PLAN, /* no new improved plan can be found, use the old one */ - REOPT_ERROR, /* an irrecovarable error occured during reoptimization */ + REOPT_ERROR, /* an irrecovarable error occurred during reoptimization */ REOPT_NONE /* not yet reoptimized */ }; @@ -951,7 +948,7 @@ public: */ JOIN_TAB *table_access_tabs; uint top_table_access_tabs_count; - + JOIN_TAB **map2table; ///< mapping between table indexes and JOIN_TABs JOIN_TAB *join_tab_save; ///< saved join_tab for subquery reexecution @@ -1129,6 +1126,12 @@ public: restore_no_rows_in_result() in ::reinit() */ bool no_rows_in_result_called; + + /** + This is set if SQL_CALC_ROWS was calculated by filesort() + and should be taken from the appropriate JOIN_TAB + */ + bool filesort_found_rows; /** Copy of this JOIN to be used with temporary tables. @@ -1229,8 +1232,14 @@ public: const char *zero_result_cause; ///< not 0 if exec must return zero result bool union_part; ///< this subselect is part of union + + enum join_optimization_state { NOT_OPTIMIZED=0, + OPTIMIZATION_IN_PROGRESS=1, + OPTIMIZATION_DONE=2}; bool optimized; ///< flag to avoid double optimization in EXPLAIN bool initialized; ///< flag to avoid double init_execution calls + + enum { QEP_NOT_PRESENT_YET, QEP_AVAILABLE, QEP_DELETED} have_query_plan; /* Additional WHERE and HAVING predicates to be considered for IN=>EXISTS @@ -1298,7 +1307,7 @@ public: lock= thd_arg->lock; select_lex= 0; //for safety tmp_join= 0; - select_distinct= test(select_options & SELECT_DISTINCT); + select_distinct= MY_TEST(select_options & SELECT_DISTINCT); no_order= 0; simple_order= 0; simple_group= 0; @@ -1313,6 +1322,7 @@ public: ref_pointer_array_size= 0; zero_result_cause= 0; optimized= 0; + have_query_plan= QEP_NOT_PRESENT_YET; initialized= 0; cleaned= 0; cond_equal= 0; @@ -1339,6 +1349,8 @@ public: emb_sjm_nest= NULL; sjm_lookup_tables= 0; sjm_scan_tables= 0; + + exec_saved_explain= false; /* The following is needed because JOIN::cleanup(true) may be called for joins for which JOIN::optimize was aborted with an error before a proper @@ -1347,15 +1359,24 @@ public: table_access_tabs= NULL; } + /* + TRUE <=> There was a JOIN::exec() call, which saved this JOIN's EXPLAIN. + The idea is that we also save at the end of JOIN::optimize(), but that + might not be the final plan. + */ + bool exec_saved_explain; + int prepare(Item ***rref_pointer_array, TABLE_LIST *tables, uint wind_num, COND *conds, uint og_num, ORDER *order, bool skip_order_by, ORDER *group, Item *having, ORDER *proc_param, SELECT_LEX *select, SELECT_LEX_UNIT *unit); bool prepare_stage2(); int optimize(); + int optimize_inner(); int reinit(); int init_execution(); void exec(); + void exec_inner(); int destroy(); void restore_tmp(); bool alloc_func_list(); @@ -1431,7 +1452,7 @@ public: void set_allowed_join_cache_types(); bool is_allowed_hash_join_access() { - return test(allowed_join_cache_types & JOIN_CACHE_HASHED_BIT) && + return MY_TEST(allowed_join_cache_types & JOIN_CACHE_HASHED_BIT) && max_allowed_join_cache_level > JOIN_CACHE_HASHED_BIT; } /* @@ -1450,7 +1471,7 @@ public: return ((const_tables != table_count && ((select_distinct || !simple_order || !simple_group) || (group_list && order) || - test(select_options & OPTION_BUFFER_RESULT))) || + MY_TEST(select_options & OPTION_BUFFER_RESULT))) || (rollup.state != ROLLUP::STATE_NONE && select_distinct)); } bool choose_subquery_plan(table_map join_tables); @@ -1469,6 +1490,11 @@ public: { return (unit->item && unit->item->is_in_predicate()); } + void save_explain_data(Explain_query *output, bool can_overwrite, + bool need_tmp_table, bool need_order, bool distinct); + int save_explain_data_intern(Explain_query *output, bool need_tmp_table, + bool need_order, bool distinct, + const char *message); private: /** TRUE if the query contains an aggregate function but has no GROUP @@ -1532,21 +1558,8 @@ public: store_key(THD *thd, Field *field_arg, uchar *ptr, uchar *null, uint length) :null_key(0), null_ptr(null), err(0) { - if (field_arg->type() == MYSQL_TYPE_BLOB - || field_arg->type() == MYSQL_TYPE_GEOMETRY) - { - /* - Key segments are always packed with a 2 byte length prefix. - See mi_rkey for details. - */ - to_field= new Field_varstring(ptr, length, 2, null, 1, - Field::NONE, field_arg->field_name, - field_arg->table->s, field_arg->charset()); - to_field->init(field_arg->table); - } - else - to_field=field_arg->new_key_field(thd->mem_root, field_arg->table, - ptr, null, 1); + to_field=field_arg->new_key_field(thd->mem_root, field_arg->table, + ptr, length, null, 1); } store_key(store_key &arg) :Sql_alloc(), null_key(arg.null_key), to_field(arg.to_field), @@ -1784,10 +1797,6 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, bool table_cant_handle_bit_fields, bool make_copy_field, uint convert_blob_length); -bool create_internal_tmp_table(TABLE *table, KEY *keyinfo, - ENGINE_COLUMNDEF *start_recinfo, - ENGINE_COLUMNDEF **recinfo, - ulonglong options, my_bool big_tables); /* General routine to change field->ptr of a NULL-terminated array of Field @@ -1822,8 +1831,12 @@ inline bool optimizer_flag(THD *thd, uint flag) return (thd->variables.optimizer_switch & flag); } +int print_fake_select_lex_join(select_result_sink *result, bool on_the_fly, + SELECT_LEX *select_lex, uint8 select_options); + uint get_index_for_order(ORDER *order, TABLE *table, SQL_SELECT *select, - ha_rows limit, bool *need_sort, bool *reverse); + ha_rows limit, ha_rows *scanned_limit, + bool *need_sort, bool *reverse); ORDER *simple_remove_const(ORDER *order, COND *where); bool const_expression_in_where(COND *cond, Item *comp_item, Field *comp_field= NULL, @@ -1837,6 +1850,31 @@ void eliminate_tables(JOIN *join); /* Index Condition Pushdown entry point function */ void push_index_cond(JOIN_TAB *tab, uint keyno); +#define OPT_LINK_EQUAL_FIELDS 1 + +/* EXPLAIN-related utility functions */ +int print_explain_message_line(select_result_sink *result, + uint8 options, + uint select_number, + const char *select_type, + ha_rows *rows, + const char *message); +void explain_append_mrr_info(QUICK_RANGE_SELECT *quick, String *res); +int print_explain_row(select_result_sink *result, + uint8 options, + uint select_number, + const char *select_type, + const char *table_name, + const char *partitions, + enum join_type jtype, + const char *possible_keys, + const char *index, + const char *key_len, + const char *ref, + ha_rows *rows, + const char *extra); +void make_possible_keys_line(TABLE *table, key_map possible_keys, String *line); + /**************************************************************************** Temporary table support for SQL Runtime ***************************************************************************/ @@ -1853,17 +1891,30 @@ TABLE *create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, bool keep_row_order= FALSE); void free_tmp_table(THD *thd, TABLE *entry); bool create_internal_tmp_table_from_heap(THD *thd, TABLE *table, - ENGINE_COLUMNDEF *start_recinfo, - ENGINE_COLUMNDEF **recinfo, + TMP_ENGINE_COLUMNDEF *start_recinfo, + TMP_ENGINE_COLUMNDEF **recinfo, int error, bool ignore_last_dupp_key_error, bool *is_duplicate); bool create_internal_tmp_table(TABLE *table, KEY *keyinfo, - ENGINE_COLUMNDEF *start_recinfo, - ENGINE_COLUMNDEF **recinfo, + TMP_ENGINE_COLUMNDEF *start_recinfo, + TMP_ENGINE_COLUMNDEF **recinfo, ulonglong options); bool open_tmp_table(TABLE *table); void setup_tmp_table_column_bitmaps(TABLE *table, uchar *bitmaps); double prev_record_reads(POSITION *positions, uint idx, table_map found_ref); void fix_list_after_tbl_changes(SELECT_LEX *new_parent, List<TABLE_LIST> *tlist); +struct st_cond_statistic +{ + Item *cond; + Field *field_arg; + ulong positive; +}; +typedef struct st_cond_statistic COND_STATISTIC; + +ulong check_selectivity(THD *thd, + ulong rows_to_read, + TABLE *table, + List<COND_STATISTIC> *conds); + #endif /* SQL_SELECT_INCLUDED */ |