| 1 | /* Copyright (c) 2000, 2016 Oracle and/or its affiliates. |
| 2 | Copyright (c) 2009, 2018 MariaDB Corporation |
| 3 | |
| 4 | This program is free software; you can redistribute it and/or modify |
| 5 | it under the terms of the GNU General Public License as published by |
| 6 | the Free Software Foundation; version 2 of the License. |
| 7 | |
| 8 | This program is distributed in the hope that it will be useful, |
| 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 11 | GNU General Public License for more details. |
| 12 | |
| 13 | You should have received a copy of the GNU General Public License |
| 14 | along with this program; if not, write to the Free Software |
| 15 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ |
| 16 | |
| 17 | /** |
| 18 | @file |
| 19 | |
| 20 | @brief |
| 21 | mysql_select and join optimization |
| 22 | |
| 23 | |
| 24 | @defgroup Query_Optimizer Query Optimizer |
| 25 | @{ |
| 26 | */ |
| 27 | |
| 28 | #ifdef USE_PRAGMA_IMPLEMENTATION |
| 29 | #pragma implementation // gcc: Class implementation |
| 30 | #endif |
| 31 | |
| 32 | #include "mariadb.h" |
| 33 | #include "sql_priv.h" |
| 34 | #include "unireg.h" |
| 35 | #include "sql_select.h" |
| 36 | #include "sql_cache.h" // query_cache_* |
| 37 | #include "sql_table.h" // primary_key_name |
| 38 | #include "probes_mysql.h" |
| 39 | #include "key.h" // key_copy, key_cmp, key_cmp_if_same |
| 40 | #include "lock.h" // mysql_unlock_some_tables, |
| 41 | // mysql_unlock_read_tables |
| 42 | #include "sql_show.h" // append_identifier |
| 43 | #include "sql_base.h" // setup_wild, setup_fields, fill_record |
| 44 | #include "sql_parse.h" // check_stack_overrun |
| 45 | #include "sql_partition.h" // make_used_partitions_str |
| 46 | #include "sql_acl.h" // *_ACL |
| 47 | #include "sql_test.h" // print_where, print_keyuse_array, |
| 48 | // print_sjm, print_plan, TEST_join |
| 49 | #include "records.h" // init_read_record, end_read_record |
| 50 | #include "filesort.h" // filesort_free_buffers |
| 51 | #include "sql_union.h" // mysql_union |
| 52 | #include "opt_subselect.h" |
| 53 | #include "sql_derived.h" |
| 54 | #include "sql_statistics.h" |
| 55 | #include "sql_cte.h" |
| 56 | #include "sql_window.h" |
| 57 | #include "tztime.h" |
| 58 | |
| 59 | #include "debug_sync.h" // DEBUG_SYNC |
| 60 | #include <m_ctype.h> |
| 61 | #include <my_bit.h> |
| 62 | #include <hash.h> |
| 63 | #include <ft_global.h> |
| 64 | #include "sys_vars_shared.h" |
| 65 | #include "sp_head.h" |
| 66 | #include "sp_rcontext.h" |
| 67 | |
| 68 | /* |
| 69 | A key part number that means we're using a fulltext scan. |
| 70 | |
| 71 | In order not to confuse it with regular equalities, we need to pick |
| 72 | a number that's greater than MAX_REF_PARTS. |
| 73 | |
| 74 | Hash Join code stores field->field_index in KEYUSE::keypart, so the |
| 75 | number needs to be bigger than MAX_FIELDS, also. |
| 76 | |
| 77 | CAUTION: sql_test.cc has its own definition of FT_KEYPART. |
| 78 | */ |
| 79 | #define FT_KEYPART (MAX_FIELDS+10) |
| 80 | |
| 81 | const char *join_type_str[]={ "UNKNOWN" ,"system" ,"const" ,"eq_ref" ,"ref" , |
| 82 | "MAYBE_REF" ,"ALL" ,"range" ,"index" ,"fulltext" , |
| 83 | "ref_or_null" ,"unique_subquery" ,"index_subquery" , |
| 84 | "index_merge" , "hash_ALL" , "hash_range" , |
| 85 | "hash_index" , "hash_index_merge" }; |
| 86 | |
| 87 | LEX_CSTRING group_key= {STRING_WITH_LEN("group_key" )}; |
| 88 | LEX_CSTRING distinct_key= {STRING_WITH_LEN("distinct_key" )}; |
| 89 | |
| 90 | struct st_sargable_param; |
| 91 | |
| 92 | static bool make_join_statistics(JOIN *join, List<TABLE_LIST> &leaves, |
| 93 | DYNAMIC_ARRAY *keyuse); |
| 94 | static bool update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse, |
| 95 | JOIN_TAB *join_tab, |
| 96 | uint tables, COND *conds, |
| 97 | table_map table_map, SELECT_LEX *select_lex, |
| 98 | SARGABLE_PARAM **sargables); |
| 99 | static int sort_keyuse(KEYUSE *a,KEYUSE *b); |
| 100 | static bool are_tables_local(JOIN_TAB *jtab, table_map used_tables); |
| 101 | static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse, |
| 102 | bool allow_full_scan, table_map used_tables); |
| 103 | void best_access_path(JOIN *join, JOIN_TAB *s, |
| 104 | table_map remaining_tables, uint idx, |
| 105 | bool disable_jbuf, double record_count, |
| 106 | POSITION *pos, POSITION *loose_scan_pos); |
| 107 | static void optimize_straight_join(JOIN *join, table_map join_tables); |
| 108 | static bool greedy_search(JOIN *join, table_map remaining_tables, |
| 109 | uint depth, uint prune_level, |
| 110 | uint use_cond_selectivity); |
| 111 | static bool best_extension_by_limited_search(JOIN *join, |
| 112 | table_map remaining_tables, |
| 113 | uint idx, double record_count, |
| 114 | double read_time, uint depth, |
| 115 | uint prune_level, |
| 116 | uint use_cond_selectivity); |
| 117 | static uint determine_search_depth(JOIN* join); |
| 118 | C_MODE_START |
| 119 | static int join_tab_cmp(const void *dummy, const void* ptr1, const void* ptr2); |
| 120 | static int join_tab_cmp_straight(const void *dummy, const void* ptr1, const void* ptr2); |
| 121 | static int join_tab_cmp_embedded_first(const void *emb, const void* ptr1, const void *ptr2); |
| 122 | C_MODE_END |
| 123 | static uint cache_record_length(JOIN *join,uint index); |
| 124 | static store_key *get_store_key(THD *thd, |
| 125 | KEYUSE *keyuse, table_map used_tables, |
| 126 | KEY_PART_INFO *key_part, uchar *key_buff, |
| 127 | uint maybe_null); |
| 128 | static bool make_outerjoin_info(JOIN *join); |
| 129 | static Item* |
| 130 | make_cond_after_sjm(THD *thd, Item *root_cond, Item *cond, table_map tables, |
| 131 | table_map sjm_tables, bool inside_or_clause); |
| 132 | static bool make_join_select(JOIN *join,SQL_SELECT *select,COND *item); |
| 133 | static void revise_cache_usage(JOIN_TAB *join_tab); |
| 134 | static bool make_join_readinfo(JOIN *join, ulonglong options, uint no_jbuf_after); |
| 135 | static bool only_eq_ref_tables(JOIN *join, ORDER *order, table_map tables); |
| 136 | static void update_depend_map(JOIN *join); |
| 137 | static void update_depend_map_for_order(JOIN *join, ORDER *order); |
| 138 | static ORDER *remove_const(JOIN *join,ORDER *first_order,COND *cond, |
| 139 | bool change_list, bool *simple_order); |
| 140 | static int return_zero_rows(JOIN *join, select_result *res, |
| 141 | List<TABLE_LIST> &tables, |
| 142 | List<Item> &fields, bool send_row, |
| 143 | ulonglong select_options, const char *info, |
| 144 | Item *having, List<Item> &all_fields); |
| 145 | static COND *build_equal_items(JOIN *join, COND *cond, |
| 146 | COND_EQUAL *inherited, |
| 147 | List<TABLE_LIST> *join_list, |
| 148 | bool ignore_on_conds, |
| 149 | COND_EQUAL **cond_equal_ref, |
| 150 | bool link_equal_fields= FALSE); |
| 151 | static COND* substitute_for_best_equal_field(THD *thd, JOIN_TAB *context_tab, |
| 152 | COND *cond, |
| 153 | COND_EQUAL *cond_equal, |
| 154 | void *table_join_idx); |
| 155 | static COND *simplify_joins(JOIN *join, List<TABLE_LIST> *join_list, |
| 156 | COND *conds, bool top, bool in_sj); |
| 157 | static bool check_interleaving_with_nj(JOIN_TAB *next); |
| 158 | static void restore_prev_nj_state(JOIN_TAB *last); |
| 159 | static uint reset_nj_counters(JOIN *join, List<TABLE_LIST> *join_list); |
| 160 | static uint build_bitmap_for_nested_joins(List<TABLE_LIST> *join_list, |
| 161 | uint first_unused); |
| 162 | |
| 163 | static COND *optimize_cond(JOIN *join, COND *conds, |
| 164 | List<TABLE_LIST> *join_list, |
| 165 | bool ignore_on_conds, |
| 166 | Item::cond_result *cond_value, |
| 167 | COND_EQUAL **cond_equal, |
| 168 | int flags= 0); |
| 169 | bool const_expression_in_where(COND *conds,Item *item, Item **comp_item); |
| 170 | static int do_select(JOIN *join, Procedure *procedure); |
| 171 | |
| 172 | static enum_nested_loop_state evaluate_join_record(JOIN *, JOIN_TAB *, int); |
| 173 | static enum_nested_loop_state |
| 174 | evaluate_null_complemented_join_record(JOIN *join, JOIN_TAB *join_tab); |
| 175 | static enum_nested_loop_state |
| 176 | end_send(JOIN *join, JOIN_TAB *join_tab, bool end_of_records); |
| 177 | static enum_nested_loop_state |
| 178 | end_write(JOIN *join, JOIN_TAB *join_tab, bool end_of_records); |
| 179 | static enum_nested_loop_state |
| 180 | end_update(JOIN *join, JOIN_TAB *join_tab, bool end_of_records); |
| 181 | static enum_nested_loop_state |
| 182 | end_unique_update(JOIN *join, JOIN_TAB *join_tab, bool end_of_records); |
| 183 | |
| 184 | static int join_read_const_table(THD *thd, JOIN_TAB *tab, POSITION *pos); |
| 185 | static int join_read_system(JOIN_TAB *tab); |
| 186 | static int join_read_const(JOIN_TAB *tab); |
| 187 | static int join_read_key(JOIN_TAB *tab); |
| 188 | static void join_read_key_unlock_row(st_join_table *tab); |
| 189 | static int join_read_always_key(JOIN_TAB *tab); |
| 190 | static int join_read_last_key(JOIN_TAB *tab); |
| 191 | static int join_no_more_records(READ_RECORD *info); |
| 192 | static int join_read_next(READ_RECORD *info); |
| 193 | static int join_init_quick_read_record(JOIN_TAB *tab); |
| 194 | static int test_if_quick_select(JOIN_TAB *tab); |
| 195 | static bool test_if_use_dynamic_range_scan(JOIN_TAB *join_tab); |
| 196 | static int join_read_first(JOIN_TAB *tab); |
| 197 | static int join_read_next(READ_RECORD *info); |
| 198 | static int join_read_next_same(READ_RECORD *info); |
| 199 | static int join_read_last(JOIN_TAB *tab); |
| 200 | static int join_read_prev_same(READ_RECORD *info); |
| 201 | static int join_read_prev(READ_RECORD *info); |
| 202 | static int join_ft_read_first(JOIN_TAB *tab); |
| 203 | static int join_ft_read_next(READ_RECORD *info); |
| 204 | int join_read_always_key_or_null(JOIN_TAB *tab); |
| 205 | int join_read_next_same_or_null(READ_RECORD *info); |
| 206 | static COND *make_cond_for_table(THD *thd, Item *cond,table_map table, |
| 207 | table_map used_table, |
| 208 | int join_tab_idx_arg, |
| 209 | bool exclude_expensive_cond, |
| 210 | bool retain_ref_cond); |
| 211 | static COND *make_cond_for_table_from_pred(THD *thd, Item *root_cond, |
| 212 | Item *cond, |
| 213 | table_map tables, |
| 214 | table_map used_table, |
| 215 | int join_tab_idx_arg, |
| 216 | bool exclude_expensive_cond, |
| 217 | bool retain_ref_cond); |
| 218 | |
| 219 | static Item* part_of_refkey(TABLE *form,Field *field); |
| 220 | uint find_shortest_key(TABLE *table, const key_map *usable_keys); |
| 221 | static bool test_if_cheaper_ordering(const JOIN_TAB *tab, |
| 222 | ORDER *order, TABLE *table, |
| 223 | key_map usable_keys, int key, |
| 224 | ha_rows select_limit, |
| 225 | int *new_key, int *new_key_direction, |
| 226 | ha_rows *new_select_limit, |
| 227 | uint *new_used_key_parts= NULL, |
| 228 | uint *saved_best_key_parts= NULL); |
| 229 | static int test_if_order_by_key(JOIN *join, |
| 230 | ORDER *order, TABLE *table, uint idx, |
| 231 | uint *used_key_parts= NULL); |
| 232 | static bool test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order, |
| 233 | ha_rows select_limit, bool no_changes, |
| 234 | const key_map *map); |
| 235 | static bool list_contains_unique_index(TABLE *table, |
| 236 | bool (*find_func) (Field *, void *), void *data); |
| 237 | static bool find_field_in_item_list (Field *field, void *data); |
| 238 | static bool find_field_in_order_list (Field *field, void *data); |
| 239 | int create_sort_index(THD *thd, JOIN *join, JOIN_TAB *tab, Filesort *fsort); |
| 240 | static int remove_dup_with_compare(THD *thd, TABLE *entry, Field **field, |
| 241 | Item *having); |
| 242 | static int remove_dup_with_hash_index(THD *thd,TABLE *table, |
| 243 | uint field_count, Field **first_field, |
| 244 | ulong key_length,Item *having); |
| 245 | static bool cmp_buffer_with_ref(THD *thd, TABLE *table, TABLE_REF *tab_ref); |
| 246 | static bool setup_new_fields(THD *thd, List<Item> &fields, |
| 247 | List<Item> &all_fields, ORDER *new_order); |
| 248 | static ORDER *create_distinct_group(THD *thd, Ref_ptr_array ref_pointer_array, |
| 249 | ORDER *order, List<Item> &fields, |
| 250 | List<Item> &all_fields, |
| 251 | bool *all_order_by_fields_used); |
| 252 | static bool test_if_subpart(ORDER *a,ORDER *b); |
| 253 | static TABLE *get_sort_by_table(ORDER *a,ORDER *b,List<TABLE_LIST> &tables, |
| 254 | table_map const_tables); |
| 255 | static void calc_group_buffer(JOIN *join,ORDER *group); |
| 256 | static bool make_group_fields(JOIN *main_join, JOIN *curr_join); |
| 257 | static bool alloc_group_fields(JOIN *join,ORDER *group); |
| 258 | // Create list for using with tempory table |
| 259 | static bool change_to_use_tmp_fields(THD *thd, Ref_ptr_array ref_pointer_array, |
| 260 | List<Item> &new_list1, |
| 261 | List<Item> &new_list2, |
| 262 | uint elements, List<Item> &items); |
| 263 | // Create list for using with tempory table |
| 264 | static bool change_refs_to_tmp_fields(THD *thd, Ref_ptr_array ref_pointer_array, |
| 265 | List<Item> &new_list1, |
| 266 | List<Item> &new_list2, |
| 267 | uint elements, List<Item> &items); |
| 268 | static void init_tmptable_sum_functions(Item_sum **func); |
| 269 | static void update_tmptable_sum_func(Item_sum **func,TABLE *tmp_table); |
| 270 | static void copy_sum_funcs(Item_sum **func_ptr, Item_sum **end); |
| 271 | static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab); |
| 272 | static bool setup_sum_funcs(THD *thd, Item_sum **func_ptr); |
| 273 | static bool prepare_sum_aggregators(Item_sum **func_ptr, bool need_distinct); |
| 274 | static bool init_sum_functions(Item_sum **func, Item_sum **end); |
| 275 | static bool update_sum_func(Item_sum **func); |
| 276 | static void select_describe(JOIN *join, bool need_tmp_table,bool need_order, |
| 277 | bool distinct, const char *message=NullS); |
| 278 | static void add_group_and_distinct_keys(JOIN *join, JOIN_TAB *join_tab); |
| 279 | static uint make_join_orderinfo(JOIN *join); |
| 280 | static bool generate_derived_keys(DYNAMIC_ARRAY *keyuse_array); |
| 281 | |
| 282 | Item_equal *find_item_equal(COND_EQUAL *cond_equal, Field *field, |
| 283 | bool *inherited_fl); |
| 284 | JOIN_TAB *first_depth_first_tab(JOIN* join); |
| 285 | JOIN_TAB *next_depth_first_tab(JOIN* join, JOIN_TAB* tab); |
| 286 | |
| 287 | static JOIN_TAB *next_breadth_first_tab(JOIN_TAB *first_top_tab, |
| 288 | uint n_top_tabs_count, JOIN_TAB *tab); |
| 289 | static bool find_order_in_list(THD *, Ref_ptr_array, TABLE_LIST *, ORDER *, |
| 290 | List<Item> &, List<Item> &, bool, bool, bool); |
| 291 | |
| 292 | static double table_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s, |
| 293 | table_map rem_tables); |
| 294 | void set_postjoin_aggr_write_func(JOIN_TAB *tab); |
| 295 | #ifndef DBUG_OFF |
| 296 | |
| 297 | /* |
| 298 | SHOW EXPLAIN testing: wait for, and serve n_calls APC requests. |
| 299 | */ |
| 300 | void dbug_serve_apcs(THD *thd, int n_calls) |
| 301 | { |
| 302 | const char *save_proc_info= thd->proc_info; |
| 303 | |
| 304 | /* Busy-wait for n_calls APC requests to arrive and be processed */ |
| 305 | int n_apcs= thd->apc_target.n_calls_processed + n_calls; |
| 306 | while (thd->apc_target.n_calls_processed < n_apcs) |
| 307 | { |
| 308 | /* This is so that mysqltest knows we're ready to serve requests: */ |
| 309 | thd_proc_info(thd, "show_explain_trap" ); |
| 310 | my_sleep(30000); |
| 311 | thd_proc_info(thd, save_proc_info); |
| 312 | if (unlikely(thd->check_killed())) |
| 313 | break; |
| 314 | } |
| 315 | } |
| 316 | |
| 317 | |
| 318 | /* |
| 319 | Debugging: check if @name=value, comparing as integer |
| 320 | |
| 321 | Intended usage: |
| 322 | |
| 323 | DBUG_EXECUTE_IF("show_explain_probe_2", |
| 324 | if (dbug_user_var_equals_int(thd, "select_id", select_id)) |
| 325 | dbug_serve_apcs(thd, 1); |
| 326 | ); |
| 327 | |
| 328 | */ |
| 329 | |
| 330 | bool dbug_user_var_equals_int(THD *thd, const char *name, int value) |
| 331 | { |
| 332 | user_var_entry *var; |
| 333 | LEX_CSTRING varname= { name, strlen(name)}; |
| 334 | if ((var= get_variable(&thd->user_vars, &varname, FALSE))) |
| 335 | { |
| 336 | bool null_value; |
| 337 | longlong var_value= var->val_int(&null_value); |
| 338 | if (!null_value && var_value == value) |
| 339 | return TRUE; |
| 340 | } |
| 341 | return FALSE; |
| 342 | } |
| 343 | #endif |
| 344 | |
| 345 | |
| 346 | /** |
| 347 | This handles SELECT with and without UNION. |
| 348 | */ |
| 349 | |
| 350 | bool handle_select(THD *thd, LEX *lex, select_result *result, |
| 351 | ulong setup_tables_done_option) |
| 352 | { |
| 353 | bool res; |
| 354 | SELECT_LEX *select_lex = &lex->select_lex; |
| 355 | DBUG_ENTER("handle_select" ); |
| 356 | MYSQL_SELECT_START(thd->query()); |
| 357 | |
| 358 | if (select_lex->master_unit()->is_unit_op() || |
| 359 | select_lex->master_unit()->fake_select_lex) |
| 360 | res= mysql_union(thd, lex, result, &lex->unit, setup_tables_done_option); |
| 361 | else |
| 362 | { |
| 363 | SELECT_LEX_UNIT *unit= &lex->unit; |
| 364 | unit->set_limit(unit->global_parameters()); |
| 365 | /* |
| 366 | 'options' of mysql_select will be set in JOIN, as far as JOIN for |
| 367 | every PS/SP execution new, we will not need reset this flag if |
| 368 | setup_tables_done_option changed for next rexecution |
| 369 | */ |
| 370 | res= mysql_select(thd, |
| 371 | select_lex->table_list.first, |
| 372 | select_lex->with_wild, select_lex->item_list, |
| 373 | select_lex->where, |
| 374 | select_lex->order_list.elements + |
| 375 | select_lex->group_list.elements, |
| 376 | select_lex->order_list.first, |
| 377 | select_lex->group_list.first, |
| 378 | select_lex->having, |
| 379 | lex->proc_list.first, |
| 380 | select_lex->options | thd->variables.option_bits | |
| 381 | setup_tables_done_option, |
| 382 | result, unit, select_lex); |
| 383 | } |
| 384 | DBUG_PRINT("info" ,("res: %d report_error: %d" , res, |
| 385 | thd->is_error())); |
| 386 | res|= thd->is_error(); |
| 387 | if (unlikely(res)) |
| 388 | result->abort_result_set(); |
| 389 | if (unlikely(thd->killed == ABORT_QUERY && !thd->no_errors)) |
| 390 | { |
| 391 | /* |
| 392 | If LIMIT ROWS EXAMINED interrupted query execution, issue a warning, |
| 393 | continue with normal processing and produce an incomplete query result. |
| 394 | */ |
| 395 | push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, |
| 396 | ER_QUERY_EXCEEDED_ROWS_EXAMINED_LIMIT, |
| 397 | ER_THD(thd, ER_QUERY_EXCEEDED_ROWS_EXAMINED_LIMIT), |
| 398 | thd->accessed_rows_and_keys, |
| 399 | thd->lex->limit_rows_examined->val_uint()); |
| 400 | thd->reset_killed(); |
| 401 | } |
| 402 | /* Disable LIMIT ROWS EXAMINED after query execution. */ |
| 403 | thd->lex->limit_rows_examined_cnt= ULONGLONG_MAX; |
| 404 | |
| 405 | MYSQL_SELECT_DONE((int) res, (ulong) thd->limit_found_rows); |
| 406 | DBUG_RETURN(res); |
| 407 | } |
| 408 | |
| 409 | |
| 410 | /** |
| 411 | Fix fields referenced from inner selects. |
| 412 | |
| 413 | @param thd Thread handle |
| 414 | @param all_fields List of all fields used in select |
| 415 | @param select Current select |
| 416 | @param ref_pointer_array Array of references to Items used in current select |
| 417 | @param group_list GROUP BY list (is NULL by default) |
| 418 | |
| 419 | @details |
| 420 | The function serves 3 purposes |
| 421 | |
| 422 | - adds fields referenced from inner query blocks to the current select list |
| 423 | |
| 424 | - Decides which class to use to reference the items (Item_ref or |
| 425 | Item_direct_ref) |
| 426 | |
| 427 | - fixes references (Item_ref objects) to these fields. |
| 428 | |
| 429 | If a field isn't already on the select list and the ref_pointer_array |
| 430 | is provided then it is added to the all_fields list and the pointer to |
| 431 | it is saved in the ref_pointer_array. |
| 432 | |
| 433 | The class to access the outer field is determined by the following rules: |
| 434 | |
| 435 | -#. If the outer field isn't used under an aggregate function then the |
| 436 | Item_ref class should be used. |
| 437 | |
| 438 | -#. If the outer field is used under an aggregate function and this |
| 439 | function is, in turn, aggregated in the query block where the outer |
| 440 | field was resolved or some query nested therein, then the |
| 441 | Item_direct_ref class should be used. Also it should be used if we are |
| 442 | grouping by a subquery that references this outer field. |
| 443 | |
| 444 | The resolution is done here and not at the fix_fields() stage as |
| 445 | it can be done only after aggregate functions are fixed and pulled up to |
| 446 | selects where they are to be aggregated. |
| 447 | |
| 448 | When the class is chosen it substitutes the original field in the |
| 449 | Item_outer_ref object. |
| 450 | |
| 451 | After this we proceed with fixing references (Item_outer_ref objects) to |
| 452 | this field from inner subqueries. |
| 453 | |
| 454 | @return Status |
| 455 | @retval true An error occurred. |
| 456 | @retval false OK. |
| 457 | */ |
| 458 | |
| 459 | bool |
| 460 | fix_inner_refs(THD *thd, List<Item> &all_fields, SELECT_LEX *select, |
| 461 | Ref_ptr_array ref_pointer_array) |
| 462 | { |
| 463 | Item_outer_ref *ref; |
| 464 | |
| 465 | /* |
| 466 | Mark the references from the inner_refs_list that are occurred in |
| 467 | the group by expressions. Those references will contain direct |
| 468 | references to the referred fields. The markers are set in |
| 469 | the found_in_group_by field of the references from the list. |
| 470 | */ |
| 471 | List_iterator_fast <Item_outer_ref> ref_it(select->inner_refs_list); |
| 472 | for (ORDER *group= select->join->group_list; group; group= group->next) |
| 473 | { |
| 474 | (*group->item)->walk(&Item::check_inner_refs_processor, TRUE, &ref_it); |
| 475 | } |
| 476 | |
| 477 | while ((ref= ref_it++)) |
| 478 | { |
| 479 | bool direct_ref= false; |
| 480 | Item *item= ref->outer_ref; |
| 481 | Item **item_ref= ref->ref; |
| 482 | Item_ref *new_ref; |
| 483 | /* |
| 484 | TODO: this field item already might be present in the select list. |
| 485 | In this case instead of adding new field item we could use an |
| 486 | existing one. The change will lead to less operations for copying fields, |
| 487 | smaller temporary tables and less data passed through filesort. |
| 488 | */ |
| 489 | if (!ref_pointer_array.is_null() && !ref->found_in_select_list) |
| 490 | { |
| 491 | int el= all_fields.elements; |
| 492 | ref_pointer_array[el]= item; |
| 493 | /* Add the field item to the select list of the current select. */ |
| 494 | all_fields.push_front(item, thd->mem_root); |
| 495 | /* |
| 496 | If it's needed reset each Item_ref item that refers this field with |
| 497 | a new reference taken from ref_pointer_array. |
| 498 | */ |
| 499 | item_ref= &ref_pointer_array[el]; |
| 500 | } |
| 501 | |
| 502 | if (ref->in_sum_func) |
| 503 | { |
| 504 | Item_sum *sum_func; |
| 505 | if (ref->in_sum_func->nest_level > select->nest_level) |
| 506 | direct_ref= TRUE; |
| 507 | else |
| 508 | { |
| 509 | for (sum_func= ref->in_sum_func; sum_func && |
| 510 | sum_func->aggr_level >= select->nest_level; |
| 511 | sum_func= sum_func->in_sum_func) |
| 512 | { |
| 513 | if (sum_func->aggr_level == select->nest_level) |
| 514 | { |
| 515 | direct_ref= TRUE; |
| 516 | break; |
| 517 | } |
| 518 | } |
| 519 | } |
| 520 | } |
| 521 | else if (ref->found_in_group_by) |
| 522 | direct_ref= TRUE; |
| 523 | |
| 524 | new_ref= direct_ref ? |
| 525 | new (thd->mem_root) Item_direct_ref(thd, ref->context, item_ref, ref->table_name, |
| 526 | &ref->field_name, ref->alias_name_used) : |
| 527 | new (thd->mem_root) Item_ref(thd, ref->context, item_ref, ref->table_name, |
| 528 | &ref->field_name, ref->alias_name_used); |
| 529 | if (!new_ref) |
| 530 | return TRUE; |
| 531 | ref->outer_ref= new_ref; |
| 532 | ref->ref= &ref->outer_ref; |
| 533 | |
| 534 | if (!ref->fixed && ref->fix_fields(thd, 0)) |
| 535 | return TRUE; |
| 536 | thd->lex->used_tables|= item->used_tables(); |
| 537 | thd->lex->current_select->select_list_tables|= item->used_tables(); |
| 538 | } |
| 539 | return false; |
| 540 | } |
| 541 | |
| 542 | /** |
| 543 | The following clauses are redundant for subqueries: |
| 544 | |
| 545 | DISTINCT |
| 546 | GROUP BY if there are no aggregate functions and no HAVING |
| 547 | clause |
| 548 | |
| 549 | Because redundant clauses are removed both from JOIN and |
| 550 | select_lex, the removal is permanent. Thus, it only makes sense to |
| 551 | call this function for normal queries and on first execution of |
| 552 | SP/PS |
| 553 | |
| 554 | @param subq_select_lex select_lex that is part of a subquery |
| 555 | predicate. This object and the associated |
| 556 | join is modified. |
| 557 | */ |
| 558 | |
| 559 | static |
| 560 | void remove_redundant_subquery_clauses(st_select_lex *subq_select_lex) |
| 561 | { |
| 562 | DBUG_ENTER("remove_redundant_subquery_clauses" ); |
| 563 | Item_subselect *subq_predicate= subq_select_lex->master_unit()->item; |
| 564 | /* |
| 565 | The removal should happen for IN, ALL, ANY and EXISTS subqueries, |
| 566 | which means all but single row subqueries. Example single row |
| 567 | subqueries: |
| 568 | a) SELECT * FROM t1 WHERE t1.a = (<single row subquery>) |
| 569 | b) SELECT a, (<single row subquery) FROM t1 |
| 570 | */ |
| 571 | if (subq_predicate->substype() == Item_subselect::SINGLEROW_SUBS) |
| 572 | DBUG_VOID_RETURN; |
| 573 | |
| 574 | /* A subquery that is not single row should be one of IN/ALL/ANY/EXISTS. */ |
| 575 | DBUG_ASSERT (subq_predicate->substype() == Item_subselect::EXISTS_SUBS || |
| 576 | subq_predicate->is_in_predicate()); |
| 577 | |
| 578 | if (subq_select_lex->options & SELECT_DISTINCT) |
| 579 | { |
| 580 | subq_select_lex->join->select_distinct= false; |
| 581 | subq_select_lex->options&= ~SELECT_DISTINCT; |
| 582 | DBUG_PRINT("info" , ("DISTINCT removed" )); |
| 583 | } |
| 584 | |
| 585 | /* |
| 586 | Remove GROUP BY if there are no aggregate functions and no HAVING |
| 587 | clause |
| 588 | */ |
| 589 | if (subq_select_lex->group_list.elements && |
| 590 | !subq_select_lex->with_sum_func && !subq_select_lex->join->having) |
| 591 | { |
| 592 | for (ORDER *ord= subq_select_lex->group_list.first; ord; ord= ord->next) |
| 593 | { |
| 594 | (*ord->item)->walk(&Item::eliminate_subselect_processor, FALSE, NULL); |
| 595 | } |
| 596 | subq_select_lex->join->group_list= NULL; |
| 597 | subq_select_lex->group_list.empty(); |
| 598 | DBUG_PRINT("info" , ("GROUP BY removed" )); |
| 599 | } |
| 600 | |
| 601 | /* |
| 602 | TODO: This would prevent processing quries with ORDER BY ... LIMIT |
| 603 | therefore we disable this optimization for now. |
| 604 | Remove GROUP BY if there are no aggregate functions and no HAVING |
| 605 | clause |
| 606 | if (subq_select_lex->group_list.elements && |
| 607 | !subq_select_lex->with_sum_func && !subq_select_lex->join->having) |
| 608 | { |
| 609 | subq_select_lex->join->group_list= NULL; |
| 610 | subq_select_lex->group_list.empty(); |
| 611 | } |
| 612 | */ |
| 613 | DBUG_VOID_RETURN; |
| 614 | } |
| 615 | |
| 616 | |
| 617 | /** |
| 618 | Function to setup clauses without sum functions. |
| 619 | */ |
| 620 | static inline int |
| 621 | setup_without_group(THD *thd, Ref_ptr_array ref_pointer_array, |
| 622 | TABLE_LIST *tables, |
| 623 | List<TABLE_LIST> &leaves, |
| 624 | List<Item> &fields, |
| 625 | List<Item> &all_fields, |
| 626 | COND **conds, |
| 627 | ORDER *order, |
| 628 | ORDER *group, |
| 629 | List<Window_spec> &win_specs, |
| 630 | List<Item_window_func> &win_funcs, |
| 631 | bool *hidden_group_fields, |
| 632 | uint *reserved) |
| 633 | { |
| 634 | int res; |
| 635 | enum_parsing_place save_place; |
| 636 | st_select_lex *const select= thd->lex->current_select; |
| 637 | nesting_map save_allow_sum_func= thd->lex->allow_sum_func; |
| 638 | /* |
| 639 | Need to stave the value, so we can turn off only any new non_agg_field_used |
| 640 | additions coming from the WHERE |
| 641 | */ |
| 642 | const bool saved_non_agg_field_used= select->non_agg_field_used(); |
| 643 | DBUG_ENTER("setup_without_group" ); |
| 644 | |
| 645 | thd->lex->allow_sum_func&= ~((nesting_map)1 << select->nest_level); |
| 646 | res= setup_conds(thd, tables, leaves, conds); |
| 647 | if (thd->lex->current_select->first_cond_optimization) |
| 648 | { |
| 649 | if (!res && *conds && ! thd->lex->current_select->merged_into) |
| 650 | (*reserved)= (*conds)->exists2in_reserved_items(); |
| 651 | else |
| 652 | (*reserved)= 0; |
| 653 | } |
| 654 | |
| 655 | /* it's not wrong to have non-aggregated columns in a WHERE */ |
| 656 | select->set_non_agg_field_used(saved_non_agg_field_used); |
| 657 | |
| 658 | thd->lex->allow_sum_func|= (nesting_map)1 << select->nest_level; |
| 659 | |
| 660 | save_place= thd->lex->current_select->context_analysis_place; |
| 661 | thd->lex->current_select->context_analysis_place= IN_ORDER_BY; |
| 662 | res= res || setup_order(thd, ref_pointer_array, tables, fields, all_fields, |
| 663 | order); |
| 664 | thd->lex->allow_sum_func&= ~((nesting_map)1 << select->nest_level); |
| 665 | thd->lex->current_select->context_analysis_place= IN_GROUP_BY; |
| 666 | res= res || setup_group(thd, ref_pointer_array, tables, fields, all_fields, |
| 667 | group, hidden_group_fields); |
| 668 | thd->lex->current_select->context_analysis_place= save_place; |
| 669 | thd->lex->allow_sum_func|= (nesting_map)1 << select->nest_level; |
| 670 | res= res || setup_windows(thd, ref_pointer_array, tables, fields, all_fields, |
| 671 | win_specs, win_funcs); |
| 672 | thd->lex->allow_sum_func= save_allow_sum_func; |
| 673 | DBUG_RETURN(res); |
| 674 | } |
| 675 | |
| 676 | bool vers_select_conds_t::init_from_sysvar(THD *thd) |
| 677 | { |
| 678 | vers_asof_timestamp_t &in= thd->variables.vers_asof_timestamp; |
| 679 | type= (vers_system_time_t) in.type; |
| 680 | start.unit= VERS_TIMESTAMP; |
| 681 | from_query= false; |
| 682 | if (type != SYSTEM_TIME_UNSPECIFIED && type != SYSTEM_TIME_ALL) |
| 683 | { |
| 684 | DBUG_ASSERT(type == SYSTEM_TIME_AS_OF); |
| 685 | start.item= new (thd->mem_root) |
| 686 | Item_datetime_literal(thd, &in.ltime, TIME_SECOND_PART_DIGITS); |
| 687 | if (!start.item) |
| 688 | return true; |
| 689 | } |
| 690 | else |
| 691 | start.item= NULL; |
| 692 | end.empty(); |
| 693 | return false; |
| 694 | } |
| 695 | |
| 696 | void vers_select_conds_t::print(String *str, enum_query_type query_type) const |
| 697 | { |
| 698 | switch (type) { |
| 699 | case SYSTEM_TIME_UNSPECIFIED: |
| 700 | break; |
| 701 | case SYSTEM_TIME_AS_OF: |
| 702 | start.print(str, query_type, STRING_WITH_LEN(" FOR SYSTEM_TIME AS OF " )); |
| 703 | break; |
| 704 | case SYSTEM_TIME_FROM_TO: |
| 705 | start.print(str, query_type, STRING_WITH_LEN(" FOR SYSTEM_TIME FROM " )); |
| 706 | end.print(str, query_type, STRING_WITH_LEN(" TO " )); |
| 707 | break; |
| 708 | case SYSTEM_TIME_BETWEEN: |
| 709 | start.print(str, query_type, STRING_WITH_LEN(" FOR SYSTEM_TIME BETWEEN " )); |
| 710 | end.print(str, query_type, STRING_WITH_LEN(" AND " )); |
| 711 | break; |
| 712 | case SYSTEM_TIME_BEFORE: |
| 713 | DBUG_ASSERT(0); |
| 714 | break; |
| 715 | case SYSTEM_TIME_ALL: |
| 716 | str->append(" FOR SYSTEM_TIME ALL" ); |
| 717 | break; |
| 718 | } |
| 719 | } |
| 720 | |
| 721 | int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables) |
| 722 | { |
| 723 | DBUG_ENTER("SELECT_LEX::vers_setup_cond" ); |
| 724 | #define newx new (thd->mem_root) |
| 725 | |
| 726 | TABLE_LIST *table; |
| 727 | |
| 728 | if (!thd->stmt_arena->is_conventional() && |
| 729 | !thd->stmt_arena->is_stmt_prepare() && !thd->stmt_arena->is_sp_execute()) |
| 730 | { |
| 731 | // statement is already prepared |
| 732 | DBUG_RETURN(0); |
| 733 | } |
| 734 | |
| 735 | if (thd->lex->is_view_context_analysis()) |
| 736 | DBUG_RETURN(0); |
| 737 | |
| 738 | if (!versioned_tables) |
| 739 | { |
| 740 | for (table= tables; table; table= table->next_local) |
| 741 | { |
| 742 | if (table->table && table->table->versioned()) |
| 743 | versioned_tables++; |
| 744 | else if (table->vers_conditions.user_defined() && |
| 745 | (table->is_non_derived() || !table->vers_conditions.used)) |
| 746 | { |
| 747 | my_error(ER_VERS_NOT_VERSIONED, MYF(0), table->alias.str); |
| 748 | DBUG_RETURN(-1); |
| 749 | } |
| 750 | } |
| 751 | } |
| 752 | |
| 753 | if (versioned_tables == 0) |
| 754 | DBUG_RETURN(0); |
| 755 | |
| 756 | /* For prepared statements we create items on statement arena, |
| 757 | because they must outlive execution phase for multiple executions. */ |
| 758 | Query_arena_stmt on_stmt_arena(thd); |
| 759 | |
| 760 | // find outer system_time |
| 761 | SELECT_LEX *outer_slex= outer_select(); |
| 762 | TABLE_LIST* outer_table= NULL; |
| 763 | |
| 764 | if (outer_slex) |
| 765 | { |
| 766 | TABLE_LIST* derived= master_unit()->derived; |
| 767 | // inner SELECT may not be a derived table (derived == NULL) |
| 768 | while (derived && outer_slex && !derived->vers_conditions.is_set()) |
| 769 | { |
| 770 | derived= outer_slex->master_unit()->derived; |
| 771 | outer_slex= outer_slex->outer_select(); |
| 772 | } |
| 773 | if (derived && outer_slex) |
| 774 | { |
| 775 | DBUG_ASSERT(derived->vers_conditions.is_set()); |
| 776 | outer_table= derived; |
| 777 | } |
| 778 | } |
| 779 | |
| 780 | for (table= tables; table; table= table->next_local) |
| 781 | { |
| 782 | if (!table->table || !table->table->versioned()) |
| 783 | continue; |
| 784 | |
| 785 | vers_select_conds_t &vers_conditions= table->vers_conditions; |
| 786 | |
| 787 | #ifdef WITH_PARTITION_STORAGE_ENGINE |
| 788 | /* |
| 789 | if the history is stored in partitions, then partitions |
| 790 | themselves are not versioned |
| 791 | */ |
| 792 | if (table->partition_names && table->table->part_info->vers_info) |
| 793 | { |
| 794 | if (vers_conditions.is_set()) |
| 795 | { |
| 796 | my_error(ER_VERS_QUERY_IN_PARTITION, MYF(0), table->alias.str); |
| 797 | DBUG_RETURN(-1); |
| 798 | } |
| 799 | else |
| 800 | vers_conditions.init(SYSTEM_TIME_ALL); |
| 801 | } |
| 802 | #endif |
| 803 | |
| 804 | if (outer_table && !vers_conditions.is_set()) |
| 805 | { |
| 806 | // propagate system_time from nearest outer SELECT_LEX |
| 807 | vers_conditions= outer_table->vers_conditions; |
| 808 | outer_table->vers_conditions.used= true; |
| 809 | } |
| 810 | |
| 811 | // propagate system_time from sysvar |
| 812 | if (!vers_conditions.is_set()) |
| 813 | { |
| 814 | if (vers_conditions.init_from_sysvar(thd)) |
| 815 | DBUG_RETURN(-1); |
| 816 | } |
| 817 | |
| 818 | if (vers_conditions.is_set()) |
| 819 | { |
| 820 | if (vers_conditions.type == SYSTEM_TIME_ALL) |
| 821 | continue; |
| 822 | |
| 823 | lock_type= TL_READ; // ignore TL_WRITE, history is immutable anyway |
| 824 | } |
| 825 | |
| 826 | const LEX_CSTRING *fstart= &table->table->vers_start_field()->field_name; |
| 827 | const LEX_CSTRING *fend= &table->table->vers_end_field()->field_name; |
| 828 | |
| 829 | Item *row_start= |
| 830 | newx Item_field(thd, &this->context, table->db.str, table->alias.str, fstart); |
| 831 | Item *row_end= |
| 832 | newx Item_field(thd, &this->context, table->db.str, table->alias.str, fend); |
| 833 | |
| 834 | bool timestamps_only= table->table->versioned(VERS_TIMESTAMP); |
| 835 | |
| 836 | if (vers_conditions.is_set()) |
| 837 | { |
| 838 | thd->where= "FOR SYSTEM_TIME" ; |
| 839 | /* TODO: do resolve fix_length_and_dec(), fix_fields(). This requires |
| 840 | storing vers_conditions as Item and make some magic related to |
| 841 | vers_system_time_t/VERS_TRX_ID at stage of fix_fields() |
| 842 | (this is large refactoring). */ |
| 843 | if (vers_conditions.resolve_units(thd)) |
| 844 | DBUG_RETURN(-1); |
| 845 | if (timestamps_only && (vers_conditions.start.unit == VERS_TRX_ID || |
| 846 | vers_conditions.end.unit == VERS_TRX_ID)) |
| 847 | { |
| 848 | my_error(ER_VERS_ENGINE_UNSUPPORTED, MYF(0), table->table_name.str); |
| 849 | DBUG_RETURN(-1); |
| 850 | } |
| 851 | } |
| 852 | |
| 853 | Item *cond1= NULL, *cond2= NULL, *cond3= NULL, *curr= NULL; |
| 854 | Item *point_in_time1= vers_conditions.start.item; |
| 855 | Item *point_in_time2= vers_conditions.end.item; |
| 856 | TABLE *t= table->table; |
| 857 | if (t->versioned(VERS_TIMESTAMP)) |
| 858 | { |
| 859 | MYSQL_TIME max_time; |
| 860 | switch (vers_conditions.type) |
| 861 | { |
| 862 | case SYSTEM_TIME_UNSPECIFIED: |
| 863 | thd->variables.time_zone->gmt_sec_to_TIME(&max_time, TIMESTAMP_MAX_VALUE); |
| 864 | max_time.second_part= TIME_MAX_SECOND_PART; |
| 865 | curr= newx Item_datetime_literal(thd, &max_time, TIME_SECOND_PART_DIGITS); |
| 866 | cond1= newx Item_func_eq(thd, row_end, curr); |
| 867 | break; |
| 868 | case SYSTEM_TIME_AS_OF: |
| 869 | cond1= newx Item_func_le(thd, row_start, point_in_time1); |
| 870 | cond2= newx Item_func_gt(thd, row_end, point_in_time1); |
| 871 | break; |
| 872 | case SYSTEM_TIME_FROM_TO: |
| 873 | cond1= newx Item_func_lt(thd, row_start, point_in_time2); |
| 874 | cond2= newx Item_func_gt(thd, row_end, point_in_time1); |
| 875 | cond3= newx Item_func_lt(thd, point_in_time1, point_in_time2); |
| 876 | break; |
| 877 | case SYSTEM_TIME_BETWEEN: |
| 878 | cond1= newx Item_func_le(thd, row_start, point_in_time2); |
| 879 | cond2= newx Item_func_gt(thd, row_end, point_in_time1); |
| 880 | cond3= newx Item_func_le(thd, point_in_time1, point_in_time2); |
| 881 | break; |
| 882 | case SYSTEM_TIME_BEFORE: |
| 883 | cond1= newx Item_func_lt(thd, row_end, point_in_time1); |
| 884 | break; |
| 885 | default: |
| 886 | DBUG_ASSERT(0); |
| 887 | } |
| 888 | } |
| 889 | else |
| 890 | { |
| 891 | DBUG_ASSERT(table->table->s && table->table->s->db_plugin); |
| 892 | |
| 893 | Item *trx_id0, *trx_id1; |
| 894 | |
| 895 | switch (vers_conditions.type) |
| 896 | { |
| 897 | case SYSTEM_TIME_UNSPECIFIED: |
| 898 | curr= newx Item_int(thd, ULONGLONG_MAX); |
| 899 | cond1= newx Item_func_eq(thd, row_end, curr); |
| 900 | break; |
| 901 | case SYSTEM_TIME_AS_OF: |
| 902 | trx_id0= vers_conditions.start.unit == VERS_TIMESTAMP |
| 903 | ? newx Item_func_trt_id(thd, point_in_time1, TR_table::FLD_TRX_ID) |
| 904 | : point_in_time1; |
| 905 | cond1= newx Item_func_trt_trx_sees_eq(thd, trx_id0, row_start); |
| 906 | cond2= newx Item_func_trt_trx_sees(thd, row_end, trx_id0); |
| 907 | break; |
| 908 | case SYSTEM_TIME_FROM_TO: |
| 909 | cond3= newx Item_func_lt(thd, point_in_time1, point_in_time2); |
| 910 | /* fall through */ |
| 911 | case SYSTEM_TIME_BETWEEN: |
| 912 | trx_id0= vers_conditions.start.unit == VERS_TIMESTAMP |
| 913 | ? newx Item_func_trt_id(thd, point_in_time1, TR_table::FLD_TRX_ID, true) |
| 914 | : point_in_time1; |
| 915 | trx_id1= vers_conditions.end.unit == VERS_TIMESTAMP |
| 916 | ? newx Item_func_trt_id(thd, point_in_time2, TR_table::FLD_TRX_ID, false) |
| 917 | : point_in_time2; |
| 918 | cond1= vers_conditions.type == SYSTEM_TIME_FROM_TO |
| 919 | ? newx Item_func_trt_trx_sees(thd, trx_id1, row_start) |
| 920 | : newx Item_func_trt_trx_sees_eq(thd, trx_id1, row_start); |
| 921 | cond2= newx Item_func_trt_trx_sees_eq(thd, row_end, trx_id0); |
| 922 | if (!cond3) |
| 923 | cond3= newx Item_func_le(thd, point_in_time1, point_in_time2); |
| 924 | break; |
| 925 | case SYSTEM_TIME_BEFORE: |
| 926 | trx_id0= vers_conditions.start.unit == VERS_TIMESTAMP |
| 927 | ? newx Item_func_trt_id(thd, point_in_time1, TR_table::FLD_TRX_ID, true) |
| 928 | : point_in_time1; |
| 929 | cond1= newx Item_func_trt_trx_sees(thd, trx_id0, row_end); |
| 930 | break; |
| 931 | default: |
| 932 | DBUG_ASSERT(0); |
| 933 | } |
| 934 | } |
| 935 | |
| 936 | if (cond1) |
| 937 | { |
| 938 | cond1= and_items(thd, cond2, cond1); |
| 939 | cond1= and_items(thd, cond3, cond1); |
| 940 | table->on_expr= and_items(thd, table->on_expr, cond1); |
| 941 | } |
| 942 | |
| 943 | table->vers_conditions.type= SYSTEM_TIME_ALL; |
| 944 | } // for (table= tables; ...) |
| 945 | |
| 946 | DBUG_RETURN(0); |
| 947 | #undef newx |
| 948 | } |
| 949 | |
| 950 | /***************************************************************************** |
| 951 | Check fields, find best join, do the select and output fields. |
| 952 | mysql_select assumes that all tables are already opened |
| 953 | *****************************************************************************/ |
| 954 | |
| 955 | |
| 956 | /** |
| 957 | Prepare of whole select (including sub queries in future). |
| 958 | |
| 959 | @todo |
| 960 | Add check of calculation of GROUP functions and fields: |
| 961 | SELECT COUNT(*)+table.col1 from table1; |
| 962 | |
| 963 | @retval |
| 964 | -1 on error |
| 965 | @retval |
| 966 | 0 on success |
| 967 | */ |
| 968 | int |
| 969 | JOIN::prepare(TABLE_LIST *tables_init, |
| 970 | uint wild_num, COND *conds_init, uint og_num, |
| 971 | ORDER *order_init, bool skip_order_by, |
| 972 | ORDER *group_init, Item *having_init, |
| 973 | ORDER *proc_param_init, SELECT_LEX *select_lex_arg, |
| 974 | SELECT_LEX_UNIT *unit_arg) |
| 975 | { |
| 976 | DBUG_ENTER("JOIN::prepare" ); |
| 977 | |
| 978 | // to prevent double initialization on EXPLAIN |
| 979 | if (optimization_state != JOIN::NOT_OPTIMIZED) |
| 980 | DBUG_RETURN(0); |
| 981 | |
| 982 | conds= conds_init; |
| 983 | order= order_init; |
| 984 | group_list= group_init; |
| 985 | having= having_init; |
| 986 | proc_param= proc_param_init; |
| 987 | tables_list= tables_init; |
| 988 | select_lex= select_lex_arg; |
| 989 | select_lex->join= this; |
| 990 | join_list= &select_lex->top_join_list; |
| 991 | union_part= unit_arg->is_unit_op(); |
| 992 | |
| 993 | // simple check that we got usable conds |
| 994 | dbug_print_item(conds); |
| 995 | |
| 996 | if (select_lex->handle_derived(thd->lex, DT_PREPARE)) |
| 997 | DBUG_RETURN(-1); |
| 998 | |
| 999 | thd->lex->current_select->context_analysis_place= NO_MATTER; |
| 1000 | thd->lex->current_select->is_item_list_lookup= 1; |
| 1001 | /* |
| 1002 | If we have already executed SELECT, then it have not sense to prevent |
| 1003 | its table from update (see unique_table()) |
| 1004 | Affects only materialized derived tables. |
| 1005 | */ |
| 1006 | /* Check that all tables, fields, conds and order are ok */ |
| 1007 | if (!(select_options & OPTION_SETUP_TABLES_DONE) && |
| 1008 | setup_tables_and_check_access(thd, &select_lex->context, join_list, |
| 1009 | tables_list, select_lex->leaf_tables, |
| 1010 | FALSE, SELECT_ACL, SELECT_ACL, FALSE)) |
| 1011 | DBUG_RETURN(-1); |
| 1012 | |
| 1013 | /* |
| 1014 | Permanently remove redundant parts from the query if |
| 1015 | 1) This is a subquery |
| 1016 | 2) This is the first time this query is optimized (since the |
| 1017 | transformation is permanent |
| 1018 | 3) Not normalizing a view. Removal should take place when a |
| 1019 | query involving a view is optimized, not when the view |
| 1020 | is created |
| 1021 | */ |
| 1022 | if (select_lex->master_unit()->item && // 1) |
| 1023 | select_lex->first_cond_optimization && // 2) |
| 1024 | !thd->lex->is_view_context_analysis()) // 3) |
| 1025 | { |
| 1026 | remove_redundant_subquery_clauses(select_lex); |
| 1027 | } |
| 1028 | |
| 1029 | /* System Versioning: handle FOR SYSTEM_TIME clause. */ |
| 1030 | if (select_lex->vers_setup_conds(thd, tables_list) < 0) |
| 1031 | DBUG_RETURN(-1); |
| 1032 | |
| 1033 | /* |
| 1034 | TRUE if the SELECT list mixes elements with and without grouping, |
| 1035 | and there is no GROUP BY clause. Mixing non-aggregated fields with |
| 1036 | aggregate functions in the SELECT list is a MySQL extenstion that |
| 1037 | is allowed only if the ONLY_FULL_GROUP_BY sql mode is not set. |
| 1038 | */ |
| 1039 | mixed_implicit_grouping= false; |
| 1040 | if ((~thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY) && |
| 1041 | select_lex->with_sum_func && !group_list) |
| 1042 | { |
| 1043 | List_iterator_fast <Item> select_it(fields_list); |
| 1044 | Item *select_el; /* Element of the SELECT clause, can be an expression. */ |
| 1045 | bool found_field_elem= false; |
| 1046 | bool found_sum_func_elem= false; |
| 1047 | |
| 1048 | while ((select_el= select_it++)) |
| 1049 | { |
| 1050 | if (select_el->with_sum_func) |
| 1051 | found_sum_func_elem= true; |
| 1052 | if (select_el->with_field) |
| 1053 | found_field_elem= true; |
| 1054 | if (found_sum_func_elem && found_field_elem) |
| 1055 | { |
| 1056 | mixed_implicit_grouping= true; |
| 1057 | break; |
| 1058 | } |
| 1059 | } |
| 1060 | } |
| 1061 | |
| 1062 | table_count= select_lex->leaf_tables.elements; |
| 1063 | |
| 1064 | TABLE_LIST *tbl; |
| 1065 | List_iterator_fast<TABLE_LIST> li(select_lex->leaf_tables); |
| 1066 | while ((tbl= li++)) |
| 1067 | { |
| 1068 | /* |
| 1069 | If the query uses implicit grouping where the select list contains both |
| 1070 | aggregate functions and non-aggregate fields, any non-aggregated field |
| 1071 | may produce a NULL value. Set all fields of each table as nullable before |
| 1072 | semantic analysis to take into account this change of nullability. |
| 1073 | |
| 1074 | Note: this loop doesn't touch tables inside merged semi-joins, because |
| 1075 | subquery-to-semijoin conversion has not been done yet. This is intended. |
| 1076 | */ |
| 1077 | if (mixed_implicit_grouping && tbl->table) |
| 1078 | tbl->table->maybe_null= 1; |
| 1079 | } |
| 1080 | |
| 1081 | uint real_og_num= og_num; |
| 1082 | if (skip_order_by && |
| 1083 | select_lex != select_lex->master_unit()->global_parameters()) |
| 1084 | real_og_num+= select_lex->order_list.elements; |
| 1085 | |
| 1086 | DBUG_ASSERT(select_lex->hidden_bit_fields == 0); |
| 1087 | if (setup_wild(thd, tables_list, fields_list, &all_fields, wild_num, |
| 1088 | &select_lex->hidden_bit_fields)) |
| 1089 | DBUG_RETURN(-1); |
| 1090 | if (select_lex->setup_ref_array(thd, real_og_num)) |
| 1091 | DBUG_RETURN(-1); |
| 1092 | |
| 1093 | ref_ptrs= ref_ptr_array_slice(0); |
| 1094 | |
| 1095 | enum_parsing_place save_place= |
| 1096 | thd->lex->current_select->context_analysis_place; |
| 1097 | thd->lex->current_select->context_analysis_place= SELECT_LIST; |
| 1098 | if (setup_fields(thd, ref_ptrs, fields_list, MARK_COLUMNS_READ, |
| 1099 | &all_fields, &select_lex->pre_fix, 1)) |
| 1100 | DBUG_RETURN(-1); |
| 1101 | thd->lex->current_select->context_analysis_place= save_place; |
| 1102 | |
| 1103 | if (setup_without_group(thd, ref_ptrs, tables_list, |
| 1104 | select_lex->leaf_tables, fields_list, |
| 1105 | all_fields, &conds, order, group_list, |
| 1106 | select_lex->window_specs, |
| 1107 | select_lex->window_funcs, |
| 1108 | &hidden_group_fields, |
| 1109 | &select_lex->select_n_reserved)) |
| 1110 | DBUG_RETURN(-1); |
| 1111 | /* Resolve the ORDER BY that was skipped, then remove it. */ |
| 1112 | if (skip_order_by && select_lex != |
| 1113 | select_lex->master_unit()->global_parameters()) |
| 1114 | { |
| 1115 | nesting_map save_allow_sum_func= thd->lex->allow_sum_func; |
| 1116 | thd->lex->allow_sum_func|= (nesting_map)1 << select_lex->nest_level; |
| 1117 | thd->where= "order clause" ; |
| 1118 | for (ORDER *order= select_lex->order_list.first; order; order= order->next) |
| 1119 | { |
| 1120 | /* Don't add the order items to all fields. Just resolve them to ensure |
| 1121 | the query is valid, we'll drop them immediately after. */ |
| 1122 | if (find_order_in_list(thd, ref_ptrs, tables_list, order, |
| 1123 | fields_list, all_fields, false, false, false)) |
| 1124 | DBUG_RETURN(-1); |
| 1125 | } |
| 1126 | thd->lex->allow_sum_func= save_allow_sum_func; |
| 1127 | select_lex->order_list.empty(); |
| 1128 | } |
| 1129 | |
| 1130 | if (having) |
| 1131 | { |
| 1132 | nesting_map save_allow_sum_func= thd->lex->allow_sum_func; |
| 1133 | thd->where="having clause" ; |
| 1134 | thd->lex->allow_sum_func|= (nesting_map)1 << select_lex_arg->nest_level; |
| 1135 | select_lex->having_fix_field= 1; |
| 1136 | /* |
| 1137 | Wrap alone field in HAVING clause in case it will be outer field |
| 1138 | of subquery which need persistent pointer on it, but having |
| 1139 | could be changed by optimizer |
| 1140 | */ |
| 1141 | if (having->type() == Item::REF_ITEM && |
| 1142 | ((Item_ref *)having)->ref_type() == Item_ref::REF) |
| 1143 | wrap_ident(thd, &having); |
| 1144 | bool having_fix_rc= (!having->fixed && |
| 1145 | (having->fix_fields(thd, &having) || |
| 1146 | having->check_cols(1))); |
| 1147 | select_lex->having_fix_field= 0; |
| 1148 | |
| 1149 | if (unlikely(having_fix_rc || thd->is_error())) |
| 1150 | DBUG_RETURN(-1); /* purecov: inspected */ |
| 1151 | thd->lex->allow_sum_func= save_allow_sum_func; |
| 1152 | |
| 1153 | if (having->with_window_func) |
| 1154 | { |
| 1155 | my_error(ER_WRONG_PLACEMENT_OF_WINDOW_FUNCTION, MYF(0)); |
| 1156 | DBUG_RETURN(-1); |
| 1157 | } |
| 1158 | } |
| 1159 | |
| 1160 | /* |
| 1161 | After setting up window functions, we may have discovered additional |
| 1162 | used tables from the PARTITION BY and ORDER BY list. Update all items |
| 1163 | that contain window functions. |
| 1164 | */ |
| 1165 | if (select_lex->have_window_funcs()) |
| 1166 | { |
| 1167 | List_iterator_fast<Item> it(select_lex->item_list); |
| 1168 | Item *item; |
| 1169 | while ((item= it++)) |
| 1170 | { |
| 1171 | if (item->with_window_func) |
| 1172 | item->update_used_tables(); |
| 1173 | } |
| 1174 | } |
| 1175 | |
| 1176 | With_clause *with_clause=select_lex->get_with_clause(); |
| 1177 | if (with_clause && with_clause->prepare_unreferenced_elements(thd)) |
| 1178 | DBUG_RETURN(1); |
| 1179 | |
| 1180 | With_element *with_elem= select_lex->get_with_element(); |
| 1181 | if (with_elem && |
| 1182 | select_lex->check_unrestricted_recursive( |
| 1183 | thd->variables.only_standard_compliant_cte)) |
| 1184 | DBUG_RETURN(-1); |
| 1185 | if (select_lex->first_execution) |
| 1186 | select_lex->check_subqueries_with_recursive_references(); |
| 1187 | |
| 1188 | int res= check_and_do_in_subquery_rewrites(this); |
| 1189 | |
| 1190 | select_lex->fix_prepare_information(thd, &conds, &having); |
| 1191 | |
| 1192 | if (res) |
| 1193 | DBUG_RETURN(res); |
| 1194 | |
| 1195 | if (order) |
| 1196 | { |
| 1197 | bool real_order= FALSE; |
| 1198 | ORDER *ord; |
| 1199 | for (ord= order; ord; ord= ord->next) |
| 1200 | { |
| 1201 | Item *item= *ord->item; |
| 1202 | /* |
| 1203 | Disregard sort order if there's only |
| 1204 | zero length NOT NULL fields (e.g. {VAR}CHAR(0) NOT NULL") or |
| 1205 | zero length NOT NULL string functions there. |
| 1206 | Such tuples don't contain any data to sort. |
| 1207 | */ |
| 1208 | if (!real_order && |
| 1209 | /* Not a zero length NOT NULL field */ |
| 1210 | ((item->type() != Item::FIELD_ITEM || |
| 1211 | ((Item_field *) item)->field->maybe_null() || |
| 1212 | ((Item_field *) item)->field->sort_length()) && |
| 1213 | /* AND not a zero length NOT NULL string function. */ |
| 1214 | (item->type() != Item::FUNC_ITEM || |
| 1215 | item->maybe_null || |
| 1216 | item->result_type() != STRING_RESULT || |
| 1217 | item->max_length))) |
| 1218 | real_order= TRUE; |
| 1219 | |
| 1220 | if (item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM) |
| 1221 | item->split_sum_func(thd, ref_ptrs, all_fields, 0); |
| 1222 | } |
| 1223 | if (!real_order) |
| 1224 | order= NULL; |
| 1225 | } |
| 1226 | |
| 1227 | if (having && having->with_sum_func) |
| 1228 | having->split_sum_func2(thd, ref_ptrs, all_fields, |
| 1229 | &having, SPLIT_SUM_SKIP_REGISTERED); |
| 1230 | if (select_lex->inner_sum_func_list) |
| 1231 | { |
| 1232 | Item_sum *end=select_lex->inner_sum_func_list; |
| 1233 | Item_sum *item_sum= end; |
| 1234 | do |
| 1235 | { |
| 1236 | item_sum= item_sum->next; |
| 1237 | item_sum->split_sum_func2(thd, ref_ptrs, |
| 1238 | all_fields, item_sum->ref_by, 0); |
| 1239 | } while (item_sum != end); |
| 1240 | } |
| 1241 | |
| 1242 | if (select_lex->inner_refs_list.elements && |
| 1243 | fix_inner_refs(thd, all_fields, select_lex, ref_ptrs)) |
| 1244 | DBUG_RETURN(-1); |
| 1245 | |
| 1246 | if (group_list) |
| 1247 | { |
| 1248 | /* |
| 1249 | Because HEAP tables can't index BIT fields we need to use an |
| 1250 | additional hidden field for grouping because later it will be |
| 1251 | converted to a LONG field. Original field will remain of the |
| 1252 | BIT type and will be returned to a client. |
| 1253 | */ |
| 1254 | for (ORDER *ord= group_list; ord; ord= ord->next) |
| 1255 | { |
| 1256 | if ((*ord->item)->type() == Item::FIELD_ITEM && |
| 1257 | (*ord->item)->field_type() == MYSQL_TYPE_BIT) |
| 1258 | { |
| 1259 | Item_field *field= new (thd->mem_root) Item_field(thd, *(Item_field**)ord->item); |
| 1260 | if (!field) |
| 1261 | DBUG_RETURN(-1); |
| 1262 | int el= all_fields.elements; |
| 1263 | ref_ptrs[el]= field; |
| 1264 | all_fields.push_front(field, thd->mem_root); |
| 1265 | ord->item= &ref_ptrs[el]; |
| 1266 | } |
| 1267 | } |
| 1268 | } |
| 1269 | |
| 1270 | /* |
| 1271 | Check if there are references to un-aggregated columns when computing |
| 1272 | aggregate functions with implicit grouping (there is no GROUP BY). |
| 1273 | */ |
| 1274 | if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY && !group_list && |
| 1275 | !(select_lex->master_unit()->item && |
| 1276 | select_lex->master_unit()->item->is_in_predicate() && |
| 1277 | ((Item_in_subselect*)select_lex->master_unit()->item)-> |
| 1278 | test_set_strategy(SUBS_MAXMIN_INJECTED)) && |
| 1279 | select_lex->non_agg_field_used() && |
| 1280 | select_lex->agg_func_used()) |
| 1281 | { |
| 1282 | my_message(ER_MIX_OF_GROUP_FUNC_AND_FIELDS, |
| 1283 | ER_THD(thd, ER_MIX_OF_GROUP_FUNC_AND_FIELDS), MYF(0)); |
| 1284 | DBUG_RETURN(-1); |
| 1285 | } |
| 1286 | { |
| 1287 | /* Caclulate the number of groups */ |
| 1288 | send_group_parts= 0; |
| 1289 | for (ORDER *group_tmp= group_list ; group_tmp ; group_tmp= group_tmp->next) |
| 1290 | send_group_parts++; |
| 1291 | } |
| 1292 | |
| 1293 | procedure= setup_procedure(thd, proc_param, result, fields_list, &error); |
| 1294 | if (unlikely(error)) |
| 1295 | goto err; /* purecov: inspected */ |
| 1296 | if (procedure) |
| 1297 | { |
| 1298 | if (setup_new_fields(thd, fields_list, all_fields, |
| 1299 | procedure->param_fields)) |
| 1300 | goto err; /* purecov: inspected */ |
| 1301 | if (procedure->group) |
| 1302 | { |
| 1303 | if (!test_if_subpart(procedure->group,group_list)) |
| 1304 | { /* purecov: inspected */ |
| 1305 | my_message(ER_DIFF_GROUPS_PROC, ER_THD(thd, ER_DIFF_GROUPS_PROC), |
| 1306 | MYF(0)); /* purecov: inspected */ |
| 1307 | goto err; /* purecov: inspected */ |
| 1308 | } |
| 1309 | } |
| 1310 | if (order && (procedure->flags & PROC_NO_SORT)) |
| 1311 | { /* purecov: inspected */ |
| 1312 | my_message(ER_ORDER_WITH_PROC, ER_THD(thd, ER_ORDER_WITH_PROC), |
| 1313 | MYF(0)); /* purecov: inspected */ |
| 1314 | goto err; /* purecov: inspected */ |
| 1315 | } |
| 1316 | if (thd->lex->derived_tables) |
| 1317 | { |
| 1318 | /* |
| 1319 | Queries with derived tables and PROCEDURE are not allowed. |
| 1320 | Many of such queries are disallowed grammatically, but there |
| 1321 | are still some complex cases: |
| 1322 | SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE() |
| 1323 | */ |
| 1324 | my_error(ER_WRONG_USAGE, MYF(0), "PROCEDURE" , |
| 1325 | thd->lex->derived_tables & DERIVED_VIEW ? |
| 1326 | "view" : "subquery" ); |
| 1327 | goto err; |
| 1328 | } |
| 1329 | if (thd->lex->sql_command != SQLCOM_SELECT) |
| 1330 | { |
| 1331 | // EXPLAIN SELECT * FROM t1 PROCEDURE ANALYSE() |
| 1332 | my_error(ER_WRONG_USAGE, MYF(0), "PROCEDURE" , "non-SELECT" ); |
| 1333 | goto err; |
| 1334 | } |
| 1335 | } |
| 1336 | |
| 1337 | if (!procedure && result && result->prepare(fields_list, unit_arg)) |
| 1338 | goto err; /* purecov: inspected */ |
| 1339 | |
| 1340 | unit= unit_arg; |
| 1341 | if (prepare_stage2()) |
| 1342 | goto err; |
| 1343 | |
| 1344 | DBUG_RETURN(0); // All OK |
| 1345 | |
| 1346 | err: |
| 1347 | delete procedure; /* purecov: inspected */ |
| 1348 | procedure= 0; |
| 1349 | DBUG_RETURN(-1); /* purecov: inspected */ |
| 1350 | } |
| 1351 | |
| 1352 | |
| 1353 | /** |
| 1354 | Second phase of prepare where we collect some statistic. |
| 1355 | |
| 1356 | @details |
| 1357 | We made this part separate to be able recalculate some statistic after |
| 1358 | transforming subquery on optimization phase. |
| 1359 | */ |
| 1360 | |
| 1361 | bool JOIN::prepare_stage2() |
| 1362 | { |
| 1363 | bool res= TRUE; |
| 1364 | DBUG_ENTER("JOIN::prepare_stage2" ); |
| 1365 | |
| 1366 | /* Init join struct */ |
| 1367 | count_field_types(select_lex, &tmp_table_param, all_fields, 0); |
| 1368 | this->group= group_list != 0; |
| 1369 | |
| 1370 | if (tmp_table_param.sum_func_count && !group_list) |
| 1371 | { |
| 1372 | implicit_grouping= TRUE; |
| 1373 | // Result will contain zero or one row - ordering is meaningless |
| 1374 | order= NULL; |
| 1375 | } |
| 1376 | |
| 1377 | #ifdef RESTRICTED_GROUP |
| 1378 | if (implicit_grouping) |
| 1379 | { |
| 1380 | my_message(ER_WRONG_SUM_SELECT,ER_THD(thd, ER_WRONG_SUM_SELECT),MYF(0)); |
| 1381 | goto err; |
| 1382 | } |
| 1383 | #endif |
| 1384 | if (select_lex->olap == ROLLUP_TYPE && rollup_init()) |
| 1385 | goto err; |
| 1386 | if (alloc_func_list()) |
| 1387 | goto err; |
| 1388 | |
| 1389 | res= FALSE; |
| 1390 | err: |
| 1391 | DBUG_RETURN(res); /* purecov: inspected */ |
| 1392 | } |
| 1393 | |
| 1394 | |
| 1395 | bool JOIN::build_explain() |
| 1396 | { |
| 1397 | create_explain_query_if_not_exists(thd->lex, thd->mem_root); |
| 1398 | have_query_plan= QEP_AVAILABLE; |
| 1399 | |
| 1400 | /* |
| 1401 | explain data must be created on the Explain_query::mem_root. Because it's |
| 1402 | just a memroot, not an arena, explain data must not contain any Items |
| 1403 | */ |
| 1404 | MEM_ROOT *old_mem_root= thd->mem_root; |
| 1405 | Item *old_free_list __attribute__((unused))= thd->free_list; |
| 1406 | thd->mem_root= thd->lex->explain->mem_root; |
| 1407 | bool res= save_explain_data(thd->lex->explain, false /* can overwrite */, |
| 1408 | need_tmp, |
| 1409 | !skip_sort_order && !no_order && (order || group_list), |
| 1410 | select_distinct); |
| 1411 | thd->mem_root= old_mem_root; |
| 1412 | DBUG_ASSERT(thd->free_list == old_free_list); // no Items were created |
| 1413 | if (res) |
| 1414 | return 1; |
| 1415 | |
| 1416 | uint select_nr= select_lex->select_number; |
| 1417 | JOIN_TAB *curr_tab= join_tab + exec_join_tab_cnt(); |
| 1418 | for (uint i= 0; i < aggr_tables; i++, curr_tab++) |
| 1419 | { |
| 1420 | if (select_nr == INT_MAX) |
| 1421 | { |
| 1422 | /* this is a fake_select_lex of a union */ |
| 1423 | select_nr= select_lex->master_unit()->first_select()->select_number; |
| 1424 | curr_tab->tracker= thd->lex->explain->get_union(select_nr)-> |
| 1425 | get_tmptable_read_tracker(); |
| 1426 | } |
| 1427 | else |
| 1428 | { |
| 1429 | curr_tab->tracker= thd->lex->explain->get_select(select_nr)-> |
| 1430 | get_using_temporary_read_tracker(); |
| 1431 | } |
| 1432 | } |
| 1433 | return 0; |
| 1434 | } |
| 1435 | |
| 1436 | |
| 1437 | int JOIN::optimize() |
| 1438 | { |
| 1439 | int res= 0; |
| 1440 | join_optimization_state init_state= optimization_state; |
| 1441 | if (optimization_state == JOIN::OPTIMIZATION_PHASE_1_DONE) |
| 1442 | res= optimize_stage2(); |
| 1443 | else |
| 1444 | { |
| 1445 | // to prevent double initialization on EXPLAIN |
| 1446 | if (optimization_state != JOIN::NOT_OPTIMIZED) |
| 1447 | return FALSE; |
| 1448 | optimization_state= JOIN::OPTIMIZATION_IN_PROGRESS; |
| 1449 | res= optimize_inner(); |
| 1450 | } |
| 1451 | if (!with_two_phase_optimization || |
| 1452 | init_state == JOIN::OPTIMIZATION_PHASE_1_DONE) |
| 1453 | { |
| 1454 | if (!res && have_query_plan != QEP_DELETED) |
| 1455 | res= build_explain(); |
| 1456 | optimization_state= JOIN::OPTIMIZATION_DONE; |
| 1457 | } |
| 1458 | return res; |
| 1459 | } |
| 1460 | |
| 1461 | |
| 1462 | int JOIN::init_join_caches() |
| 1463 | { |
| 1464 | JOIN_TAB *tab; |
| 1465 | |
| 1466 | for (tab= first_linear_tab(this, WITH_BUSH_ROOTS, WITHOUT_CONST_TABLES); |
| 1467 | tab; |
| 1468 | tab= next_linear_tab(this, tab, WITH_BUSH_ROOTS)) |
| 1469 | { |
| 1470 | TABLE *table= tab->table; |
| 1471 | if (table->file->keyread_enabled()) |
| 1472 | { |
| 1473 | if (!(table->file->index_flags(table->file->keyread, 0, 1) & HA_CLUSTERED_INDEX)) |
| 1474 | table->mark_columns_used_by_index(table->file->keyread, table->read_set); |
| 1475 | } |
| 1476 | else if ((tab->read_first_record == join_read_first || |
| 1477 | tab->read_first_record == join_read_last) && |
| 1478 | !tab->filesort && table->covering_keys.is_set(tab->index) && |
| 1479 | !table->no_keyread) |
| 1480 | { |
| 1481 | table->prepare_for_keyread(tab->index, table->read_set); |
| 1482 | } |
| 1483 | if (tab->cache && tab->cache->init(select_options & SELECT_DESCRIBE)) |
| 1484 | revise_cache_usage(tab); |
| 1485 | else |
| 1486 | tab->remove_redundant_bnl_scan_conds(); |
| 1487 | } |
| 1488 | return 0; |
| 1489 | } |
| 1490 | |
| 1491 | |
| 1492 | /** |
| 1493 | global select optimisation. |
| 1494 | |
| 1495 | @note |
| 1496 | error code saved in field 'error' |
| 1497 | |
| 1498 | @retval |
| 1499 | 0 success |
| 1500 | @retval |
| 1501 | 1 error |
| 1502 | */ |
| 1503 | |
| 1504 | int |
| 1505 | JOIN::optimize_inner() |
| 1506 | { |
| 1507 | DBUG_ENTER("JOIN::optimize" ); |
| 1508 | subq_exit_fl= false; |
| 1509 | do_send_rows = (unit->select_limit_cnt) ? 1 : 0; |
| 1510 | |
| 1511 | DEBUG_SYNC(thd, "before_join_optimize" ); |
| 1512 | |
| 1513 | THD_STAGE_INFO(thd, stage_optimizing); |
| 1514 | |
| 1515 | set_allowed_join_cache_types(); |
| 1516 | need_distinct= TRUE; |
| 1517 | |
| 1518 | /* |
| 1519 | Needed in case optimizer short-cuts, |
| 1520 | set properly in make_aggr_tables_info() |
| 1521 | */ |
| 1522 | fields= &select_lex->item_list; |
| 1523 | |
| 1524 | if (select_lex->first_cond_optimization) |
| 1525 | { |
| 1526 | //Do it only for the first execution |
| 1527 | /* Merge all mergeable derived tables/views in this SELECT. */ |
| 1528 | if (select_lex->handle_derived(thd->lex, DT_MERGE)) |
| 1529 | DBUG_RETURN(TRUE); |
| 1530 | table_count= select_lex->leaf_tables.elements; |
| 1531 | } |
| 1532 | |
| 1533 | if (select_lex->first_cond_optimization && |
| 1534 | transform_in_predicates_into_in_subq(thd)) |
| 1535 | DBUG_RETURN(1); |
| 1536 | |
| 1537 | // Update used tables after all handling derived table procedures |
| 1538 | select_lex->update_used_tables(); |
| 1539 | |
| 1540 | /* |
| 1541 | In fact we transform underlying subqueries after their 'prepare' phase and |
| 1542 | before 'optimize' from upper query 'optimize' to allow semijoin |
| 1543 | conversion happened (which done in the same way. |
| 1544 | */ |
| 1545 | if (select_lex->first_cond_optimization && |
| 1546 | conds && conds->walk(&Item::exists2in_processor, 0, thd)) |
| 1547 | DBUG_RETURN(1); |
| 1548 | /* |
| 1549 | TODO |
| 1550 | make view to decide if it is possible to write to WHERE directly or make Semi-Joins able to process ON condition if it is possible |
| 1551 | for (TABLE_LIST *tbl= tables_list; tbl; tbl= tbl->next_local) |
| 1552 | { |
| 1553 | if (tbl->on_expr && |
| 1554 | tbl->on_expr->walk(&Item::exists2in_processor, 0, thd)) |
| 1555 | DBUG_RETURN(1); |
| 1556 | } |
| 1557 | */ |
| 1558 | |
| 1559 | if (transform_max_min_subquery()) |
| 1560 | DBUG_RETURN(1); /* purecov: inspected */ |
| 1561 | |
| 1562 | if (select_lex->first_cond_optimization) |
| 1563 | { |
| 1564 | /* dump_TABLE_LIST_graph(select_lex, select_lex->leaf_tables); */ |
| 1565 | if (convert_join_subqueries_to_semijoins(this)) |
| 1566 | DBUG_RETURN(1); /* purecov: inspected */ |
| 1567 | /* dump_TABLE_LIST_graph(select_lex, select_lex->leaf_tables); */ |
| 1568 | select_lex->update_used_tables(); |
| 1569 | |
| 1570 | } |
| 1571 | |
| 1572 | eval_select_list_used_tables(); |
| 1573 | |
| 1574 | table_count= select_lex->leaf_tables.elements; |
| 1575 | |
| 1576 | if (setup_ftfuncs(select_lex)) /* should be after having->fix_fields */ |
| 1577 | DBUG_RETURN(-1); |
| 1578 | |
| 1579 | row_limit= ((select_distinct || order || group_list) ? HA_POS_ERROR : |
| 1580 | unit->select_limit_cnt); |
| 1581 | /* select_limit is used to decide if we are likely to scan the whole table */ |
| 1582 | select_limit= unit->select_limit_cnt; |
| 1583 | if (having || (select_options & OPTION_FOUND_ROWS)) |
| 1584 | select_limit= HA_POS_ERROR; |
| 1585 | #ifdef HAVE_REF_TO_FIELDS // Not done yet |
| 1586 | /* Add HAVING to WHERE if possible */ |
| 1587 | if (having && !group_list && !sum_func_count) |
| 1588 | { |
| 1589 | if (!conds) |
| 1590 | { |
| 1591 | conds= having; |
| 1592 | having= 0; |
| 1593 | } |
| 1594 | else if ((conds=new (thd->mem_root) Item_cond_and(conds,having))) |
| 1595 | { |
| 1596 | /* |
| 1597 | Item_cond_and can't be fixed after creation, so we do not check |
| 1598 | conds->fixed |
| 1599 | */ |
| 1600 | conds->fix_fields(thd, &conds); |
| 1601 | conds->change_ref_to_fields(thd, tables_list); |
| 1602 | conds->top_level_item(); |
| 1603 | having= 0; |
| 1604 | } |
| 1605 | } |
| 1606 | #endif |
| 1607 | |
| 1608 | SELECT_LEX *sel= select_lex; |
| 1609 | if (sel->first_cond_optimization) |
| 1610 | { |
| 1611 | /* |
| 1612 | The following code will allocate the new items in a permanent |
| 1613 | MEMROOT for prepared statements and stored procedures. |
| 1614 | |
| 1615 | But first we need to ensure that thd->lex->explain is allocated |
| 1616 | in the execution arena |
| 1617 | */ |
| 1618 | create_explain_query_if_not_exists(thd->lex, thd->mem_root); |
| 1619 | |
| 1620 | Query_arena *arena, backup; |
| 1621 | arena= thd->activate_stmt_arena_if_needed(&backup); |
| 1622 | |
| 1623 | sel->first_cond_optimization= 0; |
| 1624 | |
| 1625 | /* Convert all outer joins to inner joins if possible */ |
| 1626 | conds= simplify_joins(this, join_list, conds, TRUE, FALSE); |
| 1627 | if (thd->is_error() || select_lex->save_leaf_tables(thd)) |
| 1628 | { |
| 1629 | if (arena) |
| 1630 | thd->restore_active_arena(arena, &backup); |
| 1631 | DBUG_RETURN(1); |
| 1632 | } |
| 1633 | build_bitmap_for_nested_joins(join_list, 0); |
| 1634 | |
| 1635 | sel->prep_where= conds ? conds->copy_andor_structure(thd) : 0; |
| 1636 | |
| 1637 | sel->where= conds; |
| 1638 | |
| 1639 | if (arena) |
| 1640 | thd->restore_active_arena(arena, &backup); |
| 1641 | } |
| 1642 | |
| 1643 | if (optimize_constant_subqueries()) |
| 1644 | DBUG_RETURN(1); |
| 1645 | |
| 1646 | if (setup_jtbm_semi_joins(this, join_list, &conds)) |
| 1647 | DBUG_RETURN(1); |
| 1648 | |
| 1649 | if (select_lex->cond_pushed_into_where) |
| 1650 | { |
| 1651 | conds= and_conds(thd, conds, select_lex->cond_pushed_into_where); |
| 1652 | if (conds && conds->fix_fields(thd, &conds)) |
| 1653 | DBUG_RETURN(1); |
| 1654 | } |
| 1655 | if (select_lex->cond_pushed_into_having) |
| 1656 | { |
| 1657 | having= and_conds(thd, having, select_lex->cond_pushed_into_having); |
| 1658 | if (having) |
| 1659 | { |
| 1660 | select_lex->having_fix_field= 1; |
| 1661 | if (having->fix_fields(thd, &having)) |
| 1662 | DBUG_RETURN(1); |
| 1663 | select_lex->having_fix_field= 0; |
| 1664 | } |
| 1665 | } |
| 1666 | |
| 1667 | conds= optimize_cond(this, conds, join_list, FALSE, |
| 1668 | &cond_value, &cond_equal, OPT_LINK_EQUAL_FIELDS); |
| 1669 | |
| 1670 | if (thd->lex->sql_command == SQLCOM_SELECT && |
| 1671 | optimizer_flag(thd, OPTIMIZER_SWITCH_COND_PUSHDOWN_FOR_DERIVED)) |
| 1672 | { |
| 1673 | TABLE_LIST *tbl; |
| 1674 | List_iterator_fast<TABLE_LIST> li(select_lex->leaf_tables); |
| 1675 | while ((tbl= li++)) |
| 1676 | { |
| 1677 | /* |
| 1678 | Do not push conditions from where into materialized inner tables |
| 1679 | of outer joins: this is not valid. |
| 1680 | */ |
| 1681 | if (tbl->is_materialized_derived()) |
| 1682 | { |
| 1683 | JOIN *join= tbl->get_unit()->first_select()->join; |
| 1684 | if (join && |
| 1685 | join->optimization_state == JOIN::OPTIMIZATION_PHASE_1_DONE && |
| 1686 | join->with_two_phase_optimization) |
| 1687 | continue; |
| 1688 | /* |
| 1689 | Do not push conditions from where into materialized inner tables |
| 1690 | of outer joins: this is not valid. |
| 1691 | */ |
| 1692 | if (!tbl->is_inner_table_of_outer_join()) |
| 1693 | { |
| 1694 | if (pushdown_cond_for_derived(thd, conds, tbl)) |
| 1695 | DBUG_RETURN(1); |
| 1696 | } |
| 1697 | if (mysql_handle_single_derived(thd->lex, tbl, DT_OPTIMIZE)) |
| 1698 | DBUG_RETURN(1); |
| 1699 | } |
| 1700 | } |
| 1701 | } |
| 1702 | else |
| 1703 | { |
| 1704 | /* Run optimize phase for all derived tables/views used in this SELECT. */ |
| 1705 | if (select_lex->handle_derived(thd->lex, DT_OPTIMIZE)) |
| 1706 | DBUG_RETURN(1); |
| 1707 | } |
| 1708 | |
| 1709 | if (unlikely(thd->is_error())) |
| 1710 | { |
| 1711 | error= 1; |
| 1712 | DBUG_PRINT("error" ,("Error from optimize_cond" )); |
| 1713 | DBUG_RETURN(1); |
| 1714 | } |
| 1715 | |
| 1716 | { |
| 1717 | having= optimize_cond(this, having, join_list, TRUE, |
| 1718 | &having_value, &having_equal); |
| 1719 | |
| 1720 | if (unlikely(thd->is_error())) |
| 1721 | { |
| 1722 | error= 1; |
| 1723 | DBUG_PRINT("error" ,("Error from optimize_cond" )); |
| 1724 | DBUG_RETURN(1); |
| 1725 | } |
| 1726 | if (select_lex->where) |
| 1727 | { |
| 1728 | select_lex->cond_value= cond_value; |
| 1729 | if (sel->where != conds && cond_value == Item::COND_OK) |
| 1730 | thd->change_item_tree(&sel->where, conds); |
| 1731 | } |
| 1732 | if (select_lex->having) |
| 1733 | { |
| 1734 | select_lex->having_value= having_value; |
| 1735 | if (sel->having != having && having_value == Item::COND_OK) |
| 1736 | thd->change_item_tree(&sel->having, having); |
| 1737 | } |
| 1738 | if (cond_value == Item::COND_FALSE || having_value == Item::COND_FALSE || |
| 1739 | (!unit->select_limit_cnt && !(select_options & OPTION_FOUND_ROWS))) |
| 1740 | { /* Impossible cond */ |
| 1741 | DBUG_PRINT("info" , (having_value == Item::COND_FALSE ? |
| 1742 | "Impossible HAVING" : "Impossible WHERE" )); |
| 1743 | zero_result_cause= having_value == Item::COND_FALSE ? |
| 1744 | "Impossible HAVING" : "Impossible WHERE" ; |
| 1745 | table_count= top_join_tab_count= 0; |
| 1746 | error= 0; |
| 1747 | subq_exit_fl= true; |
| 1748 | goto setup_subq_exit; |
| 1749 | } |
| 1750 | } |
| 1751 | |
| 1752 | #ifdef WITH_PARTITION_STORAGE_ENGINE |
| 1753 | { |
| 1754 | TABLE_LIST *tbl; |
| 1755 | List_iterator_fast<TABLE_LIST> li(select_lex->leaf_tables); |
| 1756 | while ((tbl= li++)) |
| 1757 | { |
| 1758 | /* |
| 1759 | If tbl->embedding!=NULL that means that this table is in the inner |
| 1760 | part of the nested outer join, and we can't do partition pruning |
| 1761 | (TODO: check if this limitation can be lifted) |
| 1762 | */ |
| 1763 | if (!tbl->embedding || |
| 1764 | (tbl->embedding && tbl->embedding->sj_on_expr)) |
| 1765 | { |
| 1766 | Item *prune_cond= tbl->on_expr? tbl->on_expr : conds; |
| 1767 | tbl->table->all_partitions_pruned_away= prune_partitions(thd, |
| 1768 | tbl->table, |
| 1769 | prune_cond); |
| 1770 | } |
| 1771 | } |
| 1772 | } |
| 1773 | #endif |
| 1774 | |
| 1775 | /* |
| 1776 | Try to optimize count(*), MY_MIN() and MY_MAX() to const fields if |
| 1777 | there is implicit grouping (aggregate functions but no |
| 1778 | group_list). In this case, the result set shall only contain one |
| 1779 | row. |
| 1780 | */ |
| 1781 | if (tables_list && implicit_grouping) |
| 1782 | { |
| 1783 | int res; |
| 1784 | /* |
| 1785 | opt_sum_query() returns HA_ERR_KEY_NOT_FOUND if no rows match |
| 1786 | to the WHERE conditions, |
| 1787 | or 1 if all items were resolved (optimized away), |
| 1788 | or 0, or an error number HA_ERR_... |
| 1789 | |
| 1790 | If all items were resolved by opt_sum_query, there is no need to |
| 1791 | open any tables. |
| 1792 | */ |
| 1793 | if ((res=opt_sum_query(thd, select_lex->leaf_tables, all_fields, conds))) |
| 1794 | { |
| 1795 | DBUG_ASSERT(res >= 0); |
| 1796 | if (res == HA_ERR_KEY_NOT_FOUND) |
| 1797 | { |
| 1798 | DBUG_PRINT("info" ,("No matching min/max row" )); |
| 1799 | zero_result_cause= "No matching min/max row" ; |
| 1800 | table_count= top_join_tab_count= 0; |
| 1801 | error=0; |
| 1802 | subq_exit_fl= true; |
| 1803 | goto setup_subq_exit; |
| 1804 | } |
| 1805 | if (res > 1) |
| 1806 | { |
| 1807 | error= res; |
| 1808 | DBUG_PRINT("error" ,("Error from opt_sum_query" )); |
| 1809 | DBUG_RETURN(1); |
| 1810 | } |
| 1811 | |
| 1812 | DBUG_PRINT("info" ,("Select tables optimized away" )); |
| 1813 | if (!select_lex->have_window_funcs()) |
| 1814 | zero_result_cause= "Select tables optimized away" ; |
| 1815 | tables_list= 0; // All tables resolved |
| 1816 | select_lex->min_max_opt_list.empty(); |
| 1817 | const_tables= top_join_tab_count= table_count; |
| 1818 | /* |
| 1819 | Extract all table-independent conditions and replace the WHERE |
| 1820 | clause with them. All other conditions were computed by opt_sum_query |
| 1821 | and the MIN/MAX/COUNT function(s) have been replaced by constants, |
| 1822 | so there is no need to compute the whole WHERE clause again. |
| 1823 | Notice that make_cond_for_table() will always succeed to remove all |
| 1824 | computed conditions, because opt_sum_query() is applicable only to |
| 1825 | conjunctions. |
| 1826 | Preserve conditions for EXPLAIN. |
| 1827 | */ |
| 1828 | if (conds && !(thd->lex->describe & DESCRIBE_EXTENDED)) |
| 1829 | { |
| 1830 | COND *table_independent_conds= |
| 1831 | make_cond_for_table(thd, conds, PSEUDO_TABLE_BITS, 0, -1, |
| 1832 | FALSE, FALSE); |
| 1833 | DBUG_EXECUTE("where" , |
| 1834 | print_where(table_independent_conds, |
| 1835 | "where after opt_sum_query()" , |
| 1836 | QT_ORDINARY);); |
| 1837 | conds= table_independent_conds; |
| 1838 | } |
| 1839 | } |
| 1840 | } |
| 1841 | if (!tables_list) |
| 1842 | { |
| 1843 | DBUG_PRINT("info" ,("No tables" )); |
| 1844 | error= 0; |
| 1845 | subq_exit_fl= true; |
| 1846 | goto setup_subq_exit; |
| 1847 | } |
| 1848 | error= -1; // Error is sent to client |
| 1849 | /* get_sort_by_table() call used to be here: */ |
| 1850 | MEM_UNDEFINED(&sort_by_table, sizeof(sort_by_table)); |
| 1851 | |
| 1852 | /* |
| 1853 | We have to remove constants and duplicates from group_list before |
| 1854 | calling make_join_statistics() as this may call get_best_group_min_max() |
| 1855 | which needs a simplfied group_list. |
| 1856 | */ |
| 1857 | if (group_list && table_count == 1) |
| 1858 | { |
| 1859 | group_list= remove_const(this, group_list, conds, |
| 1860 | rollup.state == ROLLUP::STATE_NONE, |
| 1861 | &simple_group); |
| 1862 | if (unlikely(thd->is_error())) |
| 1863 | { |
| 1864 | error= 1; |
| 1865 | DBUG_RETURN(1); |
| 1866 | } |
| 1867 | } |
| 1868 | |
| 1869 | /* Calculate how to do the join */ |
| 1870 | THD_STAGE_INFO(thd, stage_statistics); |
| 1871 | result->prepare_to_read_rows(); |
| 1872 | if (unlikely(make_join_statistics(this, select_lex->leaf_tables, |
| 1873 | &keyuse)) || |
| 1874 | unlikely(thd->is_fatal_error)) |
| 1875 | { |
| 1876 | DBUG_PRINT("error" ,("Error: make_join_statistics() failed" )); |
| 1877 | DBUG_RETURN(1); |
| 1878 | } |
| 1879 | |
| 1880 | /* |
| 1881 | If a splittable materialized derived/view dt_i is embedded into |
| 1882 | into another splittable materialized derived/view dt_o then |
| 1883 | splitting plans for dt_i and dt_o are evaluated independently. |
| 1884 | First the optimizer looks for the best splitting plan sp_i for dt_i. |
| 1885 | It happens when non-splitting plans for dt_o are evaluated. |
| 1886 | The cost of sp_i is considered as the cost of materialization of dt_i |
| 1887 | when evaluating any splitting plan for dt_o. |
| 1888 | */ |
| 1889 | if (fix_all_splittings_in_plan()) |
| 1890 | DBUG_RETURN(1); |
| 1891 | |
| 1892 | setup_subq_exit: |
| 1893 | with_two_phase_optimization= check_two_phase_optimization(thd); |
| 1894 | if (with_two_phase_optimization) |
| 1895 | optimization_state= JOIN::OPTIMIZATION_PHASE_1_DONE; |
| 1896 | else |
| 1897 | { |
| 1898 | if (optimize_stage2()) |
| 1899 | DBUG_RETURN(1); |
| 1900 | } |
| 1901 | DBUG_RETURN(0); |
| 1902 | } |
| 1903 | |
| 1904 | |
| 1905 | int JOIN::optimize_stage2() |
| 1906 | { |
| 1907 | ulonglong select_opts_for_readinfo; |
| 1908 | uint no_jbuf_after; |
| 1909 | JOIN_TAB *tab; |
| 1910 | DBUG_ENTER("JOIN::optimize_stage2" ); |
| 1911 | |
| 1912 | if (subq_exit_fl) |
| 1913 | goto setup_subq_exit; |
| 1914 | |
| 1915 | if (unlikely(thd->check_killed())) |
| 1916 | DBUG_RETURN(1); |
| 1917 | |
| 1918 | /* Generate an execution plan from the found optimal join order. */ |
| 1919 | if (get_best_combination()) |
| 1920 | DBUG_RETURN(1); |
| 1921 | |
| 1922 | if (select_lex->handle_derived(thd->lex, DT_OPTIMIZE)) |
| 1923 | DBUG_RETURN(1); |
| 1924 | |
| 1925 | if (optimizer_flag(thd, OPTIMIZER_SWITCH_DERIVED_WITH_KEYS)) |
| 1926 | drop_unused_derived_keys(); |
| 1927 | |
| 1928 | if (rollup.state != ROLLUP::STATE_NONE) |
| 1929 | { |
| 1930 | if (rollup_process_const_fields()) |
| 1931 | { |
| 1932 | DBUG_PRINT("error" , ("Error: rollup_process_fields() failed" )); |
| 1933 | DBUG_RETURN(1); |
| 1934 | } |
| 1935 | } |
| 1936 | else |
| 1937 | { |
| 1938 | /* Remove distinct if only const tables */ |
| 1939 | select_distinct= select_distinct && (const_tables != table_count); |
| 1940 | } |
| 1941 | |
| 1942 | THD_STAGE_INFO(thd, stage_preparing); |
| 1943 | if (result->initialize_tables(this)) |
| 1944 | { |
| 1945 | DBUG_PRINT("error" ,("Error: initialize_tables() failed" )); |
| 1946 | DBUG_RETURN(1); // error == -1 |
| 1947 | } |
| 1948 | if (const_table_map != found_const_table_map && |
| 1949 | !(select_options & SELECT_DESCRIBE)) |
| 1950 | { |
| 1951 | // There is at least one empty const table |
| 1952 | zero_result_cause= "no matching row in const table" ; |
| 1953 | DBUG_PRINT("error" ,("Error: %s" , zero_result_cause)); |
| 1954 | error= 0; |
| 1955 | goto setup_subq_exit; |
| 1956 | } |
| 1957 | if (!(thd->variables.option_bits & OPTION_BIG_SELECTS) && |
| 1958 | best_read > (double) thd->variables.max_join_size && |
| 1959 | !(select_options & SELECT_DESCRIBE)) |
| 1960 | { /* purecov: inspected */ |
| 1961 | my_message(ER_TOO_BIG_SELECT, ER_THD(thd, ER_TOO_BIG_SELECT), MYF(0)); |
| 1962 | error= -1; |
| 1963 | DBUG_RETURN(1); |
| 1964 | } |
| 1965 | if (const_tables && !thd->locked_tables_mode && |
| 1966 | !(select_options & SELECT_NO_UNLOCK)) |
| 1967 | { |
| 1968 | /* |
| 1969 | Unlock all tables, except sequences, as accessing these may still |
| 1970 | require table updates |
| 1971 | */ |
| 1972 | mysql_unlock_some_tables(thd, table, const_tables, |
| 1973 | GET_LOCK_SKIP_SEQUENCES); |
| 1974 | } |
| 1975 | if (!conds && outer_join) |
| 1976 | { |
| 1977 | /* Handle the case where we have an OUTER JOIN without a WHERE */ |
| 1978 | conds= new (thd->mem_root) Item_int(thd, (longlong) 1,1); // Always true |
| 1979 | } |
| 1980 | |
| 1981 | if (impossible_where) |
| 1982 | { |
| 1983 | zero_result_cause= |
| 1984 | "Impossible WHERE noticed after reading const tables" ; |
| 1985 | select_lex->mark_const_derived(zero_result_cause); |
| 1986 | goto setup_subq_exit; |
| 1987 | } |
| 1988 | |
| 1989 | select= make_select(*table, const_table_map, |
| 1990 | const_table_map, conds, (SORT_INFO*) 0, 1, &error); |
| 1991 | if (unlikely(error)) |
| 1992 | { /* purecov: inspected */ |
| 1993 | error= -1; /* purecov: inspected */ |
| 1994 | DBUG_PRINT("error" ,("Error: make_select() failed" )); |
| 1995 | DBUG_RETURN(1); |
| 1996 | } |
| 1997 | |
| 1998 | reset_nj_counters(this, join_list); |
| 1999 | if (make_outerjoin_info(this)) |
| 2000 | { |
| 2001 | DBUG_RETURN(1); |
| 2002 | } |
| 2003 | |
| 2004 | /* |
| 2005 | Among the equal fields belonging to the same multiple equality |
| 2006 | choose the one that is to be retrieved first and substitute |
| 2007 | all references to these in where condition for a reference for |
| 2008 | the selected field. |
| 2009 | */ |
| 2010 | if (conds) |
| 2011 | { |
| 2012 | conds= substitute_for_best_equal_field(thd, NO_PARTICULAR_TAB, conds, |
| 2013 | cond_equal, map2table); |
| 2014 | if (unlikely(thd->is_error())) |
| 2015 | { |
| 2016 | error= 1; |
| 2017 | DBUG_PRINT("error" ,("Error from substitute_for_best_equal" )); |
| 2018 | DBUG_RETURN(1); |
| 2019 | } |
| 2020 | conds->update_used_tables(); |
| 2021 | DBUG_EXECUTE("where" , |
| 2022 | print_where(conds, |
| 2023 | "after substitute_best_equal" , |
| 2024 | QT_ORDINARY);); |
| 2025 | } |
| 2026 | |
| 2027 | /* |
| 2028 | Perform the optimization on fields evaluation mentioned above |
| 2029 | for all on expressions. |
| 2030 | */ |
| 2031 | for (tab= first_linear_tab(this, WITH_BUSH_ROOTS, WITHOUT_CONST_TABLES); tab; |
| 2032 | tab= next_linear_tab(this, tab, WITH_BUSH_ROOTS)) |
| 2033 | { |
| 2034 | if (*tab->on_expr_ref) |
| 2035 | { |
| 2036 | *tab->on_expr_ref= substitute_for_best_equal_field(thd, NO_PARTICULAR_TAB, |
| 2037 | *tab->on_expr_ref, |
| 2038 | tab->cond_equal, |
| 2039 | map2table); |
| 2040 | if (unlikely(thd->is_error())) |
| 2041 | { |
| 2042 | error= 1; |
| 2043 | DBUG_PRINT("error" ,("Error from substitute_for_best_equal" )); |
| 2044 | DBUG_RETURN(1); |
| 2045 | } |
| 2046 | (*tab->on_expr_ref)->update_used_tables(); |
| 2047 | } |
| 2048 | } |
| 2049 | |
| 2050 | /* |
| 2051 | Perform the optimization on fields evaliation mentioned above |
| 2052 | for all used ref items. |
| 2053 | */ |
| 2054 | for (tab= first_linear_tab(this, WITH_BUSH_ROOTS, WITHOUT_CONST_TABLES); tab; |
| 2055 | tab= next_linear_tab(this, tab, WITH_BUSH_ROOTS)) |
| 2056 | { |
| 2057 | uint key_copy_index=0; |
| 2058 | for (uint i=0; i < tab->ref.key_parts; i++) |
| 2059 | { |
| 2060 | Item **ref_item_ptr= tab->ref.items+i; |
| 2061 | Item *ref_item= *ref_item_ptr; |
| 2062 | if (!ref_item->used_tables() && !(select_options & SELECT_DESCRIBE)) |
| 2063 | continue; |
| 2064 | COND_EQUAL *equals= cond_equal; |
| 2065 | JOIN_TAB *first_inner= tab->first_inner; |
| 2066 | while (equals) |
| 2067 | { |
| 2068 | ref_item= substitute_for_best_equal_field(thd, tab, ref_item, |
| 2069 | equals, map2table); |
| 2070 | if (unlikely(thd->is_fatal_error)) |
| 2071 | DBUG_RETURN(1); |
| 2072 | |
| 2073 | if (first_inner) |
| 2074 | { |
| 2075 | equals= first_inner->cond_equal; |
| 2076 | first_inner= first_inner->first_upper; |
| 2077 | } |
| 2078 | else |
| 2079 | equals= 0; |
| 2080 | } |
| 2081 | ref_item->update_used_tables(); |
| 2082 | if (*ref_item_ptr != ref_item) |
| 2083 | { |
| 2084 | *ref_item_ptr= ref_item; |
| 2085 | Item *item= ref_item->real_item(); |
| 2086 | store_key *key_copy= tab->ref.key_copy[key_copy_index]; |
| 2087 | if (key_copy->type() == store_key::FIELD_STORE_KEY) |
| 2088 | { |
| 2089 | if (item->basic_const_item()) |
| 2090 | { |
| 2091 | /* It is constant propagated here */ |
| 2092 | tab->ref.key_copy[key_copy_index]= |
| 2093 | new store_key_const_item(*tab->ref.key_copy[key_copy_index], |
| 2094 | item); |
| 2095 | } |
| 2096 | else if (item->const_item()) |
| 2097 | { |
| 2098 | tab->ref.key_copy[key_copy_index]= |
| 2099 | new store_key_item(*tab->ref.key_copy[key_copy_index], |
| 2100 | item, TRUE); |
| 2101 | } |
| 2102 | else |
| 2103 | { |
| 2104 | store_key_field *field_copy= ((store_key_field *)key_copy); |
| 2105 | DBUG_ASSERT(item->type() == Item::FIELD_ITEM); |
| 2106 | field_copy->change_source_field((Item_field *) item); |
| 2107 | } |
| 2108 | } |
| 2109 | } |
| 2110 | key_copy_index++; |
| 2111 | } |
| 2112 | } |
| 2113 | |
| 2114 | if (conds && const_table_map != found_const_table_map && |
| 2115 | (select_options & SELECT_DESCRIBE)) |
| 2116 | { |
| 2117 | conds=new (thd->mem_root) Item_int(thd, (longlong) 0, 1); // Always false |
| 2118 | } |
| 2119 | |
| 2120 | /* Cache constant expressions in WHERE, HAVING, ON clauses. */ |
| 2121 | cache_const_exprs(); |
| 2122 | |
| 2123 | if (setup_semijoin_loosescan(this)) |
| 2124 | DBUG_RETURN(1); |
| 2125 | |
| 2126 | if (make_join_select(this, select, conds)) |
| 2127 | { |
| 2128 | zero_result_cause= |
| 2129 | "Impossible WHERE noticed after reading const tables" ; |
| 2130 | select_lex->mark_const_derived(zero_result_cause); |
| 2131 | goto setup_subq_exit; |
| 2132 | } |
| 2133 | |
| 2134 | error= -1; /* if goto err */ |
| 2135 | |
| 2136 | /* Optimize distinct away if possible */ |
| 2137 | { |
| 2138 | ORDER *org_order= order; |
| 2139 | order=remove_const(this, order,conds,1, &simple_order); |
| 2140 | if (unlikely(thd->is_error())) |
| 2141 | { |
| 2142 | error= 1; |
| 2143 | DBUG_RETURN(1); |
| 2144 | } |
| 2145 | |
| 2146 | /* |
| 2147 | If we are using ORDER BY NULL or ORDER BY const_expression, |
| 2148 | return result in any order (even if we are using a GROUP BY) |
| 2149 | */ |
| 2150 | if (!order && org_order) |
| 2151 | skip_sort_order= 1; |
| 2152 | } |
| 2153 | /* |
| 2154 | Check if we can optimize away GROUP BY/DISTINCT. |
| 2155 | We can do that if there are no aggregate functions, the |
| 2156 | fields in DISTINCT clause (if present) and/or columns in GROUP BY |
| 2157 | (if present) contain direct references to all key parts of |
| 2158 | an unique index (in whatever order) and if the key parts of the |
| 2159 | unique index cannot contain NULLs. |
| 2160 | Note that the unique keys for DISTINCT and GROUP BY should not |
| 2161 | be the same (as long as they are unique). |
| 2162 | |
| 2163 | The FROM clause must contain a single non-constant table. |
| 2164 | */ |
| 2165 | if (table_count - const_tables == 1 && (group || select_distinct) && |
| 2166 | !tmp_table_param.sum_func_count && |
| 2167 | (!join_tab[const_tables].select || |
| 2168 | !join_tab[const_tables].select->quick || |
| 2169 | join_tab[const_tables].select->quick->get_type() != |
| 2170 | QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX) && |
| 2171 | !select_lex->have_window_funcs()) |
| 2172 | { |
| 2173 | if (group && rollup.state == ROLLUP::STATE_NONE && |
| 2174 | list_contains_unique_index(join_tab[const_tables].table, |
| 2175 | find_field_in_order_list, |
| 2176 | (void *) group_list)) |
| 2177 | { |
| 2178 | /* |
| 2179 | We have found that grouping can be removed since groups correspond to |
| 2180 | only one row anyway, but we still have to guarantee correct result |
| 2181 | order. The line below effectively rewrites the query from GROUP BY |
| 2182 | <fields> to ORDER BY <fields>. There are three exceptions: |
| 2183 | - if skip_sort_order is set (see above), then we can simply skip |
| 2184 | GROUP BY; |
| 2185 | - if we are in a subquery, we don't have to maintain order unless there |
| 2186 | is a limit clause in the subquery. |
| 2187 | - we can only rewrite ORDER BY if the ORDER BY fields are 'compatible' |
| 2188 | with the GROUP BY ones, i.e. either one is a prefix of another. |
| 2189 | We only check if the ORDER BY is a prefix of GROUP BY. In this case |
| 2190 | test_if_subpart() copies the ASC/DESC attributes from the original |
| 2191 | ORDER BY fields. |
| 2192 | If GROUP BY is a prefix of ORDER BY, then it is safe to leave |
| 2193 | 'order' as is. |
| 2194 | */ |
| 2195 | if (!order || test_if_subpart(group_list, order)) |
| 2196 | { |
| 2197 | if (skip_sort_order || |
| 2198 | (select_lex->master_unit()->item && select_limit == HA_POS_ERROR)) // This is a subquery |
| 2199 | order= NULL; |
| 2200 | else |
| 2201 | order= group_list; |
| 2202 | } |
| 2203 | /* |
| 2204 | If we have an IGNORE INDEX FOR GROUP BY(fields) clause, this must be |
| 2205 | rewritten to IGNORE INDEX FOR ORDER BY(fields). |
| 2206 | */ |
| 2207 | join_tab->table->keys_in_use_for_order_by= |
| 2208 | join_tab->table->keys_in_use_for_group_by; |
| 2209 | group_list= 0; |
| 2210 | group= 0; |
| 2211 | } |
| 2212 | if (select_distinct && |
| 2213 | list_contains_unique_index(join_tab[const_tables].table, |
| 2214 | find_field_in_item_list, |
| 2215 | (void *) &fields_list)) |
| 2216 | { |
| 2217 | select_distinct= 0; |
| 2218 | } |
| 2219 | } |
| 2220 | if (group || tmp_table_param.sum_func_count) |
| 2221 | { |
| 2222 | if (! hidden_group_fields && rollup.state == ROLLUP::STATE_NONE |
| 2223 | && !select_lex->have_window_funcs()) |
| 2224 | select_distinct=0; |
| 2225 | } |
| 2226 | else if (select_distinct && table_count - const_tables == 1 && |
| 2227 | rollup.state == ROLLUP::STATE_NONE && |
| 2228 | !select_lex->have_window_funcs()) |
| 2229 | { |
| 2230 | /* |
| 2231 | We are only using one table. In this case we change DISTINCT to a |
| 2232 | GROUP BY query if: |
| 2233 | - The GROUP BY can be done through indexes (no sort) and the ORDER |
| 2234 | BY only uses selected fields. |
| 2235 | (In this case we can later optimize away GROUP BY and ORDER BY) |
| 2236 | - We are scanning the whole table without LIMIT |
| 2237 | This can happen if: |
| 2238 | - We are using CALC_FOUND_ROWS |
| 2239 | - We are using an ORDER BY that can't be optimized away. |
| 2240 | |
| 2241 | We don't want to use this optimization when we are using LIMIT |
| 2242 | because in this case we can just create a temporary table that |
| 2243 | holds LIMIT rows and stop when this table is full. |
| 2244 | */ |
| 2245 | bool all_order_fields_used; |
| 2246 | |
| 2247 | tab= &join_tab[const_tables]; |
| 2248 | if (order) |
| 2249 | { |
| 2250 | skip_sort_order= |
| 2251 | test_if_skip_sort_order(tab, order, select_limit, |
| 2252 | true, // no_changes |
| 2253 | &tab->table->keys_in_use_for_order_by); |
| 2254 | } |
| 2255 | if ((group_list=create_distinct_group(thd, select_lex->ref_pointer_array, |
| 2256 | order, fields_list, all_fields, |
| 2257 | &all_order_fields_used))) |
| 2258 | { |
| 2259 | const bool skip_group= |
| 2260 | skip_sort_order && |
| 2261 | test_if_skip_sort_order(tab, group_list, select_limit, |
| 2262 | true, // no_changes |
| 2263 | &tab->table->keys_in_use_for_group_by); |
| 2264 | count_field_types(select_lex, &tmp_table_param, all_fields, 0); |
| 2265 | if ((skip_group && all_order_fields_used) || |
| 2266 | select_limit == HA_POS_ERROR || |
| 2267 | (order && !skip_sort_order)) |
| 2268 | { |
| 2269 | /* Change DISTINCT to GROUP BY */ |
| 2270 | select_distinct= 0; |
| 2271 | no_order= !order; |
| 2272 | if (all_order_fields_used) |
| 2273 | { |
| 2274 | if (order && skip_sort_order) |
| 2275 | { |
| 2276 | /* |
| 2277 | Force MySQL to read the table in sorted order to get result in |
| 2278 | ORDER BY order. |
| 2279 | */ |
| 2280 | tmp_table_param.quick_group=0; |
| 2281 | } |
| 2282 | order=0; |
| 2283 | } |
| 2284 | group=1; // For end_write_group |
| 2285 | } |
| 2286 | else |
| 2287 | group_list= 0; |
| 2288 | } |
| 2289 | else if (thd->is_fatal_error) // End of memory |
| 2290 | DBUG_RETURN(1); |
| 2291 | } |
| 2292 | simple_group= rollup.state == ROLLUP::STATE_NONE; |
| 2293 | if (group) |
| 2294 | { |
| 2295 | /* |
| 2296 | Update simple_group and group_list as we now have more information, like |
| 2297 | which tables or columns are constant. |
| 2298 | */ |
| 2299 | group_list= remove_const(this, group_list, conds, |
| 2300 | rollup.state == ROLLUP::STATE_NONE, |
| 2301 | &simple_group); |
| 2302 | if (unlikely(thd->is_error())) |
| 2303 | { |
| 2304 | error= 1; |
| 2305 | DBUG_RETURN(1); |
| 2306 | } |
| 2307 | if (!group_list) |
| 2308 | { |
| 2309 | /* The output has only one row */ |
| 2310 | order=0; |
| 2311 | simple_order=1; |
| 2312 | select_distinct= 0; |
| 2313 | group_optimized_away= 1; |
| 2314 | } |
| 2315 | } |
| 2316 | |
| 2317 | calc_group_buffer(this, group_list); |
| 2318 | send_group_parts= tmp_table_param.group_parts; /* Save org parts */ |
| 2319 | if (procedure && procedure->group) |
| 2320 | { |
| 2321 | group_list= procedure->group= remove_const(this, procedure->group, conds, |
| 2322 | 1, &simple_group); |
| 2323 | if (unlikely(thd->is_error())) |
| 2324 | { |
| 2325 | error= 1; |
| 2326 | DBUG_RETURN(1); |
| 2327 | } |
| 2328 | calc_group_buffer(this, group_list); |
| 2329 | } |
| 2330 | |
| 2331 | if (test_if_subpart(group_list, order) || |
| 2332 | (!group_list && tmp_table_param.sum_func_count)) |
| 2333 | { |
| 2334 | order=0; |
| 2335 | if (is_indexed_agg_distinct(this, NULL)) |
| 2336 | sort_and_group= 0; |
| 2337 | } |
| 2338 | |
| 2339 | // Can't use sort on head table if using join buffering |
| 2340 | if (full_join || hash_join) |
| 2341 | { |
| 2342 | TABLE *stable= (sort_by_table == (TABLE *) 1 ? |
| 2343 | join_tab[const_tables].table : sort_by_table); |
| 2344 | /* |
| 2345 | FORCE INDEX FOR ORDER BY can be used to prevent join buffering when |
| 2346 | sorting on the first table. |
| 2347 | */ |
| 2348 | if (!stable || (!stable->force_index_order && |
| 2349 | !map2table[stable->tablenr]->keep_current_rowid)) |
| 2350 | { |
| 2351 | if (group_list) |
| 2352 | simple_group= 0; |
| 2353 | if (order) |
| 2354 | simple_order= 0; |
| 2355 | } |
| 2356 | } |
| 2357 | |
| 2358 | need_tmp= test_if_need_tmp_table(); |
| 2359 | //TODO this could probably go in test_if_need_tmp_table. |
| 2360 | if (this->select_lex->window_specs.elements > 0) { |
| 2361 | need_tmp= TRUE; |
| 2362 | simple_order= FALSE; |
| 2363 | } |
| 2364 | |
| 2365 | /* |
| 2366 | If the hint FORCE INDEX FOR ORDER BY/GROUP BY is used for the table |
| 2367 | whose columns are required to be returned in a sorted order, then |
| 2368 | the proper value for no_jbuf_after should be yielded by a call to |
| 2369 | the make_join_orderinfo function. |
| 2370 | Yet the current implementation of FORCE INDEX hints does not |
| 2371 | allow us to do it in a clean manner. |
| 2372 | */ |
| 2373 | no_jbuf_after= 1 ? table_count : make_join_orderinfo(this); |
| 2374 | |
| 2375 | // Don't use join buffering when we use MATCH |
| 2376 | select_opts_for_readinfo= |
| 2377 | (select_options & (SELECT_DESCRIBE | SELECT_NO_JOIN_CACHE)) | |
| 2378 | (select_lex->ftfunc_list->elements ? SELECT_NO_JOIN_CACHE : 0); |
| 2379 | |
| 2380 | if (make_join_readinfo(this, select_opts_for_readinfo, no_jbuf_after)) |
| 2381 | DBUG_RETURN(1); |
| 2382 | |
| 2383 | /* Perform FULLTEXT search before all regular searches */ |
| 2384 | if (!(select_options & SELECT_DESCRIBE)) |
| 2385 | if (init_ftfuncs(thd, select_lex, MY_TEST(order))) |
| 2386 | DBUG_RETURN(1); |
| 2387 | |
| 2388 | /* |
| 2389 | It's necessary to check const part of HAVING cond as |
| 2390 | there is a chance that some cond parts may become |
| 2391 | const items after make_join_statistics(for example |
| 2392 | when Item is a reference to cost table field from |
| 2393 | outer join). |
| 2394 | This check is performed only for those conditions |
| 2395 | which do not use aggregate functions. In such case |
| 2396 | temporary table may not be used and const condition |
| 2397 | elements may be lost during further having |
| 2398 | condition transformation in JOIN::exec. |
| 2399 | */ |
| 2400 | if (having && const_table_map && !having->with_sum_func) |
| 2401 | { |
| 2402 | having->update_used_tables(); |
| 2403 | having= having->remove_eq_conds(thd, &select_lex->having_value, true); |
| 2404 | if (select_lex->having_value == Item::COND_FALSE) |
| 2405 | { |
| 2406 | having= new (thd->mem_root) Item_int(thd, (longlong) 0,1); |
| 2407 | zero_result_cause= "Impossible HAVING noticed after reading const tables" ; |
| 2408 | error= 0; |
| 2409 | select_lex->mark_const_derived(zero_result_cause); |
| 2410 | goto setup_subq_exit; |
| 2411 | } |
| 2412 | } |
| 2413 | |
| 2414 | if (optimize_unflattened_subqueries()) |
| 2415 | DBUG_RETURN(1); |
| 2416 | |
| 2417 | int res; |
| 2418 | if ((res= rewrite_to_index_subquery_engine(this)) != -1) |
| 2419 | DBUG_RETURN(res); |
| 2420 | if (setup_subquery_caches()) |
| 2421 | DBUG_RETURN(-1); |
| 2422 | |
| 2423 | /* |
| 2424 | Need to tell handlers that to play it safe, it should fetch all |
| 2425 | columns of the primary key of the tables: this is because MySQL may |
| 2426 | build row pointers for the rows, and for all columns of the primary key |
| 2427 | the read set has not necessarily been set by the server code. |
| 2428 | */ |
| 2429 | if (need_tmp || select_distinct || group_list || order) |
| 2430 | { |
| 2431 | for (uint i= 0; i < table_count; i++) |
| 2432 | { |
| 2433 | if (!(table[i]->map & const_table_map)) |
| 2434 | table[i]->prepare_for_position(); |
| 2435 | } |
| 2436 | } |
| 2437 | |
| 2438 | DBUG_EXECUTE("info" ,TEST_join(this);); |
| 2439 | |
| 2440 | if (!only_const_tables()) |
| 2441 | { |
| 2442 | JOIN_TAB *tab= &join_tab[const_tables]; |
| 2443 | |
| 2444 | if (order) |
| 2445 | { |
| 2446 | /* |
| 2447 | Force using of tmp table if sorting by a SP or UDF function due to |
| 2448 | their expensive and probably non-deterministic nature. |
| 2449 | */ |
| 2450 | for (ORDER *tmp_order= order; tmp_order ; tmp_order=tmp_order->next) |
| 2451 | { |
| 2452 | Item *item= *tmp_order->item; |
| 2453 | if (item->is_expensive()) |
| 2454 | { |
| 2455 | /* Force tmp table without sort */ |
| 2456 | need_tmp=1; simple_order=simple_group=0; |
| 2457 | break; |
| 2458 | } |
| 2459 | } |
| 2460 | } |
| 2461 | |
| 2462 | /* |
| 2463 | Because filesort always does a full table scan or a quick range scan |
| 2464 | we must add the removed reference to the select for the table. |
| 2465 | We only need to do this when we have a simple_order or simple_group |
| 2466 | as in other cases the join is done before the sort. |
| 2467 | */ |
| 2468 | if ((order || group_list) && |
| 2469 | tab->type != JT_ALL && |
| 2470 | tab->type != JT_FT && |
| 2471 | tab->type != JT_REF_OR_NULL && |
| 2472 | ((order && simple_order) || (group_list && simple_group))) |
| 2473 | { |
| 2474 | if (add_ref_to_table_cond(thd,tab)) { |
| 2475 | DBUG_RETURN(1); |
| 2476 | } |
| 2477 | } |
| 2478 | /* |
| 2479 | Investigate whether we may use an ordered index as part of either |
| 2480 | DISTINCT, GROUP BY or ORDER BY execution. An ordered index may be |
| 2481 | used for only the first of any of these terms to be executed. This |
| 2482 | is reflected in the order which we check for test_if_skip_sort_order() |
| 2483 | below. However we do not check for DISTINCT here, as it would have |
| 2484 | been transformed to a GROUP BY at this stage if it is a candidate for |
| 2485 | ordered index optimization. |
| 2486 | If a decision was made to use an ordered index, the availability |
| 2487 | of such an access path is stored in 'ordered_index_usage' for later |
| 2488 | use by 'execute' or 'explain' |
| 2489 | */ |
| 2490 | DBUG_ASSERT(ordered_index_usage == ordered_index_void); |
| 2491 | |
| 2492 | if (group_list) // GROUP BY honoured first |
| 2493 | // (DISTINCT was rewritten to GROUP BY if skippable) |
| 2494 | { |
| 2495 | /* |
| 2496 | When there is SQL_BIG_RESULT do not sort using index for GROUP BY, |
| 2497 | and thus force sorting on disk unless a group min-max optimization |
| 2498 | is going to be used as it is applied now only for one table queries |
| 2499 | with covering indexes. |
| 2500 | */ |
| 2501 | if (!(select_options & SELECT_BIG_RESULT) || |
| 2502 | (tab->select && |
| 2503 | tab->select->quick && |
| 2504 | tab->select->quick->get_type() == |
| 2505 | QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX)) |
| 2506 | { |
| 2507 | if (simple_group && // GROUP BY is possibly skippable |
| 2508 | !select_distinct) // .. if not preceded by a DISTINCT |
| 2509 | { |
| 2510 | /* |
| 2511 | Calculate a possible 'limit' of table rows for 'GROUP BY': |
| 2512 | A specified 'LIMIT' is relative to the final resultset. |
| 2513 | 'need_tmp' implies that there will be more postprocessing |
| 2514 | so the specified 'limit' should not be enforced yet. |
| 2515 | */ |
| 2516 | const ha_rows limit = need_tmp ? HA_POS_ERROR : select_limit; |
| 2517 | if (test_if_skip_sort_order(tab, group_list, limit, false, |
| 2518 | &tab->table->keys_in_use_for_group_by)) |
| 2519 | { |
| 2520 | ordered_index_usage= ordered_index_group_by; |
| 2521 | } |
| 2522 | } |
| 2523 | |
| 2524 | /* |
| 2525 | If we are going to use semi-join LooseScan, it will depend |
| 2526 | on the selected index scan to be used. If index is not used |
| 2527 | for the GROUP BY, we risk that sorting is put on the LooseScan |
| 2528 | table. In order to avoid this, force use of temporary table. |
| 2529 | TODO: Explain the quick_group part of the test below. |
| 2530 | */ |
| 2531 | if ((ordered_index_usage != ordered_index_group_by) && |
| 2532 | ((tmp_table_param.quick_group && !procedure) || |
| 2533 | (tab->emb_sj_nest && |
| 2534 | best_positions[const_tables].sj_strategy == SJ_OPT_LOOSE_SCAN))) |
| 2535 | { |
| 2536 | need_tmp=1; |
| 2537 | simple_order= simple_group= false; // Force tmp table without sort |
| 2538 | } |
| 2539 | } |
| 2540 | } |
| 2541 | else if (order && // ORDER BY wo/ preceding GROUP BY |
| 2542 | (simple_order || skip_sort_order)) // which is possibly skippable |
| 2543 | { |
| 2544 | if (test_if_skip_sort_order(tab, order, select_limit, false, |
| 2545 | &tab->table->keys_in_use_for_order_by)) |
| 2546 | { |
| 2547 | ordered_index_usage= ordered_index_order_by; |
| 2548 | } |
| 2549 | } |
| 2550 | } |
| 2551 | |
| 2552 | if (having) |
| 2553 | having_is_correlated= MY_TEST(having->used_tables() & OUTER_REF_TABLE_BIT); |
| 2554 | tmp_having= having; |
| 2555 | |
| 2556 | if ((select_lex->options & OPTION_SCHEMA_TABLE)) |
| 2557 | optimize_schema_tables_reads(this); |
| 2558 | |
| 2559 | /* |
| 2560 | The loose index scan access method guarantees that all grouping or |
| 2561 | duplicate row elimination (for distinct) is already performed |
| 2562 | during data retrieval, and that all MIN/MAX functions are already |
| 2563 | computed for each group. Thus all MIN/MAX functions should be |
| 2564 | treated as regular functions, and there is no need to perform |
| 2565 | grouping in the main execution loop. |
| 2566 | Notice that currently loose index scan is applicable only for |
| 2567 | single table queries, thus it is sufficient to test only the first |
| 2568 | join_tab element of the plan for its access method. |
| 2569 | */ |
| 2570 | if (join_tab->is_using_loose_index_scan()) |
| 2571 | { |
| 2572 | tmp_table_param.precomputed_group_by= TRUE; |
| 2573 | if (join_tab->is_using_agg_loose_index_scan()) |
| 2574 | { |
| 2575 | need_distinct= FALSE; |
| 2576 | tmp_table_param.precomputed_group_by= FALSE; |
| 2577 | } |
| 2578 | } |
| 2579 | |
| 2580 | if (make_aggr_tables_info()) |
| 2581 | DBUG_RETURN(1); |
| 2582 | |
| 2583 | if (init_join_caches()) |
| 2584 | DBUG_RETURN(1); |
| 2585 | |
| 2586 | error= 0; |
| 2587 | |
| 2588 | if (select_options & SELECT_DESCRIBE) |
| 2589 | goto derived_exit; |
| 2590 | |
| 2591 | DBUG_RETURN(0); |
| 2592 | |
| 2593 | setup_subq_exit: |
| 2594 | /* Choose an execution strategy for this JOIN. */ |
| 2595 | if (!tables_list || !table_count) |
| 2596 | { |
| 2597 | choose_tableless_subquery_plan(); |
| 2598 | if (select_lex->have_window_funcs()) |
| 2599 | { |
| 2600 | if (!(join_tab= (JOIN_TAB*) thd->alloc(sizeof(JOIN_TAB)))) |
| 2601 | DBUG_RETURN(1); |
| 2602 | need_tmp= 1; |
| 2603 | } |
| 2604 | if (make_aggr_tables_info()) |
| 2605 | DBUG_RETURN(1); |
| 2606 | } |
| 2607 | /* |
| 2608 | Even with zero matching rows, subqueries in the HAVING clause may |
| 2609 | need to be evaluated if there are aggregate functions in the query. |
| 2610 | */ |
| 2611 | if (optimize_unflattened_subqueries()) |
| 2612 | DBUG_RETURN(1); |
| 2613 | error= 0; |
| 2614 | |
| 2615 | derived_exit: |
| 2616 | |
| 2617 | select_lex->mark_const_derived(zero_result_cause); |
| 2618 | DBUG_RETURN(0); |
| 2619 | } |
| 2620 | |
| 2621 | /** |
| 2622 | Add having condition as a where clause condition of the given temp table. |
| 2623 | |
| 2624 | @param tab Table to which having condition is added. |
| 2625 | |
| 2626 | @returns false if success, true if error. |
| 2627 | */ |
| 2628 | |
| 2629 | bool JOIN::add_having_as_table_cond(JOIN_TAB *tab) |
| 2630 | { |
| 2631 | tmp_having->update_used_tables(); |
| 2632 | table_map used_tables= tab->table->map | OUTER_REF_TABLE_BIT; |
| 2633 | |
| 2634 | /* If tmp table is not used then consider conditions of const table also */ |
| 2635 | if (!need_tmp) |
| 2636 | used_tables|= const_table_map; |
| 2637 | |
| 2638 | DBUG_ENTER("JOIN::add_having_as_table_cond" ); |
| 2639 | |
| 2640 | Item* sort_table_cond= make_cond_for_table(thd, tmp_having, used_tables, |
| 2641 | (table_map) 0, false, |
| 2642 | false, false); |
| 2643 | if (sort_table_cond) |
| 2644 | { |
| 2645 | if (!tab->select) |
| 2646 | { |
| 2647 | if (!(tab->select= new SQL_SELECT)) |
| 2648 | DBUG_RETURN(true); |
| 2649 | tab->select->head= tab->table; |
| 2650 | } |
| 2651 | if (!tab->select->cond) |
| 2652 | tab->select->cond= sort_table_cond; |
| 2653 | else |
| 2654 | { |
| 2655 | if (!(tab->select->cond= |
| 2656 | new (thd->mem_root) Item_cond_and(thd, |
| 2657 | tab->select->cond, |
| 2658 | sort_table_cond))) |
| 2659 | DBUG_RETURN(true); |
| 2660 | } |
| 2661 | if (tab->pre_idx_push_select_cond) |
| 2662 | { |
| 2663 | if (sort_table_cond->type() == Item::COND_ITEM) |
| 2664 | sort_table_cond= sort_table_cond->copy_andor_structure(thd); |
| 2665 | if (!(tab->pre_idx_push_select_cond= |
| 2666 | new (thd->mem_root) Item_cond_and(thd, |
| 2667 | tab->pre_idx_push_select_cond, |
| 2668 | sort_table_cond))) |
| 2669 | DBUG_RETURN(true); |
| 2670 | } |
| 2671 | if (tab->select->cond && !tab->select->cond->fixed) |
| 2672 | tab->select->cond->fix_fields(thd, 0); |
| 2673 | if (tab->pre_idx_push_select_cond && !tab->pre_idx_push_select_cond->fixed) |
| 2674 | tab->pre_idx_push_select_cond->fix_fields(thd, 0); |
| 2675 | tab->select->pre_idx_push_select_cond= tab->pre_idx_push_select_cond; |
| 2676 | tab->set_select_cond(tab->select->cond, __LINE__); |
| 2677 | tab->select_cond->top_level_item(); |
| 2678 | DBUG_EXECUTE("where" ,print_where(tab->select->cond, |
| 2679 | "select and having" , |
| 2680 | QT_ORDINARY);); |
| 2681 | |
| 2682 | having= make_cond_for_table(thd, tmp_having, ~ (table_map) 0, |
| 2683 | ~used_tables, false, false, false); |
| 2684 | DBUG_EXECUTE("where" , |
| 2685 | print_where(having, "having after sort" , QT_ORDINARY);); |
| 2686 | } |
| 2687 | |
| 2688 | DBUG_RETURN(false); |
| 2689 | } |
| 2690 | |
| 2691 | |
| 2692 | bool JOIN::add_fields_for_current_rowid(JOIN_TAB *cur, List<Item> *table_fields) |
| 2693 | { |
| 2694 | /* |
| 2695 | this will not walk into semi-join materialization nests but this is ok |
| 2696 | because we will never need to save current rowids for those. |
| 2697 | */ |
| 2698 | for (JOIN_TAB *tab=join_tab; tab < cur; tab++) |
| 2699 | { |
| 2700 | if (!tab->keep_current_rowid) |
| 2701 | continue; |
| 2702 | Item *item= new (thd->mem_root) Item_temptable_rowid(tab->table); |
| 2703 | item->fix_fields(thd, 0); |
| 2704 | table_fields->push_back(item, thd->mem_root); |
| 2705 | cur->tmp_table_param->func_count++; |
| 2706 | } |
| 2707 | return 0; |
| 2708 | } |
| 2709 | |
| 2710 | |
| 2711 | /** |
| 2712 | Set info for aggregation tables |
| 2713 | |
| 2714 | @details |
| 2715 | This function finalizes execution plan by taking following actions: |
| 2716 | .) aggregation temporary tables are created, but not instantiated |
| 2717 | (this is done during execution). |
| 2718 | JOIN_TABs for aggregation tables are set appropriately |
| 2719 | (see JOIN::create_postjoin_aggr_table). |
| 2720 | .) prepare fields lists (fields, all_fields, ref_pointer_array slices) for |
| 2721 | each required stage of execution. These fields lists are set for |
| 2722 | working tables' tabs and for the tab of last table in the join. |
| 2723 | .) info for sorting/grouping/dups removal is prepared and saved in |
| 2724 | appropriate tabs. Here is an example: |
| 2725 | |
| 2726 | @returns |
| 2727 | false - Ok |
| 2728 | true - Error |
| 2729 | */ |
| 2730 | |
| 2731 | bool JOIN::make_aggr_tables_info() |
| 2732 | { |
| 2733 | List<Item> *curr_all_fields= &all_fields; |
| 2734 | List<Item> *curr_fields_list= &fields_list; |
| 2735 | JOIN_TAB *curr_tab= join_tab + const_tables; |
| 2736 | TABLE *exec_tmp_table= NULL; |
| 2737 | bool distinct= false; |
| 2738 | bool keep_row_order= false; |
| 2739 | bool is_having_added_as_table_cond= false; |
| 2740 | DBUG_ENTER("JOIN::make_aggr_tables_info" ); |
| 2741 | |
| 2742 | const bool has_group_by= this->group; |
| 2743 | |
| 2744 | sort_and_group_aggr_tab= NULL; |
| 2745 | |
| 2746 | if (group_optimized_away) |
| 2747 | implicit_grouping= true; |
| 2748 | |
| 2749 | bool implicit_grouping_with_window_funcs= implicit_grouping && |
| 2750 | select_lex->have_window_funcs(); |
| 2751 | bool implicit_grouping_without_tables= implicit_grouping && |
| 2752 | !tables_list; |
| 2753 | |
| 2754 | /* |
| 2755 | Setup last table to provide fields and all_fields lists to the next |
| 2756 | node in the plan. |
| 2757 | */ |
| 2758 | if (join_tab && top_join_tab_count && tables_list) |
| 2759 | { |
| 2760 | join_tab[top_join_tab_count - 1].fields= &fields_list; |
| 2761 | join_tab[top_join_tab_count - 1].all_fields= &all_fields; |
| 2762 | } |
| 2763 | |
| 2764 | /* |
| 2765 | All optimization is done. Check if we can use the storage engines |
| 2766 | group by handler to evaluate the group by. |
| 2767 | Some storage engines, like spider can also do joins, group by and |
| 2768 | distinct in the engine, so we do this for all queries, not only |
| 2769 | GROUP BY queries. |
| 2770 | */ |
| 2771 | if (tables_list && !procedure) |
| 2772 | { |
| 2773 | /* |
| 2774 | At the moment we only support push down for queries where |
| 2775 | all tables are in the same storage engine |
| 2776 | */ |
| 2777 | TABLE_LIST *tbl= tables_list; |
| 2778 | handlerton *ht= tbl && tbl->table ? tbl->table->file->partition_ht() : 0; |
| 2779 | for (tbl= tbl->next_local; ht && tbl; tbl= tbl->next_local) |
| 2780 | { |
| 2781 | if (!tbl->table || tbl->table->file->partition_ht() != ht) |
| 2782 | ht= 0; |
| 2783 | } |
| 2784 | |
| 2785 | if (ht && ht->create_group_by) |
| 2786 | { |
| 2787 | /* Check if the storage engine can intercept the query */ |
| 2788 | Query query= {&all_fields, select_distinct, tables_list, conds, |
| 2789 | group_list, order ? order : group_list, having}; |
| 2790 | group_by_handler *gbh= ht->create_group_by(thd, &query); |
| 2791 | |
| 2792 | if (gbh) |
| 2793 | { |
| 2794 | if (!(pushdown_query= new (thd->mem_root) Pushdown_query(select_lex, gbh))) |
| 2795 | DBUG_RETURN(1); |
| 2796 | /* |
| 2797 | We must store rows in the tmp table if we need to do an ORDER BY |
| 2798 | or DISTINCT and the storage handler can't handle it. |
| 2799 | */ |
| 2800 | need_tmp= query.order_by || query.group_by || query.distinct; |
| 2801 | distinct= query.distinct; |
| 2802 | keep_row_order= query.order_by || query.group_by; |
| 2803 | |
| 2804 | order= query.order_by; |
| 2805 | |
| 2806 | aggr_tables++; |
| 2807 | curr_tab= join_tab + exec_join_tab_cnt(); |
| 2808 | bzero(curr_tab, sizeof(JOIN_TAB)); |
| 2809 | curr_tab->ref.key= -1; |
| 2810 | curr_tab->join= this; |
| 2811 | |
| 2812 | if (!(curr_tab->tmp_table_param= new TMP_TABLE_PARAM(tmp_table_param))) |
| 2813 | DBUG_RETURN(1); |
| 2814 | TABLE* table= create_tmp_table(thd, curr_tab->tmp_table_param, |
| 2815 | all_fields, |
| 2816 | NULL, query.distinct, |
| 2817 | TRUE, select_options, HA_POS_ERROR, |
| 2818 | &empty_clex_str, !need_tmp, |
| 2819 | query.order_by || query.group_by); |
| 2820 | if (!table) |
| 2821 | DBUG_RETURN(1); |
| 2822 | |
| 2823 | if (!(curr_tab->aggr= new (thd->mem_root) AGGR_OP(curr_tab))) |
| 2824 | DBUG_RETURN(1); |
| 2825 | curr_tab->aggr->set_write_func(::end_send); |
| 2826 | curr_tab->table= table; |
| 2827 | /* |
| 2828 | Setup reference fields, used by summary functions and group by fields, |
| 2829 | to point to the temporary table. |
| 2830 | The actual switching to the temporary tables fields for HAVING |
| 2831 | and ORDER BY is done in do_select() by calling |
| 2832 | set_items_ref_array(items1). |
| 2833 | */ |
| 2834 | init_items_ref_array(); |
| 2835 | items1= ref_ptr_array_slice(2); |
| 2836 | //items1= items0 + all_fields.elements; |
| 2837 | if (change_to_use_tmp_fields(thd, items1, |
| 2838 | tmp_fields_list1, tmp_all_fields1, |
| 2839 | fields_list.elements, all_fields)) |
| 2840 | DBUG_RETURN(1); |
| 2841 | |
| 2842 | /* Give storage engine access to temporary table */ |
| 2843 | gbh->table= table; |
| 2844 | pushdown_query->store_data_in_temp_table= need_tmp; |
| 2845 | pushdown_query->having= having; |
| 2846 | |
| 2847 | /* |
| 2848 | Group by and having is calculated by the group_by handler. |
| 2849 | Reset the group by and having |
| 2850 | */ |
| 2851 | DBUG_ASSERT(query.group_by == NULL); |
| 2852 | group= 0; group_list= 0; |
| 2853 | having= tmp_having= 0; |
| 2854 | /* |
| 2855 | Select distinct is handled by handler or by creating an unique index |
| 2856 | over all fields in the temporary table |
| 2857 | */ |
| 2858 | select_distinct= 0; |
| 2859 | order= query.order_by; |
| 2860 | tmp_table_param.field_count+= tmp_table_param.sum_func_count; |
| 2861 | tmp_table_param.sum_func_count= 0; |
| 2862 | |
| 2863 | fields= curr_fields_list; |
| 2864 | |
| 2865 | //todo: new: |
| 2866 | curr_tab->ref_array= &items1; |
| 2867 | curr_tab->all_fields= &tmp_all_fields1; |
| 2868 | curr_tab->fields= &tmp_fields_list1; |
| 2869 | |
| 2870 | DBUG_RETURN(thd->is_fatal_error); |
| 2871 | } |
| 2872 | } |
| 2873 | } |
| 2874 | |
| 2875 | |
| 2876 | /* |
| 2877 | The loose index scan access method guarantees that all grouping or |
| 2878 | duplicate row elimination (for distinct) is already performed |
| 2879 | during data retrieval, and that all MIN/MAX functions are already |
| 2880 | computed for each group. Thus all MIN/MAX functions should be |
| 2881 | treated as regular functions, and there is no need to perform |
| 2882 | grouping in the main execution loop. |
| 2883 | Notice that currently loose index scan is applicable only for |
| 2884 | single table queries, thus it is sufficient to test only the first |
| 2885 | join_tab element of the plan for its access method. |
| 2886 | */ |
| 2887 | if (join_tab && top_join_tab_count && tables_list && |
| 2888 | join_tab->is_using_loose_index_scan()) |
| 2889 | tmp_table_param.precomputed_group_by= |
| 2890 | !join_tab->is_using_agg_loose_index_scan(); |
| 2891 | |
| 2892 | group_list_for_estimates= group_list; |
| 2893 | /* Create a tmp table if distinct or if the sort is too complicated */ |
| 2894 | if (need_tmp) |
| 2895 | { |
| 2896 | aggr_tables++; |
| 2897 | curr_tab= join_tab + exec_join_tab_cnt(); |
| 2898 | bzero(curr_tab, sizeof(JOIN_TAB)); |
| 2899 | curr_tab->ref.key= -1; |
| 2900 | if (only_const_tables()) |
| 2901 | first_select= sub_select_postjoin_aggr; |
| 2902 | |
| 2903 | /* |
| 2904 | Create temporary table on first execution of this join. |
| 2905 | (Will be reused if this is a subquery that is executed several times.) |
| 2906 | */ |
| 2907 | init_items_ref_array(); |
| 2908 | |
| 2909 | ORDER *tmp_group= (ORDER *) 0; |
| 2910 | if (!simple_group && !procedure && !(test_flags & TEST_NO_KEY_GROUP)) |
| 2911 | tmp_group= group_list; |
| 2912 | |
| 2913 | tmp_table_param.hidden_field_count= |
| 2914 | all_fields.elements - fields_list.elements; |
| 2915 | |
| 2916 | distinct= select_distinct && !group_list && |
| 2917 | !select_lex->have_window_funcs(); |
| 2918 | keep_row_order= false; |
| 2919 | bool save_sum_fields= (group_list && simple_group) || |
| 2920 | implicit_grouping_with_window_funcs; |
| 2921 | if (create_postjoin_aggr_table(curr_tab, |
| 2922 | &all_fields, tmp_group, |
| 2923 | save_sum_fields, |
| 2924 | distinct, keep_row_order)) |
| 2925 | DBUG_RETURN(true); |
| 2926 | exec_tmp_table= curr_tab->table; |
| 2927 | |
| 2928 | if (exec_tmp_table->distinct) |
| 2929 | optimize_distinct(); |
| 2930 | |
| 2931 | /* Change sum_fields reference to calculated fields in tmp_table */ |
| 2932 | items1= ref_ptr_array_slice(2); |
| 2933 | if ((sort_and_group || curr_tab->table->group || |
| 2934 | tmp_table_param.precomputed_group_by) && |
| 2935 | !implicit_grouping_without_tables) |
| 2936 | { |
| 2937 | if (change_to_use_tmp_fields(thd, items1, |
| 2938 | tmp_fields_list1, tmp_all_fields1, |
| 2939 | fields_list.elements, all_fields)) |
| 2940 | DBUG_RETURN(true); |
| 2941 | } |
| 2942 | else |
| 2943 | { |
| 2944 | if (change_refs_to_tmp_fields(thd, items1, |
| 2945 | tmp_fields_list1, tmp_all_fields1, |
| 2946 | fields_list.elements, all_fields)) |
| 2947 | DBUG_RETURN(true); |
| 2948 | } |
| 2949 | curr_all_fields= &tmp_all_fields1; |
| 2950 | curr_fields_list= &tmp_fields_list1; |
| 2951 | // Need to set them now for correct group_fields setup, reset at the end. |
| 2952 | set_items_ref_array(items1); |
| 2953 | curr_tab->ref_array= &items1; |
| 2954 | curr_tab->all_fields= &tmp_all_fields1; |
| 2955 | curr_tab->fields= &tmp_fields_list1; |
| 2956 | set_postjoin_aggr_write_func(curr_tab); |
| 2957 | |
| 2958 | /* |
| 2959 | If having is not handled here, it will be checked before the row is sent |
| 2960 | to the client. |
| 2961 | */ |
| 2962 | if (tmp_having && |
| 2963 | (sort_and_group || (exec_tmp_table->distinct && !group_list) || |
| 2964 | select_lex->have_window_funcs())) |
| 2965 | { |
| 2966 | /* |
| 2967 | If there is no select distinct and there are no window functions |
| 2968 | then move the having to table conds of tmp table. |
| 2969 | NOTE : We cannot apply having after distinct or window functions |
| 2970 | If columns of having are not part of select distinct, |
| 2971 | then distinct may remove rows which can satisfy having. |
| 2972 | In the case of window functions we *must* make sure to not |
| 2973 | store any rows which don't match HAVING within the temp table, |
| 2974 | as rows will end up being used during their computation. |
| 2975 | */ |
| 2976 | if (!select_distinct && !select_lex->have_window_funcs() && |
| 2977 | add_having_as_table_cond(curr_tab)) |
| 2978 | DBUG_RETURN(true); |
| 2979 | is_having_added_as_table_cond= tmp_having != having; |
| 2980 | |
| 2981 | /* |
| 2982 | Having condition which we are not able to add as tmp table conds are |
| 2983 | kept as before. And, this will be applied before storing the rows in |
| 2984 | tmp table. |
| 2985 | */ |
| 2986 | curr_tab->having= having; |
| 2987 | having= NULL; // Already done |
| 2988 | } |
| 2989 | |
| 2990 | tmp_table_param.func_count= 0; |
| 2991 | tmp_table_param.field_count+= tmp_table_param.func_count; |
| 2992 | if (sort_and_group || curr_tab->table->group) |
| 2993 | { |
| 2994 | tmp_table_param.field_count+= tmp_table_param.sum_func_count; |
| 2995 | tmp_table_param.sum_func_count= 0; |
| 2996 | } |
| 2997 | |
| 2998 | if (exec_tmp_table->group) |
| 2999 | { // Already grouped |
| 3000 | if (!order && !no_order && !skip_sort_order) |
| 3001 | order= group_list; /* order by group */ |
| 3002 | group_list= NULL; |
| 3003 | } |
| 3004 | |
| 3005 | /* |
| 3006 | If we have different sort & group then we must sort the data by group |
| 3007 | and copy it to another tmp table |
| 3008 | This code is also used if we are using distinct something |
| 3009 | we haven't been able to store in the temporary table yet |
| 3010 | like SEC_TO_TIME(SUM(...)). |
| 3011 | */ |
| 3012 | if ((group_list && |
| 3013 | (!test_if_subpart(group_list, order) || select_distinct)) || |
| 3014 | (select_distinct && tmp_table_param.using_outer_summary_function)) |
| 3015 | { /* Must copy to another table */ |
| 3016 | DBUG_PRINT("info" ,("Creating group table" )); |
| 3017 | |
| 3018 | calc_group_buffer(this, group_list); |
| 3019 | count_field_types(select_lex, &tmp_table_param, tmp_all_fields1, |
| 3020 | select_distinct && !group_list); |
| 3021 | tmp_table_param.hidden_field_count= |
| 3022 | tmp_all_fields1.elements - tmp_fields_list1.elements; |
| 3023 | |
| 3024 | curr_tab++; |
| 3025 | aggr_tables++; |
| 3026 | bzero(curr_tab, sizeof(JOIN_TAB)); |
| 3027 | curr_tab->ref.key= -1; |
| 3028 | |
| 3029 | /* group data to new table */ |
| 3030 | /* |
| 3031 | If the access method is loose index scan then all MIN/MAX |
| 3032 | functions are precomputed, and should be treated as regular |
| 3033 | functions. See extended comment above. |
| 3034 | */ |
| 3035 | if (join_tab->is_using_loose_index_scan()) |
| 3036 | tmp_table_param.precomputed_group_by= TRUE; |
| 3037 | |
| 3038 | tmp_table_param.hidden_field_count= |
| 3039 | curr_all_fields->elements - curr_fields_list->elements; |
| 3040 | ORDER *dummy= NULL; //TODO can use table->group here also |
| 3041 | |
| 3042 | if (create_postjoin_aggr_table(curr_tab, curr_all_fields, dummy, true, |
| 3043 | distinct, keep_row_order)) |
| 3044 | DBUG_RETURN(true); |
| 3045 | |
| 3046 | if (group_list) |
| 3047 | { |
| 3048 | if (!only_const_tables()) // No need to sort a single row |
| 3049 | { |
| 3050 | if (add_sorting_to_table(curr_tab - 1, group_list)) |
| 3051 | DBUG_RETURN(true); |
| 3052 | } |
| 3053 | |
| 3054 | if (make_group_fields(this, this)) |
| 3055 | DBUG_RETURN(true); |
| 3056 | } |
| 3057 | |
| 3058 | // Setup sum funcs only when necessary, otherwise we might break info |
| 3059 | // for the first table |
| 3060 | if (group_list || tmp_table_param.sum_func_count) |
| 3061 | { |
| 3062 | if (make_sum_func_list(*curr_all_fields, *curr_fields_list, true, true)) |
| 3063 | DBUG_RETURN(true); |
| 3064 | if (prepare_sum_aggregators(sum_funcs, |
| 3065 | !join_tab->is_using_agg_loose_index_scan())) |
| 3066 | DBUG_RETURN(true); |
| 3067 | group_list= NULL; |
| 3068 | if (setup_sum_funcs(thd, sum_funcs)) |
| 3069 | DBUG_RETURN(true); |
| 3070 | } |
| 3071 | // No sum funcs anymore |
| 3072 | DBUG_ASSERT(items2.is_null()); |
| 3073 | |
| 3074 | items2= ref_ptr_array_slice(3); |
| 3075 | if (change_to_use_tmp_fields(thd, items2, |
| 3076 | tmp_fields_list2, tmp_all_fields2, |
| 3077 | fields_list.elements, tmp_all_fields1)) |
| 3078 | DBUG_RETURN(true); |
| 3079 | |
| 3080 | curr_fields_list= &tmp_fields_list2; |
| 3081 | curr_all_fields= &tmp_all_fields2; |
| 3082 | set_items_ref_array(items2); |
| 3083 | curr_tab->ref_array= &items2; |
| 3084 | curr_tab->all_fields= &tmp_all_fields2; |
| 3085 | curr_tab->fields= &tmp_fields_list2; |
| 3086 | set_postjoin_aggr_write_func(curr_tab); |
| 3087 | |
| 3088 | tmp_table_param.field_count+= tmp_table_param.sum_func_count; |
| 3089 | tmp_table_param.sum_func_count= 0; |
| 3090 | } |
| 3091 | if (curr_tab->table->distinct) |
| 3092 | select_distinct= false; /* Each row is unique */ |
| 3093 | |
| 3094 | if (select_distinct && !group_list) |
| 3095 | { |
| 3096 | if (having) |
| 3097 | { |
| 3098 | curr_tab->having= having; |
| 3099 | having->update_used_tables(); |
| 3100 | } |
| 3101 | /* |
| 3102 | We only need DISTINCT operation if the join is not degenerate. |
| 3103 | If it is, we must not request DISTINCT processing, because |
| 3104 | remove_duplicates() assumes there is a preceding computation step (and |
| 3105 | in the degenerate join, there's none) |
| 3106 | */ |
| 3107 | if (top_join_tab_count) |
| 3108 | curr_tab->distinct= true; |
| 3109 | |
| 3110 | having= NULL; |
| 3111 | select_distinct= false; |
| 3112 | } |
| 3113 | /* Clean tmp_table_param for the next tmp table. */ |
| 3114 | tmp_table_param.field_count= tmp_table_param.sum_func_count= |
| 3115 | tmp_table_param.func_count= 0; |
| 3116 | |
| 3117 | tmp_table_param.copy_field= tmp_table_param.copy_field_end=0; |
| 3118 | first_record= sort_and_group=0; |
| 3119 | |
| 3120 | if (!group_optimized_away || implicit_grouping_with_window_funcs) |
| 3121 | { |
| 3122 | group= false; |
| 3123 | } |
| 3124 | else |
| 3125 | { |
| 3126 | /* |
| 3127 | If grouping has been optimized away, a temporary table is |
| 3128 | normally not needed unless we're explicitly requested to create |
| 3129 | one (e.g. due to a SQL_BUFFER_RESULT hint or INSERT ... SELECT). |
| 3130 | |
| 3131 | In this case (grouping was optimized away), temp_table was |
| 3132 | created without a grouping expression and JOIN::exec() will not |
| 3133 | perform the necessary grouping (by the use of end_send_group() |
| 3134 | or end_write_group()) if JOIN::group is set to false. |
| 3135 | */ |
| 3136 | // the temporary table was explicitly requested |
| 3137 | DBUG_ASSERT(MY_TEST(select_options & OPTION_BUFFER_RESULT)); |
| 3138 | // the temporary table does not have a grouping expression |
| 3139 | DBUG_ASSERT(!curr_tab->table->group); |
| 3140 | } |
| 3141 | calc_group_buffer(this, group_list); |
| 3142 | count_field_types(select_lex, &tmp_table_param, *curr_all_fields, false); |
| 3143 | } |
| 3144 | |
| 3145 | if (group || |
| 3146 | (implicit_grouping && !implicit_grouping_with_window_funcs) || |
| 3147 | tmp_table_param.sum_func_count) |
| 3148 | { |
| 3149 | if (make_group_fields(this, this)) |
| 3150 | DBUG_RETURN(true); |
| 3151 | |
| 3152 | DBUG_ASSERT(items3.is_null()); |
| 3153 | |
| 3154 | if (items0.is_null()) |
| 3155 | init_items_ref_array(); |
| 3156 | items3= ref_ptr_array_slice(4); |
| 3157 | setup_copy_fields(thd, &tmp_table_param, |
| 3158 | items3, tmp_fields_list3, tmp_all_fields3, |
| 3159 | curr_fields_list->elements, *curr_all_fields); |
| 3160 | |
| 3161 | curr_fields_list= &tmp_fields_list3; |
| 3162 | curr_all_fields= &tmp_all_fields3; |
| 3163 | set_items_ref_array(items3); |
| 3164 | if (join_tab) |
| 3165 | { |
| 3166 | JOIN_TAB *last_tab= join_tab + top_join_tab_count + aggr_tables - 1; |
| 3167 | // Set grouped fields on the last table |
| 3168 | last_tab->ref_array= &items3; |
| 3169 | last_tab->all_fields= &tmp_all_fields3; |
| 3170 | last_tab->fields= &tmp_fields_list3; |
| 3171 | } |
| 3172 | if (make_sum_func_list(*curr_all_fields, *curr_fields_list, true, true)) |
| 3173 | DBUG_RETURN(true); |
| 3174 | if (prepare_sum_aggregators(sum_funcs, |
| 3175 | !join_tab || |
| 3176 | !join_tab-> is_using_agg_loose_index_scan())) |
| 3177 | DBUG_RETURN(true); |
| 3178 | if (unlikely(setup_sum_funcs(thd, sum_funcs) || thd->is_fatal_error)) |
| 3179 | DBUG_RETURN(true); |
| 3180 | } |
| 3181 | if (group_list || order) |
| 3182 | { |
| 3183 | DBUG_PRINT("info" ,("Sorting for send_result_set_metadata" )); |
| 3184 | THD_STAGE_INFO(thd, stage_sorting_result); |
| 3185 | /* If we have already done the group, add HAVING to sorted table */ |
| 3186 | if (tmp_having && !is_having_added_as_table_cond && |
| 3187 | !group_list && !sort_and_group) |
| 3188 | { |
| 3189 | if (add_having_as_table_cond(curr_tab)) |
| 3190 | DBUG_RETURN(true); |
| 3191 | } |
| 3192 | |
| 3193 | if (group) |
| 3194 | select_limit= HA_POS_ERROR; |
| 3195 | else if (!need_tmp) |
| 3196 | { |
| 3197 | /* |
| 3198 | We can abort sorting after thd->select_limit rows if there are no |
| 3199 | filter conditions for any tables after the sorted one. |
| 3200 | Filter conditions come in several forms: |
| 3201 | 1. as a condition item attached to the join_tab, or |
| 3202 | 2. as a keyuse attached to the join_tab (ref access). |
| 3203 | */ |
| 3204 | for (uint i= const_tables + 1; i < top_join_tab_count; i++) |
| 3205 | { |
| 3206 | JOIN_TAB *const tab= join_tab + i; |
| 3207 | if (tab->select_cond || // 1 |
| 3208 | (tab->keyuse && !tab->first_inner)) // 2 |
| 3209 | { |
| 3210 | /* We have to sort all rows */ |
| 3211 | select_limit= HA_POS_ERROR; |
| 3212 | break; |
| 3213 | } |
| 3214 | } |
| 3215 | } |
| 3216 | /* |
| 3217 | Here we add sorting stage for ORDER BY/GROUP BY clause, if the |
| 3218 | optimiser chose FILESORT to be faster than INDEX SCAN or there is |
| 3219 | no suitable index present. |
| 3220 | OPTION_FOUND_ROWS supersedes LIMIT and is taken into account. |
| 3221 | */ |
| 3222 | DBUG_PRINT("info" ,("Sorting for order by/group by" )); |
| 3223 | ORDER *order_arg= group_list ? group_list : order; |
| 3224 | if (top_join_tab_count + aggr_tables > const_tables && |
| 3225 | ordered_index_usage != |
| 3226 | (group_list ? ordered_index_group_by : ordered_index_order_by) && |
| 3227 | curr_tab->type != JT_CONST && |
| 3228 | curr_tab->type != JT_EQ_REF) // Don't sort 1 row |
| 3229 | { |
| 3230 | // Sort either first non-const table or the last tmp table |
| 3231 | JOIN_TAB *sort_tab= curr_tab; |
| 3232 | |
| 3233 | if (add_sorting_to_table(sort_tab, order_arg)) |
| 3234 | DBUG_RETURN(true); |
| 3235 | /* |
| 3236 | filesort_limit: Return only this many rows from filesort(). |
| 3237 | We can use select_limit_cnt only if we have no group_by and 1 table. |
| 3238 | This allows us to use Bounded_queue for queries like: |
| 3239 | "select SQL_CALC_FOUND_ROWS * from t1 order by b desc limit 1;" |
| 3240 | m_select_limit == HA_POS_ERROR (we need a full table scan) |
| 3241 | unit->select_limit_cnt == 1 (we only need one row in the result set) |
| 3242 | */ |
| 3243 | sort_tab->filesort->limit= |
| 3244 | (has_group_by || (join_tab + table_count > curr_tab + 1)) ? |
| 3245 | select_limit : unit->select_limit_cnt; |
| 3246 | } |
| 3247 | if (!only_const_tables() && |
| 3248 | !join_tab[const_tables].filesort && |
| 3249 | !(select_options & SELECT_DESCRIBE)) |
| 3250 | { |
| 3251 | /* |
| 3252 | If no IO cache exists for the first table then we are using an |
| 3253 | INDEX SCAN and no filesort. Thus we should not remove the sorted |
| 3254 | attribute on the INDEX SCAN. |
| 3255 | */ |
| 3256 | skip_sort_order= true; |
| 3257 | } |
| 3258 | } |
| 3259 | |
| 3260 | /* |
| 3261 | Window functions computation step should be attached to the last join_tab |
| 3262 | that's doing aggregation. |
| 3263 | The last join_tab reads the data from the temp. table. It also may do |
| 3264 | - sorting |
| 3265 | - duplicate value removal |
| 3266 | Both of these operations are done after window function computation step. |
| 3267 | */ |
| 3268 | curr_tab= join_tab + total_join_tab_cnt(); |
| 3269 | if (select_lex->window_funcs.elements) |
| 3270 | { |
| 3271 | if (!(curr_tab->window_funcs_step= new Window_funcs_computation)) |
| 3272 | DBUG_RETURN(true); |
| 3273 | if (curr_tab->window_funcs_step->setup(thd, &select_lex->window_funcs, |
| 3274 | curr_tab)) |
| 3275 | DBUG_RETURN(true); |
| 3276 | /* Count that we're using window functions. */ |
| 3277 | status_var_increment(thd->status_var.feature_window_functions); |
| 3278 | } |
| 3279 | if (select_lex->custom_agg_func_used()) |
| 3280 | status_var_increment(thd->status_var.feature_custom_aggregate_functions); |
| 3281 | |
| 3282 | fields= curr_fields_list; |
| 3283 | // Reset before execution |
| 3284 | set_items_ref_array(items0); |
| 3285 | if (join_tab) |
| 3286 | join_tab[exec_join_tab_cnt() + aggr_tables - 1].next_select= |
| 3287 | setup_end_select_func(this, NULL); |
| 3288 | group= has_group_by; |
| 3289 | |
| 3290 | DBUG_RETURN(false); |
| 3291 | } |
| 3292 | |
| 3293 | |
| 3294 | |
| 3295 | bool |
| 3296 | JOIN::create_postjoin_aggr_table(JOIN_TAB *tab, List<Item> *table_fields, |
| 3297 | ORDER *table_group, |
| 3298 | bool save_sum_fields, |
| 3299 | bool distinct, |
| 3300 | bool keep_row_order) |
| 3301 | { |
| 3302 | DBUG_ENTER("JOIN::create_postjoin_aggr_table" ); |
| 3303 | THD_STAGE_INFO(thd, stage_creating_tmp_table); |
| 3304 | |
| 3305 | /* |
| 3306 | Pushing LIMIT to the post-join temporary table creation is not applicable |
| 3307 | when there is ORDER BY or GROUP BY or there is no GROUP BY, but |
| 3308 | there are aggregate functions, because in all these cases we need |
| 3309 | all result rows. |
| 3310 | */ |
| 3311 | ha_rows table_rows_limit= ((order == NULL || skip_sort_order) && |
| 3312 | !table_group && |
| 3313 | !select_lex->with_sum_func) ? select_limit |
| 3314 | : HA_POS_ERROR; |
| 3315 | |
| 3316 | if (!(tab->tmp_table_param= new TMP_TABLE_PARAM(tmp_table_param))) |
| 3317 | DBUG_RETURN(true); |
| 3318 | if (tmp_table_keep_current_rowid) |
| 3319 | add_fields_for_current_rowid(tab, table_fields); |
| 3320 | tab->tmp_table_param->skip_create_table= true; |
| 3321 | TABLE* table= create_tmp_table(thd, tab->tmp_table_param, *table_fields, |
| 3322 | table_group, distinct, |
| 3323 | save_sum_fields, select_options, table_rows_limit, |
| 3324 | &empty_clex_str, true, keep_row_order); |
| 3325 | if (!table) |
| 3326 | DBUG_RETURN(true); |
| 3327 | tmp_table_param.using_outer_summary_function= |
| 3328 | tab->tmp_table_param->using_outer_summary_function; |
| 3329 | tab->join= this; |
| 3330 | DBUG_ASSERT(tab > tab->join->join_tab || !top_join_tab_count || !tables_list); |
| 3331 | if (tab > join_tab) |
| 3332 | (tab - 1)->next_select= sub_select_postjoin_aggr; |
| 3333 | if (!(tab->aggr= new (thd->mem_root) AGGR_OP(tab))) |
| 3334 | goto err; |
| 3335 | tab->table= table; |
| 3336 | table->reginfo.join_tab= tab; |
| 3337 | |
| 3338 | /* if group or order on first table, sort first */ |
| 3339 | if ((group_list && simple_group) || |
| 3340 | (implicit_grouping && select_lex->have_window_funcs())) |
| 3341 | { |
| 3342 | DBUG_PRINT("info" ,("Sorting for group" )); |
| 3343 | THD_STAGE_INFO(thd, stage_sorting_for_group); |
| 3344 | |
| 3345 | if (ordered_index_usage != ordered_index_group_by && |
| 3346 | !only_const_tables() && |
| 3347 | (join_tab + const_tables)->type != JT_CONST && // Don't sort 1 row |
| 3348 | !implicit_grouping && |
| 3349 | add_sorting_to_table(join_tab + const_tables, group_list)) |
| 3350 | goto err; |
| 3351 | |
| 3352 | if (alloc_group_fields(this, group_list)) |
| 3353 | goto err; |
| 3354 | if (make_sum_func_list(all_fields, fields_list, true)) |
| 3355 | goto err; |
| 3356 | if (prepare_sum_aggregators(sum_funcs, |
| 3357 | !(tables_list && |
| 3358 | join_tab->is_using_agg_loose_index_scan()))) |
| 3359 | goto err; |
| 3360 | if (setup_sum_funcs(thd, sum_funcs)) |
| 3361 | goto err; |
| 3362 | group_list= NULL; |
| 3363 | } |
| 3364 | else |
| 3365 | { |
| 3366 | if (make_sum_func_list(all_fields, fields_list, false)) |
| 3367 | goto err; |
| 3368 | if (prepare_sum_aggregators(sum_funcs, |
| 3369 | !join_tab->is_using_agg_loose_index_scan())) |
| 3370 | goto err; |
| 3371 | if (setup_sum_funcs(thd, sum_funcs)) |
| 3372 | goto err; |
| 3373 | |
| 3374 | if (!group_list && !table->distinct && order && simple_order) |
| 3375 | { |
| 3376 | DBUG_PRINT("info" ,("Sorting for order" )); |
| 3377 | THD_STAGE_INFO(thd, stage_sorting_for_order); |
| 3378 | |
| 3379 | if (ordered_index_usage != ordered_index_order_by && |
| 3380 | !only_const_tables() && |
| 3381 | add_sorting_to_table(join_tab + const_tables, order)) |
| 3382 | goto err; |
| 3383 | order= NULL; |
| 3384 | } |
| 3385 | } |
| 3386 | |
| 3387 | DBUG_RETURN(false); |
| 3388 | |
| 3389 | err: |
| 3390 | if (table != NULL) |
| 3391 | free_tmp_table(thd, table); |
| 3392 | DBUG_RETURN(true); |
| 3393 | } |
| 3394 | |
| 3395 | |
| 3396 | void |
| 3397 | JOIN::optimize_distinct() |
| 3398 | { |
| 3399 | for (JOIN_TAB *last_join_tab= join_tab + top_join_tab_count - 1; ;) |
| 3400 | { |
| 3401 | if (select_lex->select_list_tables & last_join_tab->table->map || |
| 3402 | last_join_tab->use_join_cache) |
| 3403 | break; |
| 3404 | last_join_tab->shortcut_for_distinct= true; |
| 3405 | if (last_join_tab == join_tab) |
| 3406 | break; |
| 3407 | --last_join_tab; |
| 3408 | } |
| 3409 | |
| 3410 | /* Optimize "select distinct b from t1 order by key_part_1 limit #" */ |
| 3411 | if (order && skip_sort_order) |
| 3412 | { |
| 3413 | /* Should already have been optimized away */ |
| 3414 | DBUG_ASSERT(ordered_index_usage == ordered_index_order_by); |
| 3415 | if (ordered_index_usage == ordered_index_order_by) |
| 3416 | { |
| 3417 | order= NULL; |
| 3418 | } |
| 3419 | } |
| 3420 | } |
| 3421 | |
| 3422 | |
| 3423 | /** |
| 3424 | @brief Add Filesort object to the given table to sort if with filesort |
| 3425 | |
| 3426 | @param tab the JOIN_TAB object to attach created Filesort object to |
| 3427 | @param order List of expressions to sort the table by |
| 3428 | |
| 3429 | @note This function moves tab->select, if any, to filesort->select |
| 3430 | |
| 3431 | @return false on success, true on OOM |
| 3432 | */ |
| 3433 | |
| 3434 | bool |
| 3435 | JOIN::add_sorting_to_table(JOIN_TAB *tab, ORDER *order) |
| 3436 | { |
| 3437 | tab->filesort= |
| 3438 | new (thd->mem_root) Filesort(order, HA_POS_ERROR, tab->keep_current_rowid, |
| 3439 | tab->select); |
| 3440 | if (!tab->filesort) |
| 3441 | return true; |
| 3442 | /* |
| 3443 | Select was moved to filesort->select to force join_init_read_record to use |
| 3444 | sorted result instead of reading table through select. |
| 3445 | */ |
| 3446 | if (tab->select) |
| 3447 | { |
| 3448 | tab->select= NULL; |
| 3449 | tab->set_select_cond(NULL, __LINE__); |
| 3450 | } |
| 3451 | tab->read_first_record= join_init_read_record; |
| 3452 | return false; |
| 3453 | } |
| 3454 | |
| 3455 | |
| 3456 | |
| 3457 | |
| 3458 | /** |
| 3459 | Setup expression caches for subqueries that need them |
| 3460 | |
| 3461 | @details |
| 3462 | The function wraps correlated subquery expressions that return one value |
| 3463 | into objects of the class Item_cache_wrapper setting up an expression |
| 3464 | cache for each of them. The result values of the subqueries are to be |
| 3465 | cached together with the corresponding sets of the parameters - outer |
| 3466 | references of the subqueries. |
| 3467 | |
| 3468 | @retval FALSE OK |
| 3469 | @retval TRUE Error |
| 3470 | */ |
| 3471 | |
| 3472 | bool JOIN::setup_subquery_caches() |
| 3473 | { |
| 3474 | DBUG_ENTER("JOIN::setup_subquery_caches" ); |
| 3475 | |
| 3476 | /* |
| 3477 | We have to check all this condition together because items created in |
| 3478 | one of this clauses can be moved to another one by optimizer |
| 3479 | */ |
| 3480 | if (select_lex->expr_cache_may_be_used[IN_WHERE] || |
| 3481 | select_lex->expr_cache_may_be_used[IN_HAVING] || |
| 3482 | select_lex->expr_cache_may_be_used[IN_ON] || |
| 3483 | select_lex->expr_cache_may_be_used[NO_MATTER]) |
| 3484 | { |
| 3485 | JOIN_TAB *tab; |
| 3486 | if (conds && |
| 3487 | !(conds= conds->transform(thd, &Item::expr_cache_insert_transformer, |
| 3488 | NULL))) |
| 3489 | DBUG_RETURN(TRUE); |
| 3490 | for (tab= first_linear_tab(this, WITH_BUSH_ROOTS, WITHOUT_CONST_TABLES); |
| 3491 | tab; tab= next_linear_tab(this, tab, WITH_BUSH_ROOTS)) |
| 3492 | { |
| 3493 | if (tab->select_cond && |
| 3494 | !(tab->select_cond= |
| 3495 | tab->select_cond->transform(thd, |
| 3496 | &Item::expr_cache_insert_transformer, |
| 3497 | NULL))) |
| 3498 | DBUG_RETURN(TRUE); |
| 3499 | if (tab->cache_select && tab->cache_select->cond) |
| 3500 | if (!(tab->cache_select->cond= |
| 3501 | tab->cache_select-> |
| 3502 | cond->transform(thd, &Item::expr_cache_insert_transformer, |
| 3503 | NULL))) |
| 3504 | DBUG_RETURN(TRUE); |
| 3505 | } |
| 3506 | |
| 3507 | if (having && |
| 3508 | !(having= having->transform(thd, |
| 3509 | &Item::expr_cache_insert_transformer, |
| 3510 | NULL))) |
| 3511 | DBUG_RETURN(TRUE); |
| 3512 | |
| 3513 | if (tmp_having) |
| 3514 | { |
| 3515 | DBUG_ASSERT(having == NULL); |
| 3516 | if (!(tmp_having= |
| 3517 | tmp_having->transform(thd, |
| 3518 | &Item::expr_cache_insert_transformer, |
| 3519 | NULL))) |
| 3520 | DBUG_RETURN(TRUE); |
| 3521 | } |
| 3522 | } |
| 3523 | if (select_lex->expr_cache_may_be_used[SELECT_LIST] || |
| 3524 | select_lex->expr_cache_may_be_used[IN_GROUP_BY] || |
| 3525 | select_lex->expr_cache_may_be_used[NO_MATTER]) |
| 3526 | { |
| 3527 | List_iterator<Item> li(all_fields); |
| 3528 | Item *item; |
| 3529 | while ((item= li++)) |
| 3530 | { |
| 3531 | Item *new_item; |
| 3532 | if (!(new_item= |
| 3533 | item->transform(thd, &Item::expr_cache_insert_transformer, |
| 3534 | NULL))) |
| 3535 | DBUG_RETURN(TRUE); |
| 3536 | if (new_item != item) |
| 3537 | { |
| 3538 | thd->change_item_tree(li.ref(), new_item); |
| 3539 | } |
| 3540 | } |
| 3541 | for (ORDER *tmp_group= group_list; tmp_group ; tmp_group= tmp_group->next) |
| 3542 | { |
| 3543 | if (!(*tmp_group->item= |
| 3544 | (*tmp_group->item)->transform(thd, |
| 3545 | &Item::expr_cache_insert_transformer, |
| 3546 | NULL))) |
| 3547 | DBUG_RETURN(TRUE); |
| 3548 | } |
| 3549 | } |
| 3550 | if (select_lex->expr_cache_may_be_used[NO_MATTER]) |
| 3551 | { |
| 3552 | for (ORDER *ord= order; ord; ord= ord->next) |
| 3553 | { |
| 3554 | if (!(*ord->item= |
| 3555 | (*ord->item)->transform(thd, |
| 3556 | &Item::expr_cache_insert_transformer, |
| 3557 | NULL))) |
| 3558 | DBUG_RETURN(TRUE); |
| 3559 | } |
| 3560 | } |
| 3561 | DBUG_RETURN(FALSE); |
| 3562 | } |
| 3563 | |
| 3564 | |
| 3565 | /* |
| 3566 | Shrink join buffers used for preceding tables to reduce the occupied space |
| 3567 | |
| 3568 | SYNOPSIS |
| 3569 | shrink_join_buffers() |
| 3570 | jt table up to which the buffers are to be shrunk |
| 3571 | curr_space the size of the space used by the buffers for tables 1..jt |
| 3572 | needed_space the size of the space that has to be used by these buffers |
| 3573 | |
| 3574 | DESCRIPTION |
| 3575 | The function makes an attempt to shrink all join buffers used for the |
| 3576 | tables starting from the first up to jt to reduce the total size of the |
| 3577 | space occupied by the buffers used for tables 1,...,jt from curr_space |
| 3578 | to needed_space. |
| 3579 | The function assumes that the buffer for the table jt has not been |
| 3580 | allocated yet. |
| 3581 | |
| 3582 | RETURN |
| 3583 | FALSE if all buffer have been successfully shrunk |
| 3584 | TRUE otherwise |
| 3585 | */ |
| 3586 | |
| 3587 | bool JOIN::shrink_join_buffers(JOIN_TAB *jt, |
| 3588 | ulonglong curr_space, |
| 3589 | ulonglong needed_space) |
| 3590 | { |
| 3591 | JOIN_TAB *tab; |
| 3592 | JOIN_CACHE *cache; |
| 3593 | for (tab= first_linear_tab(this, WITHOUT_BUSH_ROOTS, WITHOUT_CONST_TABLES); |
| 3594 | tab != jt; |
| 3595 | tab= next_linear_tab(this, tab, WITHOUT_BUSH_ROOTS)) |
| 3596 | { |
| 3597 | cache= tab->cache; |
| 3598 | if (cache) |
| 3599 | { |
| 3600 | size_t buff_size; |
| 3601 | if (needed_space < cache->get_min_join_buffer_size()) |
| 3602 | return TRUE; |
| 3603 | if (cache->shrink_join_buffer_in_ratio(curr_space, needed_space)) |
| 3604 | { |
| 3605 | revise_cache_usage(tab); |
| 3606 | return TRUE; |
| 3607 | } |
| 3608 | buff_size= cache->get_join_buffer_size(); |
| 3609 | curr_space-= buff_size; |
| 3610 | needed_space-= buff_size; |
| 3611 | } |
| 3612 | } |
| 3613 | |
| 3614 | cache= jt->cache; |
| 3615 | DBUG_ASSERT(cache); |
| 3616 | if (needed_space < cache->get_min_join_buffer_size()) |
| 3617 | return TRUE; |
| 3618 | cache->set_join_buffer_size((size_t)needed_space); |
| 3619 | |
| 3620 | return FALSE; |
| 3621 | } |
| 3622 | |
| 3623 | |
| 3624 | int |
| 3625 | JOIN::reinit() |
| 3626 | { |
| 3627 | DBUG_ENTER("JOIN::reinit" ); |
| 3628 | |
| 3629 | unit->offset_limit_cnt= (ha_rows)(select_lex->offset_limit ? |
| 3630 | select_lex->offset_limit->val_uint() : 0); |
| 3631 | |
| 3632 | first_record= false; |
| 3633 | group_sent= false; |
| 3634 | cleaned= false; |
| 3635 | |
| 3636 | if (aggr_tables) |
| 3637 | { |
| 3638 | JOIN_TAB *curr_tab= join_tab + exec_join_tab_cnt(); |
| 3639 | JOIN_TAB *end_tab= curr_tab + aggr_tables; |
| 3640 | for ( ; curr_tab < end_tab; curr_tab++) |
| 3641 | { |
| 3642 | TABLE *tmp_table= curr_tab->table; |
| 3643 | if (!tmp_table->is_created()) |
| 3644 | continue; |
| 3645 | tmp_table->file->extra(HA_EXTRA_RESET_STATE); |
| 3646 | tmp_table->file->ha_delete_all_rows(); |
| 3647 | } |
| 3648 | } |
| 3649 | clear_sj_tmp_tables(this); |
| 3650 | if (current_ref_ptrs != items0) |
| 3651 | { |
| 3652 | set_items_ref_array(items0); |
| 3653 | set_group_rpa= false; |
| 3654 | } |
| 3655 | |
| 3656 | /* need to reset ref access state (see join_read_key) */ |
| 3657 | if (join_tab) |
| 3658 | { |
| 3659 | JOIN_TAB *tab; |
| 3660 | for (tab= first_linear_tab(this, WITH_BUSH_ROOTS, WITH_CONST_TABLES); tab; |
| 3661 | tab= next_linear_tab(this, tab, WITH_BUSH_ROOTS)) |
| 3662 | { |
| 3663 | tab->ref.key_err= TRUE; |
| 3664 | } |
| 3665 | } |
| 3666 | |
| 3667 | /* Reset of sum functions */ |
| 3668 | if (sum_funcs) |
| 3669 | { |
| 3670 | Item_sum *func, **func_ptr= sum_funcs; |
| 3671 | while ((func= *(func_ptr++))) |
| 3672 | func->clear(); |
| 3673 | } |
| 3674 | |
| 3675 | if (no_rows_in_result_called) |
| 3676 | { |
| 3677 | /* Reset effect of possible no_rows_in_result() */ |
| 3678 | List_iterator_fast<Item> it(fields_list); |
| 3679 | Item *item; |
| 3680 | no_rows_in_result_called= 0; |
| 3681 | while ((item= it++)) |
| 3682 | item->restore_to_before_no_rows_in_result(); |
| 3683 | } |
| 3684 | |
| 3685 | if (!(select_options & SELECT_DESCRIBE)) |
| 3686 | if (init_ftfuncs(thd, select_lex, MY_TEST(order))) |
| 3687 | DBUG_RETURN(1); |
| 3688 | |
| 3689 | DBUG_RETURN(0); |
| 3690 | } |
| 3691 | |
| 3692 | |
| 3693 | /** |
| 3694 | Prepare join result. |
| 3695 | |
| 3696 | @details Prepare join result prior to join execution or describing. |
| 3697 | Instantiate derived tables and get schema tables result if necessary. |
| 3698 | |
| 3699 | @return |
| 3700 | TRUE An error during derived or schema tables instantiation. |
| 3701 | FALSE Ok |
| 3702 | */ |
| 3703 | |
| 3704 | bool JOIN::prepare_result(List<Item> **columns_list) |
| 3705 | { |
| 3706 | DBUG_ENTER("JOIN::prepare_result" ); |
| 3707 | |
| 3708 | error= 0; |
| 3709 | /* Create result tables for materialized views. */ |
| 3710 | if (!zero_result_cause && |
| 3711 | select_lex->handle_derived(thd->lex, DT_CREATE)) |
| 3712 | goto err; |
| 3713 | |
| 3714 | if (result->prepare2(this)) |
| 3715 | goto err; |
| 3716 | |
| 3717 | if ((select_lex->options & OPTION_SCHEMA_TABLE) && |
| 3718 | get_schema_tables_result(this, PROCESSED_BY_JOIN_EXEC)) |
| 3719 | goto err; |
| 3720 | |
| 3721 | DBUG_RETURN(FALSE); |
| 3722 | |
| 3723 | err: |
| 3724 | error= 1; |
| 3725 | DBUG_RETURN(TRUE); |
| 3726 | } |
| 3727 | |
| 3728 | |
| 3729 | /** |
| 3730 | @retval |
| 3731 | 0 ok |
| 3732 | 1 error |
| 3733 | */ |
| 3734 | |
| 3735 | |
| 3736 | bool JOIN::save_explain_data(Explain_query *output, bool can_overwrite, |
| 3737 | bool need_tmp_table, bool need_order, |
| 3738 | bool distinct) |
| 3739 | { |
| 3740 | /* |
| 3741 | If there is SELECT in this statement with the same number it must be the |
| 3742 | same SELECT |
| 3743 | */ |
| 3744 | DBUG_ASSERT(select_lex->select_number == UINT_MAX || |
| 3745 | select_lex->select_number == INT_MAX || |
| 3746 | !output || |
| 3747 | !output->get_select(select_lex->select_number) || |
| 3748 | output->get_select(select_lex->select_number)->select_lex == |
| 3749 | select_lex); |
| 3750 | |
| 3751 | if (select_lex->select_number != UINT_MAX && |
| 3752 | select_lex->select_number != INT_MAX /* this is not a UNION's "fake select */ && |
| 3753 | have_query_plan != JOIN::QEP_NOT_PRESENT_YET && |
| 3754 | have_query_plan != JOIN::QEP_DELETED && // this happens when there was |
| 3755 | // no QEP ever, but then |
| 3756 | //cleanup() is called multiple times |
| 3757 | output && // for "SET" command in SPs. |
| 3758 | (can_overwrite? true: !output->get_select(select_lex->select_number))) |
| 3759 | { |
| 3760 | const char *message= NULL; |
| 3761 | if (!table_count || !tables_list || zero_result_cause) |
| 3762 | { |
| 3763 | /* It's a degenerate join */ |
| 3764 | message= zero_result_cause ? zero_result_cause : "No tables used" ; |
| 3765 | } |
| 3766 | return save_explain_data_intern(thd->lex->explain, need_tmp_table, need_order, |
| 3767 | distinct, message); |
| 3768 | } |
| 3769 | |
| 3770 | /* |
| 3771 | Can have join_tab==NULL for degenerate cases (e.g. SELECT .. UNION ... SELECT LIMIT 0) |
| 3772 | */ |
| 3773 | if (select_lex == select_lex->master_unit()->fake_select_lex && join_tab) |
| 3774 | { |
| 3775 | /* |
| 3776 | This is fake_select_lex. It has no query plan, but we need to set up a |
| 3777 | tracker for ANALYZE |
| 3778 | */ |
| 3779 | uint nr= select_lex->master_unit()->first_select()->select_number; |
| 3780 | Explain_union *eu= output->get_union(nr); |
| 3781 | explain= &eu->fake_select_lex_explain; |
| 3782 | join_tab[0].tracker= eu->get_fake_select_lex_tracker(); |
| 3783 | for (uint i=0 ; i < exec_join_tab_cnt() + aggr_tables; i++) |
| 3784 | { |
| 3785 | if (join_tab[i].filesort) |
| 3786 | { |
| 3787 | if (!(join_tab[i].filesort->tracker= |
| 3788 | new Filesort_tracker(thd->lex->analyze_stmt))) |
| 3789 | return 1; |
| 3790 | } |
| 3791 | } |
| 3792 | } |
| 3793 | return 0; |
| 3794 | } |
| 3795 | |
| 3796 | |
| 3797 | void JOIN::exec() |
| 3798 | { |
| 3799 | DBUG_EXECUTE_IF("show_explain_probe_join_exec_start" , |
| 3800 | if (dbug_user_var_equals_int(thd, |
| 3801 | "show_explain_probe_select_id" , |
| 3802 | select_lex->select_number)) |
| 3803 | dbug_serve_apcs(thd, 1); |
| 3804 | ); |
| 3805 | ANALYZE_START_TRACKING(&explain->time_tracker); |
| 3806 | exec_inner(); |
| 3807 | ANALYZE_STOP_TRACKING(&explain->time_tracker); |
| 3808 | |
| 3809 | DBUG_EXECUTE_IF("show_explain_probe_join_exec_end" , |
| 3810 | if (dbug_user_var_equals_int(thd, |
| 3811 | "show_explain_probe_select_id" , |
| 3812 | select_lex->select_number)) |
| 3813 | dbug_serve_apcs(thd, 1); |
| 3814 | ); |
| 3815 | } |
| 3816 | |
| 3817 | |
| 3818 | void JOIN::exec_inner() |
| 3819 | { |
| 3820 | List<Item> *columns_list= &fields_list; |
| 3821 | DBUG_ENTER("JOIN::exec_inner" ); |
| 3822 | DBUG_ASSERT(optimization_state == JOIN::OPTIMIZATION_DONE); |
| 3823 | |
| 3824 | THD_STAGE_INFO(thd, stage_executing); |
| 3825 | |
| 3826 | /* |
| 3827 | Enable LIMIT ROWS EXAMINED during query execution if: |
| 3828 | (1) This JOIN is the outermost query (not a subquery or derived table) |
| 3829 | This ensures that the limit is enabled when actual execution begins, and |
| 3830 | not if a subquery is evaluated during optimization of the outer query. |
| 3831 | (2) This JOIN is not the result of a UNION. In this case do not apply the |
| 3832 | limit in order to produce the partial query result stored in the |
| 3833 | UNION temp table. |
| 3834 | */ |
| 3835 | if (!select_lex->outer_select() && // (1) |
| 3836 | select_lex != select_lex->master_unit()->fake_select_lex) // (2) |
| 3837 | thd->lex->set_limit_rows_examined(); |
| 3838 | |
| 3839 | if (procedure) |
| 3840 | { |
| 3841 | procedure_fields_list= fields_list; |
| 3842 | if (procedure->change_columns(thd, procedure_fields_list) || |
| 3843 | result->prepare(procedure_fields_list, unit)) |
| 3844 | { |
| 3845 | thd->set_examined_row_count(0); |
| 3846 | thd->limit_found_rows= 0; |
| 3847 | DBUG_VOID_RETURN; |
| 3848 | } |
| 3849 | columns_list= &procedure_fields_list; |
| 3850 | } |
| 3851 | if (result->prepare2(this)) |
| 3852 | DBUG_VOID_RETURN; |
| 3853 | |
| 3854 | if (!tables_list && (table_count || !select_lex->with_sum_func) && |
| 3855 | !select_lex->have_window_funcs()) |
| 3856 | { // Only test of functions |
| 3857 | if (select_options & SELECT_DESCRIBE) |
| 3858 | select_describe(this, FALSE, FALSE, FALSE, |
| 3859 | (zero_result_cause?zero_result_cause:"No tables used" )); |
| 3860 | |
| 3861 | else |
| 3862 | { |
| 3863 | if (result->send_result_set_metadata(*columns_list, |
| 3864 | Protocol::SEND_NUM_ROWS | |
| 3865 | Protocol::SEND_EOF)) |
| 3866 | { |
| 3867 | DBUG_VOID_RETURN; |
| 3868 | } |
| 3869 | |
| 3870 | /* |
| 3871 | We have to test for 'conds' here as the WHERE may not be constant |
| 3872 | even if we don't have any tables for prepared statements or if |
| 3873 | conds uses something like 'rand()'. |
| 3874 | If the HAVING clause is either impossible or always true, then |
| 3875 | JOIN::having is set to NULL by optimize_cond. |
| 3876 | In this case JOIN::exec must check for JOIN::having_value, in the |
| 3877 | same way it checks for JOIN::cond_value. |
| 3878 | */ |
| 3879 | DBUG_ASSERT(error == 0); |
| 3880 | if (cond_value != Item::COND_FALSE && |
| 3881 | having_value != Item::COND_FALSE && |
| 3882 | (!conds || conds->val_int()) && |
| 3883 | (!having || having->val_int())) |
| 3884 | { |
| 3885 | if (do_send_rows && |
| 3886 | (procedure ? (procedure->send_row(procedure_fields_list) || |
| 3887 | procedure->end_of_records()) : result->send_data(fields_list)> 0)) |
| 3888 | error= 1; |
| 3889 | else |
| 3890 | send_records= ((select_options & OPTION_FOUND_ROWS) ? 1 : |
| 3891 | thd->get_sent_row_count()); |
| 3892 | } |
| 3893 | else |
| 3894 | send_records= 0; |
| 3895 | if (likely(!error)) |
| 3896 | { |
| 3897 | join_free(); // Unlock all cursors |
| 3898 | error= (int) result->send_eof(); |
| 3899 | } |
| 3900 | } |
| 3901 | /* Single select (without union) always returns 0 or 1 row */ |
| 3902 | thd->limit_found_rows= send_records; |
| 3903 | thd->set_examined_row_count(0); |
| 3904 | DBUG_VOID_RETURN; |
| 3905 | } |
| 3906 | |
| 3907 | /* |
| 3908 | Evaluate expensive constant conditions that were not evaluated during |
| 3909 | optimization. Do not evaluate them for EXPLAIN statements as these |
| 3910 | condtions may be arbitrarily costly, and because the optimize phase |
| 3911 | might not have produced a complete executable plan for EXPLAINs. |
| 3912 | */ |
| 3913 | if (!zero_result_cause && |
| 3914 | exec_const_cond && !(select_options & SELECT_DESCRIBE) && |
| 3915 | !exec_const_cond->val_int()) |
| 3916 | zero_result_cause= "Impossible WHERE noticed after reading const tables" ; |
| 3917 | |
| 3918 | /* |
| 3919 | We've called exec_const_cond->val_int(). This may have caused an error. |
| 3920 | */ |
| 3921 | if (unlikely(thd->is_error())) |
| 3922 | { |
| 3923 | error= thd->is_error(); |
| 3924 | DBUG_VOID_RETURN; |
| 3925 | } |
| 3926 | |
| 3927 | if (zero_result_cause) |
| 3928 | { |
| 3929 | if (select_lex->have_window_funcs() && send_row_on_empty_set()) |
| 3930 | { |
| 3931 | /* |
| 3932 | The query produces just one row but it has window functions. |
| 3933 | |
| 3934 | The only way to compute the value of window function(s) is to |
| 3935 | run the entire window function computation step (there is no shortcut). |
| 3936 | */ |
| 3937 | const_tables= table_count; |
| 3938 | first_select= sub_select_postjoin_aggr; |
| 3939 | } |
| 3940 | else |
| 3941 | { |
| 3942 | (void) return_zero_rows(this, result, select_lex->leaf_tables, |
| 3943 | *columns_list, |
| 3944 | send_row_on_empty_set(), |
| 3945 | select_options, |
| 3946 | zero_result_cause, |
| 3947 | having ? having : tmp_having, all_fields); |
| 3948 | DBUG_VOID_RETURN; |
| 3949 | } |
| 3950 | } |
| 3951 | |
| 3952 | /* |
| 3953 | Evaluate all constant expressions with subqueries in the |
| 3954 | ORDER/GROUP clauses to make sure that all subqueries return a |
| 3955 | single row. The evaluation itself will trigger an error if that is |
| 3956 | not the case. |
| 3957 | */ |
| 3958 | if (exec_const_order_group_cond.elements && |
| 3959 | !(select_options & SELECT_DESCRIBE)) |
| 3960 | { |
| 3961 | List_iterator_fast<Item> const_item_it(exec_const_order_group_cond); |
| 3962 | Item *cur_const_item; |
| 3963 | while ((cur_const_item= const_item_it++)) |
| 3964 | { |
| 3965 | cur_const_item->val_str(); // This caches val_str() to Item::str_value |
| 3966 | if (unlikely(thd->is_error())) |
| 3967 | { |
| 3968 | error= thd->is_error(); |
| 3969 | DBUG_VOID_RETURN; |
| 3970 | } |
| 3971 | } |
| 3972 | } |
| 3973 | |
| 3974 | if ((this->select_lex->options & OPTION_SCHEMA_TABLE) && |
| 3975 | get_schema_tables_result(this, PROCESSED_BY_JOIN_EXEC)) |
| 3976 | DBUG_VOID_RETURN; |
| 3977 | |
| 3978 | if (select_options & SELECT_DESCRIBE) |
| 3979 | { |
| 3980 | select_describe(this, need_tmp, |
| 3981 | order != 0 && !skip_sort_order, |
| 3982 | select_distinct, |
| 3983 | !table_count ? "No tables used" : NullS); |
| 3984 | DBUG_VOID_RETURN; |
| 3985 | } |
| 3986 | else |
| 3987 | { |
| 3988 | /* it's a const select, materialize it. */ |
| 3989 | select_lex->mark_const_derived(zero_result_cause); |
| 3990 | } |
| 3991 | |
| 3992 | /* |
| 3993 | Initialize examined rows here because the values from all join parts |
| 3994 | must be accumulated in examined_row_count. Hence every join |
| 3995 | iteration must count from zero. |
| 3996 | */ |
| 3997 | join_examined_rows= 0; |
| 3998 | |
| 3999 | /* XXX: When can we have here thd->is_error() not zero? */ |
| 4000 | if (unlikely(thd->is_error())) |
| 4001 | { |
| 4002 | error= thd->is_error(); |
| 4003 | DBUG_VOID_RETURN; |
| 4004 | } |
| 4005 | |
| 4006 | THD_STAGE_INFO(thd, stage_sending_data); |
| 4007 | DBUG_PRINT("info" , ("%s" , thd->proc_info)); |
| 4008 | result->send_result_set_metadata( |
| 4009 | procedure ? procedure_fields_list : *fields, |
| 4010 | Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF); |
| 4011 | |
| 4012 | error= do_select(this, procedure); |
| 4013 | /* Accumulate the counts from all join iterations of all join parts. */ |
| 4014 | thd->inc_examined_row_count(join_examined_rows); |
| 4015 | DBUG_PRINT("counts" , ("thd->examined_row_count: %lu" , |
| 4016 | (ulong) thd->get_examined_row_count())); |
| 4017 | |
| 4018 | DBUG_VOID_RETURN; |
| 4019 | } |
| 4020 | |
| 4021 | |
| 4022 | /** |
| 4023 | Clean up join. |
| 4024 | |
| 4025 | @return |
| 4026 | Return error that hold JOIN. |
| 4027 | */ |
| 4028 | |
| 4029 | int |
| 4030 | JOIN::destroy() |
| 4031 | { |
| 4032 | DBUG_ENTER("JOIN::destroy" ); |
| 4033 | select_lex->join= 0; |
| 4034 | |
| 4035 | cond_equal= 0; |
| 4036 | having_equal= 0; |
| 4037 | |
| 4038 | cleanup(1); |
| 4039 | |
| 4040 | if (join_tab) |
| 4041 | { |
| 4042 | for (JOIN_TAB *tab= first_linear_tab(this, WITH_BUSH_ROOTS, |
| 4043 | WITH_CONST_TABLES); |
| 4044 | tab; tab= next_linear_tab(this, tab, WITH_BUSH_ROOTS)) |
| 4045 | { |
| 4046 | if (tab->aggr) |
| 4047 | { |
| 4048 | free_tmp_table(thd, tab->table); |
| 4049 | delete tab->tmp_table_param; |
| 4050 | tab->tmp_table_param= NULL; |
| 4051 | tab->aggr= NULL; |
| 4052 | } |
| 4053 | tab->table= NULL; |
| 4054 | } |
| 4055 | } |
| 4056 | |
| 4057 | /* Cleanup items referencing temporary table columns */ |
| 4058 | cleanup_item_list(tmp_all_fields1); |
| 4059 | cleanup_item_list(tmp_all_fields3); |
| 4060 | destroy_sj_tmp_tables(this); |
| 4061 | delete_dynamic(&keyuse); |
| 4062 | if (save_qep) |
| 4063 | delete(save_qep); |
| 4064 | if (ext_keyuses_for_splitting) |
| 4065 | delete(ext_keyuses_for_splitting); |
| 4066 | delete procedure; |
| 4067 | DBUG_RETURN(error); |
| 4068 | } |
| 4069 | |
| 4070 | |
| 4071 | void JOIN::cleanup_item_list(List<Item> &items) const |
| 4072 | { |
| 4073 | DBUG_ENTER("JOIN::cleanup_item_list" ); |
| 4074 | if (!items.is_empty()) |
| 4075 | { |
| 4076 | List_iterator_fast<Item> it(items); |
| 4077 | Item *item; |
| 4078 | while ((item= it++)) |
| 4079 | item->cleanup(); |
| 4080 | } |
| 4081 | DBUG_VOID_RETURN; |
| 4082 | } |
| 4083 | |
| 4084 | |
| 4085 | /** |
| 4086 | An entry point to single-unit select (a select without UNION). |
| 4087 | |
| 4088 | @param thd thread handler |
| 4089 | @param rref_pointer_array a reference to ref_pointer_array of |
| 4090 | the top-level select_lex for this query |
| 4091 | @param tables list of all tables used in this query. |
| 4092 | The tables have been pre-opened. |
| 4093 | @param wild_num number of wildcards used in the top level |
| 4094 | select of this query. |
| 4095 | For example statement |
| 4096 | SELECT *, t1.*, catalog.t2.* FROM t0, t1, t2; |
| 4097 | has 3 wildcards. |
| 4098 | @param fields list of items in SELECT list of the top-level |
| 4099 | select |
| 4100 | e.g. SELECT a, b, c FROM t1 will have Item_field |
| 4101 | for a, b and c in this list. |
| 4102 | @param conds top level item of an expression representing |
| 4103 | WHERE clause of the top level select |
| 4104 | @param og_num total number of ORDER BY and GROUP BY clauses |
| 4105 | arguments |
| 4106 | @param order linked list of ORDER BY agruments |
| 4107 | @param group linked list of GROUP BY arguments |
| 4108 | @param having top level item of HAVING expression |
| 4109 | @param proc_param list of PROCEDUREs |
| 4110 | @param select_options select options (BIG_RESULT, etc) |
| 4111 | @param result an instance of result set handling class. |
| 4112 | This object is responsible for send result |
| 4113 | set rows to the client or inserting them |
| 4114 | into a table. |
| 4115 | @param select_lex the only SELECT_LEX of this query |
| 4116 | @param unit top-level UNIT of this query |
| 4117 | UNIT is an artificial object created by the |
| 4118 | parser for every SELECT clause. |
| 4119 | e.g. |
| 4120 | SELECT * FROM t1 WHERE a1 IN (SELECT * FROM t2) |
| 4121 | has 2 unions. |
| 4122 | |
| 4123 | @retval |
| 4124 | FALSE success |
| 4125 | @retval |
| 4126 | TRUE an error |
| 4127 | */ |
| 4128 | |
| 4129 | bool |
| 4130 | mysql_select(THD *thd, |
| 4131 | TABLE_LIST *tables, uint wild_num, List<Item> &fields, |
| 4132 | COND *conds, uint og_num, ORDER *order, ORDER *group, |
| 4133 | Item *having, ORDER *proc_param, ulonglong select_options, |
| 4134 | select_result *result, SELECT_LEX_UNIT *unit, |
| 4135 | SELECT_LEX *select_lex) |
| 4136 | { |
| 4137 | int err= 0; |
| 4138 | bool free_join= 1; |
| 4139 | DBUG_ENTER("mysql_select" ); |
| 4140 | |
| 4141 | select_lex->context.resolve_in_select_list= TRUE; |
| 4142 | JOIN *join; |
| 4143 | if (select_lex->join != 0) |
| 4144 | { |
| 4145 | join= select_lex->join; |
| 4146 | /* |
| 4147 | is it single SELECT in derived table, called in derived table |
| 4148 | creation |
| 4149 | */ |
| 4150 | if (select_lex->linkage != DERIVED_TABLE_TYPE || |
| 4151 | (select_options & SELECT_DESCRIBE)) |
| 4152 | { |
| 4153 | if (select_lex->linkage != GLOBAL_OPTIONS_TYPE) |
| 4154 | { |
| 4155 | /* |
| 4156 | Original join tabs might be overwritten at first |
| 4157 | subselect execution. So we need to restore them. |
| 4158 | */ |
| 4159 | Item_subselect *subselect= select_lex->master_unit()->item; |
| 4160 | if (subselect && subselect->is_uncacheable() && join->reinit()) |
| 4161 | DBUG_RETURN(TRUE); |
| 4162 | } |
| 4163 | else |
| 4164 | { |
| 4165 | if ((err= join->prepare( tables, wild_num, |
| 4166 | conds, og_num, order, false, group, having, |
| 4167 | proc_param, select_lex, unit))) |
| 4168 | { |
| 4169 | goto err; |
| 4170 | } |
| 4171 | } |
| 4172 | } |
| 4173 | free_join= 0; |
| 4174 | join->select_options= select_options; |
| 4175 | } |
| 4176 | else |
| 4177 | { |
| 4178 | /* |
| 4179 | When in EXPLAIN, delay deleting the joins so that they are still |
| 4180 | available when we're producing EXPLAIN EXTENDED warning text. |
| 4181 | */ |
| 4182 | if (select_options & SELECT_DESCRIBE) |
| 4183 | free_join= 0; |
| 4184 | |
| 4185 | if (!(join= new (thd->mem_root) JOIN(thd, fields, select_options, result))) |
| 4186 | DBUG_RETURN(TRUE); |
| 4187 | THD_STAGE_INFO(thd, stage_init); |
| 4188 | thd->lex->used_tables=0; |
| 4189 | if ((err= join->prepare(tables, wild_num, |
| 4190 | conds, og_num, order, false, group, having, proc_param, |
| 4191 | select_lex, unit))) |
| 4192 | { |
| 4193 | goto err; |
| 4194 | } |
| 4195 | } |
| 4196 | |
| 4197 | if ((err= join->optimize())) |
| 4198 | { |
| 4199 | goto err; // 1 |
| 4200 | } |
| 4201 | |
| 4202 | if (thd->lex->describe & DESCRIBE_EXTENDED) |
| 4203 | { |
| 4204 | join->conds_history= join->conds; |
| 4205 | join->having_history= (join->having?join->having:join->tmp_having); |
| 4206 | } |
| 4207 | |
| 4208 | if (unlikely(thd->is_error())) |
| 4209 | goto err; |
| 4210 | |
| 4211 | join->exec(); |
| 4212 | |
| 4213 | if (thd->lex->describe & DESCRIBE_EXTENDED) |
| 4214 | { |
| 4215 | select_lex->where= join->conds_history; |
| 4216 | select_lex->having= join->having_history; |
| 4217 | } |
| 4218 | |
| 4219 | err: |
| 4220 | if (free_join) |
| 4221 | { |
| 4222 | THD_STAGE_INFO(thd, stage_end); |
| 4223 | err|= (int)(select_lex->cleanup()); |
| 4224 | DBUG_RETURN(err || thd->is_error()); |
| 4225 | } |
| 4226 | DBUG_RETURN(join->error ? join->error: err); |
| 4227 | } |
| 4228 | |
| 4229 | |
| 4230 | /***************************************************************************** |
| 4231 | Create JOIN_TABS, make a guess about the table types, |
| 4232 | Approximate how many records will be used in each table |
| 4233 | *****************************************************************************/ |
| 4234 | |
| 4235 | static ha_rows get_quick_record_count(THD *thd, SQL_SELECT *select, |
| 4236 | TABLE *table, |
| 4237 | const key_map *keys,ha_rows limit) |
| 4238 | { |
| 4239 | int error; |
| 4240 | DBUG_ENTER("get_quick_record_count" ); |
| 4241 | uchar buff[STACK_BUFF_ALLOC]; |
| 4242 | if (unlikely(check_stack_overrun(thd, STACK_MIN_SIZE, buff))) |
| 4243 | DBUG_RETURN(0); // Fatal error flag is set |
| 4244 | if (select) |
| 4245 | { |
| 4246 | select->head=table; |
| 4247 | table->reginfo.impossible_range=0; |
| 4248 | if (likely((error= |
| 4249 | select->test_quick_select(thd, *(key_map *)keys, |
| 4250 | (table_map) 0, |
| 4251 | limit, 0, FALSE, |
| 4252 | TRUE /* remove_where_parts*/)) == |
| 4253 | 1)) |
| 4254 | DBUG_RETURN(select->quick->records); |
| 4255 | if (unlikely(error == -1)) |
| 4256 | { |
| 4257 | table->reginfo.impossible_range=1; |
| 4258 | DBUG_RETURN(0); |
| 4259 | } |
| 4260 | DBUG_PRINT("warning" ,("Couldn't use record count on const keypart" )); |
| 4261 | } |
| 4262 | DBUG_RETURN(HA_POS_ERROR); /* This shouldn't happend */ |
| 4263 | } |
| 4264 | |
| 4265 | /* |
| 4266 | This structure is used to collect info on potentially sargable |
| 4267 | predicates in order to check whether they become sargable after |
| 4268 | reading const tables. |
| 4269 | We form a bitmap of indexes that can be used for sargable predicates. |
| 4270 | Only such indexes are involved in range analysis. |
| 4271 | */ |
| 4272 | struct SARGABLE_PARAM |
| 4273 | { |
| 4274 | Field *field; /* field against which to check sargability */ |
| 4275 | Item **arg_value; /* values of potential keys for lookups */ |
| 4276 | uint num_values; /* number of values in the above array */ |
| 4277 | }; |
| 4278 | |
| 4279 | |
| 4280 | /** |
| 4281 | Calculate the best possible join and initialize the join structure. |
| 4282 | |
| 4283 | @retval |
| 4284 | 0 ok |
| 4285 | @retval |
| 4286 | 1 Fatal error |
| 4287 | */ |
| 4288 | |
| 4289 | static bool |
| 4290 | make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list, |
| 4291 | DYNAMIC_ARRAY *keyuse_array) |
| 4292 | { |
| 4293 | int error= 0; |
| 4294 | TABLE *UNINIT_VAR(table); /* inited in all loops */ |
| 4295 | uint i,table_count,const_count,key; |
| 4296 | table_map found_const_table_map, all_table_map, found_ref, refs; |
| 4297 | key_map const_ref, eq_part; |
| 4298 | bool has_expensive_keyparts; |
| 4299 | TABLE **table_vector; |
| 4300 | JOIN_TAB *stat,*stat_end,*s,**stat_ref, **stat_vector; |
| 4301 | KEYUSE *keyuse,*start_keyuse; |
| 4302 | table_map outer_join=0; |
| 4303 | table_map no_rows_const_tables= 0; |
| 4304 | SARGABLE_PARAM *sargables= 0; |
| 4305 | List_iterator<TABLE_LIST> ti(tables_list); |
| 4306 | TABLE_LIST *tables; |
| 4307 | DBUG_ENTER("make_join_statistics" ); |
| 4308 | |
| 4309 | table_count=join->table_count; |
| 4310 | |
| 4311 | /* |
| 4312 | best_positions is ok to allocate with alloc() as we copy things to it with |
| 4313 | memcpy() |
| 4314 | */ |
| 4315 | |
| 4316 | if (!multi_alloc_root(join->thd->mem_root, |
| 4317 | &stat, sizeof(JOIN_TAB)*(table_count), |
| 4318 | &stat_ref, sizeof(JOIN_TAB*)* MAX_TABLES, |
| 4319 | &stat_vector, sizeof(JOIN_TAB*)* (table_count +1), |
| 4320 | &table_vector, sizeof(TABLE*)*(table_count*2), |
| 4321 | &join->positions, sizeof(POSITION)*(table_count + 1), |
| 4322 | &join->best_positions, |
| 4323 | sizeof(POSITION)*(table_count + 1), |
| 4324 | NullS)) |
| 4325 | DBUG_RETURN(1); |
| 4326 | |
| 4327 | /* The following should be optimized to only clear critical things */ |
| 4328 | bzero(stat, sizeof(JOIN_TAB)* table_count); |
| 4329 | /* Initialize POSITION objects */ |
| 4330 | for (i=0 ; i <= table_count ; i++) |
| 4331 | (void) new ((char*) (join->positions + i)) POSITION; |
| 4332 | |
| 4333 | join->best_ref= stat_vector; |
| 4334 | |
| 4335 | stat_end=stat+table_count; |
| 4336 | found_const_table_map= all_table_map=0; |
| 4337 | const_count=0; |
| 4338 | |
| 4339 | for (s= stat, i= 0; (tables= ti++); s++, i++) |
| 4340 | { |
| 4341 | TABLE_LIST *embedding= tables->embedding; |
| 4342 | stat_vector[i]=s; |
| 4343 | s->keys.init(); |
| 4344 | s->const_keys.init(); |
| 4345 | s->checked_keys.init(); |
| 4346 | s->needed_reg.init(); |
| 4347 | table_vector[i]=s->table=table=tables->table; |
| 4348 | s->tab_list= tables; |
| 4349 | table->pos_in_table_list= tables; |
| 4350 | error= tables->fetch_number_of_rows(); |
| 4351 | set_statistics_for_table(join->thd, table); |
| 4352 | bitmap_clear_all(&table->cond_set); |
| 4353 | |
| 4354 | #ifdef WITH_PARTITION_STORAGE_ENGINE |
| 4355 | const bool all_partitions_pruned_away= table->all_partitions_pruned_away; |
| 4356 | #else |
| 4357 | const bool all_partitions_pruned_away= FALSE; |
| 4358 | #endif |
| 4359 | |
| 4360 | DBUG_EXECUTE_IF("bug11747970_raise_error" , |
| 4361 | { join->thd->set_killed(KILL_QUERY_HARD); }); |
| 4362 | if (unlikely(error)) |
| 4363 | { |
| 4364 | table->file->print_error(error, MYF(0)); |
| 4365 | goto error; |
| 4366 | } |
| 4367 | table->quick_keys.clear_all(); |
| 4368 | table->intersect_keys.clear_all(); |
| 4369 | table->reginfo.join_tab=s; |
| 4370 | table->reginfo.not_exists_optimize=0; |
| 4371 | bzero((char*) table->const_key_parts, sizeof(key_part_map)*table->s->keys); |
| 4372 | all_table_map|= table->map; |
| 4373 | s->preread_init_done= FALSE; |
| 4374 | s->join=join; |
| 4375 | |
| 4376 | s->dependent= tables->dep_tables; |
| 4377 | if (tables->schema_table) |
| 4378 | table->file->stats.records= table->used_stat_records= 2; |
| 4379 | table->quick_condition_rows= table->stat_records(); |
| 4380 | |
| 4381 | s->on_expr_ref= &tables->on_expr; |
| 4382 | if (*s->on_expr_ref) |
| 4383 | { |
| 4384 | /* s is the only inner table of an outer join */ |
| 4385 | if (!table->is_filled_at_execution() && |
| 4386 | ((!table->file->stats.records && |
| 4387 | (table->file->ha_table_flags() & HA_STATS_RECORDS_IS_EXACT)) || |
| 4388 | all_partitions_pruned_away) && !embedding) |
| 4389 | { // Empty table |
| 4390 | s->dependent= 0; // Ignore LEFT JOIN depend. |
| 4391 | no_rows_const_tables |= table->map; |
| 4392 | set_position(join,const_count++,s,(KEYUSE*) 0); |
| 4393 | continue; |
| 4394 | } |
| 4395 | outer_join|= table->map; |
| 4396 | s->embedding_map= 0; |
| 4397 | for (;embedding; embedding= embedding->embedding) |
| 4398 | s->embedding_map|= embedding->nested_join->nj_map; |
| 4399 | continue; |
| 4400 | } |
| 4401 | if (embedding) |
| 4402 | { |
| 4403 | /* s belongs to a nested join, maybe to several embedded joins */ |
| 4404 | s->embedding_map= 0; |
| 4405 | bool inside_an_outer_join= FALSE; |
| 4406 | do |
| 4407 | { |
| 4408 | /* |
| 4409 | If this is a semi-join nest, skip it, and proceed upwards. Maybe |
| 4410 | we're in some outer join nest |
| 4411 | */ |
| 4412 | if (embedding->sj_on_expr) |
| 4413 | { |
| 4414 | embedding= embedding->embedding; |
| 4415 | continue; |
| 4416 | } |
| 4417 | inside_an_outer_join= TRUE; |
| 4418 | NESTED_JOIN *nested_join= embedding->nested_join; |
| 4419 | s->embedding_map|=nested_join->nj_map; |
| 4420 | s->dependent|= embedding->dep_tables; |
| 4421 | embedding= embedding->embedding; |
| 4422 | outer_join|= nested_join->used_tables; |
| 4423 | } |
| 4424 | while (embedding); |
| 4425 | if (inside_an_outer_join) |
| 4426 | continue; |
| 4427 | } |
| 4428 | if (!table->is_filled_at_execution() && |
| 4429 | (table->s->system || |
| 4430 | (table->file->stats.records <= 1 && |
| 4431 | (table->file->ha_table_flags() & HA_STATS_RECORDS_IS_EXACT)) || |
| 4432 | all_partitions_pruned_away) && |
| 4433 | !s->dependent && |
| 4434 | !table->fulltext_searched && !join->no_const_tables) |
| 4435 | { |
| 4436 | set_position(join,const_count++,s,(KEYUSE*) 0); |
| 4437 | no_rows_const_tables |= table->map; |
| 4438 | } |
| 4439 | |
| 4440 | /* SJ-Materialization handling: */ |
| 4441 | if (table->pos_in_table_list->jtbm_subselect && |
| 4442 | table->pos_in_table_list->jtbm_subselect->is_jtbm_const_tab) |
| 4443 | { |
| 4444 | set_position(join,const_count++,s,(KEYUSE*) 0); |
| 4445 | no_rows_const_tables |= table->map; |
| 4446 | } |
| 4447 | } |
| 4448 | |
| 4449 | stat_vector[i]=0; |
| 4450 | join->outer_join=outer_join; |
| 4451 | |
| 4452 | if (join->outer_join) |
| 4453 | { |
| 4454 | /* |
| 4455 | Build transitive closure for relation 'to be dependent on'. |
| 4456 | This will speed up the plan search for many cases with outer joins, |
| 4457 | as well as allow us to catch illegal cross references/ |
| 4458 | Warshall's algorithm is used to build the transitive closure. |
| 4459 | As we use bitmaps to represent the relation the complexity |
| 4460 | of the algorithm is O((number of tables)^2). |
| 4461 | |
| 4462 | The classic form of the Warshall's algorithm would look like: |
| 4463 | for (i= 0; i < table_count; i++) |
| 4464 | { |
| 4465 | for (j= 0; j < table_count; j++) |
| 4466 | { |
| 4467 | for (k= 0; k < table_count; k++) |
| 4468 | { |
| 4469 | if (bitmap_is_set(stat[j].dependent, i) && |
| 4470 | bitmap_is_set(stat[i].dependent, k)) |
| 4471 | bitmap_set_bit(stat[j].dependent, k); |
| 4472 | } |
| 4473 | } |
| 4474 | } |
| 4475 | */ |
| 4476 | |
| 4477 | for (s= stat ; s < stat_end ; s++) |
| 4478 | { |
| 4479 | table= s->table; |
| 4480 | for (JOIN_TAB *t= stat ; t < stat_end ; t++) |
| 4481 | { |
| 4482 | if (t->dependent & table->map) |
| 4483 | t->dependent |= table->reginfo.join_tab->dependent; |
| 4484 | } |
| 4485 | if (outer_join & s->table->map) |
| 4486 | s->table->maybe_null= 1; |
| 4487 | } |
| 4488 | /* Catch illegal cross references for outer joins */ |
| 4489 | for (i= 0, s= stat ; i < table_count ; i++, s++) |
| 4490 | { |
| 4491 | if (s->dependent & s->table->map) |
| 4492 | { |
| 4493 | join->table_count=0; // Don't use join->table |
| 4494 | my_message(ER_WRONG_OUTER_JOIN, |
| 4495 | ER_THD(join->thd, ER_WRONG_OUTER_JOIN), MYF(0)); |
| 4496 | goto error; |
| 4497 | } |
| 4498 | s->key_dependent= s->dependent; |
| 4499 | } |
| 4500 | } |
| 4501 | |
| 4502 | if (join->conds || outer_join) |
| 4503 | { |
| 4504 | if (update_ref_and_keys(join->thd, keyuse_array, stat, join->table_count, |
| 4505 | join->conds, ~outer_join, join->select_lex, &sargables)) |
| 4506 | goto error; |
| 4507 | /* |
| 4508 | Keyparts without prefixes may be useful if this JOIN is a subquery, and |
| 4509 | if the subquery may be executed via the IN-EXISTS strategy. |
| 4510 | */ |
| 4511 | bool skip_unprefixed_keyparts= |
| 4512 | !(join->is_in_subquery() && |
| 4513 | ((Item_in_subselect*)join->unit->item)->test_strategy(SUBS_IN_TO_EXISTS)); |
| 4514 | |
| 4515 | if (keyuse_array->elements && |
| 4516 | sort_and_filter_keyuse(join->thd, keyuse_array, |
| 4517 | skip_unprefixed_keyparts)) |
| 4518 | goto error; |
| 4519 | DBUG_EXECUTE("opt" , print_keyuse_array(keyuse_array);); |
| 4520 | } |
| 4521 | |
| 4522 | join->const_table_map= no_rows_const_tables; |
| 4523 | join->const_tables= const_count; |
| 4524 | eliminate_tables(join); |
| 4525 | join->const_table_map &= ~no_rows_const_tables; |
| 4526 | const_count= join->const_tables; |
| 4527 | found_const_table_map= join->const_table_map; |
| 4528 | |
| 4529 | /* Read tables with 0 or 1 rows (system tables) */ |
| 4530 | for (POSITION *p_pos=join->positions, *p_end=p_pos+const_count; |
| 4531 | p_pos < p_end ; |
| 4532 | p_pos++) |
| 4533 | { |
| 4534 | s= p_pos->table; |
| 4535 | if (! (s->table->map & join->eliminated_tables)) |
| 4536 | { |
| 4537 | int tmp; |
| 4538 | s->type=JT_SYSTEM; |
| 4539 | join->const_table_map|=s->table->map; |
| 4540 | if ((tmp=join_read_const_table(join->thd, s, p_pos))) |
| 4541 | { |
| 4542 | if (tmp > 0) |
| 4543 | goto error; // Fatal error |
| 4544 | } |
| 4545 | else |
| 4546 | { |
| 4547 | found_const_table_map|= s->table->map; |
| 4548 | s->table->pos_in_table_list->optimized_away= TRUE; |
| 4549 | } |
| 4550 | } |
| 4551 | } |
| 4552 | |
| 4553 | /* loop until no more const tables are found */ |
| 4554 | int ref_changed; |
| 4555 | do |
| 4556 | { |
| 4557 | more_const_tables_found: |
| 4558 | ref_changed = 0; |
| 4559 | found_ref=0; |
| 4560 | |
| 4561 | /* |
| 4562 | We only have to loop from stat_vector + const_count as |
| 4563 | set_position() will move all const_tables first in stat_vector |
| 4564 | */ |
| 4565 | |
| 4566 | for (JOIN_TAB **pos=stat_vector+const_count ; (s= *pos) ; pos++) |
| 4567 | { |
| 4568 | table=s->table; |
| 4569 | |
| 4570 | if (table->is_filled_at_execution()) |
| 4571 | continue; |
| 4572 | |
| 4573 | /* |
| 4574 | If equi-join condition by a key is null rejecting and after a |
| 4575 | substitution of a const table the key value happens to be null |
| 4576 | then we can state that there are no matches for this equi-join. |
| 4577 | */ |
| 4578 | if ((keyuse= s->keyuse) && *s->on_expr_ref && !s->embedding_map && |
| 4579 | !(table->map & join->eliminated_tables)) |
| 4580 | { |
| 4581 | /* |
| 4582 | When performing an outer join operation if there are no matching rows |
| 4583 | for the single row of the outer table all the inner tables are to be |
| 4584 | null complemented and thus considered as constant tables. |
| 4585 | Here we apply this consideration to the case of outer join operations |
| 4586 | with a single inner table only because the case with nested tables |
| 4587 | would require a more thorough analysis. |
| 4588 | TODO. Apply single row substitution to null complemented inner tables |
| 4589 | for nested outer join operations. |
| 4590 | */ |
| 4591 | while (keyuse->table == table) |
| 4592 | { |
| 4593 | if (!keyuse->is_for_hash_join() && |
| 4594 | !(keyuse->val->used_tables() & ~join->const_table_map) && |
| 4595 | keyuse->val->is_null() && keyuse->null_rejecting) |
| 4596 | { |
| 4597 | s->type= JT_CONST; |
| 4598 | s->table->const_table= 1; |
| 4599 | mark_as_null_row(table); |
| 4600 | found_const_table_map|= table->map; |
| 4601 | join->const_table_map|= table->map; |
| 4602 | set_position(join,const_count++,s,(KEYUSE*) 0); |
| 4603 | goto more_const_tables_found; |
| 4604 | } |
| 4605 | keyuse++; |
| 4606 | } |
| 4607 | } |
| 4608 | |
| 4609 | if (s->dependent) // If dependent on some table |
| 4610 | { |
| 4611 | // All dep. must be constants |
| 4612 | if (s->dependent & ~(found_const_table_map)) |
| 4613 | continue; |
| 4614 | if (table->file->stats.records <= 1L && |
| 4615 | (table->file->ha_table_flags() & HA_STATS_RECORDS_IS_EXACT) && |
| 4616 | !table->pos_in_table_list->embedding && |
| 4617 | !((outer_join & table->map) && |
| 4618 | (*s->on_expr_ref)->is_expensive())) |
| 4619 | { // system table |
| 4620 | int tmp= 0; |
| 4621 | s->type=JT_SYSTEM; |
| 4622 | join->const_table_map|=table->map; |
| 4623 | set_position(join,const_count++,s,(KEYUSE*) 0); |
| 4624 | if ((tmp= join_read_const_table(join->thd, s, join->positions+const_count-1))) |
| 4625 | { |
| 4626 | if (tmp > 0) |
| 4627 | goto error; // Fatal error |
| 4628 | } |
| 4629 | else |
| 4630 | found_const_table_map|= table->map; |
| 4631 | continue; |
| 4632 | } |
| 4633 | } |
| 4634 | /* check if table can be read by key or table only uses const refs */ |
| 4635 | if ((keyuse=s->keyuse)) |
| 4636 | { |
| 4637 | s->type= JT_REF; |
| 4638 | while (keyuse->table == table) |
| 4639 | { |
| 4640 | if (keyuse->is_for_hash_join()) |
| 4641 | { |
| 4642 | keyuse++; |
| 4643 | continue; |
| 4644 | } |
| 4645 | start_keyuse=keyuse; |
| 4646 | key=keyuse->key; |
| 4647 | s->keys.set_bit(key); // TODO: remove this ? |
| 4648 | |
| 4649 | refs=0; |
| 4650 | const_ref.clear_all(); |
| 4651 | eq_part.clear_all(); |
| 4652 | has_expensive_keyparts= false; |
| 4653 | do |
| 4654 | { |
| 4655 | if (keyuse->val->type() != Item::NULL_ITEM && |
| 4656 | !keyuse->optimize && |
| 4657 | keyuse->keypart != FT_KEYPART) |
| 4658 | { |
| 4659 | if (!((~found_const_table_map) & keyuse->used_tables)) |
| 4660 | { |
| 4661 | const_ref.set_bit(keyuse->keypart); |
| 4662 | if (keyuse->val->is_expensive()) |
| 4663 | has_expensive_keyparts= true; |
| 4664 | } |
| 4665 | else |
| 4666 | refs|=keyuse->used_tables; |
| 4667 | eq_part.set_bit(keyuse->keypart); |
| 4668 | } |
| 4669 | keyuse++; |
| 4670 | } while (keyuse->table == table && keyuse->key == key); |
| 4671 | |
| 4672 | TABLE_LIST *embedding= table->pos_in_table_list->embedding; |
| 4673 | /* |
| 4674 | TODO (low priority): currently we ignore the const tables that |
| 4675 | are within a semi-join nest which is within an outer join nest. |
| 4676 | The effect of this is that we don't do const substitution for |
| 4677 | such tables. |
| 4678 | */ |
| 4679 | KEY *keyinfo= table->key_info + key; |
| 4680 | uint key_parts= table->actual_n_key_parts(keyinfo); |
| 4681 | if (eq_part.is_prefix(key_parts) && |
| 4682 | !table->fulltext_searched && |
| 4683 | (!embedding || (embedding->sj_on_expr && !embedding->embedding))) |
| 4684 | { |
| 4685 | key_map base_part, base_const_ref, base_eq_part; |
| 4686 | base_part.set_prefix(keyinfo->user_defined_key_parts); |
| 4687 | base_const_ref= const_ref; |
| 4688 | base_const_ref.intersect(base_part); |
| 4689 | base_eq_part= eq_part; |
| 4690 | base_eq_part.intersect(base_part); |
| 4691 | if (table->actual_key_flags(keyinfo) & HA_NOSAME) |
| 4692 | { |
| 4693 | |
| 4694 | if (base_const_ref == base_eq_part && |
| 4695 | !has_expensive_keyparts && |
| 4696 | !((outer_join & table->map) && |
| 4697 | (*s->on_expr_ref)->is_expensive())) |
| 4698 | { // Found everything for ref. |
| 4699 | int tmp; |
| 4700 | ref_changed = 1; |
| 4701 | s->type= JT_CONST; |
| 4702 | join->const_table_map|=table->map; |
| 4703 | set_position(join,const_count++,s,start_keyuse); |
| 4704 | /* create_ref_for_key will set s->table->const_table */ |
| 4705 | if (create_ref_for_key(join, s, start_keyuse, FALSE, |
| 4706 | found_const_table_map)) |
| 4707 | goto error; |
| 4708 | if ((tmp=join_read_const_table(join->thd, s, |
| 4709 | join->positions+const_count-1))) |
| 4710 | { |
| 4711 | if (tmp > 0) |
| 4712 | goto error; // Fatal error |
| 4713 | } |
| 4714 | else |
| 4715 | found_const_table_map|= table->map; |
| 4716 | break; |
| 4717 | } |
| 4718 | else |
| 4719 | found_ref|= refs; // Table is const if all refs are const |
| 4720 | } |
| 4721 | else if (base_const_ref == base_eq_part) |
| 4722 | s->const_keys.set_bit(key); |
| 4723 | } |
| 4724 | } |
| 4725 | } |
| 4726 | } |
| 4727 | } while (join->const_table_map & found_ref && ref_changed); |
| 4728 | |
| 4729 | join->sort_by_table= get_sort_by_table(join->order, join->group_list, |
| 4730 | join->select_lex->leaf_tables, |
| 4731 | join->const_table_map); |
| 4732 | /* |
| 4733 | Update info on indexes that can be used for search lookups as |
| 4734 | reading const tables may has added new sargable predicates. |
| 4735 | */ |
| 4736 | if (const_count && sargables) |
| 4737 | { |
| 4738 | for( ; sargables->field ; sargables++) |
| 4739 | { |
| 4740 | Field *field= sargables->field; |
| 4741 | JOIN_TAB *join_tab= field->table->reginfo.join_tab; |
| 4742 | key_map possible_keys= field->key_start; |
| 4743 | possible_keys.intersect(field->table->keys_in_use_for_query); |
| 4744 | bool is_const= 1; |
| 4745 | for (uint j=0; j < sargables->num_values; j++) |
| 4746 | is_const&= sargables->arg_value[j]->const_item(); |
| 4747 | if (is_const) |
| 4748 | join_tab[0].const_keys.merge(possible_keys); |
| 4749 | } |
| 4750 | } |
| 4751 | |
| 4752 | join->impossible_where= false; |
| 4753 | if (join->conds && const_count) |
| 4754 | { |
| 4755 | Item* &conds= join->conds; |
| 4756 | COND_EQUAL *orig_cond_equal = join->cond_equal; |
| 4757 | |
| 4758 | conds->update_used_tables(); |
| 4759 | conds= conds->remove_eq_conds(join->thd, &join->cond_value, true); |
| 4760 | if (conds && conds->type() == Item::COND_ITEM && |
| 4761 | ((Item_cond*) conds)->functype() == Item_func::COND_AND_FUNC) |
| 4762 | join->cond_equal= &((Item_cond_and*) conds)->m_cond_equal; |
| 4763 | join->select_lex->where= conds; |
| 4764 | if (join->cond_value == Item::COND_FALSE) |
| 4765 | { |
| 4766 | join->impossible_where= true; |
| 4767 | conds= new (join->thd->mem_root) Item_int(join->thd, (longlong) 0, 1); |
| 4768 | } |
| 4769 | |
| 4770 | join->cond_equal= NULL; |
| 4771 | if (conds) |
| 4772 | { |
| 4773 | if (conds->type() == Item::COND_ITEM && |
| 4774 | ((Item_cond*) conds)->functype() == Item_func::COND_AND_FUNC) |
| 4775 | join->cond_equal= (&((Item_cond_and *) conds)->m_cond_equal); |
| 4776 | else if (conds->type() == Item::FUNC_ITEM && |
| 4777 | ((Item_func*) conds)->functype() == Item_func::MULT_EQUAL_FUNC) |
| 4778 | { |
| 4779 | if (!join->cond_equal) |
| 4780 | join->cond_equal= new COND_EQUAL; |
| 4781 | join->cond_equal->current_level.empty(); |
| 4782 | join->cond_equal->current_level.push_back((Item_equal*) conds, |
| 4783 | join->thd->mem_root); |
| 4784 | } |
| 4785 | } |
| 4786 | |
| 4787 | if (orig_cond_equal != join->cond_equal) |
| 4788 | { |
| 4789 | /* |
| 4790 | If join->cond_equal has changed all references to it from COND_EQUAL |
| 4791 | objects associated with ON expressions must be updated. |
| 4792 | */ |
| 4793 | for (JOIN_TAB **pos=stat_vector+const_count ; (s= *pos) ; pos++) |
| 4794 | { |
| 4795 | if (*s->on_expr_ref && s->cond_equal && |
| 4796 | s->cond_equal->upper_levels == orig_cond_equal) |
| 4797 | s->cond_equal->upper_levels= join->cond_equal; |
| 4798 | } |
| 4799 | } |
| 4800 | } |
| 4801 | |
| 4802 | /* Calc how many (possible) matched records in each table */ |
| 4803 | |
| 4804 | for (s=stat ; s < stat_end ; s++) |
| 4805 | { |
| 4806 | s->startup_cost= 0; |
| 4807 | if (s->type == JT_SYSTEM || s->type == JT_CONST) |
| 4808 | { |
| 4809 | /* Only one matching row */ |
| 4810 | s->found_records= s->records= 1; |
| 4811 | s->read_time=1.0; |
| 4812 | s->worst_seeks=1.0; |
| 4813 | continue; |
| 4814 | } |
| 4815 | /* Approximate found rows and time to read them */ |
| 4816 | if (s->table->is_filled_at_execution()) |
| 4817 | { |
| 4818 | get_delayed_table_estimates(s->table, &s->records, &s->read_time, |
| 4819 | &s->startup_cost); |
| 4820 | s->found_records= s->records; |
| 4821 | table->quick_condition_rows=s->records; |
| 4822 | } |
| 4823 | else |
| 4824 | { |
| 4825 | s->scan_time(); |
| 4826 | } |
| 4827 | |
| 4828 | if (s->table->is_splittable()) |
| 4829 | s->add_keyuses_for_splitting(); |
| 4830 | |
| 4831 | /* |
| 4832 | Set a max range of how many seeks we can expect when using keys |
| 4833 | This is can't be to high as otherwise we are likely to use |
| 4834 | table scan. |
| 4835 | */ |
| 4836 | s->worst_seeks= MY_MIN((double) s->found_records / 10, |
| 4837 | (double) s->read_time*3); |
| 4838 | if (s->worst_seeks < 2.0) // Fix for small tables |
| 4839 | s->worst_seeks=2.0; |
| 4840 | |
| 4841 | /* |
| 4842 | Add to stat->const_keys those indexes for which all group fields or |
| 4843 | all select distinct fields participate in one index. |
| 4844 | */ |
| 4845 | add_group_and_distinct_keys(join, s); |
| 4846 | |
| 4847 | s->table->cond_selectivity= 1.0; |
| 4848 | |
| 4849 | /* |
| 4850 | Perform range analysis if there are keys it could use (1). |
| 4851 | Don't do range analysis if we're on the inner side of an outer join (2). |
| 4852 | Do range analysis if we're on the inner side of a semi-join (3). |
| 4853 | Don't do range analysis for materialized subqueries (4). |
| 4854 | Don't do range analysis for materialized derived tables (5) |
| 4855 | */ |
| 4856 | if ((!s->const_keys.is_clear_all() || |
| 4857 | !bitmap_is_clear_all(&s->table->cond_set)) && // (1) |
| 4858 | (!s->table->pos_in_table_list->embedding || // (2) |
| 4859 | (s->table->pos_in_table_list->embedding && // (3) |
| 4860 | s->table->pos_in_table_list->embedding->sj_on_expr)) && // (3) |
| 4861 | !s->table->is_filled_at_execution() && // (4) |
| 4862 | !(s->table->pos_in_table_list->derived && // (5) |
| 4863 | s->table->pos_in_table_list->is_materialized_derived())) // (5) |
| 4864 | { |
| 4865 | bool impossible_range= FALSE; |
| 4866 | ha_rows records= HA_POS_ERROR; |
| 4867 | SQL_SELECT *select= 0; |
| 4868 | if (!s->const_keys.is_clear_all()) |
| 4869 | { |
| 4870 | select= make_select(s->table, found_const_table_map, |
| 4871 | found_const_table_map, |
| 4872 | *s->on_expr_ref ? *s->on_expr_ref : join->conds, |
| 4873 | (SORT_INFO*) 0, |
| 4874 | 1, &error); |
| 4875 | if (!select) |
| 4876 | goto error; |
| 4877 | records= get_quick_record_count(join->thd, select, s->table, |
| 4878 | &s->const_keys, join->row_limit); |
| 4879 | /* Range analyzer could modify the condition. */ |
| 4880 | if (*s->on_expr_ref) |
| 4881 | *s->on_expr_ref= select->cond; |
| 4882 | else |
| 4883 | join->conds= select->cond; |
| 4884 | |
| 4885 | s->quick=select->quick; |
| 4886 | s->needed_reg=select->needed_reg; |
| 4887 | select->quick=0; |
| 4888 | impossible_range= records == 0 && s->table->reginfo.impossible_range; |
| 4889 | } |
| 4890 | if (!impossible_range) |
| 4891 | { |
| 4892 | if (join->thd->variables.optimizer_use_condition_selectivity > 1) |
| 4893 | calculate_cond_selectivity_for_table(join->thd, s->table, |
| 4894 | *s->on_expr_ref ? |
| 4895 | s->on_expr_ref : &join->conds); |
| 4896 | if (s->table->reginfo.impossible_range) |
| 4897 | { |
| 4898 | impossible_range= TRUE; |
| 4899 | records= 0; |
| 4900 | } |
| 4901 | } |
| 4902 | if (impossible_range) |
| 4903 | { |
| 4904 | /* |
| 4905 | Impossible WHERE or ON expression |
| 4906 | In case of ON, we mark that the we match one empty NULL row. |
| 4907 | In case of WHERE, don't set found_const_table_map to get the |
| 4908 | caller to abort with a zero row result. |
| 4909 | */ |
| 4910 | join->const_table_map|= s->table->map; |
| 4911 | set_position(join,const_count++,s,(KEYUSE*) 0); |
| 4912 | s->type= JT_CONST; |
| 4913 | s->table->const_table= 1; |
| 4914 | if (*s->on_expr_ref) |
| 4915 | { |
| 4916 | /* Generate empty row */ |
| 4917 | s->info= ET_IMPOSSIBLE_ON_CONDITION; |
| 4918 | found_const_table_map|= s->table->map; |
| 4919 | mark_as_null_row(s->table); // All fields are NULL |
| 4920 | } |
| 4921 | } |
| 4922 | if (records != HA_POS_ERROR) |
| 4923 | { |
| 4924 | s->found_records=records; |
| 4925 | s->read_time= s->quick ? s->quick->read_time : 0.0; |
| 4926 | } |
| 4927 | if (select) |
| 4928 | delete select; |
| 4929 | } |
| 4930 | |
| 4931 | } |
| 4932 | |
| 4933 | if (pull_out_semijoin_tables(join)) |
| 4934 | DBUG_RETURN(TRUE); |
| 4935 | |
| 4936 | join->join_tab=stat; |
| 4937 | join->top_join_tab_count= table_count; |
| 4938 | join->map2table=stat_ref; |
| 4939 | join->table= table_vector; |
| 4940 | join->const_tables=const_count; |
| 4941 | join->found_const_table_map=found_const_table_map; |
| 4942 | |
| 4943 | if (join->const_tables != join->table_count) |
| 4944 | optimize_keyuse(join, keyuse_array); |
| 4945 | |
| 4946 | DBUG_ASSERT(!join->conds || !join->cond_equal || |
| 4947 | !join->cond_equal->current_level.elements || |
| 4948 | (join->conds->type() == Item::COND_ITEM && |
| 4949 | ((Item_cond*) (join->conds))->functype() == |
| 4950 | Item_func::COND_AND_FUNC && |
| 4951 | join->cond_equal == |
| 4952 | &((Item_cond_and *) (join->conds))->m_cond_equal) || |
| 4953 | (join->conds->type() == Item::FUNC_ITEM && |
| 4954 | ((Item_func*) (join->conds))->functype() == |
| 4955 | Item_func::MULT_EQUAL_FUNC && |
| 4956 | join->cond_equal->current_level.elements == 1 && |
| 4957 | join->cond_equal->current_level.head() == join->conds)); |
| 4958 | |
| 4959 | if (optimize_semijoin_nests(join, all_table_map)) |
| 4960 | DBUG_RETURN(TRUE); /* purecov: inspected */ |
| 4961 | |
| 4962 | { |
| 4963 | ha_rows records= 1; |
| 4964 | SELECT_LEX_UNIT *unit= join->select_lex->master_unit(); |
| 4965 | |
| 4966 | /* Find an optimal join order of the non-constant tables. */ |
| 4967 | if (join->const_tables != join->table_count) |
| 4968 | { |
| 4969 | if (choose_plan(join, all_table_map & ~join->const_table_map)) |
| 4970 | goto error; |
| 4971 | } |
| 4972 | else |
| 4973 | { |
| 4974 | memcpy((uchar*) join->best_positions,(uchar*) join->positions, |
| 4975 | sizeof(POSITION)*join->const_tables); |
| 4976 | join->join_record_count= 1.0; |
| 4977 | join->best_read=1.0; |
| 4978 | } |
| 4979 | |
| 4980 | if (!(join->select_options & SELECT_DESCRIBE) && |
| 4981 | unit->derived && unit->derived->is_materialized_derived()) |
| 4982 | { |
| 4983 | /* |
| 4984 | Calculate estimated number of rows for materialized derived |
| 4985 | table/view. |
| 4986 | */ |
| 4987 | for (i= 0; i < join->table_count ; i++) |
| 4988 | records*= join->best_positions[i].records_read ? |
| 4989 | (ha_rows)join->best_positions[i].records_read : 1; |
| 4990 | set_if_smaller(records, unit->select_limit_cnt); |
| 4991 | join->select_lex->increase_derived_records(records); |
| 4992 | } |
| 4993 | } |
| 4994 | |
| 4995 | if (join->choose_subquery_plan(all_table_map & ~join->const_table_map)) |
| 4996 | goto error; |
| 4997 | |
| 4998 | DEBUG_SYNC(join->thd, "inside_make_join_statistics" ); |
| 4999 | |
| 5000 | DBUG_RETURN(0); |
| 5001 | |
| 5002 | error: |
| 5003 | /* |
| 5004 | Need to clean up join_tab from TABLEs in case of error. |
| 5005 | They won't get cleaned up by JOIN::cleanup() because JOIN::join_tab |
| 5006 | may not be assigned yet by this function (which is building join_tab). |
| 5007 | Dangling TABLE::reginfo.join_tab may cause part_of_refkey to choke. |
| 5008 | */ |
| 5009 | { |
| 5010 | TABLE_LIST *tmp_table; |
| 5011 | List_iterator<TABLE_LIST> ti2(tables_list); |
| 5012 | while ((tmp_table= ti2++)) |
| 5013 | tmp_table->table->reginfo.join_tab= NULL; |
| 5014 | } |
| 5015 | DBUG_RETURN (1); |
| 5016 | } |
| 5017 | |
| 5018 | |
| 5019 | /***************************************************************************** |
| 5020 | Check with keys are used and with tables references with tables |
| 5021 | Updates in stat: |
| 5022 | keys Bitmap of all used keys |
| 5023 | const_keys Bitmap of all keys with may be used with quick_select |
| 5024 | keyuse Pointer to possible keys |
| 5025 | *****************************************************************************/ |
| 5026 | |
| 5027 | |
| 5028 | /** |
| 5029 | Merge new key definitions to old ones, remove those not used in both. |
| 5030 | |
| 5031 | This is called for OR between different levels. |
| 5032 | |
| 5033 | That is, the function operates on an array of KEY_FIELD elements which has |
| 5034 | two parts: |
| 5035 | |
| 5036 | $LEFT_PART $RIGHT_PART |
| 5037 | +-----------------------+-----------------------+ |
| 5038 | start new_fields end |
| 5039 | |
| 5040 | $LEFT_PART and $RIGHT_PART are arrays that have KEY_FIELD elements for two |
| 5041 | parts of the OR condition. Our task is to produce an array of KEY_FIELD |
| 5042 | elements that would correspond to "$LEFT_PART OR $RIGHT_PART". |
| 5043 | |
| 5044 | The rules for combining elements are as follows: |
| 5045 | |
| 5046 | (keyfieldA1 AND keyfieldA2 AND ...) OR (keyfieldB1 AND keyfieldB2 AND ...)= |
| 5047 | |
| 5048 | = AND_ij (keyfieldA_i OR keyfieldB_j) |
| 5049 | |
| 5050 | We discard all (keyfieldA_i OR keyfieldB_j) that refer to different |
| 5051 | fields. For those referring to the same field, the logic is as follows: |
| 5052 | |
| 5053 | t.keycol=expr1 OR t.keycol=expr2 -> (since expr1 and expr2 are different |
| 5054 | we can't produce a single equality, |
| 5055 | so produce nothing) |
| 5056 | |
| 5057 | t.keycol=expr1 OR t.keycol=expr1 -> t.keycol=expr1 |
| 5058 | |
| 5059 | t.keycol=expr1 OR t.keycol IS NULL -> t.keycol=expr1, and also set |
| 5060 | KEY_OPTIMIZE_REF_OR_NULL flag |
| 5061 | |
| 5062 | The last one is for ref_or_null access. We have handling for this special |
| 5063 | because it's needed for evaluating IN subqueries that are internally |
| 5064 | transformed into |
| 5065 | |
| 5066 | @code |
| 5067 | EXISTS(SELECT * FROM t1 WHERE t1.key=outer_ref_field or t1.key IS NULL) |
| 5068 | @endcode |
| 5069 | |
| 5070 | See add_key_fields() for discussion of what is and_level. |
| 5071 | |
| 5072 | KEY_FIELD::null_rejecting is processed as follows: @n |
| 5073 | result has null_rejecting=true if it is set for both ORed references. |
| 5074 | for example: |
| 5075 | - (t2.key = t1.field OR t2.key = t1.field) -> null_rejecting=true |
| 5076 | - (t2.key = t1.field OR t2.key <=> t1.field) -> null_rejecting=false |
| 5077 | |
| 5078 | @todo |
| 5079 | The result of this is that we're missing some 'ref' accesses. |
| 5080 | OptimizerTeam: Fix this |
| 5081 | */ |
| 5082 | |
| 5083 | static KEY_FIELD * |
| 5084 | merge_key_fields(KEY_FIELD *start,KEY_FIELD *new_fields,KEY_FIELD *end, |
| 5085 | uint and_level) |
| 5086 | { |
| 5087 | if (start == new_fields) |
| 5088 | return start; // Impossible or |
| 5089 | if (new_fields == end) |
| 5090 | return start; // No new fields, skip all |
| 5091 | |
| 5092 | KEY_FIELD *first_free=new_fields; |
| 5093 | |
| 5094 | /* Mark all found fields in old array */ |
| 5095 | for (; new_fields != end ; new_fields++) |
| 5096 | { |
| 5097 | for (KEY_FIELD *old=start ; old != first_free ; old++) |
| 5098 | { |
| 5099 | if (old->field == new_fields->field) |
| 5100 | { |
| 5101 | /* |
| 5102 | NOTE: below const_item() call really works as "!used_tables()", i.e. |
| 5103 | it can return FALSE where it is feasible to make it return TRUE. |
| 5104 | |
| 5105 | The cause is as follows: Some of the tables are already known to be |
| 5106 | const tables (the detection code is in make_join_statistics(), |
| 5107 | above the update_ref_and_keys() call), but we didn't propagate |
| 5108 | information about this: TABLE::const_table is not set to TRUE, and |
| 5109 | Item::update_used_tables() hasn't been called for each item. |
| 5110 | The result of this is that we're missing some 'ref' accesses. |
| 5111 | TODO: OptimizerTeam: Fix this |
| 5112 | */ |
| 5113 | if (!new_fields->val->const_item()) |
| 5114 | { |
| 5115 | /* |
| 5116 | If the value matches, we can use the key reference. |
| 5117 | If not, we keep it until we have examined all new values |
| 5118 | */ |
| 5119 | if (old->val->eq(new_fields->val, old->field->binary())) |
| 5120 | { |
| 5121 | old->level= and_level; |
| 5122 | old->optimize= ((old->optimize & new_fields->optimize & |
| 5123 | KEY_OPTIMIZE_EXISTS) | |
| 5124 | ((old->optimize | new_fields->optimize) & |
| 5125 | KEY_OPTIMIZE_REF_OR_NULL)); |
| 5126 | old->null_rejecting= (old->null_rejecting && |
| 5127 | new_fields->null_rejecting); |
| 5128 | } |
| 5129 | } |
| 5130 | else if (old->eq_func && new_fields->eq_func && |
| 5131 | old->val->eq_by_collation(new_fields->val, |
| 5132 | old->field->binary(), |
| 5133 | old->field->charset())) |
| 5134 | |
| 5135 | { |
| 5136 | old->level= and_level; |
| 5137 | old->optimize= ((old->optimize & new_fields->optimize & |
| 5138 | KEY_OPTIMIZE_EXISTS) | |
| 5139 | ((old->optimize | new_fields->optimize) & |
| 5140 | KEY_OPTIMIZE_REF_OR_NULL)); |
| 5141 | old->null_rejecting= (old->null_rejecting && |
| 5142 | new_fields->null_rejecting); |
| 5143 | } |
| 5144 | else if (old->eq_func && new_fields->eq_func && |
| 5145 | ((old->val->const_item() && !old->val->is_expensive() && |
| 5146 | old->val->is_null()) || |
| 5147 | (!new_fields->val->is_expensive() && |
| 5148 | new_fields->val->is_null()))) |
| 5149 | { |
| 5150 | /* field = expression OR field IS NULL */ |
| 5151 | old->level= and_level; |
| 5152 | if (old->field->maybe_null()) |
| 5153 | { |
| 5154 | old->optimize= KEY_OPTIMIZE_REF_OR_NULL; |
| 5155 | /* The referred expression can be NULL: */ |
| 5156 | old->null_rejecting= 0; |
| 5157 | } |
| 5158 | /* |
| 5159 | Remember the NOT NULL value unless the value does not depend |
| 5160 | on other tables. |
| 5161 | */ |
| 5162 | if (!old->val->used_tables() && !old->val->is_expensive() && |
| 5163 | old->val->is_null()) |
| 5164 | old->val= new_fields->val; |
| 5165 | } |
| 5166 | else |
| 5167 | { |
| 5168 | /* |
| 5169 | We are comparing two different const. In this case we can't |
| 5170 | use a key-lookup on this so it's better to remove the value |
| 5171 | and let the range optimzier handle it |
| 5172 | */ |
| 5173 | if (old == --first_free) // If last item |
| 5174 | break; |
| 5175 | *old= *first_free; // Remove old value |
| 5176 | old--; // Retry this value |
| 5177 | } |
| 5178 | } |
| 5179 | } |
| 5180 | } |
| 5181 | /* Remove all not used items */ |
| 5182 | for (KEY_FIELD *old=start ; old != first_free ;) |
| 5183 | { |
| 5184 | if (old->level != and_level) |
| 5185 | { // Not used in all levels |
| 5186 | if (old == --first_free) |
| 5187 | break; |
| 5188 | *old= *first_free; // Remove old value |
| 5189 | continue; |
| 5190 | } |
| 5191 | old++; |
| 5192 | } |
| 5193 | return first_free; |
| 5194 | } |
| 5195 | |
| 5196 | |
| 5197 | /* |
| 5198 | Given a field, return its index in semi-join's select list, or UINT_MAX |
| 5199 | |
| 5200 | DESCRIPTION |
| 5201 | Given a field, we find its table; then see if the table is within a |
| 5202 | semi-join nest and if the field was in select list of the subselect. |
| 5203 | If it was, we return field's index in the select list. The value is used |
| 5204 | by LooseScan strategy. |
| 5205 | */ |
| 5206 | |
| 5207 | static uint get_semi_join_select_list_index(Field *field) |
| 5208 | { |
| 5209 | uint res= UINT_MAX; |
| 5210 | TABLE_LIST *emb_sj_nest; |
| 5211 | if ((emb_sj_nest= field->table->pos_in_table_list->embedding) && |
| 5212 | emb_sj_nest->sj_on_expr) |
| 5213 | { |
| 5214 | Item_in_subselect *subq_pred= emb_sj_nest->sj_subq_pred; |
| 5215 | st_select_lex *subq_lex= subq_pred->unit->first_select(); |
| 5216 | if (subq_pred->left_expr->cols() == 1) |
| 5217 | { |
| 5218 | Item *sel_item= subq_lex->ref_pointer_array[0]; |
| 5219 | if (sel_item->type() == Item::FIELD_ITEM && |
| 5220 | ((Item_field*)sel_item)->field->eq(field)) |
| 5221 | { |
| 5222 | res= 0; |
| 5223 | } |
| 5224 | } |
| 5225 | else |
| 5226 | { |
| 5227 | for (uint i= 0; i < subq_pred->left_expr->cols(); i++) |
| 5228 | { |
| 5229 | Item *sel_item= subq_lex->ref_pointer_array[i]; |
| 5230 | if (sel_item->type() == Item::FIELD_ITEM && |
| 5231 | ((Item_field*)sel_item)->field->eq(field)) |
| 5232 | { |
| 5233 | res= i; |
| 5234 | break; |
| 5235 | } |
| 5236 | } |
| 5237 | } |
| 5238 | } |
| 5239 | return res; |
| 5240 | } |
| 5241 | |
| 5242 | |
| 5243 | /** |
| 5244 | Add a possible key to array of possible keys if it's usable as a key |
| 5245 | |
| 5246 | @param key_fields Pointer to add key, if usable |
| 5247 | @param and_level And level, to be stored in KEY_FIELD |
| 5248 | @param cond Condition predicate |
| 5249 | @param field Field used in comparision |
| 5250 | @param eq_func True if we used =, <=> or IS NULL |
| 5251 | @param value Value used for comparison with field |
| 5252 | @param num_values Number of values[] that we are comparing against |
| 5253 | @param usable_tables Tables which can be used for key optimization |
| 5254 | @param sargables IN/OUT Array of found sargable candidates |
| 5255 | @param row_col_no if = n that > 0 then field is compared only |
| 5256 | against the n-th component of row values |
| 5257 | |
| 5258 | @note |
| 5259 | If we are doing a NOT NULL comparison on a NOT NULL field in a outer join |
| 5260 | table, we store this to be able to do not exists optimization later. |
| 5261 | |
| 5262 | @returns |
| 5263 | *key_fields is incremented if we stored a key in the array |
| 5264 | */ |
| 5265 | |
| 5266 | static void |
| 5267 | add_key_field(JOIN *join, |
| 5268 | KEY_FIELD **key_fields,uint and_level, Item_bool_func *cond, |
| 5269 | Field *field, bool eq_func, Item **value, uint num_values, |
| 5270 | table_map usable_tables, SARGABLE_PARAM **sargables, |
| 5271 | uint row_col_no= 0) |
| 5272 | { |
| 5273 | uint optimize= 0; |
| 5274 | if (eq_func && |
| 5275 | ((join->is_allowed_hash_join_access() && |
| 5276 | field->hash_join_is_possible() && |
| 5277 | !(field->table->pos_in_table_list->is_materialized_derived() && |
| 5278 | field->table->is_created())) || |
| 5279 | (field->table->pos_in_table_list->is_materialized_derived() && |
| 5280 | !field->table->is_created() && !(field->flags & BLOB_FLAG)))) |
| 5281 | { |
| 5282 | optimize= KEY_OPTIMIZE_EQ; |
| 5283 | } |
| 5284 | else if (!(field->flags & PART_KEY_FLAG)) |
| 5285 | { |
| 5286 | // Don't remove column IS NULL on a LEFT JOIN table |
| 5287 | if (eq_func && (*value)->type() == Item::NULL_ITEM && |
| 5288 | field->table->maybe_null && !field->null_ptr) |
| 5289 | { |
| 5290 | optimize= KEY_OPTIMIZE_EXISTS; |
| 5291 | DBUG_ASSERT(num_values == 1); |
| 5292 | } |
| 5293 | } |
| 5294 | if (optimize != KEY_OPTIMIZE_EXISTS) |
| 5295 | { |
| 5296 | table_map used_tables=0; |
| 5297 | bool optimizable=0; |
| 5298 | for (uint i=0; i<num_values; i++) |
| 5299 | { |
| 5300 | Item *curr_val; |
| 5301 | if (row_col_no && value[i]->real_item()->type() == Item::ROW_ITEM) |
| 5302 | { |
| 5303 | Item_row *value_tuple= (Item_row *) (value[i]->real_item()); |
| 5304 | curr_val= value_tuple->element_index(row_col_no - 1); |
| 5305 | } |
| 5306 | else |
| 5307 | curr_val= value[i]; |
| 5308 | table_map value_used_tables= curr_val->used_tables(); |
| 5309 | used_tables|= value_used_tables; |
| 5310 | if (!(value_used_tables & (field->table->map | RAND_TABLE_BIT))) |
| 5311 | optimizable=1; |
| 5312 | } |
| 5313 | if (!optimizable) |
| 5314 | return; |
| 5315 | if (!(usable_tables & field->table->map)) |
| 5316 | { |
| 5317 | if (!eq_func || (*value)->type() != Item::NULL_ITEM || |
| 5318 | !field->table->maybe_null || field->null_ptr) |
| 5319 | return; // Can't use left join optimize |
| 5320 | optimize= KEY_OPTIMIZE_EXISTS; |
| 5321 | } |
| 5322 | else |
| 5323 | { |
| 5324 | JOIN_TAB *stat=field->table->reginfo.join_tab; |
| 5325 | key_map possible_keys=field->get_possible_keys(); |
| 5326 | possible_keys.intersect(field->table->keys_in_use_for_query); |
| 5327 | stat[0].keys.merge(possible_keys); // Add possible keys |
| 5328 | |
| 5329 | /* |
| 5330 | Save the following cases: |
| 5331 | Field op constant |
| 5332 | Field LIKE constant where constant doesn't start with a wildcard |
| 5333 | Field = field2 where field2 is in a different table |
| 5334 | Field op formula |
| 5335 | Field IS NULL |
| 5336 | Field IS NOT NULL |
| 5337 | Field BETWEEN ... |
| 5338 | Field IN ... |
| 5339 | */ |
| 5340 | if (field->flags & PART_KEY_FLAG) |
| 5341 | stat[0].key_dependent|=used_tables; |
| 5342 | |
| 5343 | bool is_const=1; |
| 5344 | for (uint i=0; i<num_values; i++) |
| 5345 | { |
| 5346 | Item *curr_val; |
| 5347 | if (row_col_no && value[i]->real_item()->type() == Item::ROW_ITEM) |
| 5348 | { |
| 5349 | Item_row *value_tuple= (Item_row *) (value[i]->real_item()); |
| 5350 | curr_val= value_tuple->element_index(row_col_no - 1); |
| 5351 | } |
| 5352 | else |
| 5353 | curr_val= value[i]; |
| 5354 | if (!(is_const&= curr_val->const_item())) |
| 5355 | break; |
| 5356 | } |
| 5357 | if (is_const) |
| 5358 | { |
| 5359 | stat[0].const_keys.merge(possible_keys); |
| 5360 | bitmap_set_bit(&field->table->cond_set, field->field_index); |
| 5361 | } |
| 5362 | else if (!eq_func) |
| 5363 | { |
| 5364 | /* |
| 5365 | Save info to be able check whether this predicate can be |
| 5366 | considered as sargable for range analisis after reading const tables. |
| 5367 | We do not save info about equalities as update_const_equal_items |
| 5368 | will take care of updating info on keys from sargable equalities. |
| 5369 | */ |
| 5370 | (*sargables)--; |
| 5371 | (*sargables)->field= field; |
| 5372 | (*sargables)->arg_value= value; |
| 5373 | (*sargables)->num_values= num_values; |
| 5374 | } |
| 5375 | if (!eq_func) // eq_func is NEVER true when num_values > 1 |
| 5376 | return; |
| 5377 | } |
| 5378 | } |
| 5379 | /* |
| 5380 | For the moment eq_func is always true. This slot is reserved for future |
| 5381 | extensions where we want to remembers other things than just eq comparisons |
| 5382 | */ |
| 5383 | DBUG_ASSERT(eq_func); |
| 5384 | /* Store possible eq field */ |
| 5385 | (*key_fields)->field= field; |
| 5386 | (*key_fields)->eq_func= eq_func; |
| 5387 | (*key_fields)->val= *value; |
| 5388 | (*key_fields)->cond= cond; |
| 5389 | (*key_fields)->level= and_level; |
| 5390 | (*key_fields)->optimize= optimize; |
| 5391 | /* |
| 5392 | If the condition has form "tbl.keypart = othertbl.field" and |
| 5393 | othertbl.field can be NULL, there will be no matches if othertbl.field |
| 5394 | has NULL value. |
| 5395 | We use null_rejecting in add_not_null_conds() to add |
| 5396 | 'othertbl.field IS NOT NULL' to tab->select_cond. |
| 5397 | */ |
| 5398 | { |
| 5399 | Item *real= (*value)->real_item(); |
| 5400 | if (((cond->functype() == Item_func::EQ_FUNC) || |
| 5401 | (cond->functype() == Item_func::MULT_EQUAL_FUNC)) && |
| 5402 | (real->type() == Item::FIELD_ITEM) && |
| 5403 | ((Item_field*)real)->field->maybe_null()) |
| 5404 | (*key_fields)->null_rejecting= true; |
| 5405 | else |
| 5406 | (*key_fields)->null_rejecting= false; |
| 5407 | } |
| 5408 | (*key_fields)->cond_guard= NULL; |
| 5409 | |
| 5410 | (*key_fields)->sj_pred_no= get_semi_join_select_list_index(field); |
| 5411 | (*key_fields)++; |
| 5412 | } |
| 5413 | |
| 5414 | /** |
| 5415 | Add possible keys to array of possible keys originated from a simple |
| 5416 | predicate. |
| 5417 | |
| 5418 | @param key_fields Pointer to add key, if usable |
| 5419 | @param and_level And level, to be stored in KEY_FIELD |
| 5420 | @param cond Condition predicate |
| 5421 | @param field_item Field item used for comparison |
| 5422 | @param eq_func True if we used =, <=> or IS NULL |
| 5423 | @param value Value used for comparison with field_item |
| 5424 | @param num_values Number of values[] that we are comparing against |
| 5425 | @param usable_tables Tables which can be used for key optimization |
| 5426 | @param sargables IN/OUT Array of found sargable candidates |
| 5427 | @param row_col_no if = n that > 0 then field is compared only |
| 5428 | against the n-th component of row values |
| 5429 | |
| 5430 | @note |
| 5431 | If field items f1 and f2 belong to the same multiple equality and |
| 5432 | a key is added for f1, the the same key is added for f2. |
| 5433 | |
| 5434 | @returns |
| 5435 | *key_fields is incremented if we stored a key in the array |
| 5436 | */ |
| 5437 | |
| 5438 | static void |
| 5439 | add_key_equal_fields(JOIN *join, KEY_FIELD **key_fields, uint and_level, |
| 5440 | Item_bool_func *cond, Item *field_item, |
| 5441 | bool eq_func, Item **val, |
| 5442 | uint num_values, table_map usable_tables, |
| 5443 | SARGABLE_PARAM **sargables, uint row_col_no= 0) |
| 5444 | { |
| 5445 | Field *field= ((Item_field *) (field_item->real_item()))->field; |
| 5446 | add_key_field(join, key_fields, and_level, cond, field, |
| 5447 | eq_func, val, num_values, usable_tables, sargables, |
| 5448 | row_col_no); |
| 5449 | Item_equal *item_equal= field_item->get_item_equal(); |
| 5450 | if (item_equal) |
| 5451 | { |
| 5452 | /* |
| 5453 | Add to the set of possible key values every substitution of |
| 5454 | the field for an equal field included into item_equal |
| 5455 | */ |
| 5456 | Item_equal_fields_iterator it(*item_equal); |
| 5457 | while (it++) |
| 5458 | { |
| 5459 | Field *equal_field= it.get_curr_field(); |
| 5460 | if (!field->eq(equal_field)) |
| 5461 | { |
| 5462 | add_key_field(join, key_fields, and_level, cond, equal_field, |
| 5463 | eq_func, val, num_values, usable_tables, |
| 5464 | sargables, row_col_no); |
| 5465 | } |
| 5466 | } |
| 5467 | } |
| 5468 | } |
| 5469 | |
| 5470 | |
| 5471 | /** |
| 5472 | Check if an expression is a non-outer field. |
| 5473 | |
| 5474 | Checks if an expression is a field and belongs to the current select. |
| 5475 | |
| 5476 | @param field Item expression to check |
| 5477 | |
| 5478 | @return boolean |
| 5479 | @retval TRUE the expression is a local field |
| 5480 | @retval FALSE it's something else |
| 5481 | */ |
| 5482 | |
| 5483 | static bool |
| 5484 | is_local_field (Item *field) |
| 5485 | { |
| 5486 | return field->real_item()->type() == Item::FIELD_ITEM |
| 5487 | && !(field->used_tables() & OUTER_REF_TABLE_BIT) |
| 5488 | && !((Item_field *)field->real_item())->get_depended_from(); |
| 5489 | } |
| 5490 | |
| 5491 | |
| 5492 | /* |
| 5493 | In this and other functions, and_level is a number that is ever-growing |
| 5494 | and is different for the contents of every AND or OR clause. For example, |
| 5495 | when processing clause |
| 5496 | |
| 5497 | (a AND b AND c) OR (x AND y) |
| 5498 | |
| 5499 | we'll have |
| 5500 | * KEY_FIELD elements for (a AND b AND c) are assigned and_level=1 |
| 5501 | * KEY_FIELD elements for (x AND y) are assigned and_level=2 |
| 5502 | * OR operation is performed, and whatever elements are left after it are |
| 5503 | assigned and_level=3. |
| 5504 | |
| 5505 | The primary reason for having and_level attribute is the OR operation which |
| 5506 | uses and_level to mark KEY_FIELDs that should get into the result of the OR |
| 5507 | operation |
| 5508 | */ |
| 5509 | |
| 5510 | |
| 5511 | void |
| 5512 | Item_cond_and::add_key_fields(JOIN *join, KEY_FIELD **key_fields, |
| 5513 | uint *and_level, table_map usable_tables, |
| 5514 | SARGABLE_PARAM **sargables) |
| 5515 | { |
| 5516 | List_iterator_fast<Item> li(*argument_list()); |
| 5517 | KEY_FIELD *org_key_fields= *key_fields; |
| 5518 | |
| 5519 | Item *item; |
| 5520 | while ((item=li++)) |
| 5521 | item->add_key_fields(join, key_fields, and_level, usable_tables, |
| 5522 | sargables); |
| 5523 | for (; org_key_fields != *key_fields ; org_key_fields++) |
| 5524 | org_key_fields->level= *and_level; |
| 5525 | } |
| 5526 | |
| 5527 | |
| 5528 | void |
| 5529 | Item_cond::add_key_fields(JOIN *join, KEY_FIELD **key_fields, |
| 5530 | uint *and_level, table_map usable_tables, |
| 5531 | SARGABLE_PARAM **sargables) |
| 5532 | { |
| 5533 | List_iterator_fast<Item> li(*argument_list()); |
| 5534 | KEY_FIELD *org_key_fields= *key_fields; |
| 5535 | |
| 5536 | (*and_level)++; |
| 5537 | (li++)->add_key_fields(join, key_fields, and_level, usable_tables, |
| 5538 | sargables); |
| 5539 | Item *item; |
| 5540 | while ((item=li++)) |
| 5541 | { |
| 5542 | KEY_FIELD *start_key_fields= *key_fields; |
| 5543 | (*and_level)++; |
| 5544 | item->add_key_fields(join, key_fields, and_level, usable_tables, |
| 5545 | sargables); |
| 5546 | *key_fields= merge_key_fields(org_key_fields,start_key_fields, |
| 5547 | *key_fields, ++(*and_level)); |
| 5548 | } |
| 5549 | } |
| 5550 | |
| 5551 | |
| 5552 | void |
| 5553 | Item_func_trig_cond::add_key_fields(JOIN *join, KEY_FIELD **key_fields, |
| 5554 | uint *and_level, table_map usable_tables, |
| 5555 | SARGABLE_PARAM **sargables) |
| 5556 | { |
| 5557 | /* |
| 5558 | Subquery optimization: Conditions that are pushed down into subqueries |
| 5559 | are wrapped into Item_func_trig_cond. We process the wrapped condition |
| 5560 | but need to set cond_guard for KEYUSE elements generated from it. |
| 5561 | */ |
| 5562 | if (!join->group_list && !join->order && |
| 5563 | join->unit->item && |
| 5564 | join->unit->item->substype() == Item_subselect::IN_SUBS && |
| 5565 | !join->unit->is_unit_op()) |
| 5566 | { |
| 5567 | KEY_FIELD *save= *key_fields; |
| 5568 | args[0]->add_key_fields(join, key_fields, and_level, usable_tables, |
| 5569 | sargables); |
| 5570 | // Indicate that this ref access candidate is for subquery lookup: |
| 5571 | for (; save != *key_fields; save++) |
| 5572 | save->cond_guard= get_trig_var(); |
| 5573 | } |
| 5574 | } |
| 5575 | |
| 5576 | |
| 5577 | void |
| 5578 | Item_func_between::add_key_fields(JOIN *join, KEY_FIELD **key_fields, |
| 5579 | uint *and_level, table_map usable_tables, |
| 5580 | SARGABLE_PARAM **sargables) |
| 5581 | { |
| 5582 | /* |
| 5583 | Build list of possible keys for 'a BETWEEN low AND high'. |
| 5584 | It is handled similar to the equivalent condition |
| 5585 | 'a >= low AND a <= high': |
| 5586 | */ |
| 5587 | Item_field *field_item; |
| 5588 | bool equal_func= false; |
| 5589 | uint num_values= 2; |
| 5590 | |
| 5591 | bool binary_cmp= (args[0]->real_item()->type() == Item::FIELD_ITEM) |
| 5592 | ? ((Item_field*) args[0]->real_item())->field->binary() |
| 5593 | : true; |
| 5594 | /* |
| 5595 | Additional optimization: If 'low = high': |
| 5596 | Handle as if the condition was "t.key = low". |
| 5597 | */ |
| 5598 | if (!negated && args[1]->eq(args[2], binary_cmp)) |
| 5599 | { |
| 5600 | equal_func= true; |
| 5601 | num_values= 1; |
| 5602 | } |
| 5603 | |
| 5604 | /* |
| 5605 | Append keys for 'field <cmp> value[]' if the |
| 5606 | condition is of the form:: |
| 5607 | '<field> BETWEEN value[1] AND value[2]' |
| 5608 | */ |
| 5609 | if (is_local_field(args[0])) |
| 5610 | { |
| 5611 | field_item= (Item_field *) (args[0]->real_item()); |
| 5612 | add_key_equal_fields(join, key_fields, *and_level, this, |
| 5613 | field_item, equal_func, &args[1], |
| 5614 | num_values, usable_tables, sargables); |
| 5615 | } |
| 5616 | /* |
| 5617 | Append keys for 'value[0] <cmp> field' if the |
| 5618 | condition is of the form: |
| 5619 | 'value[0] BETWEEN field1 AND field2' |
| 5620 | */ |
| 5621 | for (uint i= 1; i <= num_values; i++) |
| 5622 | { |
| 5623 | if (is_local_field(args[i])) |
| 5624 | { |
| 5625 | field_item= (Item_field *) (args[i]->real_item()); |
| 5626 | add_key_equal_fields(join, key_fields, *and_level, this, |
| 5627 | field_item, equal_func, args, |
| 5628 | 1, usable_tables, sargables); |
| 5629 | } |
| 5630 | } |
| 5631 | } |
| 5632 | |
| 5633 | |
| 5634 | void |
| 5635 | Item_func_in::add_key_fields(JOIN *join, KEY_FIELD **key_fields, |
| 5636 | uint *and_level, table_map usable_tables, |
| 5637 | SARGABLE_PARAM **sargables) |
| 5638 | { |
| 5639 | if (is_local_field(args[0]) && !(used_tables() & OUTER_REF_TABLE_BIT)) |
| 5640 | { |
| 5641 | DBUG_ASSERT(arg_count != 2); |
| 5642 | add_key_equal_fields(join, key_fields, *and_level, this, |
| 5643 | (Item_field*) (args[0]->real_item()), false, |
| 5644 | args + 1, arg_count - 1, usable_tables, sargables); |
| 5645 | } |
| 5646 | else if (key_item()->type() == Item::ROW_ITEM && |
| 5647 | !(used_tables() & OUTER_REF_TABLE_BIT)) |
| 5648 | { |
| 5649 | Item_row *key_row= (Item_row *) key_item(); |
| 5650 | Item **key_col= key_row->addr(0); |
| 5651 | uint row_cols= key_row->cols(); |
| 5652 | for (uint i= 0; i < row_cols; i++, key_col++) |
| 5653 | { |
| 5654 | if (is_local_field(*key_col)) |
| 5655 | { |
| 5656 | Item_field *field_item= (Item_field *)((*key_col)->real_item()); |
| 5657 | add_key_equal_fields(join, key_fields, *and_level, this, |
| 5658 | field_item, false, args + 1, arg_count - 1, |
| 5659 | usable_tables, sargables, i + 1); |
| 5660 | } |
| 5661 | } |
| 5662 | } |
| 5663 | |
| 5664 | } |
| 5665 | |
| 5666 | |
| 5667 | void |
| 5668 | Item_func_ne::add_key_fields(JOIN *join, KEY_FIELD **key_fields, |
| 5669 | uint *and_level, table_map usable_tables, |
| 5670 | SARGABLE_PARAM **sargables) |
| 5671 | { |
| 5672 | if (!(used_tables() & OUTER_REF_TABLE_BIT)) |
| 5673 | { |
| 5674 | /* |
| 5675 | QQ: perhaps test for !is_local_field(args[1]) is not really needed here. |
| 5676 | Other comparison functions, e.g. Item_func_le, Item_func_gt, etc, |
| 5677 | do not have this test. See Item_bool_func2::add_key_fieldoptimize_op(). |
| 5678 | Check with the optimizer team. |
| 5679 | */ |
| 5680 | if (is_local_field(args[0]) && !is_local_field(args[1])) |
| 5681 | add_key_equal_fields(join, key_fields, *and_level, this, |
| 5682 | (Item_field*) (args[0]->real_item()), false, |
| 5683 | &args[1], 1, usable_tables, sargables); |
| 5684 | /* |
| 5685 | QQ: perhaps test for !is_local_field(args[0]) is not really needed here. |
| 5686 | */ |
| 5687 | if (is_local_field(args[1]) && !is_local_field(args[0])) |
| 5688 | add_key_equal_fields(join, key_fields, *and_level, this, |
| 5689 | (Item_field*) (args[1]->real_item()), false, |
| 5690 | &args[0], 1, usable_tables, sargables); |
| 5691 | } |
| 5692 | } |
| 5693 | |
| 5694 | |
| 5695 | void |
| 5696 | Item_func_like::add_key_fields(JOIN *join, KEY_FIELD **key_fields, |
| 5697 | uint *and_level, table_map usable_tables, |
| 5698 | SARGABLE_PARAM **sargables) |
| 5699 | { |
| 5700 | if (is_local_field(args[0]) && with_sargable_pattern()) |
| 5701 | { |
| 5702 | /* |
| 5703 | SELECT * FROM t1 WHERE field LIKE const_pattern |
| 5704 | const_pattern starts with a non-wildcard character |
| 5705 | */ |
| 5706 | add_key_equal_fields(join, key_fields, *and_level, this, |
| 5707 | (Item_field*) args[0]->real_item(), false, |
| 5708 | args + 1, 1, usable_tables, sargables); |
| 5709 | } |
| 5710 | } |
| 5711 | |
| 5712 | |
| 5713 | void |
| 5714 | Item_bool_func2::add_key_fields_optimize_op(JOIN *join, KEY_FIELD **key_fields, |
| 5715 | uint *and_level, |
| 5716 | table_map usable_tables, |
| 5717 | SARGABLE_PARAM **sargables, |
| 5718 | bool equal_func) |
| 5719 | { |
| 5720 | /* If item is of type 'field op field/constant' add it to key_fields */ |
| 5721 | if (is_local_field(args[0])) |
| 5722 | { |
| 5723 | add_key_equal_fields(join, key_fields, *and_level, this, |
| 5724 | (Item_field*) args[0]->real_item(), equal_func, |
| 5725 | args + 1, 1, usable_tables, sargables); |
| 5726 | } |
| 5727 | if (is_local_field(args[1])) |
| 5728 | { |
| 5729 | add_key_equal_fields(join, key_fields, *and_level, this, |
| 5730 | (Item_field*) args[1]->real_item(), equal_func, |
| 5731 | args, 1, usable_tables, sargables); |
| 5732 | } |
| 5733 | } |
| 5734 | |
| 5735 | |
| 5736 | void |
| 5737 | Item_func_null_predicate::add_key_fields(JOIN *join, KEY_FIELD **key_fields, |
| 5738 | uint *and_level, |
| 5739 | table_map usable_tables, |
| 5740 | SARGABLE_PARAM **sargables) |
| 5741 | { |
| 5742 | /* column_name IS [NOT] NULL */ |
| 5743 | if (is_local_field(args[0]) && !(used_tables() & OUTER_REF_TABLE_BIT)) |
| 5744 | { |
| 5745 | Item *tmp= new (join->thd->mem_root) Item_null(join->thd); |
| 5746 | if (unlikely(!tmp)) // Should never be true |
| 5747 | return; |
| 5748 | add_key_equal_fields(join, key_fields, *and_level, this, |
| 5749 | (Item_field*) args[0]->real_item(), |
| 5750 | functype() == Item_func::ISNULL_FUNC, |
| 5751 | &tmp, 1, usable_tables, sargables); |
| 5752 | } |
| 5753 | } |
| 5754 | |
| 5755 | |
| 5756 | void |
| 5757 | Item_equal::add_key_fields(JOIN *join, KEY_FIELD **key_fields, |
| 5758 | uint *and_level, table_map usable_tables, |
| 5759 | SARGABLE_PARAM **sargables) |
| 5760 | { |
| 5761 | Item *const_item2= get_const(); |
| 5762 | Item_equal_fields_iterator it(*this); |
| 5763 | if (const_item2) |
| 5764 | { |
| 5765 | |
| 5766 | /* |
| 5767 | For each field field1 from item_equal consider the equality |
| 5768 | field1=const_item as a condition allowing an index access of the table |
| 5769 | with field1 by the keys value of field1. |
| 5770 | */ |
| 5771 | while (it++) |
| 5772 | { |
| 5773 | Field *equal_field= it.get_curr_field(); |
| 5774 | add_key_field(join, key_fields, *and_level, this, equal_field, |
| 5775 | TRUE, &const_item2, 1, usable_tables, sargables); |
| 5776 | } |
| 5777 | } |
| 5778 | else |
| 5779 | { |
| 5780 | /* |
| 5781 | Consider all pairs of different fields included into item_equal. |
| 5782 | For each of them (field1, field1) consider the equality |
| 5783 | field1=field2 as a condition allowing an index access of the table |
| 5784 | with field1 by the keys value of field2. |
| 5785 | */ |
| 5786 | Item_equal_fields_iterator fi(*this); |
| 5787 | while (fi++) |
| 5788 | { |
| 5789 | Field *field= fi.get_curr_field(); |
| 5790 | Item *item; |
| 5791 | while ((item= it++)) |
| 5792 | { |
| 5793 | Field *equal_field= it.get_curr_field(); |
| 5794 | if (!field->eq(equal_field)) |
| 5795 | { |
| 5796 | add_key_field(join, key_fields, *and_level, this, field, |
| 5797 | TRUE, &item, 1, usable_tables, |
| 5798 | sargables); |
| 5799 | } |
| 5800 | } |
| 5801 | it.rewind(); |
| 5802 | } |
| 5803 | } |
| 5804 | } |
| 5805 | |
| 5806 | |
| 5807 | static uint |
| 5808 | max_part_bit(key_part_map bits) |
| 5809 | { |
| 5810 | uint found; |
| 5811 | for (found=0; bits & 1 ; found++,bits>>=1) ; |
| 5812 | return found; |
| 5813 | } |
| 5814 | |
| 5815 | |
| 5816 | /** |
| 5817 | Add a new keuse to the specified array of KEYUSE objects |
| 5818 | |
| 5819 | @param[in,out] keyuse_array array of keyuses to be extended |
| 5820 | @param[in] key_field info on the key use occurrence |
| 5821 | @param[in] key key number for the keyse to be added |
| 5822 | @param[in] part key part for the keyuse to be added |
| 5823 | |
| 5824 | @note |
| 5825 | The function builds a new KEYUSE object for a key use utilizing the info |
| 5826 | on the left and right parts of the given key use extracted from the |
| 5827 | structure key_field, the key number and key part for this key use. |
| 5828 | The built object is added to the dynamic array keyuse_array. |
| 5829 | |
| 5830 | @retval 0 the built object is succesfully added |
| 5831 | @retval 1 otherwise |
| 5832 | */ |
| 5833 | |
| 5834 | static bool |
| 5835 | add_keyuse(DYNAMIC_ARRAY *keyuse_array, KEY_FIELD *key_field, |
| 5836 | uint key, uint part) |
| 5837 | { |
| 5838 | KEYUSE keyuse; |
| 5839 | Field *field= key_field->field; |
| 5840 | |
| 5841 | keyuse.table= field->table; |
| 5842 | keyuse.val= key_field->val; |
| 5843 | keyuse.key= key; |
| 5844 | if (!is_hash_join_key_no(key)) |
| 5845 | { |
| 5846 | keyuse.keypart=part; |
| 5847 | keyuse.keypart_map= (key_part_map) 1 << part; |
| 5848 | } |
| 5849 | else |
| 5850 | { |
| 5851 | keyuse.keypart= field->field_index; |
| 5852 | keyuse.keypart_map= (key_part_map) 0; |
| 5853 | } |
| 5854 | keyuse.used_tables= key_field->val->used_tables(); |
| 5855 | keyuse.optimize= key_field->optimize & KEY_OPTIMIZE_REF_OR_NULL; |
| 5856 | keyuse.ref_table_rows= 0; |
| 5857 | keyuse.null_rejecting= key_field->null_rejecting; |
| 5858 | keyuse.cond_guard= key_field->cond_guard; |
| 5859 | keyuse.sj_pred_no= key_field->sj_pred_no; |
| 5860 | keyuse.validity_ref= 0; |
| 5861 | return (insert_dynamic(keyuse_array,(uchar*) &keyuse)); |
| 5862 | } |
| 5863 | |
| 5864 | |
| 5865 | /* |
| 5866 | Add all keys with uses 'field' for some keypart |
| 5867 | If field->and_level != and_level then only mark key_part as const_part |
| 5868 | |
| 5869 | RETURN |
| 5870 | 0 - OK |
| 5871 | 1 - Out of memory. |
| 5872 | */ |
| 5873 | |
| 5874 | static bool |
| 5875 | add_key_part(DYNAMIC_ARRAY *keyuse_array, KEY_FIELD *key_field) |
| 5876 | { |
| 5877 | Field *field=key_field->field; |
| 5878 | TABLE *form= field->table; |
| 5879 | |
| 5880 | if (key_field->eq_func && !(key_field->optimize & KEY_OPTIMIZE_EXISTS)) |
| 5881 | { |
| 5882 | for (uint key=0 ; key < form->s->keys ; key++) |
| 5883 | { |
| 5884 | if (!(form->keys_in_use_for_query.is_set(key))) |
| 5885 | continue; |
| 5886 | if (form->key_info[key].flags & (HA_FULLTEXT | HA_SPATIAL)) |
| 5887 | continue; // ToDo: ft-keys in non-ft queries. SerG |
| 5888 | |
| 5889 | KEY *keyinfo= form->key_info+key; |
| 5890 | uint key_parts= form->actual_n_key_parts(keyinfo); |
| 5891 | for (uint part=0 ; part < key_parts ; part++) |
| 5892 | { |
| 5893 | if (field->eq(form->key_info[key].key_part[part].field) && |
| 5894 | field->can_optimize_keypart_ref(key_field->cond, key_field->val)) |
| 5895 | { |
| 5896 | if (add_keyuse(keyuse_array, key_field, key, part)) |
| 5897 | return TRUE; |
| 5898 | } |
| 5899 | } |
| 5900 | } |
| 5901 | if (field->hash_join_is_possible() && |
| 5902 | (key_field->optimize & KEY_OPTIMIZE_EQ) && |
| 5903 | key_field->val->used_tables()) |
| 5904 | { |
| 5905 | if (!field->can_optimize_hash_join(key_field->cond, key_field->val)) |
| 5906 | return false; |
| 5907 | if (form->is_splittable()) |
| 5908 | form->add_splitting_info_for_key_field(key_field); |
| 5909 | /* |
| 5910 | If a key use is extracted from an equi-join predicate then it is |
| 5911 | added not only as a key use for every index whose component can |
| 5912 | be evalusted utilizing this key use, but also as a key use for |
| 5913 | hash join. Such key uses are marked with a special key number. |
| 5914 | */ |
| 5915 | if (add_keyuse(keyuse_array, key_field, get_hash_join_key_no(), 0)) |
| 5916 | return TRUE; |
| 5917 | } |
| 5918 | } |
| 5919 | return FALSE; |
| 5920 | } |
| 5921 | |
| 5922 | static bool |
| 5923 | add_ft_keys(DYNAMIC_ARRAY *keyuse_array, |
| 5924 | JOIN_TAB *stat,COND *cond,table_map usable_tables) |
| 5925 | { |
| 5926 | Item_func_match *cond_func=NULL; |
| 5927 | |
| 5928 | if (!cond) |
| 5929 | return FALSE; |
| 5930 | |
| 5931 | if (cond->type() == Item::FUNC_ITEM) |
| 5932 | { |
| 5933 | Item_func *func=(Item_func *)cond; |
| 5934 | Item_func::Functype functype= func->functype(); |
| 5935 | if (functype == Item_func::FT_FUNC) |
| 5936 | cond_func=(Item_func_match *)cond; |
| 5937 | else if (func->argument_count() == 2) |
| 5938 | { |
| 5939 | Item *arg0=(Item *)(func->arguments()[0]), |
| 5940 | *arg1=(Item *)(func->arguments()[1]); |
| 5941 | if (arg1->const_item() && arg1->cols() == 1 && |
| 5942 | arg0->type() == Item::FUNC_ITEM && |
| 5943 | ((Item_func *) arg0)->functype() == Item_func::FT_FUNC && |
| 5944 | ((functype == Item_func::GE_FUNC && arg1->val_real() > 0) || |
| 5945 | (functype == Item_func::GT_FUNC && arg1->val_real() >=0))) |
| 5946 | cond_func= (Item_func_match *) arg0; |
| 5947 | else if (arg0->const_item() && arg0->cols() == 1 && |
| 5948 | arg1->type() == Item::FUNC_ITEM && |
| 5949 | ((Item_func *) arg1)->functype() == Item_func::FT_FUNC && |
| 5950 | ((functype == Item_func::LE_FUNC && arg0->val_real() > 0) || |
| 5951 | (functype == Item_func::LT_FUNC && arg0->val_real() >=0))) |
| 5952 | cond_func= (Item_func_match *) arg1; |
| 5953 | } |
| 5954 | } |
| 5955 | else if (cond->type() == Item::COND_ITEM) |
| 5956 | { |
| 5957 | List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list()); |
| 5958 | |
| 5959 | if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC) |
| 5960 | { |
| 5961 | Item *item; |
| 5962 | while ((item=li++)) |
| 5963 | { |
| 5964 | if (add_ft_keys(keyuse_array,stat,item,usable_tables)) |
| 5965 | return TRUE; |
| 5966 | } |
| 5967 | } |
| 5968 | } |
| 5969 | |
| 5970 | if (!cond_func || cond_func->key == NO_SUCH_KEY || |
| 5971 | !(usable_tables & cond_func->table->map)) |
| 5972 | return FALSE; |
| 5973 | |
| 5974 | KEYUSE keyuse; |
| 5975 | keyuse.table= cond_func->table; |
| 5976 | keyuse.val = cond_func; |
| 5977 | keyuse.key = cond_func->key; |
| 5978 | keyuse.keypart= FT_KEYPART; |
| 5979 | keyuse.used_tables=cond_func->key_item()->used_tables(); |
| 5980 | keyuse.optimize= 0; |
| 5981 | keyuse.keypart_map= 0; |
| 5982 | keyuse.sj_pred_no= UINT_MAX; |
| 5983 | keyuse.validity_ref= 0; |
| 5984 | return insert_dynamic(keyuse_array,(uchar*) &keyuse); |
| 5985 | } |
| 5986 | |
| 5987 | |
| 5988 | static int |
| 5989 | sort_keyuse(KEYUSE *a,KEYUSE *b) |
| 5990 | { |
| 5991 | int res; |
| 5992 | if (a->table->tablenr != b->table->tablenr) |
| 5993 | return (int) (a->table->tablenr - b->table->tablenr); |
| 5994 | if (a->key != b->key) |
| 5995 | return (int) (a->key - b->key); |
| 5996 | if (a->key == MAX_KEY && b->key == MAX_KEY && |
| 5997 | a->used_tables != b->used_tables) |
| 5998 | return (int) ((ulong) a->used_tables - (ulong) b->used_tables); |
| 5999 | if (a->keypart != b->keypart) |
| 6000 | return (int) (a->keypart - b->keypart); |
| 6001 | // Place const values before other ones |
| 6002 | if ((res= MY_TEST((a->used_tables & ~OUTER_REF_TABLE_BIT)) - |
| 6003 | MY_TEST((b->used_tables & ~OUTER_REF_TABLE_BIT)))) |
| 6004 | return res; |
| 6005 | /* Place rows that are not 'OPTIMIZE_REF_OR_NULL' first */ |
| 6006 | return (int) ((a->optimize & KEY_OPTIMIZE_REF_OR_NULL) - |
| 6007 | (b->optimize & KEY_OPTIMIZE_REF_OR_NULL)); |
| 6008 | } |
| 6009 | |
| 6010 | |
| 6011 | /* |
| 6012 | Add to KEY_FIELD array all 'ref' access candidates within nested join. |
| 6013 | |
| 6014 | This function populates KEY_FIELD array with entries generated from the |
| 6015 | ON condition of the given nested join, and does the same for nested joins |
| 6016 | contained within this nested join. |
| 6017 | |
| 6018 | @param[in] nested_join_table Nested join pseudo-table to process |
| 6019 | @param[in,out] end End of the key field array |
| 6020 | @param[in,out] and_level And-level |
| 6021 | @param[in,out] sargables Array of found sargable candidates |
| 6022 | |
| 6023 | |
| 6024 | @note |
| 6025 | We can add accesses to the tables that are direct children of this nested |
| 6026 | join (1), and are not inner tables w.r.t their neighbours (2). |
| 6027 | |
| 6028 | Example for #1 (outer brackets pair denotes nested join this function is |
| 6029 | invoked for): |
| 6030 | @code |
| 6031 | ... LEFT JOIN (t1 LEFT JOIN (t2 ... ) ) ON cond |
| 6032 | @endcode |
| 6033 | Example for #2: |
| 6034 | @code |
| 6035 | ... LEFT JOIN (t1 LEFT JOIN t2 ) ON cond |
| 6036 | @endcode |
| 6037 | In examples 1-2 for condition cond, we can add 'ref' access candidates to |
| 6038 | t1 only. |
| 6039 | Example #3: |
| 6040 | @code |
| 6041 | ... LEFT JOIN (t1, t2 LEFT JOIN t3 ON inner_cond) ON cond |
| 6042 | @endcode |
| 6043 | Here we can add 'ref' access candidates for t1 and t2, but not for t3. |
| 6044 | */ |
| 6045 | |
| 6046 | static void add_key_fields_for_nj(JOIN *join, TABLE_LIST *nested_join_table, |
| 6047 | KEY_FIELD **end, uint *and_level, |
| 6048 | SARGABLE_PARAM **sargables) |
| 6049 | { |
| 6050 | List_iterator<TABLE_LIST> li(nested_join_table->nested_join->join_list); |
| 6051 | List_iterator<TABLE_LIST> li2(nested_join_table->nested_join->join_list); |
| 6052 | bool have_another = FALSE; |
| 6053 | table_map tables= 0; |
| 6054 | TABLE_LIST *table; |
| 6055 | DBUG_ASSERT(nested_join_table->nested_join); |
| 6056 | |
| 6057 | while ((table= li++) || (have_another && (li=li2, have_another=FALSE, |
| 6058 | (table= li++)))) |
| 6059 | { |
| 6060 | if (table->nested_join) |
| 6061 | { |
| 6062 | if (!table->on_expr) |
| 6063 | { |
| 6064 | /* It's a semi-join nest. Walk into it as if it wasn't a nest */ |
| 6065 | have_another= TRUE; |
| 6066 | li2= li; |
| 6067 | li= List_iterator<TABLE_LIST>(table->nested_join->join_list); |
| 6068 | } |
| 6069 | else |
| 6070 | add_key_fields_for_nj(join, table, end, and_level, sargables); |
| 6071 | } |
| 6072 | else |
| 6073 | if (!table->on_expr) |
| 6074 | tables |= table->table->map; |
| 6075 | } |
| 6076 | if (nested_join_table->on_expr) |
| 6077 | nested_join_table->on_expr->add_key_fields(join, end, and_level, tables, |
| 6078 | sargables); |
| 6079 | } |
| 6080 | |
| 6081 | |
| 6082 | void count_cond_for_nj(SELECT_LEX *sel, TABLE_LIST *nested_join_table) |
| 6083 | { |
| 6084 | List_iterator<TABLE_LIST> li(nested_join_table->nested_join->join_list); |
| 6085 | List_iterator<TABLE_LIST> li2(nested_join_table->nested_join->join_list); |
| 6086 | bool have_another = FALSE; |
| 6087 | TABLE_LIST *table; |
| 6088 | |
| 6089 | while ((table= li++) || (have_another && (li=li2, have_another=FALSE, |
| 6090 | (table= li++)))) |
| 6091 | if (table->nested_join) |
| 6092 | { |
| 6093 | if (!table->on_expr) |
| 6094 | { |
| 6095 | /* It's a semi-join nest. Walk into it as if it wasn't a nest */ |
| 6096 | have_another= TRUE; |
| 6097 | li2= li; |
| 6098 | li= List_iterator<TABLE_LIST>(table->nested_join->join_list); |
| 6099 | } |
| 6100 | else |
| 6101 | count_cond_for_nj(sel, table); |
| 6102 | } |
| 6103 | if (nested_join_table->on_expr) |
| 6104 | nested_join_table->on_expr->walk(&Item::count_sargable_conds, 0, sel); |
| 6105 | |
| 6106 | } |
| 6107 | |
| 6108 | /** |
| 6109 | Update keyuse array with all possible keys we can use to fetch rows. |
| 6110 | |
| 6111 | @param thd |
| 6112 | @param[out] keyuse Put here ordered array of KEYUSE structures |
| 6113 | @param join_tab Array in tablenr_order |
| 6114 | @param tables Number of tables in join |
| 6115 | @param cond WHERE condition (note that the function analyzes |
| 6116 | join_tab[i]->on_expr too) |
| 6117 | @param normal_tables Tables not inner w.r.t some outer join (ones |
| 6118 | for which we can make ref access based the WHERE |
| 6119 | clause) |
| 6120 | @param select_lex current SELECT |
| 6121 | @param[out] sargables Array of found sargable candidates |
| 6122 | |
| 6123 | @retval |
| 6124 | 0 OK |
| 6125 | @retval |
| 6126 | 1 Out of memory. |
| 6127 | */ |
| 6128 | |
| 6129 | static bool |
| 6130 | update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab, |
| 6131 | uint tables, COND *cond, table_map normal_tables, |
| 6132 | SELECT_LEX *select_lex, SARGABLE_PARAM **sargables) |
| 6133 | { |
| 6134 | uint and_level,i; |
| 6135 | KEY_FIELD *key_fields, *end, *field; |
| 6136 | uint sz; |
| 6137 | uint m= MY_MAX(select_lex->max_equal_elems,1); |
| 6138 | DBUG_ENTER("update_ref_and_keys" ); |
| 6139 | DBUG_PRINT("enter" , ("normal_tables: %llx" , normal_tables)); |
| 6140 | |
| 6141 | SELECT_LEX *sel=thd->lex->current_select; |
| 6142 | sel->cond_count= 0; |
| 6143 | sel->between_count= 0; |
| 6144 | if (cond) |
| 6145 | cond->walk(&Item::count_sargable_conds, 0, sel); |
| 6146 | for (i=0 ; i < tables ; i++) |
| 6147 | { |
| 6148 | if (*join_tab[i].on_expr_ref) |
| 6149 | (*join_tab[i].on_expr_ref)->walk(&Item::count_sargable_conds, 0, sel); |
| 6150 | } |
| 6151 | { |
| 6152 | List_iterator<TABLE_LIST> li(*join_tab->join->join_list); |
| 6153 | TABLE_LIST *table; |
| 6154 | while ((table= li++)) |
| 6155 | { |
| 6156 | if (table->nested_join) |
| 6157 | count_cond_for_nj(sel, table); |
| 6158 | } |
| 6159 | } |
| 6160 | |
| 6161 | /* |
| 6162 | We use the same piece of memory to store both KEY_FIELD |
| 6163 | and SARGABLE_PARAM structure. |
| 6164 | KEY_FIELD values are placed at the beginning this memory |
| 6165 | while SARGABLE_PARAM values are put at the end. |
| 6166 | All predicates that are used to fill arrays of KEY_FIELD |
| 6167 | and SARGABLE_PARAM structures have at most 2 arguments |
| 6168 | except BETWEEN predicates that have 3 arguments and |
| 6169 | IN predicates. |
| 6170 | This any predicate if it's not BETWEEN/IN can be used |
| 6171 | directly to fill at most 2 array elements, either of KEY_FIELD |
| 6172 | or SARGABLE_PARAM type. For a BETWEEN predicate 3 elements |
| 6173 | can be filled as this predicate is considered as |
| 6174 | saragable with respect to each of its argument. |
| 6175 | An IN predicate can require at most 1 element as currently |
| 6176 | it is considered as sargable only for its first argument. |
| 6177 | Multiple equality can add elements that are filled after |
| 6178 | substitution of field arguments by equal fields. There |
| 6179 | can be not more than select_lex->max_equal_elems such |
| 6180 | substitutions. |
| 6181 | */ |
| 6182 | sz= MY_MAX(sizeof(KEY_FIELD),sizeof(SARGABLE_PARAM))* |
| 6183 | ((sel->cond_count*2 + sel->between_count)*m+1); |
| 6184 | if (!(key_fields=(KEY_FIELD*) thd->alloc(sz))) |
| 6185 | DBUG_RETURN(TRUE); /* purecov: inspected */ |
| 6186 | and_level= 0; |
| 6187 | field= end= key_fields; |
| 6188 | *sargables= (SARGABLE_PARAM *) key_fields + |
| 6189 | (sz - sizeof((*sargables)[0].field))/sizeof(SARGABLE_PARAM); |
| 6190 | /* set a barrier for the array of SARGABLE_PARAM */ |
| 6191 | (*sargables)[0].field= 0; |
| 6192 | |
| 6193 | if (my_init_dynamic_array2(keyuse, sizeof(KEYUSE), |
| 6194 | thd->alloc(sizeof(KEYUSE) * 20), 20, 64, |
| 6195 | MYF(MY_THREAD_SPECIFIC))) |
| 6196 | DBUG_RETURN(TRUE); |
| 6197 | |
| 6198 | if (cond) |
| 6199 | { |
| 6200 | KEY_FIELD *saved_field= field; |
| 6201 | cond->add_key_fields(join_tab->join, &end, &and_level, normal_tables, |
| 6202 | sargables); |
| 6203 | for (; field != end ; field++) |
| 6204 | { |
| 6205 | |
| 6206 | /* Mark that we can optimize LEFT JOIN */ |
| 6207 | if (field->val->type() == Item::NULL_ITEM && |
| 6208 | !field->field->real_maybe_null()) |
| 6209 | field->field->table->reginfo.not_exists_optimize=1; |
| 6210 | } |
| 6211 | field= saved_field; |
| 6212 | } |
| 6213 | for (i=0 ; i < tables ; i++) |
| 6214 | { |
| 6215 | /* |
| 6216 | Block the creation of keys for inner tables of outer joins. |
| 6217 | Here only the outer joins that can not be converted to |
| 6218 | inner joins are left and all nests that can be eliminated |
| 6219 | are flattened. |
| 6220 | In the future when we introduce conditional accesses |
| 6221 | for inner tables in outer joins these keys will be taken |
| 6222 | into account as well. |
| 6223 | */ |
| 6224 | if (*join_tab[i].on_expr_ref) |
| 6225 | (*join_tab[i].on_expr_ref)->add_key_fields(join_tab->join, &end, |
| 6226 | &and_level, |
| 6227 | join_tab[i].table->map, |
| 6228 | sargables); |
| 6229 | } |
| 6230 | |
| 6231 | /* Process ON conditions for the nested joins */ |
| 6232 | { |
| 6233 | List_iterator<TABLE_LIST> li(*join_tab->join->join_list); |
| 6234 | TABLE_LIST *table; |
| 6235 | while ((table= li++)) |
| 6236 | { |
| 6237 | if (table->nested_join) |
| 6238 | add_key_fields_for_nj(join_tab->join, table, &end, &and_level, |
| 6239 | sargables); |
| 6240 | } |
| 6241 | } |
| 6242 | |
| 6243 | /* fill keyuse with found key parts */ |
| 6244 | for ( ; field != end ; field++) |
| 6245 | { |
| 6246 | if (add_key_part(keyuse,field)) |
| 6247 | DBUG_RETURN(TRUE); |
| 6248 | } |
| 6249 | |
| 6250 | if (select_lex->ftfunc_list->elements) |
| 6251 | { |
| 6252 | if (add_ft_keys(keyuse,join_tab,cond,normal_tables)) |
| 6253 | DBUG_RETURN(TRUE); |
| 6254 | } |
| 6255 | |
| 6256 | DBUG_RETURN(FALSE); |
| 6257 | } |
| 6258 | |
| 6259 | |
| 6260 | /** |
| 6261 | Sort the array of possible keys and remove the following key parts: |
| 6262 | - ref if there is a keypart which is a ref and a const. |
| 6263 | (e.g. if there is a key(a,b) and the clause is a=3 and b=7 and b=t2.d, |
| 6264 | then we skip the key part corresponding to b=t2.d) |
| 6265 | - keyparts without previous keyparts |
| 6266 | (e.g. if there is a key(a,b,c) but only b < 5 (or a=2 and c < 3) is |
| 6267 | used in the query, we drop the partial key parts from consideration). |
| 6268 | Special treatment for ft-keys. |
| 6269 | */ |
| 6270 | |
| 6271 | bool sort_and_filter_keyuse(THD *thd, DYNAMIC_ARRAY *keyuse, |
| 6272 | bool skip_unprefixed_keyparts) |
| 6273 | { |
| 6274 | KEYUSE key_end, *prev, *save_pos, *use; |
| 6275 | uint found_eq_constant, i; |
| 6276 | |
| 6277 | DBUG_ASSERT(keyuse->elements); |
| 6278 | |
| 6279 | my_qsort(keyuse->buffer, keyuse->elements, sizeof(KEYUSE), |
| 6280 | (qsort_cmp) sort_keyuse); |
| 6281 | |
| 6282 | bzero((char*) &key_end, sizeof(key_end)); /* Add for easy testing */ |
| 6283 | if (insert_dynamic(keyuse, (uchar*) &key_end)) |
| 6284 | return TRUE; |
| 6285 | |
| 6286 | if (optimizer_flag(thd, OPTIMIZER_SWITCH_DERIVED_WITH_KEYS)) |
| 6287 | generate_derived_keys(keyuse); |
| 6288 | |
| 6289 | use= save_pos= dynamic_element(keyuse,0,KEYUSE*); |
| 6290 | prev= &key_end; |
| 6291 | found_eq_constant= 0; |
| 6292 | for (i=0 ; i < keyuse->elements-1 ; i++,use++) |
| 6293 | { |
| 6294 | if (!use->is_for_hash_join()) |
| 6295 | { |
| 6296 | if (!(use->used_tables & ~OUTER_REF_TABLE_BIT) && |
| 6297 | use->optimize != KEY_OPTIMIZE_REF_OR_NULL) |
| 6298 | use->table->const_key_parts[use->key]|= use->keypart_map; |
| 6299 | if (use->keypart != FT_KEYPART) |
| 6300 | { |
| 6301 | if (use->key == prev->key && use->table == prev->table) |
| 6302 | { |
| 6303 | if ((prev->keypart+1 < use->keypart && skip_unprefixed_keyparts) || |
| 6304 | (prev->keypart == use->keypart && found_eq_constant)) |
| 6305 | continue; /* remove */ |
| 6306 | } |
| 6307 | else if (use->keypart != 0 && skip_unprefixed_keyparts) |
| 6308 | continue; /* remove - first found must be 0 */ |
| 6309 | } |
| 6310 | |
| 6311 | prev= use; |
| 6312 | found_eq_constant= !use->used_tables; |
| 6313 | use->table->reginfo.join_tab->checked_keys.set_bit(use->key); |
| 6314 | } |
| 6315 | /* |
| 6316 | Old gcc used a memcpy(), which is undefined if save_pos==use: |
| 6317 | http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19410 |
| 6318 | http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39480 |
| 6319 | This also disables a valgrind warning, so better to have the test. |
| 6320 | */ |
| 6321 | if (save_pos != use) |
| 6322 | *save_pos= *use; |
| 6323 | /* Save ptr to first use */ |
| 6324 | if (!use->table->reginfo.join_tab->keyuse) |
| 6325 | use->table->reginfo.join_tab->keyuse= save_pos; |
| 6326 | save_pos++; |
| 6327 | } |
| 6328 | i= (uint) (save_pos-(KEYUSE*) keyuse->buffer); |
| 6329 | (void) set_dynamic(keyuse,(uchar*) &key_end,i); |
| 6330 | keyuse->elements= i; |
| 6331 | |
| 6332 | return FALSE; |
| 6333 | } |
| 6334 | |
| 6335 | |
| 6336 | /** |
| 6337 | Update some values in keyuse for faster choose_plan() loop. |
| 6338 | */ |
| 6339 | |
| 6340 | void optimize_keyuse(JOIN *join, DYNAMIC_ARRAY *keyuse_array) |
| 6341 | { |
| 6342 | KEYUSE *end,*keyuse= dynamic_element(keyuse_array, 0, KEYUSE*); |
| 6343 | |
| 6344 | for (end= keyuse+ keyuse_array->elements ; keyuse < end ; keyuse++) |
| 6345 | { |
| 6346 | table_map map; |
| 6347 | /* |
| 6348 | If we find a ref, assume this table matches a proportional |
| 6349 | part of this table. |
| 6350 | For example 100 records matching a table with 5000 records |
| 6351 | gives 5000/100 = 50 records per key |
| 6352 | Constant tables are ignored. |
| 6353 | To avoid bad matches, we don't make ref_table_rows less than 100. |
| 6354 | */ |
| 6355 | keyuse->ref_table_rows= ~(ha_rows) 0; // If no ref |
| 6356 | if (keyuse->used_tables & |
| 6357 | (map= (keyuse->used_tables & ~join->const_table_map & |
| 6358 | ~OUTER_REF_TABLE_BIT))) |
| 6359 | { |
| 6360 | uint n_tables= my_count_bits(map); |
| 6361 | if (n_tables == 1) // Only one table |
| 6362 | { |
| 6363 | Table_map_iterator it(map); |
| 6364 | int tablenr= it.next_bit(); |
| 6365 | DBUG_ASSERT(tablenr != Table_map_iterator::BITMAP_END); |
| 6366 | TABLE *tmp_table=join->table[tablenr]; |
| 6367 | if (tmp_table) // already created |
| 6368 | keyuse->ref_table_rows= MY_MAX(tmp_table->file->stats.records, 100); |
| 6369 | } |
| 6370 | } |
| 6371 | /* |
| 6372 | Outer reference (external field) is constant for single executing |
| 6373 | of subquery |
| 6374 | */ |
| 6375 | if (keyuse->used_tables == OUTER_REF_TABLE_BIT) |
| 6376 | keyuse->ref_table_rows= 1; |
| 6377 | } |
| 6378 | } |
| 6379 | |
| 6380 | |
| 6381 | /** |
| 6382 | Check for the presence of AGGFN(DISTINCT a) queries that may be subject |
| 6383 | to loose index scan. |
| 6384 | |
| 6385 | |
| 6386 | Check if the query is a subject to AGGFN(DISTINCT) using loose index scan |
| 6387 | (QUICK_GROUP_MIN_MAX_SELECT). |
| 6388 | Optionally (if out_args is supplied) will push the arguments of |
| 6389 | AGGFN(DISTINCT) to the list |
| 6390 | |
| 6391 | Check for every COUNT(DISTINCT), AVG(DISTINCT) or |
| 6392 | SUM(DISTINCT). These can be resolved by Loose Index Scan as long |
| 6393 | as all the aggregate distinct functions refer to the same |
| 6394 | fields. Thus: |
| 6395 | |
| 6396 | SELECT AGGFN(DISTINCT a, b), AGGFN(DISTINCT b, a)... => can use LIS |
| 6397 | SELECT AGGFN(DISTINCT a), AGGFN(DISTINCT a) ... => can use LIS |
| 6398 | SELECT AGGFN(DISTINCT a, b), AGGFN(DISTINCT a) ... => cannot use LIS |
| 6399 | SELECT AGGFN(DISTINCT a), AGGFN(DISTINCT b) ... => cannot use LIS |
| 6400 | etc. |
| 6401 | |
| 6402 | @param join the join to check |
| 6403 | @param[out] out_args Collect the arguments of the aggregate functions |
| 6404 | to a list. We don't worry about duplicates as |
| 6405 | these will be sorted out later in |
| 6406 | get_best_group_min_max. |
| 6407 | |
| 6408 | @return does the query qualify for indexed AGGFN(DISTINCT) |
| 6409 | @retval true it does |
| 6410 | @retval false AGGFN(DISTINCT) must apply distinct in it. |
| 6411 | */ |
| 6412 | |
| 6413 | bool |
| 6414 | is_indexed_agg_distinct(JOIN *join, List<Item_field> *out_args) |
| 6415 | { |
| 6416 | Item_sum **sum_item_ptr; |
| 6417 | bool result= false; |
| 6418 | Field_map first_aggdistinct_fields; |
| 6419 | |
| 6420 | if (join->table_count != 1 || /* reference more than 1 table */ |
| 6421 | join->select_distinct || /* or a DISTINCT */ |
| 6422 | join->select_lex->olap == ROLLUP_TYPE) /* Check (B3) for ROLLUP */ |
| 6423 | return false; |
| 6424 | |
| 6425 | if (join->make_sum_func_list(join->all_fields, join->fields_list, true)) |
| 6426 | return false; |
| 6427 | |
| 6428 | for (sum_item_ptr= join->sum_funcs; *sum_item_ptr; sum_item_ptr++) |
| 6429 | { |
| 6430 | Item_sum *sum_item= *sum_item_ptr; |
| 6431 | Field_map cur_aggdistinct_fields; |
| 6432 | Item *expr; |
| 6433 | /* aggregate is not AGGFN(DISTINCT) or more than 1 argument to it */ |
| 6434 | switch (sum_item->sum_func()) |
| 6435 | { |
| 6436 | case Item_sum::MIN_FUNC: |
| 6437 | case Item_sum::MAX_FUNC: |
| 6438 | continue; |
| 6439 | case Item_sum::COUNT_DISTINCT_FUNC: |
| 6440 | break; |
| 6441 | case Item_sum::AVG_DISTINCT_FUNC: |
| 6442 | case Item_sum::SUM_DISTINCT_FUNC: |
| 6443 | if (sum_item->get_arg_count() == 1) |
| 6444 | break; |
| 6445 | /* fall through */ |
| 6446 | default: return false; |
| 6447 | } |
| 6448 | /* |
| 6449 | We arrive here for every COUNT(DISTINCT),AVG(DISTINCT) or SUM(DISTINCT). |
| 6450 | Collect the arguments of the aggregate functions to a list. |
| 6451 | We don't worry about duplicates as these will be sorted out later in |
| 6452 | get_best_group_min_max |
| 6453 | */ |
| 6454 | for (uint i= 0; i < sum_item->get_arg_count(); i++) |
| 6455 | { |
| 6456 | expr= sum_item->get_arg(i); |
| 6457 | /* The AGGFN(DISTINCT) arg is not an attribute? */ |
| 6458 | if (expr->real_item()->type() != Item::FIELD_ITEM) |
| 6459 | return false; |
| 6460 | |
| 6461 | Item_field* item= static_cast<Item_field*>(expr->real_item()); |
| 6462 | if (out_args) |
| 6463 | out_args->push_back(item, join->thd->mem_root); |
| 6464 | |
| 6465 | cur_aggdistinct_fields.set_bit(item->field->field_index); |
| 6466 | result= true; |
| 6467 | } |
| 6468 | /* |
| 6469 | If there are multiple aggregate functions, make sure that they all |
| 6470 | refer to exactly the same set of columns. |
| 6471 | */ |
| 6472 | if (first_aggdistinct_fields.is_clear_all()) |
| 6473 | first_aggdistinct_fields.merge(cur_aggdistinct_fields); |
| 6474 | else if (first_aggdistinct_fields != cur_aggdistinct_fields) |
| 6475 | return false; |
| 6476 | } |
| 6477 | |
| 6478 | return result; |
| 6479 | } |
| 6480 | |
| 6481 | |
| 6482 | /** |
| 6483 | Discover the indexes that can be used for GROUP BY or DISTINCT queries. |
| 6484 | |
| 6485 | If the query has a GROUP BY clause, find all indexes that contain all |
| 6486 | GROUP BY fields, and add those indexes to join->const_keys. |
| 6487 | |
| 6488 | If the query has a DISTINCT clause, find all indexes that contain all |
| 6489 | SELECT fields, and add those indexes to join->const_keys. |
| 6490 | This allows later on such queries to be processed by a |
| 6491 | QUICK_GROUP_MIN_MAX_SELECT. |
| 6492 | |
| 6493 | @param join |
| 6494 | @param join_tab |
| 6495 | |
| 6496 | @return |
| 6497 | None |
| 6498 | */ |
| 6499 | |
| 6500 | static void |
| 6501 | add_group_and_distinct_keys(JOIN *join, JOIN_TAB *join_tab) |
| 6502 | { |
| 6503 | List<Item_field> indexed_fields; |
| 6504 | List_iterator<Item_field> indexed_fields_it(indexed_fields); |
| 6505 | ORDER *cur_group; |
| 6506 | Item_field *cur_item; |
| 6507 | key_map possible_keys(0); |
| 6508 | |
| 6509 | if (join->group_list || join->simple_group) |
| 6510 | { /* Collect all query fields referenced in the GROUP clause. */ |
| 6511 | for (cur_group= join->group_list; cur_group; cur_group= cur_group->next) |
| 6512 | (*cur_group->item)->walk(&Item::collect_item_field_processor, 0, |
| 6513 | &indexed_fields); |
| 6514 | } |
| 6515 | else if (join->select_distinct) |
| 6516 | { /* Collect all query fields referenced in the SELECT clause. */ |
| 6517 | List<Item> &select_items= join->fields_list; |
| 6518 | List_iterator<Item> select_items_it(select_items); |
| 6519 | Item *item; |
| 6520 | while ((item= select_items_it++)) |
| 6521 | item->walk(&Item::collect_item_field_processor, 0, &indexed_fields); |
| 6522 | } |
| 6523 | else if (join->tmp_table_param.sum_func_count && |
| 6524 | is_indexed_agg_distinct(join, &indexed_fields)) |
| 6525 | { |
| 6526 | join->sort_and_group= 1; |
| 6527 | } |
| 6528 | else |
| 6529 | return; |
| 6530 | |
| 6531 | if (indexed_fields.elements == 0) |
| 6532 | return; |
| 6533 | |
| 6534 | /* Intersect the keys of all group fields. */ |
| 6535 | cur_item= indexed_fields_it++; |
| 6536 | possible_keys.merge(cur_item->field->part_of_key); |
| 6537 | while ((cur_item= indexed_fields_it++)) |
| 6538 | { |
| 6539 | possible_keys.intersect(cur_item->field->part_of_key); |
| 6540 | } |
| 6541 | |
| 6542 | if (!possible_keys.is_clear_all()) |
| 6543 | join_tab->const_keys.merge(possible_keys); |
| 6544 | } |
| 6545 | |
| 6546 | |
| 6547 | /***************************************************************************** |
| 6548 | Go through all combinations of not marked tables and find the one |
| 6549 | which uses least records |
| 6550 | *****************************************************************************/ |
| 6551 | |
| 6552 | /** Save const tables first as used tables. */ |
| 6553 | |
| 6554 | void set_position(JOIN *join,uint idx,JOIN_TAB *table,KEYUSE *key) |
| 6555 | { |
| 6556 | join->positions[idx].table= table; |
| 6557 | join->positions[idx].key=key; |
| 6558 | join->positions[idx].records_read=1.0; /* This is a const table */ |
| 6559 | join->positions[idx].cond_selectivity= 1.0; |
| 6560 | join->positions[idx].ref_depend_map= 0; |
| 6561 | |
| 6562 | // join->positions[idx].loosescan_key= MAX_KEY; /* Not a LooseScan */ |
| 6563 | join->positions[idx].sj_strategy= SJ_OPT_NONE; |
| 6564 | join->positions[idx].use_join_buffer= FALSE; |
| 6565 | |
| 6566 | /* Move the const table as down as possible in best_ref */ |
| 6567 | JOIN_TAB **pos=join->best_ref+idx+1; |
| 6568 | JOIN_TAB *next=join->best_ref[idx]; |
| 6569 | for (;next != table ; pos++) |
| 6570 | { |
| 6571 | JOIN_TAB *tmp=pos[0]; |
| 6572 | pos[0]=next; |
| 6573 | next=tmp; |
| 6574 | } |
| 6575 | join->best_ref[idx]=table; |
| 6576 | } |
| 6577 | |
| 6578 | |
| 6579 | /* |
| 6580 | Estimate how many records we will get if we read just this table and apply |
| 6581 | a part of WHERE that can be checked for it. |
| 6582 | |
| 6583 | @detail |
| 6584 | Estimate how many records we will get if we |
| 6585 | - read the given table with its "independent" access method (either quick |
| 6586 | select or full table/index scan), |
| 6587 | - apply the part of WHERE that refers only to this table. |
| 6588 | |
| 6589 | @seealso |
| 6590 | table_cond_selectivity() produces selectivity of condition that is checked |
| 6591 | after joining rows from this table to rows from preceding tables. |
| 6592 | */ |
| 6593 | |
| 6594 | inline |
| 6595 | double matching_candidates_in_table(JOIN_TAB *s, bool with_found_constraint, |
| 6596 | uint use_cond_selectivity) |
| 6597 | { |
| 6598 | ha_rows records; |
| 6599 | double dbl_records; |
| 6600 | |
| 6601 | if (use_cond_selectivity > 1) |
| 6602 | { |
| 6603 | TABLE *table= s->table; |
| 6604 | double sel= table->cond_selectivity; |
| 6605 | double table_records= (double)table->stat_records(); |
| 6606 | dbl_records= table_records * sel; |
| 6607 | return dbl_records; |
| 6608 | } |
| 6609 | |
| 6610 | records = s->found_records; |
| 6611 | |
| 6612 | /* |
| 6613 | If there is a filtering condition on the table (i.e. ref analyzer found |
| 6614 | at least one "table.keyXpartY= exprZ", where exprZ refers only to tables |
| 6615 | preceding this table in the join order we're now considering), then |
| 6616 | assume that 25% of the rows will be filtered out by this condition. |
| 6617 | |
| 6618 | This heuristic is supposed to force tables used in exprZ to be before |
| 6619 | this table in join order. |
| 6620 | */ |
| 6621 | if (with_found_constraint) |
| 6622 | records-= records/4; |
| 6623 | |
| 6624 | /* |
| 6625 | If applicable, get a more accurate estimate. Don't use the two |
| 6626 | heuristics at once. |
| 6627 | */ |
| 6628 | if (s->table->quick_condition_rows != s->found_records) |
| 6629 | records= s->table->quick_condition_rows; |
| 6630 | |
| 6631 | dbl_records= (double)records; |
| 6632 | return dbl_records; |
| 6633 | } |
| 6634 | |
| 6635 | |
| 6636 | /** |
| 6637 | Find the best access path for an extension of a partial execution |
| 6638 | plan and add this path to the plan. |
| 6639 | |
| 6640 | The function finds the best access path to table 's' from the passed |
| 6641 | partial plan where an access path is the general term for any means to |
| 6642 | access the data in 's'. An access path may use either an index or a scan, |
| 6643 | whichever is cheaper. The input partial plan is passed via the array |
| 6644 | 'join->positions' of length 'idx'. The chosen access method for 's' and its |
| 6645 | cost are stored in 'join->positions[idx]'. |
| 6646 | |
| 6647 | @param join pointer to the structure providing all context info |
| 6648 | for the query |
| 6649 | @param s the table to be joined by the function |
| 6650 | @param thd thread for the connection that submitted the query |
| 6651 | @param remaining_tables set of tables not included into the partial plan yet |
| 6652 | @param idx the length of the partial plan |
| 6653 | @param disable_jbuf TRUE<=> Don't use join buffering |
| 6654 | @param record_count estimate for the number of records returned by the |
| 6655 | partial plan |
| 6656 | @param pos OUT Table access plan |
| 6657 | @param loose_scan_pos OUT Table plan that uses loosescan, or set cost to |
| 6658 | DBL_MAX if not possible. |
| 6659 | |
| 6660 | @return |
| 6661 | None |
| 6662 | */ |
| 6663 | |
| 6664 | void |
| 6665 | best_access_path(JOIN *join, |
| 6666 | JOIN_TAB *s, |
| 6667 | table_map remaining_tables, |
| 6668 | uint idx, |
| 6669 | bool disable_jbuf, |
| 6670 | double record_count, |
| 6671 | POSITION *pos, |
| 6672 | POSITION *loose_scan_pos) |
| 6673 | { |
| 6674 | THD *thd= join->thd; |
| 6675 | uint use_cond_selectivity= thd->variables.optimizer_use_condition_selectivity; |
| 6676 | KEYUSE *best_key= 0; |
| 6677 | uint best_max_key_part= 0; |
| 6678 | my_bool found_constraint= 0; |
| 6679 | double best= DBL_MAX; |
| 6680 | double best_time= DBL_MAX; |
| 6681 | double records= DBL_MAX; |
| 6682 | table_map best_ref_depends_map= 0; |
| 6683 | double tmp; |
| 6684 | ha_rows rec; |
| 6685 | bool best_uses_jbuf= FALSE; |
| 6686 | MY_BITMAP *eq_join_set= &s->table->eq_join_set; |
| 6687 | KEYUSE *hj_start_key= 0; |
| 6688 | SplM_plan_info *spl_plan= 0; |
| 6689 | |
| 6690 | disable_jbuf= disable_jbuf || idx == join->const_tables; |
| 6691 | |
| 6692 | Loose_scan_opt loose_scan_opt; |
| 6693 | DBUG_ENTER("best_access_path" ); |
| 6694 | |
| 6695 | bitmap_clear_all(eq_join_set); |
| 6696 | |
| 6697 | loose_scan_opt.init(join, s, remaining_tables); |
| 6698 | |
| 6699 | if (s->table->is_splittable()) |
| 6700 | spl_plan= s->choose_best_splitting(record_count, remaining_tables); |
| 6701 | |
| 6702 | if (s->keyuse) |
| 6703 | { /* Use key if possible */ |
| 6704 | KEYUSE *keyuse; |
| 6705 | KEYUSE *start_key=0; |
| 6706 | TABLE *table= s->table; |
| 6707 | double best_records= DBL_MAX; |
| 6708 | uint max_key_part=0; |
| 6709 | |
| 6710 | /* Test how we can use keys */ |
| 6711 | rec= s->records/MATCHING_ROWS_IN_OTHER_TABLE; // Assumed records/key |
| 6712 | for (keyuse=s->keyuse ; keyuse->table == table ;) |
| 6713 | { |
| 6714 | KEY *keyinfo; |
| 6715 | ulong key_flags; |
| 6716 | uint key_parts; |
| 6717 | key_part_map found_part= 0; |
| 6718 | table_map found_ref= 0; |
| 6719 | uint key= keyuse->key; |
| 6720 | bool ft_key= (keyuse->keypart == FT_KEYPART); |
| 6721 | /* Bitmap of keyparts where the ref access is over 'keypart=const': */ |
| 6722 | key_part_map const_part= 0; |
| 6723 | /* The or-null keypart in ref-or-null access: */ |
| 6724 | key_part_map ref_or_null_part= 0; |
| 6725 | if (is_hash_join_key_no(key)) |
| 6726 | { |
| 6727 | /* |
| 6728 | Hash join as any join employing join buffer can be used to join |
| 6729 | only those tables that are joined after the first non const table |
| 6730 | */ |
| 6731 | if (!(remaining_tables & keyuse->used_tables) && |
| 6732 | idx > join->const_tables) |
| 6733 | { |
| 6734 | if (!hj_start_key) |
| 6735 | hj_start_key= keyuse; |
| 6736 | bitmap_set_bit(eq_join_set, keyuse->keypart); |
| 6737 | } |
| 6738 | keyuse++; |
| 6739 | continue; |
| 6740 | } |
| 6741 | |
| 6742 | keyinfo= table->key_info+key; |
| 6743 | key_parts= table->actual_n_key_parts(keyinfo); |
| 6744 | key_flags= table->actual_key_flags(keyinfo); |
| 6745 | |
| 6746 | /* Calculate how many key segments of the current key we can use */ |
| 6747 | start_key= keyuse; |
| 6748 | |
| 6749 | loose_scan_opt.next_ref_key(); |
| 6750 | DBUG_PRINT("info" , ("Considering ref access on key %s" , |
| 6751 | keyuse->table->key_info[keyuse->key].name.str)); |
| 6752 | |
| 6753 | do /* For each keypart */ |
| 6754 | { |
| 6755 | uint keypart= keyuse->keypart; |
| 6756 | table_map best_part_found_ref= 0; |
| 6757 | double best_prev_record_reads= DBL_MAX; |
| 6758 | |
| 6759 | do /* For each way to access the keypart */ |
| 6760 | { |
| 6761 | /* |
| 6762 | if 1. expression doesn't refer to forward tables |
| 6763 | 2. we won't get two ref-or-null's |
| 6764 | */ |
| 6765 | if (!(remaining_tables & keyuse->used_tables) && |
| 6766 | (!keyuse->validity_ref || *keyuse->validity_ref) && |
| 6767 | s->access_from_tables_is_allowed(keyuse->used_tables, |
| 6768 | join->sjm_lookup_tables) && |
| 6769 | !(ref_or_null_part && (keyuse->optimize & |
| 6770 | KEY_OPTIMIZE_REF_OR_NULL))) |
| 6771 | { |
| 6772 | found_part|= keyuse->keypart_map; |
| 6773 | if (!(keyuse->used_tables & ~join->const_table_map)) |
| 6774 | const_part|= keyuse->keypart_map; |
| 6775 | |
| 6776 | double tmp2= prev_record_reads(join->positions, idx, |
| 6777 | (found_ref | keyuse->used_tables)); |
| 6778 | if (tmp2 < best_prev_record_reads) |
| 6779 | { |
| 6780 | best_part_found_ref= keyuse->used_tables & ~join->const_table_map; |
| 6781 | best_prev_record_reads= tmp2; |
| 6782 | } |
| 6783 | if (rec > keyuse->ref_table_rows) |
| 6784 | rec= keyuse->ref_table_rows; |
| 6785 | /* |
| 6786 | If there is one 'key_column IS NULL' expression, we can |
| 6787 | use this ref_or_null optimisation of this field |
| 6788 | */ |
| 6789 | if (keyuse->optimize & KEY_OPTIMIZE_REF_OR_NULL) |
| 6790 | ref_or_null_part |= keyuse->keypart_map; |
| 6791 | } |
| 6792 | loose_scan_opt.add_keyuse(remaining_tables, keyuse); |
| 6793 | keyuse++; |
| 6794 | } while (keyuse->table == table && keyuse->key == key && |
| 6795 | keyuse->keypart == keypart); |
| 6796 | found_ref|= best_part_found_ref; |
| 6797 | } while (keyuse->table == table && keyuse->key == key); |
| 6798 | |
| 6799 | /* |
| 6800 | Assume that that each key matches a proportional part of table. |
| 6801 | */ |
| 6802 | if (!found_part && !ft_key && !loose_scan_opt.have_a_case()) |
| 6803 | continue; // Nothing usable found |
| 6804 | |
| 6805 | if (rec < MATCHING_ROWS_IN_OTHER_TABLE) |
| 6806 | rec= MATCHING_ROWS_IN_OTHER_TABLE; // Fix for small tables |
| 6807 | |
| 6808 | /* |
| 6809 | ft-keys require special treatment |
| 6810 | */ |
| 6811 | if (ft_key) |
| 6812 | { |
| 6813 | /* |
| 6814 | Really, there should be records=0.0 (yes!) |
| 6815 | but 1.0 would be probably safer |
| 6816 | */ |
| 6817 | tmp= prev_record_reads(join->positions, idx, found_ref); |
| 6818 | records= 1.0; |
| 6819 | } |
| 6820 | else |
| 6821 | { |
| 6822 | found_constraint= MY_TEST(found_part); |
| 6823 | loose_scan_opt.check_ref_access_part1(s, key, start_key, found_part); |
| 6824 | |
| 6825 | /* Check if we found full key */ |
| 6826 | if (found_part == PREV_BITS(uint, key_parts) && |
| 6827 | !ref_or_null_part) |
| 6828 | { /* use eq key */ |
| 6829 | max_key_part= (uint) ~0; |
| 6830 | if ((key_flags & (HA_NOSAME | HA_NULL_PART_KEY)) == HA_NOSAME || |
| 6831 | MY_TEST(key_flags & HA_EXT_NOSAME)) |
| 6832 | { |
| 6833 | tmp = prev_record_reads(join->positions, idx, found_ref); |
| 6834 | records=1.0; |
| 6835 | } |
| 6836 | else |
| 6837 | { |
| 6838 | if (!found_ref) |
| 6839 | { /* We found a const key */ |
| 6840 | /* |
| 6841 | ReuseRangeEstimateForRef-1: |
| 6842 | We get here if we've found a ref(const) (c_i are constants): |
| 6843 | "(keypart1=c1) AND ... AND (keypartN=cN)" [ref_const_cond] |
| 6844 | |
| 6845 | If range optimizer was able to construct a "range" |
| 6846 | access on this index, then its condition "quick_cond" was |
| 6847 | eqivalent to ref_const_cond (*), and we can re-use E(#rows) |
| 6848 | from the range optimizer. |
| 6849 | |
| 6850 | Proof of (*): By properties of range and ref optimizers |
| 6851 | quick_cond will be equal or tighther than ref_const_cond. |
| 6852 | ref_const_cond already covers "smallest" possible interval - |
| 6853 | a singlepoint interval over all keyparts. Therefore, |
| 6854 | quick_cond is equivalent to ref_const_cond (if it was an |
| 6855 | empty interval we wouldn't have got here). |
| 6856 | */ |
| 6857 | if (table->quick_keys.is_set(key)) |
| 6858 | records= (double) table->quick_rows[key]; |
| 6859 | else |
| 6860 | { |
| 6861 | /* quick_range couldn't use key! */ |
| 6862 | records= (double) s->records/rec; |
| 6863 | } |
| 6864 | } |
| 6865 | else |
| 6866 | { |
| 6867 | if (!(records= keyinfo->actual_rec_per_key(key_parts-1))) |
| 6868 | { /* Prefer longer keys */ |
| 6869 | records= |
| 6870 | ((double) s->records / (double) rec * |
| 6871 | (1.0 + |
| 6872 | ((double) (table->s->max_key_length-keyinfo->key_length) / |
| 6873 | (double) table->s->max_key_length))); |
| 6874 | if (records < 2.0) |
| 6875 | records=2.0; /* Can't be as good as a unique */ |
| 6876 | } |
| 6877 | /* |
| 6878 | ReuseRangeEstimateForRef-2: We get here if we could not reuse |
| 6879 | E(#rows) from range optimizer. Make another try: |
| 6880 | |
| 6881 | If range optimizer produced E(#rows) for a prefix of the ref |
| 6882 | access we're considering, and that E(#rows) is lower then our |
| 6883 | current estimate, make an adjustment. The criteria of when we |
| 6884 | can make an adjustment is a special case of the criteria used |
| 6885 | in ReuseRangeEstimateForRef-3. |
| 6886 | */ |
| 6887 | if (table->quick_keys.is_set(key) && |
| 6888 | (const_part & |
| 6889 | (((key_part_map)1 << table->quick_key_parts[key])-1)) == |
| 6890 | (((key_part_map)1 << table->quick_key_parts[key])-1) && |
| 6891 | table->quick_n_ranges[key] == 1 && |
| 6892 | records > (double) table->quick_rows[key]) |
| 6893 | { |
| 6894 | records= (double) table->quick_rows[key]; |
| 6895 | } |
| 6896 | } |
| 6897 | /* Limit the number of matched rows */ |
| 6898 | tmp= records; |
| 6899 | set_if_smaller(tmp, (double) thd->variables.max_seeks_for_key); |
| 6900 | if (table->covering_keys.is_set(key)) |
| 6901 | tmp= table->file->keyread_time(key, 1, (ha_rows) tmp); |
| 6902 | else |
| 6903 | tmp= table->file->read_time(key, 1, |
| 6904 | (ha_rows) MY_MIN(tmp,s->worst_seeks)); |
| 6905 | tmp*= record_count; |
| 6906 | } |
| 6907 | } |
| 6908 | else |
| 6909 | { |
| 6910 | /* |
| 6911 | Use as much key-parts as possible and a uniq key is better |
| 6912 | than a not unique key |
| 6913 | Set tmp to (previous record count) * (records / combination) |
| 6914 | */ |
| 6915 | if ((found_part & 1) && |
| 6916 | (!(table->file->index_flags(key, 0, 0) & HA_ONLY_WHOLE_INDEX) || |
| 6917 | found_part == PREV_BITS(uint,keyinfo->user_defined_key_parts))) |
| 6918 | { |
| 6919 | max_key_part= max_part_bit(found_part); |
| 6920 | /* |
| 6921 | ReuseRangeEstimateForRef-3: |
| 6922 | We're now considering a ref[or_null] access via |
| 6923 | (t.keypart1=e1 AND ... AND t.keypartK=eK) [ OR |
| 6924 | (same-as-above but with one cond replaced |
| 6925 | with "t.keypart_i IS NULL")] (**) |
| 6926 | |
| 6927 | Try re-using E(#rows) from "range" optimizer: |
| 6928 | We can do so if "range" optimizer used the same intervals as |
| 6929 | in (**). The intervals used by range optimizer may be not |
| 6930 | available at this point (as "range" access might have choosen to |
| 6931 | create quick select over another index), so we can't compare |
| 6932 | them to (**). We'll make indirect judgements instead. |
| 6933 | The sufficient conditions for re-use are: |
| 6934 | (C1) All e_i in (**) are constants, i.e. found_ref==FALSE. (if |
| 6935 | this is not satisfied we have no way to know which ranges |
| 6936 | will be actually scanned by 'ref' until we execute the |
| 6937 | join) |
| 6938 | (C2) max #key parts in 'range' access == K == max_key_part (this |
| 6939 | is apparently a necessary requirement) |
| 6940 | |
| 6941 | We also have a property that "range optimizer produces equal or |
| 6942 | tighter set of scan intervals than ref(const) optimizer". Each |
| 6943 | of the intervals in (**) are "tightest possible" intervals when |
| 6944 | one limits itself to using keyparts 1..K (which we do in #2). |
| 6945 | From here it follows that range access used either one, or |
| 6946 | both of the (I1) and (I2) intervals: |
| 6947 | |
| 6948 | (t.keypart1=c1 AND ... AND t.keypartK=eK) (I1) |
| 6949 | (same-as-above but with one cond replaced |
| 6950 | with "t.keypart_i IS NULL") (I2) |
| 6951 | |
| 6952 | The remaining part is to exclude the situation where range |
| 6953 | optimizer used one interval while we're considering |
| 6954 | ref-or-null and looking for estimate for two intervals. This |
| 6955 | is done by last limitation: |
| 6956 | |
| 6957 | (C3) "range optimizer used (have ref_or_null?2:1) intervals" |
| 6958 | */ |
| 6959 | if (table->quick_keys.is_set(key) && !found_ref && //(C1) |
| 6960 | table->quick_key_parts[key] == max_key_part && //(C2) |
| 6961 | table->quick_n_ranges[key] == 1 + MY_TEST(ref_or_null_part)) //(C3) |
| 6962 | { |
| 6963 | tmp= records= (double) table->quick_rows[key]; |
| 6964 | } |
| 6965 | else |
| 6966 | { |
| 6967 | /* Check if we have statistic about the distribution */ |
| 6968 | if ((records= keyinfo->actual_rec_per_key(max_key_part-1))) |
| 6969 | { |
| 6970 | /* |
| 6971 | Fix for the case where the index statistics is too |
| 6972 | optimistic: If |
| 6973 | (1) We're considering ref(const) and there is quick select |
| 6974 | on the same index, |
| 6975 | (2) and that quick select uses more keyparts (i.e. it will |
| 6976 | scan equal/smaller interval then this ref(const)) |
| 6977 | (3) and E(#rows) for quick select is higher then our |
| 6978 | estimate, |
| 6979 | Then |
| 6980 | We'll use E(#rows) from quick select. |
| 6981 | |
| 6982 | Q: Why do we choose to use 'ref'? Won't quick select be |
| 6983 | cheaper in some cases ? |
| 6984 | TODO: figure this out and adjust the plan choice if needed. |
| 6985 | */ |
| 6986 | if (!found_ref && table->quick_keys.is_set(key) && // (1) |
| 6987 | table->quick_key_parts[key] > max_key_part && // (2) |
| 6988 | records < (double)table->quick_rows[key]) // (3) |
| 6989 | records= (double)table->quick_rows[key]; |
| 6990 | |
| 6991 | tmp= records; |
| 6992 | } |
| 6993 | else |
| 6994 | { |
| 6995 | /* |
| 6996 | Assume that the first key part matches 1% of the file |
| 6997 | and that the whole key matches 10 (duplicates) or 1 |
| 6998 | (unique) records. |
| 6999 | Assume also that more key matches proportionally more |
| 7000 | records |
| 7001 | This gives the formula: |
| 7002 | records = (x * (b-a) + a*c-b)/(c-1) |
| 7003 | |
| 7004 | b = records matched by whole key |
| 7005 | a = records matched by first key part (1% of all records?) |
| 7006 | c = number of key parts in key |
| 7007 | x = used key parts (1 <= x <= c) |
| 7008 | */ |
| 7009 | double rec_per_key; |
| 7010 | if (!(rec_per_key=(double) |
| 7011 | keyinfo->rec_per_key[keyinfo->user_defined_key_parts-1])) |
| 7012 | rec_per_key=(double) s->records/rec+1; |
| 7013 | |
| 7014 | if (!s->records) |
| 7015 | tmp = 0; |
| 7016 | else if (rec_per_key/(double) s->records >= 0.01) |
| 7017 | tmp = rec_per_key; |
| 7018 | else |
| 7019 | { |
| 7020 | double a=s->records*0.01; |
| 7021 | if (keyinfo->user_defined_key_parts > 1) |
| 7022 | tmp= (max_key_part * (rec_per_key - a) + |
| 7023 | a*keyinfo->user_defined_key_parts - rec_per_key)/ |
| 7024 | (keyinfo->user_defined_key_parts-1); |
| 7025 | else |
| 7026 | tmp= a; |
| 7027 | set_if_bigger(tmp,1.0); |
| 7028 | } |
| 7029 | records = (ulong) tmp; |
| 7030 | } |
| 7031 | |
| 7032 | if (ref_or_null_part) |
| 7033 | { |
| 7034 | /* We need to do two key searches to find key */ |
| 7035 | tmp *= 2.0; |
| 7036 | records *= 2.0; |
| 7037 | } |
| 7038 | |
| 7039 | /* |
| 7040 | ReuseRangeEstimateForRef-4: We get here if we could not reuse |
| 7041 | E(#rows) from range optimizer. Make another try: |
| 7042 | |
| 7043 | If range optimizer produced E(#rows) for a prefix of the ref |
| 7044 | access we're considering, and that E(#rows) is lower then our |
| 7045 | current estimate, make the adjustment. |
| 7046 | |
| 7047 | The decision whether we can re-use the estimate from the range |
| 7048 | optimizer is the same as in ReuseRangeEstimateForRef-3, |
| 7049 | applied to first table->quick_key_parts[key] key parts. |
| 7050 | */ |
| 7051 | if (table->quick_keys.is_set(key) && |
| 7052 | table->quick_key_parts[key] <= max_key_part && |
| 7053 | const_part & |
| 7054 | ((key_part_map)1 << table->quick_key_parts[key]) && |
| 7055 | table->quick_n_ranges[key] == 1 + MY_TEST(ref_or_null_part & |
| 7056 | const_part) && |
| 7057 | records > (double) table->quick_rows[key]) |
| 7058 | { |
| 7059 | tmp= records= (double) table->quick_rows[key]; |
| 7060 | } |
| 7061 | } |
| 7062 | |
| 7063 | /* Limit the number of matched rows */ |
| 7064 | set_if_smaller(tmp, (double) thd->variables.max_seeks_for_key); |
| 7065 | if (table->covering_keys.is_set(key)) |
| 7066 | tmp= table->file->keyread_time(key, 1, (ha_rows) tmp); |
| 7067 | else |
| 7068 | tmp= table->file->read_time(key, 1, |
| 7069 | (ha_rows) MY_MIN(tmp,s->worst_seeks)); |
| 7070 | tmp*= record_count; |
| 7071 | } |
| 7072 | else |
| 7073 | tmp= best_time; // Do nothing |
| 7074 | } |
| 7075 | |
| 7076 | tmp += s->startup_cost; |
| 7077 | loose_scan_opt.check_ref_access_part2(key, start_key, records, tmp); |
| 7078 | } /* not ft_key */ |
| 7079 | |
| 7080 | if (tmp + 0.0001 < best_time - records/(double) TIME_FOR_COMPARE) |
| 7081 | { |
| 7082 | best_time= tmp + records/(double) TIME_FOR_COMPARE; |
| 7083 | best= tmp; |
| 7084 | best_records= records; |
| 7085 | best_key= start_key; |
| 7086 | best_max_key_part= max_key_part; |
| 7087 | best_ref_depends_map= found_ref; |
| 7088 | } |
| 7089 | } /* for each key */ |
| 7090 | records= best_records; |
| 7091 | } |
| 7092 | |
| 7093 | /* |
| 7094 | If there is no key to access the table, but there is an equi-join |
| 7095 | predicate connecting the table with the privious tables then we |
| 7096 | consider the possibility of using hash join. |
| 7097 | We need also to check that: |
| 7098 | (1) s is inner table of semi-join -> join cache is allowed for semijoins |
| 7099 | (2) s is inner table of outer join -> join cache is allowed for outer joins |
| 7100 | */ |
| 7101 | if (idx > join->const_tables && best_key == 0 && |
| 7102 | (join->allowed_join_cache_types & JOIN_CACHE_HASHED_BIT) && |
| 7103 | join->max_allowed_join_cache_level > 2 && |
| 7104 | !bitmap_is_clear_all(eq_join_set) && !disable_jbuf && |
| 7105 | (!s->emb_sj_nest || |
| 7106 | join->allowed_semijoin_with_cache) && // (1) |
| 7107 | (!(s->table->map & join->outer_join) || |
| 7108 | join->allowed_outer_join_with_cache)) // (2) |
| 7109 | { |
| 7110 | double join_sel= 0.1; |
| 7111 | /* Estimate the cost of the hash join access to the table */ |
| 7112 | double rnd_records= matching_candidates_in_table(s, found_constraint, |
| 7113 | use_cond_selectivity); |
| 7114 | |
| 7115 | tmp= s->quick ? s->quick->read_time : s->scan_time(); |
| 7116 | tmp+= (s->records - rnd_records)/(double) TIME_FOR_COMPARE; |
| 7117 | |
| 7118 | /* We read the table as many times as join buffer becomes full. */ |
| 7119 | tmp*= (1.0 + floor((double) cache_record_length(join,idx) * |
| 7120 | record_count / |
| 7121 | (double) thd->variables.join_buff_size)); |
| 7122 | best_time= tmp + |
| 7123 | (record_count*join_sel) / TIME_FOR_COMPARE * rnd_records; |
| 7124 | best= tmp; |
| 7125 | records= rnd_records; |
| 7126 | best_key= hj_start_key; |
| 7127 | best_ref_depends_map= 0; |
| 7128 | best_uses_jbuf= TRUE; |
| 7129 | } |
| 7130 | |
| 7131 | /* |
| 7132 | Don't test table scan if it can't be better. |
| 7133 | Prefer key lookup if we would use the same key for scanning. |
| 7134 | |
| 7135 | Don't do a table scan on InnoDB tables, if we can read the used |
| 7136 | parts of the row from any of the used index. |
| 7137 | This is because table scans uses index and we would not win |
| 7138 | anything by using a table scan. |
| 7139 | |
| 7140 | A word for word translation of the below if-statement in sergefp's |
| 7141 | understanding: we check if we should use table scan if: |
| 7142 | (1) The found 'ref' access produces more records than a table scan |
| 7143 | (or index scan, or quick select), or 'ref' is more expensive than |
| 7144 | any of them. |
| 7145 | (2) This doesn't hold: the best way to perform table scan is to to perform |
| 7146 | 'range' access using index IDX, and the best way to perform 'ref' |
| 7147 | access is to use the same index IDX, with the same or more key parts. |
| 7148 | (note: it is not clear how this rule is/should be extended to |
| 7149 | index_merge quick selects) |
| 7150 | (3) See above note about InnoDB. |
| 7151 | (4) NOT ("FORCE INDEX(...)" is used for table and there is 'ref' access |
| 7152 | path, but there is no quick select) |
| 7153 | If the condition in the above brackets holds, then the only possible |
| 7154 | "table scan" access method is ALL/index (there is no quick select). |
| 7155 | Since we have a 'ref' access path, and FORCE INDEX instructs us to |
| 7156 | choose it over ALL/index, there is no need to consider a full table |
| 7157 | scan. |
| 7158 | (5) Non-flattenable semi-joins: don't consider doing a scan of temporary |
| 7159 | table if we had an option to make lookups into it. In real-world cases, |
| 7160 | lookups are cheaper than full scans, but when the table is small, they |
| 7161 | can be [considered to be] more expensive, which causes lookups not to |
| 7162 | be used for cases with small datasets, which is annoying. |
| 7163 | */ |
| 7164 | if ((records >= s->found_records || best > s->read_time) && // (1) |
| 7165 | !(s->quick && best_key && s->quick->index == best_key->key && // (2) |
| 7166 | best_max_key_part >= s->table->quick_key_parts[best_key->key]) &&// (2) |
| 7167 | !((s->table->file->ha_table_flags() & HA_TABLE_SCAN_ON_INDEX) && // (3) |
| 7168 | ! s->table->covering_keys.is_clear_all() && best_key && !s->quick) &&// (3) |
| 7169 | !(s->table->force_index && best_key && !s->quick) && // (4) |
| 7170 | !(best_key && s->table->pos_in_table_list->jtbm_subselect)) // (5) |
| 7171 | { // Check full join |
| 7172 | double rnd_records= matching_candidates_in_table(s, found_constraint, |
| 7173 | use_cond_selectivity); |
| 7174 | |
| 7175 | /* |
| 7176 | Range optimizer never proposes a RANGE if it isn't better |
| 7177 | than FULL: so if RANGE is present, it's always preferred to FULL. |
| 7178 | Here we estimate its cost. |
| 7179 | */ |
| 7180 | |
| 7181 | if (s->quick) |
| 7182 | { |
| 7183 | /* |
| 7184 | For each record we: |
| 7185 | - read record range through 'quick' |
| 7186 | - skip rows which does not satisfy WHERE constraints |
| 7187 | TODO: |
| 7188 | We take into account possible use of join cache for ALL/index |
| 7189 | access (see first else-branch below), but we don't take it into |
| 7190 | account here for range/index_merge access. Find out why this is so. |
| 7191 | */ |
| 7192 | tmp= record_count * |
| 7193 | (s->quick->read_time + |
| 7194 | (s->found_records - rnd_records)/(double) TIME_FOR_COMPARE); |
| 7195 | |
| 7196 | loose_scan_opt.check_range_access(join, idx, s->quick); |
| 7197 | } |
| 7198 | else |
| 7199 | { |
| 7200 | /* Estimate cost of reading table. */ |
| 7201 | if (s->table->force_index && !best_key) // index scan |
| 7202 | tmp= s->table->file->read_time(s->ref.key, 1, s->records); |
| 7203 | else // table scan |
| 7204 | tmp= s->scan_time(); |
| 7205 | |
| 7206 | if ((s->table->map & join->outer_join) || disable_jbuf) // Can't use join cache |
| 7207 | { |
| 7208 | /* |
| 7209 | For each record we have to: |
| 7210 | - read the whole table record |
| 7211 | - skip rows which does not satisfy join condition |
| 7212 | */ |
| 7213 | tmp= record_count * |
| 7214 | (tmp + |
| 7215 | (s->records - rnd_records)/(double) TIME_FOR_COMPARE); |
| 7216 | } |
| 7217 | else |
| 7218 | { |
| 7219 | /* We read the table as many times as join buffer becomes full. */ |
| 7220 | tmp*= (1.0 + floor((double) cache_record_length(join,idx) * |
| 7221 | record_count / |
| 7222 | (double) thd->variables.join_buff_size)); |
| 7223 | /* |
| 7224 | We don't make full cartesian product between rows in the scanned |
| 7225 | table and existing records because we skip all rows from the |
| 7226 | scanned table, which does not satisfy join condition when |
| 7227 | we read the table (see flush_cached_records for details). Here we |
| 7228 | take into account cost to read and skip these records. |
| 7229 | */ |
| 7230 | tmp+= (s->records - rnd_records)/(double) TIME_FOR_COMPARE; |
| 7231 | } |
| 7232 | } |
| 7233 | |
| 7234 | tmp += s->startup_cost; |
| 7235 | /* |
| 7236 | We estimate the cost of evaluating WHERE clause for found records |
| 7237 | as record_count * rnd_records / TIME_FOR_COMPARE. This cost plus |
| 7238 | tmp give us total cost of using TABLE SCAN |
| 7239 | */ |
| 7240 | if (best == DBL_MAX || |
| 7241 | (tmp + record_count/(double) TIME_FOR_COMPARE*rnd_records < |
| 7242 | (best_key->is_for_hash_join() ? best_time : |
| 7243 | best + record_count/(double) TIME_FOR_COMPARE*records))) |
| 7244 | { |
| 7245 | /* |
| 7246 | If the table has a range (s->quick is set) make_join_select() |
| 7247 | will ensure that this will be used |
| 7248 | */ |
| 7249 | best= tmp; |
| 7250 | records= rnd_records; |
| 7251 | best_key= 0; |
| 7252 | /* range/index_merge/ALL/index access method are "independent", so: */ |
| 7253 | best_ref_depends_map= 0; |
| 7254 | best_uses_jbuf= MY_TEST(!disable_jbuf && !((s->table->map & |
| 7255 | join->outer_join))); |
| 7256 | } |
| 7257 | } |
| 7258 | |
| 7259 | /* Update the cost information for the current partial plan */ |
| 7260 | pos->records_read= records; |
| 7261 | pos->read_time= best; |
| 7262 | pos->key= best_key; |
| 7263 | pos->table= s; |
| 7264 | pos->ref_depend_map= best_ref_depends_map; |
| 7265 | pos->loosescan_picker.loosescan_key= MAX_KEY; |
| 7266 | pos->use_join_buffer= best_uses_jbuf; |
| 7267 | pos->spl_plan= spl_plan; |
| 7268 | |
| 7269 | loose_scan_opt.save_to_position(s, loose_scan_pos); |
| 7270 | |
| 7271 | if (!best_key && |
| 7272 | idx == join->const_tables && |
| 7273 | s->table == join->sort_by_table && |
| 7274 | join->unit->select_limit_cnt >= records) |
| 7275 | join->sort_by_table= (TABLE*) 1; // Must use temporary table |
| 7276 | |
| 7277 | DBUG_VOID_RETURN; |
| 7278 | } |
| 7279 | |
| 7280 | |
| 7281 | /* |
| 7282 | Find JOIN_TAB's embedding (i.e, parent) subquery. |
| 7283 | - For merged semi-joins, tables inside the semi-join nest have their |
| 7284 | semi-join nest as parent. We intentionally ignore results of table |
| 7285 | pullout action here. |
| 7286 | - For non-merged semi-joins (JTBM tabs), the embedding subquery is the |
| 7287 | JTBM join tab itself. |
| 7288 | */ |
| 7289 | |
| 7290 | static TABLE_LIST* get_emb_subq(JOIN_TAB *tab) |
| 7291 | { |
| 7292 | TABLE_LIST *tlist= tab->table->pos_in_table_list; |
| 7293 | if (tlist->jtbm_subselect) |
| 7294 | return tlist; |
| 7295 | TABLE_LIST *embedding= tlist->embedding; |
| 7296 | if (!embedding || !embedding->sj_subq_pred) |
| 7297 | return NULL; |
| 7298 | return embedding; |
| 7299 | } |
| 7300 | |
| 7301 | |
| 7302 | /* |
| 7303 | Choose initial table order that "helps" semi-join optimizations. |
| 7304 | |
| 7305 | The idea is that we should start with the order that is the same as the one |
| 7306 | we would have had if we had semijoin=off: |
| 7307 | - Top-level tables go first |
| 7308 | - subquery tables are grouped together by the subquery they are in, |
| 7309 | - subquery tables are attached where the subquery predicate would have been |
| 7310 | attached if we had semi-join off. |
| 7311 | |
| 7312 | This function relies on join_tab_cmp()/join_tab_cmp_straight() to produce |
| 7313 | certain pre-liminary ordering, see compare_embedding_subqueries() for its |
| 7314 | description. |
| 7315 | */ |
| 7316 | |
| 7317 | static void choose_initial_table_order(JOIN *join) |
| 7318 | { |
| 7319 | TABLE_LIST *emb_subq; |
| 7320 | JOIN_TAB **tab= join->best_ref + join->const_tables; |
| 7321 | JOIN_TAB **tabs_end= tab + join->table_count - join->const_tables; |
| 7322 | DBUG_ENTER("choose_initial_table_order" ); |
| 7323 | /* Find where the top-level JOIN_TABs end and subquery JOIN_TABs start */ |
| 7324 | for (; tab != tabs_end; tab++) |
| 7325 | { |
| 7326 | if ((emb_subq= get_emb_subq(*tab))) |
| 7327 | break; |
| 7328 | } |
| 7329 | uint n_subquery_tabs= (uint)(tabs_end - tab); |
| 7330 | |
| 7331 | if (!n_subquery_tabs) |
| 7332 | DBUG_VOID_RETURN; |
| 7333 | |
| 7334 | /* Copy the subquery JOIN_TABs to a separate array */ |
| 7335 | JOIN_TAB *subquery_tabs[MAX_TABLES]; |
| 7336 | memcpy(subquery_tabs, tab, sizeof(JOIN_TAB*) * n_subquery_tabs); |
| 7337 | |
| 7338 | JOIN_TAB **last_top_level_tab= tab; |
| 7339 | JOIN_TAB **subq_tab= subquery_tabs; |
| 7340 | JOIN_TAB **subq_tabs_end= subquery_tabs + n_subquery_tabs; |
| 7341 | TABLE_LIST *cur_subq_nest= NULL; |
| 7342 | for (; subq_tab < subq_tabs_end; subq_tab++) |
| 7343 | { |
| 7344 | if (get_emb_subq(*subq_tab)!= cur_subq_nest) |
| 7345 | { |
| 7346 | /* |
| 7347 | Reached the part of subquery_tabs that covers tables in some subquery. |
| 7348 | */ |
| 7349 | cur_subq_nest= get_emb_subq(*subq_tab); |
| 7350 | |
| 7351 | /* Determine how many tables the subquery has */ |
| 7352 | JOIN_TAB **last_tab_for_subq; |
| 7353 | for (last_tab_for_subq= subq_tab; |
| 7354 | last_tab_for_subq < subq_tabs_end && |
| 7355 | get_emb_subq(*last_tab_for_subq) == cur_subq_nest; |
| 7356 | last_tab_for_subq++) {} |
| 7357 | uint n_subquery_tables= (uint)(last_tab_for_subq - subq_tab); |
| 7358 | |
| 7359 | /* |
| 7360 | Walk the original array and find where this subquery would have been |
| 7361 | attached to |
| 7362 | */ |
| 7363 | table_map need_tables= cur_subq_nest->original_subq_pred_used_tables; |
| 7364 | need_tables &= ~(join->const_table_map | PSEUDO_TABLE_BITS); |
| 7365 | for (JOIN_TAB **top_level_tab= join->best_ref + join->const_tables; |
| 7366 | top_level_tab < last_top_level_tab; |
| 7367 | //top_level_tab < join->best_ref + join->table_count; |
| 7368 | top_level_tab++) |
| 7369 | { |
| 7370 | need_tables &= ~(*top_level_tab)->table->map; |
| 7371 | /* Check if this is the place where subquery should be attached */ |
| 7372 | if (!need_tables) |
| 7373 | { |
| 7374 | /* Move away the top-level tables that are after top_level_tab */ |
| 7375 | size_t top_tail_len= last_top_level_tab - top_level_tab - 1; |
| 7376 | memmove(top_level_tab + 1 + n_subquery_tables, top_level_tab + 1, |
| 7377 | sizeof(JOIN_TAB*)*top_tail_len); |
| 7378 | last_top_level_tab += n_subquery_tables; |
| 7379 | memcpy(top_level_tab + 1, subq_tab, sizeof(JOIN_TAB*)*n_subquery_tables); |
| 7380 | break; |
| 7381 | } |
| 7382 | } |
| 7383 | DBUG_ASSERT(!need_tables); |
| 7384 | subq_tab += n_subquery_tables - 1; |
| 7385 | } |
| 7386 | } |
| 7387 | DBUG_VOID_RETURN; |
| 7388 | } |
| 7389 | |
| 7390 | |
| 7391 | /** |
| 7392 | Selects and invokes a search strategy for an optimal query plan. |
| 7393 | |
| 7394 | The function checks user-configurable parameters that control the search |
| 7395 | strategy for an optimal plan, selects the search method and then invokes |
| 7396 | it. Each specific optimization procedure stores the final optimal plan in |
| 7397 | the array 'join->best_positions', and the cost of the plan in |
| 7398 | 'join->best_read'. |
| 7399 | |
| 7400 | @param join pointer to the structure providing all context info for |
| 7401 | the query |
| 7402 | @param join_tables set of the tables in the query |
| 7403 | |
| 7404 | @retval |
| 7405 | FALSE ok |
| 7406 | @retval |
| 7407 | TRUE Fatal error |
| 7408 | */ |
| 7409 | |
| 7410 | bool |
| 7411 | choose_plan(JOIN *join, table_map join_tables) |
| 7412 | { |
| 7413 | uint search_depth= join->thd->variables.optimizer_search_depth; |
| 7414 | uint prune_level= join->thd->variables.optimizer_prune_level; |
| 7415 | uint use_cond_selectivity= |
| 7416 | join->thd->variables.optimizer_use_condition_selectivity; |
| 7417 | bool straight_join= MY_TEST(join->select_options & SELECT_STRAIGHT_JOIN); |
| 7418 | DBUG_ENTER("choose_plan" ); |
| 7419 | |
| 7420 | join->cur_embedding_map= 0; |
| 7421 | reset_nj_counters(join, join->join_list); |
| 7422 | qsort2_cmp jtab_sort_func; |
| 7423 | |
| 7424 | if (join->emb_sjm_nest) |
| 7425 | { |
| 7426 | /* We're optimizing semi-join materialization nest, so put the |
| 7427 | tables from this semi-join as first |
| 7428 | */ |
| 7429 | jtab_sort_func= join_tab_cmp_embedded_first; |
| 7430 | } |
| 7431 | else |
| 7432 | { |
| 7433 | /* |
| 7434 | if (SELECT_STRAIGHT_JOIN option is set) |
| 7435 | reorder tables so dependent tables come after tables they depend |
| 7436 | on, otherwise keep tables in the order they were specified in the query |
| 7437 | else |
| 7438 | Apply heuristic: pre-sort all access plans with respect to the number of |
| 7439 | records accessed. |
| 7440 | */ |
| 7441 | jtab_sort_func= straight_join ? join_tab_cmp_straight : join_tab_cmp; |
| 7442 | } |
| 7443 | |
| 7444 | /* |
| 7445 | psergey-todo: if we're not optimizing an SJM nest, |
| 7446 | - sort that outer tables are first, and each sjm nest follows |
| 7447 | - then, put each [sjm_table1, ... sjm_tableN] sub-array right where |
| 7448 | WHERE clause pushdown would have put it. |
| 7449 | */ |
| 7450 | my_qsort2(join->best_ref + join->const_tables, |
| 7451 | join->table_count - join->const_tables, sizeof(JOIN_TAB*), |
| 7452 | jtab_sort_func, (void*)join->emb_sjm_nest); |
| 7453 | |
| 7454 | if (!join->emb_sjm_nest) |
| 7455 | { |
| 7456 | choose_initial_table_order(join); |
| 7457 | } |
| 7458 | join->cur_sj_inner_tables= 0; |
| 7459 | |
| 7460 | if (straight_join) |
| 7461 | { |
| 7462 | optimize_straight_join(join, join_tables); |
| 7463 | } |
| 7464 | else |
| 7465 | { |
| 7466 | DBUG_ASSERT(search_depth <= MAX_TABLES + 1); |
| 7467 | if (search_depth == 0) |
| 7468 | /* Automatically determine a reasonable value for 'search_depth' */ |
| 7469 | search_depth= determine_search_depth(join); |
| 7470 | if (greedy_search(join, join_tables, search_depth, prune_level, |
| 7471 | use_cond_selectivity)) |
| 7472 | DBUG_RETURN(TRUE); |
| 7473 | } |
| 7474 | |
| 7475 | /* |
| 7476 | Store the cost of this query into a user variable |
| 7477 | Don't update last_query_cost for statements that are not "flat joins" : |
| 7478 | i.e. they have subqueries, unions or call stored procedures. |
| 7479 | TODO: calculate a correct cost for a query with subqueries and UNIONs. |
| 7480 | */ |
| 7481 | if (join->thd->lex->is_single_level_stmt()) |
| 7482 | join->thd->status_var.last_query_cost= join->best_read; |
| 7483 | DBUG_RETURN(FALSE); |
| 7484 | } |
| 7485 | |
| 7486 | |
| 7487 | /* |
| 7488 | Compare two join tabs based on the subqueries they are from. |
| 7489 | - top-level join tabs go first |
| 7490 | - then subqueries are ordered by their select_id (we're using this |
| 7491 | criteria because we need a cross-platform, deterministic ordering) |
| 7492 | |
| 7493 | @return |
| 7494 | 0 - equal |
| 7495 | -1 - jt1 < jt2 |
| 7496 | 1 - jt1 > jt2 |
| 7497 | */ |
| 7498 | |
| 7499 | static int compare_embedding_subqueries(JOIN_TAB *jt1, JOIN_TAB *jt2) |
| 7500 | { |
| 7501 | /* Determine if the first table is originally from a subquery */ |
| 7502 | TABLE_LIST *tbl1= jt1->table->pos_in_table_list; |
| 7503 | uint tbl1_select_no; |
| 7504 | if (tbl1->jtbm_subselect) |
| 7505 | { |
| 7506 | tbl1_select_no= |
| 7507 | tbl1->jtbm_subselect->unit->first_select()->select_number; |
| 7508 | } |
| 7509 | else if (tbl1->embedding && tbl1->embedding->sj_subq_pred) |
| 7510 | { |
| 7511 | tbl1_select_no= |
| 7512 | tbl1->embedding->sj_subq_pred->unit->first_select()->select_number; |
| 7513 | } |
| 7514 | else |
| 7515 | tbl1_select_no= 1; /* Top-level */ |
| 7516 | |
| 7517 | /* Same for the second table */ |
| 7518 | TABLE_LIST *tbl2= jt2->table->pos_in_table_list; |
| 7519 | uint tbl2_select_no; |
| 7520 | if (tbl2->jtbm_subselect) |
| 7521 | { |
| 7522 | tbl2_select_no= |
| 7523 | tbl2->jtbm_subselect->unit->first_select()->select_number; |
| 7524 | } |
| 7525 | else if (tbl2->embedding && tbl2->embedding->sj_subq_pred) |
| 7526 | { |
| 7527 | tbl2_select_no= |
| 7528 | tbl2->embedding->sj_subq_pred->unit->first_select()->select_number; |
| 7529 | } |
| 7530 | else |
| 7531 | tbl2_select_no= 1; /* Top-level */ |
| 7532 | |
| 7533 | /* |
| 7534 | Put top-level tables in front. Tables from within subqueries must follow, |
| 7535 | grouped by their owner subquery. We don't care about the order that |
| 7536 | subquery groups are in, because choose_initial_table_order() will re-order |
| 7537 | the groups. |
| 7538 | */ |
| 7539 | if (tbl1_select_no != tbl2_select_no) |
| 7540 | return tbl1_select_no > tbl2_select_no ? 1 : -1; |
| 7541 | return 0; |
| 7542 | } |
| 7543 | |
| 7544 | |
| 7545 | /** |
| 7546 | Compare two JOIN_TAB objects based on the number of accessed records. |
| 7547 | |
| 7548 | @param ptr1 pointer to first JOIN_TAB object |
| 7549 | @param ptr2 pointer to second JOIN_TAB object |
| 7550 | |
| 7551 | NOTES |
| 7552 | The order relation implemented by join_tab_cmp() is not transitive, |
| 7553 | i.e. it is possible to choose such a, b and c that (a < b) && (b < c) |
| 7554 | but (c < a). This implies that result of a sort using the relation |
| 7555 | implemented by join_tab_cmp() depends on the order in which |
| 7556 | elements are compared, i.e. the result is implementation-specific. |
| 7557 | Example: |
| 7558 | a: dependent = 0x0 table->map = 0x1 found_records = 3 ptr = 0x907e6b0 |
| 7559 | b: dependent = 0x0 table->map = 0x2 found_records = 3 ptr = 0x907e838 |
| 7560 | c: dependent = 0x6 table->map = 0x10 found_records = 2 ptr = 0x907ecd0 |
| 7561 | |
| 7562 | As for subqueries, this function must produce order that can be fed to |
| 7563 | choose_initial_table_order(). |
| 7564 | |
| 7565 | @retval |
| 7566 | 1 if first is bigger |
| 7567 | @retval |
| 7568 | -1 if second is bigger |
| 7569 | @retval |
| 7570 | 0 if equal |
| 7571 | */ |
| 7572 | |
| 7573 | static int |
| 7574 | join_tab_cmp(const void *dummy, const void* ptr1, const void* ptr2) |
| 7575 | { |
| 7576 | JOIN_TAB *jt1= *(JOIN_TAB**) ptr1; |
| 7577 | JOIN_TAB *jt2= *(JOIN_TAB**) ptr2; |
| 7578 | int cmp; |
| 7579 | |
| 7580 | if ((cmp= compare_embedding_subqueries(jt1, jt2)) != 0) |
| 7581 | return cmp; |
| 7582 | /* |
| 7583 | After that, |
| 7584 | take care about ordering imposed by LEFT JOIN constraints, |
| 7585 | possible [eq]ref accesses, and numbers of matching records in the table. |
| 7586 | */ |
| 7587 | if (jt1->dependent & jt2->table->map) |
| 7588 | return 1; |
| 7589 | if (jt2->dependent & jt1->table->map) |
| 7590 | return -1; |
| 7591 | if (jt1->found_records > jt2->found_records) |
| 7592 | return 1; |
| 7593 | if (jt1->found_records < jt2->found_records) |
| 7594 | return -1; |
| 7595 | return jt1 > jt2 ? 1 : (jt1 < jt2 ? -1 : 0); |
| 7596 | } |
| 7597 | |
| 7598 | |
| 7599 | /** |
| 7600 | Same as join_tab_cmp, but for use with SELECT_STRAIGHT_JOIN. |
| 7601 | */ |
| 7602 | |
| 7603 | static int |
| 7604 | join_tab_cmp_straight(const void *dummy, const void* ptr1, const void* ptr2) |
| 7605 | { |
| 7606 | JOIN_TAB *jt1= *(JOIN_TAB**) ptr1; |
| 7607 | JOIN_TAB *jt2= *(JOIN_TAB**) ptr2; |
| 7608 | |
| 7609 | /* |
| 7610 | We don't do subquery flattening if the parent or child select has |
| 7611 | STRAIGHT_JOIN modifier. It is complicated to implement and the semantics |
| 7612 | is hardly useful. |
| 7613 | */ |
| 7614 | DBUG_ASSERT(!jt1->emb_sj_nest); |
| 7615 | DBUG_ASSERT(!jt2->emb_sj_nest); |
| 7616 | |
| 7617 | int cmp; |
| 7618 | if ((cmp= compare_embedding_subqueries(jt1, jt2)) != 0) |
| 7619 | return cmp; |
| 7620 | |
| 7621 | if (jt1->dependent & jt2->table->map) |
| 7622 | return 1; |
| 7623 | if (jt2->dependent & jt1->table->map) |
| 7624 | return -1; |
| 7625 | return jt1 > jt2 ? 1 : (jt1 < jt2 ? -1 : 0); |
| 7626 | } |
| 7627 | |
| 7628 | |
| 7629 | /* |
| 7630 | Same as join_tab_cmp but tables from within the given semi-join nest go |
| 7631 | first. Used when the optimizing semi-join materialization nests. |
| 7632 | */ |
| 7633 | |
| 7634 | static int |
| 7635 | join_tab_cmp_embedded_first(const void *emb, const void* ptr1, const void* ptr2) |
| 7636 | { |
| 7637 | const TABLE_LIST *emb_nest= (TABLE_LIST*) emb; |
| 7638 | JOIN_TAB *jt1= *(JOIN_TAB**) ptr1; |
| 7639 | JOIN_TAB *jt2= *(JOIN_TAB**) ptr2; |
| 7640 | |
| 7641 | if (jt1->emb_sj_nest == emb_nest && jt2->emb_sj_nest != emb_nest) |
| 7642 | return -1; |
| 7643 | if (jt1->emb_sj_nest != emb_nest && jt2->emb_sj_nest == emb_nest) |
| 7644 | return 1; |
| 7645 | |
| 7646 | if (jt1->dependent & jt2->table->map) |
| 7647 | return 1; |
| 7648 | if (jt2->dependent & jt1->table->map) |
| 7649 | return -1; |
| 7650 | |
| 7651 | if (jt1->found_records > jt2->found_records) |
| 7652 | return 1; |
| 7653 | if (jt1->found_records < jt2->found_records) |
| 7654 | return -1; |
| 7655 | |
| 7656 | return jt1 > jt2 ? 1 : (jt1 < jt2 ? -1 : 0); |
| 7657 | } |
| 7658 | |
| 7659 | |
| 7660 | /** |
| 7661 | Heuristic procedure to automatically guess a reasonable degree of |
| 7662 | exhaustiveness for the greedy search procedure. |
| 7663 | |
| 7664 | The procedure estimates the optimization time and selects a search depth |
| 7665 | big enough to result in a near-optimal QEP, that doesn't take too long to |
| 7666 | find. If the number of tables in the query exceeds some constant, then |
| 7667 | search_depth is set to this constant. |
| 7668 | |
| 7669 | @param join pointer to the structure providing all context info for |
| 7670 | the query |
| 7671 | |
| 7672 | @note |
| 7673 | This is an extremely simplistic implementation that serves as a stub for a |
| 7674 | more advanced analysis of the join. Ideally the search depth should be |
| 7675 | determined by learning from previous query optimizations, because it will |
| 7676 | depend on the CPU power (and other factors). |
| 7677 | |
| 7678 | @todo |
| 7679 | this value should be determined dynamically, based on statistics: |
| 7680 | uint max_tables_for_exhaustive_opt= 7; |
| 7681 | |
| 7682 | @todo |
| 7683 | this value could be determined by some mapping of the form: |
| 7684 | depth : table_count -> [max_tables_for_exhaustive_opt..MAX_EXHAUSTIVE] |
| 7685 | |
| 7686 | @return |
| 7687 | A positive integer that specifies the search depth (and thus the |
| 7688 | exhaustiveness) of the depth-first search algorithm used by |
| 7689 | 'greedy_search'. |
| 7690 | */ |
| 7691 | |
| 7692 | static uint |
| 7693 | determine_search_depth(JOIN *join) |
| 7694 | { |
| 7695 | uint table_count= join->table_count - join->const_tables; |
| 7696 | uint search_depth; |
| 7697 | /* TODO: this value should be determined dynamically, based on statistics: */ |
| 7698 | uint max_tables_for_exhaustive_opt= 7; |
| 7699 | |
| 7700 | if (table_count <= max_tables_for_exhaustive_opt) |
| 7701 | search_depth= table_count+1; // use exhaustive for small number of tables |
| 7702 | else |
| 7703 | /* |
| 7704 | TODO: this value could be determined by some mapping of the form: |
| 7705 | depth : table_count -> [max_tables_for_exhaustive_opt..MAX_EXHAUSTIVE] |
| 7706 | */ |
| 7707 | search_depth= max_tables_for_exhaustive_opt; // use greedy search |
| 7708 | |
| 7709 | return search_depth; |
| 7710 | } |
| 7711 | |
| 7712 | |
| 7713 | /** |
| 7714 | Select the best ways to access the tables in a query without reordering them. |
| 7715 | |
| 7716 | Find the best access paths for each query table and compute their costs |
| 7717 | according to their order in the array 'join->best_ref' (thus without |
| 7718 | reordering the join tables). The function calls sequentially |
| 7719 | 'best_access_path' for each table in the query to select the best table |
| 7720 | access method. The final optimal plan is stored in the array |
| 7721 | 'join->best_positions', and the corresponding cost in 'join->best_read'. |
| 7722 | |
| 7723 | @param join pointer to the structure providing all context info for |
| 7724 | the query |
| 7725 | @param join_tables set of the tables in the query |
| 7726 | |
| 7727 | @note |
| 7728 | This function can be applied to: |
| 7729 | - queries with STRAIGHT_JOIN |
| 7730 | - internally to compute the cost of an arbitrary QEP |
| 7731 | @par |
| 7732 | Thus 'optimize_straight_join' can be used at any stage of the query |
| 7733 | optimization process to finalize a QEP as it is. |
| 7734 | */ |
| 7735 | |
| 7736 | static void |
| 7737 | optimize_straight_join(JOIN *join, table_map join_tables) |
| 7738 | { |
| 7739 | JOIN_TAB *s; |
| 7740 | uint idx= join->const_tables; |
| 7741 | bool disable_jbuf= join->thd->variables.join_cache_level == 0; |
| 7742 | double record_count= 1.0; |
| 7743 | double read_time= 0.0; |
| 7744 | uint use_cond_selectivity= |
| 7745 | join->thd->variables.optimizer_use_condition_selectivity; |
| 7746 | POSITION loose_scan_pos; |
| 7747 | |
| 7748 | for (JOIN_TAB **pos= join->best_ref + idx ; (s= *pos) ; pos++) |
| 7749 | { |
| 7750 | /* Find the best access method from 's' to the current partial plan */ |
| 7751 | best_access_path(join, s, join_tables, idx, disable_jbuf, record_count, |
| 7752 | join->positions + idx, &loose_scan_pos); |
| 7753 | |
| 7754 | /* compute the cost of the new plan extended with 's' */ |
| 7755 | record_count*= join->positions[idx].records_read; |
| 7756 | read_time+= join->positions[idx].read_time + |
| 7757 | record_count / (double) TIME_FOR_COMPARE; |
| 7758 | advance_sj_state(join, join_tables, idx, &record_count, &read_time, |
| 7759 | &loose_scan_pos); |
| 7760 | |
| 7761 | join_tables&= ~(s->table->map); |
| 7762 | double pushdown_cond_selectivity= 1.0; |
| 7763 | if (use_cond_selectivity > 1) |
| 7764 | pushdown_cond_selectivity= table_cond_selectivity(join, idx, s, |
| 7765 | join_tables); |
| 7766 | join->positions[idx].cond_selectivity= pushdown_cond_selectivity; |
| 7767 | ++idx; |
| 7768 | } |
| 7769 | |
| 7770 | if (join->sort_by_table && |
| 7771 | join->sort_by_table != join->positions[join->const_tables].table->table) |
| 7772 | read_time+= record_count; // We have to make a temp table |
| 7773 | memcpy((uchar*) join->best_positions, (uchar*) join->positions, |
| 7774 | sizeof(POSITION)*idx); |
| 7775 | join->join_record_count= record_count; |
| 7776 | join->best_read= read_time - 0.001; |
| 7777 | } |
| 7778 | |
| 7779 | |
| 7780 | /** |
| 7781 | Find a good, possibly optimal, query execution plan (QEP) by a greedy search. |
| 7782 | |
| 7783 | The search procedure uses a hybrid greedy/exhaustive search with controlled |
| 7784 | exhaustiveness. The search is performed in N = card(remaining_tables) |
| 7785 | steps. Each step evaluates how promising is each of the unoptimized tables, |
| 7786 | selects the most promising table, and extends the current partial QEP with |
| 7787 | that table. Currenly the most 'promising' table is the one with least |
| 7788 | expensive extension.\ |
| 7789 | |
| 7790 | There are two extreme cases: |
| 7791 | -# When (card(remaining_tables) < search_depth), the estimate finds the |
| 7792 | best complete continuation of the partial QEP. This continuation can be |
| 7793 | used directly as a result of the search. |
| 7794 | -# When (search_depth == 1) the 'best_extension_by_limited_search' |
| 7795 | consideres the extension of the current QEP with each of the remaining |
| 7796 | unoptimized tables. |
| 7797 | |
| 7798 | All other cases are in-between these two extremes. Thus the parameter |
| 7799 | 'search_depth' controlls the exhaustiveness of the search. The higher the |
| 7800 | value, the longer the optimization time and possibly the better the |
| 7801 | resulting plan. The lower the value, the fewer alternative plans are |
| 7802 | estimated, but the more likely to get a bad QEP. |
| 7803 | |
| 7804 | All intermediate and final results of the procedure are stored in 'join': |
| 7805 | - join->positions : modified for every partial QEP that is explored |
| 7806 | - join->best_positions: modified for the current best complete QEP |
| 7807 | - join->best_read : modified for the current best complete QEP |
| 7808 | - join->best_ref : might be partially reordered |
| 7809 | |
| 7810 | The final optimal plan is stored in 'join->best_positions', and its |
| 7811 | corresponding cost in 'join->best_read'. |
| 7812 | |
| 7813 | @note |
| 7814 | The following pseudocode describes the algorithm of 'greedy_search': |
| 7815 | |
| 7816 | @code |
| 7817 | procedure greedy_search |
| 7818 | input: remaining_tables |
| 7819 | output: pplan; |
| 7820 | { |
| 7821 | pplan = <>; |
| 7822 | do { |
| 7823 | (t, a) = best_extension(pplan, remaining_tables); |
| 7824 | pplan = concat(pplan, (t, a)); |
| 7825 | remaining_tables = remaining_tables - t; |
| 7826 | } while (remaining_tables != {}) |
| 7827 | return pplan; |
| 7828 | } |
| 7829 | |
| 7830 | @endcode |
| 7831 | where 'best_extension' is a placeholder for a procedure that selects the |
| 7832 | most "promising" of all tables in 'remaining_tables'. |
| 7833 | Currently this estimate is performed by calling |
| 7834 | 'best_extension_by_limited_search' to evaluate all extensions of the |
| 7835 | current QEP of size 'search_depth', thus the complexity of 'greedy_search' |
| 7836 | mainly depends on that of 'best_extension_by_limited_search'. |
| 7837 | |
| 7838 | @par |
| 7839 | If 'best_extension()' == 'best_extension_by_limited_search()', then the |
| 7840 | worst-case complexity of this algorithm is <= |
| 7841 | O(N*N^search_depth/search_depth). When serch_depth >= N, then the |
| 7842 | complexity of greedy_search is O(N!). |
| 7843 | |
| 7844 | @par |
| 7845 | In the future, 'greedy_search' might be extended to support other |
| 7846 | implementations of 'best_extension', e.g. some simpler quadratic procedure. |
| 7847 | |
| 7848 | @param join pointer to the structure providing all context info |
| 7849 | for the query |
| 7850 | @param remaining_tables set of tables not included into the partial plan yet |
| 7851 | @param search_depth controlls the exhaustiveness of the search |
| 7852 | @param prune_level the pruning heuristics that should be applied during |
| 7853 | search |
| 7854 | @param use_cond_selectivity specifies how the selectivity of the conditions |
| 7855 | pushed to a table should be taken into account |
| 7856 | |
| 7857 | @retval |
| 7858 | FALSE ok |
| 7859 | @retval |
| 7860 | TRUE Fatal error |
| 7861 | */ |
| 7862 | |
| 7863 | static bool |
| 7864 | greedy_search(JOIN *join, |
| 7865 | table_map remaining_tables, |
| 7866 | uint search_depth, |
| 7867 | uint prune_level, |
| 7868 | uint use_cond_selectivity) |
| 7869 | { |
| 7870 | double record_count= 1.0; |
| 7871 | double read_time= 0.0; |
| 7872 | uint idx= join->const_tables; // index into 'join->best_ref' |
| 7873 | uint best_idx; |
| 7874 | uint size_remain; // cardinality of remaining_tables |
| 7875 | POSITION best_pos; |
| 7876 | JOIN_TAB *best_table; // the next plan node to be added to the curr QEP |
| 7877 | // ==join->tables or # tables in the sj-mat nest we're optimizing |
| 7878 | uint n_tables __attribute__((unused)); |
| 7879 | DBUG_ENTER("greedy_search" ); |
| 7880 | |
| 7881 | /* number of tables that remain to be optimized */ |
| 7882 | n_tables= size_remain= my_count_bits(remaining_tables & |
| 7883 | (join->emb_sjm_nest? |
| 7884 | (join->emb_sjm_nest->sj_inner_tables & |
| 7885 | ~join->const_table_map) |
| 7886 | : |
| 7887 | ~(table_map)0)); |
| 7888 | |
| 7889 | do { |
| 7890 | /* Find the extension of the current QEP with the lowest cost */ |
| 7891 | join->best_read= DBL_MAX; |
| 7892 | if (best_extension_by_limited_search(join, remaining_tables, idx, record_count, |
| 7893 | read_time, search_depth, prune_level, |
| 7894 | use_cond_selectivity)) |
| 7895 | DBUG_RETURN(TRUE); |
| 7896 | /* |
| 7897 | 'best_read < DBL_MAX' means that optimizer managed to find |
| 7898 | some plan and updated 'best_positions' array accordingly. |
| 7899 | */ |
| 7900 | DBUG_ASSERT(join->best_read < DBL_MAX); |
| 7901 | |
| 7902 | if (size_remain <= search_depth) |
| 7903 | { |
| 7904 | /* |
| 7905 | 'join->best_positions' contains a complete optimal extension of the |
| 7906 | current partial QEP. |
| 7907 | */ |
| 7908 | DBUG_EXECUTE("opt" , print_plan(join, n_tables, |
| 7909 | record_count, read_time, read_time, |
| 7910 | "optimal" );); |
| 7911 | DBUG_RETURN(FALSE); |
| 7912 | } |
| 7913 | |
| 7914 | /* select the first table in the optimal extension as most promising */ |
| 7915 | best_pos= join->best_positions[idx]; |
| 7916 | best_table= best_pos.table; |
| 7917 | /* |
| 7918 | Each subsequent loop of 'best_extension_by_limited_search' uses |
| 7919 | 'join->positions' for cost estimates, therefore we have to update its |
| 7920 | value. |
| 7921 | */ |
| 7922 | join->positions[idx]= best_pos; |
| 7923 | |
| 7924 | /* |
| 7925 | Update the interleaving state after extending the current partial plan |
| 7926 | with a new table. |
| 7927 | We are doing this here because best_extension_by_limited_search reverts |
| 7928 | the interleaving state to the one of the non-extended partial plan |
| 7929 | on exit. |
| 7930 | */ |
| 7931 | bool is_interleave_error __attribute__((unused))= |
| 7932 | check_interleaving_with_nj (best_table); |
| 7933 | /* This has been already checked by best_extension_by_limited_search */ |
| 7934 | DBUG_ASSERT(!is_interleave_error); |
| 7935 | |
| 7936 | |
| 7937 | /* find the position of 'best_table' in 'join->best_ref' */ |
| 7938 | best_idx= idx; |
| 7939 | JOIN_TAB *pos= join->best_ref[best_idx]; |
| 7940 | while (pos && best_table != pos) |
| 7941 | pos= join->best_ref[++best_idx]; |
| 7942 | DBUG_ASSERT((pos != NULL)); // should always find 'best_table' |
| 7943 | /* move 'best_table' at the first free position in the array of joins */ |
| 7944 | swap_variables(JOIN_TAB*, join->best_ref[idx], join->best_ref[best_idx]); |
| 7945 | |
| 7946 | /* compute the cost of the new plan extended with 'best_table' */ |
| 7947 | record_count*= join->positions[idx].records_read; |
| 7948 | read_time+= join->positions[idx].read_time + |
| 7949 | record_count / (double) TIME_FOR_COMPARE; |
| 7950 | |
| 7951 | remaining_tables&= ~(best_table->table->map); |
| 7952 | --size_remain; |
| 7953 | ++idx; |
| 7954 | |
| 7955 | DBUG_EXECUTE("opt" , print_plan(join, idx, |
| 7956 | record_count, read_time, read_time, |
| 7957 | "extended" );); |
| 7958 | } while (TRUE); |
| 7959 | } |
| 7960 | |
| 7961 | |
| 7962 | /** |
| 7963 | Get cost of execution and fanout produced by selected tables in the join |
| 7964 | prefix (where prefix is defined as prefix in depth-first traversal) |
| 7965 | |
| 7966 | @param end_tab_idx The number of last tab to be taken into |
| 7967 | account (in depth-first traversal prefix) |
| 7968 | @param filter_map Bitmap of tables whose cost/fanout are to |
| 7969 | be taken into account. |
| 7970 | @param read_time_arg [out] store read time here |
| 7971 | @param record_count_arg [out] store record count here |
| 7972 | |
| 7973 | @note |
| 7974 | |
| 7975 | @returns |
| 7976 | read_time_arg and record_count_arg contain the computed cost and fanout |
| 7977 | */ |
| 7978 | |
| 7979 | void JOIN::get_partial_cost_and_fanout(int end_tab_idx, |
| 7980 | table_map filter_map, |
| 7981 | double *read_time_arg, |
| 7982 | double *record_count_arg) |
| 7983 | { |
| 7984 | double record_count= 1; |
| 7985 | double read_time= 0.0; |
| 7986 | double sj_inner_fanout= 1.0; |
| 7987 | JOIN_TAB *end_tab= NULL; |
| 7988 | JOIN_TAB *tab; |
| 7989 | int i; |
| 7990 | int last_sj_table= MAX_TABLES; |
| 7991 | |
| 7992 | /* |
| 7993 | Handle a special case where the join is degenerate, and produces no |
| 7994 | records |
| 7995 | */ |
| 7996 | if (table_count == const_tables) |
| 7997 | { |
| 7998 | *read_time_arg= 0.0; |
| 7999 | /* |
| 8000 | We return 1, because |
| 8001 | - it is the pessimistic estimate (there might be grouping) |
| 8002 | - it's safer, as we're less likely to hit the edge cases in |
| 8003 | calculations. |
| 8004 | */ |
| 8005 | *record_count_arg=1.0; |
| 8006 | return; |
| 8007 | } |
| 8008 | |
| 8009 | for (tab= first_depth_first_tab(this), i= const_tables; |
| 8010 | tab; |
| 8011 | tab= next_depth_first_tab(this, tab), i++) |
| 8012 | { |
| 8013 | end_tab= tab; |
| 8014 | if (i == end_tab_idx) |
| 8015 | break; |
| 8016 | } |
| 8017 | |
| 8018 | for (tab= first_depth_first_tab(this), i= const_tables; |
| 8019 | ; |
| 8020 | tab= next_depth_first_tab(this, tab), i++) |
| 8021 | { |
| 8022 | if (end_tab->bush_root_tab && end_tab->bush_root_tab == tab) |
| 8023 | { |
| 8024 | /* |
| 8025 | We've entered the SJM nest that contains the end_tab. The caller is |
| 8026 | - interested in fanout inside the nest (because that's how many times |
| 8027 | we'll invoke the attached WHERE conditions) |
| 8028 | - not interested in cost |
| 8029 | */ |
| 8030 | record_count= 1.0; |
| 8031 | read_time= 0.0; |
| 8032 | } |
| 8033 | |
| 8034 | /* |
| 8035 | Ignore fanout (but not cost) from sj-inner tables, as long as |
| 8036 | the range that processes them finishes before the end_tab |
| 8037 | */ |
| 8038 | if (tab->sj_strategy != SJ_OPT_NONE) |
| 8039 | { |
| 8040 | sj_inner_fanout= 1.0; |
| 8041 | last_sj_table= i + tab->n_sj_tables; |
| 8042 | } |
| 8043 | |
| 8044 | table_map cur_table_map; |
| 8045 | if (tab->table) |
| 8046 | cur_table_map= tab->table->map; |
| 8047 | else |
| 8048 | { |
| 8049 | /* This is a SJ-Materialization nest. Check all of its tables */ |
| 8050 | TABLE *first_child= tab->bush_children->start->table; |
| 8051 | TABLE_LIST *sjm_nest= first_child->pos_in_table_list->embedding; |
| 8052 | cur_table_map= sjm_nest->nested_join->used_tables; |
| 8053 | } |
| 8054 | if (tab->records_read && (cur_table_map & filter_map)) |
| 8055 | { |
| 8056 | record_count *= tab->records_read; |
| 8057 | read_time += tab->read_time + record_count / (double) TIME_FOR_COMPARE; |
| 8058 | if (tab->emb_sj_nest) |
| 8059 | sj_inner_fanout *= tab->records_read; |
| 8060 | } |
| 8061 | |
| 8062 | if (i == last_sj_table) |
| 8063 | { |
| 8064 | record_count /= sj_inner_fanout; |
| 8065 | sj_inner_fanout= 1.0; |
| 8066 | last_sj_table= MAX_TABLES; |
| 8067 | } |
| 8068 | |
| 8069 | if (tab == end_tab) |
| 8070 | break; |
| 8071 | } |
| 8072 | *read_time_arg= read_time;// + record_count / TIME_FOR_COMPARE; |
| 8073 | *record_count_arg= record_count; |
| 8074 | } |
| 8075 | |
| 8076 | |
| 8077 | /* |
| 8078 | Get prefix cost and fanout. This function is different from |
| 8079 | get_partial_cost_and_fanout: |
| 8080 | - it operates on a JOIN that haven't yet finished its optimization phase (in |
| 8081 | particular, fix_semijoin_strategies_for_picked_join_order() and |
| 8082 | get_best_combination() haven't been called) |
| 8083 | - it assumes the the join prefix doesn't have any semi-join plans |
| 8084 | |
| 8085 | These assumptions are met by the caller of the function. |
| 8086 | */ |
| 8087 | |
| 8088 | void JOIN::get_prefix_cost_and_fanout(uint n_tables, |
| 8089 | double *read_time_arg, |
| 8090 | double *record_count_arg) |
| 8091 | { |
| 8092 | double record_count= 1; |
| 8093 | double read_time= 0.0; |
| 8094 | for (uint i= const_tables; i < n_tables + const_tables ; i++) |
| 8095 | { |
| 8096 | if (best_positions[i].records_read) |
| 8097 | { |
| 8098 | record_count *= best_positions[i].records_read; |
| 8099 | read_time += best_positions[i].read_time; |
| 8100 | } |
| 8101 | } |
| 8102 | *read_time_arg= read_time;// + record_count / TIME_FOR_COMPARE; |
| 8103 | *record_count_arg= record_count; |
| 8104 | } |
| 8105 | |
| 8106 | |
| 8107 | /** |
| 8108 | Estimate the number of rows that query execution will read. |
| 8109 | |
| 8110 | @todo This is a very pessimistic upper bound. Use join selectivity |
| 8111 | when available to produce a more realistic number. |
| 8112 | */ |
| 8113 | |
| 8114 | double JOIN::get_examined_rows() |
| 8115 | { |
| 8116 | double examined_rows; |
| 8117 | double prev_fanout= 1; |
| 8118 | JOIN_TAB *tab= first_breadth_first_tab(); |
| 8119 | JOIN_TAB *prev_tab= tab; |
| 8120 | |
| 8121 | examined_rows= (double)tab->get_examined_rows(); |
| 8122 | |
| 8123 | while ((tab= next_breadth_first_tab(first_breadth_first_tab(), |
| 8124 | top_join_tab_count, tab))) |
| 8125 | { |
| 8126 | prev_fanout *= prev_tab->records_read; |
| 8127 | examined_rows+= tab->get_examined_rows() * prev_fanout; |
| 8128 | prev_tab= tab; |
| 8129 | } |
| 8130 | return examined_rows; |
| 8131 | } |
| 8132 | |
| 8133 | |
| 8134 | /** |
| 8135 | @brief |
| 8136 | Get the selectivity of equalities between columns when joining a table |
| 8137 | |
| 8138 | @param join The optimized join |
| 8139 | @param idx The number of tables in the evaluated partual join |
| 8140 | @param s The table to be joined for evaluation |
| 8141 | @param rem_tables The bitmap of tables to be joined later |
| 8142 | @param keyparts The number of key parts to used when joining s |
| 8143 | @param ref_keyuse_steps Array of references to keyuses employed to join s |
| 8144 | */ |
| 8145 | |
| 8146 | static |
| 8147 | double table_multi_eq_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s, |
| 8148 | table_map rem_tables, uint keyparts, |
| 8149 | uint16 *ref_keyuse_steps) |
| 8150 | { |
| 8151 | double sel= 1.0; |
| 8152 | COND_EQUAL *cond_equal= join->cond_equal; |
| 8153 | |
| 8154 | if (!cond_equal || !cond_equal->current_level.elements) |
| 8155 | return sel; |
| 8156 | |
| 8157 | if (!s->keyuse) |
| 8158 | return sel; |
| 8159 | |
| 8160 | Item_equal *item_equal; |
| 8161 | List_iterator_fast<Item_equal> it(cond_equal->current_level); |
| 8162 | TABLE *table= s->table; |
| 8163 | table_map table_bit= table->map; |
| 8164 | POSITION *pos= &join->positions[idx]; |
| 8165 | |
| 8166 | while ((item_equal= it++)) |
| 8167 | { |
| 8168 | /* |
| 8169 | Check whether we need to take into account the selectivity of |
| 8170 | multiple equality item_equal. If this is the case multiply |
| 8171 | the current value of sel by this selectivity |
| 8172 | */ |
| 8173 | table_map used_tables= item_equal->used_tables(); |
| 8174 | if (!(used_tables & table_bit)) |
| 8175 | continue; |
| 8176 | if (item_equal->get_const()) |
| 8177 | continue; |
| 8178 | |
| 8179 | bool adjust_sel= FALSE; |
| 8180 | Item_equal_fields_iterator fi(*item_equal); |
| 8181 | while((fi++) && !adjust_sel) |
| 8182 | { |
| 8183 | Field *fld= fi.get_curr_field(); |
| 8184 | if (fld->table->map != table_bit) |
| 8185 | continue; |
| 8186 | if (pos->key == 0) |
| 8187 | adjust_sel= TRUE; |
| 8188 | else |
| 8189 | { |
| 8190 | uint i; |
| 8191 | KEYUSE *keyuse= pos->key; |
| 8192 | uint key= keyuse->key; |
| 8193 | for (i= 0; i < keyparts; i++) |
| 8194 | { |
| 8195 | if (i > 0) |
| 8196 | keyuse+= ref_keyuse_steps[i-1]; |
| 8197 | uint fldno; |
| 8198 | if (is_hash_join_key_no(key)) |
| 8199 | fldno= keyuse->keypart; |
| 8200 | else |
| 8201 | fldno= table->key_info[key].key_part[i].fieldnr - 1; |
| 8202 | if (fld->field_index == fldno) |
| 8203 | break; |
| 8204 | } |
| 8205 | keyuse= pos->key; |
| 8206 | |
| 8207 | if (i == keyparts) |
| 8208 | { |
| 8209 | /* |
| 8210 | Field fld is included in multiple equality item_equal |
| 8211 | and is not a part of the ref key. |
| 8212 | The selectivity of the multiple equality must be taken |
| 8213 | into account unless one of the ref arguments is |
| 8214 | equal to fld. |
| 8215 | */ |
| 8216 | adjust_sel= TRUE; |
| 8217 | for (uint j= 0; j < keyparts && adjust_sel; j++) |
| 8218 | { |
| 8219 | if (j > 0) |
| 8220 | keyuse+= ref_keyuse_steps[j-1]; |
| 8221 | Item *ref_item= keyuse->val; |
| 8222 | if (ref_item->real_item()->type() == Item::FIELD_ITEM) |
| 8223 | { |
| 8224 | Item_field *field_item= (Item_field *) (ref_item->real_item()); |
| 8225 | if (item_equal->contains(field_item->field)) |
| 8226 | adjust_sel= FALSE; |
| 8227 | } |
| 8228 | } |
| 8229 | } |
| 8230 | } |
| 8231 | } |
| 8232 | if (adjust_sel) |
| 8233 | { |
| 8234 | /* |
| 8235 | If ref == 0 and there are no fields in the multiple equality |
| 8236 | item_equal that belong to the tables joined prior to s |
| 8237 | then the selectivity of multiple equality will be set to 1.0. |
| 8238 | */ |
| 8239 | double eq_fld_sel= 1.0; |
| 8240 | fi.rewind(); |
| 8241 | while ((fi++)) |
| 8242 | { |
| 8243 | double curr_eq_fld_sel; |
| 8244 | Field *fld= fi.get_curr_field(); |
| 8245 | if (!(fld->table->map & ~(table_bit | rem_tables))) |
| 8246 | continue; |
| 8247 | curr_eq_fld_sel= get_column_avg_frequency(fld) / |
| 8248 | fld->table->stat_records(); |
| 8249 | if (curr_eq_fld_sel < 1.0) |
| 8250 | set_if_bigger(eq_fld_sel, curr_eq_fld_sel); |
| 8251 | } |
| 8252 | sel*= eq_fld_sel; |
| 8253 | } |
| 8254 | } |
| 8255 | return sel; |
| 8256 | } |
| 8257 | |
| 8258 | |
| 8259 | /** |
| 8260 | @brief |
| 8261 | Get the selectivity of conditions when joining a table |
| 8262 | |
| 8263 | @param join The optimized join |
| 8264 | @param s The table to be joined for evaluation |
| 8265 | @param rem_tables The bitmap of tables to be joined later |
| 8266 | |
| 8267 | @detail |
| 8268 | Get selectivity of conditions that can be applied when joining this table |
| 8269 | with previous tables. |
| 8270 | |
| 8271 | For quick selects and full table scans, selectivity of COND(this_table) |
| 8272 | is accounted for in matching_candidates_in_table(). Here, we only count |
| 8273 | selectivity of COND(this_table, previous_tables). |
| 8274 | |
| 8275 | For other access methods, we need to calculate selectivity of the whole |
| 8276 | condition, "COND(this_table) AND COND(this_table, previous_tables)". |
| 8277 | |
| 8278 | @retval |
| 8279 | selectivity of the conditions imposed on the rows of s |
| 8280 | */ |
| 8281 | |
| 8282 | static |
| 8283 | double table_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s, |
| 8284 | table_map rem_tables) |
| 8285 | { |
| 8286 | uint16 ref_keyuse_steps[MAX_REF_PARTS - 1]; |
| 8287 | Field *field; |
| 8288 | TABLE *table= s->table; |
| 8289 | MY_BITMAP *read_set= table->read_set; |
| 8290 | double sel= s->table->cond_selectivity; |
| 8291 | POSITION *pos= &join->positions[idx]; |
| 8292 | uint keyparts= 0; |
| 8293 | uint found_part_ref_or_null= 0; |
| 8294 | |
| 8295 | if (pos->key != 0) |
| 8296 | { |
| 8297 | /* |
| 8298 | A ref access or hash join is used for this table. ref access is created |
| 8299 | from |
| 8300 | |
| 8301 | tbl.keypart1=expr1 AND tbl.keypart2=expr2 AND ... |
| 8302 | |
| 8303 | and it will only return rows for which this condition is satisified. |
| 8304 | Suppose, certain expr{i} is a constant. Since ref access only returns |
| 8305 | rows that satisfy |
| 8306 | |
| 8307 | tbl.keypart{i}=const (*) |
| 8308 | |
| 8309 | then selectivity of this equality should not be counted in return value |
| 8310 | of this function. This function uses the value of |
| 8311 | |
| 8312 | table->cond_selectivity=selectivity(COND(tbl)) (**) |
| 8313 | |
| 8314 | as a starting point. This value includes selectivity of equality (*). We |
| 8315 | should somehow discount it. |
| 8316 | |
| 8317 | Looking at calculate_cond_selectivity_for_table(), one can see that that |
| 8318 | the value is not necessarily a direct multiplicand in |
| 8319 | table->cond_selectivity |
| 8320 | |
| 8321 | There are three possible ways to discount |
| 8322 | 1. There is a potential range access on t.keypart{i}=const. |
| 8323 | (an important special case: the used ref access has a const prefix for |
| 8324 | which a range estimate is available) |
| 8325 | |
| 8326 | 2. The field has a histogram. field[x]->cond_selectivity has the data. |
| 8327 | |
| 8328 | 3. Use index stats on this index: |
| 8329 | rec_per_key[key_part+1]/rec_per_key[key_part] |
| 8330 | |
| 8331 | (TODO: more details about the "t.key=othertable.col" case) |
| 8332 | */ |
| 8333 | KEYUSE *keyuse= pos->key; |
| 8334 | KEYUSE *prev_ref_keyuse= keyuse; |
| 8335 | uint key= keyuse->key; |
| 8336 | |
| 8337 | /* |
| 8338 | Check if we have a prefix of key=const that matches a quick select. |
| 8339 | */ |
| 8340 | if (!is_hash_join_key_no(key)) |
| 8341 | { |
| 8342 | key_part_map quick_key_map= (key_part_map(1) << table->quick_key_parts[key]) - 1; |
| 8343 | if (table->quick_rows[key] && |
| 8344 | !(quick_key_map & ~table->const_key_parts[key])) |
| 8345 | { |
| 8346 | /* |
| 8347 | Ok, there is an equality for each of the key parts used by the |
| 8348 | quick select. This means, quick select's estimate can be reused to |
| 8349 | discount the selectivity of a prefix of a ref access. |
| 8350 | */ |
| 8351 | for (; quick_key_map & 1 ; quick_key_map>>= 1) |
| 8352 | { |
| 8353 | while (keyuse->table == table && keyuse->key == key && |
| 8354 | keyuse->keypart == keyparts) |
| 8355 | { |
| 8356 | keyuse++; |
| 8357 | } |
| 8358 | keyparts++; |
| 8359 | } |
| 8360 | sel /= (double)table->quick_rows[key] / (double) table->stat_records(); |
| 8361 | } |
| 8362 | } |
| 8363 | |
| 8364 | /* |
| 8365 | Go through the "keypart{N}=..." equalities and find those that were |
| 8366 | already taken into account in table->cond_selectivity. |
| 8367 | */ |
| 8368 | keyuse= pos->key; |
| 8369 | keyparts=0; |
| 8370 | while (keyuse->table == table && keyuse->key == key) |
| 8371 | { |
| 8372 | if (!(keyuse->used_tables & (rem_tables | table->map))) |
| 8373 | { |
| 8374 | if (are_tables_local(s, keyuse->val->used_tables())) |
| 8375 | { |
| 8376 | if (is_hash_join_key_no(key)) |
| 8377 | { |
| 8378 | if (keyparts == keyuse->keypart) |
| 8379 | keyparts++; |
| 8380 | } |
| 8381 | else |
| 8382 | { |
| 8383 | if (keyparts == keyuse->keypart && |
| 8384 | !((keyuse->val->used_tables()) & ~pos->ref_depend_map) && |
| 8385 | !(found_part_ref_or_null & keyuse->optimize)) |
| 8386 | { |
| 8387 | /* Found a KEYUSE object that will be used by ref access */ |
| 8388 | keyparts++; |
| 8389 | found_part_ref_or_null|= keyuse->optimize & ~KEY_OPTIMIZE_EQ; |
| 8390 | } |
| 8391 | } |
| 8392 | |
| 8393 | if (keyparts > keyuse->keypart) |
| 8394 | { |
| 8395 | /* Ok this is the keyuse that will be used for ref access */ |
| 8396 | uint fldno; |
| 8397 | if (is_hash_join_key_no(key)) |
| 8398 | fldno= keyuse->keypart; |
| 8399 | else |
| 8400 | fldno= table->key_info[key].key_part[keyparts-1].fieldnr - 1; |
| 8401 | if (keyuse->val->const_item()) |
| 8402 | { |
| 8403 | if (table->field[fldno]->cond_selectivity > 0) |
| 8404 | { |
| 8405 | sel /= table->field[fldno]->cond_selectivity; |
| 8406 | set_if_smaller(sel, 1.0); |
| 8407 | } |
| 8408 | /* |
| 8409 | TODO: we could do better here: |
| 8410 | 1. cond_selectivity might be =1 (the default) because quick |
| 8411 | select on some index prevented us from analyzing |
| 8412 | histogram for this column. |
| 8413 | 2. we could get an estimate through this? |
| 8414 | rec_per_key[key_part-1] / rec_per_key[key_part] |
| 8415 | */ |
| 8416 | } |
| 8417 | if (keyparts > 1) |
| 8418 | { |
| 8419 | ref_keyuse_steps[keyparts-2]= (uint16)(keyuse - prev_ref_keyuse); |
| 8420 | prev_ref_keyuse= keyuse; |
| 8421 | } |
| 8422 | } |
| 8423 | } |
| 8424 | } |
| 8425 | keyuse++; |
| 8426 | } |
| 8427 | } |
| 8428 | else |
| 8429 | { |
| 8430 | /* |
| 8431 | The table is accessed with full table scan, or quick select. |
| 8432 | Selectivity of COND(table) is already accounted for in |
| 8433 | matching_candidates_in_table(). |
| 8434 | */ |
| 8435 | sel= 1; |
| 8436 | } |
| 8437 | |
| 8438 | /* |
| 8439 | If the field f from the table is equal to a field from one the |
| 8440 | earlier joined tables then the selectivity of the range conditions |
| 8441 | over the field f must be discounted. |
| 8442 | |
| 8443 | We need to discount selectivity only if we're using ref-based |
| 8444 | access method (and have sel!=1). |
| 8445 | If we use ALL/range/index_merge, then sel==1, and no need to discount. |
| 8446 | */ |
| 8447 | if (pos->key != NULL) |
| 8448 | { |
| 8449 | for (Field **f_ptr=table->field ; (field= *f_ptr) ; f_ptr++) |
| 8450 | { |
| 8451 | if (!bitmap_is_set(read_set, field->field_index) || |
| 8452 | !field->next_equal_field) |
| 8453 | continue; |
| 8454 | for (Field *next_field= field->next_equal_field; |
| 8455 | next_field != field; |
| 8456 | next_field= next_field->next_equal_field) |
| 8457 | { |
| 8458 | if (!(next_field->table->map & rem_tables) && next_field->table != table) |
| 8459 | { |
| 8460 | if (field->cond_selectivity > 0) |
| 8461 | { |
| 8462 | sel/= field->cond_selectivity; |
| 8463 | set_if_smaller(sel, 1.0); |
| 8464 | } |
| 8465 | break; |
| 8466 | } |
| 8467 | } |
| 8468 | } |
| 8469 | } |
| 8470 | |
| 8471 | sel*= table_multi_eq_cond_selectivity(join, idx, s, rem_tables, |
| 8472 | keyparts, ref_keyuse_steps); |
| 8473 | |
| 8474 | return sel; |
| 8475 | } |
| 8476 | |
| 8477 | |
| 8478 | /** |
| 8479 | Find a good, possibly optimal, query execution plan (QEP) by a possibly |
| 8480 | exhaustive search. |
| 8481 | |
| 8482 | The procedure searches for the optimal ordering of the query tables in set |
| 8483 | 'remaining_tables' of size N, and the corresponding optimal access paths to |
| 8484 | each table. The choice of a table order and an access path for each table |
| 8485 | constitutes a query execution plan (QEP) that fully specifies how to |
| 8486 | execute the query. |
| 8487 | |
| 8488 | The maximal size of the found plan is controlled by the parameter |
| 8489 | 'search_depth'. When search_depth == N, the resulting plan is complete and |
| 8490 | can be used directly as a QEP. If search_depth < N, the found plan consists |
| 8491 | of only some of the query tables. Such "partial" optimal plans are useful |
| 8492 | only as input to query optimization procedures, and cannot be used directly |
| 8493 | to execute a query. |
| 8494 | |
| 8495 | The algorithm begins with an empty partial plan stored in 'join->positions' |
| 8496 | and a set of N tables - 'remaining_tables'. Each step of the algorithm |
| 8497 | evaluates the cost of the partial plan extended by all access plans for |
| 8498 | each of the relations in 'remaining_tables', expands the current partial |
| 8499 | plan with the access plan that results in lowest cost of the expanded |
| 8500 | partial plan, and removes the corresponding relation from |
| 8501 | 'remaining_tables'. The algorithm continues until it either constructs a |
| 8502 | complete optimal plan, or constructs an optimal plartial plan with size = |
| 8503 | search_depth. |
| 8504 | |
| 8505 | The final optimal plan is stored in 'join->best_positions'. The |
| 8506 | corresponding cost of the optimal plan is in 'join->best_read'. |
| 8507 | |
| 8508 | @note |
| 8509 | The procedure uses a recursive depth-first search where the depth of the |
| 8510 | recursion (and thus the exhaustiveness of the search) is controlled by the |
| 8511 | parameter 'search_depth'. |
| 8512 | |
| 8513 | @note |
| 8514 | The pseudocode below describes the algorithm of |
| 8515 | 'best_extension_by_limited_search'. The worst-case complexity of this |
| 8516 | algorithm is O(N*N^search_depth/search_depth). When serch_depth >= N, then |
| 8517 | the complexity of greedy_search is O(N!). |
| 8518 | |
| 8519 | @code |
| 8520 | procedure best_extension_by_limited_search( |
| 8521 | pplan in, // in, partial plan of tables-joined-so-far |
| 8522 | pplan_cost, // in, cost of pplan |
| 8523 | remaining_tables, // in, set of tables not referenced in pplan |
| 8524 | best_plan_so_far, // in/out, best plan found so far |
| 8525 | best_plan_so_far_cost,// in/out, cost of best_plan_so_far |
| 8526 | search_depth) // in, maximum size of the plans being considered |
| 8527 | { |
| 8528 | for each table T from remaining_tables |
| 8529 | { |
| 8530 | // Calculate the cost of using table T as above |
| 8531 | cost = complex-series-of-calculations; |
| 8532 | |
| 8533 | // Add the cost to the cost so far. |
| 8534 | pplan_cost+= cost; |
| 8535 | |
| 8536 | if (pplan_cost >= best_plan_so_far_cost) |
| 8537 | // pplan_cost already too great, stop search |
| 8538 | continue; |
| 8539 | |
| 8540 | pplan= expand pplan by best_access_method; |
| 8541 | remaining_tables= remaining_tables - table T; |
| 8542 | if (remaining_tables is not an empty set |
| 8543 | and |
| 8544 | search_depth > 1) |
| 8545 | { |
| 8546 | best_extension_by_limited_search(pplan, pplan_cost, |
| 8547 | remaining_tables, |
| 8548 | best_plan_so_far, |
| 8549 | best_plan_so_far_cost, |
| 8550 | search_depth - 1); |
| 8551 | } |
| 8552 | else |
| 8553 | { |
| 8554 | best_plan_so_far_cost= pplan_cost; |
| 8555 | best_plan_so_far= pplan; |
| 8556 | } |
| 8557 | } |
| 8558 | } |
| 8559 | @endcode |
| 8560 | |
| 8561 | @note |
| 8562 | When 'best_extension_by_limited_search' is called for the first time, |
| 8563 | 'join->best_read' must be set to the largest possible value (e.g. DBL_MAX). |
| 8564 | The actual implementation provides a way to optionally use pruning |
| 8565 | heuristic (controlled by the parameter 'prune_level') to reduce the search |
| 8566 | space by skipping some partial plans. |
| 8567 | |
| 8568 | @note |
| 8569 | The parameter 'search_depth' provides control over the recursion |
| 8570 | depth, and thus the size of the resulting optimal plan. |
| 8571 | |
| 8572 | @param join pointer to the structure providing all context info |
| 8573 | for the query |
| 8574 | @param remaining_tables set of tables not included into the partial plan yet |
| 8575 | @param idx length of the partial QEP in 'join->positions'; |
| 8576 | since a depth-first search is used, also corresponds |
| 8577 | to the current depth of the search tree; |
| 8578 | also an index in the array 'join->best_ref'; |
| 8579 | @param record_count estimate for the number of records returned by the |
| 8580 | best partial plan |
| 8581 | @param read_time the cost of the best partial plan |
| 8582 | @param search_depth maximum depth of the recursion and thus size of the |
| 8583 | found optimal plan |
| 8584 | (0 < search_depth <= join->tables+1). |
| 8585 | @param prune_level pruning heuristics that should be applied during |
| 8586 | optimization |
| 8587 | (values: 0 = EXHAUSTIVE, 1 = PRUNE_BY_TIME_OR_ROWS) |
| 8588 | @param use_cond_selectivity specifies how the selectivity of the conditions |
| 8589 | pushed to a table should be taken into account |
| 8590 | |
| 8591 | @retval |
| 8592 | FALSE ok |
| 8593 | @retval |
| 8594 | TRUE Fatal error |
| 8595 | */ |
| 8596 | |
| 8597 | static bool |
| 8598 | best_extension_by_limited_search(JOIN *join, |
| 8599 | table_map remaining_tables, |
| 8600 | uint idx, |
| 8601 | double record_count, |
| 8602 | double read_time, |
| 8603 | uint search_depth, |
| 8604 | uint prune_level, |
| 8605 | uint use_cond_selectivity) |
| 8606 | { |
| 8607 | DBUG_ENTER("best_extension_by_limited_search" ); |
| 8608 | |
| 8609 | THD *thd= join->thd; |
| 8610 | |
| 8611 | DBUG_EXECUTE_IF("show_explain_probe_best_ext_lim_search" , |
| 8612 | if (dbug_user_var_equals_int(thd, |
| 8613 | "show_explain_probe_select_id" , |
| 8614 | join->select_lex->select_number)) |
| 8615 | dbug_serve_apcs(thd, 1); |
| 8616 | ); |
| 8617 | |
| 8618 | if (unlikely(thd->check_killed())) // Abort |
| 8619 | DBUG_RETURN(TRUE); |
| 8620 | |
| 8621 | DBUG_EXECUTE("opt" , print_plan(join, idx, read_time, record_count, idx, |
| 8622 | "SOFAR:" );); |
| 8623 | |
| 8624 | /* |
| 8625 | 'join' is a partial plan with lower cost than the best plan so far, |
| 8626 | so continue expanding it further with the tables in 'remaining_tables'. |
| 8627 | */ |
| 8628 | JOIN_TAB *s; |
| 8629 | double best_record_count= DBL_MAX; |
| 8630 | double best_read_time= DBL_MAX; |
| 8631 | bool disable_jbuf= join->thd->variables.join_cache_level == 0; |
| 8632 | |
| 8633 | DBUG_EXECUTE("opt" , print_plan(join, idx, record_count, read_time, read_time, |
| 8634 | "part_plan" );); |
| 8635 | |
| 8636 | /* |
| 8637 | If we are searching for the execution plan of a materialized semi-join nest |
| 8638 | then allowed_tables contains bits only for the tables from this nest. |
| 8639 | */ |
| 8640 | table_map allowed_tables= ~(table_map)0; |
| 8641 | if (join->emb_sjm_nest) |
| 8642 | allowed_tables= join->emb_sjm_nest->sj_inner_tables & ~join->const_table_map; |
| 8643 | |
| 8644 | for (JOIN_TAB **pos= join->best_ref + idx ; (s= *pos) ; pos++) |
| 8645 | { |
| 8646 | table_map real_table_bit= s->table->map; |
| 8647 | if ((remaining_tables & real_table_bit) && |
| 8648 | (allowed_tables & real_table_bit) && |
| 8649 | !(remaining_tables & s->dependent) && |
| 8650 | (!idx || !check_interleaving_with_nj(s))) |
| 8651 | { |
| 8652 | double current_record_count, current_read_time; |
| 8653 | POSITION *position= join->positions + idx; |
| 8654 | |
| 8655 | /* Find the best access method from 's' to the current partial plan */ |
| 8656 | POSITION loose_scan_pos; |
| 8657 | best_access_path(join, s, remaining_tables, idx, disable_jbuf, |
| 8658 | record_count, position, &loose_scan_pos); |
| 8659 | |
| 8660 | /* Compute the cost of extending the plan with 's', avoid overflow */ |
| 8661 | if (position->records_read < DBL_MAX / record_count) |
| 8662 | current_record_count= record_count * position->records_read; |
| 8663 | else |
| 8664 | current_record_count= DBL_MAX; |
| 8665 | current_read_time=read_time + position->read_time + |
| 8666 | current_record_count / (double) TIME_FOR_COMPARE; |
| 8667 | |
| 8668 | advance_sj_state(join, remaining_tables, idx, ¤t_record_count, |
| 8669 | ¤t_read_time, &loose_scan_pos); |
| 8670 | |
| 8671 | /* Expand only partial plans with lower cost than the best QEP so far */ |
| 8672 | if (current_read_time >= join->best_read) |
| 8673 | { |
| 8674 | DBUG_EXECUTE("opt" , print_plan(join, idx+1, |
| 8675 | current_record_count, |
| 8676 | read_time, |
| 8677 | current_read_time, |
| 8678 | "prune_by_cost" );); |
| 8679 | restore_prev_nj_state(s); |
| 8680 | restore_prev_sj_state(remaining_tables, s, idx); |
| 8681 | continue; |
| 8682 | } |
| 8683 | |
| 8684 | /* |
| 8685 | Prune some less promising partial plans. This heuristic may miss |
| 8686 | the optimal QEPs, thus it results in a non-exhaustive search. |
| 8687 | */ |
| 8688 | if (prune_level == 1) |
| 8689 | { |
| 8690 | if (best_record_count > current_record_count || |
| 8691 | best_read_time > current_read_time || |
| 8692 | (idx == join->const_tables && // 's' is the first table in the QEP |
| 8693 | s->table == join->sort_by_table)) |
| 8694 | { |
| 8695 | if (best_record_count >= current_record_count && |
| 8696 | best_read_time >= current_read_time && |
| 8697 | /* TODO: What is the reasoning behind this condition? */ |
| 8698 | (!(s->key_dependent & allowed_tables & remaining_tables) || |
| 8699 | join->positions[idx].records_read < 2.0)) |
| 8700 | { |
| 8701 | best_record_count= current_record_count; |
| 8702 | best_read_time= current_read_time; |
| 8703 | } |
| 8704 | } |
| 8705 | else |
| 8706 | { |
| 8707 | DBUG_EXECUTE("opt" , print_plan(join, idx+1, |
| 8708 | current_record_count, |
| 8709 | read_time, |
| 8710 | current_read_time, |
| 8711 | "pruned_by_heuristic" );); |
| 8712 | restore_prev_nj_state(s); |
| 8713 | restore_prev_sj_state(remaining_tables, s, idx); |
| 8714 | continue; |
| 8715 | } |
| 8716 | } |
| 8717 | |
| 8718 | double pushdown_cond_selectivity= 1.0; |
| 8719 | if (use_cond_selectivity > 1) |
| 8720 | pushdown_cond_selectivity= table_cond_selectivity(join, idx, s, |
| 8721 | remaining_tables & |
| 8722 | ~real_table_bit); |
| 8723 | join->positions[idx].cond_selectivity= pushdown_cond_selectivity; |
| 8724 | double partial_join_cardinality= current_record_count * |
| 8725 | pushdown_cond_selectivity; |
| 8726 | if ( (search_depth > 1) && (remaining_tables & ~real_table_bit) & allowed_tables ) |
| 8727 | { /* Recursively expand the current partial plan */ |
| 8728 | swap_variables(JOIN_TAB*, join->best_ref[idx], *pos); |
| 8729 | if (best_extension_by_limited_search(join, |
| 8730 | remaining_tables & ~real_table_bit, |
| 8731 | idx + 1, |
| 8732 | partial_join_cardinality, |
| 8733 | current_read_time, |
| 8734 | search_depth - 1, |
| 8735 | prune_level, |
| 8736 | use_cond_selectivity)) |
| 8737 | DBUG_RETURN(TRUE); |
| 8738 | swap_variables(JOIN_TAB*, join->best_ref[idx], *pos); |
| 8739 | } |
| 8740 | else |
| 8741 | { /* |
| 8742 | 'join' is either the best partial QEP with 'search_depth' relations, |
| 8743 | or the best complete QEP so far, whichever is smaller. |
| 8744 | */ |
| 8745 | if (join->sort_by_table && |
| 8746 | join->sort_by_table != |
| 8747 | join->positions[join->const_tables].table->table) |
| 8748 | /* |
| 8749 | We may have to make a temp table, note that this is only a |
| 8750 | heuristic since we cannot know for sure at this point. |
| 8751 | Hence it may be wrong. |
| 8752 | */ |
| 8753 | current_read_time+= current_record_count; |
| 8754 | if (current_read_time < join->best_read) |
| 8755 | { |
| 8756 | memcpy((uchar*) join->best_positions, (uchar*) join->positions, |
| 8757 | sizeof(POSITION) * (idx + 1)); |
| 8758 | join->join_record_count= partial_join_cardinality; |
| 8759 | join->best_read= current_read_time - 0.001; |
| 8760 | } |
| 8761 | DBUG_EXECUTE("opt" , print_plan(join, idx+1, |
| 8762 | current_record_count, |
| 8763 | read_time, |
| 8764 | current_read_time, |
| 8765 | "full_plan" );); |
| 8766 | } |
| 8767 | restore_prev_nj_state(s); |
| 8768 | restore_prev_sj_state(remaining_tables, s, idx); |
| 8769 | } |
| 8770 | } |
| 8771 | DBUG_RETURN(FALSE); |
| 8772 | } |
| 8773 | |
| 8774 | |
| 8775 | /** |
| 8776 | Find how much space the prevous read not const tables takes in cache. |
| 8777 | */ |
| 8778 | |
| 8779 | void JOIN_TAB::calc_used_field_length(bool max_fl) |
| 8780 | { |
| 8781 | uint null_fields,blobs,fields; |
| 8782 | ulong rec_length; |
| 8783 | Field **f_ptr,*field; |
| 8784 | uint uneven_bit_fields; |
| 8785 | MY_BITMAP *read_set= table->read_set; |
| 8786 | |
| 8787 | uneven_bit_fields= null_fields= blobs= fields= rec_length=0; |
| 8788 | for (f_ptr=table->field ; (field= *f_ptr) ; f_ptr++) |
| 8789 | { |
| 8790 | if (bitmap_is_set(read_set, field->field_index)) |
| 8791 | { |
| 8792 | uint flags=field->flags; |
| 8793 | fields++; |
| 8794 | rec_length+=field->pack_length(); |
| 8795 | if (flags & BLOB_FLAG) |
| 8796 | blobs++; |
| 8797 | if (!(flags & NOT_NULL_FLAG)) |
| 8798 | null_fields++; |
| 8799 | if (field->type() == MYSQL_TYPE_BIT && |
| 8800 | ((Field_bit*)field)->bit_len) |
| 8801 | uneven_bit_fields++; |
| 8802 | } |
| 8803 | } |
| 8804 | if (null_fields || uneven_bit_fields) |
| 8805 | rec_length+=(table->s->null_fields+7)/8; |
| 8806 | if (table->maybe_null) |
| 8807 | rec_length+=sizeof(my_bool); |
| 8808 | |
| 8809 | /* Take into account that DuplicateElimination may need to store rowid */ |
| 8810 | uint rowid_add_size= 0; |
| 8811 | if (keep_current_rowid) |
| 8812 | { |
| 8813 | rowid_add_size= table->file->ref_length; |
| 8814 | rec_length += rowid_add_size; |
| 8815 | fields++; |
| 8816 | } |
| 8817 | |
| 8818 | if (max_fl) |
| 8819 | { |
| 8820 | // TODO: to improve this estimate for max expected length |
| 8821 | if (blobs) |
| 8822 | { |
| 8823 | ulong blob_length= table->file->stats.mean_rec_length; |
| 8824 | if (ULONG_MAX - rec_length > blob_length) |
| 8825 | rec_length+= blob_length; |
| 8826 | else |
| 8827 | rec_length= ULONG_MAX; |
| 8828 | } |
| 8829 | max_used_fieldlength= rec_length; |
| 8830 | } |
| 8831 | else if (table->file->stats.mean_rec_length) |
| 8832 | set_if_smaller(rec_length, table->file->stats.mean_rec_length + rowid_add_size); |
| 8833 | |
| 8834 | used_fields=fields; |
| 8835 | used_fieldlength=rec_length; |
| 8836 | used_blobs=blobs; |
| 8837 | used_null_fields= null_fields; |
| 8838 | used_uneven_bit_fields= uneven_bit_fields; |
| 8839 | } |
| 8840 | |
| 8841 | |
| 8842 | /* |
| 8843 | @brief |
| 8844 | Extract pushdown conditions for a table scan |
| 8845 | |
| 8846 | @details |
| 8847 | This functions extracts pushdown conditions usable when this table is scanned. |
| 8848 | The conditions are extracted either from WHERE or from ON expressions. |
| 8849 | The conditions are attached to the field cache_select of this table. |
| 8850 | |
| 8851 | @note |
| 8852 | Currently the extracted conditions are used only by BNL and BNLH join. |
| 8853 | algorithms. |
| 8854 | |
| 8855 | @retval 0 on success |
| 8856 | 1 otherwise |
| 8857 | */ |
| 8858 | |
| 8859 | int JOIN_TAB::make_scan_filter() |
| 8860 | { |
| 8861 | COND *tmp; |
| 8862 | DBUG_ENTER("make_scan_filter" ); |
| 8863 | |
| 8864 | Item *cond= is_inner_table_of_outer_join() ? |
| 8865 | *get_first_inner_table()->on_expr_ref : join->conds; |
| 8866 | |
| 8867 | if (cond && |
| 8868 | (tmp= make_cond_for_table(join->thd, cond, |
| 8869 | join->const_table_map | table->map, |
| 8870 | table->map, -1, FALSE, TRUE))) |
| 8871 | { |
| 8872 | DBUG_EXECUTE("where" ,print_where(tmp,"cache" , QT_ORDINARY);); |
| 8873 | if (!(cache_select= |
| 8874 | (SQL_SELECT*) join->thd->memdup((uchar*) select, sizeof(SQL_SELECT)))) |
| 8875 | DBUG_RETURN(1); |
| 8876 | cache_select->cond= tmp; |
| 8877 | cache_select->read_tables=join->const_table_map; |
| 8878 | } |
| 8879 | DBUG_RETURN(0); |
| 8880 | } |
| 8881 | |
| 8882 | |
| 8883 | /** |
| 8884 | @brief |
| 8885 | Check whether hash join algorithm can be used to join this table |
| 8886 | |
| 8887 | @details |
| 8888 | This function finds out whether the ref items that have been chosen |
| 8889 | by the planner to access this table can be used for hash join algorithms. |
| 8890 | The answer depends on a certain property of the the fields of the |
| 8891 | joined tables on which the hash join key is built. |
| 8892 | |
| 8893 | @note |
| 8894 | At present the function is supposed to be called only after the function |
| 8895 | get_best_combination has been called. |
| 8896 | |
| 8897 | @retval TRUE it's possible to use hash join to join this table |
| 8898 | @retval FALSE otherwise |
| 8899 | */ |
| 8900 | |
| 8901 | bool JOIN_TAB::hash_join_is_possible() |
| 8902 | { |
| 8903 | if (type != JT_REF && type != JT_EQ_REF) |
| 8904 | return FALSE; |
| 8905 | if (!is_ref_for_hash_join()) |
| 8906 | { |
| 8907 | KEY *keyinfo= table->key_info + ref.key; |
| 8908 | return keyinfo->key_part[0].field->hash_join_is_possible(); |
| 8909 | } |
| 8910 | return TRUE; |
| 8911 | } |
| 8912 | |
| 8913 | |
| 8914 | /** |
| 8915 | @brief |
| 8916 | Check whether a KEYUSE can be really used for access this join table |
| 8917 | |
| 8918 | @param join Join structure with the best join order |
| 8919 | for which the check is performed |
| 8920 | @param keyuse Evaluated KEYUSE structure |
| 8921 | |
| 8922 | @details |
| 8923 | This function is supposed to be used after the best execution plan have been |
| 8924 | already chosen and the JOIN_TAB array for the best join order been already set. |
| 8925 | For a given KEYUSE to access this JOIN_TAB in the best execution plan the |
| 8926 | function checks whether it really can be used. The function first performs |
| 8927 | the check with access_from_tables_is_allowed(). If it succeeds it checks |
| 8928 | whether the keyuse->val does not use some fields of a materialized semijoin |
| 8929 | nest that cannot be used to build keys to access outer tables. |
| 8930 | Such KEYUSEs exists for the query like this: |
| 8931 | select * from ot |
| 8932 | where ot.c in (select it1.c from it1, it2 where it1.c=f(it2.c)) |
| 8933 | Here we have two KEYUSEs to access table ot: with val=it1.c and val=f(it2.c). |
| 8934 | However if the subquery was materialized the second KEYUSE cannot be employed |
| 8935 | to access ot. |
| 8936 | |
| 8937 | @retval true the given keyuse can be used for ref access of this JOIN_TAB |
| 8938 | @retval false otherwise |
| 8939 | */ |
| 8940 | |
| 8941 | bool JOIN_TAB::keyuse_is_valid_for_access_in_chosen_plan(JOIN *join, |
| 8942 | KEYUSE *keyuse) |
| 8943 | { |
| 8944 | if (!access_from_tables_is_allowed(keyuse->used_tables, |
| 8945 | join->sjm_lookup_tables)) |
| 8946 | return false; |
| 8947 | if (join->sjm_scan_tables & table->map) |
| 8948 | return true; |
| 8949 | table_map keyuse_sjm_scan_tables= keyuse->used_tables & |
| 8950 | join->sjm_scan_tables; |
| 8951 | if (!keyuse_sjm_scan_tables) |
| 8952 | return true; |
| 8953 | uint sjm_tab_nr= 0; |
| 8954 | while (!(keyuse_sjm_scan_tables & table_map(1) << sjm_tab_nr)) |
| 8955 | sjm_tab_nr++; |
| 8956 | JOIN_TAB *sjm_tab= join->map2table[sjm_tab_nr]; |
| 8957 | TABLE_LIST *emb_sj_nest= sjm_tab->emb_sj_nest; |
| 8958 | if (!(emb_sj_nest->sj_mat_info && emb_sj_nest->sj_mat_info->is_used && |
| 8959 | emb_sj_nest->sj_mat_info->is_sj_scan)) |
| 8960 | return true; |
| 8961 | st_select_lex *sjm_sel= emb_sj_nest->sj_subq_pred->unit->first_select(); |
| 8962 | for (uint i= 0; i < sjm_sel->item_list.elements; i++) |
| 8963 | { |
| 8964 | if (sjm_sel->ref_pointer_array[i] == keyuse->val) |
| 8965 | return true; |
| 8966 | } |
| 8967 | return false; |
| 8968 | } |
| 8969 | |
| 8970 | |
| 8971 | static uint |
| 8972 | cache_record_length(JOIN *join,uint idx) |
| 8973 | { |
| 8974 | uint length=0; |
| 8975 | JOIN_TAB **pos,**end; |
| 8976 | |
| 8977 | for (pos=join->best_ref+join->const_tables,end=join->best_ref+idx ; |
| 8978 | pos != end ; |
| 8979 | pos++) |
| 8980 | { |
| 8981 | JOIN_TAB *join_tab= *pos; |
| 8982 | length+= join_tab->get_used_fieldlength(); |
| 8983 | } |
| 8984 | return length; |
| 8985 | } |
| 8986 | |
| 8987 | |
| 8988 | /* |
| 8989 | Get the number of different row combinations for subset of partial join |
| 8990 | |
| 8991 | SYNOPSIS |
| 8992 | prev_record_reads() |
| 8993 | join The join structure |
| 8994 | idx Number of tables in the partial join order (i.e. the |
| 8995 | partial join order is in join->positions[0..idx-1]) |
| 8996 | found_ref Bitmap of tables for which we need to find # of distinct |
| 8997 | row combinations. |
| 8998 | |
| 8999 | DESCRIPTION |
| 9000 | Given a partial join order (in join->positions[0..idx-1]) and a subset of |
| 9001 | tables within that join order (specified in found_ref), find out how many |
| 9002 | distinct row combinations of subset tables will be in the result of the |
| 9003 | partial join order. |
| 9004 | |
| 9005 | This is used as follows: Suppose we have a table accessed with a ref-based |
| 9006 | method. The ref access depends on current rows of tables in found_ref. |
| 9007 | We want to count # of different ref accesses. We assume two ref accesses |
| 9008 | will be different if at least one of access parameters is different. |
| 9009 | Example: consider a query |
| 9010 | |
| 9011 | SELECT * FROM t1, t2, t3 WHERE t1.key=c1 AND t2.key=c2 AND t3.key=t1.field |
| 9012 | |
| 9013 | and a join order: |
| 9014 | t1, ref access on t1.key=c1 |
| 9015 | t2, ref access on t2.key=c2 |
| 9016 | t3, ref access on t3.key=t1.field |
| 9017 | |
| 9018 | For t1: n_ref_scans = 1, n_distinct_ref_scans = 1 |
| 9019 | For t2: n_ref_scans = records_read(t1), n_distinct_ref_scans=1 |
| 9020 | For t3: n_ref_scans = records_read(t1)*records_read(t2) |
| 9021 | n_distinct_ref_scans = #records_read(t1) |
| 9022 | |
| 9023 | The reason for having this function (at least the latest version of it) |
| 9024 | is that we need to account for buffering in join execution. |
| 9025 | |
| 9026 | An edge-case example: if we have a non-first table in join accessed via |
| 9027 | ref(const) or ref(param) where there is a small number of different |
| 9028 | values of param, then the access will likely hit the disk cache and will |
| 9029 | not require any disk seeks. |
| 9030 | |
| 9031 | The proper solution would be to assume an LRU disk cache of some size, |
| 9032 | calculate probability of cache hits, etc. For now we just count |
| 9033 | identical ref accesses as one. |
| 9034 | |
| 9035 | RETURN |
| 9036 | Expected number of row combinations |
| 9037 | */ |
| 9038 | |
| 9039 | double |
| 9040 | prev_record_reads(POSITION *positions, uint idx, table_map found_ref) |
| 9041 | { |
| 9042 | double found=1.0; |
| 9043 | POSITION *pos_end= positions - 1; |
| 9044 | for (POSITION *pos= positions + idx - 1; pos != pos_end; pos--) |
| 9045 | { |
| 9046 | if (pos->table->table->map & found_ref) |
| 9047 | { |
| 9048 | found_ref|= pos->ref_depend_map; |
| 9049 | /* |
| 9050 | For the case of "t1 LEFT JOIN t2 ON ..." where t2 is a const table |
| 9051 | with no matching row we will get position[t2].records_read==0. |
| 9052 | Actually the size of output is one null-complemented row, therefore |
| 9053 | we will use value of 1 whenever we get records_read==0. |
| 9054 | |
| 9055 | Note |
| 9056 | - the above case can't occur if inner part of outer join has more |
| 9057 | than one table: table with no matches will not be marked as const. |
| 9058 | |
| 9059 | - Ideally we should add 1 to records_read for every possible null- |
| 9060 | complemented row. We're not doing it because: 1. it will require |
| 9061 | non-trivial code and add overhead. 2. The value of records_read |
| 9062 | is an inprecise estimate and adding 1 (or, in the worst case, |
| 9063 | #max_nested_outer_joins=64-1) will not make it any more precise. |
| 9064 | */ |
| 9065 | if (pos->records_read) |
| 9066 | found*= pos->records_read; |
| 9067 | } |
| 9068 | } |
| 9069 | return found; |
| 9070 | } |
| 9071 | |
| 9072 | |
| 9073 | /* |
| 9074 | Enumerate join tabs in breadth-first fashion, including const tables. |
| 9075 | */ |
| 9076 | |
| 9077 | static JOIN_TAB *next_breadth_first_tab(JOIN_TAB *first_top_tab, |
| 9078 | uint n_top_tabs_count, JOIN_TAB *tab) |
| 9079 | { |
| 9080 | n_top_tabs_count += tab->join->aggr_tables; |
| 9081 | if (!tab->bush_root_tab) |
| 9082 | { |
| 9083 | /* We're at top level. Get the next top-level tab */ |
| 9084 | tab++; |
| 9085 | if (tab < first_top_tab + n_top_tabs_count) |
| 9086 | return tab; |
| 9087 | |
| 9088 | /* No more top-level tabs. Switch to enumerating SJM nest children */ |
| 9089 | tab= first_top_tab; |
| 9090 | } |
| 9091 | else |
| 9092 | { |
| 9093 | /* We're inside of an SJM nest */ |
| 9094 | if (!tab->last_leaf_in_bush) |
| 9095 | { |
| 9096 | /* There's one more table in the nest, return it. */ |
| 9097 | return ++tab; |
| 9098 | } |
| 9099 | else |
| 9100 | { |
| 9101 | /* |
| 9102 | There are no more tables in this nest. Get out of it and then we'll |
| 9103 | proceed to the next nest. |
| 9104 | */ |
| 9105 | tab= tab->bush_root_tab + 1; |
| 9106 | } |
| 9107 | } |
| 9108 | |
| 9109 | /* |
| 9110 | Ok, "tab" points to a top-level table, and we need to find the next SJM |
| 9111 | nest and enter it. |
| 9112 | */ |
| 9113 | for (; tab < first_top_tab + n_top_tabs_count; tab++) |
| 9114 | { |
| 9115 | if (tab->bush_children) |
| 9116 | return tab->bush_children->start; |
| 9117 | } |
| 9118 | return NULL; |
| 9119 | } |
| 9120 | |
| 9121 | |
| 9122 | /* |
| 9123 | Enumerate JOIN_TABs in "EXPLAIN order". This order |
| 9124 | - const tabs are included |
| 9125 | - we enumerate "optimization tabs". |
| 9126 | - |
| 9127 | */ |
| 9128 | |
| 9129 | JOIN_TAB *first_explain_order_tab(JOIN* join) |
| 9130 | { |
| 9131 | JOIN_TAB* tab; |
| 9132 | tab= join->join_tab; |
| 9133 | if (!tab) |
| 9134 | return NULL; /* Can happen when when the tables were optimized away */ |
| 9135 | return (tab->bush_children) ? tab->bush_children->start : tab; |
| 9136 | } |
| 9137 | |
| 9138 | |
| 9139 | JOIN_TAB *next_explain_order_tab(JOIN* join, JOIN_TAB* tab) |
| 9140 | { |
| 9141 | /* If we're inside SJM nest and have reached its end, get out */ |
| 9142 | if (tab->last_leaf_in_bush) |
| 9143 | return tab->bush_root_tab; |
| 9144 | |
| 9145 | /* Move to next tab in the array we're traversing */ |
| 9146 | tab++; |
| 9147 | |
| 9148 | if (tab == join->join_tab + join->top_join_tab_count) |
| 9149 | return NULL; /* Outside SJM nest and reached EOF */ |
| 9150 | |
| 9151 | if (tab->bush_children) |
| 9152 | return tab->bush_children->start; |
| 9153 | |
| 9154 | return tab; |
| 9155 | } |
| 9156 | |
| 9157 | |
| 9158 | |
| 9159 | JOIN_TAB *first_top_level_tab(JOIN *join, enum enum_with_const_tables const_tbls) |
| 9160 | { |
| 9161 | JOIN_TAB *tab= join->join_tab; |
| 9162 | if (const_tbls == WITHOUT_CONST_TABLES) |
| 9163 | { |
| 9164 | if (join->const_tables == join->table_count || !tab) |
| 9165 | return NULL; |
| 9166 | tab += join->const_tables; |
| 9167 | } |
| 9168 | return tab; |
| 9169 | } |
| 9170 | |
| 9171 | |
| 9172 | JOIN_TAB *next_top_level_tab(JOIN *join, JOIN_TAB *tab) |
| 9173 | { |
| 9174 | tab= next_breadth_first_tab(join->first_breadth_first_tab(), |
| 9175 | join->top_join_tab_count, tab); |
| 9176 | if (tab && tab->bush_root_tab) |
| 9177 | tab= NULL; |
| 9178 | return tab; |
| 9179 | } |
| 9180 | |
| 9181 | |
| 9182 | JOIN_TAB *first_linear_tab(JOIN *join, |
| 9183 | enum enum_with_bush_roots include_bush_roots, |
| 9184 | enum enum_with_const_tables const_tbls) |
| 9185 | { |
| 9186 | JOIN_TAB *first= join->join_tab; |
| 9187 | |
| 9188 | if (!first) |
| 9189 | return NULL; |
| 9190 | |
| 9191 | if (const_tbls == WITHOUT_CONST_TABLES) |
| 9192 | first+= join->const_tables; |
| 9193 | |
| 9194 | if (first >= join->join_tab + join->top_join_tab_count) |
| 9195 | return NULL; /* All are const tables */ |
| 9196 | |
| 9197 | if (first->bush_children && include_bush_roots == WITHOUT_BUSH_ROOTS) |
| 9198 | { |
| 9199 | /* This JOIN_TAB is a SJM nest; Start from first table in nest */ |
| 9200 | return first->bush_children->start; |
| 9201 | } |
| 9202 | |
| 9203 | return first; |
| 9204 | } |
| 9205 | |
| 9206 | |
| 9207 | /* |
| 9208 | A helper function to loop over all join's join_tab in sequential fashion |
| 9209 | |
| 9210 | DESCRIPTION |
| 9211 | Depending on include_bush_roots parameter, JOIN_TABs that represent |
| 9212 | SJM-scan/lookups are either returned or omitted. |
| 9213 | |
| 9214 | SJM-Bush children are returned right after (or in place of) their container |
| 9215 | join tab (TODO: does anybody depend on this? A: make_join_readinfo() seems |
| 9216 | to) |
| 9217 | |
| 9218 | For example, if we have this structure: |
| 9219 | |
| 9220 | ot1--ot2--sjm1----------------ot3-... |
| 9221 | | |
| 9222 | +--it1--it2--it3 |
| 9223 | |
| 9224 | calls to next_linear_tab( include_bush_roots=TRUE) will return: |
| 9225 | |
| 9226 | ot1 ot2 sjm1 it1 it2 it3 ot3 ... |
| 9227 | |
| 9228 | while calls to next_linear_tab( include_bush_roots=FALSE) will return: |
| 9229 | |
| 9230 | ot1 ot2 it1 it2 it3 ot3 ... |
| 9231 | |
| 9232 | (note that sjm1 won't be returned). |
| 9233 | */ |
| 9234 | |
| 9235 | JOIN_TAB *next_linear_tab(JOIN* join, JOIN_TAB* tab, |
| 9236 | enum enum_with_bush_roots include_bush_roots) |
| 9237 | { |
| 9238 | if (include_bush_roots == WITH_BUSH_ROOTS && tab->bush_children) |
| 9239 | { |
| 9240 | /* This JOIN_TAB is a SJM nest; Start from first table in nest */ |
| 9241 | return tab->bush_children->start; |
| 9242 | } |
| 9243 | |
| 9244 | DBUG_ASSERT(!tab->last_leaf_in_bush || tab->bush_root_tab); |
| 9245 | |
| 9246 | if (tab->bush_root_tab) /* Are we inside an SJM nest */ |
| 9247 | { |
| 9248 | /* Inside SJM nest */ |
| 9249 | if (!tab->last_leaf_in_bush) |
| 9250 | return tab+1; /* Return next in nest */ |
| 9251 | /* Continue from the sjm on the top level */ |
| 9252 | tab= tab->bush_root_tab; |
| 9253 | } |
| 9254 | |
| 9255 | /* If no more JOIN_TAB's on the top level */ |
| 9256 | if (++tab == join->join_tab + join->top_join_tab_count + join->aggr_tables) |
| 9257 | return NULL; |
| 9258 | |
| 9259 | if (include_bush_roots == WITHOUT_BUSH_ROOTS && tab->bush_children) |
| 9260 | { |
| 9261 | /* This JOIN_TAB is a SJM nest; Start from first table in nest */ |
| 9262 | tab= tab->bush_children->start; |
| 9263 | } |
| 9264 | return tab; |
| 9265 | } |
| 9266 | |
| 9267 | |
| 9268 | /* |
| 9269 | Start to iterate over all join tables in bush-children-first order, excluding |
| 9270 | the const tables (see next_depth_first_tab() comment for details) |
| 9271 | */ |
| 9272 | |
| 9273 | JOIN_TAB *first_depth_first_tab(JOIN* join) |
| 9274 | { |
| 9275 | JOIN_TAB* tab; |
| 9276 | /* This means we're starting the enumeration */ |
| 9277 | if (join->const_tables == join->top_join_tab_count || !join->join_tab) |
| 9278 | return NULL; |
| 9279 | |
| 9280 | tab= join->join_tab + join->const_tables; |
| 9281 | |
| 9282 | return (tab->bush_children) ? tab->bush_children->start : tab; |
| 9283 | } |
| 9284 | |
| 9285 | |
| 9286 | /* |
| 9287 | A helper function to iterate over all join tables in bush-children-first order |
| 9288 | |
| 9289 | DESCRIPTION |
| 9290 | |
| 9291 | For example, for this join plan |
| 9292 | |
| 9293 | ot1--ot2--sjm1------------ot3-... |
| 9294 | | |
| 9295 | | |
| 9296 | it1--it2--it3 |
| 9297 | |
| 9298 | call to first_depth_first_tab() will return ot1, and subsequent calls to |
| 9299 | next_depth_first_tab() will return: |
| 9300 | |
| 9301 | ot2 it1 it2 it3 sjm ot3 ... |
| 9302 | */ |
| 9303 | |
| 9304 | JOIN_TAB *next_depth_first_tab(JOIN* join, JOIN_TAB* tab) |
| 9305 | { |
| 9306 | /* If we're inside SJM nest and have reached its end, get out */ |
| 9307 | if (tab->last_leaf_in_bush) |
| 9308 | return tab->bush_root_tab; |
| 9309 | |
| 9310 | /* Move to next tab in the array we're traversing */ |
| 9311 | tab++; |
| 9312 | |
| 9313 | if (tab == join->join_tab +join->top_join_tab_count) |
| 9314 | return NULL; /* Outside SJM nest and reached EOF */ |
| 9315 | |
| 9316 | if (tab->bush_children) |
| 9317 | return tab->bush_children->start; |
| 9318 | |
| 9319 | return tab; |
| 9320 | } |
| 9321 | |
| 9322 | |
| 9323 | bool JOIN::check_two_phase_optimization(THD *thd) |
| 9324 | { |
| 9325 | if (check_for_splittable_materialized()) |
| 9326 | return true; |
| 9327 | return false; |
| 9328 | } |
| 9329 | |
| 9330 | |
| 9331 | bool JOIN::inject_cond_into_where(Item *injected_cond) |
| 9332 | { |
| 9333 | Item *where_item= injected_cond; |
| 9334 | List<Item> *and_args= NULL; |
| 9335 | if (conds && conds->type() == Item::COND_ITEM && |
| 9336 | ((Item_cond*) conds)->functype() == Item_func::COND_AND_FUNC) |
| 9337 | { |
| 9338 | and_args= ((Item_cond*) conds)->argument_list(); |
| 9339 | if (cond_equal) |
| 9340 | and_args->disjoin((List<Item> *) &cond_equal->current_level); |
| 9341 | } |
| 9342 | |
| 9343 | where_item= and_items(thd, conds, where_item); |
| 9344 | if (!where_item->fixed && where_item->fix_fields(thd, 0)) |
| 9345 | return true; |
| 9346 | thd->change_item_tree(&select_lex->where, where_item); |
| 9347 | select_lex->where->top_level_item(); |
| 9348 | conds= select_lex->where; |
| 9349 | |
| 9350 | if (and_args && cond_equal) |
| 9351 | { |
| 9352 | and_args= ((Item_cond*) conds)->argument_list(); |
| 9353 | List_iterator<Item_equal> li(cond_equal->current_level); |
| 9354 | Item_equal *elem; |
| 9355 | while ((elem= li++)) |
| 9356 | { |
| 9357 | and_args->push_back(elem, thd->mem_root); |
| 9358 | } |
| 9359 | } |
| 9360 | |
| 9361 | return false; |
| 9362 | |
| 9363 | } |
| 9364 | |
| 9365 | |
| 9366 | static Item * const null_ptr= NULL; |
| 9367 | |
| 9368 | /* |
| 9369 | Set up join struct according to the picked join order in |
| 9370 | |
| 9371 | SYNOPSIS |
| 9372 | get_best_combination() |
| 9373 | join The join to process (the picked join order is mainly in |
| 9374 | join->best_positions) |
| 9375 | |
| 9376 | DESCRIPTION |
| 9377 | Setup join structures according the picked join order |
| 9378 | - finalize semi-join strategy choices (see |
| 9379 | fix_semijoin_strategies_for_picked_join_order) |
| 9380 | - create join->join_tab array and put there the JOIN_TABs in the join order |
| 9381 | - create data structures describing ref access methods. |
| 9382 | |
| 9383 | NOTE |
| 9384 | In this function we switch from pre-join-optimization JOIN_TABs to |
| 9385 | post-join-optimization JOIN_TABs. This is achieved by copying the entire |
| 9386 | JOIN_TAB objects. |
| 9387 | |
| 9388 | RETURN |
| 9389 | FALSE OK |
| 9390 | TRUE Out of memory |
| 9391 | */ |
| 9392 | |
| 9393 | bool JOIN::get_best_combination() |
| 9394 | { |
| 9395 | uint tablenr; |
| 9396 | table_map used_tables; |
| 9397 | JOIN_TAB *j; |
| 9398 | KEYUSE *keyuse; |
| 9399 | DBUG_ENTER("get_best_combination" ); |
| 9400 | |
| 9401 | /* |
| 9402 | Additional plan nodes for postjoin tmp tables: |
| 9403 | 1? + // For GROUP BY |
| 9404 | 1? + // For DISTINCT |
| 9405 | 1? + // For aggregation functions aggregated in outer query |
| 9406 | // when used with distinct |
| 9407 | 1? + // For ORDER BY |
| 9408 | 1? // buffer result |
| 9409 | Up to 2 tmp tables are actually used, but it's hard to tell exact number |
| 9410 | at this stage. |
| 9411 | */ |
| 9412 | uint aggr_tables= (group_list ? 1 : 0) + |
| 9413 | (select_distinct ? |
| 9414 | (tmp_table_param.using_outer_summary_function ? 2 : 1) : 0) + |
| 9415 | (order ? 1 : 0) + |
| 9416 | (select_options & (SELECT_BIG_RESULT | OPTION_BUFFER_RESULT) ? 1 : 0) ; |
| 9417 | |
| 9418 | if (aggr_tables == 0) |
| 9419 | aggr_tables= 1; /* For group by pushdown */ |
| 9420 | |
| 9421 | if (select_lex->window_specs.elements) |
| 9422 | aggr_tables++; |
| 9423 | |
| 9424 | if (aggr_tables > 2) |
| 9425 | aggr_tables= 2; |
| 9426 | if (!(join_tab= (JOIN_TAB*) thd->alloc(sizeof(JOIN_TAB)* |
| 9427 | (top_join_tab_count + aggr_tables)))) |
| 9428 | DBUG_RETURN(TRUE); |
| 9429 | |
| 9430 | full_join=0; |
| 9431 | hash_join= FALSE; |
| 9432 | |
| 9433 | fix_semijoin_strategies_for_picked_join_order(this); |
| 9434 | |
| 9435 | JOIN_TAB_RANGE *root_range; |
| 9436 | if (!(root_range= new (thd->mem_root) JOIN_TAB_RANGE)) |
| 9437 | DBUG_RETURN(TRUE); |
| 9438 | root_range->start= join_tab; |
| 9439 | /* root_range->end will be set later */ |
| 9440 | join_tab_ranges.empty(); |
| 9441 | |
| 9442 | if (join_tab_ranges.push_back(root_range, thd->mem_root)) |
| 9443 | DBUG_RETURN(TRUE); |
| 9444 | |
| 9445 | JOIN_TAB *sjm_nest_end= NULL; |
| 9446 | JOIN_TAB *sjm_nest_root= NULL; |
| 9447 | |
| 9448 | for (j=join_tab, tablenr=0 ; tablenr < table_count ; tablenr++,j++) |
| 9449 | { |
| 9450 | TABLE *form; |
| 9451 | POSITION *cur_pos= &best_positions[tablenr]; |
| 9452 | if (cur_pos->sj_strategy == SJ_OPT_MATERIALIZE || |
| 9453 | cur_pos->sj_strategy == SJ_OPT_MATERIALIZE_SCAN) |
| 9454 | { |
| 9455 | /* |
| 9456 | Ok, we've entered an SJ-Materialization semi-join (note that this can't |
| 9457 | be done recursively, semi-joins are not allowed to be nested). |
| 9458 | 1. Put into main join order a JOIN_TAB that represents a lookup or scan |
| 9459 | in the temptable. |
| 9460 | */ |
| 9461 | bzero(j, sizeof(JOIN_TAB)); |
| 9462 | j->join= this; |
| 9463 | j->table= NULL; //temporary way to tell SJM tables from others. |
| 9464 | j->ref.key = -1; |
| 9465 | j->on_expr_ref= (Item**) &null_ptr; |
| 9466 | j->keys= key_map(1); /* The unique index is always in 'possible keys' in EXPLAIN */ |
| 9467 | |
| 9468 | /* |
| 9469 | 2. Proceed with processing SJM nest's join tabs, putting them into the |
| 9470 | sub-order |
| 9471 | */ |
| 9472 | SJ_MATERIALIZATION_INFO *sjm= cur_pos->table->emb_sj_nest->sj_mat_info; |
| 9473 | j->records_read= (sjm->is_sj_scan? sjm->rows : 1); |
| 9474 | j->records= (ha_rows) j->records_read; |
| 9475 | j->cond_selectivity= 1.0; |
| 9476 | JOIN_TAB *jt; |
| 9477 | JOIN_TAB_RANGE *jt_range; |
| 9478 | if (!(jt= (JOIN_TAB*) thd->alloc(sizeof(JOIN_TAB)*sjm->tables)) || |
| 9479 | !(jt_range= new JOIN_TAB_RANGE)) |
| 9480 | DBUG_RETURN(TRUE); |
| 9481 | jt_range->start= jt; |
| 9482 | jt_range->end= jt + sjm->tables; |
| 9483 | join_tab_ranges.push_back(jt_range, thd->mem_root); |
| 9484 | j->bush_children= jt_range; |
| 9485 | sjm_nest_end= jt + sjm->tables; |
| 9486 | sjm_nest_root= j; |
| 9487 | |
| 9488 | j= jt; |
| 9489 | } |
| 9490 | |
| 9491 | *j= *best_positions[tablenr].table; |
| 9492 | |
| 9493 | j->bush_root_tab= sjm_nest_root; |
| 9494 | |
| 9495 | form= table[tablenr]= j->table; |
| 9496 | form->reginfo.join_tab=j; |
| 9497 | DBUG_PRINT("info" ,("type: %d" , j->type)); |
| 9498 | if (j->type == JT_CONST) |
| 9499 | goto loop_end; // Handled in make_join_stat.. |
| 9500 | |
| 9501 | j->loosescan_match_tab= NULL; //non-nulls will be set later |
| 9502 | j->inside_loosescan_range= FALSE; |
| 9503 | j->ref.key = -1; |
| 9504 | j->ref.key_parts=0; |
| 9505 | |
| 9506 | if (j->type == JT_SYSTEM) |
| 9507 | goto loop_end; |
| 9508 | if ( !(keyuse= best_positions[tablenr].key)) |
| 9509 | { |
| 9510 | j->type=JT_ALL; |
| 9511 | if (best_positions[tablenr].use_join_buffer && |
| 9512 | tablenr != const_tables) |
| 9513 | full_join= 1; |
| 9514 | } |
| 9515 | |
| 9516 | /*if (best_positions[tablenr].sj_strategy == SJ_OPT_LOOSE_SCAN) |
| 9517 | { |
| 9518 | DBUG_ASSERT(!keyuse || keyuse->key == |
| 9519 | best_positions[tablenr].loosescan_picker.loosescan_key); |
| 9520 | j->index= best_positions[tablenr].loosescan_picker.loosescan_key; |
| 9521 | }*/ |
| 9522 | |
| 9523 | if ((j->type == JT_REF || j->type == JT_EQ_REF) && |
| 9524 | is_hash_join_key_no(j->ref.key)) |
| 9525 | hash_join= TRUE; |
| 9526 | |
| 9527 | loop_end: |
| 9528 | /* |
| 9529 | Save records_read in JOIN_TAB so that select_describe()/etc don't have |
| 9530 | to access join->best_positions[]. |
| 9531 | */ |
| 9532 | j->records_read= best_positions[tablenr].records_read; |
| 9533 | j->cond_selectivity= best_positions[tablenr].cond_selectivity; |
| 9534 | map2table[j->table->tablenr]= j; |
| 9535 | |
| 9536 | /* If we've reached the end of sjm nest, switch back to main sequence */ |
| 9537 | if (j + 1 == sjm_nest_end) |
| 9538 | { |
| 9539 | j->last_leaf_in_bush= TRUE; |
| 9540 | j= sjm_nest_root; |
| 9541 | sjm_nest_root= NULL; |
| 9542 | sjm_nest_end= NULL; |
| 9543 | } |
| 9544 | } |
| 9545 | root_range->end= j; |
| 9546 | |
| 9547 | used_tables= OUTER_REF_TABLE_BIT; // Outer row is already read |
| 9548 | for (j=join_tab, tablenr=0 ; tablenr < table_count ; tablenr++,j++) |
| 9549 | { |
| 9550 | if (j->bush_children) |
| 9551 | j= j->bush_children->start; |
| 9552 | |
| 9553 | used_tables|= j->table->map; |
| 9554 | if (j->type != JT_CONST && j->type != JT_SYSTEM) |
| 9555 | { |
| 9556 | if ((keyuse= best_positions[tablenr].key) && |
| 9557 | create_ref_for_key(this, j, keyuse, TRUE, used_tables)) |
| 9558 | DBUG_RETURN(TRUE); // Something went wrong |
| 9559 | } |
| 9560 | if (j->last_leaf_in_bush) |
| 9561 | j= j->bush_root_tab; |
| 9562 | } |
| 9563 | |
| 9564 | top_join_tab_count= (uint)(join_tab_ranges.head()->end - |
| 9565 | join_tab_ranges.head()->start); |
| 9566 | |
| 9567 | update_depend_map(this); |
| 9568 | DBUG_RETURN(0); |
| 9569 | } |
| 9570 | |
| 9571 | /** |
| 9572 | Create a descriptor of hash join key to access a given join table |
| 9573 | |
| 9574 | @param join join which the join table belongs to |
| 9575 | @param join_tab the join table to access |
| 9576 | @param org_keyuse beginning of the key uses to join this table |
| 9577 | @param used_tables bitmap of the previous tables |
| 9578 | |
| 9579 | @details |
| 9580 | This function first finds key uses that can be utilized by the hash join |
| 9581 | algorithm to join join_tab to the previous tables marked in the bitmap |
| 9582 | used_tables. The tested key uses are taken from the array of all key uses |
| 9583 | for 'join' starting from the position org_keyuse. After all interesting key |
| 9584 | uses have been found the function builds a descriptor of the corresponding |
| 9585 | key that is used by the hash join algorithm would it be chosen to join |
| 9586 | the table join_tab. |
| 9587 | |
| 9588 | @retval FALSE the descriptor for a hash join key is successfully created |
| 9589 | @retval TRUE otherwise |
| 9590 | */ |
| 9591 | |
| 9592 | static bool create_hj_key_for_table(JOIN *join, JOIN_TAB *join_tab, |
| 9593 | KEYUSE *org_keyuse, table_map used_tables) |
| 9594 | { |
| 9595 | KEY *keyinfo; |
| 9596 | KEY_PART_INFO *key_part_info; |
| 9597 | KEYUSE *keyuse= org_keyuse; |
| 9598 | uint key_parts= 0; |
| 9599 | THD *thd= join->thd; |
| 9600 | TABLE *table= join_tab->table; |
| 9601 | bool first_keyuse= TRUE; |
| 9602 | DBUG_ENTER("create_hj_key_for_table" ); |
| 9603 | |
| 9604 | do |
| 9605 | { |
| 9606 | if (!(~used_tables & keyuse->used_tables) && |
| 9607 | join_tab->keyuse_is_valid_for_access_in_chosen_plan(join, keyuse) && |
| 9608 | are_tables_local(join_tab, keyuse->used_tables)) |
| 9609 | { |
| 9610 | if (first_keyuse) |
| 9611 | { |
| 9612 | key_parts++; |
| 9613 | first_keyuse= FALSE; |
| 9614 | } |
| 9615 | else |
| 9616 | { |
| 9617 | KEYUSE *curr= org_keyuse; |
| 9618 | for( ; curr < keyuse; curr++) |
| 9619 | { |
| 9620 | if (curr->keypart == keyuse->keypart && |
| 9621 | !(~used_tables & curr->used_tables) && |
| 9622 | join_tab->keyuse_is_valid_for_access_in_chosen_plan(join, |
| 9623 | keyuse) && |
| 9624 | are_tables_local(join_tab, curr->used_tables)) |
| 9625 | break; |
| 9626 | } |
| 9627 | if (curr == keyuse) |
| 9628 | key_parts++; |
| 9629 | } |
| 9630 | } |
| 9631 | keyuse++; |
| 9632 | } while (keyuse->table == table && keyuse->is_for_hash_join()); |
| 9633 | if (!key_parts) |
| 9634 | DBUG_RETURN(TRUE); |
| 9635 | /* This memory is allocated only once for the joined table join_tab */ |
| 9636 | if (!(keyinfo= (KEY *) thd->alloc(sizeof(KEY))) || |
| 9637 | !(key_part_info = (KEY_PART_INFO *) thd->alloc(sizeof(KEY_PART_INFO)* |
| 9638 | key_parts))) |
| 9639 | DBUG_RETURN(TRUE); |
| 9640 | keyinfo->usable_key_parts= keyinfo->user_defined_key_parts = key_parts; |
| 9641 | keyinfo->ext_key_parts= keyinfo->user_defined_key_parts; |
| 9642 | keyinfo->key_part= key_part_info; |
| 9643 | keyinfo->key_length=0; |
| 9644 | keyinfo->algorithm= HA_KEY_ALG_UNDEF; |
| 9645 | keyinfo->flags= HA_GENERATED_KEY; |
| 9646 | keyinfo->is_statistics_from_stat_tables= FALSE; |
| 9647 | keyinfo->name.str= "$hj" ; |
| 9648 | keyinfo->name.length= 3; |
| 9649 | keyinfo->rec_per_key= (ulong*) thd->calloc(sizeof(ulong)*key_parts); |
| 9650 | if (!keyinfo->rec_per_key) |
| 9651 | DBUG_RETURN(TRUE); |
| 9652 | keyinfo->key_part= key_part_info; |
| 9653 | |
| 9654 | first_keyuse= TRUE; |
| 9655 | keyuse= org_keyuse; |
| 9656 | do |
| 9657 | { |
| 9658 | if (!(~used_tables & keyuse->used_tables) && |
| 9659 | join_tab->keyuse_is_valid_for_access_in_chosen_plan(join, keyuse) && |
| 9660 | are_tables_local(join_tab, keyuse->used_tables)) |
| 9661 | { |
| 9662 | bool add_key_part= TRUE; |
| 9663 | if (!first_keyuse) |
| 9664 | { |
| 9665 | for(KEYUSE *curr= org_keyuse; curr < keyuse; curr++) |
| 9666 | { |
| 9667 | if (curr->keypart == keyuse->keypart && |
| 9668 | !(~used_tables & curr->used_tables) && |
| 9669 | join_tab->keyuse_is_valid_for_access_in_chosen_plan(join, |
| 9670 | curr) && |
| 9671 | are_tables_local(join_tab, curr->used_tables)) |
| 9672 | { |
| 9673 | keyuse->keypart= NO_KEYPART; |
| 9674 | add_key_part= FALSE; |
| 9675 | break; |
| 9676 | } |
| 9677 | } |
| 9678 | } |
| 9679 | if (add_key_part) |
| 9680 | { |
| 9681 | Field *field= table->field[keyuse->keypart]; |
| 9682 | uint fieldnr= keyuse->keypart+1; |
| 9683 | table->create_key_part_by_field(key_part_info, field, fieldnr); |
| 9684 | keyinfo->key_length += key_part_info->store_length; |
| 9685 | key_part_info++; |
| 9686 | } |
| 9687 | } |
| 9688 | first_keyuse= FALSE; |
| 9689 | keyuse++; |
| 9690 | } while (keyuse->table == table && keyuse->is_for_hash_join()); |
| 9691 | |
| 9692 | keyinfo->ext_key_parts= keyinfo->user_defined_key_parts; |
| 9693 | keyinfo->ext_key_flags= keyinfo->flags; |
| 9694 | keyinfo->ext_key_part_map= 0; |
| 9695 | |
| 9696 | join_tab->hj_key= keyinfo; |
| 9697 | |
| 9698 | DBUG_RETURN(FALSE); |
| 9699 | } |
| 9700 | |
| 9701 | /* |
| 9702 | Check if a set of tables specified by used_tables can be accessed when |
| 9703 | we're doing scan on join_tab jtab. |
| 9704 | */ |
| 9705 | static bool are_tables_local(JOIN_TAB *jtab, table_map used_tables) |
| 9706 | { |
| 9707 | if (jtab->bush_root_tab) |
| 9708 | { |
| 9709 | /* |
| 9710 | jtab is inside execution join nest. We may not refer to outside tables, |
| 9711 | except the const tables. |
| 9712 | */ |
| 9713 | table_map local_tables= jtab->emb_sj_nest->nested_join->used_tables | |
| 9714 | jtab->join->const_table_map | |
| 9715 | OUTER_REF_TABLE_BIT; |
| 9716 | return !MY_TEST(used_tables & ~local_tables); |
| 9717 | } |
| 9718 | |
| 9719 | /* |
| 9720 | If we got here then jtab is at top level. |
| 9721 | - all other tables at top level are accessible, |
| 9722 | - tables in join nests are accessible too, because all their columns that |
| 9723 | are needed at top level will be unpacked when scanning the |
| 9724 | materialization table. |
| 9725 | */ |
| 9726 | return TRUE; |
| 9727 | } |
| 9728 | |
| 9729 | static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, |
| 9730 | KEYUSE *org_keyuse, bool allow_full_scan, |
| 9731 | table_map used_tables) |
| 9732 | { |
| 9733 | uint keyparts, length, key; |
| 9734 | TABLE *table; |
| 9735 | KEY *keyinfo; |
| 9736 | KEYUSE *keyuse= org_keyuse; |
| 9737 | bool ftkey= (keyuse->keypart == FT_KEYPART); |
| 9738 | THD *thd= join->thd; |
| 9739 | DBUG_ENTER("create_ref_for_key" ); |
| 9740 | |
| 9741 | /* Use best key from find_best */ |
| 9742 | table= j->table; |
| 9743 | key= keyuse->key; |
| 9744 | if (!is_hash_join_key_no(key)) |
| 9745 | keyinfo= table->key_info+key; |
| 9746 | else |
| 9747 | { |
| 9748 | if (create_hj_key_for_table(join, j, org_keyuse, used_tables)) |
| 9749 | DBUG_RETURN(TRUE); |
| 9750 | keyinfo= j->hj_key; |
| 9751 | } |
| 9752 | |
| 9753 | if (ftkey) |
| 9754 | { |
| 9755 | Item_func_match *ifm=(Item_func_match *)keyuse->val; |
| 9756 | |
| 9757 | length=0; |
| 9758 | keyparts=1; |
| 9759 | ifm->join_key=1; |
| 9760 | } |
| 9761 | else |
| 9762 | { |
| 9763 | keyparts=length=0; |
| 9764 | uint found_part_ref_or_null= 0; |
| 9765 | /* |
| 9766 | Calculate length for the used key |
| 9767 | Stop if there is a missing key part or when we find second key_part |
| 9768 | with KEY_OPTIMIZE_REF_OR_NULL |
| 9769 | */ |
| 9770 | do |
| 9771 | { |
| 9772 | if (!(~used_tables & keyuse->used_tables) && |
| 9773 | (!keyuse->validity_ref || *keyuse->validity_ref) && |
| 9774 | j->keyuse_is_valid_for_access_in_chosen_plan(join, keyuse)) |
| 9775 | { |
| 9776 | if (are_tables_local(j, keyuse->val->used_tables())) |
| 9777 | { |
| 9778 | if ((is_hash_join_key_no(key) && keyuse->keypart != NO_KEYPART) || |
| 9779 | (!is_hash_join_key_no(key) && keyparts == keyuse->keypart && |
| 9780 | !(found_part_ref_or_null & keyuse->optimize))) |
| 9781 | { |
| 9782 | length+= keyinfo->key_part[keyparts].store_length; |
| 9783 | keyparts++; |
| 9784 | found_part_ref_or_null|= keyuse->optimize & ~KEY_OPTIMIZE_EQ; |
| 9785 | } |
| 9786 | } |
| 9787 | } |
| 9788 | keyuse++; |
| 9789 | } while (keyuse->table == table && keyuse->key == key); |
| 9790 | |
| 9791 | if (!keyparts && allow_full_scan) |
| 9792 | { |
| 9793 | /* It's a LooseIndexScan strategy scanning whole index */ |
| 9794 | j->type= JT_ALL; |
| 9795 | j->index= key; |
| 9796 | DBUG_RETURN(FALSE); |
| 9797 | } |
| 9798 | |
| 9799 | DBUG_ASSERT(length > 0); |
| 9800 | DBUG_ASSERT(keyparts != 0); |
| 9801 | } /* not ftkey */ |
| 9802 | |
| 9803 | /* set up fieldref */ |
| 9804 | j->ref.key_parts= keyparts; |
| 9805 | j->ref.key_length= length; |
| 9806 | j->ref.key= (int) key; |
| 9807 | if (!(j->ref.key_buff= (uchar*) thd->calloc(ALIGN_SIZE(length)*2)) || |
| 9808 | !(j->ref.key_copy= (store_key**) thd->alloc((sizeof(store_key*) * |
| 9809 | (keyparts+1)))) || |
| 9810 | !(j->ref.items=(Item**) thd->alloc(sizeof(Item*)*keyparts)) || |
| 9811 | !(j->ref.cond_guards= (bool**) thd->alloc(sizeof(uint*)*keyparts))) |
| 9812 | { |
| 9813 | DBUG_RETURN(TRUE); |
| 9814 | } |
| 9815 | j->ref.key_buff2=j->ref.key_buff+ALIGN_SIZE(length); |
| 9816 | j->ref.key_err=1; |
| 9817 | j->ref.has_record= FALSE; |
| 9818 | j->ref.null_rejecting= 0; |
| 9819 | j->ref.disable_cache= FALSE; |
| 9820 | j->ref.null_ref_part= NO_REF_PART; |
| 9821 | j->ref.const_ref_part_map= 0; |
| 9822 | keyuse=org_keyuse; |
| 9823 | |
| 9824 | store_key **ref_key= j->ref.key_copy; |
| 9825 | uchar *key_buff=j->ref.key_buff, *null_ref_key= 0; |
| 9826 | uint null_ref_part= NO_REF_PART; |
| 9827 | bool keyuse_uses_no_tables= TRUE; |
| 9828 | if (ftkey) |
| 9829 | { |
| 9830 | j->ref.items[0]=((Item_func*)(keyuse->val))->key_item(); |
| 9831 | /* Predicates pushed down into subquery can't be used FT access */ |
| 9832 | j->ref.cond_guards[0]= NULL; |
| 9833 | if (keyuse->used_tables) |
| 9834 | DBUG_RETURN(TRUE); // not supported yet. SerG |
| 9835 | |
| 9836 | j->type=JT_FT; |
| 9837 | } |
| 9838 | else |
| 9839 | { |
| 9840 | uint i; |
| 9841 | for (i=0 ; i < keyparts ; keyuse++,i++) |
| 9842 | { |
| 9843 | while (((~used_tables) & keyuse->used_tables) || |
| 9844 | (keyuse->validity_ref && !(*keyuse->validity_ref)) || |
| 9845 | !j->keyuse_is_valid_for_access_in_chosen_plan(join, keyuse) || |
| 9846 | keyuse->keypart == NO_KEYPART || |
| 9847 | (keyuse->keypart != |
| 9848 | (is_hash_join_key_no(key) ? |
| 9849 | keyinfo->key_part[i].field->field_index : i)) || |
| 9850 | !are_tables_local(j, keyuse->val->used_tables())) |
| 9851 | keyuse++; /* Skip other parts */ |
| 9852 | |
| 9853 | uint maybe_null= MY_TEST(keyinfo->key_part[i].null_bit); |
| 9854 | j->ref.items[i]=keyuse->val; // Save for cond removal |
| 9855 | j->ref.cond_guards[i]= keyuse->cond_guard; |
| 9856 | if (keyuse->null_rejecting) |
| 9857 | j->ref.null_rejecting|= (key_part_map)1 << i; |
| 9858 | keyuse_uses_no_tables= keyuse_uses_no_tables && !keyuse->used_tables; |
| 9859 | /* |
| 9860 | Todo: we should remove this check for thd->lex->describe on the next |
| 9861 | line. With SHOW EXPLAIN code, EXPLAIN printout code no longer depends |
| 9862 | on it. However, removing the check caused change in lots of query |
| 9863 | plans! Does the optimizer depend on the contents of |
| 9864 | table_ref->key_copy ? If yes, do we produce incorrect EXPLAINs? |
| 9865 | */ |
| 9866 | if (!keyuse->val->used_tables() && !thd->lex->describe) |
| 9867 | { // Compare against constant |
| 9868 | store_key_item tmp(thd, |
| 9869 | keyinfo->key_part[i].field, |
| 9870 | key_buff + maybe_null, |
| 9871 | maybe_null ? key_buff : 0, |
| 9872 | keyinfo->key_part[i].length, |
| 9873 | keyuse->val, |
| 9874 | FALSE); |
| 9875 | if (unlikely(thd->is_fatal_error)) |
| 9876 | DBUG_RETURN(TRUE); |
| 9877 | tmp.copy(); |
| 9878 | j->ref.const_ref_part_map |= key_part_map(1) << i ; |
| 9879 | } |
| 9880 | else |
| 9881 | *ref_key++= get_store_key(thd, |
| 9882 | keyuse,join->const_table_map, |
| 9883 | &keyinfo->key_part[i], |
| 9884 | key_buff, maybe_null); |
| 9885 | /* |
| 9886 | Remember if we are going to use REF_OR_NULL |
| 9887 | But only if field _really_ can be null i.e. we force JT_REF |
| 9888 | instead of JT_REF_OR_NULL in case if field can't be null |
| 9889 | */ |
| 9890 | if ((keyuse->optimize & KEY_OPTIMIZE_REF_OR_NULL) && maybe_null) |
| 9891 | { |
| 9892 | null_ref_key= key_buff; |
| 9893 | null_ref_part= i; |
| 9894 | } |
| 9895 | key_buff+= keyinfo->key_part[i].store_length; |
| 9896 | } |
| 9897 | } /* not ftkey */ |
| 9898 | *ref_key=0; // end_marker |
| 9899 | if (j->type == JT_FT) |
| 9900 | DBUG_RETURN(0); |
| 9901 | ulong key_flags= j->table->actual_key_flags(keyinfo); |
| 9902 | if (j->type == JT_CONST) |
| 9903 | j->table->const_table= 1; |
| 9904 | else if (!((keyparts == keyinfo->user_defined_key_parts && |
| 9905 | ((key_flags & (HA_NOSAME | HA_NULL_PART_KEY)) == HA_NOSAME)) || |
| 9906 | (keyparts > keyinfo->user_defined_key_parts && // true only for extended keys |
| 9907 | MY_TEST(key_flags & HA_EXT_NOSAME) && |
| 9908 | keyparts == keyinfo->ext_key_parts)) || |
| 9909 | null_ref_key) |
| 9910 | { |
| 9911 | /* Must read with repeat */ |
| 9912 | j->type= null_ref_key ? JT_REF_OR_NULL : JT_REF; |
| 9913 | j->ref.null_ref_key= null_ref_key; |
| 9914 | j->ref.null_ref_part= null_ref_part; |
| 9915 | } |
| 9916 | else if (keyuse_uses_no_tables) |
| 9917 | { |
| 9918 | /* |
| 9919 | This happen if we are using a constant expression in the ON part |
| 9920 | of an LEFT JOIN. |
| 9921 | SELECT * FROM a LEFT JOIN b ON b.key=30 |
| 9922 | Here we should not mark the table as a 'const' as a field may |
| 9923 | have a 'normal' value or a NULL value. |
| 9924 | */ |
| 9925 | j->type=JT_CONST; |
| 9926 | } |
| 9927 | else |
| 9928 | j->type=JT_EQ_REF; |
| 9929 | |
| 9930 | j->read_record.unlock_row= (j->type == JT_EQ_REF)? |
| 9931 | join_read_key_unlock_row : rr_unlock_row; |
| 9932 | DBUG_RETURN(0); |
| 9933 | } |
| 9934 | |
| 9935 | |
| 9936 | |
| 9937 | static store_key * |
| 9938 | get_store_key(THD *thd, KEYUSE *keyuse, table_map used_tables, |
| 9939 | KEY_PART_INFO *key_part, uchar *key_buff, uint maybe_null) |
| 9940 | { |
| 9941 | if (!((~used_tables) & keyuse->used_tables)) // if const item |
| 9942 | { |
| 9943 | return new store_key_const_item(thd, |
| 9944 | key_part->field, |
| 9945 | key_buff + maybe_null, |
| 9946 | maybe_null ? key_buff : 0, |
| 9947 | key_part->length, |
| 9948 | keyuse->val); |
| 9949 | } |
| 9950 | else if (keyuse->val->type() == Item::FIELD_ITEM || |
| 9951 | (keyuse->val->type() == Item::REF_ITEM && |
| 9952 | ((((Item_ref*)keyuse->val)->ref_type() == Item_ref::OUTER_REF && |
| 9953 | (*(Item_ref**)((Item_ref*)keyuse->val)->ref)->ref_type() == |
| 9954 | Item_ref::DIRECT_REF) || |
| 9955 | ((Item_ref*)keyuse->val)->ref_type() == Item_ref::VIEW_REF) && |
| 9956 | keyuse->val->real_item()->type() == Item::FIELD_ITEM)) |
| 9957 | return new store_key_field(thd, |
| 9958 | key_part->field, |
| 9959 | key_buff + maybe_null, |
| 9960 | maybe_null ? key_buff : 0, |
| 9961 | key_part->length, |
| 9962 | ((Item_field*) keyuse->val->real_item())->field, |
| 9963 | keyuse->val->real_item()->full_name()); |
| 9964 | |
| 9965 | return new store_key_item(thd, |
| 9966 | key_part->field, |
| 9967 | key_buff + maybe_null, |
| 9968 | maybe_null ? key_buff : 0, |
| 9969 | key_part->length, |
| 9970 | keyuse->val, FALSE); |
| 9971 | } |
| 9972 | |
| 9973 | |
| 9974 | inline void add_cond_and_fix(THD *thd, Item **e1, Item *e2) |
| 9975 | { |
| 9976 | if (*e1) |
| 9977 | { |
| 9978 | if (!e2) |
| 9979 | return; |
| 9980 | Item *res; |
| 9981 | if ((res= new (thd->mem_root) Item_cond_and(thd, *e1, e2))) |
| 9982 | { |
| 9983 | res->fix_fields(thd, 0); |
| 9984 | res->update_used_tables(); |
| 9985 | *e1= res; |
| 9986 | } |
| 9987 | } |
| 9988 | else |
| 9989 | *e1= e2; |
| 9990 | } |
| 9991 | |
| 9992 | |
| 9993 | /** |
| 9994 | Add to join_tab->select_cond[i] "table.field IS NOT NULL" conditions |
| 9995 | we've inferred from ref/eq_ref access performed. |
| 9996 | |
| 9997 | This function is a part of "Early NULL-values filtering for ref access" |
| 9998 | optimization. |
| 9999 | |
| 10000 | Example of this optimization: |
| 10001 | For query SELECT * FROM t1,t2 WHERE t2.key=t1.field @n |
| 10002 | and plan " any-access(t1), ref(t2.key=t1.field) " @n |
| 10003 | add "t1.field IS NOT NULL" to t1's table condition. @n |
| 10004 | |
| 10005 | Description of the optimization: |
| 10006 | |
| 10007 | We look through equalities choosen to perform ref/eq_ref access, |
| 10008 | pick equalities that have form "tbl.part_of_key = othertbl.field" |
| 10009 | (where othertbl is a non-const table and othertbl.field may be NULL) |
| 10010 | and add them to conditions on correspoding tables (othertbl in this |
| 10011 | example). |
| 10012 | |
| 10013 | Exception from that is the case when referred_tab->join != join. |
| 10014 | I.e. don't add NOT NULL constraints from any embedded subquery. |
| 10015 | Consider this query: |
| 10016 | @code |
| 10017 | SELECT A.f2 FROM t1 LEFT JOIN t2 A ON A.f2 = f1 |
| 10018 | WHERE A.f3=(SELECT MIN(f3) FROM t2 C WHERE A.f4 = C.f4) OR A.f3 IS NULL; |
| 10019 | @endocde |
| 10020 | Here condition A.f3 IS NOT NULL is going to be added to the WHERE |
| 10021 | condition of the embedding query. |
| 10022 | Another example: |
| 10023 | SELECT * FROM t10, t11 WHERE (t10.a < 10 OR t10.a IS NULL) |
| 10024 | AND t11.b <=> t10.b AND (t11.a = (SELECT MAX(a) FROM t12 |
| 10025 | WHERE t12.b = t10.a )); |
| 10026 | Here condition t10.a IS NOT NULL is going to be added. |
| 10027 | In both cases addition of NOT NULL condition will erroneously reject |
| 10028 | some rows of the result set. |
| 10029 | referred_tab->join != join constraint would disallow such additions. |
| 10030 | |
| 10031 | This optimization doesn't affect the choices that ref, range, or join |
| 10032 | optimizer make. This was intentional because this was added after 4.1 |
| 10033 | was GA. |
| 10034 | |
| 10035 | Implementation overview |
| 10036 | 1. update_ref_and_keys() accumulates info about null-rejecting |
| 10037 | predicates in in KEY_FIELD::null_rejecting |
| 10038 | 1.1 add_key_part saves these to KEYUSE. |
| 10039 | 2. create_ref_for_key copies them to TABLE_REF. |
| 10040 | 3. add_not_null_conds adds "x IS NOT NULL" to join_tab->select_cond of |
| 10041 | appropiate JOIN_TAB members. |
| 10042 | */ |
| 10043 | |
| 10044 | static void add_not_null_conds(JOIN *join) |
| 10045 | { |
| 10046 | JOIN_TAB *tab; |
| 10047 | DBUG_ENTER("add_not_null_conds" ); |
| 10048 | |
| 10049 | for (tab= first_linear_tab(join, WITH_BUSH_ROOTS, WITHOUT_CONST_TABLES); |
| 10050 | tab; |
| 10051 | tab= next_linear_tab(join, tab, WITH_BUSH_ROOTS)) |
| 10052 | { |
| 10053 | if (tab->type == JT_REF || tab->type == JT_EQ_REF || |
| 10054 | tab->type == JT_REF_OR_NULL) |
| 10055 | { |
| 10056 | for (uint keypart= 0; keypart < tab->ref.key_parts; keypart++) |
| 10057 | { |
| 10058 | if (tab->ref.null_rejecting & ((key_part_map)1 << keypart)) |
| 10059 | { |
| 10060 | Item *item= tab->ref.items[keypart]; |
| 10061 | Item *notnull; |
| 10062 | Item *real= item->real_item(); |
| 10063 | if (real->const_item() && real->type() != Item::FIELD_ITEM && |
| 10064 | !real->is_expensive()) |
| 10065 | { |
| 10066 | /* |
| 10067 | It could be constant instead of field after constant |
| 10068 | propagation. |
| 10069 | */ |
| 10070 | continue; |
| 10071 | } |
| 10072 | DBUG_ASSERT(real->type() == Item::FIELD_ITEM); |
| 10073 | Item_field *not_null_item= (Item_field*)real; |
| 10074 | JOIN_TAB *referred_tab= not_null_item->field->table->reginfo.join_tab; |
| 10075 | /* |
| 10076 | For UPDATE queries such as: |
| 10077 | UPDATE t1 SET t1.f2=(SELECT MAX(t2.f4) FROM t2 WHERE t2.f3=t1.f1); |
| 10078 | not_null_item is the t1.f1, but it's referred_tab is 0. |
| 10079 | */ |
| 10080 | if (!(notnull= new (join->thd->mem_root) |
| 10081 | Item_func_isnotnull(join->thd, item))) |
| 10082 | DBUG_VOID_RETURN; |
| 10083 | /* |
| 10084 | We need to do full fix_fields() call here in order to have correct |
| 10085 | notnull->const_item(). This is needed e.g. by test_quick_select |
| 10086 | when it is called from make_join_select after this function is |
| 10087 | called. |
| 10088 | */ |
| 10089 | if (notnull->fix_fields(join->thd, ¬null)) |
| 10090 | DBUG_VOID_RETURN; |
| 10091 | |
| 10092 | DBUG_EXECUTE("where" ,print_where(notnull, |
| 10093 | (referred_tab ? |
| 10094 | referred_tab->table->alias.c_ptr() : |
| 10095 | "outer_ref_cond" ), |
| 10096 | QT_ORDINARY);); |
| 10097 | if (!tab->first_inner) |
| 10098 | { |
| 10099 | COND *new_cond= (referred_tab && referred_tab->join == join) ? |
| 10100 | referred_tab->select_cond : |
| 10101 | join->outer_ref_cond; |
| 10102 | add_cond_and_fix(join->thd, &new_cond, notnull); |
| 10103 | if (referred_tab && referred_tab->join == join) |
| 10104 | referred_tab->set_select_cond(new_cond, __LINE__); |
| 10105 | else |
| 10106 | join->outer_ref_cond= new_cond; |
| 10107 | } |
| 10108 | else |
| 10109 | add_cond_and_fix(join->thd, tab->first_inner->on_expr_ref, notnull); |
| 10110 | } |
| 10111 | } |
| 10112 | } |
| 10113 | } |
| 10114 | DBUG_VOID_RETURN; |
| 10115 | } |
| 10116 | |
| 10117 | /** |
| 10118 | Build a predicate guarded by match variables for embedding outer joins. |
| 10119 | The function recursively adds guards for predicate cond |
| 10120 | assending from tab to the first inner table next embedding |
| 10121 | nested outer join and so on until it reaches root_tab |
| 10122 | (root_tab can be 0). |
| 10123 | |
| 10124 | In other words: |
| 10125 | add_found_match_trig_cond(tab->first_inner_tab, y, 0) is the way one should |
| 10126 | wrap parts of WHERE. The idea is that the part of WHERE should be only |
| 10127 | evaluated after we've finished figuring out whether outer joins. |
| 10128 | ^^^ is the above correct? |
| 10129 | |
| 10130 | @param tab the first inner table for most nested outer join |
| 10131 | @param cond the predicate to be guarded (must be set) |
| 10132 | @param root_tab the first inner table to stop |
| 10133 | |
| 10134 | @return |
| 10135 | - pointer to the guarded predicate, if success |
| 10136 | - 0, otherwise |
| 10137 | */ |
| 10138 | |
| 10139 | static COND* |
| 10140 | add_found_match_trig_cond(THD *thd, JOIN_TAB *tab, COND *cond, |
| 10141 | JOIN_TAB *root_tab) |
| 10142 | { |
| 10143 | COND *tmp; |
| 10144 | DBUG_ASSERT(cond != 0); |
| 10145 | if (tab == root_tab) |
| 10146 | return cond; |
| 10147 | if ((tmp= add_found_match_trig_cond(thd, tab->first_upper, cond, root_tab))) |
| 10148 | tmp= new (thd->mem_root) Item_func_trig_cond(thd, tmp, &tab->found); |
| 10149 | if (tmp) |
| 10150 | { |
| 10151 | tmp->quick_fix_field(); |
| 10152 | tmp->update_used_tables(); |
| 10153 | } |
| 10154 | return tmp; |
| 10155 | } |
| 10156 | |
| 10157 | |
| 10158 | bool TABLE_LIST::is_active_sjm() |
| 10159 | { |
| 10160 | return sj_mat_info && sj_mat_info->is_used; |
| 10161 | } |
| 10162 | |
| 10163 | |
| 10164 | /** |
| 10165 | Fill in outer join related info for the execution plan structure. |
| 10166 | |
| 10167 | For each outer join operation left after simplification of the |
| 10168 | original query the function set up the following pointers in the linear |
| 10169 | structure join->join_tab representing the selected execution plan. |
| 10170 | The first inner table t0 for the operation is set to refer to the last |
| 10171 | inner table tk through the field t0->last_inner. |
| 10172 | Any inner table ti for the operation are set to refer to the first |
| 10173 | inner table ti->first_inner. |
| 10174 | The first inner table t0 for the operation is set to refer to the |
| 10175 | first inner table of the embedding outer join operation, if there is any, |
| 10176 | through the field t0->first_upper. |
| 10177 | The on expression for the outer join operation is attached to the |
| 10178 | corresponding first inner table through the field t0->on_expr_ref. |
| 10179 | Here ti are structures of the JOIN_TAB type. |
| 10180 | |
| 10181 | In other words, for each join tab, set |
| 10182 | - first_inner |
| 10183 | - last_inner |
| 10184 | - first_upper |
| 10185 | - on_expr_ref, cond_equal |
| 10186 | |
| 10187 | EXAMPLE. For the query: |
| 10188 | @code |
| 10189 | SELECT * FROM t1 |
| 10190 | LEFT JOIN |
| 10191 | (t2, t3 LEFT JOIN t4 ON t3.a=t4.a) |
| 10192 | ON (t1.a=t2.a AND t1.b=t3.b) |
| 10193 | WHERE t1.c > 5, |
| 10194 | @endcode |
| 10195 | |
| 10196 | given the execution plan with the table order t1,t2,t3,t4 |
| 10197 | is selected, the following references will be set; |
| 10198 | t4->last_inner=[t4], t4->first_inner=[t4], t4->first_upper=[t2] |
| 10199 | t2->last_inner=[t4], t2->first_inner=t3->first_inner=[t2], |
| 10200 | on expression (t1.a=t2.a AND t1.b=t3.b) will be attached to |
| 10201 | *t2->on_expr_ref, while t3.a=t4.a will be attached to *t4->on_expr_ref. |
| 10202 | |
| 10203 | @param join reference to the info fully describing the query |
| 10204 | |
| 10205 | @note |
| 10206 | The function assumes that the simplification procedure has been |
| 10207 | already applied to the join query (see simplify_joins). |
| 10208 | This function can be called only after the execution plan |
| 10209 | has been chosen. |
| 10210 | */ |
| 10211 | |
| 10212 | static bool |
| 10213 | make_outerjoin_info(JOIN *join) |
| 10214 | { |
| 10215 | DBUG_ENTER("make_outerjoin_info" ); |
| 10216 | |
| 10217 | /* |
| 10218 | Create temp. tables for merged SJ-Materialization nests. We need to do |
| 10219 | this now, because further code relies on tab->table and |
| 10220 | tab->table->pos_in_table_list being set. |
| 10221 | */ |
| 10222 | JOIN_TAB *tab; |
| 10223 | for (tab= first_linear_tab(join, WITH_BUSH_ROOTS, WITHOUT_CONST_TABLES); |
| 10224 | tab; |
| 10225 | tab= next_linear_tab(join, tab, WITH_BUSH_ROOTS)) |
| 10226 | { |
| 10227 | if (tab->bush_children) |
| 10228 | { |
| 10229 | if (setup_sj_materialization_part1(tab)) |
| 10230 | DBUG_RETURN(TRUE); |
| 10231 | tab->table->reginfo.join_tab= tab; |
| 10232 | } |
| 10233 | } |
| 10234 | |
| 10235 | for (tab= first_linear_tab(join, WITH_BUSH_ROOTS, WITHOUT_CONST_TABLES); |
| 10236 | tab; |
| 10237 | tab= next_linear_tab(join, tab, WITH_BUSH_ROOTS)) |
| 10238 | { |
| 10239 | TABLE *table= tab->table; |
| 10240 | TABLE_LIST *tbl= table->pos_in_table_list; |
| 10241 | TABLE_LIST *embedding= tbl->embedding; |
| 10242 | |
| 10243 | if (tbl->outer_join & (JOIN_TYPE_LEFT | JOIN_TYPE_RIGHT)) |
| 10244 | { |
| 10245 | /* |
| 10246 | Table tab is the only one inner table for outer join. |
| 10247 | (Like table t4 for the table reference t3 LEFT JOIN t4 ON t3.a=t4.a |
| 10248 | is in the query above.) |
| 10249 | */ |
| 10250 | tab->last_inner= tab->first_inner= tab; |
| 10251 | tab->on_expr_ref= &tbl->on_expr; |
| 10252 | tab->cond_equal= tbl->cond_equal; |
| 10253 | if (embedding && !embedding->is_active_sjm()) |
| 10254 | tab->first_upper= embedding->nested_join->first_nested; |
| 10255 | } |
| 10256 | else if (!embedding) |
| 10257 | tab->table->reginfo.not_exists_optimize= 0; |
| 10258 | |
| 10259 | for ( ; embedding ; embedding= embedding->embedding) |
| 10260 | { |
| 10261 | if (embedding->is_active_sjm()) |
| 10262 | { |
| 10263 | /* We're trying to walk out of an SJ-Materialization nest. Don't do this. */ |
| 10264 | break; |
| 10265 | } |
| 10266 | /* Ignore sj-nests: */ |
| 10267 | if (!(embedding->on_expr && embedding->outer_join)) |
| 10268 | { |
| 10269 | tab->table->reginfo.not_exists_optimize= 0; |
| 10270 | continue; |
| 10271 | } |
| 10272 | NESTED_JOIN *nested_join= embedding->nested_join; |
| 10273 | if (!nested_join->counter) |
| 10274 | { |
| 10275 | /* |
| 10276 | Table tab is the first inner table for nested_join. |
| 10277 | Save reference to it in the nested join structure. |
| 10278 | */ |
| 10279 | nested_join->first_nested= tab; |
| 10280 | tab->on_expr_ref= &embedding->on_expr; |
| 10281 | tab->cond_equal= tbl->cond_equal; |
| 10282 | if (embedding->embedding) |
| 10283 | tab->first_upper= embedding->embedding->nested_join->first_nested; |
| 10284 | } |
| 10285 | if (!tab->first_inner) |
| 10286 | tab->first_inner= nested_join->first_nested; |
| 10287 | if (++nested_join->counter < nested_join->n_tables) |
| 10288 | break; |
| 10289 | /* Table tab is the last inner table for nested join. */ |
| 10290 | nested_join->first_nested->last_inner= tab; |
| 10291 | } |
| 10292 | } |
| 10293 | DBUG_RETURN(FALSE); |
| 10294 | } |
| 10295 | |
| 10296 | |
| 10297 | static bool |
| 10298 | make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) |
| 10299 | { |
| 10300 | THD *thd= join->thd; |
| 10301 | DBUG_ENTER("make_join_select" ); |
| 10302 | if (select) |
| 10303 | { |
| 10304 | add_not_null_conds(join); |
| 10305 | table_map used_tables; |
| 10306 | /* |
| 10307 | Step #1: Extract constant condition |
| 10308 | - Extract and check the constant part of the WHERE |
| 10309 | - Extract constant parts of ON expressions from outer |
| 10310 | joins and attach them appropriately. |
| 10311 | */ |
| 10312 | if (cond) /* Because of QUICK_GROUP_MIN_MAX_SELECT */ |
| 10313 | { /* there may be a select without a cond. */ |
| 10314 | if (join->table_count > 1) |
| 10315 | cond->update_used_tables(); // Tablenr may have changed |
| 10316 | |
| 10317 | /* |
| 10318 | Extract expressions that depend on constant tables |
| 10319 | 1. Const part of the join's WHERE clause can be checked immediately |
| 10320 | and if it is not satisfied then the join has empty result |
| 10321 | 2. Constant parts of outer joins' ON expressions must be attached |
| 10322 | there inside the triggers. |
| 10323 | */ |
| 10324 | { // Check const tables |
| 10325 | join->exec_const_cond= |
| 10326 | make_cond_for_table(thd, cond, |
| 10327 | join->const_table_map, |
| 10328 | (table_map) 0, -1, FALSE, FALSE); |
| 10329 | /* Add conditions added by add_not_null_conds(). */ |
| 10330 | for (uint i= 0 ; i < join->const_tables ; i++) |
| 10331 | add_cond_and_fix(thd, &join->exec_const_cond, |
| 10332 | join->join_tab[i].select_cond); |
| 10333 | |
| 10334 | DBUG_EXECUTE("where" ,print_where(join->exec_const_cond,"constants" , |
| 10335 | QT_ORDINARY);); |
| 10336 | if (join->exec_const_cond && !join->exec_const_cond->is_expensive() && |
| 10337 | !join->exec_const_cond->val_int()) |
| 10338 | { |
| 10339 | DBUG_PRINT("info" ,("Found impossible WHERE condition" )); |
| 10340 | join->exec_const_cond= NULL; |
| 10341 | DBUG_RETURN(1); // Impossible const condition |
| 10342 | } |
| 10343 | |
| 10344 | if (join->table_count != join->const_tables) |
| 10345 | { |
| 10346 | COND *outer_ref_cond= make_cond_for_table(thd, cond, |
| 10347 | join->const_table_map | |
| 10348 | OUTER_REF_TABLE_BIT, |
| 10349 | OUTER_REF_TABLE_BIT, |
| 10350 | -1, FALSE, FALSE); |
| 10351 | if (outer_ref_cond) |
| 10352 | { |
| 10353 | add_cond_and_fix(thd, &outer_ref_cond, join->outer_ref_cond); |
| 10354 | join->outer_ref_cond= outer_ref_cond; |
| 10355 | } |
| 10356 | } |
| 10357 | else |
| 10358 | { |
| 10359 | COND *pseudo_bits_cond= |
| 10360 | make_cond_for_table(thd, cond, |
| 10361 | join->const_table_map | |
| 10362 | PSEUDO_TABLE_BITS, |
| 10363 | PSEUDO_TABLE_BITS, |
| 10364 | -1, FALSE, FALSE); |
| 10365 | if (pseudo_bits_cond) |
| 10366 | { |
| 10367 | add_cond_and_fix(thd, &pseudo_bits_cond, |
| 10368 | join->pseudo_bits_cond); |
| 10369 | join->pseudo_bits_cond= pseudo_bits_cond; |
| 10370 | } |
| 10371 | } |
| 10372 | } |
| 10373 | } |
| 10374 | |
| 10375 | /* |
| 10376 | Step #2: Extract WHERE/ON parts |
| 10377 | */ |
| 10378 | uint i; |
| 10379 | for (i= join->top_join_tab_count - 1; i >= join->const_tables; i--) |
| 10380 | { |
| 10381 | if (!join->join_tab[i].bush_children) |
| 10382 | break; |
| 10383 | } |
| 10384 | uint last_top_base_tab_idx= i; |
| 10385 | |
| 10386 | table_map save_used_tables= 0; |
| 10387 | used_tables=((select->const_tables=join->const_table_map) | |
| 10388 | OUTER_REF_TABLE_BIT | RAND_TABLE_BIT); |
| 10389 | JOIN_TAB *tab; |
| 10390 | table_map current_map; |
| 10391 | i= join->const_tables; |
| 10392 | for (tab= first_depth_first_tab(join); tab; |
| 10393 | tab= next_depth_first_tab(join, tab), i++) |
| 10394 | { |
| 10395 | bool is_hj; |
| 10396 | |
| 10397 | /* |
| 10398 | first_inner is the X in queries like: |
| 10399 | SELECT * FROM t1 LEFT OUTER JOIN (t2 JOIN t3) ON X |
| 10400 | */ |
| 10401 | JOIN_TAB *first_inner_tab= tab->first_inner; |
| 10402 | |
| 10403 | if (!tab->bush_children) |
| 10404 | current_map= tab->table->map; |
| 10405 | else |
| 10406 | current_map= tab->bush_children->start->emb_sj_nest->sj_inner_tables; |
| 10407 | |
| 10408 | bool use_quick_range=0; |
| 10409 | COND *tmp; |
| 10410 | |
| 10411 | /* |
| 10412 | Tables that are within SJ-Materialization nests cannot have their |
| 10413 | conditions referring to preceding non-const tables. |
| 10414 | - If we're looking at the first SJM table, reset used_tables |
| 10415 | to refer to only allowed tables |
| 10416 | */ |
| 10417 | if (tab->emb_sj_nest && tab->emb_sj_nest->sj_mat_info && |
| 10418 | tab->emb_sj_nest->sj_mat_info->is_used && |
| 10419 | !(used_tables & tab->emb_sj_nest->sj_inner_tables)) |
| 10420 | { |
| 10421 | save_used_tables= used_tables; |
| 10422 | used_tables= join->const_table_map | OUTER_REF_TABLE_BIT | |
| 10423 | RAND_TABLE_BIT; |
| 10424 | } |
| 10425 | |
| 10426 | /* |
| 10427 | Following force including random expression in last table condition. |
| 10428 | It solve problem with select like SELECT * FROM t1 WHERE rand() > 0.5 |
| 10429 | */ |
| 10430 | if (tab == join->join_tab + last_top_base_tab_idx) |
| 10431 | current_map|= RAND_TABLE_BIT; |
| 10432 | used_tables|=current_map; |
| 10433 | |
| 10434 | if (tab->type == JT_REF && tab->quick && |
| 10435 | (((uint) tab->ref.key == tab->quick->index && |
| 10436 | tab->ref.key_length < tab->quick->max_used_key_length) || |
| 10437 | (!is_hash_join_key_no(tab->ref.key) && |
| 10438 | tab->table->intersect_keys.is_set(tab->ref.key)))) |
| 10439 | { |
| 10440 | /* Range uses longer key; Use this instead of ref on key */ |
| 10441 | tab->type=JT_ALL; |
| 10442 | use_quick_range=1; |
| 10443 | tab->use_quick=1; |
| 10444 | tab->ref.key= -1; |
| 10445 | tab->ref.key_parts=0; // Don't use ref key. |
| 10446 | join->best_positions[i].records_read= rows2double(tab->quick->records); |
| 10447 | /* |
| 10448 | We will use join cache here : prevent sorting of the first |
| 10449 | table only and sort at the end. |
| 10450 | */ |
| 10451 | if (i != join->const_tables && |
| 10452 | join->table_count > join->const_tables + 1 && |
| 10453 | join->best_positions[i].use_join_buffer) |
| 10454 | join->full_join= 1; |
| 10455 | } |
| 10456 | |
| 10457 | tmp= NULL; |
| 10458 | |
| 10459 | if (cond) |
| 10460 | { |
| 10461 | if (tab->bush_children) |
| 10462 | { |
| 10463 | // Reached the materialization tab |
| 10464 | tmp= make_cond_after_sjm(thd, cond, cond, save_used_tables, |
| 10465 | used_tables, /*inside_or_clause=*/FALSE); |
| 10466 | used_tables= save_used_tables | used_tables; |
| 10467 | save_used_tables= 0; |
| 10468 | } |
| 10469 | else |
| 10470 | { |
| 10471 | tmp= make_cond_for_table(thd, cond, used_tables, current_map, i, |
| 10472 | FALSE, FALSE); |
| 10473 | } |
| 10474 | /* Add conditions added by add_not_null_conds(). */ |
| 10475 | if (tab->select_cond) |
| 10476 | add_cond_and_fix(thd, &tmp, tab->select_cond); |
| 10477 | } |
| 10478 | |
| 10479 | is_hj= (tab->type == JT_REF || tab->type == JT_EQ_REF) && |
| 10480 | (join->allowed_join_cache_types & JOIN_CACHE_HASHED_BIT) && |
| 10481 | ((join->max_allowed_join_cache_level+1)/2 == 2 || |
| 10482 | ((join->max_allowed_join_cache_level+1)/2 > 2 && |
| 10483 | is_hash_join_key_no(tab->ref.key))) && |
| 10484 | (!tab->emb_sj_nest || |
| 10485 | join->allowed_semijoin_with_cache) && |
| 10486 | (!(tab->table->map & join->outer_join) || |
| 10487 | join->allowed_outer_join_with_cache); |
| 10488 | |
| 10489 | if (cond && !tmp && tab->quick) |
| 10490 | { // Outer join |
| 10491 | if (tab->type != JT_ALL && !is_hj) |
| 10492 | { |
| 10493 | /* |
| 10494 | Don't use the quick method |
| 10495 | We come here in the case where we have 'key=constant' and |
| 10496 | the test is removed by make_cond_for_table() |
| 10497 | */ |
| 10498 | delete tab->quick; |
| 10499 | tab->quick= 0; |
| 10500 | } |
| 10501 | else |
| 10502 | { |
| 10503 | /* |
| 10504 | Hack to handle the case where we only refer to a table |
| 10505 | in the ON part of an OUTER JOIN. In this case we want the code |
| 10506 | below to check if we should use 'quick' instead. |
| 10507 | */ |
| 10508 | DBUG_PRINT("info" , ("Item_int" )); |
| 10509 | tmp= new (thd->mem_root) Item_int(thd, (longlong) 1, 1); // Always true |
| 10510 | } |
| 10511 | |
| 10512 | } |
| 10513 | if (tmp || !cond || tab->type == JT_REF || tab->type == JT_REF_OR_NULL || |
| 10514 | tab->type == JT_EQ_REF || first_inner_tab) |
| 10515 | { |
| 10516 | DBUG_EXECUTE("where" ,print_where(tmp, |
| 10517 | tab->table? tab->table->alias.c_ptr() :"sjm-nest" , |
| 10518 | QT_ORDINARY);); |
| 10519 | SQL_SELECT *sel= tab->select= ((SQL_SELECT*) |
| 10520 | thd->memdup((uchar*) select, |
| 10521 | sizeof(*select))); |
| 10522 | if (!sel) |
| 10523 | DBUG_RETURN(1); // End of memory |
| 10524 | /* |
| 10525 | If tab is an inner table of an outer join operation, |
| 10526 | add a match guard to the pushed down predicate. |
| 10527 | The guard will turn the predicate on only after |
| 10528 | the first match for outer tables is encountered. |
| 10529 | */ |
| 10530 | if (cond && tmp) |
| 10531 | { |
| 10532 | /* |
| 10533 | Because of QUICK_GROUP_MIN_MAX_SELECT there may be a select without |
| 10534 | a cond, so neutralize the hack above. |
| 10535 | */ |
| 10536 | COND *tmp_cond; |
| 10537 | if (!(tmp_cond= add_found_match_trig_cond(thd, first_inner_tab, tmp, |
| 10538 | 0))) |
| 10539 | DBUG_RETURN(1); |
| 10540 | sel->cond= tmp_cond; |
| 10541 | tab->set_select_cond(tmp_cond, __LINE__); |
| 10542 | /* Push condition to storage engine if this is enabled |
| 10543 | and the condition is not guarded */ |
| 10544 | if (tab->table) |
| 10545 | { |
| 10546 | tab->table->file->pushed_cond= NULL; |
| 10547 | if ((tab->table->file->ha_table_flags() & |
| 10548 | HA_CAN_TABLE_CONDITION_PUSHDOWN) && |
| 10549 | !first_inner_tab) |
| 10550 | { |
| 10551 | COND *push_cond= |
| 10552 | make_cond_for_table(thd, tmp_cond, current_map, current_map, |
| 10553 | -1, FALSE, FALSE); |
| 10554 | if (push_cond) |
| 10555 | { |
| 10556 | /* Push condition to handler */ |
| 10557 | if (!tab->table->file->cond_push(push_cond)) |
| 10558 | tab->table->file->pushed_cond= push_cond; |
| 10559 | } |
| 10560 | } |
| 10561 | } |
| 10562 | } |
| 10563 | else |
| 10564 | { |
| 10565 | sel->cond= NULL; |
| 10566 | tab->set_select_cond(NULL, __LINE__); |
| 10567 | } |
| 10568 | |
| 10569 | sel->head=tab->table; |
| 10570 | DBUG_EXECUTE("where" , |
| 10571 | print_where(tmp, |
| 10572 | tab->table ? tab->table->alias.c_ptr() : |
| 10573 | "(sjm-nest)" , |
| 10574 | QT_ORDINARY);); |
| 10575 | if (tab->quick) |
| 10576 | { |
| 10577 | /* Use quick key read if it's a constant and it's not used |
| 10578 | with key reading */ |
| 10579 | if ((tab->needed_reg.is_clear_all() && tab->type != JT_EQ_REF && |
| 10580 | tab->type != JT_FT && |
| 10581 | ((tab->type != JT_CONST && tab->type != JT_REF) || |
| 10582 | (uint) tab->ref.key == tab->quick->index)) || is_hj) |
| 10583 | { |
| 10584 | DBUG_ASSERT(tab->quick->is_valid()); |
| 10585 | sel->quick=tab->quick; // Use value from get_quick_... |
| 10586 | sel->quick_keys.clear_all(); |
| 10587 | sel->needed_reg.clear_all(); |
| 10588 | } |
| 10589 | else |
| 10590 | { |
| 10591 | delete tab->quick; |
| 10592 | } |
| 10593 | tab->quick=0; |
| 10594 | } |
| 10595 | uint ref_key= sel->head? (uint) sel->head->reginfo.join_tab->ref.key+1 : 0; |
| 10596 | if (i == join->const_tables && ref_key) |
| 10597 | { |
| 10598 | if (!tab->const_keys.is_clear_all() && |
| 10599 | tab->table->reginfo.impossible_range) |
| 10600 | DBUG_RETURN(1); |
| 10601 | } |
| 10602 | else if (tab->type == JT_ALL && ! use_quick_range) |
| 10603 | { |
| 10604 | if (!tab->const_keys.is_clear_all() && |
| 10605 | tab->table->reginfo.impossible_range) |
| 10606 | DBUG_RETURN(1); // Impossible range |
| 10607 | /* |
| 10608 | We plan to scan all rows. |
| 10609 | Check again if we should use an index. |
| 10610 | We could have used an column from a previous table in |
| 10611 | the index if we are using limit and this is the first table |
| 10612 | |
| 10613 | (1) - Don't switch the used index if we are using semi-join |
| 10614 | LooseScan on this table. Using different index will not |
| 10615 | produce the desired ordering and de-duplication. |
| 10616 | */ |
| 10617 | |
| 10618 | if (!tab->table->is_filled_at_execution() && |
| 10619 | !tab->loosescan_match_tab && // (1) |
| 10620 | ((cond && (!tab->keys.is_subset(tab->const_keys) && i > 0)) || |
| 10621 | (!tab->const_keys.is_clear_all() && i == join->const_tables && |
| 10622 | join->unit->select_limit_cnt < |
| 10623 | join->best_positions[i].records_read && |
| 10624 | !(join->select_options & OPTION_FOUND_ROWS)))) |
| 10625 | { |
| 10626 | /* Join with outer join condition */ |
| 10627 | COND *orig_cond=sel->cond; |
| 10628 | sel->cond= and_conds(thd, sel->cond, *tab->on_expr_ref); |
| 10629 | |
| 10630 | /* |
| 10631 | We can't call sel->cond->fix_fields, |
| 10632 | as it will break tab->on_expr if it's AND condition |
| 10633 | (fix_fields currently removes extra AND/OR levels). |
| 10634 | Yet attributes of the just built condition are not needed. |
| 10635 | Thus we call sel->cond->quick_fix_field for safety. |
| 10636 | */ |
| 10637 | if (sel->cond && !sel->cond->fixed) |
| 10638 | sel->cond->quick_fix_field(); |
| 10639 | |
| 10640 | if (sel->test_quick_select(thd, tab->keys, |
| 10641 | ((used_tables & ~ current_map) | |
| 10642 | OUTER_REF_TABLE_BIT), |
| 10643 | (join->select_options & |
| 10644 | OPTION_FOUND_ROWS ? |
| 10645 | HA_POS_ERROR : |
| 10646 | join->unit->select_limit_cnt), 0, |
| 10647 | FALSE, FALSE) < 0) |
| 10648 | { |
| 10649 | /* |
| 10650 | Before reporting "Impossible WHERE" for the whole query |
| 10651 | we have to check isn't it only "impossible ON" instead |
| 10652 | */ |
| 10653 | sel->cond=orig_cond; |
| 10654 | if (!*tab->on_expr_ref || |
| 10655 | sel->test_quick_select(thd, tab->keys, |
| 10656 | used_tables & ~ current_map, |
| 10657 | (join->select_options & |
| 10658 | OPTION_FOUND_ROWS ? |
| 10659 | HA_POS_ERROR : |
| 10660 | join->unit->select_limit_cnt),0, |
| 10661 | FALSE, FALSE) < 0) |
| 10662 | DBUG_RETURN(1); // Impossible WHERE |
| 10663 | } |
| 10664 | else |
| 10665 | sel->cond=orig_cond; |
| 10666 | |
| 10667 | /* Fix for EXPLAIN */ |
| 10668 | if (sel->quick) |
| 10669 | join->best_positions[i].records_read= (double)sel->quick->records; |
| 10670 | } |
| 10671 | else |
| 10672 | { |
| 10673 | sel->needed_reg=tab->needed_reg; |
| 10674 | } |
| 10675 | sel->quick_keys= tab->table->quick_keys; |
| 10676 | if (!sel->quick_keys.is_subset(tab->checked_keys) || |
| 10677 | !sel->needed_reg.is_subset(tab->checked_keys)) |
| 10678 | { |
| 10679 | /* |
| 10680 | "Range checked for each record" is a "last resort" access method |
| 10681 | that should only be used when the other option is a cross-product |
| 10682 | join. |
| 10683 | |
| 10684 | We use the following condition (it's approximate): |
| 10685 | 1. There are potential keys for (sel->needed_reg) |
| 10686 | 2. There were no possible ways to construct a quick select, or |
| 10687 | the quick select would be more expensive than the full table |
| 10688 | scan. |
| 10689 | */ |
| 10690 | tab->use_quick= (!sel->needed_reg.is_clear_all() && |
| 10691 | (sel->quick_keys.is_clear_all() || |
| 10692 | (sel->quick && |
| 10693 | sel->quick->read_time > |
| 10694 | tab->table->file->scan_time() + |
| 10695 | tab->table->file->stats.records/TIME_FOR_COMPARE |
| 10696 | ))) ? |
| 10697 | 2 : 1; |
| 10698 | sel->read_tables= used_tables & ~current_map; |
| 10699 | sel->quick_keys.clear_all(); |
| 10700 | } |
| 10701 | if (i != join->const_tables && tab->use_quick != 2 && |
| 10702 | !tab->first_inner) |
| 10703 | { /* Read with cache */ |
| 10704 | if (tab->make_scan_filter()) |
| 10705 | DBUG_RETURN(1); |
| 10706 | } |
| 10707 | } |
| 10708 | } |
| 10709 | |
| 10710 | /* |
| 10711 | Push down conditions from all ON expressions. |
| 10712 | Each of these conditions are guarded by a variable |
| 10713 | that turns if off just before null complemented row for |
| 10714 | outer joins is formed. Thus, the condition from an |
| 10715 | 'on expression' are guaranteed not to be checked for |
| 10716 | the null complemented row. |
| 10717 | */ |
| 10718 | |
| 10719 | /* |
| 10720 | First push down constant conditions from ON expressions. |
| 10721 | - Each pushed-down condition is wrapped into trigger which is |
| 10722 | enabled only for non-NULL-complemented record |
| 10723 | - The condition is attached to the first_inner_table. |
| 10724 | |
| 10725 | With regards to join nests: |
| 10726 | - if we start at top level, don't walk into nests |
| 10727 | - if we start inside a nest, stay within that nest. |
| 10728 | */ |
| 10729 | JOIN_TAB *start_from= tab->bush_root_tab? |
| 10730 | tab->bush_root_tab->bush_children->start : |
| 10731 | join->join_tab + join->const_tables; |
| 10732 | JOIN_TAB *end_with= tab->bush_root_tab? |
| 10733 | tab->bush_root_tab->bush_children->end : |
| 10734 | join->join_tab + join->top_join_tab_count; |
| 10735 | for (JOIN_TAB *join_tab= start_from; |
| 10736 | join_tab != end_with; |
| 10737 | join_tab++) |
| 10738 | { |
| 10739 | if (*join_tab->on_expr_ref) |
| 10740 | { |
| 10741 | JOIN_TAB *cond_tab= join_tab->first_inner; |
| 10742 | COND *tmp_cond= make_cond_for_table(thd, *join_tab->on_expr_ref, |
| 10743 | join->const_table_map, |
| 10744 | (table_map) 0, -1, FALSE, FALSE); |
| 10745 | if (!tmp_cond) |
| 10746 | continue; |
| 10747 | tmp_cond= new (thd->mem_root) Item_func_trig_cond(thd, tmp_cond, |
| 10748 | &cond_tab->not_null_compl); |
| 10749 | if (!tmp_cond) |
| 10750 | DBUG_RETURN(1); |
| 10751 | tmp_cond->quick_fix_field(); |
| 10752 | cond_tab->select_cond= !cond_tab->select_cond ? tmp_cond : |
| 10753 | new (thd->mem_root) Item_cond_and(thd, cond_tab->select_cond, |
| 10754 | tmp_cond); |
| 10755 | if (!cond_tab->select_cond) |
| 10756 | DBUG_RETURN(1); |
| 10757 | cond_tab->select_cond->quick_fix_field(); |
| 10758 | cond_tab->select_cond->update_used_tables(); |
| 10759 | if (cond_tab->select) |
| 10760 | cond_tab->select->cond= cond_tab->select_cond; |
| 10761 | } |
| 10762 | } |
| 10763 | |
| 10764 | |
| 10765 | /* Push down non-constant conditions from ON expressions */ |
| 10766 | JOIN_TAB *last_tab= tab; |
| 10767 | |
| 10768 | /* |
| 10769 | while we're inside of an outer join and last_tab is |
| 10770 | the last of its tables ... |
| 10771 | */ |
| 10772 | while (first_inner_tab && first_inner_tab->last_inner == last_tab) |
| 10773 | { |
| 10774 | /* |
| 10775 | Table tab is the last inner table of an outer join. |
| 10776 | An on expression is always attached to it. |
| 10777 | */ |
| 10778 | COND *on_expr= *first_inner_tab->on_expr_ref; |
| 10779 | |
| 10780 | table_map used_tables2= (join->const_table_map | |
| 10781 | OUTER_REF_TABLE_BIT | RAND_TABLE_BIT); |
| 10782 | |
| 10783 | start_from= tab->bush_root_tab? |
| 10784 | tab->bush_root_tab->bush_children->start : |
| 10785 | join->join_tab + join->const_tables; |
| 10786 | for (JOIN_TAB *inner_tab= start_from; |
| 10787 | inner_tab <= last_tab; |
| 10788 | inner_tab++) |
| 10789 | { |
| 10790 | DBUG_ASSERT(inner_tab->table); |
| 10791 | current_map= inner_tab->table->map; |
| 10792 | used_tables2|= current_map; |
| 10793 | /* |
| 10794 | psergey: have put the -1 below. It's bad, will need to fix it. |
| 10795 | */ |
| 10796 | COND *tmp_cond= make_cond_for_table(thd, on_expr, used_tables2, |
| 10797 | current_map, |
| 10798 | /*(inner_tab - first_tab)*/ -1, |
| 10799 | FALSE, FALSE); |
| 10800 | bool is_sjm_lookup_tab= FALSE; |
| 10801 | if (inner_tab->bush_children) |
| 10802 | { |
| 10803 | /* |
| 10804 | 'inner_tab' is an SJ-Materialization tab, i.e. we have a join |
| 10805 | order like this: |
| 10806 | |
| 10807 | ot1 sjm_tab LEFT JOIN ot2 ot3 |
| 10808 | ^ ^ |
| 10809 | 'tab'-+ +--- left join we're adding triggers for |
| 10810 | |
| 10811 | LEFT JOIN's ON expression may not have references to subquery |
| 10812 | columns. The subquery was in the WHERE clause, so IN-equality |
| 10813 | is in the WHERE clause, also. |
| 10814 | However, equality propagation code may have propagated the |
| 10815 | IN-equality into ON expression, and we may get things like |
| 10816 | |
| 10817 | subquery_inner_table=const |
| 10818 | |
| 10819 | in the ON expression. We must not check such conditions during |
| 10820 | SJM-lookup, because 1) subquery_inner_table has no valid current |
| 10821 | row (materialization temp.table has it instead), and 2) they |
| 10822 | would be true anyway. |
| 10823 | */ |
| 10824 | SJ_MATERIALIZATION_INFO *sjm= |
| 10825 | inner_tab->bush_children->start->emb_sj_nest->sj_mat_info; |
| 10826 | if (sjm->is_used && !sjm->is_sj_scan) |
| 10827 | is_sjm_lookup_tab= TRUE; |
| 10828 | } |
| 10829 | |
| 10830 | if (inner_tab == first_inner_tab && inner_tab->on_precond && |
| 10831 | !is_sjm_lookup_tab) |
| 10832 | add_cond_and_fix(thd, &tmp_cond, inner_tab->on_precond); |
| 10833 | if (tmp_cond && !is_sjm_lookup_tab) |
| 10834 | { |
| 10835 | JOIN_TAB *cond_tab= (inner_tab < first_inner_tab ? |
| 10836 | first_inner_tab : inner_tab); |
| 10837 | Item **sel_cond_ref= (inner_tab < first_inner_tab ? |
| 10838 | &first_inner_tab->on_precond : |
| 10839 | &inner_tab->select_cond); |
| 10840 | /* |
| 10841 | First add the guards for match variables of |
| 10842 | all embedding outer join operations. |
| 10843 | */ |
| 10844 | if (!(tmp_cond= add_found_match_trig_cond(thd, |
| 10845 | cond_tab->first_inner, |
| 10846 | tmp_cond, |
| 10847 | first_inner_tab))) |
| 10848 | DBUG_RETURN(1); |
| 10849 | /* |
| 10850 | Now add the guard turning the predicate off for |
| 10851 | the null complemented row. |
| 10852 | */ |
| 10853 | DBUG_PRINT("info" , ("Item_func_trig_cond" )); |
| 10854 | tmp_cond= new (thd->mem_root) Item_func_trig_cond(thd, tmp_cond, |
| 10855 | &first_inner_tab-> |
| 10856 | not_null_compl); |
| 10857 | DBUG_PRINT("info" , ("Item_func_trig_cond %p" , |
| 10858 | tmp_cond)); |
| 10859 | if (tmp_cond) |
| 10860 | tmp_cond->quick_fix_field(); |
| 10861 | /* Add the predicate to other pushed down predicates */ |
| 10862 | DBUG_PRINT("info" , ("Item_cond_and" )); |
| 10863 | *sel_cond_ref= !(*sel_cond_ref) ? |
| 10864 | tmp_cond : |
| 10865 | new (thd->mem_root) Item_cond_and(thd, *sel_cond_ref, tmp_cond); |
| 10866 | DBUG_PRINT("info" , ("Item_cond_and %p" , |
| 10867 | (*sel_cond_ref))); |
| 10868 | if (!(*sel_cond_ref)) |
| 10869 | DBUG_RETURN(1); |
| 10870 | (*sel_cond_ref)->quick_fix_field(); |
| 10871 | (*sel_cond_ref)->update_used_tables(); |
| 10872 | if (cond_tab->select) |
| 10873 | cond_tab->select->cond= cond_tab->select_cond; |
| 10874 | } |
| 10875 | } |
| 10876 | first_inner_tab= first_inner_tab->first_upper; |
| 10877 | } |
| 10878 | } |
| 10879 | } |
| 10880 | DBUG_RETURN(0); |
| 10881 | } |
| 10882 | |
| 10883 | |
| 10884 | static |
| 10885 | uint get_next_field_for_derived_key(uchar *arg) |
| 10886 | { |
| 10887 | KEYUSE *keyuse= *(KEYUSE **) arg; |
| 10888 | if (!keyuse) |
| 10889 | return (uint) (-1); |
| 10890 | TABLE *table= keyuse->table; |
| 10891 | uint key= keyuse->key; |
| 10892 | uint fldno= keyuse->keypart; |
| 10893 | uint keypart= keyuse->keypart_map == (key_part_map) 1 ? |
| 10894 | 0 : (keyuse-1)->keypart+1; |
| 10895 | for ( ; |
| 10896 | keyuse->table == table && keyuse->key == key && keyuse->keypart == fldno; |
| 10897 | keyuse++) |
| 10898 | keyuse->keypart= keypart; |
| 10899 | if (keyuse->key != key) |
| 10900 | keyuse= 0; |
| 10901 | *((KEYUSE **) arg)= keyuse; |
| 10902 | return fldno; |
| 10903 | } |
| 10904 | |
| 10905 | |
| 10906 | static |
| 10907 | uint get_next_field_for_derived_key_simple(uchar *arg) |
| 10908 | { |
| 10909 | KEYUSE *keyuse= *(KEYUSE **) arg; |
| 10910 | if (!keyuse) |
| 10911 | return (uint) (-1); |
| 10912 | TABLE *table= keyuse->table; |
| 10913 | uint key= keyuse->key; |
| 10914 | uint fldno= keyuse->keypart; |
| 10915 | for ( ; |
| 10916 | keyuse->table == table && keyuse->key == key && keyuse->keypart == fldno; |
| 10917 | keyuse++) |
| 10918 | ; |
| 10919 | if (keyuse->key != key) |
| 10920 | keyuse= 0; |
| 10921 | *((KEYUSE **) arg)= keyuse; |
| 10922 | return fldno; |
| 10923 | } |
| 10924 | |
| 10925 | static |
| 10926 | bool generate_derived_keys_for_table(KEYUSE *keyuse, uint count, uint keys) |
| 10927 | { |
| 10928 | TABLE *table= keyuse->table; |
| 10929 | if (table->alloc_keys(keys)) |
| 10930 | return TRUE; |
| 10931 | uint key_count= 0; |
| 10932 | KEYUSE *first_keyuse= keyuse; |
| 10933 | uint prev_part= keyuse->keypart; |
| 10934 | uint parts= 0; |
| 10935 | uint i= 0; |
| 10936 | |
| 10937 | for ( ; i < count && key_count < keys; ) |
| 10938 | { |
| 10939 | do |
| 10940 | { |
| 10941 | keyuse->key= table->s->keys; |
| 10942 | keyuse->keypart_map= (key_part_map) (1 << parts); |
| 10943 | keyuse++; |
| 10944 | i++; |
| 10945 | } |
| 10946 | while (i < count && keyuse->used_tables == first_keyuse->used_tables && |
| 10947 | keyuse->keypart == prev_part); |
| 10948 | parts++; |
| 10949 | if (i < count && keyuse->used_tables == first_keyuse->used_tables) |
| 10950 | { |
| 10951 | prev_part= keyuse->keypart; |
| 10952 | } |
| 10953 | else |
| 10954 | { |
| 10955 | KEYUSE *save_first_keyuse= first_keyuse; |
| 10956 | if (table->check_tmp_key(table->s->keys, parts, |
| 10957 | get_next_field_for_derived_key_simple, |
| 10958 | (uchar *) &first_keyuse)) |
| 10959 | |
| 10960 | { |
| 10961 | first_keyuse= save_first_keyuse; |
| 10962 | if (table->add_tmp_key(table->s->keys, parts, |
| 10963 | get_next_field_for_derived_key, |
| 10964 | (uchar *) &first_keyuse, |
| 10965 | FALSE)) |
| 10966 | return TRUE; |
| 10967 | table->reginfo.join_tab->keys.set_bit(table->s->keys); |
| 10968 | } |
| 10969 | else |
| 10970 | { |
| 10971 | /* Mark keyuses for this key to be excluded */ |
| 10972 | for (KEYUSE *curr=save_first_keyuse; curr < keyuse; curr++) |
| 10973 | { |
| 10974 | curr->key= MAX_KEY; |
| 10975 | } |
| 10976 | } |
| 10977 | first_keyuse= keyuse; |
| 10978 | key_count++; |
| 10979 | parts= 0; |
| 10980 | prev_part= keyuse->keypart; |
| 10981 | } |
| 10982 | } |
| 10983 | |
| 10984 | return FALSE; |
| 10985 | } |
| 10986 | |
| 10987 | |
| 10988 | static |
| 10989 | bool generate_derived_keys(DYNAMIC_ARRAY *keyuse_array) |
| 10990 | { |
| 10991 | KEYUSE *keyuse= dynamic_element(keyuse_array, 0, KEYUSE*); |
| 10992 | uint elements= keyuse_array->elements; |
| 10993 | TABLE *prev_table= 0; |
| 10994 | for (uint i= 0; i < elements; i++, keyuse++) |
| 10995 | { |
| 10996 | if (!keyuse->table) |
| 10997 | break; |
| 10998 | KEYUSE *first_table_keyuse= NULL; |
| 10999 | table_map last_used_tables= 0; |
| 11000 | uint count= 0; |
| 11001 | uint keys= 0; |
| 11002 | TABLE_LIST *derived= NULL; |
| 11003 | if (keyuse->table != prev_table) |
| 11004 | derived= keyuse->table->pos_in_table_list; |
| 11005 | while (derived && derived->is_materialized_derived()) |
| 11006 | { |
| 11007 | if (keyuse->table != prev_table) |
| 11008 | { |
| 11009 | prev_table= keyuse->table; |
| 11010 | while (keyuse->table == prev_table && keyuse->key != MAX_KEY) |
| 11011 | { |
| 11012 | keyuse++; |
| 11013 | i++; |
| 11014 | } |
| 11015 | if (keyuse->table != prev_table) |
| 11016 | { |
| 11017 | keyuse--; |
| 11018 | i--; |
| 11019 | derived= NULL; |
| 11020 | continue; |
| 11021 | } |
| 11022 | first_table_keyuse= keyuse; |
| 11023 | last_used_tables= keyuse->used_tables; |
| 11024 | count= 0; |
| 11025 | keys= 0; |
| 11026 | } |
| 11027 | else if (keyuse->used_tables != last_used_tables) |
| 11028 | { |
| 11029 | keys++; |
| 11030 | last_used_tables= keyuse->used_tables; |
| 11031 | } |
| 11032 | count++; |
| 11033 | keyuse++; |
| 11034 | i++; |
| 11035 | if (keyuse->table != prev_table) |
| 11036 | { |
| 11037 | if (generate_derived_keys_for_table(first_table_keyuse, count, ++keys)) |
| 11038 | return TRUE; |
| 11039 | keyuse--; |
| 11040 | i--; |
| 11041 | derived= NULL; |
| 11042 | } |
| 11043 | } |
| 11044 | } |
| 11045 | return FALSE; |
| 11046 | } |
| 11047 | |
| 11048 | |
| 11049 | /* |
| 11050 | @brief |
| 11051 | Drops unused keys for each materialized derived table/view |
| 11052 | |
| 11053 | @details |
| 11054 | For materialized derived tables only ref access can be used, it employs |
| 11055 | only one index, thus we don't need the rest. For each materialized derived |
| 11056 | table/view call TABLE::use_index to save one index chosen by the optimizer |
| 11057 | and free others. No key is chosen then all keys will be dropped. |
| 11058 | */ |
| 11059 | |
| 11060 | void JOIN::drop_unused_derived_keys() |
| 11061 | { |
| 11062 | JOIN_TAB *tab; |
| 11063 | for (tab= first_linear_tab(this, WITH_BUSH_ROOTS, WITHOUT_CONST_TABLES); |
| 11064 | tab; |
| 11065 | tab= next_linear_tab(this, tab, WITH_BUSH_ROOTS)) |
| 11066 | { |
| 11067 | |
| 11068 | TABLE *tmp_tbl= tab->table; |
| 11069 | if (!tmp_tbl) |
| 11070 | continue; |
| 11071 | if (!tmp_tbl->pos_in_table_list->is_materialized_derived()) |
| 11072 | continue; |
| 11073 | if (tmp_tbl->max_keys > 1 && !tab->is_ref_for_hash_join()) |
| 11074 | tmp_tbl->use_index(tab->ref.key); |
| 11075 | if (tmp_tbl->s->keys) |
| 11076 | { |
| 11077 | if (tab->ref.key >= 0 && tab->ref.key < MAX_KEY) |
| 11078 | tab->ref.key= 0; |
| 11079 | else |
| 11080 | tmp_tbl->s->keys= 0; |
| 11081 | } |
| 11082 | tab->keys= (key_map) (tmp_tbl->s->keys ? 1 : 0); |
| 11083 | } |
| 11084 | } |
| 11085 | |
| 11086 | |
| 11087 | /* |
| 11088 | Evaluate the bitmap of used tables for items from the select list |
| 11089 | */ |
| 11090 | |
| 11091 | inline void JOIN::eval_select_list_used_tables() |
| 11092 | { |
| 11093 | select_list_used_tables= 0; |
| 11094 | Item *item; |
| 11095 | List_iterator_fast<Item> it(fields_list); |
| 11096 | while ((item= it++)) |
| 11097 | { |
| 11098 | select_list_used_tables|= item->used_tables(); |
| 11099 | } |
| 11100 | Item_outer_ref *ref; |
| 11101 | List_iterator_fast<Item_outer_ref> ref_it(select_lex->inner_refs_list); |
| 11102 | while ((ref= ref_it++)) |
| 11103 | { |
| 11104 | item= ref->outer_ref; |
| 11105 | select_list_used_tables|= item->used_tables(); |
| 11106 | } |
| 11107 | } |
| 11108 | |
| 11109 | |
| 11110 | /* |
| 11111 | Determine {after which table we'll produce ordered set} |
| 11112 | |
| 11113 | SYNOPSIS |
| 11114 | make_join_orderinfo() |
| 11115 | join |
| 11116 | |
| 11117 | |
| 11118 | DESCRIPTION |
| 11119 | Determine if the set is already ordered for ORDER BY, so it can |
| 11120 | disable join cache because it will change the ordering of the results. |
| 11121 | Code handles sort table that is at any location (not only first after |
| 11122 | the const tables) despite the fact that it's currently prohibited. |
| 11123 | We must disable join cache if the first non-const table alone is |
| 11124 | ordered. If there is a temp table the ordering is done as a last |
| 11125 | operation and doesn't prevent join cache usage. |
| 11126 | |
| 11127 | RETURN |
| 11128 | Number of table after which the set will be ordered |
| 11129 | join->tables if we don't need an ordered set |
| 11130 | */ |
| 11131 | |
| 11132 | static uint make_join_orderinfo(JOIN *join) |
| 11133 | { |
| 11134 | /* |
| 11135 | This function needs to be fixed to take into account that we now have SJM |
| 11136 | nests. |
| 11137 | */ |
| 11138 | DBUG_ASSERT(0); |
| 11139 | |
| 11140 | JOIN_TAB *tab; |
| 11141 | if (join->need_tmp) |
| 11142 | return join->table_count; |
| 11143 | tab= join->get_sort_by_join_tab(); |
| 11144 | return tab ? (uint)(tab-join->join_tab) : join->table_count; |
| 11145 | } |
| 11146 | |
| 11147 | /* |
| 11148 | Deny usage of join buffer for the specified table |
| 11149 | |
| 11150 | SYNOPSIS |
| 11151 | set_join_cache_denial() |
| 11152 | tab join table for which join buffer usage is to be denied |
| 11153 | |
| 11154 | DESCRIPTION |
| 11155 | The function denies usage of join buffer when joining the table 'tab'. |
| 11156 | The table is marked as not employing any join buffer. If a join cache |
| 11157 | object has been already allocated for the table this object is destroyed. |
| 11158 | |
| 11159 | RETURN |
| 11160 | none |
| 11161 | */ |
| 11162 | |
| 11163 | static |
| 11164 | void set_join_cache_denial(JOIN_TAB *join_tab) |
| 11165 | { |
| 11166 | if (join_tab->cache) |
| 11167 | { |
| 11168 | /* |
| 11169 | If there is a previous cache linked to this cache through the |
| 11170 | next_cache pointer: remove the link. |
| 11171 | */ |
| 11172 | if (join_tab->cache->prev_cache) |
| 11173 | join_tab->cache->prev_cache->next_cache= 0; |
| 11174 | /* |
| 11175 | Same for the next_cache |
| 11176 | */ |
| 11177 | if (join_tab->cache->next_cache) |
| 11178 | join_tab->cache->next_cache->prev_cache= 0; |
| 11179 | |
| 11180 | join_tab->cache->free(); |
| 11181 | join_tab->cache= 0; |
| 11182 | } |
| 11183 | if (join_tab->use_join_cache) |
| 11184 | { |
| 11185 | join_tab->use_join_cache= FALSE; |
| 11186 | join_tab->used_join_cache_level= 0; |
| 11187 | /* |
| 11188 | It could be only sub_select(). It could not be sub_seject_sjm because we |
| 11189 | don't do join buffering for the first table in sjm nest. |
| 11190 | */ |
| 11191 | join_tab[-1].next_select= sub_select; |
| 11192 | if (join_tab->type == JT_REF && join_tab->is_ref_for_hash_join()) |
| 11193 | { |
| 11194 | join_tab->type= JT_ALL; |
| 11195 | join_tab->ref.key_parts= 0; |
| 11196 | } |
| 11197 | join_tab->join->return_tab= join_tab; |
| 11198 | } |
| 11199 | } |
| 11200 | |
| 11201 | |
| 11202 | /** |
| 11203 | The default implementation of unlock-row method of READ_RECORD, |
| 11204 | used in all access methods. |
| 11205 | */ |
| 11206 | |
| 11207 | void rr_unlock_row(st_join_table *tab) |
| 11208 | { |
| 11209 | READ_RECORD *info= &tab->read_record; |
| 11210 | info->table->file->unlock_row(); |
| 11211 | } |
| 11212 | |
| 11213 | |
| 11214 | /** |
| 11215 | Pick the appropriate access method functions |
| 11216 | |
| 11217 | Sets the functions for the selected table access method |
| 11218 | |
| 11219 | @param tab Table reference to put access method |
| 11220 | */ |
| 11221 | |
| 11222 | static void |
| 11223 | pick_table_access_method(JOIN_TAB *tab) |
| 11224 | { |
| 11225 | switch (tab->type) |
| 11226 | { |
| 11227 | case JT_REF: |
| 11228 | tab->read_first_record= join_read_always_key; |
| 11229 | tab->read_record.read_record_func= join_read_next_same; |
| 11230 | break; |
| 11231 | |
| 11232 | case JT_REF_OR_NULL: |
| 11233 | tab->read_first_record= join_read_always_key_or_null; |
| 11234 | tab->read_record.read_record_func= join_read_next_same_or_null; |
| 11235 | break; |
| 11236 | |
| 11237 | case JT_CONST: |
| 11238 | tab->read_first_record= join_read_const; |
| 11239 | tab->read_record.read_record_func= join_no_more_records; |
| 11240 | break; |
| 11241 | |
| 11242 | case JT_EQ_REF: |
| 11243 | tab->read_first_record= join_read_key; |
| 11244 | tab->read_record.read_record_func= join_no_more_records; |
| 11245 | break; |
| 11246 | |
| 11247 | case JT_FT: |
| 11248 | tab->read_first_record= join_ft_read_first; |
| 11249 | tab->read_record.read_record_func= join_ft_read_next; |
| 11250 | break; |
| 11251 | |
| 11252 | case JT_SYSTEM: |
| 11253 | tab->read_first_record= join_read_system; |
| 11254 | tab->read_record.read_record_func= join_no_more_records; |
| 11255 | break; |
| 11256 | |
| 11257 | /* keep gcc happy */ |
| 11258 | default: |
| 11259 | break; |
| 11260 | } |
| 11261 | } |
| 11262 | |
| 11263 | |
| 11264 | /* |
| 11265 | Revise usage of join buffer for the specified table and the whole nest |
| 11266 | |
| 11267 | SYNOPSIS |
| 11268 | revise_cache_usage() |
| 11269 | tab join table for which join buffer usage is to be revised |
| 11270 | |
| 11271 | DESCRIPTION |
| 11272 | The function revise the decision to use a join buffer for the table 'tab'. |
| 11273 | If this table happened to be among the inner tables of a nested outer join/ |
| 11274 | semi-join the functions denies usage of join buffers for all of them |
| 11275 | |
| 11276 | RETURN |
| 11277 | none |
| 11278 | */ |
| 11279 | |
| 11280 | static |
| 11281 | void revise_cache_usage(JOIN_TAB *join_tab) |
| 11282 | { |
| 11283 | JOIN_TAB *tab; |
| 11284 | JOIN_TAB *first_inner; |
| 11285 | |
| 11286 | if (join_tab->first_inner) |
| 11287 | { |
| 11288 | JOIN_TAB *end_tab= join_tab; |
| 11289 | for (first_inner= join_tab->first_inner; |
| 11290 | first_inner; |
| 11291 | first_inner= first_inner->first_upper) |
| 11292 | { |
| 11293 | for (tab= end_tab; tab >= first_inner; tab--) |
| 11294 | set_join_cache_denial(tab); |
| 11295 | end_tab= first_inner; |
| 11296 | } |
| 11297 | } |
| 11298 | else if (join_tab->first_sj_inner_tab) |
| 11299 | { |
| 11300 | first_inner= join_tab->first_sj_inner_tab; |
| 11301 | for (tab= join_tab; tab >= first_inner; tab--) |
| 11302 | { |
| 11303 | set_join_cache_denial(tab); |
| 11304 | } |
| 11305 | } |
| 11306 | else set_join_cache_denial(join_tab); |
| 11307 | } |
| 11308 | |
| 11309 | |
| 11310 | /* |
| 11311 | end_select-compatible function that writes the record into a sjm temptable |
| 11312 | |
| 11313 | SYNOPSIS |
| 11314 | end_sj_materialize() |
| 11315 | join The join |
| 11316 | join_tab Points to right after the last join_tab in materialization bush |
| 11317 | end_of_records FALSE <=> This call is made to pass another record |
| 11318 | combination |
| 11319 | TRUE <=> EOF (no action) |
| 11320 | |
| 11321 | DESCRIPTION |
| 11322 | This function is used by semi-join materialization to capture suquery's |
| 11323 | resultset and write it into the temptable (that is, materialize it). |
| 11324 | |
| 11325 | NOTE |
| 11326 | This function is used only for semi-join materialization. Non-semijoin |
| 11327 | materialization uses different mechanism. |
| 11328 | |
| 11329 | RETURN |
| 11330 | NESTED_LOOP_OK |
| 11331 | NESTED_LOOP_ERROR |
| 11332 | */ |
| 11333 | |
| 11334 | enum_nested_loop_state |
| 11335 | end_sj_materialize(JOIN *join, JOIN_TAB *join_tab, bool end_of_records) |
| 11336 | { |
| 11337 | int error; |
| 11338 | THD *thd= join->thd; |
| 11339 | SJ_MATERIALIZATION_INFO *sjm= join_tab[-1].emb_sj_nest->sj_mat_info; |
| 11340 | DBUG_ENTER("end_sj_materialize" ); |
| 11341 | if (!end_of_records) |
| 11342 | { |
| 11343 | TABLE *table= sjm->table; |
| 11344 | |
| 11345 | List_iterator<Item> it(sjm->sjm_table_cols); |
| 11346 | Item *item; |
| 11347 | while ((item= it++)) |
| 11348 | { |
| 11349 | if (item->is_null()) |
| 11350 | DBUG_RETURN(NESTED_LOOP_OK); |
| 11351 | } |
| 11352 | fill_record(thd, table, table->field, sjm->sjm_table_cols, TRUE, FALSE); |
| 11353 | if (unlikely(thd->is_error())) |
| 11354 | DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */ |
| 11355 | if (unlikely((error= table->file->ha_write_tmp_row(table->record[0])))) |
| 11356 | { |
| 11357 | /* create_myisam_from_heap will generate error if needed */ |
| 11358 | if (table->file->is_fatal_error(error, HA_CHECK_DUP) && |
| 11359 | create_internal_tmp_table_from_heap(thd, table, |
| 11360 | sjm->sjm_table_param.start_recinfo, |
| 11361 | &sjm->sjm_table_param.recinfo, error, 1, NULL)) |
| 11362 | DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */ |
| 11363 | } |
| 11364 | } |
| 11365 | DBUG_RETURN(NESTED_LOOP_OK); |
| 11366 | } |
| 11367 | |
| 11368 | |
| 11369 | /* |
| 11370 | Check whether a join buffer can be used to join the specified table |
| 11371 | |
| 11372 | SYNOPSIS |
| 11373 | check_join_cache_usage() |
| 11374 | tab joined table to check join buffer usage for |
| 11375 | options options of the join |
| 11376 | no_jbuf_after don't use join buffering after table with this number |
| 11377 | prev_tab previous join table |
| 11378 | |
| 11379 | DESCRIPTION |
| 11380 | The function finds out whether the table 'tab' can be joined using a join |
| 11381 | buffer. This check is performed after the best execution plan for 'join' |
| 11382 | has been chosen. If the function decides that a join buffer can be employed |
| 11383 | then it selects the most appropriate join cache object that contains this |
| 11384 | join buffer. |
| 11385 | The result of the check and the type of the the join buffer to be used |
| 11386 | depend on: |
| 11387 | - the access method to access rows of the joined table |
| 11388 | - whether the join table is an inner table of an outer join or semi-join |
| 11389 | - whether the optimizer switches |
| 11390 | outer_join_with_cache, semijoin_with_cache, join_cache_incremental, |
| 11391 | join_cache_hashed, join_cache_bka, |
| 11392 | are set on or off |
| 11393 | - the join cache level set for the query |
| 11394 | - the join 'options'. |
| 11395 | |
| 11396 | In any case join buffer is not used if the number of the joined table is |
| 11397 | greater than 'no_jbuf_after'. It's also never used if the value of |
| 11398 | join_cache_level is equal to 0. |
| 11399 | If the optimizer switch outer_join_with_cache is off no join buffer is |
| 11400 | used for outer join operations. |
| 11401 | If the optimizer switch semijoin_with_cache is off no join buffer is used |
| 11402 | for semi-join operations. |
| 11403 | If the optimizer switch join_cache_incremental is off no incremental join |
| 11404 | buffers are used. |
| 11405 | If the optimizer switch join_cache_hashed is off then the optimizer uses |
| 11406 | neither BNLH algorithm, nor BKAH algorithm to perform join operations. |
| 11407 | |
| 11408 | If the optimizer switch join_cache_bka is off then the optimizer uses |
| 11409 | neither BKA algorithm, nor BKAH algorithm to perform join operation. |
| 11410 | The valid settings for join_cache_level lay in the interval 0..8. |
| 11411 | If it set to 0 no join buffers are used to perform join operations. |
| 11412 | Currently we differentiate between join caches of 8 levels: |
| 11413 | 1 : non-incremental join cache used for BNL join algorithm |
| 11414 | 2 : incremental join cache used for BNL join algorithm |
| 11415 | 3 : non-incremental join cache used for BNLH join algorithm |
| 11416 | 4 : incremental join cache used for BNLH join algorithm |
| 11417 | 5 : non-incremental join cache used for BKA join algorithm |
| 11418 | 6 : incremental join cache used for BKA join algorithm |
| 11419 | 7 : non-incremental join cache used for BKAH join algorithm |
| 11420 | 8 : incremental join cache used for BKAH join algorithm |
| 11421 | If the value of join_cache_level is set to n then no join caches of |
| 11422 | levels higher than n can be employed. |
| 11423 | |
| 11424 | If the optimizer switches outer_join_with_cache, semijoin_with_cache, |
| 11425 | join_cache_incremental, join_cache_hashed, join_cache_bka are all on |
| 11426 | the following rules are applied. |
| 11427 | If join_cache_level==1|2 then join buffer is used for inner joins, outer |
| 11428 | joins and semi-joins with 'JT_ALL' access method. In this case a |
| 11429 | JOIN_CACHE_BNL object is employed. |
| 11430 | If join_cache_level==3|4 and then join buffer is used for a join operation |
| 11431 | (inner join, outer join, semi-join) with 'JT_REF'/'JT_EQREF' access method |
| 11432 | then a JOIN_CACHE_BNLH object is employed. |
| 11433 | If an index is used to access rows of the joined table and the value of |
| 11434 | join_cache_level==5|6 then a JOIN_CACHE_BKA object is employed. |
| 11435 | If an index is used to access rows of the joined table and the value of |
| 11436 | join_cache_level==7|8 then a JOIN_CACHE_BKAH object is employed. |
| 11437 | If the value of join_cache_level is odd then creation of a non-linked |
| 11438 | join cache is forced. |
| 11439 | |
| 11440 | Currently for any join operation a join cache of the level of the |
| 11441 | highest allowed and applicable level is used. |
| 11442 | For example, if join_cache_level is set to 6 and the optimizer switch |
| 11443 | join_cache_bka is off, while the optimizer switch join_cache_hashed is |
| 11444 | on then for any inner join operation with JT_REF/JT_EQREF access method |
| 11445 | to the joined table the BNLH join algorithm will be used, while for |
| 11446 | the table accessed by the JT_ALL methods the BNL algorithm will be used. |
| 11447 | |
| 11448 | If the function decides that a join buffer can be used to join the table |
| 11449 | 'tab' then it sets the value of tab->use_join_buffer to TRUE and assigns |
| 11450 | the selected join cache object to the field 'cache' of the previous |
| 11451 | join table. |
| 11452 | If the function creates a join cache object it tries to initialize it. The |
| 11453 | failure to do this results in an invocation of the function that destructs |
| 11454 | the created object. |
| 11455 | If the function decides that but some reasons no join buffer can be used |
| 11456 | for a table it calls the function revise_cache_usage that checks |
| 11457 | whether join cache should be denied for some previous tables. In this case |
| 11458 | a pointer to the first table for which join cache usage has been denied |
| 11459 | is passed in join->return_val (see the function set_join_cache_denial). |
| 11460 | |
| 11461 | The functions changes the value the fields tab->icp_other_tables_ok and |
| 11462 | tab->idx_cond_fact_out to FALSE if the chosen join cache algorithm |
| 11463 | requires it. |
| 11464 | |
| 11465 | NOTES |
| 11466 | An inner table of a nested outer join or a nested semi-join can be currently |
| 11467 | joined only when a linked cache object is employed. In these cases setting |
| 11468 | join_cache_incremental to 'off' results in denial of usage of any join |
| 11469 | buffer when joining the table. |
| 11470 | For a nested outer join/semi-join, currently, we either use join buffers for |
| 11471 | all inner tables or for none of them. |
| 11472 | Some engines (e.g. Falcon) currently allow to use only a join cache |
| 11473 | of the type JOIN_CACHE_BKAH when the joined table is accessed through |
| 11474 | an index. For these engines setting the value of join_cache_level to 5 or 6 |
| 11475 | results in that no join buffer is used to join the table. |
| 11476 | |
| 11477 | RETURN VALUE |
| 11478 | cache level if cache is used, otherwise returns 0 |
| 11479 | |
| 11480 | TODO |
| 11481 | Support BKA inside SJ-Materialization nests. When doing this, we'll need |
| 11482 | to only store sj-inner tables in the join buffer. |
| 11483 | #if 0 |
| 11484 | JOIN_TAB *first_tab= join->join_tab+join->const_tables; |
| 11485 | uint n_tables= i-join->const_tables; |
| 11486 | / * |
| 11487 | We normally put all preceding tables into the join buffer, except |
| 11488 | for the constant tables. |
| 11489 | If we're inside a semi-join materialization nest, e.g. |
| 11490 | |
| 11491 | outer_tbl1 outer_tbl2 ( inner_tbl1, inner_tbl2 ) ... |
| 11492 | ^-- we're here |
| 11493 | |
| 11494 | then we need to put into the join buffer only the tables from |
| 11495 | within the nest. |
| 11496 | * / |
| 11497 | if (i >= first_sjm_table && i < last_sjm_table) |
| 11498 | { |
| 11499 | n_tables= i - first_sjm_table; // will be >0 if we got here |
| 11500 | first_tab= join->join_tab + first_sjm_table; |
| 11501 | } |
| 11502 | #endif |
| 11503 | */ |
| 11504 | |
| 11505 | static |
| 11506 | uint check_join_cache_usage(JOIN_TAB *tab, |
| 11507 | ulonglong options, |
| 11508 | uint no_jbuf_after, |
| 11509 | uint table_index, |
| 11510 | JOIN_TAB *prev_tab) |
| 11511 | { |
| 11512 | Cost_estimate cost; |
| 11513 | uint flags= 0; |
| 11514 | ha_rows rows= 0; |
| 11515 | uint bufsz= 4096; |
| 11516 | JOIN_CACHE *prev_cache=0; |
| 11517 | JOIN *join= tab->join; |
| 11518 | MEM_ROOT *root= join->thd->mem_root; |
| 11519 | uint cache_level= tab->used_join_cache_level; |
| 11520 | bool force_unlinked_cache= |
| 11521 | !(join->allowed_join_cache_types & JOIN_CACHE_INCREMENTAL_BIT); |
| 11522 | bool no_hashed_cache= |
| 11523 | !(join->allowed_join_cache_types & JOIN_CACHE_HASHED_BIT); |
| 11524 | bool no_bka_cache= |
| 11525 | !(join->allowed_join_cache_types & JOIN_CACHE_BKA_BIT); |
| 11526 | |
| 11527 | join->return_tab= 0; |
| 11528 | |
| 11529 | /* |
| 11530 | Don't use join cache if @@join_cache_level==0 or this table is the first |
| 11531 | one join suborder (either at top level or inside a bush) |
| 11532 | */ |
| 11533 | if (cache_level == 0 || !prev_tab) |
| 11534 | return 0; |
| 11535 | |
| 11536 | if (force_unlinked_cache && (cache_level%2 == 0)) |
| 11537 | cache_level--; |
| 11538 | |
| 11539 | if (options & SELECT_NO_JOIN_CACHE) |
| 11540 | goto no_join_cache; |
| 11541 | |
| 11542 | if (tab->use_quick == 2) |
| 11543 | goto no_join_cache; |
| 11544 | |
| 11545 | if (tab->table->map & join->complex_firstmatch_tables) |
| 11546 | goto no_join_cache; |
| 11547 | |
| 11548 | /* |
| 11549 | Don't use join cache if we're inside a join tab range covered by LooseScan |
| 11550 | strategy (TODO: LooseScan is very similar to FirstMatch so theoretically it |
| 11551 | should be possible to use join buffering in the same way we're using it for |
| 11552 | multi-table firstmatch ranges). |
| 11553 | */ |
| 11554 | if (tab->inside_loosescan_range) |
| 11555 | goto no_join_cache; |
| 11556 | |
| 11557 | if (tab->is_inner_table_of_semijoin() && |
| 11558 | !join->allowed_semijoin_with_cache) |
| 11559 | goto no_join_cache; |
| 11560 | if (tab->is_inner_table_of_outer_join() && |
| 11561 | !join->allowed_outer_join_with_cache) |
| 11562 | goto no_join_cache; |
| 11563 | |
| 11564 | /* |
| 11565 | Non-linked join buffers can't guarantee one match |
| 11566 | */ |
| 11567 | if (tab->is_nested_inner()) |
| 11568 | { |
| 11569 | if (force_unlinked_cache || cache_level == 1) |
| 11570 | goto no_join_cache; |
| 11571 | if (cache_level & 1) |
| 11572 | cache_level--; |
| 11573 | } |
| 11574 | |
| 11575 | /* |
| 11576 | Don't use BKA for materialized tables. We could actually have a |
| 11577 | meaningful use of BKA when linked join buffers are used. |
| 11578 | |
| 11579 | The problem is, the temp.table is not filled (actually not even opened |
| 11580 | properly) yet, and this doesn't let us call |
| 11581 | handler->multi_range_read_info(). It is possible to come up with |
| 11582 | estimates, etc. without acessing the table, but it seems not to worth the |
| 11583 | effort now. |
| 11584 | */ |
| 11585 | if (tab->table->pos_in_table_list->is_materialized_derived()) |
| 11586 | no_bka_cache= true; |
| 11587 | |
| 11588 | /* |
| 11589 | Don't use join buffering if we're dictated not to by no_jbuf_after |
| 11590 | (This is not meaningfully used currently) |
| 11591 | */ |
| 11592 | if (table_index > no_jbuf_after) |
| 11593 | goto no_join_cache; |
| 11594 | |
| 11595 | /* |
| 11596 | TODO: BNL join buffer should be perfectly ok with tab->bush_children. |
| 11597 | */ |
| 11598 | if (tab->loosescan_match_tab || tab->bush_children) |
| 11599 | goto no_join_cache; |
| 11600 | |
| 11601 | for (JOIN_TAB *first_inner= tab->first_inner; first_inner; |
| 11602 | first_inner= first_inner->first_upper) |
| 11603 | { |
| 11604 | if (first_inner != tab && |
| 11605 | (!first_inner->use_join_cache || !(tab-1)->use_join_cache)) |
| 11606 | goto no_join_cache; |
| 11607 | } |
| 11608 | if (tab->first_sj_inner_tab && tab->first_sj_inner_tab != tab && |
| 11609 | (!tab->first_sj_inner_tab->use_join_cache || !(tab-1)->use_join_cache)) |
| 11610 | goto no_join_cache; |
| 11611 | if (!prev_tab->use_join_cache) |
| 11612 | { |
| 11613 | /* |
| 11614 | Check whether table tab and the previous one belong to the same nest of |
| 11615 | inner tables and if so do not use join buffer when joining table tab. |
| 11616 | */ |
| 11617 | if (tab->first_inner && tab != tab->first_inner) |
| 11618 | { |
| 11619 | for (JOIN_TAB *first_inner= tab[-1].first_inner; |
| 11620 | first_inner; |
| 11621 | first_inner= first_inner->first_upper) |
| 11622 | { |
| 11623 | if (first_inner == tab->first_inner) |
| 11624 | goto no_join_cache; |
| 11625 | } |
| 11626 | } |
| 11627 | else if (tab->first_sj_inner_tab && tab != tab->first_sj_inner_tab && |
| 11628 | tab->first_sj_inner_tab == tab[-1].first_sj_inner_tab) |
| 11629 | goto no_join_cache; |
| 11630 | } |
| 11631 | |
| 11632 | prev_cache= prev_tab->cache; |
| 11633 | |
| 11634 | switch (tab->type) { |
| 11635 | case JT_ALL: |
| 11636 | if (cache_level == 1) |
| 11637 | prev_cache= 0; |
| 11638 | if ((tab->cache= new (root) JOIN_CACHE_BNL(join, tab, prev_cache))) |
| 11639 | { |
| 11640 | tab->icp_other_tables_ok= FALSE; |
| 11641 | return (2 - MY_TEST(!prev_cache)); |
| 11642 | } |
| 11643 | goto no_join_cache; |
| 11644 | case JT_SYSTEM: |
| 11645 | case JT_CONST: |
| 11646 | case JT_REF: |
| 11647 | case JT_EQ_REF: |
| 11648 | if (cache_level <=2 || (no_hashed_cache && no_bka_cache)) |
| 11649 | goto no_join_cache; |
| 11650 | if (tab->ref.is_access_triggered()) |
| 11651 | goto no_join_cache; |
| 11652 | |
| 11653 | if (!tab->is_ref_for_hash_join() && !no_bka_cache) |
| 11654 | { |
| 11655 | flags= HA_MRR_NO_NULL_ENDPOINTS | HA_MRR_SINGLE_POINT; |
| 11656 | if (tab->table->covering_keys.is_set(tab->ref.key)) |
| 11657 | flags|= HA_MRR_INDEX_ONLY; |
| 11658 | rows= tab->table->file->multi_range_read_info(tab->ref.key, 10, 20, |
| 11659 | tab->ref.key_parts, |
| 11660 | &bufsz, &flags, &cost); |
| 11661 | } |
| 11662 | |
| 11663 | if ((cache_level <=4 && !no_hashed_cache) || no_bka_cache || |
| 11664 | tab->is_ref_for_hash_join() || |
| 11665 | ((flags & HA_MRR_NO_ASSOCIATION) && cache_level <=6)) |
| 11666 | { |
| 11667 | if (!tab->hash_join_is_possible() || |
| 11668 | tab->make_scan_filter()) |
| 11669 | goto no_join_cache; |
| 11670 | if (cache_level == 3) |
| 11671 | prev_cache= 0; |
| 11672 | if ((tab->cache= new (root) JOIN_CACHE_BNLH(join, tab, prev_cache))) |
| 11673 | { |
| 11674 | tab->icp_other_tables_ok= FALSE; |
| 11675 | return (4 - MY_TEST(!prev_cache)); |
| 11676 | } |
| 11677 | goto no_join_cache; |
| 11678 | } |
| 11679 | if (cache_level > 4 && no_bka_cache) |
| 11680 | goto no_join_cache; |
| 11681 | |
| 11682 | if ((flags & HA_MRR_NO_ASSOCIATION) && |
| 11683 | (cache_level <= 6 || no_hashed_cache)) |
| 11684 | goto no_join_cache; |
| 11685 | |
| 11686 | if ((rows != HA_POS_ERROR) && !(flags & HA_MRR_USE_DEFAULT_IMPL)) |
| 11687 | { |
| 11688 | if (cache_level <= 6 || no_hashed_cache) |
| 11689 | { |
| 11690 | if (cache_level == 5) |
| 11691 | prev_cache= 0; |
| 11692 | if ((tab->cache= new (root) JOIN_CACHE_BKA(join, tab, flags, prev_cache))) |
| 11693 | return (6 - MY_TEST(!prev_cache)); |
| 11694 | goto no_join_cache; |
| 11695 | } |
| 11696 | else |
| 11697 | { |
| 11698 | if (cache_level == 7) |
| 11699 | prev_cache= 0; |
| 11700 | if ((tab->cache= new (root) JOIN_CACHE_BKAH(join, tab, flags, prev_cache))) |
| 11701 | { |
| 11702 | tab->idx_cond_fact_out= FALSE; |
| 11703 | return (8 - MY_TEST(!prev_cache)); |
| 11704 | } |
| 11705 | goto no_join_cache; |
| 11706 | } |
| 11707 | } |
| 11708 | goto no_join_cache; |
| 11709 | default : ; |
| 11710 | } |
| 11711 | |
| 11712 | no_join_cache: |
| 11713 | if (tab->type != JT_ALL && tab->is_ref_for_hash_join()) |
| 11714 | { |
| 11715 | tab->type= JT_ALL; |
| 11716 | tab->ref.key_parts= 0; |
| 11717 | } |
| 11718 | revise_cache_usage(tab); |
| 11719 | return 0; |
| 11720 | } |
| 11721 | |
| 11722 | |
| 11723 | /* |
| 11724 | Check whether join buffers can be used to join tables of a join |
| 11725 | |
| 11726 | SYNOPSIS |
| 11727 | check_join_cache_usage() |
| 11728 | join join whose tables are to be checked |
| 11729 | options options of the join |
| 11730 | no_jbuf_after don't use join buffering after table with this number |
| 11731 | (The tables are assumed to be numbered in |
| 11732 | first_linear_tab(join, WITHOUT_CONST_TABLES), |
| 11733 | next_linear_tab(join, WITH_CONST_TABLES) order). |
| 11734 | |
| 11735 | DESCRIPTION |
| 11736 | For each table after the first non-constant table the function checks |
| 11737 | whether the table can be joined using a join buffer. If the function decides |
| 11738 | that a join buffer can be employed then it selects the most appropriate join |
| 11739 | cache object that contains this join buffer whose level is not greater |
| 11740 | than join_cache_level set for the join. To make this check the function |
| 11741 | calls the function check_join_cache_usage for every non-constant table. |
| 11742 | |
| 11743 | NOTES |
| 11744 | In some situations (e.g. for nested outer joins, for nested semi-joins) only |
| 11745 | incremental buffers can be used. If it turns out that for some inner table |
| 11746 | no join buffer can be used then any inner table of an outer/semi-join nest |
| 11747 | cannot use join buffer. In the case when already chosen buffer must be |
| 11748 | denied for a table the function recalls check_join_cache_usage() |
| 11749 | starting from this table. The pointer to the table from which the check |
| 11750 | has to be restarted is returned in join->return_val (see the description |
| 11751 | of check_join_cache_usage). |
| 11752 | */ |
| 11753 | |
| 11754 | void check_join_cache_usage_for_tables(JOIN *join, ulonglong options, |
| 11755 | uint no_jbuf_after) |
| 11756 | { |
| 11757 | JOIN_TAB *tab; |
| 11758 | JOIN_TAB *prev_tab; |
| 11759 | |
| 11760 | for (tab= first_linear_tab(join, WITH_BUSH_ROOTS, WITHOUT_CONST_TABLES); |
| 11761 | tab; |
| 11762 | tab= next_linear_tab(join, tab, WITH_BUSH_ROOTS)) |
| 11763 | { |
| 11764 | tab->used_join_cache_level= join->max_allowed_join_cache_level; |
| 11765 | } |
| 11766 | |
| 11767 | uint idx= join->const_tables; |
| 11768 | for (tab= first_linear_tab(join, WITH_BUSH_ROOTS, WITHOUT_CONST_TABLES); |
| 11769 | tab; |
| 11770 | tab= next_linear_tab(join, tab, WITH_BUSH_ROOTS)) |
| 11771 | { |
| 11772 | restart: |
| 11773 | tab->icp_other_tables_ok= TRUE; |
| 11774 | tab->idx_cond_fact_out= TRUE; |
| 11775 | |
| 11776 | /* |
| 11777 | Check if we have a preceding join_tab, as something that will feed us |
| 11778 | records that we could buffer. We don't have it, if |
| 11779 | - this is the first non-const table in the join order, |
| 11780 | - this is the first table inside an SJM nest. |
| 11781 | */ |
| 11782 | prev_tab= tab - 1; |
| 11783 | if (tab == join->join_tab + join->const_tables || |
| 11784 | (tab->bush_root_tab && tab->bush_root_tab->bush_children->start == tab)) |
| 11785 | prev_tab= NULL; |
| 11786 | |
| 11787 | switch (tab->type) { |
| 11788 | case JT_SYSTEM: |
| 11789 | case JT_CONST: |
| 11790 | case JT_EQ_REF: |
| 11791 | case JT_REF: |
| 11792 | case JT_REF_OR_NULL: |
| 11793 | case JT_ALL: |
| 11794 | tab->used_join_cache_level= check_join_cache_usage(tab, options, |
| 11795 | no_jbuf_after, |
| 11796 | idx, |
| 11797 | prev_tab); |
| 11798 | tab->use_join_cache= MY_TEST(tab->used_join_cache_level); |
| 11799 | /* |
| 11800 | psergey-merge: todo: raise the question that this is really stupid that |
| 11801 | we can first allocate a join buffer, then decide not to use it and free |
| 11802 | it. |
| 11803 | */ |
| 11804 | if (join->return_tab) |
| 11805 | { |
| 11806 | tab= join->return_tab; |
| 11807 | goto restart; |
| 11808 | } |
| 11809 | break; |
| 11810 | default: |
| 11811 | tab->used_join_cache_level= 0; |
| 11812 | } |
| 11813 | if (!tab->bush_children) |
| 11814 | idx++; |
| 11815 | } |
| 11816 | } |
| 11817 | |
| 11818 | /** |
| 11819 | Remove pushdown conditions that are already checked by the scan phase |
| 11820 | of BNL/BNLH joins. |
| 11821 | |
| 11822 | @note |
| 11823 | If the single-table condition for this table will be used by a |
| 11824 | blocked join to pre-filter this table's rows, there is no need |
| 11825 | to re-check the same single-table condition for each joined record. |
| 11826 | |
| 11827 | This method removes from JOIN_TAB::select_cond and JOIN_TAB::select::cond |
| 11828 | all top-level conjuncts that also appear in in JOIN_TAB::cache_select::cond. |
| 11829 | */ |
| 11830 | |
| 11831 | void JOIN_TAB::remove_redundant_bnl_scan_conds() |
| 11832 | { |
| 11833 | if (!(select_cond && cache_select && cache && |
| 11834 | (cache->get_join_alg() == JOIN_CACHE::BNL_JOIN_ALG || |
| 11835 | cache->get_join_alg() == JOIN_CACHE::BNLH_JOIN_ALG))) |
| 11836 | return; |
| 11837 | |
| 11838 | /* |
| 11839 | select->cond is not processed separately. This method assumes it is always |
| 11840 | the same as select_cond. |
| 11841 | */ |
| 11842 | if (select && select->cond != select_cond) |
| 11843 | return; |
| 11844 | |
| 11845 | if (is_cond_and(select_cond)) |
| 11846 | { |
| 11847 | List_iterator<Item> pushed_cond_li(*((Item_cond*) select_cond)->argument_list()); |
| 11848 | Item *pushed_item; |
| 11849 | Item_cond_and *reduced_select_cond= new (join->thd->mem_root) |
| 11850 | Item_cond_and(join->thd); |
| 11851 | |
| 11852 | if (is_cond_and(cache_select->cond)) |
| 11853 | { |
| 11854 | List_iterator<Item> scan_cond_li(*((Item_cond*) cache_select->cond)->argument_list()); |
| 11855 | Item *scan_item; |
| 11856 | while ((pushed_item= pushed_cond_li++)) |
| 11857 | { |
| 11858 | bool found_cond= false; |
| 11859 | scan_cond_li.rewind(); |
| 11860 | while ((scan_item= scan_cond_li++)) |
| 11861 | { |
| 11862 | if (pushed_item->eq(scan_item, 0)) |
| 11863 | { |
| 11864 | found_cond= true; |
| 11865 | break; |
| 11866 | } |
| 11867 | } |
| 11868 | if (!found_cond) |
| 11869 | reduced_select_cond->add(pushed_item, join->thd->mem_root); |
| 11870 | } |
| 11871 | } |
| 11872 | else |
| 11873 | { |
| 11874 | while ((pushed_item= pushed_cond_li++)) |
| 11875 | { |
| 11876 | if (!pushed_item->eq(cache_select->cond, 0)) |
| 11877 | reduced_select_cond->add(pushed_item, join->thd->mem_root); |
| 11878 | } |
| 11879 | } |
| 11880 | |
| 11881 | /* |
| 11882 | JOIN_CACHE::check_match uses JOIN_TAB::select->cond instead of |
| 11883 | JOIN_TAB::select_cond. set_cond() sets both pointers. |
| 11884 | */ |
| 11885 | if (reduced_select_cond->argument_list()->is_empty()) |
| 11886 | set_cond(NULL); |
| 11887 | else if (reduced_select_cond->argument_list()->elements == 1) |
| 11888 | set_cond(reduced_select_cond->argument_list()->head()); |
| 11889 | else |
| 11890 | { |
| 11891 | reduced_select_cond->quick_fix_field(); |
| 11892 | set_cond(reduced_select_cond); |
| 11893 | } |
| 11894 | } |
| 11895 | else if (select_cond->eq(cache_select->cond, 0)) |
| 11896 | set_cond(NULL); |
| 11897 | } |
| 11898 | |
| 11899 | |
| 11900 | /* |
| 11901 | Plan refinement stage: do various setup things for the executor |
| 11902 | |
| 11903 | SYNOPSIS |
| 11904 | make_join_readinfo() |
| 11905 | join Join being processed |
| 11906 | options Join's options (checking for SELECT_DESCRIBE, |
| 11907 | SELECT_NO_JOIN_CACHE) |
| 11908 | no_jbuf_after Don't use join buffering after table with this number. |
| 11909 | |
| 11910 | DESCRIPTION |
| 11911 | Plan refinement stage: do various set ups for the executioner |
| 11912 | - set up use of join buffering |
| 11913 | - push index conditions |
| 11914 | - increment relevant counters |
| 11915 | - etc |
| 11916 | |
| 11917 | RETURN |
| 11918 | FALSE - OK |
| 11919 | TRUE - Out of memory |
| 11920 | */ |
| 11921 | |
| 11922 | static bool |
| 11923 | make_join_readinfo(JOIN *join, ulonglong options, uint no_jbuf_after) |
| 11924 | { |
| 11925 | JOIN_TAB *tab; |
| 11926 | uint i; |
| 11927 | DBUG_ENTER("make_join_readinfo" ); |
| 11928 | |
| 11929 | bool statistics= MY_TEST(!(join->select_options & SELECT_DESCRIBE)); |
| 11930 | bool sorted= 1; |
| 11931 | |
| 11932 | join->complex_firstmatch_tables= table_map(0); |
| 11933 | |
| 11934 | if (!join->select_lex->sj_nests.is_empty() && |
| 11935 | setup_semijoin_dups_elimination(join, options, no_jbuf_after)) |
| 11936 | DBUG_RETURN(TRUE); /* purecov: inspected */ |
| 11937 | |
| 11938 | /* For const tables, set partial_join_cardinality to 1. */ |
| 11939 | for (tab= join->join_tab; tab != join->join_tab + join->const_tables; tab++) |
| 11940 | tab->partial_join_cardinality= 1; |
| 11941 | |
| 11942 | JOIN_TAB *prev_tab= NULL; |
| 11943 | i= join->const_tables; |
| 11944 | for (tab= first_linear_tab(join, WITH_BUSH_ROOTS, WITHOUT_CONST_TABLES); |
| 11945 | tab; |
| 11946 | prev_tab=tab, tab= next_linear_tab(join, tab, WITH_BUSH_ROOTS)) |
| 11947 | { |
| 11948 | /* |
| 11949 | The approximation below for partial join cardinality is not good because |
| 11950 | - it does not take into account some pushdown predicates |
| 11951 | - it does not differentiate between inner joins, outer joins and |
| 11952 | semi-joins. |
| 11953 | Later it should be improved. |
| 11954 | */ |
| 11955 | |
| 11956 | if (tab->bush_root_tab && tab->bush_root_tab->bush_children->start == tab) |
| 11957 | prev_tab= NULL; |
| 11958 | DBUG_ASSERT(tab->bush_children || tab->table == join->best_positions[i].table->table); |
| 11959 | |
| 11960 | tab->partial_join_cardinality= join->best_positions[i].records_read * |
| 11961 | (prev_tab? prev_tab->partial_join_cardinality : 1); |
| 11962 | if (!tab->bush_children) |
| 11963 | i++; |
| 11964 | } |
| 11965 | |
| 11966 | check_join_cache_usage_for_tables(join, options, no_jbuf_after); |
| 11967 | |
| 11968 | JOIN_TAB *first_tab; |
| 11969 | for (tab= first_tab= first_linear_tab(join, WITH_BUSH_ROOTS, WITHOUT_CONST_TABLES); |
| 11970 | tab; |
| 11971 | tab= next_linear_tab(join, tab, WITH_BUSH_ROOTS)) |
| 11972 | { |
| 11973 | if (tab->bush_children) |
| 11974 | { |
| 11975 | if (setup_sj_materialization_part2(tab)) |
| 11976 | return TRUE; |
| 11977 | } |
| 11978 | |
| 11979 | TABLE *table=tab->table; |
| 11980 | uint jcl= tab->used_join_cache_level; |
| 11981 | tab->read_record.table= table; |
| 11982 | tab->read_record.unlock_row= rr_unlock_row; |
| 11983 | tab->sorted= sorted; |
| 11984 | sorted= 0; // only first must be sorted |
| 11985 | |
| 11986 | |
| 11987 | /* |
| 11988 | We should not set tab->next_select for the last table in the |
| 11989 | SMJ-nest, as setup_sj_materialization() has already set it to |
| 11990 | end_sj_materialize. |
| 11991 | */ |
| 11992 | if (!(tab->bush_root_tab && |
| 11993 | tab->bush_root_tab->bush_children->end == tab + 1)) |
| 11994 | { |
| 11995 | tab->next_select=sub_select; /* normal select */ |
| 11996 | } |
| 11997 | |
| 11998 | |
| 11999 | if (tab->loosescan_match_tab) |
| 12000 | { |
| 12001 | if (!(tab->loosescan_buf= (uchar*)join->thd->alloc(tab-> |
| 12002 | loosescan_key_len))) |
| 12003 | return TRUE; /* purecov: inspected */ |
| 12004 | tab->sorted= TRUE; |
| 12005 | } |
| 12006 | table->status=STATUS_NO_RECORD; |
| 12007 | pick_table_access_method (tab); |
| 12008 | |
| 12009 | if (jcl) |
| 12010 | tab[-1].next_select=sub_select_cache; |
| 12011 | |
| 12012 | if (tab->cache && tab->cache->get_join_alg() == JOIN_CACHE::BNLH_JOIN_ALG) |
| 12013 | tab->type= JT_HASH; |
| 12014 | |
| 12015 | switch (tab->type) { |
| 12016 | case JT_SYSTEM: // Only happens with left join |
| 12017 | case JT_CONST: // Only happens with left join |
| 12018 | /* Only happens with outer joins */ |
| 12019 | tab->read_first_record= tab->type == JT_SYSTEM ? join_read_system |
| 12020 | : join_read_const; |
| 12021 | if (table->covering_keys.is_set(tab->ref.key) && !table->no_keyread) |
| 12022 | table->file->ha_start_keyread(tab->ref.key); |
| 12023 | else if ((!jcl || jcl > 4) && !tab->ref.is_access_triggered()) |
| 12024 | push_index_cond(tab, tab->ref.key); |
| 12025 | break; |
| 12026 | case JT_EQ_REF: |
| 12027 | tab->read_record.unlock_row= join_read_key_unlock_row; |
| 12028 | /* fall through */ |
| 12029 | if (table->covering_keys.is_set(tab->ref.key) && !table->no_keyread) |
| 12030 | table->file->ha_start_keyread(tab->ref.key); |
| 12031 | else if ((!jcl || jcl > 4) && !tab->ref.is_access_triggered()) |
| 12032 | push_index_cond(tab, tab->ref.key); |
| 12033 | break; |
| 12034 | case JT_REF_OR_NULL: |
| 12035 | case JT_REF: |
| 12036 | if (tab->select) |
| 12037 | { |
| 12038 | delete tab->select->quick; |
| 12039 | tab->select->quick=0; |
| 12040 | } |
| 12041 | delete tab->quick; |
| 12042 | tab->quick=0; |
| 12043 | if (table->covering_keys.is_set(tab->ref.key) && !table->no_keyread) |
| 12044 | table->file->ha_start_keyread(tab->ref.key); |
| 12045 | else if ((!jcl || jcl > 4) && !tab->ref.is_access_triggered()) |
| 12046 | push_index_cond(tab, tab->ref.key); |
| 12047 | break; |
| 12048 | case JT_ALL: |
| 12049 | case JT_HASH: |
| 12050 | /* |
| 12051 | If previous table use cache |
| 12052 | If the incoming data set is already sorted don't use cache. |
| 12053 | Also don't use cache if this is the first table in semi-join |
| 12054 | materialization nest. |
| 12055 | */ |
| 12056 | /* These init changes read_record */ |
| 12057 | if (tab->use_quick == 2) |
| 12058 | { |
| 12059 | join->thd->set_status_no_good_index_used(); |
| 12060 | tab->read_first_record= join_init_quick_read_record; |
| 12061 | if (statistics) |
| 12062 | join->thd->inc_status_select_range_check(); |
| 12063 | } |
| 12064 | else |
| 12065 | { |
| 12066 | if (!tab->bush_children) |
| 12067 | tab->read_first_record= join_init_read_record; |
| 12068 | if (tab == first_tab) |
| 12069 | { |
| 12070 | if (tab->select && tab->select->quick) |
| 12071 | { |
| 12072 | if (statistics) |
| 12073 | join->thd->inc_status_select_range(); |
| 12074 | } |
| 12075 | else |
| 12076 | { |
| 12077 | join->thd->set_status_no_index_used(); |
| 12078 | if (statistics) |
| 12079 | { |
| 12080 | join->thd->inc_status_select_scan(); |
| 12081 | join->thd->query_plan_flags|= QPLAN_FULL_SCAN; |
| 12082 | } |
| 12083 | } |
| 12084 | } |
| 12085 | else |
| 12086 | { |
| 12087 | if (tab->select && tab->select->quick) |
| 12088 | { |
| 12089 | if (statistics) |
| 12090 | join->thd->inc_status_select_full_range_join(); |
| 12091 | } |
| 12092 | else |
| 12093 | { |
| 12094 | join->thd->set_status_no_index_used(); |
| 12095 | if (statistics) |
| 12096 | { |
| 12097 | join->thd->inc_status_select_full_join(); |
| 12098 | join->thd->query_plan_flags|= QPLAN_FULL_JOIN; |
| 12099 | } |
| 12100 | } |
| 12101 | } |
| 12102 | if (!table->no_keyread) |
| 12103 | { |
| 12104 | if (tab->select && tab->select->quick && |
| 12105 | tab->select->quick->index != MAX_KEY && //not index_merge |
| 12106 | table->covering_keys.is_set(tab->select->quick->index)) |
| 12107 | table->file->ha_start_keyread(tab->select->quick->index); |
| 12108 | else if (!table->covering_keys.is_clear_all() && |
| 12109 | !(tab->select && tab->select->quick)) |
| 12110 | { // Only read index tree |
| 12111 | if (tab->loosescan_match_tab) |
| 12112 | tab->index= tab->loosescan_key; |
| 12113 | else |
| 12114 | { |
| 12115 | #ifdef BAD_OPTIMIZATION |
| 12116 | /* |
| 12117 | It has turned out that the below change, while speeding things |
| 12118 | up for disk-bound loads, slows them down for cases when the data |
| 12119 | is in disk cache (see BUG#35850): |
| 12120 | See bug #26447: "Using the clustered index for a table scan |
| 12121 | is always faster than using a secondary index". |
| 12122 | */ |
| 12123 | if (table->s->primary_key != MAX_KEY && |
| 12124 | table->file->primary_key_is_clustered()) |
| 12125 | tab->index= table->s->primary_key; |
| 12126 | else |
| 12127 | #endif |
| 12128 | tab->index=find_shortest_key(table, & table->covering_keys); |
| 12129 | } |
| 12130 | tab->read_first_record= join_read_first; |
| 12131 | /* Read with index_first / index_next */ |
| 12132 | tab->type= tab->type == JT_ALL ? JT_NEXT : JT_HASH_NEXT; |
| 12133 | } |
| 12134 | } |
| 12135 | if (tab->select && tab->select->quick && |
| 12136 | tab->select->quick->index != MAX_KEY && |
| 12137 | !tab->table->file->keyread_enabled()) |
| 12138 | push_index_cond(tab, tab->select->quick->index); |
| 12139 | } |
| 12140 | break; |
| 12141 | case JT_FT: |
| 12142 | break; |
| 12143 | /* purecov: begin deadcode */ |
| 12144 | default: |
| 12145 | DBUG_PRINT("error" ,("Table type %d found" ,tab->type)); |
| 12146 | break; |
| 12147 | case JT_UNKNOWN: |
| 12148 | case JT_MAYBE_REF: |
| 12149 | abort(); |
| 12150 | /* purecov: end */ |
| 12151 | } |
| 12152 | |
| 12153 | DBUG_EXECUTE("where" , |
| 12154 | char buff[256]; |
| 12155 | String str(buff,sizeof(buff),system_charset_info); |
| 12156 | str.length(0); |
| 12157 | str.append(tab->table? tab->table->alias.c_ptr() :"<no_table_name>" ); |
| 12158 | str.append(" final_pushdown_cond" ); |
| 12159 | print_where(tab->select_cond, str.c_ptr_safe(), QT_ORDINARY);); |
| 12160 | } |
| 12161 | uint n_top_tables= (uint)(join->join_tab_ranges.head()->end - |
| 12162 | join->join_tab_ranges.head()->start); |
| 12163 | |
| 12164 | join->join_tab[n_top_tables - 1].next_select=0; /* Set by do_select */ |
| 12165 | |
| 12166 | /* |
| 12167 | If a join buffer is used to join a table the ordering by an index |
| 12168 | for the first non-constant table cannot be employed anymore. |
| 12169 | */ |
| 12170 | for (tab= join->join_tab + join->const_tables ; |
| 12171 | tab != join->join_tab + n_top_tables ; tab++) |
| 12172 | { |
| 12173 | if (tab->use_join_cache) |
| 12174 | { |
| 12175 | JOIN_TAB *sort_by_tab= join->group && join->simple_group && |
| 12176 | join->group_list ? |
| 12177 | join->join_tab+join->const_tables : |
| 12178 | join->get_sort_by_join_tab(); |
| 12179 | /* |
| 12180 | It could be that sort_by_tab==NULL, and the plan is to use filesort() |
| 12181 | on the first table. |
| 12182 | */ |
| 12183 | if (join->order) |
| 12184 | { |
| 12185 | join->simple_order= 0; |
| 12186 | join->need_tmp= 1; |
| 12187 | } |
| 12188 | |
| 12189 | if (join->group && !join->group_optimized_away) |
| 12190 | { |
| 12191 | join->need_tmp= 1; |
| 12192 | join->simple_group= 0; |
| 12193 | } |
| 12194 | |
| 12195 | if (sort_by_tab) |
| 12196 | { |
| 12197 | join->need_tmp= 1; |
| 12198 | join->simple_order= join->simple_group= 0; |
| 12199 | if (sort_by_tab->type == JT_NEXT && |
| 12200 | !sort_by_tab->table->covering_keys.is_set(sort_by_tab->index)) |
| 12201 | { |
| 12202 | sort_by_tab->type= JT_ALL; |
| 12203 | sort_by_tab->read_first_record= join_init_read_record; |
| 12204 | } |
| 12205 | else if (sort_by_tab->type == JT_HASH_NEXT && |
| 12206 | !sort_by_tab->table->covering_keys.is_set(sort_by_tab->index)) |
| 12207 | { |
| 12208 | sort_by_tab->type= JT_HASH; |
| 12209 | sort_by_tab->read_first_record= join_init_read_record; |
| 12210 | } |
| 12211 | } |
| 12212 | break; |
| 12213 | } |
| 12214 | } |
| 12215 | |
| 12216 | DBUG_RETURN(FALSE); |
| 12217 | } |
| 12218 | |
| 12219 | |
| 12220 | /** |
| 12221 | Give error if we some tables are done with a full join. |
| 12222 | |
| 12223 | This is used by multi_table_update and multi_table_delete when running |
| 12224 | in safe mode. |
| 12225 | |
| 12226 | @param join Join condition |
| 12227 | |
| 12228 | @retval |
| 12229 | 0 ok |
| 12230 | @retval |
| 12231 | 1 Error (full join used) |
| 12232 | */ |
| 12233 | |
| 12234 | bool error_if_full_join(JOIN *join) |
| 12235 | { |
| 12236 | for (JOIN_TAB *tab=first_top_level_tab(join, WITH_CONST_TABLES); tab; |
| 12237 | tab= next_top_level_tab(join, tab)) |
| 12238 | { |
| 12239 | if (tab->type == JT_ALL && (!tab->select || !tab->select->quick)) |
| 12240 | { |
| 12241 | my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE, |
| 12242 | ER_THD(join->thd, |
| 12243 | ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0)); |
| 12244 | return(1); |
| 12245 | } |
| 12246 | } |
| 12247 | return(0); |
| 12248 | } |
| 12249 | |
| 12250 | |
| 12251 | /** |
| 12252 | cleanup JOIN_TAB. |
| 12253 | |
| 12254 | DESCRIPTION |
| 12255 | This is invoked when we've finished all join executions. |
| 12256 | */ |
| 12257 | |
| 12258 | void JOIN_TAB::cleanup() |
| 12259 | { |
| 12260 | DBUG_ENTER("JOIN_TAB::cleanup" ); |
| 12261 | |
| 12262 | if (tab_list && tab_list->is_with_table_recursive_reference() && |
| 12263 | tab_list->with->is_cleaned()) |
| 12264 | DBUG_VOID_RETURN; |
| 12265 | |
| 12266 | DBUG_PRINT("enter" , ("tab: %p table %s.%s" , |
| 12267 | this, |
| 12268 | (table ? table->s->db.str : "?" ), |
| 12269 | (table ? table->s->table_name.str : "?" ))); |
| 12270 | delete select; |
| 12271 | select= 0; |
| 12272 | delete quick; |
| 12273 | quick= 0; |
| 12274 | if (cache) |
| 12275 | { |
| 12276 | cache->free(); |
| 12277 | cache= 0; |
| 12278 | } |
| 12279 | limit= 0; |
| 12280 | // Free select that was created for filesort outside of create_sort_index |
| 12281 | if (filesort && filesort->select && !filesort->own_select) |
| 12282 | delete filesort->select; |
| 12283 | delete filesort; |
| 12284 | filesort= NULL; |
| 12285 | /* Skip non-existing derived tables/views result tables */ |
| 12286 | if (table && |
| 12287 | (table->s->tmp_table != INTERNAL_TMP_TABLE || table->is_created())) |
| 12288 | { |
| 12289 | table->file->ha_end_keyread(); |
| 12290 | table->file->ha_index_or_rnd_end(); |
| 12291 | } |
| 12292 | if (table) |
| 12293 | { |
| 12294 | table->file->ha_end_keyread(); |
| 12295 | table->file->ha_index_or_rnd_end(); |
| 12296 | preread_init_done= FALSE; |
| 12297 | if (table->pos_in_table_list && |
| 12298 | table->pos_in_table_list->jtbm_subselect) |
| 12299 | { |
| 12300 | if (table->pos_in_table_list->jtbm_subselect->is_jtbm_const_tab) |
| 12301 | { |
| 12302 | /* |
| 12303 | Set this to NULL so that cleanup_empty_jtbm_semi_joins() doesn't |
| 12304 | attempt to make another free_tmp_table call. |
| 12305 | */ |
| 12306 | table->pos_in_table_list->table= NULL; |
| 12307 | free_tmp_table(join->thd, table); |
| 12308 | table= NULL; |
| 12309 | } |
| 12310 | else |
| 12311 | { |
| 12312 | TABLE_LIST *tmp= table->pos_in_table_list; |
| 12313 | end_read_record(&read_record); |
| 12314 | tmp->jtbm_subselect->cleanup(); |
| 12315 | /* |
| 12316 | The above call freed the materializedd temptable. Set it to NULL so |
| 12317 | that we don't attempt to touch it if JOIN_TAB::cleanup() is invoked |
| 12318 | multiple times (it may be) |
| 12319 | */ |
| 12320 | tmp->table= NULL; |
| 12321 | table= NULL; |
| 12322 | } |
| 12323 | DBUG_VOID_RETURN; |
| 12324 | } |
| 12325 | /* |
| 12326 | We need to reset this for next select |
| 12327 | (Tested in part_of_refkey) |
| 12328 | */ |
| 12329 | table->reginfo.join_tab= 0; |
| 12330 | } |
| 12331 | end_read_record(&read_record); |
| 12332 | explain_plan= NULL; |
| 12333 | DBUG_VOID_RETURN; |
| 12334 | } |
| 12335 | |
| 12336 | |
| 12337 | /** |
| 12338 | Estimate the time to get rows of the joined table |
| 12339 | */ |
| 12340 | |
| 12341 | double JOIN_TAB::scan_time() |
| 12342 | { |
| 12343 | double res; |
| 12344 | if (table->is_created()) |
| 12345 | { |
| 12346 | if (table->is_filled_at_execution()) |
| 12347 | { |
| 12348 | get_delayed_table_estimates(table, &records, &read_time, |
| 12349 | &startup_cost); |
| 12350 | found_records= records; |
| 12351 | table->quick_condition_rows= records; |
| 12352 | } |
| 12353 | else |
| 12354 | { |
| 12355 | found_records= records= table->stat_records(); |
| 12356 | read_time= table->file->scan_time(); |
| 12357 | /* |
| 12358 | table->quick_condition_rows has already been set to |
| 12359 | table->file->stats.records |
| 12360 | */ |
| 12361 | } |
| 12362 | res= read_time; |
| 12363 | } |
| 12364 | else |
| 12365 | { |
| 12366 | found_records= records=table->stat_records(); |
| 12367 | read_time= found_records ? (double)found_records: 10.0;// TODO:fix this stub |
| 12368 | res= read_time; |
| 12369 | } |
| 12370 | return res; |
| 12371 | } |
| 12372 | |
| 12373 | |
| 12374 | /** |
| 12375 | Estimate the number of rows that a an access method will read from a table. |
| 12376 | |
| 12377 | @todo: why not use JOIN_TAB::found_records |
| 12378 | */ |
| 12379 | |
| 12380 | ha_rows JOIN_TAB::get_examined_rows() |
| 12381 | { |
| 12382 | double examined_rows; |
| 12383 | SQL_SELECT *sel= filesort? filesort->select : this->select; |
| 12384 | |
| 12385 | if (sel && sel->quick && use_quick != 2) |
| 12386 | examined_rows= (double)sel->quick->records; |
| 12387 | else if (type == JT_NEXT || type == JT_ALL || |
| 12388 | type == JT_HASH || type ==JT_HASH_NEXT) |
| 12389 | { |
| 12390 | if (limit) |
| 12391 | { |
| 12392 | /* |
| 12393 | @todo This estimate is wrong, a LIMIT query may examine much more rows |
| 12394 | than the LIMIT itself. |
| 12395 | */ |
| 12396 | examined_rows= (double)limit; |
| 12397 | } |
| 12398 | else |
| 12399 | { |
| 12400 | if (table->is_filled_at_execution()) |
| 12401 | examined_rows= (double)records; |
| 12402 | else |
| 12403 | { |
| 12404 | /* |
| 12405 | handler->info(HA_STATUS_VARIABLE) has been called in |
| 12406 | make_join_statistics() |
| 12407 | */ |
| 12408 | examined_rows= (double)table->stat_records(); |
| 12409 | } |
| 12410 | } |
| 12411 | } |
| 12412 | else |
| 12413 | examined_rows= records_read; |
| 12414 | |
| 12415 | return (ha_rows) examined_rows; |
| 12416 | } |
| 12417 | |
| 12418 | |
| 12419 | /** |
| 12420 | Initialize the join_tab before reading. |
| 12421 | Currently only derived table/view materialization is done here. |
| 12422 | |
| 12423 | TODO: consider moving this together with join_tab_execution_startup |
| 12424 | */ |
| 12425 | bool JOIN_TAB::preread_init() |
| 12426 | { |
| 12427 | TABLE_LIST *derived= table->pos_in_table_list; |
| 12428 | if (!derived || !derived->is_materialized_derived()) |
| 12429 | { |
| 12430 | preread_init_done= TRUE; |
| 12431 | return FALSE; |
| 12432 | } |
| 12433 | |
| 12434 | /* Materialize derived table/view. */ |
| 12435 | if ((!derived->get_unit()->executed || |
| 12436 | derived->is_recursive_with_table() || |
| 12437 | derived->get_unit()->uncacheable) && |
| 12438 | mysql_handle_single_derived(join->thd->lex, |
| 12439 | derived, DT_CREATE | DT_FILL)) |
| 12440 | return TRUE; |
| 12441 | |
| 12442 | if (!(derived->get_unit()->uncacheable & UNCACHEABLE_DEPENDENT) || |
| 12443 | derived->is_nonrecursive_derived_with_rec_ref()) |
| 12444 | preread_init_done= TRUE; |
| 12445 | if (select && select->quick) |
| 12446 | select->quick->replace_handler(table->file); |
| 12447 | |
| 12448 | DBUG_EXECUTE_IF("show_explain_probe_join_tab_preread" , |
| 12449 | if (dbug_user_var_equals_int(join->thd, |
| 12450 | "show_explain_probe_select_id" , |
| 12451 | join->select_lex->select_number)) |
| 12452 | dbug_serve_apcs(join->thd, 1); |
| 12453 | ); |
| 12454 | |
| 12455 | /* init ftfuns for just initialized derived table */ |
| 12456 | if (table->fulltext_searched) |
| 12457 | if (init_ftfuncs(join->thd, join->select_lex, MY_TEST(join->order))) |
| 12458 | return TRUE; |
| 12459 | |
| 12460 | return FALSE; |
| 12461 | } |
| 12462 | |
| 12463 | |
| 12464 | /** |
| 12465 | Build a TABLE_REF structure for index lookup in the temporary table |
| 12466 | |
| 12467 | @param thd Thread handle |
| 12468 | @param tmp_key The temporary table key |
| 12469 | @param it The iterator of items for lookup in the key |
| 12470 | @param skip Number of fields from the beginning to skip |
| 12471 | |
| 12472 | @details |
| 12473 | Build TABLE_REF object for lookup in the key 'tmp_key' using items |
| 12474 | accessible via item iterator 'it'. |
| 12475 | |
| 12476 | @retval TRUE Error |
| 12477 | @retval FALSE OK |
| 12478 | */ |
| 12479 | |
| 12480 | bool TABLE_REF::tmp_table_index_lookup_init(THD *thd, |
| 12481 | KEY *tmp_key, |
| 12482 | Item_iterator &it, |
| 12483 | bool value, |
| 12484 | uint skip) |
| 12485 | { |
| 12486 | uint tmp_key_parts= tmp_key->user_defined_key_parts; |
| 12487 | uint i; |
| 12488 | DBUG_ENTER("TABLE_REF::tmp_table_index_lookup_init" ); |
| 12489 | |
| 12490 | key= 0; /* The only temp table index. */ |
| 12491 | key_length= tmp_key->key_length; |
| 12492 | if (!(key_buff= |
| 12493 | (uchar*) thd->calloc(ALIGN_SIZE(tmp_key->key_length) * 2)) || |
| 12494 | !(key_copy= |
| 12495 | (store_key**) thd->alloc((sizeof(store_key*) * |
| 12496 | (tmp_key_parts + 1)))) || |
| 12497 | !(items= |
| 12498 | (Item**) thd->alloc(sizeof(Item*) * tmp_key_parts))) |
| 12499 | DBUG_RETURN(TRUE); |
| 12500 | |
| 12501 | key_buff2= key_buff + ALIGN_SIZE(tmp_key->key_length); |
| 12502 | |
| 12503 | KEY_PART_INFO *cur_key_part= tmp_key->key_part; |
| 12504 | store_key **ref_key= key_copy; |
| 12505 | uchar *cur_ref_buff= key_buff; |
| 12506 | |
| 12507 | it.open(); |
| 12508 | for (i= 0; i < skip; i++) it.next(); |
| 12509 | for (i= 0; i < tmp_key_parts; i++, cur_key_part++, ref_key++) |
| 12510 | { |
| 12511 | Item *item= it.next(); |
| 12512 | DBUG_ASSERT(item); |
| 12513 | items[i]= item; |
| 12514 | int null_count= MY_TEST(cur_key_part->field->real_maybe_null()); |
| 12515 | *ref_key= new store_key_item(thd, cur_key_part->field, |
| 12516 | /* TIMOUR: |
| 12517 | the NULL byte is taken into account in |
| 12518 | cur_key_part->store_length, so instead of |
| 12519 | cur_ref_buff + MY_TEST(maybe_null), we could |
| 12520 | use that information instead. |
| 12521 | */ |
| 12522 | cur_ref_buff + null_count, |
| 12523 | null_count ? cur_ref_buff : 0, |
| 12524 | cur_key_part->length, items[i], value); |
| 12525 | cur_ref_buff+= cur_key_part->store_length; |
| 12526 | } |
| 12527 | *ref_key= NULL; /* End marker. */ |
| 12528 | key_err= 1; |
| 12529 | key_parts= tmp_key_parts; |
| 12530 | DBUG_RETURN(FALSE); |
| 12531 | } |
| 12532 | |
| 12533 | |
| 12534 | /* |
| 12535 | Check if ref access uses "Full scan on NULL key" (i.e. it actually alternates |
| 12536 | between ref access and full table scan) |
| 12537 | */ |
| 12538 | |
| 12539 | bool TABLE_REF::is_access_triggered() |
| 12540 | { |
| 12541 | for (uint i = 0; i < key_parts; i++) |
| 12542 | { |
| 12543 | if (cond_guards[i]) |
| 12544 | return TRUE; |
| 12545 | } |
| 12546 | return FALSE; |
| 12547 | } |
| 12548 | |
| 12549 | |
| 12550 | /** |
| 12551 | Partially cleanup JOIN after it has executed: close index or rnd read |
| 12552 | (table cursors), free quick selects. |
| 12553 | |
| 12554 | This function is called in the end of execution of a JOIN, before the used |
| 12555 | tables are unlocked and closed. |
| 12556 | |
| 12557 | For a join that is resolved using a temporary table, the first sweep is |
| 12558 | performed against actual tables and an intermediate result is inserted |
| 12559 | into the temprorary table. |
| 12560 | The last sweep is performed against the temporary table. Therefore, |
| 12561 | the base tables and associated buffers used to fill the temporary table |
| 12562 | are no longer needed, and this function is called to free them. |
| 12563 | |
| 12564 | For a join that is performed without a temporary table, this function |
| 12565 | is called after all rows are sent, but before EOF packet is sent. |
| 12566 | |
| 12567 | For a simple SELECT with no subqueries this function performs a full |
| 12568 | cleanup of the JOIN and calls mysql_unlock_read_tables to free used base |
| 12569 | tables. |
| 12570 | |
| 12571 | If a JOIN is executed for a subquery or if it has a subquery, we can't |
| 12572 | do the full cleanup and need to do a partial cleanup only. |
| 12573 | - If a JOIN is not the top level join, we must not unlock the tables |
| 12574 | because the outer select may not have been evaluated yet, and we |
| 12575 | can't unlock only selected tables of a query. |
| 12576 | - Additionally, if this JOIN corresponds to a correlated subquery, we |
| 12577 | should not free quick selects and join buffers because they will be |
| 12578 | needed for the next execution of the correlated subquery. |
| 12579 | - However, if this is a JOIN for a [sub]select, which is not |
| 12580 | a correlated subquery itself, but has subqueries, we can free it |
| 12581 | fully and also free JOINs of all its subqueries. The exception |
| 12582 | is a subquery in SELECT list, e.g: @n |
| 12583 | SELECT a, (select MY_MAX(b) from t1) group by c @n |
| 12584 | This subquery will not be evaluated at first sweep and its value will |
| 12585 | not be inserted into the temporary table. Instead, it's evaluated |
| 12586 | when selecting from the temporary table. Therefore, it can't be freed |
| 12587 | here even though it's not correlated. |
| 12588 | |
| 12589 | @todo |
| 12590 | Unlock tables even if the join isn't top level select in the tree |
| 12591 | */ |
| 12592 | |
| 12593 | void JOIN::join_free() |
| 12594 | { |
| 12595 | SELECT_LEX_UNIT *tmp_unit; |
| 12596 | SELECT_LEX *sl; |
| 12597 | /* |
| 12598 | Optimization: if not EXPLAIN and we are done with the JOIN, |
| 12599 | free all tables. |
| 12600 | */ |
| 12601 | bool full= !(select_lex->uncacheable) && !(thd->lex->describe); |
| 12602 | bool can_unlock= full; |
| 12603 | DBUG_ENTER("JOIN::join_free" ); |
| 12604 | |
| 12605 | cleanup(full); |
| 12606 | |
| 12607 | for (tmp_unit= select_lex->first_inner_unit(); |
| 12608 | tmp_unit; |
| 12609 | tmp_unit= tmp_unit->next_unit()) |
| 12610 | for (sl= tmp_unit->first_select(); sl; sl= sl->next_select()) |
| 12611 | { |
| 12612 | Item_subselect *subselect= sl->master_unit()->item; |
| 12613 | bool full_local= full && (!subselect || subselect->is_evaluated()); |
| 12614 | /* |
| 12615 | If this join is evaluated, we can fully clean it up and clean up all |
| 12616 | its underlying joins even if they are correlated -- they will not be |
| 12617 | used any more anyway. |
| 12618 | If this join is not yet evaluated, we still must clean it up to |
| 12619 | close its table cursors -- it may never get evaluated, as in case of |
| 12620 | ... HAVING FALSE OR a IN (SELECT ...)) |
| 12621 | but all table cursors must be closed before the unlock. |
| 12622 | */ |
| 12623 | sl->cleanup_all_joins(full_local); |
| 12624 | /* Can't unlock if at least one JOIN is still needed */ |
| 12625 | can_unlock= can_unlock && full_local; |
| 12626 | } |
| 12627 | |
| 12628 | /* |
| 12629 | We are not using tables anymore |
| 12630 | Unlock all tables. We may be in an INSERT .... SELECT statement. |
| 12631 | */ |
| 12632 | if (can_unlock && lock && thd->lock && ! thd->locked_tables_mode && |
| 12633 | !(select_options & SELECT_NO_UNLOCK) && |
| 12634 | !select_lex->subquery_in_having && |
| 12635 | (select_lex == (thd->lex->unit.fake_select_lex ? |
| 12636 | thd->lex->unit.fake_select_lex : &thd->lex->select_lex))) |
| 12637 | { |
| 12638 | /* |
| 12639 | TODO: unlock tables even if the join isn't top level select in the |
| 12640 | tree. |
| 12641 | */ |
| 12642 | mysql_unlock_read_tables(thd, lock); // Don't free join->lock |
| 12643 | lock= 0; |
| 12644 | } |
| 12645 | |
| 12646 | DBUG_VOID_RETURN; |
| 12647 | } |
| 12648 | |
| 12649 | |
| 12650 | /** |
| 12651 | Free resources of given join. |
| 12652 | |
| 12653 | @param full true if we should free all resources, call with full==1 |
| 12654 | should be last, before it this function can be called with |
| 12655 | full==0 |
| 12656 | |
| 12657 | @note |
| 12658 | With subquery this function definitely will be called several times, |
| 12659 | but even for simple query it can be called several times. |
| 12660 | */ |
| 12661 | |
| 12662 | void JOIN::cleanup(bool full) |
| 12663 | { |
| 12664 | DBUG_ENTER("JOIN::cleanup" ); |
| 12665 | DBUG_PRINT("enter" , ("full %u" , (uint) full)); |
| 12666 | |
| 12667 | if (full) |
| 12668 | have_query_plan= QEP_DELETED; |
| 12669 | |
| 12670 | if (original_join_tab) |
| 12671 | { |
| 12672 | /* Free the original optimized join created for the group_by_handler */ |
| 12673 | join_tab= original_join_tab; |
| 12674 | original_join_tab= 0; |
| 12675 | table_count= original_table_count; |
| 12676 | } |
| 12677 | |
| 12678 | if (join_tab) |
| 12679 | { |
| 12680 | JOIN_TAB *tab; |
| 12681 | |
| 12682 | if (full) |
| 12683 | { |
| 12684 | /* |
| 12685 | Call cleanup() on join tabs used by the join optimization |
| 12686 | (join->join_tab may now be pointing to result of make_simple_join |
| 12687 | reading from the temporary table) |
| 12688 | |
| 12689 | We also need to check table_count to handle various degenerate joins |
| 12690 | w/o tables: they don't have some members initialized and |
| 12691 | WALK_OPTIMIZATION_TABS may not work correctly for them. |
| 12692 | */ |
| 12693 | if (top_join_tab_count && tables_list) |
| 12694 | { |
| 12695 | for (tab= first_breadth_first_tab(); tab; |
| 12696 | tab= next_breadth_first_tab(first_breadth_first_tab(), |
| 12697 | top_join_tab_count, tab)) |
| 12698 | { |
| 12699 | tab->cleanup(); |
| 12700 | delete tab->filesort_result; |
| 12701 | tab->filesort_result= NULL; |
| 12702 | } |
| 12703 | } |
| 12704 | cleaned= true; |
| 12705 | //psergey2: added (Q: why not in the above loop?) |
| 12706 | { |
| 12707 | JOIN_TAB *curr_tab= join_tab + exec_join_tab_cnt(); |
| 12708 | for (uint i= 0; i < aggr_tables; i++, curr_tab++) |
| 12709 | { |
| 12710 | if (curr_tab->aggr) |
| 12711 | { |
| 12712 | free_tmp_table(thd, curr_tab->table); |
| 12713 | delete curr_tab->tmp_table_param; |
| 12714 | curr_tab->tmp_table_param= NULL; |
| 12715 | curr_tab->aggr= NULL; |
| 12716 | |
| 12717 | delete curr_tab->filesort_result; |
| 12718 | curr_tab->filesort_result= NULL; |
| 12719 | } |
| 12720 | } |
| 12721 | aggr_tables= 0; // psergey3 |
| 12722 | } |
| 12723 | } |
| 12724 | else |
| 12725 | { |
| 12726 | for (tab= first_linear_tab(this, WITH_BUSH_ROOTS, WITH_CONST_TABLES); tab; |
| 12727 | tab= next_linear_tab(this, tab, WITH_BUSH_ROOTS)) |
| 12728 | { |
| 12729 | if (!tab->table) |
| 12730 | continue; |
| 12731 | DBUG_PRINT("info" , ("close index: %s.%s alias: %s" , |
| 12732 | tab->table->s->db.str, |
| 12733 | tab->table->s->table_name.str, |
| 12734 | tab->table->alias.c_ptr())); |
| 12735 | if (tab->table->is_created()) |
| 12736 | { |
| 12737 | tab->table->file->ha_index_or_rnd_end(); |
| 12738 | if (tab->aggr) |
| 12739 | { |
| 12740 | int tmp= 0; |
| 12741 | if ((tmp= tab->table->file->extra(HA_EXTRA_NO_CACHE))) |
| 12742 | tab->table->file->print_error(tmp, MYF(0)); |
| 12743 | } |
| 12744 | } |
| 12745 | delete tab->filesort_result; |
| 12746 | tab->filesort_result= NULL; |
| 12747 | } |
| 12748 | } |
| 12749 | } |
| 12750 | if (full) |
| 12751 | { |
| 12752 | cleanup_empty_jtbm_semi_joins(this, join_list); |
| 12753 | |
| 12754 | // Run Cached_item DTORs! |
| 12755 | group_fields.delete_elements(); |
| 12756 | |
| 12757 | /* |
| 12758 | We can't call delete_elements() on copy_funcs as this will cause |
| 12759 | problems in free_elements() as some of the elements are then deleted. |
| 12760 | */ |
| 12761 | tmp_table_param.copy_funcs.empty(); |
| 12762 | /* |
| 12763 | If we have tmp_join and 'this' JOIN is not tmp_join and |
| 12764 | tmp_table_param.copy_field's of them are equal then we have to remove |
| 12765 | pointer to tmp_table_param.copy_field from tmp_join, because it will |
| 12766 | be removed in tmp_table_param.cleanup(). |
| 12767 | */ |
| 12768 | tmp_table_param.cleanup(); |
| 12769 | |
| 12770 | delete pushdown_query; |
| 12771 | pushdown_query= 0; |
| 12772 | |
| 12773 | if (!join_tab) |
| 12774 | { |
| 12775 | List_iterator<TABLE_LIST> li(*join_list); |
| 12776 | TABLE_LIST *table_ref; |
| 12777 | while ((table_ref= li++)) |
| 12778 | { |
| 12779 | if (table_ref->table && |
| 12780 | table_ref->jtbm_subselect && |
| 12781 | table_ref->jtbm_subselect->is_jtbm_const_tab) |
| 12782 | { |
| 12783 | free_tmp_table(thd, table_ref->table); |
| 12784 | table_ref->table= NULL; |
| 12785 | } |
| 12786 | } |
| 12787 | } |
| 12788 | } |
| 12789 | /* Restore ref array to original state */ |
| 12790 | if (current_ref_ptrs != items0) |
| 12791 | { |
| 12792 | set_items_ref_array(items0); |
| 12793 | set_group_rpa= false; |
| 12794 | } |
| 12795 | DBUG_VOID_RETURN; |
| 12796 | } |
| 12797 | |
| 12798 | |
| 12799 | /** |
| 12800 | Remove the following expressions from ORDER BY and GROUP BY: |
| 12801 | Constant expressions @n |
| 12802 | Expression that only uses tables that are of type EQ_REF and the reference |
| 12803 | is in the ORDER list or if all refereed tables are of the above type. |
| 12804 | |
| 12805 | In the following, the X field can be removed: |
| 12806 | @code |
| 12807 | SELECT * FROM t1,t2 WHERE t1.a=t2.a ORDER BY t1.a,t2.X |
| 12808 | SELECT * FROM t1,t2,t3 WHERE t1.a=t2.a AND t2.b=t3.b ORDER BY t1.a,t3.X |
| 12809 | @endcode |
| 12810 | |
| 12811 | These can't be optimized: |
| 12812 | @code |
| 12813 | SELECT * FROM t1,t2 WHERE t1.a=t2.a ORDER BY t2.X,t1.a |
| 12814 | SELECT * FROM t1,t2 WHERE t1.a=t2.a AND t1.b=t2.b ORDER BY t1.a,t2.c |
| 12815 | SELECT * FROM t1,t2 WHERE t1.a=t2.a ORDER BY t2.b,t1.a |
| 12816 | @endcode |
| 12817 | |
| 12818 | TODO: this function checks ORDER::used, which can only have a value of 0. |
| 12819 | */ |
| 12820 | |
| 12821 | static bool |
| 12822 | eq_ref_table(JOIN *join, ORDER *start_order, JOIN_TAB *tab) |
| 12823 | { |
| 12824 | if (tab->cached_eq_ref_table) // If cached |
| 12825 | return tab->eq_ref_table; |
| 12826 | tab->cached_eq_ref_table=1; |
| 12827 | /* We can skip const tables only if not an outer table */ |
| 12828 | if (tab->type == JT_CONST && !tab->first_inner) |
| 12829 | return (tab->eq_ref_table=1); /* purecov: inspected */ |
| 12830 | if (tab->type != JT_EQ_REF || tab->table->maybe_null) |
| 12831 | return (tab->eq_ref_table=0); // We must use this |
| 12832 | Item **ref_item=tab->ref.items; |
| 12833 | Item **end=ref_item+tab->ref.key_parts; |
| 12834 | uint found=0; |
| 12835 | table_map map=tab->table->map; |
| 12836 | |
| 12837 | for (; ref_item != end ; ref_item++) |
| 12838 | { |
| 12839 | if (! (*ref_item)->const_item()) |
| 12840 | { // Not a const ref |
| 12841 | ORDER *order; |
| 12842 | for (order=start_order ; order ; order=order->next) |
| 12843 | { |
| 12844 | if ((*ref_item)->eq(order->item[0],0)) |
| 12845 | break; |
| 12846 | } |
| 12847 | if (order) |
| 12848 | { |
| 12849 | if (!(order->used & map)) |
| 12850 | { |
| 12851 | found++; |
| 12852 | order->used|= map; |
| 12853 | } |
| 12854 | continue; // Used in ORDER BY |
| 12855 | } |
| 12856 | if (!only_eq_ref_tables(join,start_order, (*ref_item)->used_tables())) |
| 12857 | return (tab->eq_ref_table=0); |
| 12858 | } |
| 12859 | } |
| 12860 | /* Check that there was no reference to table before sort order */ |
| 12861 | for (; found && start_order ; start_order=start_order->next) |
| 12862 | { |
| 12863 | if (start_order->used & map) |
| 12864 | { |
| 12865 | found--; |
| 12866 | continue; |
| 12867 | } |
| 12868 | if (start_order->depend_map & map) |
| 12869 | return (tab->eq_ref_table=0); |
| 12870 | } |
| 12871 | return tab->eq_ref_table=1; |
| 12872 | } |
| 12873 | |
| 12874 | |
| 12875 | static bool |
| 12876 | only_eq_ref_tables(JOIN *join,ORDER *order,table_map tables) |
| 12877 | { |
| 12878 | tables&= ~PSEUDO_TABLE_BITS; |
| 12879 | for (JOIN_TAB **tab=join->map2table ; tables ; tab++, tables>>=1) |
| 12880 | { |
| 12881 | if (tables & 1 && !eq_ref_table(join, order, *tab)) |
| 12882 | return 0; |
| 12883 | } |
| 12884 | return 1; |
| 12885 | } |
| 12886 | |
| 12887 | |
| 12888 | /** Update the dependency map for the tables. */ |
| 12889 | |
| 12890 | static void update_depend_map(JOIN *join) |
| 12891 | { |
| 12892 | JOIN_TAB *join_tab; |
| 12893 | for (join_tab= first_linear_tab(join, WITH_BUSH_ROOTS, WITH_CONST_TABLES); |
| 12894 | join_tab; |
| 12895 | join_tab= next_linear_tab(join, join_tab, WITH_BUSH_ROOTS)) |
| 12896 | { |
| 12897 | TABLE_REF *ref= &join_tab->ref; |
| 12898 | table_map depend_map=0; |
| 12899 | Item **item=ref->items; |
| 12900 | uint i; |
| 12901 | for (i=0 ; i < ref->key_parts ; i++,item++) |
| 12902 | depend_map|=(*item)->used_tables(); |
| 12903 | depend_map&= ~OUTER_REF_TABLE_BIT; |
| 12904 | ref->depend_map= depend_map; |
| 12905 | for (JOIN_TAB **tab=join->map2table; |
| 12906 | depend_map ; |
| 12907 | tab++,depend_map>>=1 ) |
| 12908 | { |
| 12909 | if (depend_map & 1) |
| 12910 | ref->depend_map|=(*tab)->ref.depend_map; |
| 12911 | } |
| 12912 | } |
| 12913 | } |
| 12914 | |
| 12915 | |
| 12916 | /** Update the dependency map for the sort order. */ |
| 12917 | |
| 12918 | static void update_depend_map_for_order(JOIN *join, ORDER *order) |
| 12919 | { |
| 12920 | for (; order ; order=order->next) |
| 12921 | { |
| 12922 | table_map depend_map; |
| 12923 | order->item[0]->update_used_tables(); |
| 12924 | order->depend_map=depend_map=order->item[0]->used_tables(); |
| 12925 | order->used= 0; |
| 12926 | // Not item_sum(), RAND() and no reference to table outside of sub select |
| 12927 | if (!(order->depend_map & (OUTER_REF_TABLE_BIT | RAND_TABLE_BIT)) |
| 12928 | && !order->item[0]->with_sum_func && |
| 12929 | join->join_tab) |
| 12930 | { |
| 12931 | for (JOIN_TAB **tab=join->map2table; |
| 12932 | depend_map ; |
| 12933 | tab++, depend_map>>=1) |
| 12934 | { |
| 12935 | if (depend_map & 1) |
| 12936 | order->depend_map|=(*tab)->ref.depend_map; |
| 12937 | } |
| 12938 | } |
| 12939 | } |
| 12940 | } |
| 12941 | |
| 12942 | |
| 12943 | /** |
| 12944 | Remove all constants and check if ORDER only contains simple |
| 12945 | expressions. |
| 12946 | |
| 12947 | We also remove all duplicate expressions, keeping only the first one. |
| 12948 | |
| 12949 | simple_order is set to 1 if sort_order only uses fields from head table |
| 12950 | and the head table is not a LEFT JOIN table. |
| 12951 | |
| 12952 | @param join Join handler |
| 12953 | @param first_order List of SORT or GROUP order |
| 12954 | @param cond WHERE statement |
| 12955 | @param change_list Set to 1 if we should remove things from list. |
| 12956 | If this is not set, then only simple_order is |
| 12957 | calculated. This is not set when we |
| 12958 | are using ROLLUP |
| 12959 | @param simple_order Set to 1 if we are only using simple |
| 12960 | expressions. |
| 12961 | |
| 12962 | @return |
| 12963 | Returns new sort order |
| 12964 | */ |
| 12965 | |
| 12966 | static ORDER * |
| 12967 | remove_const(JOIN *join,ORDER *first_order, COND *cond, |
| 12968 | bool change_list, bool *simple_order) |
| 12969 | { |
| 12970 | *simple_order= join->rollup.state == ROLLUP::STATE_NONE; |
| 12971 | if (join->only_const_tables()) |
| 12972 | return change_list ? 0 : first_order; // No need to sort |
| 12973 | |
| 12974 | ORDER *order,**prev_ptr, *tmp_order; |
| 12975 | table_map UNINIT_VAR(first_table); /* protected by first_is_base_table */ |
| 12976 | table_map not_const_tables= ~join->const_table_map; |
| 12977 | table_map ref; |
| 12978 | bool first_is_base_table= FALSE; |
| 12979 | DBUG_ENTER("remove_const" ); |
| 12980 | |
| 12981 | /* |
| 12982 | Join tab is set after make_join_statistics() has been called. |
| 12983 | In case of one table with GROUP BY this function is called before |
| 12984 | join_tab is set for the GROUP_BY expression |
| 12985 | */ |
| 12986 | if (join->join_tab) |
| 12987 | { |
| 12988 | if (join->join_tab[join->const_tables].table) |
| 12989 | { |
| 12990 | first_table= join->join_tab[join->const_tables].table->map; |
| 12991 | first_is_base_table= TRUE; |
| 12992 | } |
| 12993 | |
| 12994 | /* |
| 12995 | Cleanup to avoid interference of calls of this function for |
| 12996 | ORDER BY and GROUP BY |
| 12997 | */ |
| 12998 | for (JOIN_TAB *tab= join->join_tab + join->const_tables; |
| 12999 | tab < join->join_tab + join->table_count; |
| 13000 | tab++) |
| 13001 | tab->cached_eq_ref_table= FALSE; |
| 13002 | |
| 13003 | *simple_order= *join->join_tab[join->const_tables].on_expr_ref ? 0 : 1; |
| 13004 | } |
| 13005 | else |
| 13006 | { |
| 13007 | first_is_base_table= FALSE; |
| 13008 | first_table= 0; // Not used, for gcc |
| 13009 | } |
| 13010 | |
| 13011 | prev_ptr= &first_order; |
| 13012 | |
| 13013 | /* NOTE: A variable of not_const_tables ^ first_table; breaks gcc 2.7 */ |
| 13014 | |
| 13015 | update_depend_map_for_order(join, first_order); |
| 13016 | for (order=first_order; order ; order=order->next) |
| 13017 | { |
| 13018 | table_map order_tables=order->item[0]->used_tables(); |
| 13019 | if (order->item[0]->with_sum_func || |
| 13020 | /* |
| 13021 | If the outer table of an outer join is const (either by itself or |
| 13022 | after applying WHERE condition), grouping on a field from such a |
| 13023 | table will be optimized away and filesort without temporary table |
| 13024 | will be used unless we prevent that now. Filesort is not fit to |
| 13025 | handle joins and the join condition is not applied. We can't detect |
| 13026 | the case without an expensive test, however, so we force temporary |
| 13027 | table for all queries containing more than one table, ROLLUP, and an |
| 13028 | outer join. |
| 13029 | */ |
| 13030 | (join->table_count > 1 && join->rollup.state == ROLLUP::STATE_INITED && |
| 13031 | join->outer_join)) |
| 13032 | *simple_order=0; // Must do a temp table to sort |
| 13033 | else if (!(order_tables & not_const_tables)) |
| 13034 | { |
| 13035 | if (order->item[0]->with_subquery()) |
| 13036 | { |
| 13037 | /* |
| 13038 | Delay the evaluation of constant ORDER and/or GROUP expressions that |
| 13039 | contain subqueries until the execution phase. |
| 13040 | */ |
| 13041 | join->exec_const_order_group_cond.push_back(order->item[0], |
| 13042 | join->thd->mem_root); |
| 13043 | } |
| 13044 | DBUG_PRINT("info" ,("removing: %s" , order->item[0]->full_name())); |
| 13045 | continue; |
| 13046 | } |
| 13047 | else |
| 13048 | { |
| 13049 | if (order_tables & (RAND_TABLE_BIT | OUTER_REF_TABLE_BIT)) |
| 13050 | *simple_order=0; |
| 13051 | else |
| 13052 | { |
| 13053 | if (cond && const_expression_in_where(cond,order->item[0])) |
| 13054 | { |
| 13055 | DBUG_PRINT("info" ,("removing: %s" , order->item[0]->full_name())); |
| 13056 | continue; |
| 13057 | } |
| 13058 | if (first_is_base_table && |
| 13059 | (ref=order_tables & (not_const_tables ^ first_table))) |
| 13060 | { |
| 13061 | if (!(order_tables & first_table) && |
| 13062 | only_eq_ref_tables(join,first_order, ref)) |
| 13063 | { |
| 13064 | DBUG_PRINT("info" ,("removing: %s" , order->item[0]->full_name())); |
| 13065 | continue; |
| 13066 | } |
| 13067 | /* |
| 13068 | UseMultipleEqualitiesToRemoveTempTable: |
| 13069 | Can use multiple-equalities here to check that ORDER BY columns |
| 13070 | can be used without tmp. table. |
| 13071 | */ |
| 13072 | bool can_subst_to_first_table= false; |
| 13073 | bool first_is_in_sjm_nest= false; |
| 13074 | if (first_is_base_table) |
| 13075 | { |
| 13076 | TABLE_LIST *tbl_for_first= |
| 13077 | join->join_tab[join->const_tables].table->pos_in_table_list; |
| 13078 | first_is_in_sjm_nest= tbl_for_first->sj_mat_info && |
| 13079 | tbl_for_first->sj_mat_info->is_used; |
| 13080 | } |
| 13081 | /* |
| 13082 | Currently we do not employ the optimization that uses multiple |
| 13083 | equalities for ORDER BY to remove tmp table in the case when |
| 13084 | the first table happens to be the result of materialization of |
| 13085 | a semi-join nest ( <=> first_is_in_sjm_nest == true). |
| 13086 | |
| 13087 | When a semi-join nest is materialized and scanned to look for |
| 13088 | possible matches in the remaining tables for every its row |
| 13089 | the fields from the result of materialization are copied |
| 13090 | into the record buffers of tables from the semi-join nest. |
| 13091 | So these copies are used to access the remaining tables rather |
| 13092 | than the fields from the result of materialization. |
| 13093 | |
| 13094 | Unfortunately now this so-called 'copy back' technique is |
| 13095 | supported only if the rows are scanned with the rr_sequential |
| 13096 | function, but not with other rr_* functions that are employed |
| 13097 | when the result of materialization is required to be sorted. |
| 13098 | |
| 13099 | TODO: either to support 'copy back' technique for the above case, |
| 13100 | or to get rid of this technique altogether. |
| 13101 | */ |
| 13102 | if (optimizer_flag(join->thd, OPTIMIZER_SWITCH_ORDERBY_EQ_PROP) && |
| 13103 | first_is_base_table && !first_is_in_sjm_nest && |
| 13104 | order->item[0]->real_item()->type() == Item::FIELD_ITEM && |
| 13105 | join->cond_equal) |
| 13106 | { |
| 13107 | table_map first_table_bit= |
| 13108 | join->join_tab[join->const_tables].table->map; |
| 13109 | |
| 13110 | Item *item= order->item[0]; |
| 13111 | |
| 13112 | /* |
| 13113 | TODO: equality substitution in the context of ORDER BY is |
| 13114 | sometimes allowed when it is not allowed in the general case. |
| 13115 | |
| 13116 | We make the below call for its side effect: it will locate the |
| 13117 | multiple equality the item belongs to and set item->item_equal |
| 13118 | accordingly. |
| 13119 | */ |
| 13120 | Item *res= item->propagate_equal_fields(join->thd, |
| 13121 | Value_source:: |
| 13122 | Context_identity(), |
| 13123 | join->cond_equal); |
| 13124 | Item_equal *item_eq; |
| 13125 | if ((item_eq= res->get_item_equal())) |
| 13126 | { |
| 13127 | Item *first= item_eq->get_first(NO_PARTICULAR_TAB, NULL); |
| 13128 | if (first->const_item() || first->used_tables() == |
| 13129 | first_table_bit) |
| 13130 | { |
| 13131 | can_subst_to_first_table= true; |
| 13132 | } |
| 13133 | } |
| 13134 | } |
| 13135 | |
| 13136 | if (!can_subst_to_first_table) |
| 13137 | { |
| 13138 | *simple_order=0; // Must do a temp table to sort |
| 13139 | } |
| 13140 | } |
| 13141 | } |
| 13142 | } |
| 13143 | /* Remove ORDER BY entries that we have seen before */ |
| 13144 | for (tmp_order= first_order; |
| 13145 | tmp_order != order; |
| 13146 | tmp_order= tmp_order->next) |
| 13147 | { |
| 13148 | if (tmp_order->item[0]->eq(order->item[0],1)) |
| 13149 | break; |
| 13150 | } |
| 13151 | if (tmp_order != order) |
| 13152 | continue; // Duplicate order by. Remove |
| 13153 | |
| 13154 | if (change_list) |
| 13155 | *prev_ptr= order; // use this entry |
| 13156 | prev_ptr= &order->next; |
| 13157 | } |
| 13158 | if (change_list) |
| 13159 | *prev_ptr=0; |
| 13160 | if (prev_ptr == &first_order) // Nothing to sort/group |
| 13161 | *simple_order=1; |
| 13162 | #ifndef DBUG_OFF |
| 13163 | if (unlikely(join->thd->is_error())) |
| 13164 | DBUG_PRINT("error" ,("Error from remove_const" )); |
| 13165 | #endif |
| 13166 | DBUG_PRINT("exit" ,("simple_order: %d" ,(int) *simple_order)); |
| 13167 | DBUG_RETURN(first_order); |
| 13168 | } |
| 13169 | |
| 13170 | |
| 13171 | /** |
| 13172 | Filter out ORDER items those are equal to constants in WHERE |
| 13173 | |
| 13174 | This function is a limited version of remove_const() for use |
| 13175 | with non-JOIN statements (i.e. single-table UPDATE and DELETE). |
| 13176 | |
| 13177 | |
| 13178 | @param order Linked list of ORDER BY arguments |
| 13179 | @param cond WHERE expression |
| 13180 | |
| 13181 | @return pointer to new filtered ORDER list or NULL if whole list eliminated |
| 13182 | |
| 13183 | @note |
| 13184 | This function overwrites input order list. |
| 13185 | */ |
| 13186 | |
| 13187 | ORDER *simple_remove_const(ORDER *order, COND *where) |
| 13188 | { |
| 13189 | if (!order || !where) |
| 13190 | return order; |
| 13191 | |
| 13192 | ORDER *first= NULL, *prev= NULL; |
| 13193 | for (; order; order= order->next) |
| 13194 | { |
| 13195 | DBUG_ASSERT(!order->item[0]->with_sum_func); // should never happen |
| 13196 | if (!const_expression_in_where(where, order->item[0])) |
| 13197 | { |
| 13198 | if (!first) |
| 13199 | first= order; |
| 13200 | if (prev) |
| 13201 | prev->next= order; |
| 13202 | prev= order; |
| 13203 | } |
| 13204 | } |
| 13205 | if (prev) |
| 13206 | prev->next= NULL; |
| 13207 | return first; |
| 13208 | } |
| 13209 | |
| 13210 | |
| 13211 | static int |
| 13212 | return_zero_rows(JOIN *join, select_result *result, List<TABLE_LIST> &tables, |
| 13213 | List<Item> &fields, bool send_row, ulonglong select_options, |
| 13214 | const char *info, Item *having, List<Item> &all_fields) |
| 13215 | { |
| 13216 | DBUG_ENTER("return_zero_rows" ); |
| 13217 | |
| 13218 | if (select_options & SELECT_DESCRIBE) |
| 13219 | { |
| 13220 | select_describe(join, FALSE, FALSE, FALSE, info); |
| 13221 | DBUG_RETURN(0); |
| 13222 | } |
| 13223 | |
| 13224 | join->join_free(); |
| 13225 | |
| 13226 | if (send_row) |
| 13227 | { |
| 13228 | /* |
| 13229 | Set all tables to have NULL row. This is needed as we will be evaluating |
| 13230 | HAVING condition. |
| 13231 | */ |
| 13232 | List_iterator<TABLE_LIST> ti(tables); |
| 13233 | TABLE_LIST *table; |
| 13234 | while ((table= ti++)) |
| 13235 | { |
| 13236 | /* |
| 13237 | Don't touch semi-join materialization tables, as the above join_free() |
| 13238 | call has freed them (and HAVING clause can't have references to them |
| 13239 | anyway). |
| 13240 | */ |
| 13241 | if (!table->is_jtbm()) |
| 13242 | mark_as_null_row(table->table); // All fields are NULL |
| 13243 | } |
| 13244 | List_iterator_fast<Item> it(all_fields); |
| 13245 | Item *item; |
| 13246 | /* |
| 13247 | Inform all items (especially aggregating) to calculate HAVING correctly, |
| 13248 | also we will need it for sending results. |
| 13249 | */ |
| 13250 | while ((item= it++)) |
| 13251 | item->no_rows_in_result(); |
| 13252 | if (having && having->val_int() == 0) |
| 13253 | send_row=0; |
| 13254 | } |
| 13255 | |
| 13256 | /* Update results for FOUND_ROWS */ |
| 13257 | if (!join->send_row_on_empty_set()) |
| 13258 | { |
| 13259 | join->thd->set_examined_row_count(0); |
| 13260 | join->thd->limit_found_rows= 0; |
| 13261 | } |
| 13262 | |
| 13263 | if (!(result->send_result_set_metadata(fields, |
| 13264 | Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))) |
| 13265 | { |
| 13266 | bool send_error= FALSE; |
| 13267 | if (send_row) |
| 13268 | send_error= result->send_data(fields) > 0; |
| 13269 | if (likely(!send_error)) |
| 13270 | result->send_eof(); // Should be safe |
| 13271 | } |
| 13272 | DBUG_RETURN(0); |
| 13273 | } |
| 13274 | |
| 13275 | /* |
| 13276 | used only in JOIN::clear |
| 13277 | */ |
| 13278 | static void clear_tables(JOIN *join) |
| 13279 | { |
| 13280 | /* |
| 13281 | must clear only the non-const tables, as const tables |
| 13282 | are not re-calculated. |
| 13283 | */ |
| 13284 | for (uint i= 0 ; i < join->table_count ; i++) |
| 13285 | { |
| 13286 | if (!(join->table[i]->map & join->const_table_map)) |
| 13287 | mark_as_null_row(join->table[i]); // All fields are NULL |
| 13288 | } |
| 13289 | } |
| 13290 | |
| 13291 | /***************************************************************************** |
| 13292 | Make som simple condition optimization: |
| 13293 | If there is a test 'field = const' change all refs to 'field' to 'const' |
| 13294 | Remove all dummy tests 'item = item', 'const op const'. |
| 13295 | Remove all 'item is NULL', when item can never be null! |
| 13296 | item->marker should be 0 for all items on entry |
| 13297 | Return in cond_value FALSE if condition is impossible (1 = 2) |
| 13298 | *****************************************************************************/ |
| 13299 | |
| 13300 | class COND_CMP :public ilink { |
| 13301 | public: |
| 13302 | static void *operator new(size_t size, MEM_ROOT *mem_root) |
| 13303 | { |
| 13304 | return alloc_root(mem_root, size); |
| 13305 | } |
| 13306 | static void operator delete(void *ptr __attribute__((unused)), |
| 13307 | size_t size __attribute__((unused))) |
| 13308 | { TRASH_FREE(ptr, size); } |
| 13309 | |
| 13310 | static void operator delete(void *, MEM_ROOT*) {} |
| 13311 | |
| 13312 | Item *and_level; |
| 13313 | Item_bool_func2 *cmp_func; |
| 13314 | COND_CMP(Item *a,Item_bool_func2 *b) :and_level(a),cmp_func(b) {} |
| 13315 | }; |
| 13316 | |
| 13317 | /** |
| 13318 | Find the multiple equality predicate containing a field. |
| 13319 | |
| 13320 | The function retrieves the multiple equalities accessed through |
| 13321 | the con_equal structure from current level and up looking for |
| 13322 | an equality containing field. It stops retrieval as soon as the equality |
| 13323 | is found and set up inherited_fl to TRUE if it's found on upper levels. |
| 13324 | |
| 13325 | @param cond_equal multiple equalities to search in |
| 13326 | @param field field to look for |
| 13327 | @param[out] inherited_fl set up to TRUE if multiple equality is found |
| 13328 | on upper levels (not on current level of |
| 13329 | cond_equal) |
| 13330 | |
| 13331 | @return |
| 13332 | - Item_equal for the found multiple equality predicate if a success; |
| 13333 | - NULL otherwise. |
| 13334 | */ |
| 13335 | |
| 13336 | Item_equal *find_item_equal(COND_EQUAL *cond_equal, Field *field, |
| 13337 | bool *inherited_fl) |
| 13338 | { |
| 13339 | Item_equal *item= 0; |
| 13340 | bool in_upper_level= FALSE; |
| 13341 | while (cond_equal) |
| 13342 | { |
| 13343 | List_iterator_fast<Item_equal> li(cond_equal->current_level); |
| 13344 | while ((item= li++)) |
| 13345 | { |
| 13346 | if (item->contains(field)) |
| 13347 | goto finish; |
| 13348 | } |
| 13349 | in_upper_level= TRUE; |
| 13350 | cond_equal= cond_equal->upper_levels; |
| 13351 | } |
| 13352 | in_upper_level= FALSE; |
| 13353 | finish: |
| 13354 | *inherited_fl= in_upper_level; |
| 13355 | return item; |
| 13356 | } |
| 13357 | |
| 13358 | |
| 13359 | /** |
| 13360 | Check whether an equality can be used to build multiple equalities. |
| 13361 | |
| 13362 | This function first checks whether the equality (left_item=right_item) |
| 13363 | is a simple equality i.e. the one that equates a field with another field |
| 13364 | or a constant (field=field_item or field=const_item). |
| 13365 | If this is the case the function looks for a multiple equality |
| 13366 | in the lists referenced directly or indirectly by cond_equal inferring |
| 13367 | the given simple equality. If it doesn't find any, it builds a multiple |
| 13368 | equality that covers the predicate, i.e. the predicate can be inferred |
| 13369 | from this multiple equality. |
| 13370 | The built multiple equality could be obtained in such a way: |
| 13371 | create a binary multiple equality equivalent to the predicate, then |
| 13372 | merge it, if possible, with one of old multiple equalities. |
| 13373 | This guarantees that the set of multiple equalities covering equality |
| 13374 | predicates will be minimal. |
| 13375 | |
| 13376 | EXAMPLE: |
| 13377 | For the where condition |
| 13378 | @code |
| 13379 | WHERE a=b AND b=c AND |
| 13380 | (b=2 OR f=e) |
| 13381 | @endcode |
| 13382 | the check_equality will be called for the following equality |
| 13383 | predicates a=b, b=c, b=2 and f=e. |
| 13384 | - For a=b it will be called with *cond_equal=(0,[]) and will transform |
| 13385 | *cond_equal into (0,[Item_equal(a,b)]). |
| 13386 | - For b=c it will be called with *cond_equal=(0,[Item_equal(a,b)]) |
| 13387 | and will transform *cond_equal into CE=(0,[Item_equal(a,b,c)]). |
| 13388 | - For b=2 it will be called with *cond_equal=(ptr(CE),[]) |
| 13389 | and will transform *cond_equal into (ptr(CE),[Item_equal(2,a,b,c)]). |
| 13390 | - For f=e it will be called with *cond_equal=(ptr(CE), []) |
| 13391 | and will transform *cond_equal into (ptr(CE),[Item_equal(f,e)]). |
| 13392 | |
| 13393 | @note |
| 13394 | Now only fields that have the same type definitions (verified by |
| 13395 | the Field::eq_def method) are placed to the same multiple equalities. |
| 13396 | Because of this some equality predicates are not eliminated and |
| 13397 | can be used in the constant propagation procedure. |
| 13398 | We could weeken the equlity test as soon as at least one of the |
| 13399 | equal fields is to be equal to a constant. It would require a |
| 13400 | more complicated implementation: we would have to store, in |
| 13401 | general case, its own constant for each fields from the multiple |
| 13402 | equality. But at the same time it would allow us to get rid |
| 13403 | of constant propagation completely: it would be done by the call |
| 13404 | to cond->build_equal_items(). |
| 13405 | |
| 13406 | |
| 13407 | The implementation does not follow exactly the above rules to |
| 13408 | build a new multiple equality for the equality predicate. |
| 13409 | If it processes the equality of the form field1=field2, it |
| 13410 | looks for multiple equalities me1 containig field1 and me2 containing |
| 13411 | field2. If only one of them is found the fuction expands it with |
| 13412 | the lacking field. If multiple equalities for both fields are |
| 13413 | found they are merged. If both searches fail a new multiple equality |
| 13414 | containing just field1 and field2 is added to the existing |
| 13415 | multiple equalities. |
| 13416 | If the function processes the predicate of the form field1=const, |
| 13417 | it looks for a multiple equality containing field1. If found, the |
| 13418 | function checks the constant of the multiple equality. If the value |
| 13419 | is unknown, it is setup to const. Otherwise the value is compared with |
| 13420 | const and the evaluation of the equality predicate is performed. |
| 13421 | When expanding/merging equality predicates from the upper levels |
| 13422 | the function first copies them for the current level. It looks |
| 13423 | acceptable, as this happens rarely. The implementation without |
| 13424 | copying would be much more complicated. |
| 13425 | |
| 13426 | For description of how equality propagation works with SJM nests, grep |
| 13427 | for EqualityPropagationAndSjmNests. |
| 13428 | |
| 13429 | @param left_item left term of the quality to be checked |
| 13430 | @param right_item right term of the equality to be checked |
| 13431 | @param item equality item if the equality originates from a condition |
| 13432 | predicate, 0 if the equality is the result of row |
| 13433 | elimination |
| 13434 | @param cond_equal multiple equalities that must hold together with the |
| 13435 | equality |
| 13436 | |
| 13437 | @retval |
| 13438 | TRUE if the predicate is a simple equality predicate to be used |
| 13439 | for building multiple equalities |
| 13440 | @retval |
| 13441 | FALSE otherwise |
| 13442 | */ |
| 13443 | |
| 13444 | static bool check_simple_equality(THD *thd, const Item::Context &ctx, |
| 13445 | Item *left_item, Item *right_item, |
| 13446 | COND_EQUAL *cond_equal) |
| 13447 | { |
| 13448 | Item *orig_left_item= left_item; |
| 13449 | Item *orig_right_item= right_item; |
| 13450 | if (left_item->type() == Item::REF_ITEM && |
| 13451 | ((Item_ref*)left_item)->ref_type() == Item_ref::VIEW_REF) |
| 13452 | { |
| 13453 | if (((Item_ref*)left_item)->get_depended_from()) |
| 13454 | return FALSE; |
| 13455 | left_item= left_item->real_item(); |
| 13456 | } |
| 13457 | if (right_item->type() == Item::REF_ITEM && |
| 13458 | ((Item_ref*)right_item)->ref_type() == Item_ref::VIEW_REF) |
| 13459 | { |
| 13460 | if (((Item_ref*)right_item)->get_depended_from()) |
| 13461 | return FALSE; |
| 13462 | right_item= right_item->real_item(); |
| 13463 | } |
| 13464 | if (left_item->type() == Item::FIELD_ITEM && |
| 13465 | right_item->type() == Item::FIELD_ITEM && |
| 13466 | !((Item_field*)left_item)->get_depended_from() && |
| 13467 | !((Item_field*)right_item)->get_depended_from()) |
| 13468 | { |
| 13469 | /* The predicate the form field1=field2 is processed */ |
| 13470 | |
| 13471 | Field *left_field= ((Item_field*) left_item)->field; |
| 13472 | Field *right_field= ((Item_field*) right_item)->field; |
| 13473 | |
| 13474 | if (!left_field->eq_def(right_field)) |
| 13475 | return FALSE; |
| 13476 | |
| 13477 | /* Search for multiple equalities containing field1 and/or field2 */ |
| 13478 | bool left_copyfl, right_copyfl; |
| 13479 | Item_equal *left_item_equal= |
| 13480 | find_item_equal(cond_equal, left_field, &left_copyfl); |
| 13481 | Item_equal *right_item_equal= |
| 13482 | find_item_equal(cond_equal, right_field, &right_copyfl); |
| 13483 | |
| 13484 | /* As (NULL=NULL) != TRUE we can't just remove the predicate f=f */ |
| 13485 | if (left_field->eq(right_field)) /* f = f */ |
| 13486 | return (!(left_field->maybe_null() && !left_item_equal)); |
| 13487 | |
| 13488 | if (left_item_equal && left_item_equal == right_item_equal) |
| 13489 | { |
| 13490 | /* |
| 13491 | The equality predicate is inference of one of the existing |
| 13492 | multiple equalities, i.e the condition is already covered |
| 13493 | by upper level equalities |
| 13494 | */ |
| 13495 | return TRUE; |
| 13496 | } |
| 13497 | |
| 13498 | /* Copy the found multiple equalities at the current level if needed */ |
| 13499 | if (left_copyfl) |
| 13500 | { |
| 13501 | /* left_item_equal of an upper level contains left_item */ |
| 13502 | left_item_equal= new (thd->mem_root) Item_equal(thd, left_item_equal); |
| 13503 | left_item_equal->set_context_field(((Item_field*) left_item)); |
| 13504 | cond_equal->current_level.push_back(left_item_equal, thd->mem_root); |
| 13505 | } |
| 13506 | if (right_copyfl) |
| 13507 | { |
| 13508 | /* right_item_equal of an upper level contains right_item */ |
| 13509 | right_item_equal= new (thd->mem_root) Item_equal(thd, right_item_equal); |
| 13510 | right_item_equal->set_context_field(((Item_field*) right_item)); |
| 13511 | cond_equal->current_level.push_back(right_item_equal, thd->mem_root); |
| 13512 | } |
| 13513 | |
| 13514 | if (left_item_equal) |
| 13515 | { |
| 13516 | /* left item was found in the current or one of the upper levels */ |
| 13517 | if (! right_item_equal) |
| 13518 | left_item_equal->add(orig_right_item, thd->mem_root); |
| 13519 | else |
| 13520 | { |
| 13521 | /* Merge two multiple equalities forming a new one */ |
| 13522 | left_item_equal->merge(thd, right_item_equal); |
| 13523 | /* Remove the merged multiple equality from the list */ |
| 13524 | List_iterator<Item_equal> li(cond_equal->current_level); |
| 13525 | while ((li++) != right_item_equal) ; |
| 13526 | li.remove(); |
| 13527 | } |
| 13528 | } |
| 13529 | else |
| 13530 | { |
| 13531 | /* left item was not found neither the current nor in upper levels */ |
| 13532 | if (right_item_equal) |
| 13533 | right_item_equal->add(orig_left_item, thd->mem_root); |
| 13534 | else |
| 13535 | { |
| 13536 | /* None of the fields was found in multiple equalities */ |
| 13537 | Type_handler_hybrid_field_type |
| 13538 | tmp(orig_left_item->type_handler_for_comparison()); |
| 13539 | if (tmp.aggregate_for_comparison(orig_right_item-> |
| 13540 | type_handler_for_comparison())) |
| 13541 | return false; |
| 13542 | Item_equal *item_equal= |
| 13543 | new (thd->mem_root) Item_equal(thd, tmp.type_handler(), |
| 13544 | orig_left_item, orig_right_item, |
| 13545 | false); |
| 13546 | item_equal->set_context_field((Item_field*)left_item); |
| 13547 | cond_equal->current_level.push_back(item_equal, thd->mem_root); |
| 13548 | } |
| 13549 | } |
| 13550 | return TRUE; |
| 13551 | } |
| 13552 | |
| 13553 | { |
| 13554 | /* The predicate of the form field=const/const=field is processed */ |
| 13555 | Item *const_item= 0; |
| 13556 | Item_field *field_item= 0; |
| 13557 | Item *orig_field_item= 0; |
| 13558 | if (left_item->type() == Item::FIELD_ITEM && |
| 13559 | !((Item_field*)left_item)->get_depended_from() && |
| 13560 | right_item->const_item() && !right_item->is_expensive()) |
| 13561 | { |
| 13562 | orig_field_item= orig_left_item; |
| 13563 | field_item= (Item_field *) left_item; |
| 13564 | const_item= right_item; |
| 13565 | } |
| 13566 | else if (right_item->type() == Item::FIELD_ITEM && |
| 13567 | !((Item_field*)right_item)->get_depended_from() && |
| 13568 | left_item->const_item() && !left_item->is_expensive()) |
| 13569 | { |
| 13570 | orig_field_item= orig_right_item; |
| 13571 | field_item= (Item_field *) right_item; |
| 13572 | const_item= left_item; |
| 13573 | } |
| 13574 | |
| 13575 | if (const_item && |
| 13576 | field_item->field->test_if_equality_guarantees_uniqueness(const_item)) |
| 13577 | { |
| 13578 | /* |
| 13579 | field_item and const_item are arguments of a scalar or a row |
| 13580 | comparison function: |
| 13581 | WHERE column=constant |
| 13582 | WHERE (column, ...) = (constant, ...) |
| 13583 | |
| 13584 | The owner comparison function has previously called fix_fields(), |
| 13585 | so field_item and const_item should be directly comparable items, |
| 13586 | field_item->cmp_context and const_item->cmp_context should be set. |
| 13587 | In case of string comparison, charsets and collations of |
| 13588 | field_item and const_item should have already be aggregated |
| 13589 | for comparison, all necessary character set converters installed |
| 13590 | and fixed. |
| 13591 | |
| 13592 | In case of string comparison, const_item can be either: |
| 13593 | - a weaker constant that does not need to be converted to field_item: |
| 13594 | WHERE latin1_field = 'latin1_const' |
| 13595 | WHERE varbinary_field = 'latin1_const' |
| 13596 | WHERE latin1_bin_field = 'latin1_general_ci_const' |
| 13597 | - a stronger constant that does not need to be converted to field_item: |
| 13598 | WHERE latin1_field = binary 0xDF |
| 13599 | WHERE latin1_field = 'a' COLLATE latin1_bin |
| 13600 | - a result of conversion (e.g. from the session character set) |
| 13601 | to the character set of field_item: |
| 13602 | WHERE latin1_field = 'utf8_string_with_latin1_repertoire' |
| 13603 | */ |
| 13604 | bool copyfl; |
| 13605 | |
| 13606 | Item_equal *item_equal = find_item_equal(cond_equal, |
| 13607 | field_item->field, ©fl); |
| 13608 | if (copyfl) |
| 13609 | { |
| 13610 | item_equal= new (thd->mem_root) Item_equal(thd, item_equal); |
| 13611 | cond_equal->current_level.push_back(item_equal, thd->mem_root); |
| 13612 | item_equal->set_context_field(field_item); |
| 13613 | } |
| 13614 | Item *const_item2= field_item->field->get_equal_const_item(thd, ctx, |
| 13615 | const_item); |
| 13616 | if (!const_item2) |
| 13617 | return false; |
| 13618 | |
| 13619 | if (item_equal) |
| 13620 | { |
| 13621 | /* |
| 13622 | The flag cond_false will be set to 1 after this, if item_equal |
| 13623 | already contains a constant and its value is not equal to |
| 13624 | the value of const_item. |
| 13625 | */ |
| 13626 | item_equal->add_const(thd, const_item2); |
| 13627 | } |
| 13628 | else |
| 13629 | { |
| 13630 | Type_handler_hybrid_field_type |
| 13631 | tmp(orig_left_item->type_handler_for_comparison()); |
| 13632 | if (tmp.aggregate_for_comparison(orig_right_item-> |
| 13633 | type_handler_for_comparison())) |
| 13634 | return false; |
| 13635 | item_equal= new (thd->mem_root) Item_equal(thd, tmp.type_handler(), |
| 13636 | const_item2, |
| 13637 | orig_field_item, true); |
| 13638 | item_equal->set_context_field(field_item); |
| 13639 | cond_equal->current_level.push_back(item_equal, thd->mem_root); |
| 13640 | } |
| 13641 | return TRUE; |
| 13642 | } |
| 13643 | } |
| 13644 | return FALSE; |
| 13645 | } |
| 13646 | |
| 13647 | |
| 13648 | /** |
| 13649 | Convert row equalities into a conjunction of regular equalities. |
| 13650 | |
| 13651 | The function converts a row equality of the form (E1,...,En)=(E'1,...,E'n) |
| 13652 | into a list of equalities E1=E'1,...,En=E'n. For each of these equalities |
| 13653 | Ei=E'i the function checks whether it is a simple equality or a row |
| 13654 | equality. If it is a simple equality it is used to expand multiple |
| 13655 | equalities of cond_equal. If it is a row equality it converted to a |
| 13656 | sequence of equalities between row elements. If Ei=E'i is neither a |
| 13657 | simple equality nor a row equality the item for this predicate is added |
| 13658 | to eq_list. |
| 13659 | |
| 13660 | @param thd thread handle |
| 13661 | @param left_row left term of the row equality to be processed |
| 13662 | @param right_row right term of the row equality to be processed |
| 13663 | @param cond_equal multiple equalities that must hold together with the |
| 13664 | predicate |
| 13665 | @param eq_list results of conversions of row equalities that are not |
| 13666 | simple enough to form multiple equalities |
| 13667 | |
| 13668 | @retval |
| 13669 | TRUE if conversion has succeeded (no fatal error) |
| 13670 | @retval |
| 13671 | FALSE otherwise |
| 13672 | */ |
| 13673 | |
| 13674 | static bool check_row_equality(THD *thd, const Arg_comparator *comparators, |
| 13675 | Item *left_row, Item_row *right_row, |
| 13676 | COND_EQUAL *cond_equal, List<Item>* eq_list) |
| 13677 | { |
| 13678 | uint n= left_row->cols(); |
| 13679 | for (uint i= 0 ; i < n; i++) |
| 13680 | { |
| 13681 | bool is_converted; |
| 13682 | Item *left_item= left_row->element_index(i); |
| 13683 | Item *right_item= right_row->element_index(i); |
| 13684 | if (left_item->type() == Item::ROW_ITEM && |
| 13685 | right_item->type() == Item::ROW_ITEM) |
| 13686 | { |
| 13687 | /* |
| 13688 | Item_splocal for ROW SP variables return Item::ROW_ITEM. |
| 13689 | Here we know that left_item and right_item are not Item_splocal, |
| 13690 | because ROW SP variables with nested ROWs are not supported yet. |
| 13691 | It's safe to cast left_item and right_item to Item_row. |
| 13692 | */ |
| 13693 | DBUG_ASSERT(!left_item->get_item_splocal()); |
| 13694 | DBUG_ASSERT(!right_item->get_item_splocal()); |
| 13695 | is_converted= check_row_equality(thd, |
| 13696 | comparators[i].subcomparators(), |
| 13697 | (Item_row *) left_item, |
| 13698 | (Item_row *) right_item, |
| 13699 | cond_equal, eq_list); |
| 13700 | } |
| 13701 | else |
| 13702 | { |
| 13703 | const Arg_comparator *tmp= &comparators[i]; |
| 13704 | is_converted= check_simple_equality(thd, |
| 13705 | Item::Context(Item::ANY_SUBST, |
| 13706 | tmp->compare_type_handler(), |
| 13707 | tmp->compare_collation()), |
| 13708 | left_item, right_item, |
| 13709 | cond_equal); |
| 13710 | } |
| 13711 | |
| 13712 | if (!is_converted) |
| 13713 | { |
| 13714 | Item_func_eq *eq_item; |
| 13715 | if (!(eq_item= new (thd->mem_root) Item_func_eq(thd, left_item, right_item)) || |
| 13716 | eq_item->set_cmp_func()) |
| 13717 | return FALSE; |
| 13718 | eq_item->quick_fix_field(); |
| 13719 | eq_list->push_back(eq_item, thd->mem_root); |
| 13720 | } |
| 13721 | } |
| 13722 | return TRUE; |
| 13723 | } |
| 13724 | |
| 13725 | |
| 13726 | /** |
| 13727 | Eliminate row equalities and form multiple equalities predicates. |
| 13728 | |
| 13729 | This function checks whether the item is a simple equality |
| 13730 | i.e. the one that equates a field with another field or a constant |
| 13731 | (field=field_item or field=constant_item), or, a row equality. |
| 13732 | For a simple equality the function looks for a multiple equality |
| 13733 | in the lists referenced directly or indirectly by cond_equal inferring |
| 13734 | the given simple equality. If it doesn't find any, it builds/expands |
| 13735 | multiple equality that covers the predicate. |
| 13736 | Row equalities are eliminated substituted for conjunctive regular |
| 13737 | equalities which are treated in the same way as original equality |
| 13738 | predicates. |
| 13739 | |
| 13740 | @param thd thread handle |
| 13741 | @param item predicate to process |
| 13742 | @param cond_equal multiple equalities that must hold together with the |
| 13743 | predicate |
| 13744 | @param eq_list results of conversions of row equalities that are not |
| 13745 | simple enough to form multiple equalities |
| 13746 | |
| 13747 | @retval |
| 13748 | TRUE if re-writing rules have been applied |
| 13749 | @retval |
| 13750 | FALSE otherwise, i.e. |
| 13751 | if the predicate is not an equality, |
| 13752 | or, if the equality is neither a simple one nor a row equality, |
| 13753 | or, if the procedure fails by a fatal error. |
| 13754 | */ |
| 13755 | |
| 13756 | bool Item_func_eq::check_equality(THD *thd, COND_EQUAL *cond_equal, |
| 13757 | List<Item> *eq_list) |
| 13758 | { |
| 13759 | Item *left_item= arguments()[0]; |
| 13760 | Item *right_item= arguments()[1]; |
| 13761 | |
| 13762 | if (left_item->type() == Item::ROW_ITEM && |
| 13763 | right_item->type() == Item::ROW_ITEM) |
| 13764 | { |
| 13765 | /* |
| 13766 | Item_splocal::type() for ROW variables returns Item::ROW_ITEM. |
| 13767 | Distinguish ROW-type Item_splocal from Item_row. |
| 13768 | Example query: |
| 13769 | SELECT 1 FROM DUAL WHERE row_sp_variable=ROW(100,200); |
| 13770 | */ |
| 13771 | if (left_item->get_item_splocal() || |
| 13772 | right_item->get_item_splocal()) |
| 13773 | return false; |
| 13774 | return check_row_equality(thd, |
| 13775 | cmp.subcomparators(), |
| 13776 | (Item_row *) left_item, |
| 13777 | (Item_row *) right_item, |
| 13778 | cond_equal, eq_list); |
| 13779 | } |
| 13780 | return check_simple_equality(thd, |
| 13781 | Context(ANY_SUBST, |
| 13782 | compare_type_handler(), |
| 13783 | compare_collation()), |
| 13784 | left_item, right_item, cond_equal); |
| 13785 | } |
| 13786 | |
| 13787 | |
| 13788 | /** |
| 13789 | Item_xxx::build_equal_items() |
| 13790 | |
| 13791 | Replace all equality predicates in a condition referenced by "this" |
| 13792 | by multiple equality items. |
| 13793 | |
| 13794 | At each 'and' level the function detects items for equality predicates |
| 13795 | and replaced them by a set of multiple equality items of class Item_equal, |
| 13796 | taking into account inherited equalities from upper levels. |
| 13797 | If an equality predicate is used not in a conjunction it's just |
| 13798 | replaced by a multiple equality predicate. |
| 13799 | For each 'and' level the function set a pointer to the inherited |
| 13800 | multiple equalities in the cond_equal field of the associated |
| 13801 | object of the type Item_cond_and. |
| 13802 | The function also traverses the cond tree and and for each field reference |
| 13803 | sets a pointer to the multiple equality item containing the field, if there |
| 13804 | is any. If this multiple equality equates fields to a constant the |
| 13805 | function replaces the field reference by the constant in the cases |
| 13806 | when the field is not of a string type or when the field reference is |
| 13807 | just an argument of a comparison predicate. |
| 13808 | The function also determines the maximum number of members in |
| 13809 | equality lists of each Item_cond_and object assigning it to |
| 13810 | thd->lex->current_select->max_equal_elems. |
| 13811 | |
| 13812 | @note |
| 13813 | Multiple equality predicate =(f1,..fn) is equivalent to the conjuction of |
| 13814 | f1=f2, .., fn-1=fn. It substitutes any inference from these |
| 13815 | equality predicates that is equivalent to the conjunction. |
| 13816 | Thus, =(a1,a2,a3) can substitute for ((a1=a3) AND (a2=a3) AND (a2=a1)) as |
| 13817 | it is equivalent to ((a1=a2) AND (a2=a3)). |
| 13818 | The function always makes a substitution of all equality predicates occurred |
| 13819 | in a conjuction for a minimal set of multiple equality predicates. |
| 13820 | This set can be considered as a canonical representation of the |
| 13821 | sub-conjunction of the equality predicates. |
| 13822 | E.g. (t1.a=t2.b AND t2.b>5 AND t1.a=t3.c) is replaced by |
| 13823 | (=(t1.a,t2.b,t3.c) AND t2.b>5), not by |
| 13824 | (=(t1.a,t2.b) AND =(t1.a,t3.c) AND t2.b>5); |
| 13825 | while (t1.a=t2.b AND t2.b>5 AND t3.c=t4.d) is replaced by |
| 13826 | (=(t1.a,t2.b) AND =(t3.c=t4.d) AND t2.b>5), |
| 13827 | but if additionally =(t4.d,t2.b) is inherited, it |
| 13828 | will be replaced by (=(t1.a,t2.b,t3.c,t4.d) AND t2.b>5) |
| 13829 | |
| 13830 | The function performs the substitution in a recursive descent by |
| 13831 | the condtion tree, passing to the next AND level a chain of multiple |
| 13832 | equality predicates which have been built at the upper levels. |
| 13833 | The Item_equal items built at the level are attached to other |
| 13834 | non-equality conjucts as a sublist. The pointer to the inherited |
| 13835 | multiple equalities is saved in the and condition object (Item_cond_and). |
| 13836 | This chain allows us for any field reference occurence easyly to find a |
| 13837 | multiple equality that must be held for this occurence. |
| 13838 | For each AND level we do the following: |
| 13839 | - scan it for all equality predicate (=) items |
| 13840 | - join them into disjoint Item_equal() groups |
| 13841 | - process the included OR conditions recursively to do the same for |
| 13842 | lower AND levels. |
| 13843 | |
| 13844 | We need to do things in this order as lower AND levels need to know about |
| 13845 | all possible Item_equal objects in upper levels. |
| 13846 | |
| 13847 | @param thd thread handle |
| 13848 | @param inherited path to all inherited multiple equality items |
| 13849 | |
| 13850 | @return |
| 13851 | pointer to the transformed condition, |
| 13852 | whose Used_tables_and_const_cache is up to date, |
| 13853 | so no additional update_used_tables() is needed on the result. |
| 13854 | */ |
| 13855 | |
| 13856 | COND *Item_cond_and::build_equal_items(THD *thd, |
| 13857 | COND_EQUAL *inherited, |
| 13858 | bool link_item_fields, |
| 13859 | COND_EQUAL **cond_equal_ref) |
| 13860 | { |
| 13861 | Item_equal *item_equal; |
| 13862 | COND_EQUAL cond_equal; |
| 13863 | cond_equal.upper_levels= inherited; |
| 13864 | |
| 13865 | if (check_stack_overrun(thd, STACK_MIN_SIZE, NULL)) |
| 13866 | return this; // Fatal error flag is set! |
| 13867 | |
| 13868 | List<Item> eq_list; |
| 13869 | List<Item> *cond_args= argument_list(); |
| 13870 | |
| 13871 | List_iterator<Item> li(*cond_args); |
| 13872 | Item *item; |
| 13873 | |
| 13874 | DBUG_ASSERT(!cond_equal_ref || !cond_equal_ref[0]); |
| 13875 | /* |
| 13876 | Retrieve all conjuncts of this level detecting the equality |
| 13877 | that are subject to substitution by multiple equality items and |
| 13878 | removing each such predicate from the conjunction after having |
| 13879 | found/created a multiple equality whose inference the predicate is. |
| 13880 | */ |
| 13881 | while ((item= li++)) |
| 13882 | { |
| 13883 | /* |
| 13884 | PS/SP note: we can safely remove a node from AND-OR |
| 13885 | structure here because it's restored before each |
| 13886 | re-execution of any prepared statement/stored procedure. |
| 13887 | */ |
| 13888 | if (item->check_equality(thd, &cond_equal, &eq_list)) |
| 13889 | li.remove(); |
| 13890 | } |
| 13891 | |
| 13892 | /* |
| 13893 | Check if we eliminated all the predicates of the level, e.g. |
| 13894 | (a=a AND b=b AND a=a). |
| 13895 | */ |
| 13896 | if (!cond_args->elements && |
| 13897 | !cond_equal.current_level.elements && |
| 13898 | !eq_list.elements) |
| 13899 | return new (thd->mem_root) Item_int(thd, (longlong) 1, 1); |
| 13900 | |
| 13901 | List_iterator_fast<Item_equal> it(cond_equal.current_level); |
| 13902 | while ((item_equal= it++)) |
| 13903 | { |
| 13904 | item_equal->set_link_equal_fields(link_item_fields); |
| 13905 | item_equal->fix_fields(thd, NULL); |
| 13906 | item_equal->update_used_tables(); |
| 13907 | set_if_bigger(thd->lex->current_select->max_equal_elems, |
| 13908 | item_equal->n_field_items()); |
| 13909 | } |
| 13910 | |
| 13911 | m_cond_equal.copy(cond_equal); |
| 13912 | cond_equal.current_level= m_cond_equal.current_level; |
| 13913 | inherited= &m_cond_equal; |
| 13914 | |
| 13915 | /* |
| 13916 | Make replacement of equality predicates for lower levels |
| 13917 | of the condition expression. |
| 13918 | */ |
| 13919 | li.rewind(); |
| 13920 | while ((item= li++)) |
| 13921 | { |
| 13922 | Item *new_item; |
| 13923 | if ((new_item= item->build_equal_items(thd, inherited, false, NULL)) |
| 13924 | != item) |
| 13925 | { |
| 13926 | /* This replacement happens only for standalone equalities */ |
| 13927 | /* |
| 13928 | This is ok with PS/SP as the replacement is done for |
| 13929 | cond_args of an AND/OR item, which are restored for each |
| 13930 | execution of PS/SP. |
| 13931 | */ |
| 13932 | li.replace(new_item); |
| 13933 | } |
| 13934 | } |
| 13935 | cond_args->append(&eq_list); |
| 13936 | cond_args->append((List<Item> *)&cond_equal.current_level); |
| 13937 | update_used_tables(); |
| 13938 | if (cond_equal_ref) |
| 13939 | *cond_equal_ref= &m_cond_equal; |
| 13940 | return this; |
| 13941 | } |
| 13942 | |
| 13943 | |
| 13944 | COND *Item_cond::build_equal_items(THD *thd, |
| 13945 | COND_EQUAL *inherited, |
| 13946 | bool link_item_fields, |
| 13947 | COND_EQUAL **cond_equal_ref) |
| 13948 | { |
| 13949 | List<Item> *cond_args= argument_list(); |
| 13950 | |
| 13951 | List_iterator<Item> li(*cond_args); |
| 13952 | Item *item; |
| 13953 | |
| 13954 | DBUG_ASSERT(!cond_equal_ref || !cond_equal_ref[0]); |
| 13955 | /* |
| 13956 | Make replacement of equality predicates for lower levels |
| 13957 | of the condition expression. |
| 13958 | Update used_tables_cache and const_item_cache on the way. |
| 13959 | */ |
| 13960 | used_tables_and_const_cache_init(); |
| 13961 | while ((item= li++)) |
| 13962 | { |
| 13963 | Item *new_item; |
| 13964 | if ((new_item= item->build_equal_items(thd, inherited, false, NULL)) |
| 13965 | != item) |
| 13966 | { |
| 13967 | /* This replacement happens only for standalone equalities */ |
| 13968 | /* |
| 13969 | This is ok with PS/SP as the replacement is done for |
| 13970 | arguments of an AND/OR item, which are restored for each |
| 13971 | execution of PS/SP. |
| 13972 | */ |
| 13973 | li.replace(new_item); |
| 13974 | } |
| 13975 | used_tables_and_const_cache_join(new_item); |
| 13976 | } |
| 13977 | return this; |
| 13978 | } |
| 13979 | |
| 13980 | |
| 13981 | COND *Item_func_eq::build_equal_items(THD *thd, |
| 13982 | COND_EQUAL *inherited, |
| 13983 | bool link_item_fields, |
| 13984 | COND_EQUAL **cond_equal_ref) |
| 13985 | { |
| 13986 | COND_EQUAL cond_equal; |
| 13987 | cond_equal.upper_levels= inherited; |
| 13988 | List<Item> eq_list; |
| 13989 | |
| 13990 | DBUG_ASSERT(!cond_equal_ref || !cond_equal_ref[0]); |
| 13991 | /* |
| 13992 | If an equality predicate forms the whole and level, |
| 13993 | we call it standalone equality and it's processed here. |
| 13994 | E.g. in the following where condition |
| 13995 | WHERE a=5 AND (b=5 or a=c) |
| 13996 | (b=5) and (a=c) are standalone equalities. |
| 13997 | In general we can't leave alone standalone eqalities: |
| 13998 | for WHERE a=b AND c=d AND (b=c OR d=5) |
| 13999 | b=c is replaced by =(a,b,c,d). |
| 14000 | */ |
| 14001 | if (Item_func_eq::check_equality(thd, &cond_equal, &eq_list)) |
| 14002 | { |
| 14003 | Item_equal *item_equal; |
| 14004 | int n= cond_equal.current_level.elements + eq_list.elements; |
| 14005 | if (n == 0) |
| 14006 | return new (thd->mem_root) Item_int(thd, (longlong) 1, 1); |
| 14007 | else if (n == 1) |
| 14008 | { |
| 14009 | if ((item_equal= cond_equal.current_level.pop())) |
| 14010 | { |
| 14011 | item_equal->fix_fields(thd, NULL); |
| 14012 | item_equal->update_used_tables(); |
| 14013 | set_if_bigger(thd->lex->current_select->max_equal_elems, |
| 14014 | item_equal->n_field_items()); |
| 14015 | item_equal->upper_levels= inherited; |
| 14016 | if (cond_equal_ref) |
| 14017 | *cond_equal_ref= new (thd->mem_root) COND_EQUAL(item_equal, |
| 14018 | thd->mem_root); |
| 14019 | return item_equal; |
| 14020 | } |
| 14021 | Item *res= eq_list.pop(); |
| 14022 | res->update_used_tables(); |
| 14023 | DBUG_ASSERT(res->type() == FUNC_ITEM); |
| 14024 | return res; |
| 14025 | } |
| 14026 | else |
| 14027 | { |
| 14028 | /* |
| 14029 | Here a new AND level must be created. It can happen only |
| 14030 | when a row equality is processed as a standalone predicate. |
| 14031 | */ |
| 14032 | Item_cond_and *and_cond= new (thd->mem_root) Item_cond_and(thd, eq_list); |
| 14033 | and_cond->quick_fix_field(); |
| 14034 | List<Item> *cond_args= and_cond->argument_list(); |
| 14035 | List_iterator_fast<Item_equal> it(cond_equal.current_level); |
| 14036 | while ((item_equal= it++)) |
| 14037 | { |
| 14038 | item_equal->fix_length_and_dec(); |
| 14039 | item_equal->update_used_tables(); |
| 14040 | set_if_bigger(thd->lex->current_select->max_equal_elems, |
| 14041 | item_equal->n_field_items()); |
| 14042 | } |
| 14043 | and_cond->m_cond_equal.copy(cond_equal); |
| 14044 | cond_equal.current_level= and_cond->m_cond_equal.current_level; |
| 14045 | cond_args->append((List<Item> *)&cond_equal.current_level); |
| 14046 | and_cond->update_used_tables(); |
| 14047 | if (cond_equal_ref) |
| 14048 | *cond_equal_ref= &and_cond->m_cond_equal; |
| 14049 | return and_cond; |
| 14050 | } |
| 14051 | } |
| 14052 | return Item_func::build_equal_items(thd, inherited, link_item_fields, |
| 14053 | cond_equal_ref); |
| 14054 | } |
| 14055 | |
| 14056 | |
| 14057 | COND *Item_func::build_equal_items(THD *thd, COND_EQUAL *inherited, |
| 14058 | bool link_item_fields, |
| 14059 | COND_EQUAL **cond_equal_ref) |
| 14060 | { |
| 14061 | /* |
| 14062 | For each field reference in cond, not from equal item predicates, |
| 14063 | set a pointer to the multiple equality it belongs to (if there is any) |
| 14064 | as soon the field is not of a string type or the field reference is |
| 14065 | an argument of a comparison predicate. |
| 14066 | */ |
| 14067 | COND *cond= propagate_equal_fields(thd, Context_boolean(), inherited); |
| 14068 | cond->update_used_tables(); |
| 14069 | DBUG_ASSERT(cond == this); |
| 14070 | DBUG_ASSERT(!cond_equal_ref || !cond_equal_ref[0]); |
| 14071 | return cond; |
| 14072 | } |
| 14073 | |
| 14074 | |
| 14075 | COND *Item_equal::build_equal_items(THD *thd, COND_EQUAL *inherited, |
| 14076 | bool link_item_fields, |
| 14077 | COND_EQUAL **cond_equal_ref) |
| 14078 | { |
| 14079 | COND *cond= Item_func::build_equal_items(thd, inherited, link_item_fields, |
| 14080 | cond_equal_ref); |
| 14081 | if (cond_equal_ref) |
| 14082 | *cond_equal_ref= new (thd->mem_root) COND_EQUAL(this, thd->mem_root); |
| 14083 | return cond; |
| 14084 | } |
| 14085 | |
| 14086 | |
| 14087 | /** |
| 14088 | Build multiple equalities for a condition and all on expressions that |
| 14089 | inherit these multiple equalities. |
| 14090 | |
| 14091 | The function first applies the cond->build_equal_items() method |
| 14092 | to build all multiple equalities for condition cond utilizing equalities |
| 14093 | referred through the parameter inherited. The extended set of |
| 14094 | equalities is returned in the structure referred by the cond_equal_ref |
| 14095 | parameter. After this the function calls itself recursively for |
| 14096 | all on expressions whose direct references can be found in join_list |
| 14097 | and who inherit directly the multiple equalities just having built. |
| 14098 | |
| 14099 | @note |
| 14100 | The on expression used in an outer join operation inherits all equalities |
| 14101 | from the on expression of the embedding join, if there is any, or |
| 14102 | otherwise - from the where condition. |
| 14103 | This fact is not obvious, but presumably can be proved. |
| 14104 | Consider the following query: |
| 14105 | @code |
| 14106 | SELECT * FROM (t1,t2) LEFT JOIN (t3,t4) ON t1.a=t3.a AND t2.a=t4.a |
| 14107 | WHERE t1.a=t2.a; |
| 14108 | @endcode |
| 14109 | If the on expression in the query inherits =(t1.a,t2.a), then we |
| 14110 | can build the multiple equality =(t1.a,t2.a,t3.a,t4.a) that infers |
| 14111 | the equality t3.a=t4.a. Although the on expression |
| 14112 | t1.a=t3.a AND t2.a=t4.a AND t3.a=t4.a is not equivalent to the one |
| 14113 | in the query the latter can be replaced by the former: the new query |
| 14114 | will return the same result set as the original one. |
| 14115 | |
| 14116 | Interesting that multiple equality =(t1.a,t2.a,t3.a,t4.a) allows us |
| 14117 | to use t1.a=t3.a AND t3.a=t4.a under the on condition: |
| 14118 | @code |
| 14119 | SELECT * FROM (t1,t2) LEFT JOIN (t3,t4) ON t1.a=t3.a AND t3.a=t4.a |
| 14120 | WHERE t1.a=t2.a |
| 14121 | @endcode |
| 14122 | This query equivalent to: |
| 14123 | @code |
| 14124 | SELECT * FROM (t1 LEFT JOIN (t3,t4) ON t1.a=t3.a AND t3.a=t4.a),t2 |
| 14125 | WHERE t1.a=t2.a |
| 14126 | @endcode |
| 14127 | Similarly the original query can be rewritten to the query: |
| 14128 | @code |
| 14129 | SELECT * FROM (t1,t2) LEFT JOIN (t3,t4) ON t2.a=t4.a AND t3.a=t4.a |
| 14130 | WHERE t1.a=t2.a |
| 14131 | @endcode |
| 14132 | that is equivalent to: |
| 14133 | @code |
| 14134 | SELECT * FROM (t2 LEFT JOIN (t3,t4)ON t2.a=t4.a AND t3.a=t4.a), t1 |
| 14135 | WHERE t1.a=t2.a |
| 14136 | @endcode |
| 14137 | Thus, applying equalities from the where condition we basically |
| 14138 | can get more freedom in performing join operations. |
| 14139 | Although we don't use this property now, it probably makes sense to use |
| 14140 | it in the future. |
| 14141 | @param thd Thread handler |
| 14142 | @param cond condition to build the multiple equalities for |
| 14143 | @param inherited path to all inherited multiple equality items |
| 14144 | @param join_list list of join tables to which the condition |
| 14145 | refers to |
| 14146 | @ignore_on_conds TRUE <-> do not build multiple equalities |
| 14147 | for on expressions |
| 14148 | @param[out] cond_equal_ref pointer to the structure to place built |
| 14149 | equalities in |
| 14150 | @param link_equal_items equal fields are to be linked |
| 14151 | |
| 14152 | @return |
| 14153 | pointer to the transformed condition containing multiple equalities |
| 14154 | */ |
| 14155 | |
| 14156 | static COND *build_equal_items(JOIN *join, COND *cond, |
| 14157 | COND_EQUAL *inherited, |
| 14158 | List<TABLE_LIST> *join_list, |
| 14159 | bool ignore_on_conds, |
| 14160 | COND_EQUAL **cond_equal_ref, |
| 14161 | bool link_equal_fields) |
| 14162 | { |
| 14163 | THD *thd= join->thd; |
| 14164 | |
| 14165 | *cond_equal_ref= NULL; |
| 14166 | |
| 14167 | if (cond) |
| 14168 | { |
| 14169 | cond= cond->build_equal_items(thd, inherited, link_equal_fields, |
| 14170 | cond_equal_ref); |
| 14171 | if (*cond_equal_ref) |
| 14172 | { |
| 14173 | (*cond_equal_ref)->upper_levels= inherited; |
| 14174 | inherited= *cond_equal_ref; |
| 14175 | } |
| 14176 | } |
| 14177 | |
| 14178 | if (join_list && !ignore_on_conds) |
| 14179 | { |
| 14180 | TABLE_LIST *table; |
| 14181 | List_iterator<TABLE_LIST> li(*join_list); |
| 14182 | |
| 14183 | while ((table= li++)) |
| 14184 | { |
| 14185 | if (table->on_expr) |
| 14186 | { |
| 14187 | List<TABLE_LIST> *nested_join_list= table->nested_join ? |
| 14188 | &table->nested_join->join_list : NULL; |
| 14189 | /* |
| 14190 | We can modify table->on_expr because its old value will |
| 14191 | be restored before re-execution of PS/SP. |
| 14192 | */ |
| 14193 | table->on_expr= build_equal_items(join, table->on_expr, inherited, |
| 14194 | nested_join_list, ignore_on_conds, |
| 14195 | &table->cond_equal); |
| 14196 | } |
| 14197 | } |
| 14198 | } |
| 14199 | |
| 14200 | return cond; |
| 14201 | } |
| 14202 | |
| 14203 | |
| 14204 | /** |
| 14205 | Compare field items by table order in the execution plan. |
| 14206 | |
| 14207 | If field1 and field2 belong to different tables then |
| 14208 | field1 considered as better than field2 if the table containing |
| 14209 | field1 is accessed earlier than the table containing field2. |
| 14210 | The function finds out what of two fields is better according |
| 14211 | this criteria. |
| 14212 | If field1 and field2 belong to the same table then the result |
| 14213 | of comparison depends on whether the fields are parts of |
| 14214 | the key that are used to access this table. |
| 14215 | |
| 14216 | @param field1 first field item to compare |
| 14217 | @param field2 second field item to compare |
| 14218 | @param table_join_idx index to tables determining table order |
| 14219 | |
| 14220 | @retval |
| 14221 | 1 if field1 is better than field2 |
| 14222 | @retval |
| 14223 | -1 if field2 is better than field1 |
| 14224 | @retval |
| 14225 | 0 otherwise |
| 14226 | */ |
| 14227 | |
| 14228 | static int compare_fields_by_table_order(Item *field1, |
| 14229 | Item *field2, |
| 14230 | void *table_join_idx) |
| 14231 | { |
| 14232 | int cmp= 0; |
| 14233 | bool outer_ref= 0; |
| 14234 | Item_field *f1= (Item_field *) (field1->real_item()); |
| 14235 | Item_field *f2= (Item_field *) (field2->real_item()); |
| 14236 | if (field1->const_item() || f1->const_item()) |
| 14237 | return -1; |
| 14238 | if (field2->const_item() || f2->const_item()) |
| 14239 | return 1; |
| 14240 | if (f1->used_tables() & OUTER_REF_TABLE_BIT) |
| 14241 | { |
| 14242 | outer_ref= 1; |
| 14243 | cmp= -1; |
| 14244 | } |
| 14245 | if (f2->used_tables() & OUTER_REF_TABLE_BIT) |
| 14246 | { |
| 14247 | outer_ref= 1; |
| 14248 | cmp++; |
| 14249 | } |
| 14250 | if (outer_ref) |
| 14251 | return cmp; |
| 14252 | JOIN_TAB **idx= (JOIN_TAB **) table_join_idx; |
| 14253 | |
| 14254 | JOIN_TAB *tab1= idx[f1->field->table->tablenr]; |
| 14255 | JOIN_TAB *tab2= idx[f2->field->table->tablenr]; |
| 14256 | |
| 14257 | /* |
| 14258 | if one of the table is inside a merged SJM nest and another one isn't, |
| 14259 | compare SJM bush roots of the tables. |
| 14260 | */ |
| 14261 | if (tab1->bush_root_tab != tab2->bush_root_tab) |
| 14262 | { |
| 14263 | if (tab1->bush_root_tab) |
| 14264 | tab1= tab1->bush_root_tab; |
| 14265 | |
| 14266 | if (tab2->bush_root_tab) |
| 14267 | tab2= tab2->bush_root_tab; |
| 14268 | } |
| 14269 | |
| 14270 | cmp= (int)(tab1 - tab2); |
| 14271 | |
| 14272 | if (!cmp) |
| 14273 | { |
| 14274 | /* Fields f1, f2 belong to the same table */ |
| 14275 | |
| 14276 | JOIN_TAB *tab= idx[f1->field->table->tablenr]; |
| 14277 | uint keyno= MAX_KEY; |
| 14278 | if (tab->ref.key_parts) |
| 14279 | keyno= tab->ref.key; |
| 14280 | else if (tab->select && tab->select->quick) |
| 14281 | keyno = tab->select->quick->index; |
| 14282 | if (keyno != MAX_KEY) |
| 14283 | { |
| 14284 | if (f1->field->part_of_key.is_set(keyno)) |
| 14285 | cmp= -1; |
| 14286 | if (f2->field->part_of_key.is_set(keyno)) |
| 14287 | cmp++; |
| 14288 | /* |
| 14289 | Here: |
| 14290 | if both f1, f2 are components of the key tab->ref.key then cmp==0, |
| 14291 | if only f1 is a component of the key then cmp==-1 (f1 is better), |
| 14292 | if only f2 is a component of the key then cmp==1, (f2 is better), |
| 14293 | if none of f1,f1 is component of the key cmp==0. |
| 14294 | */ |
| 14295 | if (!cmp) |
| 14296 | { |
| 14297 | KEY *key_info= tab->table->key_info + keyno; |
| 14298 | for (uint i= 0; i < key_info->user_defined_key_parts; i++) |
| 14299 | { |
| 14300 | Field *fld= key_info->key_part[i].field; |
| 14301 | if (fld->eq(f1->field)) |
| 14302 | { |
| 14303 | cmp= -1; // f1 is better |
| 14304 | break; |
| 14305 | } |
| 14306 | if (fld->eq(f2->field)) |
| 14307 | { |
| 14308 | cmp= 1; // f2 is better |
| 14309 | break; |
| 14310 | } |
| 14311 | } |
| 14312 | } |
| 14313 | } |
| 14314 | if (!cmp) |
| 14315 | cmp= f1->field->field_index-f2->field->field_index; |
| 14316 | } |
| 14317 | return cmp < 0 ? -1 : (cmp ? 1 : 0); |
| 14318 | } |
| 14319 | |
| 14320 | |
| 14321 | static TABLE_LIST* embedding_sjm(Item *item) |
| 14322 | { |
| 14323 | Item_field *item_field= (Item_field *) (item->real_item()); |
| 14324 | TABLE_LIST *nest= item_field->field->table->pos_in_table_list->embedding; |
| 14325 | if (nest && nest->sj_mat_info && nest->sj_mat_info->is_used) |
| 14326 | return nest; |
| 14327 | else |
| 14328 | return NULL; |
| 14329 | } |
| 14330 | |
| 14331 | /** |
| 14332 | Generate minimal set of simple equalities equivalent to a multiple equality. |
| 14333 | |
| 14334 | The function retrieves the fields of the multiple equality item |
| 14335 | item_equal and for each field f: |
| 14336 | - if item_equal contains const it generates the equality f=const_item; |
| 14337 | - otherwise, if f is not the first field, generates the equality |
| 14338 | f=item_equal->get_first(). |
| 14339 | All generated equality are added to the cond conjunction. |
| 14340 | |
| 14341 | @param cond condition to add the generated equality to |
| 14342 | @param upper_levels structure to access multiple equality of upper levels |
| 14343 | @param item_equal multiple equality to generate simple equality from |
| 14344 | |
| 14345 | @note |
| 14346 | Before generating an equality function checks that it has not |
| 14347 | been generated for multiple equalities of the upper levels. |
| 14348 | E.g. for the following where condition |
| 14349 | WHERE a=5 AND ((a=b AND b=c) OR c>4) |
| 14350 | the upper level AND condition will contain =(5,a), |
| 14351 | while the lower level AND condition will contain =(5,a,b,c). |
| 14352 | When splitting =(5,a,b,c) into a separate equality predicates |
| 14353 | we should omit 5=a, as we have it already in the upper level. |
| 14354 | The following where condition gives us a more complicated case: |
| 14355 | WHERE t1.a=t2.b AND t3.c=t4.d AND (t2.b=t3.c OR t4.e>5 ...) AND ... |
| 14356 | Given the tables are accessed in the order t1->t2->t3->t4 for |
| 14357 | the selected query execution plan the lower level multiple |
| 14358 | equality =(t1.a,t2.b,t3.c,t4.d) formally should be converted to |
| 14359 | t1.a=t2.b AND t1.a=t3.c AND t1.a=t4.d. But t1.a=t2.a will be |
| 14360 | generated for the upper level. Also t3.c=t4.d will be generated there. |
| 14361 | So only t1.a=t3.c should be left in the lower level. |
| 14362 | If cond is equal to 0, then not more then one equality is generated |
| 14363 | and a pointer to it is returned as the result of the function. |
| 14364 | |
| 14365 | Equality substutution and semi-join materialization nests: |
| 14366 | |
| 14367 | In case join order looks like this: |
| 14368 | |
| 14369 | outer_tbl1 outer_tbl2 SJM (inner_tbl1 inner_tbl2) outer_tbl3 |
| 14370 | |
| 14371 | We must not construct equalities like |
| 14372 | |
| 14373 | outer_tbl1.col = inner_tbl1.col |
| 14374 | |
| 14375 | because they would get attached to inner_tbl1 and will get evaluated |
| 14376 | during materialization phase, when we don't have current value of |
| 14377 | outer_tbl1.col. |
| 14378 | |
| 14379 | Item_equal::get_first() also takes similar measures for dealing with |
| 14380 | equality substitution in presense of SJM nests. |
| 14381 | |
| 14382 | Grep for EqualityPropagationAndSjmNests for a more verbose description. |
| 14383 | |
| 14384 | @return |
| 14385 | - The condition with generated simple equalities or |
| 14386 | a pointer to the simple generated equality, if success. |
| 14387 | - 0, otherwise. |
| 14388 | */ |
| 14389 | |
| 14390 | Item *eliminate_item_equal(THD *thd, COND *cond, COND_EQUAL *upper_levels, |
| 14391 | Item_equal *item_equal) |
| 14392 | { |
| 14393 | List<Item> eq_list; |
| 14394 | Item_func_eq *eq_item= 0; |
| 14395 | if (((Item *) item_equal)->const_item() && !item_equal->val_int()) |
| 14396 | return new (thd->mem_root) Item_int(thd, (longlong) 0, 1); |
| 14397 | Item *item_const= item_equal->get_const(); |
| 14398 | Item_equal_fields_iterator it(*item_equal); |
| 14399 | Item *head; |
| 14400 | TABLE_LIST *current_sjm= NULL; |
| 14401 | Item *current_sjm_head= NULL; |
| 14402 | |
| 14403 | DBUG_ASSERT(!cond || |
| 14404 | cond->type() == Item::INT_ITEM || |
| 14405 | (cond->type() == Item::FUNC_ITEM && |
| 14406 | ((Item_func *) cond)->functype() == Item_func::EQ_FUNC) || |
| 14407 | (cond->type() == Item::COND_ITEM && |
| 14408 | ((Item_func *) cond)->functype() == Item_func::COND_AND_FUNC)); |
| 14409 | |
| 14410 | /* |
| 14411 | Pick the "head" item: the constant one or the first in the join order |
| 14412 | (if the first in the join order happends to be inside an SJM nest, that's |
| 14413 | ok, because this is where the value will be unpacked after |
| 14414 | materialization). |
| 14415 | */ |
| 14416 | if (item_const) |
| 14417 | head= item_const; |
| 14418 | else |
| 14419 | { |
| 14420 | TABLE_LIST *emb_nest; |
| 14421 | head= item_equal->get_first(NO_PARTICULAR_TAB, NULL); |
| 14422 | it++; |
| 14423 | if ((emb_nest= embedding_sjm(head))) |
| 14424 | { |
| 14425 | current_sjm= emb_nest; |
| 14426 | current_sjm_head= head; |
| 14427 | } |
| 14428 | } |
| 14429 | |
| 14430 | Item *field_item; |
| 14431 | /* |
| 14432 | For each other item, generate "item=head" equality (except the tables that |
| 14433 | are within SJ-Materialization nests, for those "head" is defined |
| 14434 | differently) |
| 14435 | */ |
| 14436 | while ((field_item= it++)) |
| 14437 | { |
| 14438 | Item_equal *upper= field_item->find_item_equal(upper_levels); |
| 14439 | Item *item= field_item; |
| 14440 | TABLE_LIST *field_sjm= embedding_sjm(field_item); |
| 14441 | if (!field_sjm) |
| 14442 | { |
| 14443 | current_sjm= NULL; |
| 14444 | current_sjm_head= NULL; |
| 14445 | } |
| 14446 | |
| 14447 | /* |
| 14448 | Check if "field_item=head" equality is already guaranteed to be true |
| 14449 | on upper AND-levels. |
| 14450 | */ |
| 14451 | if (upper) |
| 14452 | { |
| 14453 | TABLE_LIST *native_sjm= embedding_sjm(item_equal->context_field); |
| 14454 | Item *upper_const= upper->get_const(); |
| 14455 | if (item_const && upper_const) |
| 14456 | { |
| 14457 | /* |
| 14458 | Upper item also has "field_item=const". |
| 14459 | Don't produce equality if const is equal to item_const. |
| 14460 | */ |
| 14461 | Item_func_eq *func= new (thd->mem_root) Item_func_eq(thd, item_const, upper_const); |
| 14462 | func->set_cmp_func(); |
| 14463 | func->quick_fix_field(); |
| 14464 | if (func->val_int()) |
| 14465 | item= 0; |
| 14466 | } |
| 14467 | else |
| 14468 | { |
| 14469 | Item_equal_fields_iterator li(*item_equal); |
| 14470 | while ((item= li++) != field_item) |
| 14471 | { |
| 14472 | if (embedding_sjm(item) == field_sjm && |
| 14473 | item->find_item_equal(upper_levels) == upper) |
| 14474 | break; |
| 14475 | } |
| 14476 | } |
| 14477 | if (embedding_sjm(field_item) != native_sjm) |
| 14478 | item= NULL; /* Don't produce equality */ |
| 14479 | } |
| 14480 | |
| 14481 | bool produce_equality= MY_TEST(item == field_item); |
| 14482 | if (!item_const && field_sjm && field_sjm != current_sjm) |
| 14483 | { |
| 14484 | /* Entering an SJM nest */ |
| 14485 | current_sjm_head= field_item; |
| 14486 | if (!field_sjm->sj_mat_info->is_sj_scan) |
| 14487 | produce_equality= FALSE; |
| 14488 | } |
| 14489 | |
| 14490 | if (produce_equality) |
| 14491 | { |
| 14492 | if (eq_item && eq_list.push_back(eq_item, thd->mem_root)) |
| 14493 | return 0; |
| 14494 | |
| 14495 | /* |
| 14496 | If we're inside an SJM-nest (current_sjm!=NULL), and the multi-equality |
| 14497 | doesn't include a constant, we should produce equality with the first |
| 14498 | of the equal items in this SJM (except for the first element inside the |
| 14499 | SJM. For that, we produce the equality with the "head" item). |
| 14500 | |
| 14501 | In other cases, get the "head" item, which is either first of the |
| 14502 | equals on top level, or the constant. |
| 14503 | */ |
| 14504 | Item *head_item= (!item_const && current_sjm && |
| 14505 | current_sjm_head != field_item) ? current_sjm_head: head; |
| 14506 | Item *head_real_item= head_item->real_item(); |
| 14507 | if (head_real_item->type() == Item::FIELD_ITEM) |
| 14508 | head_item= head_real_item; |
| 14509 | |
| 14510 | eq_item= new (thd->mem_root) Item_func_eq(thd, field_item->real_item(), head_item); |
| 14511 | |
| 14512 | if (!eq_item || eq_item->set_cmp_func()) |
| 14513 | return 0; |
| 14514 | eq_item->quick_fix_field(); |
| 14515 | } |
| 14516 | current_sjm= field_sjm; |
| 14517 | } |
| 14518 | |
| 14519 | /* |
| 14520 | We have produced zero, one, or more pair-wise equalities eq_i. We want to |
| 14521 | return an expression in form: |
| 14522 | |
| 14523 | cond AND eq_1 AND eq_2 AND eq_3 AND ... |
| 14524 | |
| 14525 | 'cond' is a parameter for this function, which may be NULL, an Item_int(1), |
| 14526 | or an Item_func_eq or an Item_cond_and. |
| 14527 | |
| 14528 | We want to return a well-formed condition: no nested Item_cond_and objects, |
| 14529 | or Item_cond_and with a single child: |
| 14530 | - if 'cond' is an Item_cond_and, we add eq_i as its tail |
| 14531 | - if 'cond' is Item_int(1), we return eq_i |
| 14532 | - otherwise, we create our own Item_cond_and and put 'cond' at the front of |
| 14533 | it. |
| 14534 | - if we have only one condition to return, we don't create an Item_cond_and |
| 14535 | */ |
| 14536 | |
| 14537 | if (eq_item && eq_list.push_back(eq_item, thd->mem_root)) |
| 14538 | return 0; |
| 14539 | COND *res= 0; |
| 14540 | switch (eq_list.elements) |
| 14541 | { |
| 14542 | case 0: |
| 14543 | res= cond ? cond : new (thd->mem_root) Item_int(thd, (longlong) 1, 1); |
| 14544 | break; |
| 14545 | case 1: |
| 14546 | if (!cond || cond->type() == Item::INT_ITEM) |
| 14547 | res= eq_item; |
| 14548 | break; |
| 14549 | default: |
| 14550 | break; |
| 14551 | } |
| 14552 | if (!res) |
| 14553 | { |
| 14554 | if (cond) |
| 14555 | { |
| 14556 | if (cond->type() == Item::COND_ITEM) |
| 14557 | { |
| 14558 | res= cond; |
| 14559 | ((Item_cond *) res)->add_at_end(&eq_list); |
| 14560 | } |
| 14561 | else if (eq_list.push_front(cond, thd->mem_root)) |
| 14562 | return 0; |
| 14563 | } |
| 14564 | } |
| 14565 | if (!res) |
| 14566 | res= new (thd->mem_root) Item_cond_and(thd, eq_list); |
| 14567 | if (res) |
| 14568 | { |
| 14569 | res->quick_fix_field(); |
| 14570 | res->update_used_tables(); |
| 14571 | } |
| 14572 | |
| 14573 | return res; |
| 14574 | } |
| 14575 | |
| 14576 | |
| 14577 | /** |
| 14578 | Substitute every field reference in a condition by the best equal field |
| 14579 | and eliminate all multiple equality predicates. |
| 14580 | |
| 14581 | The function retrieves the cond condition and for each encountered |
| 14582 | multiple equality predicate it sorts the field references in it |
| 14583 | according to the order of tables specified by the table_join_idx |
| 14584 | parameter. Then it eliminates the multiple equality predicate it |
| 14585 | replacing it by the conjunction of simple equality predicates |
| 14586 | equating every field from the multiple equality to the first |
| 14587 | field in it, or to the constant, if there is any. |
| 14588 | After this the function retrieves all other conjuncted |
| 14589 | predicates substitute every field reference by the field reference |
| 14590 | to the first equal field or equal constant if there are any. |
| 14591 | |
| 14592 | @param context_tab Join tab that 'cond' will be attached to, or |
| 14593 | NO_PARTICULAR_TAB. See notes above. |
| 14594 | @param cond condition to process |
| 14595 | @param cond_equal multiple equalities to take into consideration |
| 14596 | @param table_join_idx index to tables determining field preference |
| 14597 | |
| 14598 | @note |
| 14599 | At the first glance full sort of fields in multiple equality |
| 14600 | seems to be an overkill. Yet it's not the case due to possible |
| 14601 | new fields in multiple equality item of lower levels. We want |
| 14602 | the order in them to comply with the order of upper levels. |
| 14603 | |
| 14604 | context_tab may be used to specify which join tab `cond` will be |
| 14605 | attached to. There are two possible cases: |
| 14606 | |
| 14607 | 1. context_tab != NO_PARTICULAR_TAB |
| 14608 | We're doing substitution for an Item which will be evaluated in the |
| 14609 | context of a particular item. For example, if the optimizer does a |
| 14610 | ref access on "tbl1.key= expr" then |
| 14611 | = equality substitution will be perfomed on 'expr' |
| 14612 | = it is known in advance that 'expr' will be evaluated when |
| 14613 | table t1 is accessed. |
| 14614 | Note that in this kind of substution we never have to replace Item_equal |
| 14615 | objects. For example, for |
| 14616 | |
| 14617 | t.key= func(col1=col2 AND col2=const) |
| 14618 | |
| 14619 | we will not build Item_equal or do equality substution (if we decide to, |
| 14620 | this function will need to be fixed to handle it) |
| 14621 | |
| 14622 | 2. context_tab == NO_PARTICULAR_TAB |
| 14623 | We're doing substitution in WHERE/ON condition, which is not yet |
| 14624 | attached to any particular join_tab. We will use information about the |
| 14625 | chosen join order to make "optimal" substitions, i.e. those that allow |
| 14626 | to apply filtering as soon as possible. See eliminate_item_equal() and |
| 14627 | Item_equal::get_first() for details. |
| 14628 | |
| 14629 | @return |
| 14630 | The transformed condition, or NULL in case of error |
| 14631 | */ |
| 14632 | |
| 14633 | static COND* substitute_for_best_equal_field(THD *thd, JOIN_TAB *context_tab, |
| 14634 | COND *cond, |
| 14635 | COND_EQUAL *cond_equal, |
| 14636 | void *table_join_idx) |
| 14637 | { |
| 14638 | Item_equal *item_equal; |
| 14639 | COND *org_cond= cond; // Return this in case of fatal error |
| 14640 | |
| 14641 | if (cond->type() == Item::COND_ITEM) |
| 14642 | { |
| 14643 | List<Item> *cond_list= ((Item_cond*) cond)->argument_list(); |
| 14644 | |
| 14645 | bool and_level= ((Item_cond*) cond)->functype() == |
| 14646 | Item_func::COND_AND_FUNC; |
| 14647 | if (and_level) |
| 14648 | { |
| 14649 | cond_equal= &((Item_cond_and *) cond)->m_cond_equal; |
| 14650 | cond_list->disjoin((List<Item> *) &cond_equal->current_level);/* remove Item_equal objects from the AND. */ |
| 14651 | |
| 14652 | List_iterator_fast<Item_equal> it(cond_equal->current_level); |
| 14653 | while ((item_equal= it++)) |
| 14654 | { |
| 14655 | item_equal->sort(&compare_fields_by_table_order, table_join_idx); |
| 14656 | } |
| 14657 | } |
| 14658 | |
| 14659 | List_iterator<Item> li(*cond_list); |
| 14660 | Item *item; |
| 14661 | while ((item= li++)) |
| 14662 | { |
| 14663 | Item *new_item= substitute_for_best_equal_field(thd, context_tab, |
| 14664 | item, cond_equal, |
| 14665 | table_join_idx); |
| 14666 | /* |
| 14667 | This works OK with PS/SP re-execution as changes are made to |
| 14668 | the arguments of AND/OR items only |
| 14669 | */ |
| 14670 | if (new_item && new_item != item) |
| 14671 | li.replace(new_item); |
| 14672 | } |
| 14673 | |
| 14674 | if (and_level) |
| 14675 | { |
| 14676 | COND *eq_cond= 0; |
| 14677 | List_iterator_fast<Item_equal> it(cond_equal->current_level); |
| 14678 | bool false_eq_cond= FALSE; |
| 14679 | while ((item_equal= it++)) |
| 14680 | { |
| 14681 | eq_cond= eliminate_item_equal(thd, eq_cond, cond_equal->upper_levels, |
| 14682 | item_equal); |
| 14683 | if (!eq_cond) |
| 14684 | { |
| 14685 | eq_cond= 0; |
| 14686 | break; |
| 14687 | } |
| 14688 | else if (eq_cond->type() == Item::INT_ITEM && !eq_cond->val_bool()) |
| 14689 | { |
| 14690 | /* |
| 14691 | This occurs when eliminate_item_equal() founds that cond is |
| 14692 | always false and substitutes it with Item_int 0. |
| 14693 | Due to this, value of item_equal will be 0, so just return it. |
| 14694 | */ |
| 14695 | cond= eq_cond; |
| 14696 | false_eq_cond= TRUE; |
| 14697 | break; |
| 14698 | } |
| 14699 | } |
| 14700 | if (eq_cond && !false_eq_cond) |
| 14701 | { |
| 14702 | /* Insert the generated equalities before all other conditions */ |
| 14703 | if (eq_cond->type() == Item::COND_ITEM) |
| 14704 | ((Item_cond *) cond)->add_at_head( |
| 14705 | ((Item_cond *) eq_cond)->argument_list()); |
| 14706 | else |
| 14707 | { |
| 14708 | if (cond_list->is_empty()) |
| 14709 | cond= eq_cond; |
| 14710 | else |
| 14711 | { |
| 14712 | /* Do not add an equality condition if it's always true */ |
| 14713 | if (eq_cond->type() != Item::INT_ITEM && |
| 14714 | cond_list->push_front(eq_cond, thd->mem_root)) |
| 14715 | eq_cond= 0; |
| 14716 | } |
| 14717 | } |
| 14718 | } |
| 14719 | if (!eq_cond) |
| 14720 | { |
| 14721 | /* |
| 14722 | We are out of memory doing the transformation. |
| 14723 | This is a fatal error now. However we bail out by returning the |
| 14724 | original condition that we had before we started the transformation. |
| 14725 | */ |
| 14726 | cond_list->append((List<Item> *) &cond_equal->current_level); |
| 14727 | } |
| 14728 | } |
| 14729 | } |
| 14730 | else if (cond->type() == Item::FUNC_ITEM && |
| 14731 | ((Item_cond*) cond)->functype() == Item_func::MULT_EQUAL_FUNC) |
| 14732 | { |
| 14733 | item_equal= (Item_equal *) cond; |
| 14734 | item_equal->sort(&compare_fields_by_table_order, table_join_idx); |
| 14735 | cond_equal= item_equal->upper_levels; |
| 14736 | if (cond_equal && cond_equal->current_level.head() == item_equal) |
| 14737 | cond_equal= cond_equal->upper_levels; |
| 14738 | cond= eliminate_item_equal(thd, 0, cond_equal, item_equal); |
| 14739 | return cond ? cond : org_cond; |
| 14740 | } |
| 14741 | else |
| 14742 | { |
| 14743 | while (cond_equal) |
| 14744 | { |
| 14745 | List_iterator_fast<Item_equal> it(cond_equal->current_level); |
| 14746 | while((item_equal= it++)) |
| 14747 | { |
| 14748 | REPLACE_EQUAL_FIELD_ARG arg= {item_equal, context_tab}; |
| 14749 | if (!(cond= cond->transform(thd, &Item::replace_equal_field, |
| 14750 | (uchar *) &arg))) |
| 14751 | return 0; |
| 14752 | } |
| 14753 | cond_equal= cond_equal->upper_levels; |
| 14754 | } |
| 14755 | } |
| 14756 | return cond; |
| 14757 | } |
| 14758 | |
| 14759 | |
| 14760 | /** |
| 14761 | Check appearance of new constant items in multiple equalities |
| 14762 | of a condition after reading a constant table. |
| 14763 | |
| 14764 | The function retrieves the cond condition and for each encountered |
| 14765 | multiple equality checks whether new constants have appeared after |
| 14766 | reading the constant (single row) table tab. If so it adjusts |
| 14767 | the multiple equality appropriately. |
| 14768 | |
| 14769 | @param cond condition whose multiple equalities are to be checked |
| 14770 | @param table constant table that has been read |
| 14771 | @param const_key mark key parts as constant |
| 14772 | */ |
| 14773 | |
| 14774 | static void update_const_equal_items(THD *thd, COND *cond, JOIN_TAB *tab, |
| 14775 | bool const_key) |
| 14776 | { |
| 14777 | if (!(cond->used_tables() & tab->table->map)) |
| 14778 | return; |
| 14779 | |
| 14780 | if (cond->type() == Item::COND_ITEM) |
| 14781 | { |
| 14782 | List<Item> *cond_list= ((Item_cond*) cond)->argument_list(); |
| 14783 | List_iterator_fast<Item> li(*cond_list); |
| 14784 | Item *item; |
| 14785 | while ((item= li++)) |
| 14786 | update_const_equal_items(thd, item, tab, |
| 14787 | (((Item_cond*) cond)->top_level() && |
| 14788 | ((Item_cond*) cond)->functype() == |
| 14789 | Item_func::COND_AND_FUNC)); |
| 14790 | } |
| 14791 | else if (cond->type() == Item::FUNC_ITEM && |
| 14792 | ((Item_cond*) cond)->functype() == Item_func::MULT_EQUAL_FUNC) |
| 14793 | { |
| 14794 | Item_equal *item_equal= (Item_equal *) cond; |
| 14795 | bool contained_const= item_equal->get_const() != NULL; |
| 14796 | item_equal->update_const(thd); |
| 14797 | if (!contained_const && item_equal->get_const()) |
| 14798 | { |
| 14799 | /* Update keys for range analysis */ |
| 14800 | Item_equal_fields_iterator it(*item_equal); |
| 14801 | while (it++) |
| 14802 | { |
| 14803 | Field *field= it.get_curr_field(); |
| 14804 | JOIN_TAB *stat= field->table->reginfo.join_tab; |
| 14805 | key_map possible_keys= field->key_start; |
| 14806 | possible_keys.intersect(field->table->keys_in_use_for_query); |
| 14807 | stat[0].const_keys.merge(possible_keys); |
| 14808 | |
| 14809 | /* |
| 14810 | For each field in the multiple equality (for which we know that it |
| 14811 | is a constant) we have to find its corresponding key part, and set |
| 14812 | that key part in const_key_parts. |
| 14813 | */ |
| 14814 | if (!possible_keys.is_clear_all()) |
| 14815 | { |
| 14816 | TABLE *field_tab= field->table; |
| 14817 | KEYUSE *use; |
| 14818 | for (use= stat->keyuse; use && use->table == field_tab; use++) |
| 14819 | if (const_key && |
| 14820 | !use->is_for_hash_join() && possible_keys.is_set(use->key) && |
| 14821 | field_tab->key_info[use->key].key_part[use->keypart].field == |
| 14822 | field) |
| 14823 | field_tab->const_key_parts[use->key]|= use->keypart_map; |
| 14824 | } |
| 14825 | } |
| 14826 | } |
| 14827 | } |
| 14828 | } |
| 14829 | |
| 14830 | |
| 14831 | /** |
| 14832 | Check if |
| 14833 | WHERE expr=value AND expr=const |
| 14834 | can be rewritten as: |
| 14835 | WHERE const=value AND expr=const |
| 14836 | |
| 14837 | @param target - the target operator whose "expr" argument will be |
| 14838 | replaced to "const". |
| 14839 | @param target_expr - the target's "expr" which will be replaced to "const". |
| 14840 | @param target_value - the target's second argument, it will remain unchanged. |
| 14841 | @param source - the equality expression ("=" or "<=>") that |
| 14842 | can be used to rewrite the "target" part |
| 14843 | (under certain conditions, see the code). |
| 14844 | @param source_expr - the source's "expr". It should be exactly equal to |
| 14845 | the target's "expr" to make condition rewrite possible. |
| 14846 | @param source_const - the source's "const" argument, it will be inserted |
| 14847 | into "target" instead of "expr". |
| 14848 | */ |
| 14849 | static bool |
| 14850 | can_change_cond_ref_to_const(Item_bool_func2 *target, |
| 14851 | Item *target_expr, Item *target_value, |
| 14852 | Item_bool_func2 *source, |
| 14853 | Item *source_expr, Item *source_const) |
| 14854 | { |
| 14855 | return target_expr->eq(source_expr,0) && |
| 14856 | target_value != source_const && |
| 14857 | target->compare_type_handler()-> |
| 14858 | can_change_cond_ref_to_const(target, target_expr, target_value, |
| 14859 | source, source_expr, source_const); |
| 14860 | } |
| 14861 | |
| 14862 | |
| 14863 | /* |
| 14864 | change field = field to field = const for each found field = const in the |
| 14865 | and_level |
| 14866 | */ |
| 14867 | |
| 14868 | static void |
| 14869 | change_cond_ref_to_const(THD *thd, I_List<COND_CMP> *save_list, |
| 14870 | Item *and_father, Item *cond, |
| 14871 | Item_bool_func2 *field_value_owner, |
| 14872 | Item *field, Item *value) |
| 14873 | { |
| 14874 | if (cond->type() == Item::COND_ITEM) |
| 14875 | { |
| 14876 | bool and_level= ((Item_cond*) cond)->functype() == |
| 14877 | Item_func::COND_AND_FUNC; |
| 14878 | List_iterator<Item> li(*((Item_cond*) cond)->argument_list()); |
| 14879 | Item *item; |
| 14880 | while ((item=li++)) |
| 14881 | change_cond_ref_to_const(thd, save_list,and_level ? cond : item, item, |
| 14882 | field_value_owner, field, value); |
| 14883 | return; |
| 14884 | } |
| 14885 | if (cond->eq_cmp_result() == Item::COND_OK) |
| 14886 | return; // Not a boolean function |
| 14887 | |
| 14888 | Item_bool_func2 *func= (Item_bool_func2*) cond; |
| 14889 | Item **args= func->arguments(); |
| 14890 | Item *left_item= args[0]; |
| 14891 | Item *right_item= args[1]; |
| 14892 | Item_func::Functype functype= func->functype(); |
| 14893 | |
| 14894 | if (can_change_cond_ref_to_const(func, right_item, left_item, |
| 14895 | field_value_owner, field, value)) |
| 14896 | { |
| 14897 | Item *tmp=value->clone_item(thd); |
| 14898 | if (tmp) |
| 14899 | { |
| 14900 | tmp->collation.set(right_item->collation); |
| 14901 | thd->change_item_tree(args + 1, tmp); |
| 14902 | func->update_used_tables(); |
| 14903 | if ((functype == Item_func::EQ_FUNC || functype == Item_func::EQUAL_FUNC) |
| 14904 | && and_father != cond && !left_item->const_item()) |
| 14905 | { |
| 14906 | cond->marker=1; |
| 14907 | COND_CMP *tmp2; |
| 14908 | /* Will work, even if malloc would fail */ |
| 14909 | if ((tmp2= new (thd->mem_root) COND_CMP(and_father, func))) |
| 14910 | save_list->push_back(tmp2); |
| 14911 | } |
| 14912 | /* |
| 14913 | LIKE can be optimized for BINARY/VARBINARY/BLOB columns, e.g.: |
| 14914 | |
| 14915 | from: WHERE CONCAT(c1)='const1' AND CONCAT(c1) LIKE 'const2' |
| 14916 | to: WHERE CONCAT(c1)='const1' AND 'const1' LIKE 'const2' |
| 14917 | |
| 14918 | So make sure to use set_cmp_func() only for non-LIKE operators. |
| 14919 | */ |
| 14920 | if (functype != Item_func::LIKE_FUNC) |
| 14921 | ((Item_bool_rowready_func2*) func)->set_cmp_func(); |
| 14922 | } |
| 14923 | } |
| 14924 | else if (can_change_cond_ref_to_const(func, left_item, right_item, |
| 14925 | field_value_owner, field, value)) |
| 14926 | { |
| 14927 | Item *tmp= value->clone_item(thd); |
| 14928 | if (tmp) |
| 14929 | { |
| 14930 | tmp->collation.set(left_item->collation); |
| 14931 | thd->change_item_tree(args, tmp); |
| 14932 | value= tmp; |
| 14933 | func->update_used_tables(); |
| 14934 | if ((functype == Item_func::EQ_FUNC || functype == Item_func::EQUAL_FUNC) |
| 14935 | && and_father != cond && !right_item->const_item()) |
| 14936 | { |
| 14937 | args[0]= args[1]; // For easy check |
| 14938 | thd->change_item_tree(args + 1, value); |
| 14939 | cond->marker=1; |
| 14940 | COND_CMP *tmp2; |
| 14941 | /* Will work, even if malloc would fail */ |
| 14942 | if ((tmp2=new (thd->mem_root) COND_CMP(and_father, func))) |
| 14943 | save_list->push_back(tmp2); |
| 14944 | } |
| 14945 | if (functype != Item_func::LIKE_FUNC) |
| 14946 | ((Item_bool_rowready_func2*) func)->set_cmp_func(); |
| 14947 | } |
| 14948 | } |
| 14949 | } |
| 14950 | |
| 14951 | |
| 14952 | static void |
| 14953 | propagate_cond_constants(THD *thd, I_List<COND_CMP> *save_list, |
| 14954 | COND *and_father, COND *cond) |
| 14955 | { |
| 14956 | if (cond->type() == Item::COND_ITEM) |
| 14957 | { |
| 14958 | bool and_level= ((Item_cond*) cond)->functype() == |
| 14959 | Item_func::COND_AND_FUNC; |
| 14960 | List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list()); |
| 14961 | Item *item; |
| 14962 | I_List<COND_CMP> save; |
| 14963 | while ((item=li++)) |
| 14964 | { |
| 14965 | propagate_cond_constants(thd, &save,and_level ? cond : item, item); |
| 14966 | } |
| 14967 | if (and_level) |
| 14968 | { // Handle other found items |
| 14969 | I_List_iterator<COND_CMP> cond_itr(save); |
| 14970 | COND_CMP *cond_cmp; |
| 14971 | while ((cond_cmp=cond_itr++)) |
| 14972 | { |
| 14973 | Item **args= cond_cmp->cmp_func->arguments(); |
| 14974 | if (!args[0]->const_item()) |
| 14975 | change_cond_ref_to_const(thd, &save,cond_cmp->and_level, |
| 14976 | cond_cmp->and_level, |
| 14977 | cond_cmp->cmp_func, args[0], args[1]); |
| 14978 | } |
| 14979 | } |
| 14980 | } |
| 14981 | else if (and_father != cond && !cond->marker) // In a AND group |
| 14982 | { |
| 14983 | if (cond->type() == Item::FUNC_ITEM && |
| 14984 | (((Item_func*) cond)->functype() == Item_func::EQ_FUNC || |
| 14985 | ((Item_func*) cond)->functype() == Item_func::EQUAL_FUNC)) |
| 14986 | { |
| 14987 | Item_func_eq *func=(Item_func_eq*) cond; |
| 14988 | Item **args= func->arguments(); |
| 14989 | bool left_const= args[0]->const_item() && !args[0]->is_expensive(); |
| 14990 | bool right_const= args[1]->const_item() && !args[1]->is_expensive(); |
| 14991 | if (!(left_const && right_const) && |
| 14992 | args[0]->cmp_type() == args[1]->cmp_type()) |
| 14993 | { |
| 14994 | if (right_const) |
| 14995 | { |
| 14996 | resolve_const_item(thd, &args[1], args[0]); |
| 14997 | func->update_used_tables(); |
| 14998 | change_cond_ref_to_const(thd, save_list, and_father, and_father, |
| 14999 | func, args[0], args[1]); |
| 15000 | } |
| 15001 | else if (left_const) |
| 15002 | { |
| 15003 | resolve_const_item(thd, &args[0], args[1]); |
| 15004 | func->update_used_tables(); |
| 15005 | change_cond_ref_to_const(thd, save_list, and_father, and_father, |
| 15006 | func, args[1], args[0]); |
| 15007 | } |
| 15008 | } |
| 15009 | } |
| 15010 | } |
| 15011 | } |
| 15012 | |
| 15013 | /** |
| 15014 | Simplify joins replacing outer joins by inner joins whenever it's |
| 15015 | possible. |
| 15016 | |
| 15017 | The function, during a retrieval of join_list, eliminates those |
| 15018 | outer joins that can be converted into inner join, possibly nested. |
| 15019 | It also moves the on expressions for the converted outer joins |
| 15020 | and from inner joins to conds. |
| 15021 | The function also calculates some attributes for nested joins: |
| 15022 | - used_tables |
| 15023 | - not_null_tables |
| 15024 | - dep_tables. |
| 15025 | - on_expr_dep_tables |
| 15026 | The first two attributes are used to test whether an outer join can |
| 15027 | be substituted for an inner join. The third attribute represents the |
| 15028 | relation 'to be dependent on' for tables. If table t2 is dependent |
| 15029 | on table t1, then in any evaluated execution plan table access to |
| 15030 | table t2 must precede access to table t2. This relation is used also |
| 15031 | to check whether the query contains invalid cross-references. |
| 15032 | The forth attribute is an auxiliary one and is used to calculate |
| 15033 | dep_tables. |
| 15034 | As the attribute dep_tables qualifies possibles orders of tables in the |
| 15035 | execution plan, the dependencies required by the straight join |
| 15036 | modifiers are reflected in this attribute as well. |
| 15037 | The function also removes all braces that can be removed from the join |
| 15038 | expression without changing its meaning. |
| 15039 | |
| 15040 | @note |
| 15041 | An outer join can be replaced by an inner join if the where condition |
| 15042 | or the on expression for an embedding nested join contains a conjunctive |
| 15043 | predicate rejecting null values for some attribute of the inner tables. |
| 15044 | |
| 15045 | E.g. in the query: |
| 15046 | @code |
| 15047 | SELECT * FROM t1 LEFT JOIN t2 ON t2.a=t1.a WHERE t2.b < 5 |
| 15048 | @endcode |
| 15049 | the predicate t2.b < 5 rejects nulls. |
| 15050 | The query is converted first to: |
| 15051 | @code |
| 15052 | SELECT * FROM t1 INNER JOIN t2 ON t2.a=t1.a WHERE t2.b < 5 |
| 15053 | @endcode |
| 15054 | then to the equivalent form: |
| 15055 | @code |
| 15056 | SELECT * FROM t1, t2 ON t2.a=t1.a WHERE t2.b < 5 AND t2.a=t1.a |
| 15057 | @endcode |
| 15058 | |
| 15059 | |
| 15060 | Similarly the following query: |
| 15061 | @code |
| 15062 | SELECT * from t1 LEFT JOIN (t2, t3) ON t2.a=t1.a t3.b=t1.b |
| 15063 | WHERE t2.c < 5 |
| 15064 | @endcode |
| 15065 | is converted to: |
| 15066 | @code |
| 15067 | SELECT * FROM t1, (t2, t3) WHERE t2.c < 5 AND t2.a=t1.a t3.b=t1.b |
| 15068 | |
| 15069 | @endcode |
| 15070 | |
| 15071 | One conversion might trigger another: |
| 15072 | @code |
| 15073 | SELECT * FROM t1 LEFT JOIN t2 ON t2.a=t1.a |
| 15074 | LEFT JOIN t3 ON t3.b=t2.b |
| 15075 | WHERE t3 IS NOT NULL => |
| 15076 | SELECT * FROM t1 LEFT JOIN t2 ON t2.a=t1.a, t3 |
| 15077 | WHERE t3 IS NOT NULL AND t3.b=t2.b => |
| 15078 | SELECT * FROM t1, t2, t3 |
| 15079 | WHERE t3 IS NOT NULL AND t3.b=t2.b AND t2.a=t1.a |
| 15080 | @endcode |
| 15081 | |
| 15082 | The function removes all unnecessary braces from the expression |
| 15083 | produced by the conversions. |
| 15084 | E.g. |
| 15085 | @code |
| 15086 | SELECT * FROM t1, (t2, t3) WHERE t2.c < 5 AND t2.a=t1.a AND t3.b=t1.b |
| 15087 | @endcode |
| 15088 | finally is converted to: |
| 15089 | @code |
| 15090 | SELECT * FROM t1, t2, t3 WHERE t2.c < 5 AND t2.a=t1.a AND t3.b=t1.b |
| 15091 | |
| 15092 | @endcode |
| 15093 | |
| 15094 | |
| 15095 | It also will remove braces from the following queries: |
| 15096 | @code |
| 15097 | SELECT * from (t1 LEFT JOIN t2 ON t2.a=t1.a) LEFT JOIN t3 ON t3.b=t2.b |
| 15098 | SELECT * from (t1, (t2,t3)) WHERE t1.a=t2.a AND t2.b=t3.b. |
| 15099 | @endcode |
| 15100 | |
| 15101 | The benefit of this simplification procedure is that it might return |
| 15102 | a query for which the optimizer can evaluate execution plan with more |
| 15103 | join orders. With a left join operation the optimizer does not |
| 15104 | consider any plan where one of the inner tables is before some of outer |
| 15105 | tables. |
| 15106 | |
| 15107 | IMPLEMENTATION |
| 15108 | The function is implemented by a recursive procedure. On the recursive |
| 15109 | ascent all attributes are calculated, all outer joins that can be |
| 15110 | converted are replaced and then all unnecessary braces are removed. |
| 15111 | As join list contains join tables in the reverse order sequential |
| 15112 | elimination of outer joins does not require extra recursive calls. |
| 15113 | |
| 15114 | SEMI-JOIN NOTES |
| 15115 | Remove all semi-joins that have are within another semi-join (i.e. have |
| 15116 | an "ancestor" semi-join nest) |
| 15117 | |
| 15118 | EXAMPLES |
| 15119 | Here is an example of a join query with invalid cross references: |
| 15120 | @code |
| 15121 | SELECT * FROM t1 LEFT JOIN t2 ON t2.a=t3.a LEFT JOIN t3 ON t3.b=t1.b |
| 15122 | @endcode |
| 15123 | |
| 15124 | @param join reference to the query info |
| 15125 | @param join_list list representation of the join to be converted |
| 15126 | @param conds conditions to add on expressions for converted joins |
| 15127 | @param top true <=> conds is the where condition |
| 15128 | @param in_sj TRUE <=> processing semi-join nest's children |
| 15129 | @return |
| 15130 | - The new condition, if success |
| 15131 | - 0, otherwise |
| 15132 | */ |
| 15133 | |
| 15134 | static COND * |
| 15135 | simplify_joins(JOIN *join, List<TABLE_LIST> *join_list, COND *conds, bool top, |
| 15136 | bool in_sj) |
| 15137 | { |
| 15138 | TABLE_LIST *table; |
| 15139 | NESTED_JOIN *nested_join; |
| 15140 | TABLE_LIST *prev_table= 0; |
| 15141 | List_iterator<TABLE_LIST> li(*join_list); |
| 15142 | bool straight_join= MY_TEST(join->select_options & SELECT_STRAIGHT_JOIN); |
| 15143 | DBUG_ENTER("simplify_joins" ); |
| 15144 | |
| 15145 | /* |
| 15146 | Try to simplify join operations from join_list. |
| 15147 | The most outer join operation is checked for conversion first. |
| 15148 | */ |
| 15149 | while ((table= li++)) |
| 15150 | { |
| 15151 | table_map used_tables; |
| 15152 | table_map not_null_tables= (table_map) 0; |
| 15153 | |
| 15154 | if ((nested_join= table->nested_join)) |
| 15155 | { |
| 15156 | /* |
| 15157 | If the element of join_list is a nested join apply |
| 15158 | the procedure to its nested join list first. |
| 15159 | */ |
| 15160 | if (table->on_expr) |
| 15161 | { |
| 15162 | Item *expr= table->on_expr; |
| 15163 | /* |
| 15164 | If an on expression E is attached to the table, |
| 15165 | check all null rejected predicates in this expression. |
| 15166 | If such a predicate over an attribute belonging to |
| 15167 | an inner table of an embedded outer join is found, |
| 15168 | the outer join is converted to an inner join and |
| 15169 | the corresponding on expression is added to E. |
| 15170 | */ |
| 15171 | expr= simplify_joins(join, &nested_join->join_list, |
| 15172 | expr, FALSE, in_sj || table->sj_on_expr); |
| 15173 | |
| 15174 | if (!table->prep_on_expr || expr != table->on_expr) |
| 15175 | { |
| 15176 | DBUG_ASSERT(expr); |
| 15177 | |
| 15178 | table->on_expr= expr; |
| 15179 | table->prep_on_expr= expr->copy_andor_structure(join->thd); |
| 15180 | } |
| 15181 | } |
| 15182 | nested_join->used_tables= (table_map) 0; |
| 15183 | nested_join->not_null_tables=(table_map) 0; |
| 15184 | conds= simplify_joins(join, &nested_join->join_list, conds, top, |
| 15185 | in_sj || table->sj_on_expr); |
| 15186 | used_tables= nested_join->used_tables; |
| 15187 | not_null_tables= nested_join->not_null_tables; |
| 15188 | /* The following two might become unequal after table elimination: */ |
| 15189 | nested_join->n_tables= nested_join->join_list.elements; |
| 15190 | } |
| 15191 | else |
| 15192 | { |
| 15193 | if (!table->prep_on_expr) |
| 15194 | table->prep_on_expr= table->on_expr; |
| 15195 | used_tables= table->get_map(); |
| 15196 | if (conds) |
| 15197 | not_null_tables= conds->not_null_tables(); |
| 15198 | } |
| 15199 | |
| 15200 | if (table->embedding) |
| 15201 | { |
| 15202 | table->embedding->nested_join->used_tables|= used_tables; |
| 15203 | table->embedding->nested_join->not_null_tables|= not_null_tables; |
| 15204 | } |
| 15205 | |
| 15206 | if (!(table->outer_join & (JOIN_TYPE_LEFT | JOIN_TYPE_RIGHT)) || |
| 15207 | (used_tables & not_null_tables)) |
| 15208 | { |
| 15209 | /* |
| 15210 | For some of the inner tables there are conjunctive predicates |
| 15211 | that reject nulls => the outer join can be replaced by an inner join. |
| 15212 | */ |
| 15213 | if (table->outer_join && !table->embedding && table->table) |
| 15214 | table->table->maybe_null= FALSE; |
| 15215 | table->outer_join= 0; |
| 15216 | if (!(straight_join || table->straight)) |
| 15217 | table->dep_tables= table->embedding && !table->embedding->sj_subq_pred ? |
| 15218 | table->embedding->dep_tables : 0; |
| 15219 | if (table->on_expr) |
| 15220 | { |
| 15221 | /* Add ON expression to the WHERE or upper-level ON condition. */ |
| 15222 | if (conds) |
| 15223 | { |
| 15224 | conds= and_conds(join->thd, conds, table->on_expr); |
| 15225 | conds->top_level_item(); |
| 15226 | /* conds is always a new item as both cond and on_expr existed */ |
| 15227 | DBUG_ASSERT(!conds->fixed); |
| 15228 | conds->fix_fields(join->thd, &conds); |
| 15229 | } |
| 15230 | else |
| 15231 | conds= table->on_expr; |
| 15232 | table->prep_on_expr= table->on_expr= 0; |
| 15233 | } |
| 15234 | } |
| 15235 | |
| 15236 | /* |
| 15237 | Only inner tables of non-convertible outer joins |
| 15238 | remain with on_expr. |
| 15239 | */ |
| 15240 | if (table->on_expr) |
| 15241 | { |
| 15242 | table_map table_on_expr_used_tables= table->on_expr->used_tables(); |
| 15243 | table->dep_tables|= table_on_expr_used_tables; |
| 15244 | if (table->embedding) |
| 15245 | { |
| 15246 | table->dep_tables&= ~table->embedding->nested_join->used_tables; |
| 15247 | /* |
| 15248 | Embedding table depends on tables used |
| 15249 | in embedded on expressions. |
| 15250 | */ |
| 15251 | table->embedding->on_expr_dep_tables|= table_on_expr_used_tables; |
| 15252 | } |
| 15253 | else |
| 15254 | table->dep_tables&= ~table->get_map(); |
| 15255 | } |
| 15256 | |
| 15257 | if (prev_table) |
| 15258 | { |
| 15259 | /* The order of tables is reverse: prev_table follows table */ |
| 15260 | if (prev_table->straight || straight_join) |
| 15261 | prev_table->dep_tables|= used_tables; |
| 15262 | if (prev_table->on_expr) |
| 15263 | { |
| 15264 | prev_table->dep_tables|= table->on_expr_dep_tables; |
| 15265 | table_map prev_used_tables= prev_table->nested_join ? |
| 15266 | prev_table->nested_join->used_tables : |
| 15267 | prev_table->get_map(); |
| 15268 | /* |
| 15269 | If on expression contains only references to inner tables |
| 15270 | we still make the inner tables dependent on the outer tables. |
| 15271 | It would be enough to set dependency only on one outer table |
| 15272 | for them. Yet this is really a rare case. |
| 15273 | Note: |
| 15274 | RAND_TABLE_BIT mask should not be counted as it |
| 15275 | prevents update of inner table dependences. |
| 15276 | For example it might happen if RAND() function |
| 15277 | is used in JOIN ON clause. |
| 15278 | */ |
| 15279 | if (!((prev_table->on_expr->used_tables() & |
| 15280 | ~(OUTER_REF_TABLE_BIT | RAND_TABLE_BIT)) & |
| 15281 | ~prev_used_tables)) |
| 15282 | prev_table->dep_tables|= used_tables; |
| 15283 | } |
| 15284 | } |
| 15285 | prev_table= table; |
| 15286 | } |
| 15287 | |
| 15288 | /* |
| 15289 | Flatten nested joins that can be flattened. |
| 15290 | no ON expression and not a semi-join => can be flattened. |
| 15291 | */ |
| 15292 | li.rewind(); |
| 15293 | while ((table= li++)) |
| 15294 | { |
| 15295 | nested_join= table->nested_join; |
| 15296 | if (table->sj_on_expr && !in_sj) |
| 15297 | { |
| 15298 | /* |
| 15299 | If this is a semi-join that is not contained within another semi-join |
| 15300 | leave it intact (otherwise it is flattened) |
| 15301 | */ |
| 15302 | /* |
| 15303 | Make sure that any semi-join appear in |
| 15304 | the join->select_lex->sj_nests list only once |
| 15305 | */ |
| 15306 | List_iterator_fast<TABLE_LIST> sj_it(join->select_lex->sj_nests); |
| 15307 | TABLE_LIST *sj_nest; |
| 15308 | while ((sj_nest= sj_it++)) |
| 15309 | { |
| 15310 | if (table == sj_nest) |
| 15311 | break; |
| 15312 | } |
| 15313 | if (sj_nest) |
| 15314 | continue; |
| 15315 | join->select_lex->sj_nests.push_back(table, join->thd->mem_root); |
| 15316 | |
| 15317 | /* |
| 15318 | Also, walk through semi-join children and mark those that are now |
| 15319 | top-level |
| 15320 | */ |
| 15321 | TABLE_LIST *tbl; |
| 15322 | List_iterator<TABLE_LIST> it(nested_join->join_list); |
| 15323 | while ((tbl= it++)) |
| 15324 | { |
| 15325 | if (!tbl->on_expr && tbl->table) |
| 15326 | tbl->table->maybe_null= FALSE; |
| 15327 | } |
| 15328 | } |
| 15329 | else if (nested_join && !table->on_expr) |
| 15330 | { |
| 15331 | TABLE_LIST *tbl; |
| 15332 | List_iterator<TABLE_LIST> it(nested_join->join_list); |
| 15333 | List<TABLE_LIST> repl_list; |
| 15334 | while ((tbl= it++)) |
| 15335 | { |
| 15336 | tbl->embedding= table->embedding; |
| 15337 | if (!tbl->embedding && !tbl->on_expr && tbl->table) |
| 15338 | tbl->table->maybe_null= FALSE; |
| 15339 | tbl->join_list= table->join_list; |
| 15340 | repl_list.push_back(tbl, join->thd->mem_root); |
| 15341 | tbl->dep_tables|= table->dep_tables; |
| 15342 | } |
| 15343 | li.replace(repl_list); |
| 15344 | } |
| 15345 | } |
| 15346 | DBUG_RETURN(conds); |
| 15347 | } |
| 15348 | |
| 15349 | |
| 15350 | /** |
| 15351 | Assign each nested join structure a bit in nested_join_map. |
| 15352 | |
| 15353 | Assign each nested join structure (except ones that embed only one element |
| 15354 | and so are redundant) a bit in nested_join_map. |
| 15355 | |
| 15356 | @param join Join being processed |
| 15357 | @param join_list List of tables |
| 15358 | @param first_unused Number of first unused bit in nested_join_map before the |
| 15359 | call |
| 15360 | |
| 15361 | @note |
| 15362 | This function is called after simplify_joins(), when there are no |
| 15363 | redundant nested joins, #non_redundant_nested_joins <= #tables_in_join so |
| 15364 | we will not run out of bits in nested_join_map. |
| 15365 | |
| 15366 | @return |
| 15367 | First unused bit in nested_join_map after the call. |
| 15368 | */ |
| 15369 | |
| 15370 | static uint build_bitmap_for_nested_joins(List<TABLE_LIST> *join_list, |
| 15371 | uint first_unused) |
| 15372 | { |
| 15373 | List_iterator<TABLE_LIST> li(*join_list); |
| 15374 | TABLE_LIST *table; |
| 15375 | DBUG_ENTER("build_bitmap_for_nested_joins" ); |
| 15376 | while ((table= li++)) |
| 15377 | { |
| 15378 | NESTED_JOIN *nested_join; |
| 15379 | if ((nested_join= table->nested_join)) |
| 15380 | { |
| 15381 | /* |
| 15382 | It is guaranteed by simplify_joins() function that a nested join |
| 15383 | that has only one child represents a single table VIEW (and the child |
| 15384 | is an underlying table). We don't assign bits to such nested join |
| 15385 | structures because |
| 15386 | 1. it is redundant (a "sequence" of one table cannot be interleaved |
| 15387 | with anything) |
| 15388 | 2. we could run out bits in nested_join_map otherwise. |
| 15389 | */ |
| 15390 | if (nested_join->n_tables != 1) |
| 15391 | { |
| 15392 | /* Don't assign bits to sj-nests */ |
| 15393 | if (table->on_expr) |
| 15394 | nested_join->nj_map= (nested_join_map) 1 << first_unused++; |
| 15395 | first_unused= build_bitmap_for_nested_joins(&nested_join->join_list, |
| 15396 | first_unused); |
| 15397 | } |
| 15398 | } |
| 15399 | } |
| 15400 | DBUG_RETURN(first_unused); |
| 15401 | } |
| 15402 | |
| 15403 | |
| 15404 | /** |
| 15405 | Set NESTED_JOIN::counter=0 in all nested joins in passed list. |
| 15406 | |
| 15407 | Recursively set NESTED_JOIN::counter=0 for all nested joins contained in |
| 15408 | the passed join_list. |
| 15409 | |
| 15410 | @param join_list List of nested joins to process. It may also contain base |
| 15411 | tables which will be ignored. |
| 15412 | */ |
| 15413 | |
| 15414 | static uint reset_nj_counters(JOIN *join, List<TABLE_LIST> *join_list) |
| 15415 | { |
| 15416 | List_iterator<TABLE_LIST> li(*join_list); |
| 15417 | TABLE_LIST *table; |
| 15418 | DBUG_ENTER("reset_nj_counters" ); |
| 15419 | uint n=0; |
| 15420 | while ((table= li++)) |
| 15421 | { |
| 15422 | NESTED_JOIN *nested_join; |
| 15423 | bool is_eliminated_nest= FALSE; |
| 15424 | if ((nested_join= table->nested_join)) |
| 15425 | { |
| 15426 | nested_join->counter= 0; |
| 15427 | nested_join->n_tables= reset_nj_counters(join, &nested_join->join_list); |
| 15428 | if (!nested_join->n_tables) |
| 15429 | is_eliminated_nest= TRUE; |
| 15430 | } |
| 15431 | if ((table->nested_join && !is_eliminated_nest) || |
| 15432 | (!table->nested_join && (table->table->map & ~join->eliminated_tables))) |
| 15433 | n++; |
| 15434 | } |
| 15435 | DBUG_RETURN(n); |
| 15436 | } |
| 15437 | |
| 15438 | |
| 15439 | /** |
| 15440 | Check interleaving with an inner tables of an outer join for |
| 15441 | extension table. |
| 15442 | |
| 15443 | Check if table next_tab can be added to current partial join order, and |
| 15444 | if yes, record that it has been added. |
| 15445 | |
| 15446 | The function assumes that both current partial join order and its |
| 15447 | extension with next_tab are valid wrt table dependencies. |
| 15448 | |
| 15449 | @verbatim |
| 15450 | IMPLEMENTATION |
| 15451 | LIMITATIONS ON JOIN ORDER |
| 15452 | The nested [outer] joins executioner algorithm imposes these limitations |
| 15453 | on join order: |
| 15454 | 1. "Outer tables first" - any "outer" table must be before any |
| 15455 | corresponding "inner" table. |
| 15456 | 2. "No interleaving" - tables inside a nested join must form a continuous |
| 15457 | sequence in join order (i.e. the sequence must not be interrupted by |
| 15458 | tables that are outside of this nested join). |
| 15459 | |
| 15460 | #1 is checked elsewhere, this function checks #2 provided that #1 has |
| 15461 | been already checked. |
| 15462 | |
| 15463 | WHY NEED NON-INTERLEAVING |
| 15464 | Consider an example: |
| 15465 | |
| 15466 | select * from t0 join t1 left join (t2 join t3) on cond1 |
| 15467 | |
| 15468 | The join order "t1 t2 t0 t3" is invalid: |
| 15469 | |
| 15470 | table t0 is outside of the nested join, so WHERE condition for t0 is |
| 15471 | attached directly to t0 (without triggers, and it may be used to access |
| 15472 | t0). Applying WHERE(t0) to (t2,t0,t3) record is invalid as we may miss |
| 15473 | combinations of (t1, t2, t3) that satisfy condition cond1, and produce a |
| 15474 | null-complemented (t1, t2.NULLs, t3.NULLs) row, which should not have |
| 15475 | been produced. |
| 15476 | |
| 15477 | If table t0 is not between t2 and t3, the problem doesn't exist: |
| 15478 | If t0 is located after (t2,t3), WHERE(t0) is applied after nested join |
| 15479 | processing has finished. |
| 15480 | If t0 is located before (t2,t3), predicates like WHERE_cond(t0, t2) are |
| 15481 | wrapped into condition triggers, which takes care of correct nested |
| 15482 | join processing. |
| 15483 | |
| 15484 | HOW IT IS IMPLEMENTED |
| 15485 | The limitations on join order can be rephrased as follows: for valid |
| 15486 | join order one must be able to: |
| 15487 | 1. write down the used tables in the join order on one line. |
| 15488 | 2. for each nested join, put one '(' and one ')' on the said line |
| 15489 | 3. write "LEFT JOIN" and "ON (...)" where appropriate |
| 15490 | 4. get a query equivalent to the query we're trying to execute. |
| 15491 | |
| 15492 | Calls to check_interleaving_with_nj() are equivalent to writing the |
| 15493 | above described line from left to right. |
| 15494 | A single check_interleaving_with_nj(A,B) call is equivalent to writing |
| 15495 | table B and appropriate brackets on condition that table A and |
| 15496 | appropriate brackets is the last what was written. Graphically the |
| 15497 | transition is as follows: |
| 15498 | |
| 15499 | +---- current position |
| 15500 | | |
| 15501 | ... last_tab ))) | ( next_tab ) )..) | ... |
| 15502 | X Y Z | |
| 15503 | +- need to move to this |
| 15504 | position. |
| 15505 | |
| 15506 | Notes about the position: |
| 15507 | The caller guarantees that there is no more then one X-bracket by |
| 15508 | checking "!(remaining_tables & s->dependent)" before calling this |
| 15509 | function. X-bracket may have a pair in Y-bracket. |
| 15510 | |
| 15511 | When "writing" we store/update this auxilary info about the current |
| 15512 | position: |
| 15513 | 1. join->cur_embedding_map - bitmap of pairs of brackets (aka nested |
| 15514 | joins) we've opened but didn't close. |
| 15515 | 2. {each NESTED_JOIN structure not simplified away}->counter - number |
| 15516 | of this nested join's children that have already been added to to |
| 15517 | the partial join order. |
| 15518 | @endverbatim |
| 15519 | |
| 15520 | @param next_tab Table we're going to extend the current partial join with |
| 15521 | |
| 15522 | @retval |
| 15523 | FALSE Join order extended, nested joins info about current join |
| 15524 | order (see NOTE section) updated. |
| 15525 | @retval |
| 15526 | TRUE Requested join order extension not allowed. |
| 15527 | */ |
| 15528 | |
| 15529 | static bool check_interleaving_with_nj(JOIN_TAB *next_tab) |
| 15530 | { |
| 15531 | TABLE_LIST *next_emb= next_tab->table->pos_in_table_list->embedding; |
| 15532 | JOIN *join= next_tab->join; |
| 15533 | |
| 15534 | if (join->cur_embedding_map & ~next_tab->embedding_map) |
| 15535 | { |
| 15536 | /* |
| 15537 | next_tab is outside of the "pair of brackets" we're currently in. |
| 15538 | Cannot add it. |
| 15539 | */ |
| 15540 | return TRUE; |
| 15541 | } |
| 15542 | |
| 15543 | /* |
| 15544 | Do update counters for "pairs of brackets" that we've left (marked as |
| 15545 | X,Y,Z in the above picture) |
| 15546 | */ |
| 15547 | for (;next_emb && next_emb != join->emb_sjm_nest; next_emb= next_emb->embedding) |
| 15548 | { |
| 15549 | if (!next_emb->sj_on_expr) |
| 15550 | { |
| 15551 | next_emb->nested_join->counter++; |
| 15552 | if (next_emb->nested_join->counter == 1) |
| 15553 | { |
| 15554 | /* |
| 15555 | next_emb is the first table inside a nested join we've "entered". In |
| 15556 | the picture above, we're looking at the 'X' bracket. Don't exit yet as |
| 15557 | X bracket might have Y pair bracket. |
| 15558 | */ |
| 15559 | join->cur_embedding_map |= next_emb->nested_join->nj_map; |
| 15560 | } |
| 15561 | |
| 15562 | if (next_emb->nested_join->n_tables != |
| 15563 | next_emb->nested_join->counter) |
| 15564 | break; |
| 15565 | |
| 15566 | /* |
| 15567 | We're currently at Y or Z-bracket as depicted in the above picture. |
| 15568 | Mark that we've left it and continue walking up the brackets hierarchy. |
| 15569 | */ |
| 15570 | join->cur_embedding_map &= ~next_emb->nested_join->nj_map; |
| 15571 | } |
| 15572 | } |
| 15573 | return FALSE; |
| 15574 | } |
| 15575 | |
| 15576 | |
| 15577 | /** |
| 15578 | Nested joins perspective: Remove the last table from the join order. |
| 15579 | |
| 15580 | The algorithm is the reciprocal of check_interleaving_with_nj(), hence |
| 15581 | parent join nest nodes are updated only when the last table in its child |
| 15582 | node is removed. The ASCII graphic below will clarify. |
| 15583 | |
| 15584 | %A table nesting such as <tt> t1 x [ ( t2 x t3 ) x ( t4 x t5 ) ] </tt>is |
| 15585 | represented by the below join nest tree. |
| 15586 | |
| 15587 | @verbatim |
| 15588 | NJ1 |
| 15589 | _/ / \ |
| 15590 | _/ / NJ2 |
| 15591 | _/ / / \ |
| 15592 | / / / \ |
| 15593 | t1 x [ (t2 x t3) x (t4 x t5) ] |
| 15594 | @endverbatim |
| 15595 | |
| 15596 | At the point in time when check_interleaving_with_nj() adds the table t5 to |
| 15597 | the query execution plan, QEP, it also directs the node named NJ2 to mark |
| 15598 | the table as covered. NJ2 does so by incrementing its @c counter |
| 15599 | member. Since all of NJ2's tables are now covered by the QEP, the algorithm |
| 15600 | proceeds up the tree to NJ1, incrementing its counter as well. All join |
| 15601 | nests are now completely covered by the QEP. |
| 15602 | |
| 15603 | restore_prev_nj_state() does the above in reverse. As seen above, the node |
| 15604 | NJ1 contains the nodes t2, t3, and NJ2. Its counter being equal to 3 means |
| 15605 | that the plan covers t2, t3, and NJ2, @e and that the sub-plan (t4 x t5) |
| 15606 | completely covers NJ2. The removal of t5 from the partial plan will first |
| 15607 | decrement NJ2's counter to 1. It will then detect that NJ2 went from being |
| 15608 | completely to partially covered, and hence the algorithm must continue |
| 15609 | upwards to NJ1 and decrement its counter to 2. %A subsequent removal of t4 |
| 15610 | will however not influence NJ1 since it did not un-cover the last table in |
| 15611 | NJ2. |
| 15612 | |
| 15613 | SYNOPSIS |
| 15614 | restore_prev_nj_state() |
| 15615 | last join table to remove, it is assumed to be the last in current |
| 15616 | partial join order. |
| 15617 | |
| 15618 | DESCRIPTION |
| 15619 | |
| 15620 | Remove the last table from the partial join order and update the nested |
| 15621 | joins counters and join->cur_embedding_map. It is ok to call this |
| 15622 | function for the first table in join order (for which |
| 15623 | check_interleaving_with_nj has not been called) |
| 15624 | |
| 15625 | @param last join table to remove, it is assumed to be the last in current |
| 15626 | partial join order. |
| 15627 | */ |
| 15628 | |
| 15629 | static void restore_prev_nj_state(JOIN_TAB *last) |
| 15630 | { |
| 15631 | TABLE_LIST *last_emb= last->table->pos_in_table_list->embedding; |
| 15632 | JOIN *join= last->join; |
| 15633 | for (;last_emb != NULL && last_emb != join->emb_sjm_nest; |
| 15634 | last_emb= last_emb->embedding) |
| 15635 | { |
| 15636 | if (!last_emb->sj_on_expr) |
| 15637 | { |
| 15638 | NESTED_JOIN *nest= last_emb->nested_join; |
| 15639 | DBUG_ASSERT(nest->counter > 0); |
| 15640 | |
| 15641 | bool was_fully_covered= nest->is_fully_covered(); |
| 15642 | |
| 15643 | join->cur_embedding_map|= nest->nj_map; |
| 15644 | |
| 15645 | if (--nest->counter == 0) |
| 15646 | join->cur_embedding_map&= ~nest->nj_map; |
| 15647 | |
| 15648 | if (!was_fully_covered) |
| 15649 | break; |
| 15650 | } |
| 15651 | } |
| 15652 | } |
| 15653 | |
| 15654 | |
| 15655 | |
| 15656 | /* |
| 15657 | Change access methods not to use join buffering and adjust costs accordingly |
| 15658 | |
| 15659 | SYNOPSIS |
| 15660 | optimize_wo_join_buffering() |
| 15661 | join |
| 15662 | first_tab The first tab to do re-optimization for |
| 15663 | last_tab The last tab to do re-optimization for |
| 15664 | last_remaining_tables Bitmap of tables that are not in the |
| 15665 | [0...last_tab] join prefix |
| 15666 | first_alt TRUE <=> Use the LooseScan plan for the first_tab |
| 15667 | no_jbuf_before Don't allow to use join buffering before this |
| 15668 | table |
| 15669 | reopt_rec_count OUT New output record count |
| 15670 | reopt_cost OUT New join prefix cost |
| 15671 | |
| 15672 | DESCRIPTION |
| 15673 | Given a join prefix [0; ... first_tab], change the access to the tables |
| 15674 | in the [first_tab; last_tab] not to use join buffering. This is needed |
| 15675 | because some semi-join strategies cannot be used together with the join |
| 15676 | buffering. |
| 15677 | In general case the best table order in [first_tab; last_tab] range with |
| 15678 | join buffering is different from the best order without join buffering but |
| 15679 | we don't try finding a better join order. (TODO ask Igor why did we |
| 15680 | chose not to do this in the end. that's actually the difference from the |
| 15681 | forking approach) |
| 15682 | */ |
| 15683 | |
| 15684 | void optimize_wo_join_buffering(JOIN *join, uint first_tab, uint last_tab, |
| 15685 | table_map last_remaining_tables, |
| 15686 | bool first_alt, uint no_jbuf_before, |
| 15687 | double *outer_rec_count, double *reopt_cost) |
| 15688 | { |
| 15689 | double cost, rec_count; |
| 15690 | table_map reopt_remaining_tables= last_remaining_tables; |
| 15691 | uint i; |
| 15692 | |
| 15693 | if (first_tab > join->const_tables) |
| 15694 | { |
| 15695 | cost= join->positions[first_tab - 1].prefix_cost.total_cost(); |
| 15696 | rec_count= join->positions[first_tab - 1].prefix_record_count; |
| 15697 | } |
| 15698 | else |
| 15699 | { |
| 15700 | cost= 0.0; |
| 15701 | rec_count= 1; |
| 15702 | } |
| 15703 | |
| 15704 | *outer_rec_count= rec_count; |
| 15705 | for (i= first_tab; i <= last_tab; i++) |
| 15706 | reopt_remaining_tables |= join->positions[i].table->table->map; |
| 15707 | |
| 15708 | /* |
| 15709 | best_access_path() optimization depends on the value of |
| 15710 | join->cur_sj_inner_tables. Our goal in this function is to do a |
| 15711 | re-optimization with disabled join buffering, but no other changes. |
| 15712 | In order to achieve this, cur_sj_inner_tables needs have the same |
| 15713 | value it had during the original invocations of best_access_path. |
| 15714 | |
| 15715 | We know that this function, optimize_wo_join_buffering() is called to |
| 15716 | re-optimize semi-join join order range, which allows to conclude that |
| 15717 | the "original" value of cur_sj_inner_tables was 0. |
| 15718 | */ |
| 15719 | table_map save_cur_sj_inner_tables= join->cur_sj_inner_tables; |
| 15720 | join->cur_sj_inner_tables= 0; |
| 15721 | |
| 15722 | for (i= first_tab; i <= last_tab; i++) |
| 15723 | { |
| 15724 | JOIN_TAB *rs= join->positions[i].table; |
| 15725 | POSITION pos, loose_scan_pos; |
| 15726 | |
| 15727 | if ((i == first_tab && first_alt) || join->positions[i].use_join_buffer) |
| 15728 | { |
| 15729 | /* Find the best access method that would not use join buffering */ |
| 15730 | best_access_path(join, rs, reopt_remaining_tables, i, |
| 15731 | TRUE, rec_count, |
| 15732 | &pos, &loose_scan_pos); |
| 15733 | } |
| 15734 | else |
| 15735 | pos= join->positions[i]; |
| 15736 | |
| 15737 | if ((i == first_tab && first_alt)) |
| 15738 | pos= loose_scan_pos; |
| 15739 | |
| 15740 | reopt_remaining_tables &= ~rs->table->map; |
| 15741 | rec_count *= pos.records_read; |
| 15742 | cost += pos.read_time; |
| 15743 | |
| 15744 | if (!rs->emb_sj_nest) |
| 15745 | *outer_rec_count *= pos.records_read; |
| 15746 | } |
| 15747 | join->cur_sj_inner_tables= save_cur_sj_inner_tables; |
| 15748 | |
| 15749 | *reopt_cost= cost; |
| 15750 | } |
| 15751 | |
| 15752 | |
| 15753 | static COND * |
| 15754 | optimize_cond(JOIN *join, COND *conds, |
| 15755 | List<TABLE_LIST> *join_list, bool ignore_on_conds, |
| 15756 | Item::cond_result *cond_value, COND_EQUAL **cond_equal, |
| 15757 | int flags) |
| 15758 | { |
| 15759 | THD *thd= join->thd; |
| 15760 | DBUG_ENTER("optimize_cond" ); |
| 15761 | |
| 15762 | if (!conds) |
| 15763 | { |
| 15764 | *cond_value= Item::COND_TRUE; |
| 15765 | if (!ignore_on_conds) |
| 15766 | build_equal_items(join, NULL, NULL, join_list, ignore_on_conds, |
| 15767 | cond_equal); |
| 15768 | } |
| 15769 | else |
| 15770 | { |
| 15771 | /* |
| 15772 | Build all multiple equality predicates and eliminate equality |
| 15773 | predicates that can be inferred from these multiple equalities. |
| 15774 | For each reference of a field included into a multiple equality |
| 15775 | that occurs in a function set a pointer to the multiple equality |
| 15776 | predicate. Substitute a constant instead of this field if the |
| 15777 | multiple equality contains a constant. |
| 15778 | */ |
| 15779 | DBUG_EXECUTE("where" , print_where(conds, "original" , QT_ORDINARY);); |
| 15780 | conds= build_equal_items(join, conds, NULL, join_list, |
| 15781 | ignore_on_conds, cond_equal, |
| 15782 | MY_TEST(flags & OPT_LINK_EQUAL_FIELDS)); |
| 15783 | DBUG_EXECUTE("where" ,print_where(conds,"after equal_items" , QT_ORDINARY);); |
| 15784 | |
| 15785 | /* change field = field to field = const for each found field = const */ |
| 15786 | propagate_cond_constants(thd, (I_List<COND_CMP> *) 0, conds, conds); |
| 15787 | /* |
| 15788 | Remove all instances of item == item |
| 15789 | Remove all and-levels where CONST item != CONST item |
| 15790 | */ |
| 15791 | DBUG_EXECUTE("where" ,print_where(conds,"after const change" , QT_ORDINARY);); |
| 15792 | conds= conds->remove_eq_conds(thd, cond_value, true); |
| 15793 | if (conds && conds->type() == Item::COND_ITEM && |
| 15794 | ((Item_cond*) conds)->functype() == Item_func::COND_AND_FUNC) |
| 15795 | *cond_equal= &((Item_cond_and*) conds)->m_cond_equal; |
| 15796 | DBUG_EXECUTE("info" ,print_where(conds,"after remove" , QT_ORDINARY);); |
| 15797 | } |
| 15798 | DBUG_RETURN(conds); |
| 15799 | } |
| 15800 | |
| 15801 | |
| 15802 | /** |
| 15803 | @brief |
| 15804 | Propagate multiple equalities to the sub-expressions of a condition |
| 15805 | |
| 15806 | @param thd thread handle |
| 15807 | @param cond the condition where equalities are to be propagated |
| 15808 | @param *new_equalities the multiple equalities to be propagated |
| 15809 | @param inherited path to all inherited multiple equality items |
| 15810 | @param[out] is_simplifiable_cond 'cond' may be simplified after the |
| 15811 | propagation of the equalities |
| 15812 | |
| 15813 | @details |
| 15814 | The function recursively traverses the tree of the condition 'cond' and |
| 15815 | for each its AND sub-level of any depth the function merges the multiple |
| 15816 | equalities from the list 'new_equalities' into the multiple equalities |
| 15817 | attached to the AND item created for this sub-level. |
| 15818 | The function also [re]sets references to the equalities formed by the |
| 15819 | merges of multiple equalities in all field items occurred in 'cond' |
| 15820 | that are encountered in the equalities. |
| 15821 | If the result of any merge of multiple equalities is an impossible |
| 15822 | condition the function returns TRUE in the parameter is_simplifiable_cond. |
| 15823 | */ |
| 15824 | |
| 15825 | void propagate_new_equalities(THD *thd, Item *cond, |
| 15826 | List<Item_equal> *new_equalities, |
| 15827 | COND_EQUAL *inherited, |
| 15828 | bool *is_simplifiable_cond) |
| 15829 | { |
| 15830 | if (cond->type() == Item::COND_ITEM) |
| 15831 | { |
| 15832 | bool and_level= ((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC; |
| 15833 | if (and_level) |
| 15834 | { |
| 15835 | Item_cond_and *cond_and= (Item_cond_and *) cond; |
| 15836 | List<Item_equal> *cond_equalities= &cond_and->m_cond_equal.current_level; |
| 15837 | cond_and->m_cond_equal.upper_levels= inherited; |
| 15838 | if (!cond_equalities->is_empty() && cond_equalities != new_equalities) |
| 15839 | { |
| 15840 | Item_equal *equal_item; |
| 15841 | List_iterator<Item_equal> it(*new_equalities); |
| 15842 | while ((equal_item= it++)) |
| 15843 | { |
| 15844 | equal_item->merge_into_list(thd, cond_equalities, true, true); |
| 15845 | } |
| 15846 | List_iterator<Item_equal> ei(*cond_equalities); |
| 15847 | while ((equal_item= ei++)) |
| 15848 | { |
| 15849 | if (equal_item->const_item() && !equal_item->val_int()) |
| 15850 | { |
| 15851 | *is_simplifiable_cond= true; |
| 15852 | return; |
| 15853 | } |
| 15854 | } |
| 15855 | } |
| 15856 | } |
| 15857 | |
| 15858 | Item *item; |
| 15859 | List_iterator<Item> li(*((Item_cond*) cond)->argument_list()); |
| 15860 | while ((item= li++)) |
| 15861 | { |
| 15862 | COND_EQUAL *new_inherited= and_level && item->type() == Item::COND_ITEM ? |
| 15863 | &((Item_cond_and *) cond)->m_cond_equal : |
| 15864 | inherited; |
| 15865 | propagate_new_equalities(thd, item, new_equalities, new_inherited, |
| 15866 | is_simplifiable_cond); |
| 15867 | } |
| 15868 | } |
| 15869 | else if (cond->type() == Item::FUNC_ITEM && |
| 15870 | ((Item_cond*) cond)->functype() == Item_func::MULT_EQUAL_FUNC) |
| 15871 | { |
| 15872 | Item_equal *equal_item; |
| 15873 | List_iterator<Item_equal> it(*new_equalities); |
| 15874 | Item_equal *equality= (Item_equal *) cond; |
| 15875 | equality->upper_levels= inherited; |
| 15876 | while ((equal_item= it++)) |
| 15877 | { |
| 15878 | equality->merge_with_check(thd, equal_item, true); |
| 15879 | } |
| 15880 | if (equality->const_item() && !equality->val_int()) |
| 15881 | *is_simplifiable_cond= true; |
| 15882 | } |
| 15883 | else |
| 15884 | { |
| 15885 | cond= cond->propagate_equal_fields(thd, |
| 15886 | Item::Context_boolean(), inherited); |
| 15887 | cond->update_used_tables(); |
| 15888 | } |
| 15889 | } |
| 15890 | |
| 15891 | /* |
| 15892 | Check if cond_is_datetime_is_null() is true for the condition cond, or |
| 15893 | for any of its AND/OR-children |
| 15894 | */ |
| 15895 | bool cond_has_datetime_is_null(Item *cond) |
| 15896 | { |
| 15897 | if (cond_is_datetime_is_null(cond)) |
| 15898 | return true; |
| 15899 | |
| 15900 | if (cond->type() == Item::COND_ITEM) |
| 15901 | { |
| 15902 | List<Item> *cond_arg_list= ((Item_cond*) cond)->argument_list(); |
| 15903 | List_iterator<Item> li(*cond_arg_list); |
| 15904 | Item *item; |
| 15905 | while ((item= li++)) |
| 15906 | { |
| 15907 | if (cond_has_datetime_is_null(item)) |
| 15908 | return true; |
| 15909 | } |
| 15910 | } |
| 15911 | return false; |
| 15912 | } |
| 15913 | |
| 15914 | /* |
| 15915 | Check if passed condtition has for of |
| 15916 | |
| 15917 | not_null_date_col IS NULL |
| 15918 | |
| 15919 | where not_null_date_col has a datte or datetime type |
| 15920 | */ |
| 15921 | |
| 15922 | bool cond_is_datetime_is_null(Item *cond) |
| 15923 | { |
| 15924 | if (cond->type() == Item::FUNC_ITEM && |
| 15925 | ((Item_func*) cond)->functype() == Item_func::ISNULL_FUNC) |
| 15926 | { |
| 15927 | return ((Item_func_isnull*) cond)->arg_is_datetime_notnull_field(); |
| 15928 | } |
| 15929 | return false; |
| 15930 | } |
| 15931 | |
| 15932 | |
| 15933 | /** |
| 15934 | @brief |
| 15935 | Evaluate all constant boolean sub-expressions in a condition |
| 15936 | |
| 15937 | @param thd thread handle |
| 15938 | @param cond condition where where to evaluate constant sub-expressions |
| 15939 | @param[out] cond_value : the returned value of the condition |
| 15940 | (TRUE/FALSE/UNKNOWN: |
| 15941 | Item::COND_TRUE/Item::COND_FALSE/Item::COND_OK) |
| 15942 | @return |
| 15943 | the item that is the result of the substitution of all inexpensive constant |
| 15944 | boolean sub-expressions into cond, or, |
| 15945 | NULL if the condition is constant and is evaluated to FALSE. |
| 15946 | |
| 15947 | @details |
| 15948 | This function looks for all inexpensive constant boolean sub-expressions in |
| 15949 | the given condition 'cond' and substitutes them for their values. |
| 15950 | For example, the condition 2 > (5 + 1) or a < (10 / 2) |
| 15951 | will be transformed to the condition a < (10 / 2). |
| 15952 | Note that a constant sub-expression is evaluated only if it is constant and |
| 15953 | inexpensive. A sub-expression with an uncorrelated subquery may be evaluated |
| 15954 | only if the subquery is considered as inexpensive. |
| 15955 | The function does not evaluate a constant sub-expression if it is not on one |
| 15956 | of AND/OR levels of the condition 'cond'. For example, the subquery in the |
| 15957 | condition a > (select max(b) from t1 where b > 5) will never be evaluated |
| 15958 | by this function. |
| 15959 | If a constant boolean sub-expression is evaluated to TRUE then: |
| 15960 | - when the sub-expression is a conjunct of an AND formula it is simply |
| 15961 | removed from this formula |
| 15962 | - when the sub-expression is a disjunct of an OR formula the whole OR |
| 15963 | formula is converted to TRUE |
| 15964 | If a constant boolean sub-expression is evaluated to FALSE then: |
| 15965 | - when the sub-expression is a disjunct of an OR formula it is simply |
| 15966 | removed from this formula |
| 15967 | - when the sub-expression is a conjuct of an AND formula the whole AND |
| 15968 | formula is converted to FALSE |
| 15969 | When a disjunct/conjunct is removed from an OR/AND formula it might happen |
| 15970 | that there is only one conjunct/disjunct remaining. In this case this |
| 15971 | remaining disjunct/conjunct must be merged into underlying AND/OR formula, |
| 15972 | because AND/OR levels must alternate in the same way as they alternate |
| 15973 | after fix_fields() is called for the original condition. |
| 15974 | The specifics of merging a formula f into an AND formula A appears |
| 15975 | when A contains multiple equalities and f contains multiple equalities. |
| 15976 | In this case the multiple equalities from f and A have to be merged. |
| 15977 | After this the resulting multiple equalities have to be propagated into |
| 15978 | the all AND/OR levels of the formula A (see propagate_new_equalities()). |
| 15979 | The propagation of multiple equalities might result in forming multiple |
| 15980 | equalities that are always FALSE. This, in its turn, might trigger further |
| 15981 | simplification of the condition. |
| 15982 | |
| 15983 | @note |
| 15984 | EXAMPLE 1: |
| 15985 | SELECT * FROM t1 WHERE (b = 1 OR a = 1) AND (b = 5 AND a = 5 OR 1 != 1); |
| 15986 | First 1 != 1 will be removed from the second conjunct: |
| 15987 | => SELECT * FROM t1 WHERE (b = 1 OR a = 1) AND (b = 5 AND a = 5); |
| 15988 | Then (b = 5 AND a = 5) will be merged into the top level condition: |
| 15989 | => SELECT * FROM t1 WHERE (b = 1 OR a = 1) AND (b = 5) AND (a = 5); |
| 15990 | Then (b = 5), (a = 5) will be propagated into the disjuncs of |
| 15991 | (b = 1 OR a = 1): |
| 15992 | => SELECT * FROM t1 WHERE ((b = 1) AND (b = 5) AND (a = 5) OR |
| 15993 | (a = 1) AND (b = 5) AND (a = 5)) AND |
| 15994 | (b = 5) AND (a = 5) |
| 15995 | => SELECT * FROM t1 WHERE ((FALSE AND (a = 5)) OR |
| 15996 | (FALSE AND (b = 5))) AND |
| 15997 | (b = 5) AND (a = 5) |
| 15998 | After this an additional call of remove_eq_conds() converts it |
| 15999 | to FALSE |
| 16000 | |
| 16001 | EXAMPLE 2: |
| 16002 | SELECT * FROM t1 WHERE (b = 1 OR a = 5) AND (b = 5 AND a = 5 OR 1 != 1); |
| 16003 | => SELECT * FROM t1 WHERE (b = 1 OR a = 5) AND (b = 5 AND a = 5); |
| 16004 | => SELECT * FROM t1 WHERE (b = 1 OR a = 5) AND (b = 5) AND (a = 5); |
| 16005 | => SELECT * FROM t1 WHERE ((b = 1) AND (b = 5) AND (a = 5) OR |
| 16006 | (a = 5) AND (b = 5) AND (a = 5)) AND |
| 16007 | (b = 5) AND (a = 5) |
| 16008 | => SELECT * FROM t1 WHERE ((FALSE AND (a = 5)) OR |
| 16009 | ((b = 5) AND (a = 5))) AND |
| 16010 | (b = 5) AND (a = 5) |
| 16011 | After this an additional call of remove_eq_conds() converts it to |
| 16012 | => SELECT * FROM t1 WHERE (b = 5) AND (a = 5) |
| 16013 | */ |
| 16014 | |
| 16015 | |
| 16016 | COND * |
| 16017 | Item_cond::remove_eq_conds(THD *thd, Item::cond_result *cond_value, |
| 16018 | bool top_level_arg) |
| 16019 | { |
| 16020 | bool and_level= functype() == Item_func::COND_AND_FUNC; |
| 16021 | List<Item> *cond_arg_list= argument_list(); |
| 16022 | |
| 16023 | if (and_level) |
| 16024 | { |
| 16025 | /* |
| 16026 | Remove multiple equalities that became always true (e.g. after |
| 16027 | constant row substitution). |
| 16028 | They would be removed later in the function anyway, but the list of |
| 16029 | them cond_equal.current_level also must be adjusted correspondingly. |
| 16030 | So it's easier to do it at one pass through the list of the equalities. |
| 16031 | */ |
| 16032 | List<Item_equal> *cond_equalities= |
| 16033 | &((Item_cond_and *) this)->m_cond_equal.current_level; |
| 16034 | cond_arg_list->disjoin((List<Item> *) cond_equalities); |
| 16035 | List_iterator<Item_equal> it(*cond_equalities); |
| 16036 | Item_equal *eq_item; |
| 16037 | while ((eq_item= it++)) |
| 16038 | { |
| 16039 | if (eq_item->const_item() && eq_item->val_int()) |
| 16040 | it.remove(); |
| 16041 | } |
| 16042 | cond_arg_list->append((List<Item> *) cond_equalities); |
| 16043 | } |
| 16044 | |
| 16045 | List<Item_equal> new_equalities; |
| 16046 | List_iterator<Item> li(*cond_arg_list); |
| 16047 | bool should_fix_fields= 0; |
| 16048 | Item::cond_result tmp_cond_value; |
| 16049 | Item *item; |
| 16050 | |
| 16051 | /* |
| 16052 | If the list cond_arg_list became empty then it consisted only |
| 16053 | of always true multiple equalities. |
| 16054 | */ |
| 16055 | *cond_value= cond_arg_list->elements ? Item::COND_UNDEF : Item::COND_TRUE; |
| 16056 | |
| 16057 | while ((item=li++)) |
| 16058 | { |
| 16059 | Item *new_item= item->remove_eq_conds(thd, &tmp_cond_value, false); |
| 16060 | if (!new_item) |
| 16061 | { |
| 16062 | /* This can happen only when item is converted to TRUE or FALSE */ |
| 16063 | li.remove(); |
| 16064 | } |
| 16065 | else if (item != new_item) |
| 16066 | { |
| 16067 | /* |
| 16068 | This can happen when: |
| 16069 | - item was an OR formula converted to one disjunct |
| 16070 | - item was an AND formula converted to one conjunct |
| 16071 | In these cases the disjunct/conjunct must be merged into the |
| 16072 | argument list of cond. |
| 16073 | */ |
| 16074 | if (new_item->type() == Item::COND_ITEM && |
| 16075 | item->type() == Item::COND_ITEM) |
| 16076 | { |
| 16077 | DBUG_ASSERT(functype() == ((Item_cond *) new_item)->functype()); |
| 16078 | List<Item> *new_item_arg_list= |
| 16079 | ((Item_cond *) new_item)->argument_list(); |
| 16080 | if (and_level) |
| 16081 | { |
| 16082 | /* |
| 16083 | If new_item is an AND formula then multiple equalities |
| 16084 | of new_item_arg_list must merged into multiple equalities |
| 16085 | of cond_arg_list. |
| 16086 | */ |
| 16087 | List<Item_equal> *new_item_equalities= |
| 16088 | &((Item_cond_and *) new_item)->m_cond_equal.current_level; |
| 16089 | if (!new_item_equalities->is_empty()) |
| 16090 | { |
| 16091 | /* |
| 16092 | Cut the multiple equalities from the new_item_arg_list and |
| 16093 | append them on the list new_equalities. Later the equalities |
| 16094 | from this list will be merged into the multiple equalities |
| 16095 | of cond_arg_list all together. |
| 16096 | */ |
| 16097 | new_item_arg_list->disjoin((List<Item> *) new_item_equalities); |
| 16098 | new_equalities.append(new_item_equalities); |
| 16099 | } |
| 16100 | } |
| 16101 | if (new_item_arg_list->is_empty()) |
| 16102 | li.remove(); |
| 16103 | else |
| 16104 | { |
| 16105 | uint cnt= new_item_arg_list->elements; |
| 16106 | li.replace(*new_item_arg_list); |
| 16107 | /* Make iterator li ignore new items */ |
| 16108 | for (cnt--; cnt; cnt--) |
| 16109 | li++; |
| 16110 | should_fix_fields= 1; |
| 16111 | } |
| 16112 | } |
| 16113 | else if (and_level && |
| 16114 | new_item->type() == Item::FUNC_ITEM && |
| 16115 | ((Item_cond*) new_item)->functype() == |
| 16116 | Item_func::MULT_EQUAL_FUNC) |
| 16117 | { |
| 16118 | li.remove(); |
| 16119 | new_equalities.push_back((Item_equal *) new_item, thd->mem_root); |
| 16120 | } |
| 16121 | else |
| 16122 | { |
| 16123 | if (new_item->type() == Item::COND_ITEM && |
| 16124 | ((Item_cond*) new_item)->functype() == functype()) |
| 16125 | { |
| 16126 | List<Item> *new_item_arg_list= |
| 16127 | ((Item_cond *) new_item)->argument_list(); |
| 16128 | uint cnt= new_item_arg_list->elements; |
| 16129 | li.replace(*new_item_arg_list); |
| 16130 | /* Make iterator li ignore new items */ |
| 16131 | for (cnt--; cnt; cnt--) |
| 16132 | li++; |
| 16133 | } |
| 16134 | else |
| 16135 | li.replace(new_item); |
| 16136 | should_fix_fields= 1; |
| 16137 | } |
| 16138 | } |
| 16139 | if (*cond_value == Item::COND_UNDEF) |
| 16140 | *cond_value= tmp_cond_value; |
| 16141 | switch (tmp_cond_value) { |
| 16142 | case Item::COND_OK: // Not TRUE or FALSE |
| 16143 | if (and_level || *cond_value == Item::COND_FALSE) |
| 16144 | *cond_value=tmp_cond_value; |
| 16145 | break; |
| 16146 | case Item::COND_FALSE: |
| 16147 | if (and_level) |
| 16148 | { |
| 16149 | *cond_value= tmp_cond_value; |
| 16150 | return (COND*) 0; // Always false |
| 16151 | } |
| 16152 | break; |
| 16153 | case Item::COND_TRUE: |
| 16154 | if (!and_level) |
| 16155 | { |
| 16156 | *cond_value= tmp_cond_value; |
| 16157 | return (COND*) 0; // Always true |
| 16158 | } |
| 16159 | break; |
| 16160 | case Item::COND_UNDEF: // Impossible |
| 16161 | break; /* purecov: deadcode */ |
| 16162 | } |
| 16163 | } |
| 16164 | COND *cond= this; |
| 16165 | if (!new_equalities.is_empty()) |
| 16166 | { |
| 16167 | DBUG_ASSERT(and_level); |
| 16168 | /* |
| 16169 | Merge multiple equalities that were cut from the results of |
| 16170 | simplification of OR formulas converted into AND formulas. |
| 16171 | These multiple equalities are to be merged into the |
| 16172 | multiple equalities of cond_arg_list. |
| 16173 | */ |
| 16174 | COND_EQUAL *cond_equal= &((Item_cond_and *) this)->m_cond_equal; |
| 16175 | List<Item_equal> *cond_equalities= &cond_equal->current_level; |
| 16176 | cond_arg_list->disjoin((List<Item> *) cond_equalities); |
| 16177 | Item_equal *equality; |
| 16178 | List_iterator_fast<Item_equal> it(new_equalities); |
| 16179 | while ((equality= it++)) |
| 16180 | { |
| 16181 | equality->upper_levels= cond_equal->upper_levels; |
| 16182 | equality->merge_into_list(thd, cond_equalities, false, false); |
| 16183 | List_iterator_fast<Item_equal> ei(*cond_equalities); |
| 16184 | while ((equality= ei++)) |
| 16185 | { |
| 16186 | if (equality->const_item() && !equality->val_int()) |
| 16187 | { |
| 16188 | *cond_value= Item::COND_FALSE; |
| 16189 | return (COND*) 0; |
| 16190 | } |
| 16191 | } |
| 16192 | } |
| 16193 | cond_arg_list->append((List<Item> *) cond_equalities); |
| 16194 | /* |
| 16195 | Propagate the newly formed multiple equalities to |
| 16196 | the all AND/OR levels of cond |
| 16197 | */ |
| 16198 | bool is_simplifiable_cond= false; |
| 16199 | propagate_new_equalities(thd, this, cond_equalities, |
| 16200 | cond_equal->upper_levels, |
| 16201 | &is_simplifiable_cond); |
| 16202 | /* |
| 16203 | If the above propagation of multiple equalities brings us |
| 16204 | to multiple equalities that are always FALSE then try to |
| 16205 | simplify the condition with remove_eq_cond() again. |
| 16206 | */ |
| 16207 | if (is_simplifiable_cond) |
| 16208 | { |
| 16209 | if (!(cond= cond->remove_eq_conds(thd, cond_value, false))) |
| 16210 | return cond; |
| 16211 | } |
| 16212 | should_fix_fields= 1; |
| 16213 | } |
| 16214 | if (should_fix_fields) |
| 16215 | cond->update_used_tables(); |
| 16216 | |
| 16217 | if (!((Item_cond*) cond)->argument_list()->elements || |
| 16218 | *cond_value != Item::COND_OK) |
| 16219 | return (COND*) 0; |
| 16220 | if (((Item_cond*) cond)->argument_list()->elements == 1) |
| 16221 | { // Remove list |
| 16222 | item= ((Item_cond*) cond)->argument_list()->head(); |
| 16223 | ((Item_cond*) cond)->argument_list()->empty(); |
| 16224 | return item; |
| 16225 | } |
| 16226 | *cond_value= Item::COND_OK; |
| 16227 | return cond; |
| 16228 | } |
| 16229 | |
| 16230 | |
| 16231 | COND * |
| 16232 | Item::remove_eq_conds(THD *thd, Item::cond_result *cond_value, bool top_level_arg) |
| 16233 | { |
| 16234 | if (const_item() && !is_expensive()) |
| 16235 | { |
| 16236 | *cond_value= eval_const_cond(this) ? Item::COND_TRUE : Item::COND_FALSE; |
| 16237 | return (COND*) 0; |
| 16238 | } |
| 16239 | *cond_value= Item::COND_OK; |
| 16240 | return this; // Point at next and level |
| 16241 | } |
| 16242 | |
| 16243 | |
| 16244 | COND * |
| 16245 | Item_bool_func2::remove_eq_conds(THD *thd, Item::cond_result *cond_value, |
| 16246 | bool top_level_arg) |
| 16247 | { |
| 16248 | if (const_item() && !is_expensive()) |
| 16249 | { |
| 16250 | *cond_value= eval_const_cond(this) ? Item::COND_TRUE : Item::COND_FALSE; |
| 16251 | return (COND*) 0; |
| 16252 | } |
| 16253 | if ((*cond_value= eq_cmp_result()) != Item::COND_OK) |
| 16254 | { |
| 16255 | if (args[0]->eq(args[1], true)) |
| 16256 | { |
| 16257 | if (!args[0]->maybe_null || functype() == Item_func::EQUAL_FUNC) |
| 16258 | return (COND*) 0; // Compare of identical items |
| 16259 | } |
| 16260 | } |
| 16261 | *cond_value= Item::COND_OK; |
| 16262 | return this; // Point at next and level |
| 16263 | } |
| 16264 | |
| 16265 | |
| 16266 | /** |
| 16267 | Remove const and eq items. Return new item, or NULL if no condition |
| 16268 | cond_value is set to according: |
| 16269 | COND_OK query is possible (field = constant) |
| 16270 | COND_TRUE always true ( 1 = 1 ) |
| 16271 | COND_FALSE always false ( 1 = 2 ) |
| 16272 | |
| 16273 | SYNPOSIS |
| 16274 | remove_eq_conds() |
| 16275 | thd THD environment |
| 16276 | cond the condition to handle |
| 16277 | cond_value the resulting value of the condition |
| 16278 | |
| 16279 | NOTES |
| 16280 | calls the inner_remove_eq_conds to check all the tree reqursively |
| 16281 | |
| 16282 | RETURN |
| 16283 | *COND with the simplified condition |
| 16284 | */ |
| 16285 | |
| 16286 | COND * |
| 16287 | Item_func_isnull::remove_eq_conds(THD *thd, Item::cond_result *cond_value, |
| 16288 | bool top_level_arg) |
| 16289 | { |
| 16290 | Item *real_item= args[0]->real_item(); |
| 16291 | if (real_item->type() == Item::FIELD_ITEM) |
| 16292 | { |
| 16293 | Field *field= ((Item_field*) real_item)->field; |
| 16294 | |
| 16295 | if (((field->type() == MYSQL_TYPE_DATE) || |
| 16296 | (field->type() == MYSQL_TYPE_DATETIME)) && |
| 16297 | (field->flags & NOT_NULL_FLAG)) |
| 16298 | { |
| 16299 | /* fix to replace 'NULL' dates with '0' (shreeve@uci.edu) */ |
| 16300 | /* |
| 16301 | See BUG#12594011 |
| 16302 | Documentation says that |
| 16303 | SELECT datetime_notnull d FROM t1 WHERE d IS NULL |
| 16304 | shall return rows where d=='0000-00-00' |
| 16305 | |
| 16306 | Thus, for DATE and DATETIME columns defined as NOT NULL, |
| 16307 | "date_notnull IS NULL" has to be modified to |
| 16308 | "date_notnull IS NULL OR date_notnull == 0" (if outer join) |
| 16309 | "date_notnull == 0" (otherwise) |
| 16310 | |
| 16311 | */ |
| 16312 | |
| 16313 | Item *item0= new(thd->mem_root) Item_int(thd, (longlong) 0, 1); |
| 16314 | Item *eq_cond= new(thd->mem_root) Item_func_eq(thd, args[0], item0); |
| 16315 | if (!eq_cond) |
| 16316 | return this; |
| 16317 | |
| 16318 | COND *cond= this; |
| 16319 | if (field->table->pos_in_table_list->is_inner_table_of_outer_join()) |
| 16320 | { |
| 16321 | // outer join: transform "col IS NULL" to "col IS NULL or col=0" |
| 16322 | Item *or_cond= new(thd->mem_root) Item_cond_or(thd, eq_cond, this); |
| 16323 | if (!or_cond) |
| 16324 | return this; |
| 16325 | cond= or_cond; |
| 16326 | } |
| 16327 | else |
| 16328 | { |
| 16329 | // not outer join: transform "col IS NULL" to "col=0" |
| 16330 | cond= eq_cond; |
| 16331 | } |
| 16332 | |
| 16333 | cond->fix_fields(thd, &cond); |
| 16334 | /* |
| 16335 | Note: although args[0] is a field, cond can still be a constant |
| 16336 | (in case field is a part of a dependent subquery). |
| 16337 | |
| 16338 | Note: we call cond->Item::remove_eq_conds() non-virtually (statically) |
| 16339 | for performance purpose. |
| 16340 | A non-qualified call, i.e. just cond->remove_eq_conds(), |
| 16341 | would call Item_bool_func2::remove_eq_conds() instead, which would |
| 16342 | try to do some extra job to detect if args[0] and args[1] are |
| 16343 | equivalent items. We know they are not (we have field=0 here). |
| 16344 | */ |
| 16345 | return cond->Item::remove_eq_conds(thd, cond_value, false); |
| 16346 | } |
| 16347 | |
| 16348 | /* |
| 16349 | Handles this special case for some ODBC applications: |
| 16350 | The are requesting the row that was just updated with a auto_increment |
| 16351 | value with this construct: |
| 16352 | |
| 16353 | SELECT * from table_name where auto_increment_column IS NULL |
| 16354 | This will be changed to: |
| 16355 | SELECT * from table_name where auto_increment_column = LAST_INSERT_ID |
| 16356 | |
| 16357 | Note, this substitution is done if the NULL test is the only condition! |
| 16358 | If the NULL test is a part of a more complex condition, it is not |
| 16359 | substituted and is treated normally: |
| 16360 | WHERE auto_increment IS NULL AND something_else |
| 16361 | */ |
| 16362 | |
| 16363 | if (top_level_arg) // "auto_increment_column IS NULL" is the only condition |
| 16364 | { |
| 16365 | if (field->flags & AUTO_INCREMENT_FLAG && !field->table->maybe_null && |
| 16366 | (thd->variables.option_bits & OPTION_AUTO_IS_NULL) && |
| 16367 | (thd->first_successful_insert_id_in_prev_stmt > 0 && |
| 16368 | thd->substitute_null_with_insert_id)) |
| 16369 | { |
| 16370 | #ifdef HAVE_QUERY_CACHE |
| 16371 | query_cache_abort(thd, &thd->query_cache_tls); |
| 16372 | #endif |
| 16373 | COND *new_cond, *cond= this; |
| 16374 | /* If this fails, we will catch it later before executing query */ |
| 16375 | if ((new_cond= new (thd->mem_root) Item_func_eq(thd, args[0], |
| 16376 | new (thd->mem_root) Item_int(thd, "last_insert_id()" , |
| 16377 | thd->read_first_successful_insert_id_in_prev_stmt(), |
| 16378 | MY_INT64_NUM_DECIMAL_DIGITS)))) |
| 16379 | { |
| 16380 | cond= new_cond; |
| 16381 | /* |
| 16382 | Item_func_eq can't be fixed after creation so we do not check |
| 16383 | cond->fixed, also it do not need tables so we use 0 as second |
| 16384 | argument. |
| 16385 | */ |
| 16386 | cond->fix_fields(thd, &cond); |
| 16387 | } |
| 16388 | /* |
| 16389 | IS NULL should be mapped to LAST_INSERT_ID only for first row, so |
| 16390 | clear for next row |
| 16391 | */ |
| 16392 | thd->substitute_null_with_insert_id= FALSE; |
| 16393 | |
| 16394 | *cond_value= Item::COND_OK; |
| 16395 | return cond; |
| 16396 | } |
| 16397 | } |
| 16398 | } |
| 16399 | return Item::remove_eq_conds(thd, cond_value, top_level_arg); |
| 16400 | } |
| 16401 | |
| 16402 | |
| 16403 | /** |
| 16404 | Check if equality can be used in removing components of GROUP BY/DISTINCT |
| 16405 | |
| 16406 | @param l the left comparison argument (a field if any) |
| 16407 | @param r the right comparison argument (a const of any) |
| 16408 | |
| 16409 | @details |
| 16410 | Checks if an equality predicate can be used to take away |
| 16411 | DISTINCT/GROUP BY because it is known to be true for exactly one |
| 16412 | distinct value (e.g. <expr> == <const>). |
| 16413 | Arguments must be compared in the native type of the left argument |
| 16414 | and (for strings) in the native collation of the left argument. |
| 16415 | Otherwise, for example, |
| 16416 | <string_field> = <int_const> may match more than 1 distinct value or |
| 16417 | the <string_field>. |
| 16418 | |
| 16419 | @note We don't need to aggregate l and r collations here, because r - |
| 16420 | the constant item - has already been converted to a proper collation |
| 16421 | for comparison. We only need to compare this collation with field's collation. |
| 16422 | |
| 16423 | @retval true can be used |
| 16424 | @retval false cannot be used |
| 16425 | */ |
| 16426 | |
| 16427 | /* |
| 16428 | psergey-todo: this returns false for int_column='1234' (here '1234' is a |
| 16429 | constant. Need to discuss this with Bar). |
| 16430 | |
| 16431 | See also Field::test_if_equality_guaranees_uniqueness(const Item *item); |
| 16432 | */ |
| 16433 | static bool |
| 16434 | test_if_equality_guarantees_uniqueness(Item *l, Item *r) |
| 16435 | { |
| 16436 | return (r->const_item() || !(r->used_tables() & ~OUTER_REF_TABLE_BIT)) && |
| 16437 | item_cmp_type(l, r) == l->cmp_type() && |
| 16438 | (l->cmp_type() != STRING_RESULT || |
| 16439 | l->collation.collation == r->collation.collation); |
| 16440 | } |
| 16441 | |
| 16442 | |
| 16443 | /* |
| 16444 | Return TRUE if i1 and i2 (if any) are equal items, |
| 16445 | or if i1 is a wrapper item around the f2 field. |
| 16446 | */ |
| 16447 | |
| 16448 | static bool equal(Item *i1, Item *i2, Field *f2) |
| 16449 | { |
| 16450 | DBUG_ASSERT((i2 == NULL) ^ (f2 == NULL)); |
| 16451 | |
| 16452 | if (i2 != NULL) |
| 16453 | return i1->eq(i2, 1); |
| 16454 | else if (i1->type() == Item::FIELD_ITEM) |
| 16455 | return f2->eq(((Item_field *) i1)->field); |
| 16456 | else |
| 16457 | return FALSE; |
| 16458 | } |
| 16459 | |
| 16460 | |
| 16461 | /** |
| 16462 | Test if a field or an item is equal to a constant value in WHERE |
| 16463 | |
| 16464 | @param cond WHERE clause expression |
| 16465 | @param comp_item Item to find in WHERE expression |
| 16466 | (if comp_field != NULL) |
| 16467 | @param comp_field Field to find in WHERE expression |
| 16468 | (if comp_item != NULL) |
| 16469 | @param[out] const_item intermediate arg, set to Item pointer to NULL |
| 16470 | |
| 16471 | @return TRUE if the field is a constant value in WHERE |
| 16472 | |
| 16473 | @note |
| 16474 | comp_item and comp_field parameters are mutually exclusive. |
| 16475 | */ |
| 16476 | bool |
| 16477 | const_expression_in_where(COND *cond, Item *comp_item, Field *comp_field, |
| 16478 | Item **const_item) |
| 16479 | { |
| 16480 | DBUG_ASSERT((comp_item == NULL) ^ (comp_field == NULL)); |
| 16481 | |
| 16482 | Item *intermediate= NULL; |
| 16483 | if (const_item == NULL) |
| 16484 | const_item= &intermediate; |
| 16485 | |
| 16486 | if (cond->type() == Item::COND_ITEM) |
| 16487 | { |
| 16488 | bool and_level= (((Item_cond*) cond)->functype() |
| 16489 | == Item_func::COND_AND_FUNC); |
| 16490 | List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list()); |
| 16491 | Item *item; |
| 16492 | while ((item=li++)) |
| 16493 | { |
| 16494 | bool res=const_expression_in_where(item, comp_item, comp_field, |
| 16495 | const_item); |
| 16496 | if (res) // Is a const value |
| 16497 | { |
| 16498 | if (and_level) |
| 16499 | return 1; |
| 16500 | } |
| 16501 | else if (!and_level) |
| 16502 | return 0; |
| 16503 | } |
| 16504 | return and_level ? 0 : 1; |
| 16505 | } |
| 16506 | else if (cond->eq_cmp_result() != Item::COND_OK) |
| 16507 | { // boolean compare function |
| 16508 | Item_func* func= (Item_func*) cond; |
| 16509 | if (func->functype() != Item_func::EQUAL_FUNC && |
| 16510 | func->functype() != Item_func::EQ_FUNC) |
| 16511 | return 0; |
| 16512 | Item *left_item= ((Item_func*) cond)->arguments()[0]; |
| 16513 | Item *right_item= ((Item_func*) cond)->arguments()[1]; |
| 16514 | if (equal(left_item, comp_item, comp_field)) |
| 16515 | { |
| 16516 | if (test_if_equality_guarantees_uniqueness (left_item, right_item)) |
| 16517 | { |
| 16518 | if (*const_item) |
| 16519 | return right_item->eq(*const_item, 1); |
| 16520 | *const_item=right_item; |
| 16521 | return 1; |
| 16522 | } |
| 16523 | } |
| 16524 | else if (equal(right_item, comp_item, comp_field)) |
| 16525 | { |
| 16526 | if (test_if_equality_guarantees_uniqueness (right_item, left_item)) |
| 16527 | { |
| 16528 | if (*const_item) |
| 16529 | return left_item->eq(*const_item, 1); |
| 16530 | *const_item=left_item; |
| 16531 | return 1; |
| 16532 | } |
| 16533 | } |
| 16534 | } |
| 16535 | return 0; |
| 16536 | } |
| 16537 | |
| 16538 | |
| 16539 | /**************************************************************************** |
| 16540 | Create internal temporary table |
| 16541 | ****************************************************************************/ |
| 16542 | |
| 16543 | /** |
| 16544 | Create field for temporary table from given field. |
| 16545 | |
| 16546 | @param thd Thread handler |
| 16547 | @param org_field field from which new field will be created |
| 16548 | @param name New field name |
| 16549 | @param table Temporary table |
| 16550 | @param item !=NULL if item->result_field should point to new field. |
| 16551 | This is relevant for how fill_record() is going to work: |
| 16552 | If item != NULL then fill_record() will update |
| 16553 | the record in the original table. |
| 16554 | If item == NULL then fill_record() will update |
| 16555 | the temporary table |
| 16556 | |
| 16557 | @retval |
| 16558 | NULL on error |
| 16559 | @retval |
| 16560 | new_created field |
| 16561 | */ |
| 16562 | |
| 16563 | Field *create_tmp_field_from_field(THD *thd, Field *org_field, |
| 16564 | LEX_CSTRING *name, TABLE *table, |
| 16565 | Item_field *item) |
| 16566 | { |
| 16567 | Field *new_field; |
| 16568 | |
| 16569 | new_field= org_field->make_new_field(thd->mem_root, table, |
| 16570 | table == org_field->table); |
| 16571 | if (new_field) |
| 16572 | { |
| 16573 | new_field->init(table); |
| 16574 | new_field->orig_table= org_field->orig_table; |
| 16575 | if (item) |
| 16576 | item->result_field= new_field; |
| 16577 | else |
| 16578 | new_field->field_name= *name; |
| 16579 | new_field->flags|= org_field->flags & NO_DEFAULT_VALUE_FLAG; |
| 16580 | if (org_field->maybe_null() || (item && item->maybe_null)) |
| 16581 | new_field->flags&= ~NOT_NULL_FLAG; // Because of outer join |
| 16582 | if (org_field->type() == MYSQL_TYPE_VAR_STRING || |
| 16583 | org_field->type() == MYSQL_TYPE_VARCHAR) |
| 16584 | table->s->db_create_options|= HA_OPTION_PACK_RECORD; |
| 16585 | else if (org_field->type() == FIELD_TYPE_DOUBLE) |
| 16586 | ((Field_double *) new_field)->not_fixed= TRUE; |
| 16587 | new_field->vcol_info= 0; |
| 16588 | new_field->cond_selectivity= 1.0; |
| 16589 | new_field->next_equal_field= NULL; |
| 16590 | new_field->option_list= NULL; |
| 16591 | new_field->option_struct= NULL; |
| 16592 | } |
| 16593 | return new_field; |
| 16594 | } |
| 16595 | |
| 16596 | |
| 16597 | Field *Item::create_tmp_field_int(TABLE *table, uint convert_int_length) |
| 16598 | { |
| 16599 | const Type_handler *h= &type_handler_long; |
| 16600 | if (max_char_length() > convert_int_length) |
| 16601 | h= &type_handler_longlong; |
| 16602 | return h->make_and_init_table_field(&name, Record_addr(maybe_null), |
| 16603 | *this, table); |
| 16604 | } |
| 16605 | |
| 16606 | |
| 16607 | Field *Item_sum::create_tmp_field(bool group, TABLE *table) |
| 16608 | { |
| 16609 | Field *UNINIT_VAR(new_field); |
| 16610 | MEM_ROOT *mem_root= table->in_use->mem_root; |
| 16611 | |
| 16612 | switch (cmp_type()) { |
| 16613 | case REAL_RESULT: |
| 16614 | { |
| 16615 | new_field= new (mem_root) |
| 16616 | Field_double(max_char_length(), maybe_null, &name, decimals, TRUE); |
| 16617 | break; |
| 16618 | } |
| 16619 | case INT_RESULT: |
| 16620 | case TIME_RESULT: |
| 16621 | case DECIMAL_RESULT: |
| 16622 | case STRING_RESULT: |
| 16623 | new_field= tmp_table_field_from_field_type(table); |
| 16624 | break; |
| 16625 | case ROW_RESULT: |
| 16626 | // This case should never be choosen |
| 16627 | DBUG_ASSERT(0); |
| 16628 | new_field= 0; |
| 16629 | break; |
| 16630 | } |
| 16631 | if (new_field) |
| 16632 | new_field->init(table); |
| 16633 | return new_field; |
| 16634 | } |
| 16635 | |
| 16636 | |
| 16637 | static void create_tmp_field_from_item_finalize(THD *thd, |
| 16638 | Field *new_field, |
| 16639 | Item *item, |
| 16640 | Item ***copy_func, |
| 16641 | bool modify_item) |
| 16642 | { |
| 16643 | if (copy_func && |
| 16644 | (item->is_result_field() || |
| 16645 | (item->real_item()->is_result_field()))) |
| 16646 | *((*copy_func)++) = item; // Save for copy_funcs |
| 16647 | if (modify_item) |
| 16648 | item->set_result_field(new_field); |
| 16649 | if (item->type() == Item::NULL_ITEM) |
| 16650 | new_field->is_created_from_null_item= TRUE; |
| 16651 | } |
| 16652 | |
| 16653 | |
| 16654 | /** |
| 16655 | Create field for temporary table using type of given item. |
| 16656 | |
| 16657 | @param thd Thread handler |
| 16658 | @param item Item to create a field for |
| 16659 | @param table Temporary table |
| 16660 | @param copy_func If set and item is a function, store copy of |
| 16661 | item in this array |
| 16662 | @param modify_item 1 if item->result_field should point to new |
| 16663 | item. This is relevent for how fill_record() |
| 16664 | is going to work: |
| 16665 | If modify_item is 1 then fill_record() will |
| 16666 | update the record in the original table. |
| 16667 | If modify_item is 0 then fill_record() will |
| 16668 | update the temporary table |
| 16669 | |
| 16670 | @retval |
| 16671 | 0 on error |
| 16672 | @retval |
| 16673 | new_created field |
| 16674 | */ |
| 16675 | |
| 16676 | static Field *create_tmp_field_from_item(THD *thd, Item *item, TABLE *table, |
| 16677 | Item ***copy_func, bool modify_item) |
| 16678 | { |
| 16679 | Field *UNINIT_VAR(new_field); |
| 16680 | DBUG_ASSERT(thd == table->in_use); |
| 16681 | if ((new_field= item->create_tmp_field(false, table))) |
| 16682 | create_tmp_field_from_item_finalize(thd, new_field, item, |
| 16683 | copy_func, modify_item); |
| 16684 | return new_field; |
| 16685 | } |
| 16686 | |
| 16687 | |
| 16688 | /** |
| 16689 | Create field for information schema table. |
| 16690 | |
| 16691 | @param thd Thread handler |
| 16692 | @param table Temporary table |
| 16693 | @param item Item to create a field for |
| 16694 | |
| 16695 | @retval |
| 16696 | 0 on error |
| 16697 | @retval |
| 16698 | new_created field |
| 16699 | */ |
| 16700 | |
| 16701 | Field *Item::create_field_for_schema(THD *thd, TABLE *table) |
| 16702 | { |
| 16703 | if (field_type() == MYSQL_TYPE_VARCHAR) |
| 16704 | { |
| 16705 | Field *field; |
| 16706 | if (max_length > MAX_FIELD_VARCHARLENGTH) |
| 16707 | field= new (thd->mem_root) Field_blob(max_length, maybe_null, &name, |
| 16708 | collation.collation); |
| 16709 | else if (max_length > 0) |
| 16710 | field= new (thd->mem_root) Field_varstring(max_length, maybe_null, &name, |
| 16711 | table->s, |
| 16712 | collation.collation); |
| 16713 | else |
| 16714 | field= new Field_null((uchar*) 0, 0, Field::NONE, &name, |
| 16715 | collation.collation); |
| 16716 | if (field) |
| 16717 | field->init(table); |
| 16718 | return field; |
| 16719 | } |
| 16720 | return tmp_table_field_from_field_type(table); |
| 16721 | } |
| 16722 | |
| 16723 | |
| 16724 | /** |
| 16725 | Create field for temporary table. |
| 16726 | |
| 16727 | @param thd Thread handler |
| 16728 | @param table Temporary table |
| 16729 | @param item Item to create a field for |
| 16730 | @param type Type of item (normally item->type) |
| 16731 | @param copy_func If set and item is a function, store copy of item |
| 16732 | in this array |
| 16733 | @param from_field if field will be created using other field as example, |
| 16734 | pointer example field will be written here |
| 16735 | @param default_field If field has a default value field, store it here |
| 16736 | @param group 1 if we are going to do a relative group by on result |
| 16737 | @param modify_item 1 if item->result_field should point to new item. |
| 16738 | This is relevent for how fill_record() is going to |
| 16739 | work: |
| 16740 | If modify_item is 1 then fill_record() will update |
| 16741 | the record in the original table. |
| 16742 | If modify_item is 0 then fill_record() will update |
| 16743 | the temporary table |
| 16744 | |
| 16745 | @retval |
| 16746 | 0 on error |
| 16747 | @retval |
| 16748 | new_created field |
| 16749 | */ |
| 16750 | |
| 16751 | Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, |
| 16752 | Item ***copy_func, Field **from_field, |
| 16753 | Field **default_field, |
| 16754 | bool group, bool modify_item, |
| 16755 | bool table_cant_handle_bit_fields, |
| 16756 | bool make_copy_field) |
| 16757 | { |
| 16758 | Field *result; |
| 16759 | Item::Type orig_type= type; |
| 16760 | Item *orig_item= 0; |
| 16761 | |
| 16762 | DBUG_ASSERT(thd == table->in_use); |
| 16763 | |
| 16764 | if (type != Item::FIELD_ITEM && |
| 16765 | item->real_item()->type() == Item::FIELD_ITEM) |
| 16766 | { |
| 16767 | orig_item= item; |
| 16768 | item= item->real_item(); |
| 16769 | type= Item::FIELD_ITEM; |
| 16770 | } |
| 16771 | |
| 16772 | switch (type) { |
| 16773 | case Item::TYPE_HOLDER: |
| 16774 | case Item::SUM_FUNC_ITEM: |
| 16775 | { |
| 16776 | result= item->create_tmp_field(group, table); |
| 16777 | if (!result) |
| 16778 | my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR)); |
| 16779 | return result; |
| 16780 | } |
| 16781 | case Item::FIELD_ITEM: |
| 16782 | case Item::DEFAULT_VALUE_ITEM: |
| 16783 | case Item::INSERT_VALUE_ITEM: |
| 16784 | case Item::TRIGGER_FIELD_ITEM: |
| 16785 | { |
| 16786 | Item_field *field= (Item_field*) item; |
| 16787 | bool orig_modify= modify_item; |
| 16788 | if (orig_type == Item::REF_ITEM) |
| 16789 | modify_item= 0; |
| 16790 | /* |
| 16791 | If item have to be able to store NULLs but underlaid field can't do it, |
| 16792 | create_tmp_field_from_field() can't be used for tmp field creation. |
| 16793 | */ |
| 16794 | if (((field->maybe_null && field->in_rollup) || |
| 16795 | (thd->create_tmp_table_for_derived && /* for mat. view/dt */ |
| 16796 | orig_item && orig_item->maybe_null)) && |
| 16797 | !field->field->maybe_null()) |
| 16798 | { |
| 16799 | bool save_maybe_null= FALSE; |
| 16800 | /* |
| 16801 | The item the ref points to may have maybe_null flag set while |
| 16802 | the ref doesn't have it. This may happen for outer fields |
| 16803 | when the outer query decided at some point after name resolution phase |
| 16804 | that this field might be null. Take this into account here. |
| 16805 | */ |
| 16806 | if (orig_item) |
| 16807 | { |
| 16808 | save_maybe_null= item->maybe_null; |
| 16809 | item->maybe_null= orig_item->maybe_null; |
| 16810 | } |
| 16811 | result= create_tmp_field_from_item(thd, item, table, NULL, |
| 16812 | modify_item); |
| 16813 | *from_field= field->field; |
| 16814 | if (result && modify_item) |
| 16815 | field->result_field= result; |
| 16816 | if (orig_item) |
| 16817 | item->maybe_null= save_maybe_null; |
| 16818 | } |
| 16819 | else if (table_cant_handle_bit_fields && field->field->type() == |
| 16820 | MYSQL_TYPE_BIT) |
| 16821 | { |
| 16822 | const Type_handler *handler= item->type_handler_long_or_longlong(); |
| 16823 | *from_field= field->field; |
| 16824 | if ((result= |
| 16825 | handler->make_and_init_table_field(&item->name, |
| 16826 | Record_addr(item->maybe_null), |
| 16827 | *item, table))) |
| 16828 | create_tmp_field_from_item_finalize(thd, result, item, |
| 16829 | copy_func, modify_item); |
| 16830 | if (result && modify_item) |
| 16831 | field->result_field= result; |
| 16832 | } |
| 16833 | else |
| 16834 | { |
| 16835 | LEX_CSTRING *tmp= orig_item ? &orig_item->name : &item->name; |
| 16836 | result= create_tmp_field_from_field(thd, (*from_field= field->field), |
| 16837 | tmp, table, |
| 16838 | modify_item ? field : |
| 16839 | NULL); |
| 16840 | } |
| 16841 | |
| 16842 | if (orig_type == Item::REF_ITEM && orig_modify) |
| 16843 | ((Item_ref*)orig_item)->set_result_field(result); |
| 16844 | /* |
| 16845 | Fields that are used as arguments to the DEFAULT() function already have |
| 16846 | their data pointers set to the default value during name resolution. See |
| 16847 | Item_default_value::fix_fields. |
| 16848 | */ |
| 16849 | if (orig_type != Item::DEFAULT_VALUE_ITEM && field->field->eq_def(result)) |
| 16850 | *default_field= field->field; |
| 16851 | return result; |
| 16852 | } |
| 16853 | /* Fall through */ |
| 16854 | case Item::FUNC_ITEM: |
| 16855 | if (((Item_func *) item)->functype() == Item_func::FUNC_SP) |
| 16856 | { |
| 16857 | Item_func_sp *item_func_sp= (Item_func_sp *) item; |
| 16858 | Field *sp_result_field= item_func_sp->get_sp_result_field(); |
| 16859 | |
| 16860 | if (make_copy_field) |
| 16861 | { |
| 16862 | DBUG_ASSERT(item_func_sp->result_field); |
| 16863 | *from_field= item_func_sp->result_field; |
| 16864 | } |
| 16865 | else |
| 16866 | { |
| 16867 | *((*copy_func)++)= item; |
| 16868 | } |
| 16869 | Field *result_field= |
| 16870 | create_tmp_field_from_field(thd, |
| 16871 | sp_result_field, |
| 16872 | &item_func_sp->name, |
| 16873 | table, |
| 16874 | NULL); |
| 16875 | |
| 16876 | if (modify_item) |
| 16877 | item->set_result_field(result_field); |
| 16878 | |
| 16879 | return result_field; |
| 16880 | } |
| 16881 | |
| 16882 | /* Fall through */ |
| 16883 | case Item::COND_ITEM: |
| 16884 | case Item::FIELD_AVG_ITEM: |
| 16885 | case Item::FIELD_STD_ITEM: |
| 16886 | case Item::SUBSELECT_ITEM: |
| 16887 | /* The following can only happen with 'CREATE TABLE ... SELECT' */ |
| 16888 | case Item::PROC_ITEM: |
| 16889 | case Item::INT_ITEM: |
| 16890 | case Item::REAL_ITEM: |
| 16891 | case Item::DECIMAL_ITEM: |
| 16892 | case Item::STRING_ITEM: |
| 16893 | case Item::DATE_ITEM: |
| 16894 | case Item::REF_ITEM: |
| 16895 | case Item::NULL_ITEM: |
| 16896 | case Item::VARBIN_ITEM: |
| 16897 | case Item::CACHE_ITEM: |
| 16898 | case Item::WINDOW_FUNC_ITEM: // psergey-winfunc: |
| 16899 | case Item::EXPR_CACHE_ITEM: |
| 16900 | case Item::PARAM_ITEM: |
| 16901 | if (make_copy_field) |
| 16902 | { |
| 16903 | DBUG_ASSERT(((Item_result_field*)item)->result_field); |
| 16904 | *from_field= ((Item_result_field*)item)->result_field; |
| 16905 | } |
| 16906 | return create_tmp_field_from_item(thd, item, table, |
| 16907 | (make_copy_field ? 0 : copy_func), |
| 16908 | modify_item); |
| 16909 | default: // Dosen't have to be stored |
| 16910 | return 0; |
| 16911 | } |
| 16912 | } |
| 16913 | |
| 16914 | /* |
| 16915 | Set up column usage bitmaps for a temporary table |
| 16916 | |
| 16917 | IMPLEMENTATION |
| 16918 | For temporary tables, we need one bitmap with all columns set and |
| 16919 | a tmp_set bitmap to be used by things like filesort. |
| 16920 | */ |
| 16921 | |
| 16922 | void |
| 16923 | setup_tmp_table_column_bitmaps(TABLE *table, uchar *bitmaps, uint field_count) |
| 16924 | { |
| 16925 | uint bitmap_size= bitmap_buffer_size(field_count); |
| 16926 | |
| 16927 | DBUG_ASSERT(table->s->virtual_fields == 0 && table->def_vcol_set == 0); |
| 16928 | |
| 16929 | my_bitmap_init(&table->def_read_set, (my_bitmap_map*) bitmaps, field_count, |
| 16930 | FALSE); |
| 16931 | bitmaps+= bitmap_size; |
| 16932 | my_bitmap_init(&table->tmp_set, |
| 16933 | (my_bitmap_map*) bitmaps, field_count, FALSE); |
| 16934 | bitmaps+= bitmap_size; |
| 16935 | my_bitmap_init(&table->eq_join_set, |
| 16936 | (my_bitmap_map*) bitmaps, field_count, FALSE); |
| 16937 | bitmaps+= bitmap_size; |
| 16938 | my_bitmap_init(&table->cond_set, |
| 16939 | (my_bitmap_map*) bitmaps, field_count, FALSE); |
| 16940 | bitmaps+= bitmap_size; |
| 16941 | my_bitmap_init(&table->has_value_set, |
| 16942 | (my_bitmap_map*) bitmaps, field_count, FALSE); |
| 16943 | /* write_set and all_set are copies of read_set */ |
| 16944 | table->def_write_set= table->def_read_set; |
| 16945 | table->s->all_set= table->def_read_set; |
| 16946 | bitmap_set_all(&table->s->all_set); |
| 16947 | table->default_column_bitmaps(); |
| 16948 | } |
| 16949 | |
| 16950 | |
| 16951 | void |
| 16952 | setup_tmp_table_column_bitmaps(TABLE *table, uchar *bitmaps) |
| 16953 | { |
| 16954 | setup_tmp_table_column_bitmaps(table, bitmaps, table->s->fields); |
| 16955 | } |
| 16956 | |
| 16957 | |
| 16958 | /** |
| 16959 | Create a temp table according to a field list. |
| 16960 | |
| 16961 | Given field pointers are changed to point at tmp_table for |
| 16962 | send_result_set_metadata. The table object is self contained: it's |
| 16963 | allocated in its own memory root, as well as Field objects |
| 16964 | created for table columns. |
| 16965 | This function will replace Item_sum items in 'fields' list with |
| 16966 | corresponding Item_field items, pointing at the fields in the |
| 16967 | temporary table, unless this was prohibited by TRUE |
| 16968 | value of argument save_sum_fields. The Item_field objects |
| 16969 | are created in THD memory root. |
| 16970 | |
| 16971 | @param thd thread handle |
| 16972 | @param param a description used as input to create the table |
| 16973 | @param fields list of items that will be used to define |
| 16974 | column types of the table (also see NOTES) |
| 16975 | @param group Create an unique key over all group by fields. |
| 16976 | This is used to retrive the row during |
| 16977 | end_write_group() and update them. |
| 16978 | @param distinct should table rows be distinct |
| 16979 | @param save_sum_fields see NOTES |
| 16980 | @param select_options Optiions for how the select is run. |
| 16981 | See sql_priv.h for a list of options. |
| 16982 | @param rows_limit Maximum number of rows to insert into the |
| 16983 | temporary table |
| 16984 | @param table_alias possible name of the temporary table that can |
| 16985 | be used for name resolving; can be "". |
| 16986 | @param do_not_open only create the TABLE object, do not |
| 16987 | open the table in the engine |
| 16988 | @param keep_row_order rows need to be read in the order they were |
| 16989 | inserted, the engine should preserve this order |
| 16990 | */ |
| 16991 | |
| 16992 | TABLE * |
| 16993 | create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields, |
| 16994 | ORDER *group, bool distinct, bool save_sum_fields, |
| 16995 | ulonglong select_options, ha_rows rows_limit, |
| 16996 | const LEX_CSTRING *table_alias, bool do_not_open, |
| 16997 | bool keep_row_order) |
| 16998 | { |
| 16999 | MEM_ROOT *mem_root_save, own_root; |
| 17000 | TABLE *table; |
| 17001 | TABLE_SHARE *share; |
| 17002 | uint i,field_count,null_count,null_pack_length; |
| 17003 | uint copy_func_count= param->func_count; |
| 17004 | uint hidden_null_count, hidden_null_pack_length, hidden_field_count; |
| 17005 | uint blob_count,group_null_items, string_count; |
| 17006 | uint temp_pool_slot=MY_BIT_NONE; |
| 17007 | uint fieldnr= 0; |
| 17008 | ulong reclength, string_total_length; |
| 17009 | bool using_unique_constraint= false; |
| 17010 | bool use_packed_rows= false; |
| 17011 | bool not_all_columns= !(select_options & TMP_TABLE_ALL_COLUMNS); |
| 17012 | char *tmpname,path[FN_REFLEN]; |
| 17013 | uchar *pos, *group_buff, *bitmaps; |
| 17014 | uchar *null_flags; |
| 17015 | Field **reg_field, **from_field, **default_field; |
| 17016 | uint *blob_field; |
| 17017 | Copy_field *copy=0; |
| 17018 | KEY *keyinfo; |
| 17019 | KEY_PART_INFO *key_part_info; |
| 17020 | Item **copy_func; |
| 17021 | TMP_ENGINE_COLUMNDEF *recinfo; |
| 17022 | /* |
| 17023 | total_uneven_bit_length is uneven bit length for visible fields |
| 17024 | hidden_uneven_bit_length is uneven bit length for hidden fields |
| 17025 | */ |
| 17026 | uint total_uneven_bit_length= 0, hidden_uneven_bit_length= 0; |
| 17027 | bool force_copy_fields= param->force_copy_fields; |
| 17028 | /* Treat sum functions as normal ones when loose index scan is used. */ |
| 17029 | save_sum_fields|= param->precomputed_group_by; |
| 17030 | DBUG_ENTER("create_tmp_table" ); |
| 17031 | DBUG_PRINT("enter" , |
| 17032 | ("table_alias: '%s' distinct: %d save_sum_fields: %d " |
| 17033 | "rows_limit: %lu group: %d" , table_alias->str, |
| 17034 | (int) distinct, (int) save_sum_fields, |
| 17035 | (ulong) rows_limit, MY_TEST(group))); |
| 17036 | |
| 17037 | if (use_temp_pool && !(test_flags & TEST_KEEP_TMP_TABLES)) |
| 17038 | temp_pool_slot = bitmap_lock_set_next(&temp_pool); |
| 17039 | |
| 17040 | if (temp_pool_slot != MY_BIT_NONE) // we got a slot |
| 17041 | sprintf(path, "%s_%lx_%i" , tmp_file_prefix, |
| 17042 | current_pid, temp_pool_slot); |
| 17043 | else |
| 17044 | { |
| 17045 | /* if we run out of slots or we are not using tempool */ |
| 17046 | sprintf(path, "%s%lx_%lx_%x" , tmp_file_prefix,current_pid, |
| 17047 | (ulong) thd->thread_id, thd->tmp_table++); |
| 17048 | } |
| 17049 | |
| 17050 | /* |
| 17051 | No need to change table name to lower case as we are only creating |
| 17052 | MyISAM, Aria or HEAP tables here |
| 17053 | */ |
| 17054 | fn_format(path, path, mysql_tmpdir, "" , |
| 17055 | MY_REPLACE_EXT|MY_UNPACK_FILENAME); |
| 17056 | |
| 17057 | if (group) |
| 17058 | { |
| 17059 | ORDER **prev= &group; |
| 17060 | if (!param->quick_group) |
| 17061 | group=0; // Can't use group key |
| 17062 | else for (ORDER *tmp=group ; tmp ; tmp=tmp->next) |
| 17063 | { |
| 17064 | /* Exclude found constant from the list */ |
| 17065 | if ((*tmp->item)->const_item()) |
| 17066 | { |
| 17067 | *prev= tmp->next; |
| 17068 | param->group_parts--; |
| 17069 | continue; |
| 17070 | } |
| 17071 | else |
| 17072 | prev= &(tmp->next); |
| 17073 | /* |
| 17074 | marker == 4 means two things: |
| 17075 | - store NULLs in the key, and |
| 17076 | - convert BIT fields to 64-bit long, needed because MEMORY tables |
| 17077 | can't index BIT fields. |
| 17078 | */ |
| 17079 | (*tmp->item)->marker=4; // Store null in key |
| 17080 | if ((*tmp->item)->too_big_for_varchar()) |
| 17081 | using_unique_constraint= true; |
| 17082 | } |
| 17083 | if (param->group_length >= MAX_BLOB_WIDTH) |
| 17084 | using_unique_constraint= true; |
| 17085 | if (group) |
| 17086 | distinct=0; // Can't use distinct |
| 17087 | } |
| 17088 | |
| 17089 | field_count=param->field_count+param->func_count+param->sum_func_count; |
| 17090 | hidden_field_count=param->hidden_field_count; |
| 17091 | |
| 17092 | /* |
| 17093 | When loose index scan is employed as access method, it already |
| 17094 | computes all groups and the result of all aggregate functions. We |
| 17095 | make space for the items of the aggregate function in the list of |
| 17096 | functions TMP_TABLE_PARAM::items_to_copy, so that the values of |
| 17097 | these items are stored in the temporary table. |
| 17098 | */ |
| 17099 | if (param->precomputed_group_by) |
| 17100 | copy_func_count+= param->sum_func_count; |
| 17101 | |
| 17102 | init_sql_alloc(&own_root, "tmp_table" , TABLE_ALLOC_BLOCK_SIZE, 0, |
| 17103 | MYF(MY_THREAD_SPECIFIC)); |
| 17104 | |
| 17105 | if (!multi_alloc_root(&own_root, |
| 17106 | &table, sizeof(*table), |
| 17107 | &share, sizeof(*share), |
| 17108 | ®_field, sizeof(Field*) * (field_count+1), |
| 17109 | &default_field, sizeof(Field*) * (field_count), |
| 17110 | &blob_field, sizeof(uint)*(field_count+1), |
| 17111 | &from_field, sizeof(Field*)*field_count, |
| 17112 | ©_func, sizeof(*copy_func)*(copy_func_count+1), |
| 17113 | ¶m->keyinfo, sizeof(*param->keyinfo), |
| 17114 | &key_part_info, |
| 17115 | sizeof(*key_part_info)*(param->group_parts+1), |
| 17116 | ¶m->start_recinfo, |
| 17117 | sizeof(*param->recinfo)*(field_count*2+4), |
| 17118 | &tmpname, (uint) strlen(path)+1, |
| 17119 | &group_buff, (group && ! using_unique_constraint ? |
| 17120 | param->group_length : 0), |
| 17121 | &bitmaps, bitmap_buffer_size(field_count)*6, |
| 17122 | NullS)) |
| 17123 | { |
| 17124 | if (temp_pool_slot != MY_BIT_NONE) |
| 17125 | bitmap_lock_clear_bit(&temp_pool, temp_pool_slot); |
| 17126 | DBUG_RETURN(NULL); /* purecov: inspected */ |
| 17127 | } |
| 17128 | /* Copy_field belongs to TMP_TABLE_PARAM, allocate it in THD mem_root */ |
| 17129 | if (!(param->copy_field= copy= new (thd->mem_root) Copy_field[field_count])) |
| 17130 | { |
| 17131 | if (temp_pool_slot != MY_BIT_NONE) |
| 17132 | bitmap_lock_clear_bit(&temp_pool, temp_pool_slot); |
| 17133 | free_root(&own_root, MYF(0)); /* purecov: inspected */ |
| 17134 | DBUG_RETURN(NULL); /* purecov: inspected */ |
| 17135 | } |
| 17136 | param->items_to_copy= copy_func; |
| 17137 | strmov(tmpname, path); |
| 17138 | /* make table according to fields */ |
| 17139 | |
| 17140 | bzero((char*) table,sizeof(*table)); |
| 17141 | bzero((char*) reg_field,sizeof(Field*)*(field_count+1)); |
| 17142 | bzero((char*) default_field, sizeof(Field*) * (field_count)); |
| 17143 | bzero((char*) from_field,sizeof(Field*)*field_count); |
| 17144 | |
| 17145 | table->mem_root= own_root; |
| 17146 | mem_root_save= thd->mem_root; |
| 17147 | thd->mem_root= &table->mem_root; |
| 17148 | |
| 17149 | table->field=reg_field; |
| 17150 | table->alias.set(table_alias->str, table_alias->length, table_alias_charset); |
| 17151 | |
| 17152 | table->reginfo.lock_type=TL_WRITE; /* Will be updated */ |
| 17153 | table->map=1; |
| 17154 | table->temp_pool_slot = temp_pool_slot; |
| 17155 | table->copy_blobs= 1; |
| 17156 | table->in_use= thd; |
| 17157 | table->quick_keys.init(); |
| 17158 | table->covering_keys.init(); |
| 17159 | table->intersect_keys.init(); |
| 17160 | table->keys_in_use_for_query.init(); |
| 17161 | table->no_rows_with_nulls= param->force_not_null_cols; |
| 17162 | |
| 17163 | table->s= share; |
| 17164 | init_tmp_table_share(thd, share, "" , 0, tmpname, tmpname); |
| 17165 | share->blob_field= blob_field; |
| 17166 | share->table_charset= param->table_charset; |
| 17167 | share->primary_key= MAX_KEY; // Indicate no primary key |
| 17168 | share->keys_for_keyread.init(); |
| 17169 | share->keys_in_use.init(); |
| 17170 | if (param->schema_table) |
| 17171 | share->db= INFORMATION_SCHEMA_NAME; |
| 17172 | |
| 17173 | /* Calculate which type of fields we will store in the temporary table */ |
| 17174 | |
| 17175 | reclength= string_total_length= 0; |
| 17176 | blob_count= string_count= null_count= hidden_null_count= group_null_items= 0; |
| 17177 | param->using_outer_summary_function= 0; |
| 17178 | |
| 17179 | List_iterator_fast<Item> li(fields); |
| 17180 | Item *item; |
| 17181 | Field **tmp_from_field=from_field; |
| 17182 | while ((item=li++)) |
| 17183 | { |
| 17184 | Item::Type type= item->type(); |
| 17185 | if (type == Item::COPY_STR_ITEM) |
| 17186 | { |
| 17187 | item= ((Item_copy *)item)->get_item(); |
| 17188 | type= item->type(); |
| 17189 | } |
| 17190 | if (not_all_columns) |
| 17191 | { |
| 17192 | if (item->with_sum_func && type != Item::SUM_FUNC_ITEM) |
| 17193 | { |
| 17194 | if (item->used_tables() & OUTER_REF_TABLE_BIT) |
| 17195 | item->update_used_tables(); |
| 17196 | if ((item->real_type() == Item::SUBSELECT_ITEM) || |
| 17197 | (item->used_tables() & ~OUTER_REF_TABLE_BIT)) |
| 17198 | { |
| 17199 | /* |
| 17200 | Mark that the we have ignored an item that refers to a summary |
| 17201 | function. We need to know this if someone is going to use |
| 17202 | DISTINCT on the result. |
| 17203 | */ |
| 17204 | param->using_outer_summary_function=1; |
| 17205 | continue; |
| 17206 | } |
| 17207 | } |
| 17208 | if (item->const_item() && (int) hidden_field_count <= 0) |
| 17209 | continue; // We don't have to store this |
| 17210 | } |
| 17211 | if (type == Item::SUM_FUNC_ITEM && !group && !save_sum_fields) |
| 17212 | { /* Can't calc group yet */ |
| 17213 | Item_sum *sum_item= (Item_sum *) item; |
| 17214 | sum_item->result_field=0; |
| 17215 | for (i=0 ; i < sum_item->get_arg_count() ; i++) |
| 17216 | { |
| 17217 | Item *arg= sum_item->get_arg(i); |
| 17218 | if (!arg->const_item()) |
| 17219 | { |
| 17220 | Item *tmp_item; |
| 17221 | Field *new_field= |
| 17222 | create_tmp_field(thd, table, arg, arg->type(), ©_func, |
| 17223 | tmp_from_field, &default_field[fieldnr], |
| 17224 | group != 0,not_all_columns, |
| 17225 | distinct, false); |
| 17226 | if (!new_field) |
| 17227 | goto err; // Should be OOM |
| 17228 | DBUG_ASSERT(!new_field->field_name.str || strlen(new_field->field_name.str) == new_field->field_name.length); |
| 17229 | tmp_from_field++; |
| 17230 | reclength+=new_field->pack_length(); |
| 17231 | if (new_field->flags & BLOB_FLAG) |
| 17232 | { |
| 17233 | *blob_field++= fieldnr; |
| 17234 | blob_count++; |
| 17235 | } |
| 17236 | if (new_field->type() == MYSQL_TYPE_BIT) |
| 17237 | total_uneven_bit_length+= new_field->field_length & 7; |
| 17238 | *(reg_field++)= new_field; |
| 17239 | if (new_field->real_type() == MYSQL_TYPE_STRING || |
| 17240 | new_field->real_type() == MYSQL_TYPE_VARCHAR) |
| 17241 | { |
| 17242 | string_count++; |
| 17243 | string_total_length+= new_field->pack_length(); |
| 17244 | } |
| 17245 | thd->mem_root= mem_root_save; |
| 17246 | if (!(tmp_item= new (thd->mem_root) |
| 17247 | Item_temptable_field(thd, new_field))) |
| 17248 | goto err; |
| 17249 | arg= sum_item->set_arg(i, thd, tmp_item); |
| 17250 | thd->mem_root= &table->mem_root; |
| 17251 | if (param->force_not_null_cols) |
| 17252 | { |
| 17253 | new_field->flags|= NOT_NULL_FLAG; |
| 17254 | new_field->null_ptr= NULL; |
| 17255 | } |
| 17256 | if (!(new_field->flags & NOT_NULL_FLAG)) |
| 17257 | { |
| 17258 | null_count++; |
| 17259 | /* |
| 17260 | new_field->maybe_null() is still false, it will be |
| 17261 | changed below. But we have to setup Item_field correctly |
| 17262 | */ |
| 17263 | arg->maybe_null=1; |
| 17264 | } |
| 17265 | new_field->field_index= fieldnr++; |
| 17266 | } |
| 17267 | } |
| 17268 | } |
| 17269 | else |
| 17270 | { |
| 17271 | /* |
| 17272 | The last parameter to create_tmp_field() is a bit tricky: |
| 17273 | |
| 17274 | We need to set it to 0 in union, to get fill_record() to modify the |
| 17275 | temporary table. |
| 17276 | We need to set it to 1 on multi-table-update and in select to |
| 17277 | write rows to the temporary table. |
| 17278 | We here distinguish between UNION and multi-table-updates by the fact |
| 17279 | that in the later case group is set to the row pointer. |
| 17280 | |
| 17281 | The test for item->marker == 4 is ensure we don't create a group-by |
| 17282 | key over a bit field as heap tables can't handle that. |
| 17283 | */ |
| 17284 | Field *new_field= (param->schema_table) ? |
| 17285 | item->create_field_for_schema(thd, table) : |
| 17286 | create_tmp_field(thd, table, item, type, ©_func, |
| 17287 | tmp_from_field, &default_field[fieldnr], |
| 17288 | group != 0, |
| 17289 | !force_copy_fields && |
| 17290 | (not_all_columns || group !=0), |
| 17291 | /* |
| 17292 | If item->marker == 4 then we force create_tmp_field |
| 17293 | to create a 64-bit longs for BIT fields because HEAP |
| 17294 | tables can't index BIT fields directly. We do the |
| 17295 | same for distinct, as we want the distinct index |
| 17296 | to be usable in this case too. |
| 17297 | */ |
| 17298 | item->marker == 4 || param->bit_fields_as_long, |
| 17299 | force_copy_fields); |
| 17300 | |
| 17301 | if (unlikely(!new_field)) |
| 17302 | { |
| 17303 | if (unlikely(thd->is_fatal_error)) |
| 17304 | goto err; // Got OOM |
| 17305 | continue; // Some kind of const item |
| 17306 | } |
| 17307 | DBUG_ASSERT(!new_field->field_name.str || strlen(new_field->field_name.str) == new_field->field_name.length); |
| 17308 | if (type == Item::SUM_FUNC_ITEM) |
| 17309 | { |
| 17310 | Item_sum *agg_item= (Item_sum *) item; |
| 17311 | /* |
| 17312 | Update the result field only if it has never been set, or if the |
| 17313 | created temporary table is not to be used for subquery |
| 17314 | materialization. |
| 17315 | |
| 17316 | The reason is that for subqueries that require |
| 17317 | materialization as part of their plan, we create the |
| 17318 | 'external' temporary table needed for IN execution, after |
| 17319 | the 'internal' temporary table needed for grouping. Since |
| 17320 | both the external and the internal temporary tables are |
| 17321 | created for the same list of SELECT fields of the subquery, |
| 17322 | setting 'result_field' for each invocation of |
| 17323 | create_tmp_table overrides the previous value of |
| 17324 | 'result_field'. |
| 17325 | |
| 17326 | The condition below prevents the creation of the external |
| 17327 | temp table to override the 'result_field' that was set for |
| 17328 | the internal temp table. |
| 17329 | */ |
| 17330 | if (!agg_item->result_field || !param->materialized_subquery) |
| 17331 | agg_item->result_field= new_field; |
| 17332 | } |
| 17333 | tmp_from_field++; |
| 17334 | if (param->force_not_null_cols) |
| 17335 | { |
| 17336 | new_field->flags|= NOT_NULL_FLAG; |
| 17337 | new_field->null_ptr= NULL; |
| 17338 | } |
| 17339 | reclength+=new_field->pack_length(); |
| 17340 | if (!(new_field->flags & NOT_NULL_FLAG)) |
| 17341 | null_count++; |
| 17342 | if (new_field->type() == MYSQL_TYPE_BIT) |
| 17343 | total_uneven_bit_length+= new_field->field_length & 7; |
| 17344 | if (new_field->flags & BLOB_FLAG) |
| 17345 | { |
| 17346 | *blob_field++= fieldnr; |
| 17347 | blob_count++; |
| 17348 | } |
| 17349 | |
| 17350 | if (new_field->real_type() == MYSQL_TYPE_STRING || |
| 17351 | new_field->real_type() == MYSQL_TYPE_VARCHAR) |
| 17352 | { |
| 17353 | string_count++; |
| 17354 | string_total_length+= new_field->pack_length(); |
| 17355 | } |
| 17356 | |
| 17357 | if (item->marker == 4 && item->maybe_null) |
| 17358 | { |
| 17359 | group_null_items++; |
| 17360 | new_field->flags|= GROUP_FLAG; |
| 17361 | } |
| 17362 | new_field->field_index= fieldnr++; |
| 17363 | *(reg_field++)= new_field; |
| 17364 | } |
| 17365 | if (!--hidden_field_count) |
| 17366 | { |
| 17367 | /* |
| 17368 | This was the last hidden field; Remember how many hidden fields could |
| 17369 | have null |
| 17370 | */ |
| 17371 | hidden_null_count=null_count; |
| 17372 | /* |
| 17373 | We need to update hidden_field_count as we may have stored group |
| 17374 | functions with constant arguments |
| 17375 | */ |
| 17376 | param->hidden_field_count= fieldnr; |
| 17377 | null_count= 0; |
| 17378 | /* |
| 17379 | On last hidden field we store uneven bit length in |
| 17380 | hidden_uneven_bit_length and proceed calculation of |
| 17381 | uneven bits for visible fields into |
| 17382 | total_uneven_bit_length variable. |
| 17383 | */ |
| 17384 | hidden_uneven_bit_length= total_uneven_bit_length; |
| 17385 | total_uneven_bit_length= 0; |
| 17386 | } |
| 17387 | } |
| 17388 | DBUG_ASSERT(fieldnr == (uint) (reg_field - table->field)); |
| 17389 | DBUG_ASSERT(field_count >= (uint) (reg_field - table->field)); |
| 17390 | field_count= fieldnr; |
| 17391 | *reg_field= 0; |
| 17392 | *blob_field= 0; // End marker |
| 17393 | share->fields= field_count; |
| 17394 | share->column_bitmap_size= bitmap_buffer_size(share->fields); |
| 17395 | |
| 17396 | /* If result table is small; use a heap */ |
| 17397 | /* future: storage engine selection can be made dynamic? */ |
| 17398 | if (blob_count || using_unique_constraint |
| 17399 | || (thd->variables.big_tables && !(select_options & SELECT_SMALL_RESULT)) |
| 17400 | || (select_options & TMP_TABLE_FORCE_MYISAM) |
| 17401 | || thd->variables.tmp_memory_table_size == 0) |
| 17402 | { |
| 17403 | share->db_plugin= ha_lock_engine(0, TMP_ENGINE_HTON); |
| 17404 | table->file= get_new_handler(share, &table->mem_root, |
| 17405 | share->db_type()); |
| 17406 | if (group && |
| 17407 | (param->group_parts > table->file->max_key_parts() || |
| 17408 | param->group_length > table->file->max_key_length())) |
| 17409 | using_unique_constraint= true; |
| 17410 | } |
| 17411 | else |
| 17412 | { |
| 17413 | share->db_plugin= ha_lock_engine(0, heap_hton); |
| 17414 | table->file= get_new_handler(share, &table->mem_root, |
| 17415 | share->db_type()); |
| 17416 | } |
| 17417 | if (!table->file) |
| 17418 | goto err; |
| 17419 | |
| 17420 | if (table->file->set_ha_share_ref(&share->ha_share)) |
| 17421 | { |
| 17422 | delete table->file; |
| 17423 | goto err; |
| 17424 | } |
| 17425 | |
| 17426 | if (!using_unique_constraint) |
| 17427 | reclength+= group_null_items; // null flag is stored separately |
| 17428 | |
| 17429 | share->blob_fields= blob_count; |
| 17430 | if (blob_count == 0) |
| 17431 | { |
| 17432 | /* We need to ensure that first byte is not 0 for the delete link */ |
| 17433 | if (param->hidden_field_count) |
| 17434 | hidden_null_count++; |
| 17435 | else |
| 17436 | null_count++; |
| 17437 | } |
| 17438 | hidden_null_pack_length= (hidden_null_count + 7 + |
| 17439 | hidden_uneven_bit_length) / 8; |
| 17440 | null_pack_length= (hidden_null_pack_length + |
| 17441 | (null_count + total_uneven_bit_length + 7) / 8); |
| 17442 | reclength+=null_pack_length; |
| 17443 | if (!reclength) |
| 17444 | reclength=1; // Dummy select |
| 17445 | /* Use packed rows if there is blobs or a lot of space to gain */ |
| 17446 | if (blob_count || |
| 17447 | (string_total_length >= STRING_TOTAL_LENGTH_TO_PACK_ROWS && |
| 17448 | (reclength / string_total_length <= RATIO_TO_PACK_ROWS || |
| 17449 | string_total_length / string_count >= AVG_STRING_LENGTH_TO_PACK_ROWS))) |
| 17450 | use_packed_rows= 1; |
| 17451 | |
| 17452 | share->reclength= reclength; |
| 17453 | { |
| 17454 | uint alloc_length=ALIGN_SIZE(reclength+MI_UNIQUE_HASH_LENGTH+1); |
| 17455 | share->rec_buff_length= alloc_length; |
| 17456 | if (!(table->record[0]= (uchar*) |
| 17457 | alloc_root(&table->mem_root, alloc_length*3))) |
| 17458 | goto err; |
| 17459 | table->record[1]= table->record[0]+alloc_length; |
| 17460 | share->default_values= table->record[1]+alloc_length; |
| 17461 | } |
| 17462 | copy_func[0]=0; // End marker |
| 17463 | param->func_count= (uint)(copy_func - param->items_to_copy); |
| 17464 | |
| 17465 | setup_tmp_table_column_bitmaps(table, bitmaps); |
| 17466 | |
| 17467 | recinfo=param->start_recinfo; |
| 17468 | null_flags=(uchar*) table->record[0]; |
| 17469 | pos=table->record[0]+ null_pack_length; |
| 17470 | if (null_pack_length) |
| 17471 | { |
| 17472 | bzero((uchar*) recinfo,sizeof(*recinfo)); |
| 17473 | recinfo->type=FIELD_NORMAL; |
| 17474 | recinfo->length=null_pack_length; |
| 17475 | recinfo++; |
| 17476 | bfill(null_flags,null_pack_length,255); // Set null fields |
| 17477 | |
| 17478 | table->null_flags= (uchar*) table->record[0]; |
| 17479 | share->null_fields= null_count+ hidden_null_count; |
| 17480 | share->null_bytes= share->null_bytes_for_compare= null_pack_length; |
| 17481 | } |
| 17482 | null_count= (blob_count == 0) ? 1 : 0; |
| 17483 | hidden_field_count=param->hidden_field_count; |
| 17484 | for (i=0,reg_field=table->field; i < field_count; i++,reg_field++,recinfo++) |
| 17485 | { |
| 17486 | Field *field= *reg_field; |
| 17487 | uint length; |
| 17488 | bzero((uchar*) recinfo,sizeof(*recinfo)); |
| 17489 | |
| 17490 | if (!(field->flags & NOT_NULL_FLAG)) |
| 17491 | { |
| 17492 | recinfo->null_bit= (uint8)1 << (null_count & 7); |
| 17493 | recinfo->null_pos= null_count/8; |
| 17494 | field->move_field(pos,null_flags+null_count/8, |
| 17495 | (uint8)1 << (null_count & 7)); |
| 17496 | null_count++; |
| 17497 | } |
| 17498 | else |
| 17499 | field->move_field(pos,(uchar*) 0,0); |
| 17500 | if (field->type() == MYSQL_TYPE_BIT) |
| 17501 | { |
| 17502 | /* We have to reserve place for extra bits among null bits */ |
| 17503 | ((Field_bit*) field)->set_bit_ptr(null_flags + null_count / 8, |
| 17504 | null_count & 7); |
| 17505 | null_count+= (field->field_length & 7); |
| 17506 | } |
| 17507 | field->reset(); |
| 17508 | |
| 17509 | /* |
| 17510 | Test if there is a default field value. The test for ->ptr is to skip |
| 17511 | 'offset' fields generated by initalize_tables |
| 17512 | */ |
| 17513 | if (default_field[i] && default_field[i]->ptr) |
| 17514 | { |
| 17515 | /* |
| 17516 | default_field[i] is set only in the cases when 'field' can |
| 17517 | inherit the default value that is defined for the field referred |
| 17518 | by the Item_field object from which 'field' has been created. |
| 17519 | */ |
| 17520 | const Field *orig_field= default_field[i]; |
| 17521 | /* Get the value from default_values */ |
| 17522 | if (orig_field->is_null_in_record(orig_field->table->s->default_values)) |
| 17523 | field->set_null(); |
| 17524 | else |
| 17525 | { |
| 17526 | field->set_notnull(); |
| 17527 | memcpy(field->ptr, |
| 17528 | orig_field->ptr_in_record(orig_field->table->s->default_values), |
| 17529 | field->pack_length_in_rec()); |
| 17530 | } |
| 17531 | } |
| 17532 | |
| 17533 | if (from_field[i]) |
| 17534 | { /* Not a table Item */ |
| 17535 | copy->set(field,from_field[i],save_sum_fields); |
| 17536 | copy++; |
| 17537 | } |
| 17538 | length=field->pack_length(); |
| 17539 | pos+= length; |
| 17540 | |
| 17541 | /* Make entry for create table */ |
| 17542 | recinfo->length=length; |
| 17543 | if (field->flags & BLOB_FLAG) |
| 17544 | recinfo->type= FIELD_BLOB; |
| 17545 | else if (use_packed_rows && |
| 17546 | field->real_type() == MYSQL_TYPE_STRING && |
| 17547 | length >= MIN_STRING_LENGTH_TO_PACK_ROWS) |
| 17548 | recinfo->type= FIELD_SKIP_ENDSPACE; |
| 17549 | else if (field->real_type() == MYSQL_TYPE_VARCHAR) |
| 17550 | recinfo->type= FIELD_VARCHAR; |
| 17551 | else |
| 17552 | recinfo->type= FIELD_NORMAL; |
| 17553 | |
| 17554 | if (!--hidden_field_count) |
| 17555 | null_count=(null_count+7) & ~7; // move to next byte |
| 17556 | |
| 17557 | // fix table name in field entry |
| 17558 | field->set_table_name(&table->alias); |
| 17559 | } |
| 17560 | |
| 17561 | param->copy_field_end=copy; |
| 17562 | param->recinfo= recinfo; // Pointer to after last field |
| 17563 | store_record(table,s->default_values); // Make empty default record |
| 17564 | |
| 17565 | if (thd->variables.tmp_memory_table_size == ~ (ulonglong) 0) // No limit |
| 17566 | share->max_rows= ~(ha_rows) 0; |
| 17567 | else |
| 17568 | share->max_rows= (ha_rows) (((share->db_type() == heap_hton) ? |
| 17569 | MY_MIN(thd->variables.tmp_memory_table_size, |
| 17570 | thd->variables.max_heap_table_size) : |
| 17571 | thd->variables.tmp_memory_table_size) / |
| 17572 | share->reclength); |
| 17573 | set_if_bigger(share->max_rows,1); // For dummy start options |
| 17574 | /* |
| 17575 | Push the LIMIT clause to the temporary table creation, so that we |
| 17576 | materialize only up to 'rows_limit' records instead of all result records. |
| 17577 | */ |
| 17578 | set_if_smaller(share->max_rows, rows_limit); |
| 17579 | param->end_write_records= rows_limit; |
| 17580 | |
| 17581 | keyinfo= param->keyinfo; |
| 17582 | |
| 17583 | if (group) |
| 17584 | { |
| 17585 | DBUG_PRINT("info" ,("Creating group key in temporary table" )); |
| 17586 | table->group=group; /* Table is grouped by key */ |
| 17587 | param->group_buff=group_buff; |
| 17588 | share->keys=1; |
| 17589 | share->uniques= MY_TEST(using_unique_constraint); |
| 17590 | table->key_info= table->s->key_info= keyinfo; |
| 17591 | table->keys_in_use_for_query.set_bit(0); |
| 17592 | share->keys_in_use.set_bit(0); |
| 17593 | keyinfo->key_part=key_part_info; |
| 17594 | keyinfo->flags=HA_NOSAME | HA_BINARY_PACK_KEY | HA_PACK_KEY; |
| 17595 | keyinfo->ext_key_flags= keyinfo->flags; |
| 17596 | keyinfo->usable_key_parts=keyinfo->user_defined_key_parts= param->group_parts; |
| 17597 | keyinfo->ext_key_parts= keyinfo->user_defined_key_parts; |
| 17598 | keyinfo->key_length=0; |
| 17599 | keyinfo->rec_per_key=NULL; |
| 17600 | keyinfo->read_stats= NULL; |
| 17601 | keyinfo->collected_stats= NULL; |
| 17602 | keyinfo->algorithm= HA_KEY_ALG_UNDEF; |
| 17603 | keyinfo->is_statistics_from_stat_tables= FALSE; |
| 17604 | keyinfo->name= group_key; |
| 17605 | ORDER *cur_group= group; |
| 17606 | for (; cur_group ; cur_group= cur_group->next, key_part_info++) |
| 17607 | { |
| 17608 | Field *field=(*cur_group->item)->get_tmp_table_field(); |
| 17609 | DBUG_ASSERT(field->table == table); |
| 17610 | bool maybe_null=(*cur_group->item)->maybe_null; |
| 17611 | key_part_info->null_bit=0; |
| 17612 | key_part_info->field= field; |
| 17613 | key_part_info->fieldnr= field->field_index + 1; |
| 17614 | if (cur_group == group) |
| 17615 | field->key_start.set_bit(0); |
| 17616 | key_part_info->offset= field->offset(table->record[0]); |
| 17617 | key_part_info->length= (uint16) field->key_length(); |
| 17618 | key_part_info->type= (uint8) field->key_type(); |
| 17619 | key_part_info->key_type = |
| 17620 | ((ha_base_keytype) key_part_info->type == HA_KEYTYPE_TEXT || |
| 17621 | (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT1 || |
| 17622 | (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT2) ? |
| 17623 | 0 : FIELDFLAG_BINARY; |
| 17624 | key_part_info->key_part_flag= 0; |
| 17625 | if (!using_unique_constraint) |
| 17626 | { |
| 17627 | cur_group->buff=(char*) group_buff; |
| 17628 | |
| 17629 | if (maybe_null && !field->null_bit) |
| 17630 | { |
| 17631 | /* |
| 17632 | This can only happen in the unusual case where an outer join |
| 17633 | table was found to be not-nullable by the optimizer and we |
| 17634 | the item can't really be null. |
| 17635 | We solve this by marking the item as !maybe_null to ensure |
| 17636 | that the key,field and item definition match. |
| 17637 | */ |
| 17638 | (*cur_group->item)->maybe_null= maybe_null= 0; |
| 17639 | } |
| 17640 | |
| 17641 | if (!(cur_group->field= field->new_key_field(thd->mem_root,table, |
| 17642 | group_buff + |
| 17643 | MY_TEST(maybe_null), |
| 17644 | key_part_info->length, |
| 17645 | field->null_ptr, |
| 17646 | field->null_bit))) |
| 17647 | goto err; /* purecov: inspected */ |
| 17648 | |
| 17649 | if (maybe_null) |
| 17650 | { |
| 17651 | /* |
| 17652 | To be able to group on NULL, we reserved place in group_buff |
| 17653 | for the NULL flag just before the column. (see above). |
| 17654 | The field data is after this flag. |
| 17655 | The NULL flag is updated in 'end_update()' and 'end_write()' |
| 17656 | */ |
| 17657 | keyinfo->flags|= HA_NULL_ARE_EQUAL; // def. that NULL == NULL |
| 17658 | key_part_info->null_bit=field->null_bit; |
| 17659 | key_part_info->null_offset= (uint) (field->null_ptr - |
| 17660 | (uchar*) table->record[0]); |
| 17661 | cur_group->buff++; // Pointer to field data |
| 17662 | group_buff++; // Skipp null flag |
| 17663 | } |
| 17664 | group_buff+= cur_group->field->pack_length(); |
| 17665 | } |
| 17666 | keyinfo->key_length+= key_part_info->length; |
| 17667 | } |
| 17668 | /* |
| 17669 | Ensure we didn't overrun the group buffer. The < is only true when |
| 17670 | some maybe_null fields was changed to be not null fields. |
| 17671 | */ |
| 17672 | DBUG_ASSERT(using_unique_constraint || |
| 17673 | group_buff <= param->group_buff + param->group_length); |
| 17674 | } |
| 17675 | |
| 17676 | if (distinct && field_count != param->hidden_field_count) |
| 17677 | { |
| 17678 | /* |
| 17679 | Create an unique key or an unique constraint over all columns |
| 17680 | that should be in the result. In the temporary table, there are |
| 17681 | 'param->hidden_field_count' extra columns, whose null bits are stored |
| 17682 | in the first 'hidden_null_pack_length' bytes of the row. |
| 17683 | */ |
| 17684 | DBUG_PRINT("info" ,("hidden_field_count: %d" , param->hidden_field_count)); |
| 17685 | |
| 17686 | if (blob_count) |
| 17687 | { |
| 17688 | /* |
| 17689 | Special mode for index creation in MyISAM used to support unique |
| 17690 | indexes on blobs with arbitrary length. Such indexes cannot be |
| 17691 | used for lookups. |
| 17692 | */ |
| 17693 | share->uniques= 1; |
| 17694 | } |
| 17695 | null_pack_length-=hidden_null_pack_length; |
| 17696 | keyinfo->user_defined_key_parts= |
| 17697 | ((field_count-param->hidden_field_count)+ |
| 17698 | (share->uniques ? MY_TEST(null_pack_length) : 0)); |
| 17699 | keyinfo->ext_key_parts= keyinfo->user_defined_key_parts; |
| 17700 | keyinfo->usable_key_parts= keyinfo->user_defined_key_parts; |
| 17701 | table->distinct= 1; |
| 17702 | share->keys= 1; |
| 17703 | if (!(key_part_info= (KEY_PART_INFO*) |
| 17704 | alloc_root(&table->mem_root, |
| 17705 | keyinfo->user_defined_key_parts * sizeof(KEY_PART_INFO)))) |
| 17706 | goto err; |
| 17707 | bzero((void*) key_part_info, keyinfo->user_defined_key_parts * sizeof(KEY_PART_INFO)); |
| 17708 | table->keys_in_use_for_query.set_bit(0); |
| 17709 | share->keys_in_use.set_bit(0); |
| 17710 | table->key_info= table->s->key_info= keyinfo; |
| 17711 | keyinfo->key_part=key_part_info; |
| 17712 | keyinfo->flags=HA_NOSAME | HA_NULL_ARE_EQUAL | HA_BINARY_PACK_KEY | HA_PACK_KEY; |
| 17713 | keyinfo->ext_key_flags= keyinfo->flags; |
| 17714 | keyinfo->key_length= 0; // Will compute the sum of the parts below. |
| 17715 | keyinfo->name= distinct_key; |
| 17716 | keyinfo->algorithm= HA_KEY_ALG_UNDEF; |
| 17717 | keyinfo->is_statistics_from_stat_tables= FALSE; |
| 17718 | keyinfo->read_stats= NULL; |
| 17719 | keyinfo->collected_stats= NULL; |
| 17720 | |
| 17721 | /* |
| 17722 | Needed by non-merged semi-joins: SJ-Materialized table must have a valid |
| 17723 | rec_per_key array, because it participates in join optimization. Since |
| 17724 | the table has no data, the only statistics we can provide is "unknown", |
| 17725 | i.e. zero values. |
| 17726 | |
| 17727 | (For table record count, we calculate and set JOIN_TAB::found_records, |
| 17728 | see get_delayed_table_estimates()). |
| 17729 | */ |
| 17730 | size_t rpk_size= keyinfo->user_defined_key_parts * sizeof(keyinfo->rec_per_key[0]); |
| 17731 | if (!(keyinfo->rec_per_key= (ulong*) alloc_root(&table->mem_root, |
| 17732 | rpk_size))) |
| 17733 | goto err; |
| 17734 | bzero(keyinfo->rec_per_key, rpk_size); |
| 17735 | |
| 17736 | /* |
| 17737 | Create an extra field to hold NULL bits so that unique indexes on |
| 17738 | blobs can distinguish NULL from 0. This extra field is not needed |
| 17739 | when we do not use UNIQUE indexes for blobs. |
| 17740 | */ |
| 17741 | if (null_pack_length && share->uniques) |
| 17742 | { |
| 17743 | key_part_info->null_bit=0; |
| 17744 | key_part_info->offset=hidden_null_pack_length; |
| 17745 | key_part_info->length=null_pack_length; |
| 17746 | key_part_info->field= new Field_string(table->record[0], |
| 17747 | (uint32) key_part_info->length, |
| 17748 | (uchar*) 0, |
| 17749 | (uint) 0, |
| 17750 | Field::NONE, |
| 17751 | &null_clex_str, &my_charset_bin); |
| 17752 | if (!key_part_info->field) |
| 17753 | goto err; |
| 17754 | key_part_info->field->init(table); |
| 17755 | key_part_info->key_type=FIELDFLAG_BINARY; |
| 17756 | key_part_info->type= HA_KEYTYPE_BINARY; |
| 17757 | key_part_info->fieldnr= key_part_info->field->field_index + 1; |
| 17758 | key_part_info++; |
| 17759 | } |
| 17760 | /* Create a distinct key over the columns we are going to return */ |
| 17761 | for (i=param->hidden_field_count, reg_field=table->field + i ; |
| 17762 | i < field_count; |
| 17763 | i++, reg_field++, key_part_info++) |
| 17764 | { |
| 17765 | key_part_info->field= *reg_field; |
| 17766 | (*reg_field)->flags |= PART_KEY_FLAG; |
| 17767 | if (key_part_info == keyinfo->key_part) |
| 17768 | (*reg_field)->key_start.set_bit(0); |
| 17769 | key_part_info->null_bit= (*reg_field)->null_bit; |
| 17770 | key_part_info->null_offset= (uint) ((*reg_field)->null_ptr - |
| 17771 | (uchar*) table->record[0]); |
| 17772 | |
| 17773 | key_part_info->offset= (*reg_field)->offset(table->record[0]); |
| 17774 | key_part_info->length= (uint16) (*reg_field)->pack_length(); |
| 17775 | key_part_info->fieldnr= (*reg_field)->field_index + 1; |
| 17776 | /* TODO: |
| 17777 | The below method of computing the key format length of the |
| 17778 | key part is a copy/paste from opt_range.cc, and table.cc. |
| 17779 | This should be factored out, e.g. as a method of Field. |
| 17780 | In addition it is not clear if any of the Field::*_length |
| 17781 | methods is supposed to compute the same length. If so, it |
| 17782 | might be reused. |
| 17783 | */ |
| 17784 | key_part_info->store_length= key_part_info->length; |
| 17785 | |
| 17786 | if ((*reg_field)->real_maybe_null()) |
| 17787 | { |
| 17788 | key_part_info->store_length+= HA_KEY_NULL_LENGTH; |
| 17789 | key_part_info->key_part_flag |= HA_NULL_PART; |
| 17790 | } |
| 17791 | if ((*reg_field)->type() == MYSQL_TYPE_BLOB || |
| 17792 | (*reg_field)->real_type() == MYSQL_TYPE_VARCHAR || |
| 17793 | (*reg_field)->type() == MYSQL_TYPE_GEOMETRY) |
| 17794 | { |
| 17795 | if ((*reg_field)->type() == MYSQL_TYPE_BLOB || |
| 17796 | (*reg_field)->type() == MYSQL_TYPE_GEOMETRY) |
| 17797 | key_part_info->key_part_flag|= HA_BLOB_PART; |
| 17798 | else |
| 17799 | key_part_info->key_part_flag|= HA_VAR_LENGTH_PART; |
| 17800 | |
| 17801 | key_part_info->store_length+=HA_KEY_BLOB_LENGTH; |
| 17802 | } |
| 17803 | |
| 17804 | keyinfo->key_length+= key_part_info->store_length; |
| 17805 | |
| 17806 | key_part_info->type= (uint8) (*reg_field)->key_type(); |
| 17807 | key_part_info->key_type = |
| 17808 | ((ha_base_keytype) key_part_info->type == HA_KEYTYPE_TEXT || |
| 17809 | (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT1 || |
| 17810 | (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT2) ? |
| 17811 | 0 : FIELDFLAG_BINARY; |
| 17812 | } |
| 17813 | } |
| 17814 | |
| 17815 | if (unlikely(thd->is_fatal_error)) // If end of memory |
| 17816 | goto err; /* purecov: inspected */ |
| 17817 | share->db_record_offset= 1; |
| 17818 | table->used_for_duplicate_elimination= (param->sum_func_count == 0 && |
| 17819 | (table->group || table->distinct)); |
| 17820 | table->keep_row_order= keep_row_order; |
| 17821 | |
| 17822 | if (!do_not_open) |
| 17823 | { |
| 17824 | if (instantiate_tmp_table(table, param->keyinfo, param->start_recinfo, |
| 17825 | ¶m->recinfo, select_options)) |
| 17826 | goto err; |
| 17827 | } |
| 17828 | |
| 17829 | // Make empty record so random data is not written to disk |
| 17830 | empty_record(table); |
| 17831 | |
| 17832 | thd->mem_root= mem_root_save; |
| 17833 | |
| 17834 | DBUG_RETURN(table); |
| 17835 | |
| 17836 | err: |
| 17837 | thd->mem_root= mem_root_save; |
| 17838 | free_tmp_table(thd,table); /* purecov: inspected */ |
| 17839 | if (temp_pool_slot != MY_BIT_NONE) |
| 17840 | bitmap_lock_clear_bit(&temp_pool, temp_pool_slot); |
| 17841 | DBUG_RETURN(NULL); /* purecov: inspected */ |
| 17842 | } |
| 17843 | |
| 17844 | |
| 17845 | /****************************************************************************/ |
| 17846 | |
| 17847 | void *Virtual_tmp_table::operator new(size_t size, THD *thd) throw() |
| 17848 | { |
| 17849 | return (Virtual_tmp_table *) alloc_root(thd->mem_root, size); |
| 17850 | } |
| 17851 | |
| 17852 | |
| 17853 | bool Virtual_tmp_table::init(uint field_count) |
| 17854 | { |
| 17855 | uint *blob_field; |
| 17856 | uchar *bitmaps; |
| 17857 | DBUG_ENTER("Virtual_tmp_table::init" ); |
| 17858 | if (!multi_alloc_root(in_use->mem_root, |
| 17859 | &s, sizeof(*s), |
| 17860 | &field, (field_count + 1) * sizeof(Field*), |
| 17861 | &blob_field, (field_count + 1) * sizeof(uint), |
| 17862 | &bitmaps, bitmap_buffer_size(field_count) * 6, |
| 17863 | NullS)) |
| 17864 | DBUG_RETURN(true); |
| 17865 | bzero(s, sizeof(*s)); |
| 17866 | s->blob_field= blob_field; |
| 17867 | setup_tmp_table_column_bitmaps(this, bitmaps, field_count); |
| 17868 | m_alloced_field_count= field_count; |
| 17869 | DBUG_RETURN(false); |
| 17870 | }; |
| 17871 | |
| 17872 | |
| 17873 | bool Virtual_tmp_table::add(List<Spvar_definition> &field_list) |
| 17874 | { |
| 17875 | /* Create all fields and calculate the total length of record */ |
| 17876 | Spvar_definition *cdef; /* column definition */ |
| 17877 | List_iterator_fast<Spvar_definition> it(field_list); |
| 17878 | DBUG_ENTER("Virtual_tmp_table::add" ); |
| 17879 | while ((cdef= it++)) |
| 17880 | { |
| 17881 | Field *tmp; |
| 17882 | if (!(tmp= cdef->make_field(s, in_use->mem_root, 0, |
| 17883 | (uchar*) (f_maybe_null(cdef->pack_flag) ? "" : 0), |
| 17884 | f_maybe_null(cdef->pack_flag) ? 1 : 0, |
| 17885 | &cdef->field_name))) |
| 17886 | DBUG_RETURN(true); |
| 17887 | add(tmp); |
| 17888 | } |
| 17889 | DBUG_RETURN(false); |
| 17890 | } |
| 17891 | |
| 17892 | |
| 17893 | void Virtual_tmp_table::setup_field_pointers() |
| 17894 | { |
| 17895 | uchar *null_pos= record[0]; |
| 17896 | uchar *field_pos= null_pos + s->null_bytes; |
| 17897 | uint null_bit= 1; |
| 17898 | |
| 17899 | for (Field **cur_ptr= field; *cur_ptr; ++cur_ptr) |
| 17900 | { |
| 17901 | Field *cur_field= *cur_ptr; |
| 17902 | if ((cur_field->flags & NOT_NULL_FLAG)) |
| 17903 | cur_field->move_field(field_pos); |
| 17904 | else |
| 17905 | { |
| 17906 | cur_field->move_field(field_pos, (uchar*) null_pos, null_bit); |
| 17907 | null_bit<<= 1; |
| 17908 | if (null_bit == (uint)1 << 8) |
| 17909 | { |
| 17910 | ++null_pos; |
| 17911 | null_bit= 1; |
| 17912 | } |
| 17913 | } |
| 17914 | if (cur_field->type() == MYSQL_TYPE_BIT && |
| 17915 | cur_field->key_type() == HA_KEYTYPE_BIT) |
| 17916 | { |
| 17917 | /* This is a Field_bit since key_type is HA_KEYTYPE_BIT */ |
| 17918 | static_cast<Field_bit*>(cur_field)->set_bit_ptr(null_pos, null_bit); |
| 17919 | null_bit+= cur_field->field_length & 7; |
| 17920 | if (null_bit > 7) |
| 17921 | { |
| 17922 | null_pos++; |
| 17923 | null_bit-= 8; |
| 17924 | } |
| 17925 | } |
| 17926 | cur_field->reset(); |
| 17927 | field_pos+= cur_field->pack_length(); |
| 17928 | } |
| 17929 | } |
| 17930 | |
| 17931 | |
| 17932 | bool Virtual_tmp_table::open() |
| 17933 | { |
| 17934 | // Make sure that we added all the fields we planned to: |
| 17935 | DBUG_ASSERT(s->fields == m_alloced_field_count); |
| 17936 | field[s->fields]= NULL; // mark the end of the list |
| 17937 | s->blob_field[s->blob_fields]= 0; // mark the end of the list |
| 17938 | |
| 17939 | uint null_pack_length= (s->null_fields + 7) / 8; // NULL-bit array length |
| 17940 | s->reclength+= null_pack_length; |
| 17941 | s->rec_buff_length= ALIGN_SIZE(s->reclength + 1); |
| 17942 | if (!(record[0]= (uchar*) in_use->alloc(s->rec_buff_length))) |
| 17943 | return true; |
| 17944 | if (null_pack_length) |
| 17945 | { |
| 17946 | null_flags= (uchar*) record[0]; |
| 17947 | s->null_bytes= s->null_bytes_for_compare= null_pack_length; |
| 17948 | } |
| 17949 | setup_field_pointers(); |
| 17950 | return false; |
| 17951 | } |
| 17952 | |
| 17953 | |
| 17954 | bool Virtual_tmp_table::sp_find_field_by_name(uint *idx, |
| 17955 | const LEX_CSTRING &name) const |
| 17956 | { |
| 17957 | Field *f; |
| 17958 | for (uint i= 0; (f= field[i]); i++) |
| 17959 | { |
| 17960 | // Use the same comparison style with sp_context::find_variable() |
| 17961 | if (!my_strnncoll(system_charset_info, |
| 17962 | (const uchar *) f->field_name.str, |
| 17963 | f->field_name.length, |
| 17964 | (const uchar *) name.str, name.length)) |
| 17965 | { |
| 17966 | *idx= i; |
| 17967 | return false; |
| 17968 | } |
| 17969 | } |
| 17970 | return true; |
| 17971 | } |
| 17972 | |
| 17973 | |
| 17974 | bool |
| 17975 | Virtual_tmp_table::sp_find_field_by_name_or_error(uint *idx, |
| 17976 | const LEX_CSTRING &var_name, |
| 17977 | const LEX_CSTRING &field_name) |
| 17978 | const |
| 17979 | { |
| 17980 | if (sp_find_field_by_name(idx, field_name)) |
| 17981 | { |
| 17982 | my_error(ER_ROW_VARIABLE_DOES_NOT_HAVE_FIELD, MYF(0), |
| 17983 | var_name.str, field_name.str); |
| 17984 | return true; |
| 17985 | } |
| 17986 | return false; |
| 17987 | } |
| 17988 | |
| 17989 | |
| 17990 | bool Virtual_tmp_table::sp_set_all_fields_from_item_list(THD *thd, |
| 17991 | List<Item> &items) |
| 17992 | { |
| 17993 | DBUG_ASSERT(s->fields == items.elements); |
| 17994 | List_iterator<Item> it(items); |
| 17995 | Item *item; |
| 17996 | for (uint i= 0 ; (item= it++) ; i++) |
| 17997 | { |
| 17998 | if (field[i]->sp_prepare_and_store_item(thd, &item)) |
| 17999 | return true; |
| 18000 | } |
| 18001 | return false; |
| 18002 | } |
| 18003 | |
| 18004 | |
| 18005 | bool Virtual_tmp_table::sp_set_all_fields_from_item(THD *thd, Item *value) |
| 18006 | { |
| 18007 | DBUG_ASSERT(value->fixed); |
| 18008 | DBUG_ASSERT(value->cols() == s->fields); |
| 18009 | for (uint i= 0; i < value->cols(); i++) |
| 18010 | { |
| 18011 | if (field[i]->sp_prepare_and_store_item(thd, value->addr(i))) |
| 18012 | return true; |
| 18013 | } |
| 18014 | return false; |
| 18015 | } |
| 18016 | |
| 18017 | |
| 18018 | bool open_tmp_table(TABLE *table) |
| 18019 | { |
| 18020 | int error; |
| 18021 | if (unlikely((error= table->file->ha_open(table, table->s->table_name.str, |
| 18022 | O_RDWR, |
| 18023 | HA_OPEN_TMP_TABLE | |
| 18024 | HA_OPEN_INTERNAL_TABLE)))) |
| 18025 | { |
| 18026 | table->file->print_error(error, MYF(0)); /* purecov: inspected */ |
| 18027 | table->db_stat= 0; |
| 18028 | return 1; |
| 18029 | } |
| 18030 | table->db_stat= HA_OPEN_KEYFILE; |
| 18031 | (void) table->file->extra(HA_EXTRA_QUICK); /* Faster */ |
| 18032 | if (!table->is_created()) |
| 18033 | { |
| 18034 | table->set_created(); |
| 18035 | table->in_use->inc_status_created_tmp_tables(); |
| 18036 | } |
| 18037 | |
| 18038 | return 0; |
| 18039 | } |
| 18040 | |
| 18041 | |
| 18042 | #ifdef USE_ARIA_FOR_TMP_TABLES |
| 18043 | /* |
| 18044 | Create internal (MyISAM or Maria) temporary table |
| 18045 | |
| 18046 | SYNOPSIS |
| 18047 | create_internal_tmp_table() |
| 18048 | table Table object that descrimes the table to be created |
| 18049 | keyinfo Description of the index (there is always one index) |
| 18050 | start_recinfo engine's column descriptions |
| 18051 | recinfo INOUT End of engine's column descriptions |
| 18052 | options Option bits |
| 18053 | |
| 18054 | DESCRIPTION |
| 18055 | Create an internal emporary table according to passed description. The is |
| 18056 | assumed to have one unique index or constraint. |
| 18057 | |
| 18058 | The passed array or TMP_ENGINE_COLUMNDEF structures must have this form: |
| 18059 | |
| 18060 | 1. 1-byte column (afaiu for 'deleted' flag) (note maybe not 1-byte |
| 18061 | when there are many nullable columns) |
| 18062 | 2. Table columns |
| 18063 | 3. One free TMP_ENGINE_COLUMNDEF element (*recinfo points here) |
| 18064 | |
| 18065 | This function may use the free element to create hash column for unique |
| 18066 | constraint. |
| 18067 | |
| 18068 | RETURN |
| 18069 | FALSE - OK |
| 18070 | TRUE - Error |
| 18071 | */ |
| 18072 | |
| 18073 | |
| 18074 | bool create_internal_tmp_table(TABLE *table, KEY *keyinfo, |
| 18075 | TMP_ENGINE_COLUMNDEF *start_recinfo, |
| 18076 | TMP_ENGINE_COLUMNDEF **recinfo, |
| 18077 | ulonglong options) |
| 18078 | { |
| 18079 | int error; |
| 18080 | MARIA_KEYDEF keydef; |
| 18081 | MARIA_UNIQUEDEF uniquedef; |
| 18082 | TABLE_SHARE *share= table->s; |
| 18083 | MARIA_CREATE_INFO create_info; |
| 18084 | DBUG_ENTER("create_internal_tmp_table" ); |
| 18085 | |
| 18086 | if (share->keys) |
| 18087 | { // Get keys for ni_create |
| 18088 | bool using_unique_constraint=0; |
| 18089 | HA_KEYSEG *seg= (HA_KEYSEG*) alloc_root(&table->mem_root, |
| 18090 | sizeof(*seg) * keyinfo->user_defined_key_parts); |
| 18091 | if (!seg) |
| 18092 | goto err; |
| 18093 | |
| 18094 | bzero(seg, sizeof(*seg) * keyinfo->user_defined_key_parts); |
| 18095 | /* |
| 18096 | Note that a similar check is performed during |
| 18097 | subquery_types_allow_materialization. See MDEV-7122 for more details as |
| 18098 | to why. Whenever this changes, it must be updated there as well, for |
| 18099 | all tmp_table engines. |
| 18100 | */ |
| 18101 | if (keyinfo->key_length > table->file->max_key_length() || |
| 18102 | keyinfo->user_defined_key_parts > table->file->max_key_parts() || |
| 18103 | share->uniques) |
| 18104 | { |
| 18105 | if (!share->uniques && !(keyinfo->flags & HA_NOSAME)) |
| 18106 | { |
| 18107 | my_error(ER_INTERNAL_ERROR, MYF(0), |
| 18108 | "Using too big key for internal temp tables" ); |
| 18109 | DBUG_RETURN(1); |
| 18110 | } |
| 18111 | |
| 18112 | /* Can't create a key; Make a unique constraint instead of a key */ |
| 18113 | share->keys= 0; |
| 18114 | share->uniques= 1; |
| 18115 | using_unique_constraint=1; |
| 18116 | bzero((char*) &uniquedef,sizeof(uniquedef)); |
| 18117 | uniquedef.keysegs=keyinfo->user_defined_key_parts; |
| 18118 | uniquedef.seg=seg; |
| 18119 | uniquedef.null_are_equal=1; |
| 18120 | |
| 18121 | /* Create extra column for hash value */ |
| 18122 | bzero((uchar*) *recinfo,sizeof(**recinfo)); |
| 18123 | (*recinfo)->type= FIELD_CHECK; |
| 18124 | (*recinfo)->length= MARIA_UNIQUE_HASH_LENGTH; |
| 18125 | (*recinfo)++; |
| 18126 | share->reclength+= MARIA_UNIQUE_HASH_LENGTH; |
| 18127 | } |
| 18128 | else |
| 18129 | { |
| 18130 | /* Create a key */ |
| 18131 | bzero((char*) &keydef,sizeof(keydef)); |
| 18132 | keydef.flag= keyinfo->flags & HA_NOSAME; |
| 18133 | keydef.keysegs= keyinfo->user_defined_key_parts; |
| 18134 | keydef.seg= seg; |
| 18135 | } |
| 18136 | for (uint i=0; i < keyinfo->user_defined_key_parts ; i++,seg++) |
| 18137 | { |
| 18138 | Field *field=keyinfo->key_part[i].field; |
| 18139 | seg->flag= 0; |
| 18140 | seg->language= field->charset()->number; |
| 18141 | seg->length= keyinfo->key_part[i].length; |
| 18142 | seg->start= keyinfo->key_part[i].offset; |
| 18143 | if (field->flags & BLOB_FLAG) |
| 18144 | { |
| 18145 | seg->type= |
| 18146 | ((keyinfo->key_part[i].key_type & FIELDFLAG_BINARY) ? |
| 18147 | HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2); |
| 18148 | seg->bit_start= (uint8)(field->pack_length() - |
| 18149 | portable_sizeof_char_ptr); |
| 18150 | seg->flag= HA_BLOB_PART; |
| 18151 | seg->length=0; // Whole blob in unique constraint |
| 18152 | } |
| 18153 | else |
| 18154 | { |
| 18155 | seg->type= keyinfo->key_part[i].type; |
| 18156 | /* Tell handler if it can do suffic space compression */ |
| 18157 | if (field->real_type() == MYSQL_TYPE_STRING && |
| 18158 | keyinfo->key_part[i].length > 32) |
| 18159 | seg->flag|= HA_SPACE_PACK; |
| 18160 | } |
| 18161 | if (!(field->flags & NOT_NULL_FLAG)) |
| 18162 | { |
| 18163 | seg->null_bit= field->null_bit; |
| 18164 | seg->null_pos= (uint) (field->null_ptr - (uchar*) table->record[0]); |
| 18165 | /* |
| 18166 | We are using a GROUP BY on something that contains NULL |
| 18167 | In this case we have to tell Aria that two NULL should |
| 18168 | on INSERT be regarded at the same value |
| 18169 | */ |
| 18170 | if (!using_unique_constraint) |
| 18171 | keydef.flag|= HA_NULL_ARE_EQUAL; |
| 18172 | } |
| 18173 | } |
| 18174 | } |
| 18175 | bzero((char*) &create_info,sizeof(create_info)); |
| 18176 | create_info.data_file_length= table->in_use->variables.tmp_disk_table_size; |
| 18177 | |
| 18178 | /* |
| 18179 | The logic for choosing the record format: |
| 18180 | The STATIC_RECORD format is the fastest one, because it's so simple, |
| 18181 | so we use this by default for short rows. |
| 18182 | BLOCK_RECORD caches both row and data, so this is generally faster than |
| 18183 | DYNAMIC_RECORD. The one exception is when we write to tmp table and |
| 18184 | want to use keys for duplicate elimination as with BLOCK RECORD |
| 18185 | we first write the row, then check for key conflicts and then we have to |
| 18186 | delete the row. The cases when this can happen is when there is |
| 18187 | a group by and no sum functions or if distinct is used. |
| 18188 | */ |
| 18189 | { |
| 18190 | enum data_file_type file_type= table->no_rows ? NO_RECORD : |
| 18191 | (share->reclength < 64 && !share->blob_fields ? STATIC_RECORD : |
| 18192 | table->used_for_duplicate_elimination ? DYNAMIC_RECORD : BLOCK_RECORD); |
| 18193 | uint create_flags= HA_CREATE_TMP_TABLE | HA_CREATE_INTERNAL_TABLE | |
| 18194 | (table->keep_row_order ? HA_PRESERVE_INSERT_ORDER : 0); |
| 18195 | |
| 18196 | if (file_type != NO_RECORD && encrypt_tmp_disk_tables) |
| 18197 | { |
| 18198 | /* encryption is only supported for BLOCK_RECORD */ |
| 18199 | file_type= BLOCK_RECORD; |
| 18200 | if (table->used_for_duplicate_elimination) |
| 18201 | { |
| 18202 | /* |
| 18203 | sql-layer expect the last column to be stored/restored also |
| 18204 | when it's null. |
| 18205 | |
| 18206 | This is probably a bug (that sql-layer doesn't annotate |
| 18207 | the column as not-null) but both heap, aria-static, aria-dynamic and |
| 18208 | myisam has this property. aria-block_record does not since it |
| 18209 | does not store null-columns at all. |
| 18210 | Emulate behaviour by making column not-nullable when creating the |
| 18211 | table. |
| 18212 | */ |
| 18213 | uint cols= (uint)(*recinfo-start_recinfo); |
| 18214 | start_recinfo[cols-1].null_bit= 0; |
| 18215 | } |
| 18216 | } |
| 18217 | |
| 18218 | if (unlikely((error= maria_create(share->table_name.str, |
| 18219 | file_type, |
| 18220 | share->keys, &keydef, |
| 18221 | (uint) (*recinfo-start_recinfo), |
| 18222 | start_recinfo, |
| 18223 | share->uniques, &uniquedef, |
| 18224 | &create_info, |
| 18225 | create_flags)))) |
| 18226 | { |
| 18227 | table->file->print_error(error,MYF(0)); /* purecov: inspected */ |
| 18228 | table->db_stat=0; |
| 18229 | goto err; |
| 18230 | } |
| 18231 | } |
| 18232 | |
| 18233 | table->in_use->inc_status_created_tmp_disk_tables(); |
| 18234 | table->in_use->inc_status_created_tmp_tables(); |
| 18235 | share->db_record_offset= 1; |
| 18236 | table->set_created(); |
| 18237 | DBUG_RETURN(0); |
| 18238 | err: |
| 18239 | DBUG_RETURN(1); |
| 18240 | } |
| 18241 | |
| 18242 | #else |
| 18243 | |
| 18244 | /* |
| 18245 | Create internal (MyISAM or Maria) temporary table |
| 18246 | |
| 18247 | SYNOPSIS |
| 18248 | create_internal_tmp_table() |
| 18249 | table Table object that descrimes the table to be created |
| 18250 | keyinfo Description of the index (there is always one index) |
| 18251 | start_recinfo engine's column descriptions |
| 18252 | recinfo INOUT End of engine's column descriptions |
| 18253 | options Option bits |
| 18254 | |
| 18255 | DESCRIPTION |
| 18256 | Create an internal emporary table according to passed description. The is |
| 18257 | assumed to have one unique index or constraint. |
| 18258 | |
| 18259 | The passed array or TMP_ENGINE_COLUMNDEF structures must have this form: |
| 18260 | |
| 18261 | 1. 1-byte column (afaiu for 'deleted' flag) (note maybe not 1-byte |
| 18262 | when there are many nullable columns) |
| 18263 | 2. Table columns |
| 18264 | 3. One free TMP_ENGINE_COLUMNDEF element (*recinfo points here) |
| 18265 | |
| 18266 | This function may use the free element to create hash column for unique |
| 18267 | constraint. |
| 18268 | |
| 18269 | RETURN |
| 18270 | FALSE - OK |
| 18271 | TRUE - Error |
| 18272 | */ |
| 18273 | |
| 18274 | /* Create internal MyISAM temporary table */ |
| 18275 | |
| 18276 | bool create_internal_tmp_table(TABLE *table, KEY *keyinfo, |
| 18277 | TMP_ENGINE_COLUMNDEF *start_recinfo, |
| 18278 | TMP_ENGINE_COLUMNDEF **recinfo, |
| 18279 | ulonglong options) |
| 18280 | { |
| 18281 | int error; |
| 18282 | MI_KEYDEF keydef; |
| 18283 | MI_UNIQUEDEF uniquedef; |
| 18284 | TABLE_SHARE *share= table->s; |
| 18285 | DBUG_ENTER("create_internal_tmp_table" ); |
| 18286 | |
| 18287 | if (share->keys) |
| 18288 | { // Get keys for ni_create |
| 18289 | bool using_unique_constraint=0; |
| 18290 | HA_KEYSEG *seg= (HA_KEYSEG*) alloc_root(&table->mem_root, |
| 18291 | sizeof(*seg) * keyinfo->user_defined_key_parts); |
| 18292 | if (!seg) |
| 18293 | goto err; |
| 18294 | |
| 18295 | bzero(seg, sizeof(*seg) * keyinfo->user_defined_key_parts); |
| 18296 | /* |
| 18297 | Note that a similar check is performed during |
| 18298 | subquery_types_allow_materialization. See MDEV-7122 for more details as |
| 18299 | to why. Whenever this changes, it must be updated there as well, for |
| 18300 | all tmp_table engines. |
| 18301 | */ |
| 18302 | if (keyinfo->key_length > table->file->max_key_length() || |
| 18303 | keyinfo->user_defined_key_parts > table->file->max_key_parts() || |
| 18304 | share->uniques) |
| 18305 | { |
| 18306 | /* Can't create a key; Make a unique constraint instead of a key */ |
| 18307 | share->keys= 0; |
| 18308 | share->uniques= 1; |
| 18309 | using_unique_constraint=1; |
| 18310 | bzero((char*) &uniquedef,sizeof(uniquedef)); |
| 18311 | uniquedef.keysegs=keyinfo->user_defined_key_parts; |
| 18312 | uniquedef.seg=seg; |
| 18313 | uniquedef.null_are_equal=1; |
| 18314 | |
| 18315 | /* Create extra column for hash value */ |
| 18316 | bzero((uchar*) *recinfo,sizeof(**recinfo)); |
| 18317 | (*recinfo)->type= FIELD_CHECK; |
| 18318 | (*recinfo)->length=MI_UNIQUE_HASH_LENGTH; |
| 18319 | (*recinfo)++; |
| 18320 | share->reclength+=MI_UNIQUE_HASH_LENGTH; |
| 18321 | } |
| 18322 | else |
| 18323 | { |
| 18324 | /* Create an unique key */ |
| 18325 | bzero((char*) &keydef,sizeof(keydef)); |
| 18326 | keydef.flag= ((keyinfo->flags & HA_NOSAME) | HA_BINARY_PACK_KEY | |
| 18327 | HA_PACK_KEY); |
| 18328 | keydef.keysegs= keyinfo->user_defined_key_parts; |
| 18329 | keydef.seg= seg; |
| 18330 | } |
| 18331 | for (uint i=0; i < keyinfo->user_defined_key_parts ; i++,seg++) |
| 18332 | { |
| 18333 | Field *field=keyinfo->key_part[i].field; |
| 18334 | seg->flag= 0; |
| 18335 | seg->language= field->charset()->number; |
| 18336 | seg->length= keyinfo->key_part[i].length; |
| 18337 | seg->start= keyinfo->key_part[i].offset; |
| 18338 | if (field->flags & BLOB_FLAG) |
| 18339 | { |
| 18340 | seg->type= |
| 18341 | ((keyinfo->key_part[i].key_type & FIELDFLAG_BINARY) ? |
| 18342 | HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2); |
| 18343 | seg->bit_start= (uint8)(field->pack_length() - portable_sizeof_char_ptr); |
| 18344 | seg->flag= HA_BLOB_PART; |
| 18345 | seg->length=0; // Whole blob in unique constraint |
| 18346 | } |
| 18347 | else |
| 18348 | { |
| 18349 | seg->type= keyinfo->key_part[i].type; |
| 18350 | /* Tell handler if it can do suffic space compression */ |
| 18351 | if (field->real_type() == MYSQL_TYPE_STRING && |
| 18352 | keyinfo->key_part[i].length > 4) |
| 18353 | seg->flag|= HA_SPACE_PACK; |
| 18354 | } |
| 18355 | if (!(field->flags & NOT_NULL_FLAG)) |
| 18356 | { |
| 18357 | seg->null_bit= field->null_bit; |
| 18358 | seg->null_pos= (uint) (field->null_ptr - (uchar*) table->record[0]); |
| 18359 | /* |
| 18360 | We are using a GROUP BY on something that contains NULL |
| 18361 | In this case we have to tell MyISAM that two NULL should |
| 18362 | on INSERT be regarded at the same value |
| 18363 | */ |
| 18364 | if (!using_unique_constraint) |
| 18365 | keydef.flag|= HA_NULL_ARE_EQUAL; |
| 18366 | } |
| 18367 | } |
| 18368 | } |
| 18369 | MI_CREATE_INFO create_info; |
| 18370 | bzero((char*) &create_info,sizeof(create_info)); |
| 18371 | create_info.data_file_length= table->in_use->variables.tmp_disk_table_size; |
| 18372 | |
| 18373 | if (unlikely((error= mi_create(share->table_name.str, share->keys, &keydef, |
| 18374 | (uint) (*recinfo-start_recinfo), |
| 18375 | start_recinfo, |
| 18376 | share->uniques, &uniquedef, |
| 18377 | &create_info, |
| 18378 | HA_CREATE_TMP_TABLE | |
| 18379 | HA_CREATE_INTERNAL_TABLE | |
| 18380 | ((share->db_create_options & |
| 18381 | HA_OPTION_PACK_RECORD) ? |
| 18382 | HA_PACK_RECORD : 0) |
| 18383 | )))) |
| 18384 | { |
| 18385 | table->file->print_error(error,MYF(0)); /* purecov: inspected */ |
| 18386 | table->db_stat=0; |
| 18387 | goto err; |
| 18388 | } |
| 18389 | table->in_use->inc_status_created_tmp_disk_tables(); |
| 18390 | table->in_use->inc_status_created_tmp_tables(); |
| 18391 | share->db_record_offset= 1; |
| 18392 | table->set_created(); |
| 18393 | DBUG_RETURN(0); |
| 18394 | err: |
| 18395 | DBUG_RETURN(1); |
| 18396 | } |
| 18397 | |
| 18398 | #endif /* USE_ARIA_FOR_TMP_TABLES */ |
| 18399 | |
| 18400 | |
| 18401 | /* |
| 18402 | If a HEAP table gets full, create a internal table in MyISAM or Maria |
| 18403 | and copy all rows to this |
| 18404 | */ |
| 18405 | |
| 18406 | |
| 18407 | bool |
| 18408 | create_internal_tmp_table_from_heap(THD *thd, TABLE *table, |
| 18409 | TMP_ENGINE_COLUMNDEF *start_recinfo, |
| 18410 | TMP_ENGINE_COLUMNDEF **recinfo, |
| 18411 | int error, |
| 18412 | bool ignore_last_dupp_key_error, |
| 18413 | bool *is_duplicate) |
| 18414 | { |
| 18415 | TABLE new_table; |
| 18416 | TABLE_SHARE share; |
| 18417 | const char *save_proc_info; |
| 18418 | int write_err= 0; |
| 18419 | DBUG_ENTER("create_internal_tmp_table_from_heap" ); |
| 18420 | if (is_duplicate) |
| 18421 | *is_duplicate= FALSE; |
| 18422 | |
| 18423 | if (table->s->db_type() != heap_hton || |
| 18424 | error != HA_ERR_RECORD_FILE_FULL) |
| 18425 | { |
| 18426 | /* |
| 18427 | We don't want this error to be converted to a warning, e.g. in case of |
| 18428 | INSERT IGNORE ... SELECT. |
| 18429 | */ |
| 18430 | table->file->print_error(error, MYF(ME_FATALERROR)); |
| 18431 | DBUG_RETURN(1); |
| 18432 | } |
| 18433 | new_table= *table; |
| 18434 | share= *table->s; |
| 18435 | new_table.s= &share; |
| 18436 | new_table.s->db_plugin= ha_lock_engine(thd, TMP_ENGINE_HTON); |
| 18437 | if (unlikely(!(new_table.file= get_new_handler(&share, &new_table.mem_root, |
| 18438 | new_table.s->db_type())))) |
| 18439 | DBUG_RETURN(1); // End of memory |
| 18440 | |
| 18441 | if (unlikely(new_table.file->set_ha_share_ref(&share.ha_share))) |
| 18442 | { |
| 18443 | delete new_table.file; |
| 18444 | DBUG_RETURN(1); |
| 18445 | } |
| 18446 | |
| 18447 | save_proc_info=thd->proc_info; |
| 18448 | THD_STAGE_INFO(thd, stage_converting_heap_to_myisam); |
| 18449 | |
| 18450 | new_table.no_rows= table->no_rows; |
| 18451 | if (create_internal_tmp_table(&new_table, table->key_info, start_recinfo, |
| 18452 | recinfo, |
| 18453 | thd->lex->select_lex.options | |
| 18454 | thd->variables.option_bits)) |
| 18455 | goto err2; |
| 18456 | if (open_tmp_table(&new_table)) |
| 18457 | goto err1; |
| 18458 | if (table->file->indexes_are_disabled()) |
| 18459 | new_table.file->ha_disable_indexes(HA_KEY_SWITCH_ALL); |
| 18460 | table->file->ha_index_or_rnd_end(); |
| 18461 | if (table->file->ha_rnd_init_with_error(1)) |
| 18462 | DBUG_RETURN(1); |
| 18463 | if (new_table.no_rows) |
| 18464 | new_table.file->extra(HA_EXTRA_NO_ROWS); |
| 18465 | else |
| 18466 | { |
| 18467 | /* update table->file->stats.records */ |
| 18468 | table->file->info(HA_STATUS_VARIABLE); |
| 18469 | new_table.file->ha_start_bulk_insert(table->file->stats.records); |
| 18470 | } |
| 18471 | |
| 18472 | /* |
| 18473 | copy all old rows from heap table to MyISAM table |
| 18474 | This is the only code that uses record[1] to read/write but this |
| 18475 | is safe as this is a temporary MyISAM table without timestamp/autoincrement |
| 18476 | or partitioning. |
| 18477 | */ |
| 18478 | while (!table->file->ha_rnd_next(new_table.record[1])) |
| 18479 | { |
| 18480 | write_err= new_table.file->ha_write_tmp_row(new_table.record[1]); |
| 18481 | DBUG_EXECUTE_IF("raise_error" , write_err= HA_ERR_FOUND_DUPP_KEY ;); |
| 18482 | if (write_err) |
| 18483 | goto err; |
| 18484 | if (unlikely(thd->check_killed())) |
| 18485 | { |
| 18486 | thd->send_kill_message(); |
| 18487 | goto err_killed; |
| 18488 | } |
| 18489 | } |
| 18490 | if (!new_table.no_rows && new_table.file->ha_end_bulk_insert()) |
| 18491 | goto err; |
| 18492 | /* copy row that filled HEAP table */ |
| 18493 | if (unlikely((write_err=new_table.file->ha_write_tmp_row(table->record[0])))) |
| 18494 | { |
| 18495 | if (new_table.file->is_fatal_error(write_err, HA_CHECK_DUP) || |
| 18496 | !ignore_last_dupp_key_error) |
| 18497 | goto err; |
| 18498 | if (is_duplicate) |
| 18499 | *is_duplicate= TRUE; |
| 18500 | } |
| 18501 | else |
| 18502 | { |
| 18503 | if (is_duplicate) |
| 18504 | *is_duplicate= FALSE; |
| 18505 | } |
| 18506 | |
| 18507 | /* remove heap table and change to use myisam table */ |
| 18508 | (void) table->file->ha_rnd_end(); |
| 18509 | (void) table->file->ha_close(); // This deletes the table ! |
| 18510 | delete table->file; |
| 18511 | table->file=0; |
| 18512 | plugin_unlock(0, table->s->db_plugin); |
| 18513 | share.db_plugin= my_plugin_lock(0, share.db_plugin); |
| 18514 | new_table.s= table->s; // Keep old share |
| 18515 | *table= new_table; |
| 18516 | *table->s= share; |
| 18517 | |
| 18518 | table->file->change_table_ptr(table, table->s); |
| 18519 | table->use_all_columns(); |
| 18520 | if (save_proc_info) |
| 18521 | thd_proc_info(thd, (!strcmp(save_proc_info,"Copying to tmp table" ) ? |
| 18522 | "Copying to tmp table on disk" : save_proc_info)); |
| 18523 | DBUG_RETURN(0); |
| 18524 | |
| 18525 | err: |
| 18526 | DBUG_PRINT("error" ,("Got error: %d" ,write_err)); |
| 18527 | table->file->print_error(write_err, MYF(0)); |
| 18528 | err_killed: |
| 18529 | (void) table->file->ha_rnd_end(); |
| 18530 | (void) new_table.file->ha_close(); |
| 18531 | err1: |
| 18532 | new_table.file->ha_delete_table(new_table.s->table_name.str); |
| 18533 | err2: |
| 18534 | delete new_table.file; |
| 18535 | thd_proc_info(thd, save_proc_info); |
| 18536 | table->mem_root= new_table.mem_root; |
| 18537 | DBUG_RETURN(1); |
| 18538 | } |
| 18539 | |
| 18540 | |
| 18541 | void |
| 18542 | free_tmp_table(THD *thd, TABLE *entry) |
| 18543 | { |
| 18544 | MEM_ROOT own_root= entry->mem_root; |
| 18545 | const char *save_proc_info; |
| 18546 | DBUG_ENTER("free_tmp_table" ); |
| 18547 | DBUG_PRINT("enter" ,("table: %s alias: %s" ,entry->s->table_name.str, |
| 18548 | entry->alias.c_ptr())); |
| 18549 | |
| 18550 | save_proc_info=thd->proc_info; |
| 18551 | THD_STAGE_INFO(thd, stage_removing_tmp_table); |
| 18552 | |
| 18553 | if (entry->file && entry->is_created()) |
| 18554 | { |
| 18555 | entry->file->ha_index_or_rnd_end(); |
| 18556 | if (entry->db_stat) |
| 18557 | { |
| 18558 | entry->file->info(HA_STATUS_VARIABLE); |
| 18559 | thd->tmp_tables_size+= (entry->file->stats.data_file_length + |
| 18560 | entry->file->stats.index_file_length); |
| 18561 | entry->file->ha_drop_table(entry->s->table_name.str); |
| 18562 | } |
| 18563 | else |
| 18564 | entry->file->ha_delete_table(entry->s->table_name.str); |
| 18565 | delete entry->file; |
| 18566 | } |
| 18567 | |
| 18568 | /* free blobs */ |
| 18569 | for (Field **ptr=entry->field ; *ptr ; ptr++) |
| 18570 | (*ptr)->free(); |
| 18571 | |
| 18572 | if (entry->temp_pool_slot != MY_BIT_NONE) |
| 18573 | bitmap_lock_clear_bit(&temp_pool, entry->temp_pool_slot); |
| 18574 | |
| 18575 | plugin_unlock(0, entry->s->db_plugin); |
| 18576 | entry->alias.free(); |
| 18577 | |
| 18578 | if (entry->pos_in_table_list && entry->pos_in_table_list->table) |
| 18579 | { |
| 18580 | DBUG_ASSERT(entry->pos_in_table_list->table == entry); |
| 18581 | entry->pos_in_table_list->table= NULL; |
| 18582 | } |
| 18583 | |
| 18584 | free_root(&own_root, MYF(0)); /* the table is allocated in its own root */ |
| 18585 | thd_proc_info(thd, save_proc_info); |
| 18586 | |
| 18587 | DBUG_VOID_RETURN; |
| 18588 | } |
| 18589 | |
| 18590 | |
| 18591 | /** |
| 18592 | @brief |
| 18593 | Set write_func of AGGR_OP object |
| 18594 | |
| 18595 | @param join_tab JOIN_TAB of the corresponding tmp table |
| 18596 | |
| 18597 | @details |
| 18598 | Function sets up write_func according to how AGGR_OP object that |
| 18599 | is attached to the given join_tab will be used in the query. |
| 18600 | */ |
| 18601 | |
| 18602 | void set_postjoin_aggr_write_func(JOIN_TAB *tab) |
| 18603 | { |
| 18604 | JOIN *join= tab->join; |
| 18605 | TABLE *table= tab->table; |
| 18606 | AGGR_OP *aggr= tab->aggr; |
| 18607 | TMP_TABLE_PARAM *tmp_tbl= tab->tmp_table_param; |
| 18608 | |
| 18609 | DBUG_ASSERT(table && aggr); |
| 18610 | |
| 18611 | if (table->group && tmp_tbl->sum_func_count && |
| 18612 | !tmp_tbl->precomputed_group_by) |
| 18613 | { |
| 18614 | /* |
| 18615 | Note for MyISAM tmp tables: if uniques is true keys won't be |
| 18616 | created. |
| 18617 | */ |
| 18618 | if (table->s->keys && !table->s->uniques) |
| 18619 | { |
| 18620 | DBUG_PRINT("info" ,("Using end_update" )); |
| 18621 | aggr->set_write_func(end_update); |
| 18622 | } |
| 18623 | else |
| 18624 | { |
| 18625 | DBUG_PRINT("info" ,("Using end_unique_update" )); |
| 18626 | aggr->set_write_func(end_unique_update); |
| 18627 | } |
| 18628 | } |
| 18629 | else if (join->sort_and_group && !tmp_tbl->precomputed_group_by && |
| 18630 | !join->sort_and_group_aggr_tab && join->tables_list) |
| 18631 | { |
| 18632 | DBUG_PRINT("info" ,("Using end_write_group" )); |
| 18633 | aggr->set_write_func(end_write_group); |
| 18634 | join->sort_and_group_aggr_tab= tab; |
| 18635 | } |
| 18636 | else |
| 18637 | { |
| 18638 | DBUG_PRINT("info" ,("Using end_write" )); |
| 18639 | aggr->set_write_func(end_write); |
| 18640 | if (tmp_tbl->precomputed_group_by) |
| 18641 | { |
| 18642 | /* |
| 18643 | A preceding call to create_tmp_table in the case when loose |
| 18644 | index scan is used guarantees that |
| 18645 | TMP_TABLE_PARAM::items_to_copy has enough space for the group |
| 18646 | by functions. It is OK here to use memcpy since we copy |
| 18647 | Item_sum pointers into an array of Item pointers. |
| 18648 | */ |
| 18649 | memcpy(tmp_tbl->items_to_copy + tmp_tbl->func_count, |
| 18650 | join->sum_funcs, |
| 18651 | sizeof(Item*)*tmp_tbl->sum_func_count); |
| 18652 | tmp_tbl->items_to_copy[tmp_tbl->func_count+tmp_tbl->sum_func_count]= 0; |
| 18653 | } |
| 18654 | } |
| 18655 | } |
| 18656 | |
| 18657 | |
| 18658 | /** |
| 18659 | @details |
| 18660 | Rows produced by a join sweep may end up in a temporary table or be sent |
| 18661 | to a client. Set the function of the nested loop join algorithm which |
| 18662 | handles final fully constructed and matched records. |
| 18663 | |
| 18664 | @param join join to setup the function for. |
| 18665 | |
| 18666 | @return |
| 18667 | end_select function to use. This function can't fail. |
| 18668 | */ |
| 18669 | |
| 18670 | Next_select_func setup_end_select_func(JOIN *join, JOIN_TAB *tab) |
| 18671 | { |
| 18672 | TMP_TABLE_PARAM *tmp_tbl= tab ? tab->tmp_table_param : &join->tmp_table_param; |
| 18673 | |
| 18674 | /* |
| 18675 | Choose method for presenting result to user. Use end_send_group |
| 18676 | if the query requires grouping (has a GROUP BY clause and/or one or |
| 18677 | more aggregate functions). Use end_send if the query should not |
| 18678 | be grouped. |
| 18679 | */ |
| 18680 | if (join->sort_and_group && !tmp_tbl->precomputed_group_by) |
| 18681 | { |
| 18682 | DBUG_PRINT("info" ,("Using end_send_group" )); |
| 18683 | return end_send_group; |
| 18684 | } |
| 18685 | DBUG_PRINT("info" ,("Using end_send" )); |
| 18686 | return end_send; |
| 18687 | } |
| 18688 | |
| 18689 | |
| 18690 | /** |
| 18691 | Make a join of all tables and write it on socket or to table. |
| 18692 | |
| 18693 | @retval |
| 18694 | 0 if ok |
| 18695 | @retval |
| 18696 | 1 if error is sent |
| 18697 | @retval |
| 18698 | -1 if error should be sent |
| 18699 | */ |
| 18700 | |
| 18701 | static int |
| 18702 | do_select(JOIN *join, Procedure *procedure) |
| 18703 | { |
| 18704 | int rc= 0; |
| 18705 | enum_nested_loop_state error= NESTED_LOOP_OK; |
| 18706 | DBUG_ENTER("do_select" ); |
| 18707 | |
| 18708 | if (join->pushdown_query) |
| 18709 | { |
| 18710 | /* Select fields are in the temporary table */ |
| 18711 | join->fields= &join->tmp_fields_list1; |
| 18712 | /* Setup HAVING to work with fields in temporary table */ |
| 18713 | join->set_items_ref_array(join->items1); |
| 18714 | /* The storage engine will take care of the group by query result */ |
| 18715 | int res= join->pushdown_query->execute(join); |
| 18716 | |
| 18717 | if (res) |
| 18718 | DBUG_RETURN(res); |
| 18719 | |
| 18720 | if (join->pushdown_query->store_data_in_temp_table) |
| 18721 | { |
| 18722 | JOIN_TAB *last_tab= join->join_tab + join->table_count - |
| 18723 | join->exec_join_tab_cnt(); |
| 18724 | last_tab->next_select= end_send; |
| 18725 | |
| 18726 | enum_nested_loop_state state= last_tab->aggr->end_send(); |
| 18727 | if (state >= NESTED_LOOP_OK) |
| 18728 | state= sub_select(join, last_tab, true); |
| 18729 | |
| 18730 | if (state < NESTED_LOOP_OK) |
| 18731 | res= 1; |
| 18732 | |
| 18733 | if (join->result->send_eof()) |
| 18734 | res= 1; |
| 18735 | } |
| 18736 | DBUG_RETURN(res); |
| 18737 | } |
| 18738 | |
| 18739 | join->procedure= procedure; |
| 18740 | join->duplicate_rows= join->send_records=0; |
| 18741 | if (join->only_const_tables() && !join->need_tmp) |
| 18742 | { |
| 18743 | Next_select_func end_select= setup_end_select_func(join, NULL); |
| 18744 | /* |
| 18745 | HAVING will be checked after processing aggregate functions, |
| 18746 | But WHERE should checked here (we alredy have read tables). |
| 18747 | Notice that make_join_select() splits all conditions in this case |
| 18748 | into two groups exec_const_cond and outer_ref_cond. |
| 18749 | If join->table_count == join->const_tables then it is |
| 18750 | sufficient to check only the condition pseudo_bits_cond. |
| 18751 | */ |
| 18752 | DBUG_ASSERT(join->outer_ref_cond == NULL); |
| 18753 | if (!join->pseudo_bits_cond || join->pseudo_bits_cond->val_int()) |
| 18754 | { |
| 18755 | // HAVING will be checked by end_select |
| 18756 | error= (*end_select)(join, 0, 0); |
| 18757 | if (error >= NESTED_LOOP_OK) |
| 18758 | error= (*end_select)(join, 0, 1); |
| 18759 | |
| 18760 | /* |
| 18761 | If we don't go through evaluate_join_record(), do the counting |
| 18762 | here. join->send_records is increased on success in end_send(), |
| 18763 | so we don't touch it here. |
| 18764 | */ |
| 18765 | join->join_examined_rows++; |
| 18766 | DBUG_ASSERT(join->join_examined_rows <= 1); |
| 18767 | } |
| 18768 | else if (join->send_row_on_empty_set()) |
| 18769 | { |
| 18770 | if (!join->having || join->having->val_int()) |
| 18771 | { |
| 18772 | List<Item> *columns_list= (procedure ? &join->procedure_fields_list : |
| 18773 | join->fields); |
| 18774 | rc= join->result->send_data(*columns_list) > 0; |
| 18775 | } |
| 18776 | } |
| 18777 | /* |
| 18778 | An error can happen when evaluating the conds |
| 18779 | (the join condition and piece of where clause |
| 18780 | relevant to this join table). |
| 18781 | */ |
| 18782 | if (unlikely(join->thd->is_error())) |
| 18783 | error= NESTED_LOOP_ERROR; |
| 18784 | } |
| 18785 | else |
| 18786 | { |
| 18787 | DBUG_EXECUTE_IF("show_explain_probe_do_select" , |
| 18788 | if (dbug_user_var_equals_int(join->thd, |
| 18789 | "show_explain_probe_select_id" , |
| 18790 | join->select_lex->select_number)) |
| 18791 | dbug_serve_apcs(join->thd, 1); |
| 18792 | ); |
| 18793 | |
| 18794 | JOIN_TAB *join_tab= join->join_tab + |
| 18795 | (join->tables_list ? join->const_tables : 0); |
| 18796 | if (join->outer_ref_cond && !join->outer_ref_cond->val_int()) |
| 18797 | error= NESTED_LOOP_NO_MORE_ROWS; |
| 18798 | else |
| 18799 | error= join->first_select(join,join_tab,0); |
| 18800 | if (error >= NESTED_LOOP_OK && likely(join->thd->killed != ABORT_QUERY)) |
| 18801 | error= join->first_select(join,join_tab,1); |
| 18802 | } |
| 18803 | |
| 18804 | join->thd->limit_found_rows= join->send_records - join->duplicate_rows; |
| 18805 | |
| 18806 | if (error == NESTED_LOOP_NO_MORE_ROWS || |
| 18807 | unlikely(join->thd->killed == ABORT_QUERY)) |
| 18808 | error= NESTED_LOOP_OK; |
| 18809 | |
| 18810 | /* |
| 18811 | For "order by with limit", we cannot rely on send_records, but need |
| 18812 | to use the rowcount read originally into the join_tab applying the |
| 18813 | filesort. There cannot be any post-filtering conditions, nor any |
| 18814 | following join_tabs in this case, so this rowcount properly represents |
| 18815 | the correct number of qualifying rows. |
| 18816 | */ |
| 18817 | if (join->order) |
| 18818 | { |
| 18819 | // Save # of found records prior to cleanup |
| 18820 | JOIN_TAB *sort_tab; |
| 18821 | JOIN_TAB *join_tab= join->join_tab; |
| 18822 | uint const_tables= join->const_tables; |
| 18823 | |
| 18824 | // Take record count from first non constant table or from last tmp table |
| 18825 | if (join->aggr_tables > 0) |
| 18826 | sort_tab= join_tab + join->top_join_tab_count + join->aggr_tables - 1; |
| 18827 | else |
| 18828 | { |
| 18829 | DBUG_ASSERT(!join->only_const_tables()); |
| 18830 | sort_tab= join_tab + const_tables; |
| 18831 | } |
| 18832 | if (sort_tab->filesort && |
| 18833 | join->select_options & OPTION_FOUND_ROWS && |
| 18834 | sort_tab->filesort->sortorder && |
| 18835 | sort_tab->filesort->limit != HA_POS_ERROR) |
| 18836 | { |
| 18837 | join->thd->limit_found_rows= sort_tab->records; |
| 18838 | } |
| 18839 | } |
| 18840 | |
| 18841 | { |
| 18842 | /* |
| 18843 | The following will unlock all cursors if the command wasn't an |
| 18844 | update command |
| 18845 | */ |
| 18846 | join->join_free(); // Unlock all cursors |
| 18847 | } |
| 18848 | if (error == NESTED_LOOP_OK) |
| 18849 | { |
| 18850 | /* |
| 18851 | Sic: this branch works even if rc != 0, e.g. when |
| 18852 | send_data above returns an error. |
| 18853 | */ |
| 18854 | if (unlikely(join->result->send_eof())) |
| 18855 | rc= 1; // Don't send error |
| 18856 | DBUG_PRINT("info" ,("%ld records output" , (long) join->send_records)); |
| 18857 | } |
| 18858 | else |
| 18859 | rc= -1; |
| 18860 | #ifndef DBUG_OFF |
| 18861 | if (rc) |
| 18862 | { |
| 18863 | DBUG_PRINT("error" ,("Error: do_select() failed" )); |
| 18864 | } |
| 18865 | #endif |
| 18866 | rc= join->thd->is_error() ? -1 : rc; |
| 18867 | DBUG_RETURN(rc); |
| 18868 | } |
| 18869 | |
| 18870 | |
| 18871 | int rr_sequential_and_unpack(READ_RECORD *info) |
| 18872 | { |
| 18873 | int error; |
| 18874 | if (unlikely((error= rr_sequential(info)))) |
| 18875 | return error; |
| 18876 | |
| 18877 | for (Copy_field *cp= info->copy_field; cp != info->copy_field_end; cp++) |
| 18878 | (*cp->do_copy)(cp); |
| 18879 | |
| 18880 | return error; |
| 18881 | } |
| 18882 | |
| 18883 | |
| 18884 | /** |
| 18885 | @brief |
| 18886 | Instantiates temporary table |
| 18887 | |
| 18888 | @param table Table object that describes the table to be |
| 18889 | instantiated |
| 18890 | @param keyinfo Description of the index (there is always one index) |
| 18891 | @param start_recinfo Column descriptions |
| 18892 | @param recinfo INOUT End of column descriptions |
| 18893 | @param options Option bits |
| 18894 | |
| 18895 | @details |
| 18896 | Creates tmp table and opens it. |
| 18897 | |
| 18898 | @return |
| 18899 | FALSE - OK |
| 18900 | TRUE - Error |
| 18901 | */ |
| 18902 | |
| 18903 | bool instantiate_tmp_table(TABLE *table, KEY *keyinfo, |
| 18904 | TMP_ENGINE_COLUMNDEF *start_recinfo, |
| 18905 | TMP_ENGINE_COLUMNDEF **recinfo, |
| 18906 | ulonglong options) |
| 18907 | { |
| 18908 | if (table->s->db_type() == TMP_ENGINE_HTON) |
| 18909 | { |
| 18910 | /* |
| 18911 | If it is not heap (in-memory) table then convert index to unique |
| 18912 | constrain. |
| 18913 | */ |
| 18914 | if (create_internal_tmp_table(table, keyinfo, start_recinfo, recinfo, |
| 18915 | options)) |
| 18916 | return TRUE; |
| 18917 | // Make empty record so random data is not written to disk |
| 18918 | empty_record(table); |
| 18919 | } |
| 18920 | if (open_tmp_table(table)) |
| 18921 | return TRUE; |
| 18922 | |
| 18923 | return FALSE; |
| 18924 | } |
| 18925 | |
| 18926 | |
| 18927 | /** |
| 18928 | @brief |
| 18929 | Accumulate rows of the result of an aggregation operation in a tmp table |
| 18930 | |
| 18931 | @param join pointer to the structure providing all context info for the query |
| 18932 | @param join_tab the JOIN_TAB object to which the operation is attached |
| 18933 | @param end_records TRUE <=> all records were accumulated, send them further |
| 18934 | |
| 18935 | @details |
| 18936 | This function accumulates records of the aggreagation operation for |
| 18937 | the node join_tab from the execution plan in a tmp table. To add a new |
| 18938 | record the function calls join_tab->aggr->put_records. |
| 18939 | When there is no more records to save, in this |
| 18940 | case the end_of_records argument == true, function tells the operation to |
| 18941 | send records further by calling aggr->send_records(). |
| 18942 | When all records are sent this function passes 'end_of_records' signal |
| 18943 | further by calling sub_select() with end_of_records argument set to |
| 18944 | true. After that aggr->end_send() is called to tell the operation that |
| 18945 | it could end internal buffer scan. |
| 18946 | |
| 18947 | @note |
| 18948 | This function is not expected to be called when dynamic range scan is |
| 18949 | used to scan join_tab because range scans aren't used for tmp tables. |
| 18950 | |
| 18951 | @return |
| 18952 | return one of enum_nested_loop_state. |
| 18953 | */ |
| 18954 | |
| 18955 | enum_nested_loop_state |
| 18956 | sub_select_postjoin_aggr(JOIN *join, JOIN_TAB *join_tab, bool end_of_records) |
| 18957 | { |
| 18958 | enum_nested_loop_state rc; |
| 18959 | AGGR_OP *aggr= join_tab->aggr; |
| 18960 | |
| 18961 | /* This function cannot be called if join_tab has no associated aggregation */ |
| 18962 | DBUG_ASSERT(aggr != NULL); |
| 18963 | |
| 18964 | DBUG_ENTER("sub_select_aggr_tab" ); |
| 18965 | |
| 18966 | if (join->thd->killed) |
| 18967 | { |
| 18968 | /* The user has aborted the execution of the query */ |
| 18969 | join->thd->send_kill_message(); |
| 18970 | DBUG_RETURN(NESTED_LOOP_KILLED); |
| 18971 | } |
| 18972 | |
| 18973 | if (end_of_records) |
| 18974 | { |
| 18975 | rc= aggr->end_send(); |
| 18976 | if (rc >= NESTED_LOOP_OK) |
| 18977 | rc= sub_select(join, join_tab, end_of_records); |
| 18978 | DBUG_RETURN(rc); |
| 18979 | } |
| 18980 | |
| 18981 | rc= aggr->put_record(); |
| 18982 | |
| 18983 | DBUG_RETURN(rc); |
| 18984 | } |
| 18985 | |
| 18986 | |
| 18987 | /* |
| 18988 | Fill the join buffer with partial records, retrieve all full matches for |
| 18989 | them |
| 18990 | |
| 18991 | SYNOPSIS |
| 18992 | sub_select_cache() |
| 18993 | join pointer to the structure providing all context info for the |
| 18994 | query |
| 18995 | join_tab the first next table of the execution plan to be retrieved |
| 18996 | end_records true when we need to perform final steps of the retrieval |
| 18997 | |
| 18998 | DESCRIPTION |
| 18999 | For a given table Ti= join_tab from the sequence of tables of the chosen |
| 19000 | execution plan T1,...,Ti,...,Tn the function just put the partial record |
| 19001 | t1,...,t[i-1] into the join buffer associated with table Ti unless this |
| 19002 | is the last record added into the buffer. In this case, the function |
| 19003 | additionally finds all matching full records for all partial |
| 19004 | records accumulated in the buffer, after which it cleans the buffer up. |
| 19005 | If a partial join record t1,...,ti is extended utilizing a dynamic |
| 19006 | range scan then it is not put into the join buffer. Rather all matching |
| 19007 | records are found for it at once by the function sub_select. |
| 19008 | |
| 19009 | NOTES |
| 19010 | The function implements the algorithmic schema for both Blocked Nested |
| 19011 | Loop Join and Batched Key Access Join. The difference can be seen only at |
| 19012 | the level of of the implementation of the put_record and join_records |
| 19013 | virtual methods for the cache object associated with the join_tab. |
| 19014 | The put_record method accumulates records in the cache, while the |
| 19015 | join_records method builds all matching join records and send them into |
| 19016 | the output stream. |
| 19017 | |
| 19018 | RETURN |
| 19019 | return one of enum_nested_loop_state, except NESTED_LOOP_NO_MORE_ROWS. |
| 19020 | */ |
| 19021 | |
| 19022 | enum_nested_loop_state |
| 19023 | sub_select_cache(JOIN *join, JOIN_TAB *join_tab, bool end_of_records) |
| 19024 | { |
| 19025 | enum_nested_loop_state rc; |
| 19026 | JOIN_CACHE *cache= join_tab->cache; |
| 19027 | DBUG_ENTER("sub_select_cache" ); |
| 19028 | |
| 19029 | /* |
| 19030 | This function cannot be called if join_tab has no associated join |
| 19031 | buffer |
| 19032 | */ |
| 19033 | DBUG_ASSERT(cache != NULL); |
| 19034 | |
| 19035 | join_tab->cache->reset_join(join); |
| 19036 | |
| 19037 | if (end_of_records) |
| 19038 | { |
| 19039 | rc= cache->join_records(FALSE); |
| 19040 | if (rc == NESTED_LOOP_OK || rc == NESTED_LOOP_NO_MORE_ROWS || |
| 19041 | rc == NESTED_LOOP_QUERY_LIMIT) |
| 19042 | rc= sub_select(join, join_tab, end_of_records); |
| 19043 | DBUG_RETURN(rc); |
| 19044 | } |
| 19045 | if (unlikely(join->thd->check_killed())) |
| 19046 | { |
| 19047 | /* The user has aborted the execution of the query */ |
| 19048 | join->thd->send_kill_message(); |
| 19049 | DBUG_RETURN(NESTED_LOOP_KILLED); |
| 19050 | } |
| 19051 | if (!test_if_use_dynamic_range_scan(join_tab)) |
| 19052 | { |
| 19053 | if (!cache->put_record()) |
| 19054 | DBUG_RETURN(NESTED_LOOP_OK); |
| 19055 | /* |
| 19056 | We has decided that after the record we've just put into the buffer |
| 19057 | won't add any more records. Now try to find all the matching |
| 19058 | extensions for all records in the buffer. |
| 19059 | */ |
| 19060 | rc= cache->join_records(FALSE); |
| 19061 | DBUG_RETURN(rc); |
| 19062 | } |
| 19063 | /* |
| 19064 | TODO: Check whether we really need the call below and we can't do |
| 19065 | without it. If it's not the case remove it. |
| 19066 | */ |
| 19067 | rc= cache->join_records(TRUE); |
| 19068 | if (rc == NESTED_LOOP_OK || rc == NESTED_LOOP_NO_MORE_ROWS || |
| 19069 | rc == NESTED_LOOP_QUERY_LIMIT) |
| 19070 | rc= sub_select(join, join_tab, end_of_records); |
| 19071 | DBUG_RETURN(rc); |
| 19072 | } |
| 19073 | |
| 19074 | /** |
| 19075 | Retrieve records ends with a given beginning from the result of a join. |
| 19076 | |
| 19077 | For a given partial join record consisting of records from the tables |
| 19078 | preceding the table join_tab in the execution plan, the function |
| 19079 | retrieves all matching full records from the result set and |
| 19080 | send them to the result set stream. |
| 19081 | |
| 19082 | @note |
| 19083 | The function effectively implements the final (n-k) nested loops |
| 19084 | of nested loops join algorithm, where k is the ordinal number of |
| 19085 | the join_tab table and n is the total number of tables in the join query. |
| 19086 | It performs nested loops joins with all conjunctive predicates from |
| 19087 | the where condition pushed as low to the tables as possible. |
| 19088 | E.g. for the query |
| 19089 | @code |
| 19090 | SELECT * FROM t1,t2,t3 |
| 19091 | WHERE t1.a=t2.a AND t2.b=t3.b AND t1.a BETWEEN 5 AND 9 |
| 19092 | @endcode |
| 19093 | the predicate (t1.a BETWEEN 5 AND 9) will be pushed to table t1, |
| 19094 | given the selected plan prescribes to nest retrievals of the |
| 19095 | joined tables in the following order: t1,t2,t3. |
| 19096 | A pushed down predicate are attached to the table which it pushed to, |
| 19097 | at the field join_tab->select_cond. |
| 19098 | When executing a nested loop of level k the function runs through |
| 19099 | the rows of 'join_tab' and for each row checks the pushed condition |
| 19100 | attached to the table. |
| 19101 | If it is false the function moves to the next row of the |
| 19102 | table. If the condition is true the function recursively executes (n-k-1) |
| 19103 | remaining embedded nested loops. |
| 19104 | The situation becomes more complicated if outer joins are involved in |
| 19105 | the execution plan. In this case the pushed down predicates can be |
| 19106 | checked only at certain conditions. |
| 19107 | Suppose for the query |
| 19108 | @code |
| 19109 | SELECT * FROM t1 LEFT JOIN (t2,t3) ON t3.a=t1.a |
| 19110 | WHERE t1>2 AND (t2.b>5 OR t2.b IS NULL) |
| 19111 | @endcode |
| 19112 | the optimizer has chosen a plan with the table order t1,t2,t3. |
| 19113 | The predicate P1=t1>2 will be pushed down to the table t1, while the |
| 19114 | predicate P2=(t2.b>5 OR t2.b IS NULL) will be attached to the table |
| 19115 | t2. But the second predicate can not be unconditionally tested right |
| 19116 | after a row from t2 has been read. This can be done only after the |
| 19117 | first row with t3.a=t1.a has been encountered. |
| 19118 | Thus, the second predicate P2 is supplied with a guarded value that are |
| 19119 | stored in the field 'found' of the first inner table for the outer join |
| 19120 | (table t2). When the first row with t3.a=t1.a for the current row |
| 19121 | of table t1 appears, the value becomes true. For now on the predicate |
| 19122 | is evaluated immediately after the row of table t2 has been read. |
| 19123 | When the first row with t3.a=t1.a has been encountered all |
| 19124 | conditions attached to the inner tables t2,t3 must be evaluated. |
| 19125 | Only when all of them are true the row is sent to the output stream. |
| 19126 | If not, the function returns to the lowest nest level that has a false |
| 19127 | attached condition. |
| 19128 | The predicates from on expressions are also pushed down. If in the |
| 19129 | the above example the on expression were (t3.a=t1.a AND t2.a=t1.a), |
| 19130 | then t1.a=t2.a would be pushed down to table t2, and without any |
| 19131 | guard. |
| 19132 | If after the run through all rows of table t2, the first inner table |
| 19133 | for the outer join operation, it turns out that no matches are |
| 19134 | found for the current row of t1, then current row from table t1 |
| 19135 | is complemented by nulls for t2 and t3. Then the pushed down predicates |
| 19136 | are checked for the composed row almost in the same way as it had |
| 19137 | been done for the first row with a match. The only difference is |
| 19138 | the predicates from on expressions are not checked. |
| 19139 | |
| 19140 | @par |
| 19141 | @b IMPLEMENTATION |
| 19142 | @par |
| 19143 | The function forms output rows for a current partial join of k |
| 19144 | tables tables recursively. |
| 19145 | For each partial join record ending with a certain row from |
| 19146 | join_tab it calls sub_select that builds all possible matching |
| 19147 | tails from the result set. |
| 19148 | To be able check predicates conditionally items of the class |
| 19149 | Item_func_trig_cond are employed. |
| 19150 | An object of this class is constructed from an item of class COND |
| 19151 | and a pointer to a guarding boolean variable. |
| 19152 | When the value of the guard variable is true the value of the object |
| 19153 | is the same as the value of the predicate, otherwise it's just returns |
| 19154 | true. |
| 19155 | To carry out a return to a nested loop level of join table t the pointer |
| 19156 | to t is remembered in the field 'return_rtab' of the join structure. |
| 19157 | Consider the following query: |
| 19158 | @code |
| 19159 | SELECT * FROM t1, |
| 19160 | LEFT JOIN |
| 19161 | (t2, t3 LEFT JOIN (t4,t5) ON t5.a=t3.a) |
| 19162 | ON t4.a=t2.a |
| 19163 | WHERE (t2.b=5 OR t2.b IS NULL) AND (t4.b=2 OR t4.b IS NULL) |
| 19164 | @endcode |
| 19165 | Suppose the chosen execution plan dictates the order t1,t2,t3,t4,t5 |
| 19166 | and suppose for a given joined rows from tables t1,t2,t3 there are |
| 19167 | no rows in the result set yet. |
| 19168 | When first row from t5 that satisfies the on condition |
| 19169 | t5.a=t3.a is found, the pushed down predicate t4.b=2 OR t4.b IS NULL |
| 19170 | becomes 'activated', as well the predicate t4.a=t2.a. But |
| 19171 | the predicate (t2.b=5 OR t2.b IS NULL) can not be checked until |
| 19172 | t4.a=t2.a becomes true. |
| 19173 | In order not to re-evaluate the predicates that were already evaluated |
| 19174 | as attached pushed down predicates, a pointer to the the first |
| 19175 | most inner unmatched table is maintained in join_tab->first_unmatched. |
| 19176 | Thus, when the first row from t5 with t5.a=t3.a is found |
| 19177 | this pointer for t5 is changed from t4 to t2. |
| 19178 | |
| 19179 | @par |
| 19180 | @b STRUCTURE @b NOTES |
| 19181 | @par |
| 19182 | join_tab->first_unmatched points always backwards to the first inner |
| 19183 | table of the embedding nested join, if any. |
| 19184 | |
| 19185 | @param join pointer to the structure providing all context info for |
| 19186 | the query |
| 19187 | @param join_tab the first next table of the execution plan to be retrieved |
| 19188 | @param end_records true when we need to perform final steps of retrival |
| 19189 | |
| 19190 | @return |
| 19191 | return one of enum_nested_loop_state, except NESTED_LOOP_NO_MORE_ROWS. |
| 19192 | */ |
| 19193 | |
| 19194 | enum_nested_loop_state |
| 19195 | sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records) |
| 19196 | { |
| 19197 | DBUG_ENTER("sub_select" ); |
| 19198 | |
| 19199 | if (join_tab->last_inner) |
| 19200 | { |
| 19201 | JOIN_TAB *last_inner_tab= join_tab->last_inner; |
| 19202 | for (JOIN_TAB *jt= join_tab; jt <= last_inner_tab; jt++) |
| 19203 | jt->table->null_row= 0; |
| 19204 | } |
| 19205 | else |
| 19206 | join_tab->table->null_row=0; |
| 19207 | |
| 19208 | if (end_of_records) |
| 19209 | { |
| 19210 | enum_nested_loop_state nls= |
| 19211 | (*join_tab->next_select)(join,join_tab+1,end_of_records); |
| 19212 | DBUG_RETURN(nls); |
| 19213 | } |
| 19214 | join_tab->tracker->r_scans++; |
| 19215 | |
| 19216 | int error; |
| 19217 | enum_nested_loop_state rc= NESTED_LOOP_OK; |
| 19218 | READ_RECORD *info= &join_tab->read_record; |
| 19219 | |
| 19220 | |
| 19221 | for (SJ_TMP_TABLE *flush_dups_table= join_tab->flush_weedout_table; |
| 19222 | flush_dups_table; |
| 19223 | flush_dups_table= flush_dups_table->next_flush_table) |
| 19224 | { |
| 19225 | flush_dups_table->sj_weedout_delete_rows(); |
| 19226 | } |
| 19227 | |
| 19228 | if (!join_tab->preread_init_done && join_tab->preread_init()) |
| 19229 | DBUG_RETURN(NESTED_LOOP_ERROR); |
| 19230 | |
| 19231 | join->return_tab= join_tab; |
| 19232 | |
| 19233 | if (join_tab->last_inner) |
| 19234 | { |
| 19235 | /* join_tab is the first inner table for an outer join operation. */ |
| 19236 | |
| 19237 | /* Set initial state of guard variables for this table.*/ |
| 19238 | join_tab->found=0; |
| 19239 | join_tab->not_null_compl= 1; |
| 19240 | |
| 19241 | /* Set first_unmatched for the last inner table of this group */ |
| 19242 | join_tab->last_inner->first_unmatched= join_tab; |
| 19243 | if (join_tab->on_precond && !join_tab->on_precond->val_int()) |
| 19244 | rc= NESTED_LOOP_NO_MORE_ROWS; |
| 19245 | } |
| 19246 | join->thd->get_stmt_da()->reset_current_row_for_warning(); |
| 19247 | |
| 19248 | if (rc != NESTED_LOOP_NO_MORE_ROWS && |
| 19249 | (rc= join_tab_execution_startup(join_tab)) < 0) |
| 19250 | DBUG_RETURN(rc); |
| 19251 | |
| 19252 | if (join_tab->loosescan_match_tab) |
| 19253 | join_tab->loosescan_match_tab->found_match= FALSE; |
| 19254 | |
| 19255 | if (rc != NESTED_LOOP_NO_MORE_ROWS) |
| 19256 | { |
| 19257 | error= (*join_tab->read_first_record)(join_tab); |
| 19258 | if (!error && join_tab->keep_current_rowid) |
| 19259 | join_tab->table->file->position(join_tab->table->record[0]); |
| 19260 | rc= evaluate_join_record(join, join_tab, error); |
| 19261 | } |
| 19262 | |
| 19263 | /* |
| 19264 | Note: psergey has added the 2nd part of the following condition; the |
| 19265 | change should probably be made in 5.1, too. |
| 19266 | */ |
| 19267 | bool skip_over= FALSE; |
| 19268 | while (rc == NESTED_LOOP_OK && join->return_tab >= join_tab) |
| 19269 | { |
| 19270 | if (join_tab->loosescan_match_tab && |
| 19271 | join_tab->loosescan_match_tab->found_match) |
| 19272 | { |
| 19273 | KEY *key= join_tab->table->key_info + join_tab->loosescan_key; |
| 19274 | key_copy(join_tab->loosescan_buf, join_tab->table->record[0], key, |
| 19275 | join_tab->loosescan_key_len); |
| 19276 | skip_over= TRUE; |
| 19277 | } |
| 19278 | |
| 19279 | error= info->read_record(); |
| 19280 | |
| 19281 | if (skip_over && likely(!error)) |
| 19282 | { |
| 19283 | if (!key_cmp(join_tab->table->key_info[join_tab->loosescan_key].key_part, |
| 19284 | join_tab->loosescan_buf, join_tab->loosescan_key_len)) |
| 19285 | { |
| 19286 | /* |
| 19287 | This is the LooseScan action: skip over records with the same key |
| 19288 | value if we already had a match for them. |
| 19289 | */ |
| 19290 | continue; |
| 19291 | } |
| 19292 | join_tab->loosescan_match_tab->found_match= FALSE; |
| 19293 | skip_over= FALSE; |
| 19294 | } |
| 19295 | |
| 19296 | if (join_tab->keep_current_rowid && likely(!error)) |
| 19297 | join_tab->table->file->position(join_tab->table->record[0]); |
| 19298 | |
| 19299 | rc= evaluate_join_record(join, join_tab, error); |
| 19300 | } |
| 19301 | |
| 19302 | if (rc == NESTED_LOOP_NO_MORE_ROWS && |
| 19303 | join_tab->last_inner && !join_tab->found) |
| 19304 | rc= evaluate_null_complemented_join_record(join, join_tab); |
| 19305 | |
| 19306 | if (rc == NESTED_LOOP_NO_MORE_ROWS) |
| 19307 | rc= NESTED_LOOP_OK; |
| 19308 | DBUG_RETURN(rc); |
| 19309 | } |
| 19310 | |
| 19311 | /** |
| 19312 | @brief Process one row of the nested loop join. |
| 19313 | |
| 19314 | This function will evaluate parts of WHERE/ON clauses that are |
| 19315 | applicable to the partial row on hand and in case of success |
| 19316 | submit this row to the next level of the nested loop. |
| 19317 | |
| 19318 | @param join - The join object |
| 19319 | @param join_tab - The most inner join_tab being processed |
| 19320 | @param error > 0: Error, terminate processing |
| 19321 | = 0: (Partial) row is available |
| 19322 | < 0: No more rows available at this level |
| 19323 | @return Nested loop state (Ok, No_more_rows, Error, Killed) |
| 19324 | */ |
| 19325 | |
| 19326 | static enum_nested_loop_state |
| 19327 | evaluate_join_record(JOIN *join, JOIN_TAB *join_tab, |
| 19328 | int error) |
| 19329 | { |
| 19330 | bool shortcut_for_distinct= join_tab->shortcut_for_distinct; |
| 19331 | ha_rows found_records=join->found_records; |
| 19332 | COND *select_cond= join_tab->select_cond; |
| 19333 | bool select_cond_result= TRUE; |
| 19334 | |
| 19335 | DBUG_ENTER("evaluate_join_record" ); |
| 19336 | DBUG_PRINT("enter" , |
| 19337 | ("evaluate_join_record join: %p join_tab: %p" |
| 19338 | " cond: %p error: %d alias %s" , |
| 19339 | join, join_tab, select_cond, error, |
| 19340 | join_tab->table->alias.ptr())); |
| 19341 | |
| 19342 | if (error > 0 || unlikely(join->thd->is_error())) // Fatal error |
| 19343 | DBUG_RETURN(NESTED_LOOP_ERROR); |
| 19344 | if (error < 0) |
| 19345 | DBUG_RETURN(NESTED_LOOP_NO_MORE_ROWS); |
| 19346 | if (unlikely(join->thd->check_killed())) // Aborted by user |
| 19347 | { |
| 19348 | join->thd->send_kill_message(); |
| 19349 | DBUG_RETURN(NESTED_LOOP_KILLED); /* purecov: inspected */ |
| 19350 | } |
| 19351 | |
| 19352 | join_tab->tracker->r_rows++; |
| 19353 | |
| 19354 | if (select_cond) |
| 19355 | { |
| 19356 | select_cond_result= MY_TEST(select_cond->val_int()); |
| 19357 | |
| 19358 | /* check for errors evaluating the condition */ |
| 19359 | if (unlikely(join->thd->is_error())) |
| 19360 | DBUG_RETURN(NESTED_LOOP_ERROR); |
| 19361 | } |
| 19362 | |
| 19363 | if (!select_cond || select_cond_result) |
| 19364 | { |
| 19365 | /* |
| 19366 | There is no select condition or the attached pushed down |
| 19367 | condition is true => a match is found. |
| 19368 | */ |
| 19369 | join_tab->tracker->r_rows_after_where++; |
| 19370 | |
| 19371 | bool found= 1; |
| 19372 | while (join_tab->first_unmatched && found) |
| 19373 | { |
| 19374 | /* |
| 19375 | The while condition is always false if join_tab is not |
| 19376 | the last inner join table of an outer join operation. |
| 19377 | */ |
| 19378 | JOIN_TAB *first_unmatched= join_tab->first_unmatched; |
| 19379 | /* |
| 19380 | Mark that a match for current outer table is found. |
| 19381 | This activates push down conditional predicates attached |
| 19382 | to the all inner tables of the outer join. |
| 19383 | */ |
| 19384 | first_unmatched->found= 1; |
| 19385 | for (JOIN_TAB *tab= first_unmatched; tab <= join_tab; tab++) |
| 19386 | { |
| 19387 | /* |
| 19388 | Check whether 'not exists' optimization can be used here. |
| 19389 | If tab->table->reginfo.not_exists_optimize is set to true |
| 19390 | then WHERE contains a conjunctive predicate IS NULL over |
| 19391 | a non-nullable field of tab. When activated this predicate |
| 19392 | will filter out all records with matches for the left part |
| 19393 | of the outer join whose inner tables start from the |
| 19394 | first_unmatched table and include table tab. To safely use |
| 19395 | 'not exists' optimization we have to check that the |
| 19396 | IS NULL predicate is really activated, i.e. all guards |
| 19397 | that wrap it are in the 'open' state. |
| 19398 | */ |
| 19399 | bool not_exists_opt_is_applicable= |
| 19400 | tab->table->reginfo.not_exists_optimize; |
| 19401 | for (JOIN_TAB *first_upper= first_unmatched->first_upper; |
| 19402 | not_exists_opt_is_applicable && first_upper; |
| 19403 | first_upper= first_upper->first_upper) |
| 19404 | { |
| 19405 | if (!first_upper->found) |
| 19406 | not_exists_opt_is_applicable= false; |
| 19407 | } |
| 19408 | /* Check all predicates that has just been activated. */ |
| 19409 | /* |
| 19410 | Actually all predicates non-guarded by first_unmatched->found |
| 19411 | will be re-evaluated again. It could be fixed, but, probably, |
| 19412 | it's not worth doing now. |
| 19413 | */ |
| 19414 | if (tab->select_cond && !tab->select_cond->val_int()) |
| 19415 | { |
| 19416 | /* The condition attached to table tab is false */ |
| 19417 | if (tab == join_tab) |
| 19418 | { |
| 19419 | found= 0; |
| 19420 | if (not_exists_opt_is_applicable) |
| 19421 | DBUG_RETURN(NESTED_LOOP_NO_MORE_ROWS); |
| 19422 | } |
| 19423 | else |
| 19424 | { |
| 19425 | /* |
| 19426 | Set a return point if rejected predicate is attached |
| 19427 | not to the last table of the current nest level. |
| 19428 | */ |
| 19429 | join->return_tab= tab; |
| 19430 | if (not_exists_opt_is_applicable) |
| 19431 | DBUG_RETURN(NESTED_LOOP_NO_MORE_ROWS); |
| 19432 | else |
| 19433 | DBUG_RETURN(NESTED_LOOP_OK); |
| 19434 | } |
| 19435 | } |
| 19436 | } |
| 19437 | /* |
| 19438 | Check whether join_tab is not the last inner table |
| 19439 | for another embedding outer join. |
| 19440 | */ |
| 19441 | if ((first_unmatched= first_unmatched->first_upper) && |
| 19442 | first_unmatched->last_inner != join_tab) |
| 19443 | first_unmatched= 0; |
| 19444 | join_tab->first_unmatched= first_unmatched; |
| 19445 | } |
| 19446 | |
| 19447 | JOIN_TAB *return_tab= join->return_tab; |
| 19448 | join_tab->found_match= TRUE; |
| 19449 | |
| 19450 | if (join_tab->check_weed_out_table && found) |
| 19451 | { |
| 19452 | int res= join_tab->check_weed_out_table->sj_weedout_check_row(join->thd); |
| 19453 | DBUG_PRINT("info" , ("weedout_check: %d" , res)); |
| 19454 | if (res == -1) |
| 19455 | DBUG_RETURN(NESTED_LOOP_ERROR); |
| 19456 | else if (res == 1) |
| 19457 | found= FALSE; |
| 19458 | } |
| 19459 | else if (join_tab->do_firstmatch) |
| 19460 | { |
| 19461 | /* |
| 19462 | We should return to the join_tab->do_firstmatch after we have |
| 19463 | enumerated all the suffixes for current prefix row combination |
| 19464 | */ |
| 19465 | return_tab= join_tab->do_firstmatch; |
| 19466 | } |
| 19467 | |
| 19468 | /* |
| 19469 | It was not just a return to lower loop level when one |
| 19470 | of the newly activated predicates is evaluated as false |
| 19471 | (See above join->return_tab= tab). |
| 19472 | */ |
| 19473 | join->join_examined_rows++; |
| 19474 | DBUG_PRINT("counts" , ("join->examined_rows++: %lu found: %d" , |
| 19475 | (ulong) join->join_examined_rows, (int) found)); |
| 19476 | |
| 19477 | if (found) |
| 19478 | { |
| 19479 | enum enum_nested_loop_state rc; |
| 19480 | /* A match from join_tab is found for the current partial join. */ |
| 19481 | rc= (*join_tab->next_select)(join, join_tab+1, 0); |
| 19482 | join->thd->get_stmt_da()->inc_current_row_for_warning(); |
| 19483 | if (rc != NESTED_LOOP_OK && rc != NESTED_LOOP_NO_MORE_ROWS) |
| 19484 | DBUG_RETURN(rc); |
| 19485 | if (return_tab < join->return_tab) |
| 19486 | join->return_tab= return_tab; |
| 19487 | |
| 19488 | /* check for errors evaluating the condition */ |
| 19489 | if (unlikely(join->thd->is_error())) |
| 19490 | DBUG_RETURN(NESTED_LOOP_ERROR); |
| 19491 | |
| 19492 | if (join->return_tab < join_tab) |
| 19493 | DBUG_RETURN(NESTED_LOOP_OK); |
| 19494 | /* |
| 19495 | Test if this was a SELECT DISTINCT query on a table that |
| 19496 | was not in the field list; In this case we can abort if |
| 19497 | we found a row, as no new rows can be added to the result. |
| 19498 | */ |
| 19499 | if (shortcut_for_distinct && found_records != join->found_records) |
| 19500 | DBUG_RETURN(NESTED_LOOP_NO_MORE_ROWS); |
| 19501 | } |
| 19502 | else |
| 19503 | { |
| 19504 | join->thd->get_stmt_da()->inc_current_row_for_warning(); |
| 19505 | join_tab->read_record.unlock_row(join_tab); |
| 19506 | } |
| 19507 | } |
| 19508 | else |
| 19509 | { |
| 19510 | /* |
| 19511 | The condition pushed down to the table join_tab rejects all rows |
| 19512 | with the beginning coinciding with the current partial join. |
| 19513 | */ |
| 19514 | join->join_examined_rows++; |
| 19515 | join->thd->get_stmt_da()->inc_current_row_for_warning(); |
| 19516 | join_tab->read_record.unlock_row(join_tab); |
| 19517 | } |
| 19518 | DBUG_RETURN(NESTED_LOOP_OK); |
| 19519 | } |
| 19520 | |
| 19521 | /** |
| 19522 | |
| 19523 | @details |
| 19524 | Construct a NULL complimented partial join record and feed it to the next |
| 19525 | level of the nested loop. This function is used in case we have |
| 19526 | an OUTER join and no matching record was found. |
| 19527 | */ |
| 19528 | |
| 19529 | static enum_nested_loop_state |
| 19530 | evaluate_null_complemented_join_record(JOIN *join, JOIN_TAB *join_tab) |
| 19531 | { |
| 19532 | /* |
| 19533 | The table join_tab is the first inner table of a outer join operation |
| 19534 | and no matches has been found for the current outer row. |
| 19535 | */ |
| 19536 | JOIN_TAB *last_inner_tab= join_tab->last_inner; |
| 19537 | /* Cache variables for faster loop */ |
| 19538 | COND *select_cond; |
| 19539 | for ( ; join_tab <= last_inner_tab ; join_tab++) |
| 19540 | { |
| 19541 | /* Change the the values of guard predicate variables. */ |
| 19542 | join_tab->found= 1; |
| 19543 | join_tab->not_null_compl= 0; |
| 19544 | /* The outer row is complemented by nulls for each inner tables */ |
| 19545 | restore_record(join_tab->table,s->default_values); // Make empty record |
| 19546 | mark_as_null_row(join_tab->table); // For group by without error |
| 19547 | select_cond= join_tab->select_cond; |
| 19548 | /* Check all attached conditions for inner table rows. */ |
| 19549 | if (select_cond && !select_cond->val_int()) |
| 19550 | return NESTED_LOOP_OK; |
| 19551 | } |
| 19552 | join_tab--; |
| 19553 | /* |
| 19554 | The row complemented by nulls might be the first row |
| 19555 | of embedding outer joins. |
| 19556 | If so, perform the same actions as in the code |
| 19557 | for the first regular outer join row above. |
| 19558 | */ |
| 19559 | for ( ; ; ) |
| 19560 | { |
| 19561 | JOIN_TAB *first_unmatched= join_tab->first_unmatched; |
| 19562 | if ((first_unmatched= first_unmatched->first_upper) && |
| 19563 | first_unmatched->last_inner != join_tab) |
| 19564 | first_unmatched= 0; |
| 19565 | join_tab->first_unmatched= first_unmatched; |
| 19566 | if (!first_unmatched) |
| 19567 | break; |
| 19568 | first_unmatched->found= 1; |
| 19569 | for (JOIN_TAB *tab= first_unmatched; tab <= join_tab; tab++) |
| 19570 | { |
| 19571 | if (tab->select_cond && !tab->select_cond->val_int()) |
| 19572 | { |
| 19573 | join->return_tab= tab; |
| 19574 | return NESTED_LOOP_OK; |
| 19575 | } |
| 19576 | } |
| 19577 | } |
| 19578 | /* |
| 19579 | The row complemented by nulls satisfies all conditions |
| 19580 | attached to inner tables. |
| 19581 | */ |
| 19582 | if (join_tab->check_weed_out_table) |
| 19583 | { |
| 19584 | int res= join_tab->check_weed_out_table->sj_weedout_check_row(join->thd); |
| 19585 | if (res == -1) |
| 19586 | return NESTED_LOOP_ERROR; |
| 19587 | else if (res == 1) |
| 19588 | return NESTED_LOOP_OK; |
| 19589 | } |
| 19590 | else if (join_tab->do_firstmatch) |
| 19591 | { |
| 19592 | /* |
| 19593 | We should return to the join_tab->do_firstmatch after we have |
| 19594 | enumerated all the suffixes for current prefix row combination |
| 19595 | */ |
| 19596 | if (join_tab->do_firstmatch < join->return_tab) |
| 19597 | join->return_tab= join_tab->do_firstmatch; |
| 19598 | } |
| 19599 | |
| 19600 | /* |
| 19601 | Send the row complemented by nulls to be joined with the |
| 19602 | remaining tables. |
| 19603 | */ |
| 19604 | return (*join_tab->next_select)(join, join_tab+1, 0); |
| 19605 | } |
| 19606 | |
| 19607 | /***************************************************************************** |
| 19608 | The different ways to read a record |
| 19609 | Returns -1 if row was not found, 0 if row was found and 1 on errors |
| 19610 | *****************************************************************************/ |
| 19611 | |
| 19612 | /** Help function when we get some an error from the table handler. */ |
| 19613 | |
| 19614 | int report_error(TABLE *table, int error) |
| 19615 | { |
| 19616 | if (error == HA_ERR_END_OF_FILE || error == HA_ERR_KEY_NOT_FOUND) |
| 19617 | { |
| 19618 | table->status= STATUS_GARBAGE; |
| 19619 | return -1; // key not found; ok |
| 19620 | } |
| 19621 | /* |
| 19622 | Locking reads can legally return also these errors, do not |
| 19623 | print them to the .err log |
| 19624 | */ |
| 19625 | if (error != HA_ERR_LOCK_DEADLOCK && error != HA_ERR_LOCK_WAIT_TIMEOUT |
| 19626 | && error != HA_ERR_TABLE_DEF_CHANGED && !table->in_use->killed) |
| 19627 | sql_print_error("Got error %d when reading table '%s'" , |
| 19628 | error, table->s->path.str); |
| 19629 | table->file->print_error(error,MYF(0)); |
| 19630 | return 1; |
| 19631 | } |
| 19632 | |
| 19633 | |
| 19634 | int safe_index_read(JOIN_TAB *tab) |
| 19635 | { |
| 19636 | int error; |
| 19637 | TABLE *table= tab->table; |
| 19638 | if (unlikely((error= |
| 19639 | table->file->ha_index_read_map(table->record[0], |
| 19640 | tab->ref.key_buff, |
| 19641 | make_prev_keypart_map(tab->ref.key_parts), |
| 19642 | HA_READ_KEY_EXACT)))) |
| 19643 | return report_error(table, error); |
| 19644 | return 0; |
| 19645 | } |
| 19646 | |
| 19647 | |
| 19648 | /** |
| 19649 | Reads content of constant table |
| 19650 | |
| 19651 | @param tab table |
| 19652 | @param pos position of table in query plan |
| 19653 | |
| 19654 | @retval 0 ok, one row was found or one NULL-complemented row was created |
| 19655 | @retval -1 ok, no row was found and no NULL-complemented row was created |
| 19656 | @retval 1 error |
| 19657 | */ |
| 19658 | |
| 19659 | static int |
| 19660 | join_read_const_table(THD *thd, JOIN_TAB *tab, POSITION *pos) |
| 19661 | { |
| 19662 | int error; |
| 19663 | TABLE_LIST *tbl; |
| 19664 | DBUG_ENTER("join_read_const_table" ); |
| 19665 | TABLE *table=tab->table; |
| 19666 | table->const_table=1; |
| 19667 | table->null_row=0; |
| 19668 | table->status=STATUS_NO_RECORD; |
| 19669 | |
| 19670 | if (tab->table->pos_in_table_list->is_materialized_derived() && |
| 19671 | !tab->table->pos_in_table_list->fill_me) |
| 19672 | { |
| 19673 | //TODO: don't get here at all |
| 19674 | /* Skip materialized derived tables/views. */ |
| 19675 | DBUG_RETURN(0); |
| 19676 | } |
| 19677 | else if (tab->table->pos_in_table_list->jtbm_subselect && |
| 19678 | tab->table->pos_in_table_list->jtbm_subselect->is_jtbm_const_tab) |
| 19679 | { |
| 19680 | /* Row will not be found */ |
| 19681 | int res; |
| 19682 | if (tab->table->pos_in_table_list->jtbm_subselect->jtbm_const_row_found) |
| 19683 | res= 0; |
| 19684 | else |
| 19685 | res= -1; |
| 19686 | DBUG_RETURN(res); |
| 19687 | } |
| 19688 | else if (tab->type == JT_SYSTEM) |
| 19689 | { |
| 19690 | if (unlikely((error=join_read_system(tab)))) |
| 19691 | { // Info for DESCRIBE |
| 19692 | tab->info= ET_CONST_ROW_NOT_FOUND; |
| 19693 | /* Mark for EXPLAIN that the row was not found */ |
| 19694 | pos->records_read=0.0; |
| 19695 | pos->ref_depend_map= 0; |
| 19696 | if (!table->pos_in_table_list->outer_join || error > 0) |
| 19697 | DBUG_RETURN(error); |
| 19698 | } |
| 19699 | /* |
| 19700 | The optimizer trust the engine that when stats.records is 0, there |
| 19701 | was no found rows |
| 19702 | */ |
| 19703 | DBUG_ASSERT(table->file->stats.records > 0 || error); |
| 19704 | } |
| 19705 | else |
| 19706 | { |
| 19707 | if (/*!table->file->key_read && */ |
| 19708 | table->covering_keys.is_set(tab->ref.key) && !table->no_keyread && |
| 19709 | (int) table->reginfo.lock_type <= (int) TL_READ_HIGH_PRIORITY) |
| 19710 | { |
| 19711 | table->file->ha_start_keyread(tab->ref.key); |
| 19712 | tab->index= tab->ref.key; |
| 19713 | } |
| 19714 | error=join_read_const(tab); |
| 19715 | table->file->ha_end_keyread(); |
| 19716 | if (unlikely(error)) |
| 19717 | { |
| 19718 | tab->info= ET_UNIQUE_ROW_NOT_FOUND; |
| 19719 | /* Mark for EXPLAIN that the row was not found */ |
| 19720 | pos->records_read=0.0; |
| 19721 | pos->ref_depend_map= 0; |
| 19722 | if (!table->pos_in_table_list->outer_join || error > 0) |
| 19723 | DBUG_RETURN(error); |
| 19724 | } |
| 19725 | } |
| 19726 | /* |
| 19727 | Evaluate an on-expression only if it is not considered expensive. |
| 19728 | This mainly prevents executing subqueries in optimization phase. |
| 19729 | This is necessary since proper setup for such execution has not been |
| 19730 | done at this stage. |
| 19731 | */ |
| 19732 | if (*tab->on_expr_ref && !table->null_row && |
| 19733 | !(*tab->on_expr_ref)->is_expensive()) |
| 19734 | { |
| 19735 | #if !defined(DBUG_OFF) && defined(NOT_USING_ITEM_EQUAL) |
| 19736 | /* |
| 19737 | This test could be very useful to find bugs in the optimizer |
| 19738 | where we would call this function with an expression that can't be |
| 19739 | evaluated yet. We can't have this enabled by default as long as |
| 19740 | have items like Item_equal, that doesn't report they are const but |
| 19741 | they can still be called even if they contain not const items. |
| 19742 | */ |
| 19743 | (*tab->on_expr_ref)->update_used_tables(); |
| 19744 | DBUG_ASSERT((*tab->on_expr_ref)->const_item()); |
| 19745 | #endif |
| 19746 | if ((table->null_row= MY_TEST((*tab->on_expr_ref)->val_int() == 0))) |
| 19747 | mark_as_null_row(table); |
| 19748 | } |
| 19749 | if (!table->null_row) |
| 19750 | table->maybe_null=0; |
| 19751 | |
| 19752 | { |
| 19753 | JOIN *join= tab->join; |
| 19754 | List_iterator<TABLE_LIST> ti(join->select_lex->leaf_tables); |
| 19755 | /* Check appearance of new constant items in Item_equal objects */ |
| 19756 | if (join->conds) |
| 19757 | update_const_equal_items(thd, join->conds, tab, TRUE); |
| 19758 | while ((tbl= ti++)) |
| 19759 | { |
| 19760 | TABLE_LIST *embedded; |
| 19761 | TABLE_LIST *embedding= tbl; |
| 19762 | do |
| 19763 | { |
| 19764 | embedded= embedding; |
| 19765 | if (embedded->on_expr) |
| 19766 | update_const_equal_items(thd, embedded->on_expr, tab, TRUE); |
| 19767 | embedding= embedded->embedding; |
| 19768 | } |
| 19769 | while (embedding && |
| 19770 | embedding->nested_join->join_list.head() == embedded); |
| 19771 | } |
| 19772 | } |
| 19773 | DBUG_RETURN(0); |
| 19774 | } |
| 19775 | |
| 19776 | |
| 19777 | /** |
| 19778 | Read a constant table when there is at most one matching row, using a table |
| 19779 | scan. |
| 19780 | |
| 19781 | @param tab Table to read |
| 19782 | |
| 19783 | @retval 0 Row was found |
| 19784 | @retval -1 Row was not found |
| 19785 | @retval 1 Got an error (other than row not found) during read |
| 19786 | */ |
| 19787 | static int |
| 19788 | join_read_system(JOIN_TAB *tab) |
| 19789 | { |
| 19790 | TABLE *table= tab->table; |
| 19791 | int error; |
| 19792 | if (table->status & STATUS_GARBAGE) // If first read |
| 19793 | { |
| 19794 | if (unlikely((error= |
| 19795 | table->file->ha_read_first_row(table->record[0], |
| 19796 | table->s->primary_key)))) |
| 19797 | { |
| 19798 | if (error != HA_ERR_END_OF_FILE) |
| 19799 | return report_error(table, error); |
| 19800 | table->const_table= 1; |
| 19801 | mark_as_null_row(tab->table); |
| 19802 | empty_record(table); // Make empty record |
| 19803 | return -1; |
| 19804 | } |
| 19805 | store_record(table,record[1]); |
| 19806 | } |
| 19807 | else if (!table->status) // Only happens with left join |
| 19808 | restore_record(table,record[1]); // restore old record |
| 19809 | table->null_row=0; |
| 19810 | return table->status ? -1 : 0; |
| 19811 | } |
| 19812 | |
| 19813 | |
| 19814 | /** |
| 19815 | Read a table when there is at most one matching row. |
| 19816 | |
| 19817 | @param tab Table to read |
| 19818 | |
| 19819 | @retval 0 Row was found |
| 19820 | @retval -1 Row was not found |
| 19821 | @retval 1 Got an error (other than row not found) during read |
| 19822 | */ |
| 19823 | |
| 19824 | static int |
| 19825 | join_read_const(JOIN_TAB *tab) |
| 19826 | { |
| 19827 | int error; |
| 19828 | TABLE *table= tab->table; |
| 19829 | if (table->status & STATUS_GARBAGE) // If first read |
| 19830 | { |
| 19831 | table->status= 0; |
| 19832 | if (cp_buffer_from_ref(tab->join->thd, table, &tab->ref)) |
| 19833 | error=HA_ERR_KEY_NOT_FOUND; |
| 19834 | else |
| 19835 | { |
| 19836 | error= table->file->ha_index_read_idx_map(table->record[0],tab->ref.key, |
| 19837 | (uchar*) tab->ref.key_buff, |
| 19838 | make_prev_keypart_map(tab->ref.key_parts), |
| 19839 | HA_READ_KEY_EXACT); |
| 19840 | } |
| 19841 | if (unlikely(error)) |
| 19842 | { |
| 19843 | table->status= STATUS_NOT_FOUND; |
| 19844 | mark_as_null_row(tab->table); |
| 19845 | empty_record(table); |
| 19846 | if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE) |
| 19847 | return report_error(table, error); |
| 19848 | return -1; |
| 19849 | } |
| 19850 | store_record(table,record[1]); |
| 19851 | } |
| 19852 | else if (!(table->status & ~STATUS_NULL_ROW)) // Only happens with left join |
| 19853 | { |
| 19854 | table->status=0; |
| 19855 | restore_record(table,record[1]); // restore old record |
| 19856 | } |
| 19857 | table->null_row=0; |
| 19858 | return table->status ? -1 : 0; |
| 19859 | } |
| 19860 | |
| 19861 | /* |
| 19862 | eq_ref access method implementation: "read_first" function |
| 19863 | |
| 19864 | SYNOPSIS |
| 19865 | join_read_key() |
| 19866 | tab JOIN_TAB of the accessed table |
| 19867 | |
| 19868 | DESCRIPTION |
| 19869 | This is "read_fist" function for the eq_ref access method. The difference |
| 19870 | from ref access function is that is that it has a one-element lookup |
| 19871 | cache (see cmp_buffer_with_ref) |
| 19872 | |
| 19873 | RETURN |
| 19874 | 0 - Ok |
| 19875 | -1 - Row not found |
| 19876 | 1 - Error |
| 19877 | */ |
| 19878 | |
| 19879 | |
| 19880 | static int |
| 19881 | join_read_key(JOIN_TAB *tab) |
| 19882 | { |
| 19883 | return join_read_key2(tab->join->thd, tab, tab->table, &tab->ref); |
| 19884 | } |
| 19885 | |
| 19886 | |
| 19887 | /* |
| 19888 | eq_ref access handler but generalized a bit to support TABLE and TABLE_REF |
| 19889 | not from the join_tab. See join_read_key for detailed synopsis. |
| 19890 | */ |
| 19891 | int join_read_key2(THD *thd, JOIN_TAB *tab, TABLE *table, TABLE_REF *table_ref) |
| 19892 | { |
| 19893 | int error; |
| 19894 | if (!table->file->inited) |
| 19895 | { |
| 19896 | error= table->file->ha_index_init(table_ref->key, tab ? tab->sorted : TRUE); |
| 19897 | if (unlikely(error)) |
| 19898 | { |
| 19899 | (void) report_error(table, error); |
| 19900 | return 1; |
| 19901 | } |
| 19902 | } |
| 19903 | |
| 19904 | /* |
| 19905 | The following is needed when one makes ref (or eq_ref) access from row |
| 19906 | comparisons: one must call row->bring_value() to get the new values. |
| 19907 | */ |
| 19908 | if (tab && tab->bush_children) |
| 19909 | { |
| 19910 | TABLE_LIST *emb_sj_nest= tab->bush_children->start->emb_sj_nest; |
| 19911 | emb_sj_nest->sj_subq_pred->left_expr->bring_value(); |
| 19912 | } |
| 19913 | |
| 19914 | /* TODO: Why don't we do "Late NULLs Filtering" here? */ |
| 19915 | |
| 19916 | if (cmp_buffer_with_ref(thd, table, table_ref) || |
| 19917 | (table->status & (STATUS_GARBAGE | STATUS_NO_PARENT | STATUS_NULL_ROW))) |
| 19918 | { |
| 19919 | if (table_ref->key_err) |
| 19920 | { |
| 19921 | table->status=STATUS_NOT_FOUND; |
| 19922 | return -1; |
| 19923 | } |
| 19924 | /* |
| 19925 | Moving away from the current record. Unlock the row |
| 19926 | in the handler if it did not match the partial WHERE. |
| 19927 | */ |
| 19928 | if (tab && tab->ref.has_record && tab->ref.use_count == 0) |
| 19929 | { |
| 19930 | tab->read_record.table->file->unlock_row(); |
| 19931 | table_ref->has_record= FALSE; |
| 19932 | } |
| 19933 | error=table->file->ha_index_read_map(table->record[0], |
| 19934 | table_ref->key_buff, |
| 19935 | make_prev_keypart_map(table_ref->key_parts), |
| 19936 | HA_READ_KEY_EXACT); |
| 19937 | if (unlikely(error) && |
| 19938 | error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE) |
| 19939 | return report_error(table, error); |
| 19940 | |
| 19941 | if (likely(!error)) |
| 19942 | { |
| 19943 | table_ref->has_record= TRUE; |
| 19944 | table_ref->use_count= 1; |
| 19945 | } |
| 19946 | } |
| 19947 | else if (table->status == 0) |
| 19948 | { |
| 19949 | DBUG_ASSERT(table_ref->has_record); |
| 19950 | table_ref->use_count++; |
| 19951 | } |
| 19952 | table->null_row=0; |
| 19953 | return table->status ? -1 : 0; |
| 19954 | } |
| 19955 | |
| 19956 | |
| 19957 | /** |
| 19958 | Since join_read_key may buffer a record, do not unlock |
| 19959 | it if it was not used in this invocation of join_read_key(). |
| 19960 | Only count locks, thus remembering if the record was left unused, |
| 19961 | and unlock already when pruning the current value of |
| 19962 | TABLE_REF buffer. |
| 19963 | @sa join_read_key() |
| 19964 | */ |
| 19965 | |
| 19966 | static void |
| 19967 | join_read_key_unlock_row(st_join_table *tab) |
| 19968 | { |
| 19969 | DBUG_ASSERT(tab->ref.use_count); |
| 19970 | if (tab->ref.use_count) |
| 19971 | tab->ref.use_count--; |
| 19972 | } |
| 19973 | |
| 19974 | /* |
| 19975 | ref access method implementation: "read_first" function |
| 19976 | |
| 19977 | SYNOPSIS |
| 19978 | join_read_always_key() |
| 19979 | tab JOIN_TAB of the accessed table |
| 19980 | |
| 19981 | DESCRIPTION |
| 19982 | This is "read_fist" function for the "ref" access method. |
| 19983 | |
| 19984 | The functon must leave the index initialized when it returns. |
| 19985 | ref_or_null access implementation depends on that. |
| 19986 | |
| 19987 | RETURN |
| 19988 | 0 - Ok |
| 19989 | -1 - Row not found |
| 19990 | 1 - Error |
| 19991 | */ |
| 19992 | |
| 19993 | static int |
| 19994 | join_read_always_key(JOIN_TAB *tab) |
| 19995 | { |
| 19996 | int error; |
| 19997 | TABLE *table= tab->table; |
| 19998 | |
| 19999 | /* Initialize the index first */ |
| 20000 | if (!table->file->inited) |
| 20001 | { |
| 20002 | if (unlikely((error= table->file->ha_index_init(tab->ref.key, |
| 20003 | tab->sorted)))) |
| 20004 | { |
| 20005 | (void) report_error(table, error); |
| 20006 | return 1; |
| 20007 | } |
| 20008 | } |
| 20009 | |
| 20010 | if (unlikely(cp_buffer_from_ref(tab->join->thd, table, &tab->ref))) |
| 20011 | return -1; |
| 20012 | if (unlikely((error= |
| 20013 | table->file->prepare_index_key_scan_map(tab->ref.key_buff, |
| 20014 | make_prev_keypart_map(tab->ref.key_parts))))) |
| 20015 | { |
| 20016 | report_error(table,error); |
| 20017 | return -1; |
| 20018 | } |
| 20019 | if ((error= table->file->ha_index_read_map(table->record[0], |
| 20020 | tab->ref.key_buff, |
| 20021 | make_prev_keypart_map(tab->ref.key_parts), |
| 20022 | HA_READ_KEY_EXACT))) |
| 20023 | { |
| 20024 | if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE) |
| 20025 | return report_error(table, error); |
| 20026 | return -1; /* purecov: inspected */ |
| 20027 | } |
| 20028 | return 0; |
| 20029 | } |
| 20030 | |
| 20031 | |
| 20032 | /** |
| 20033 | This function is used when optimizing away ORDER BY in |
| 20034 | SELECT * FROM t1 WHERE a=1 ORDER BY a DESC,b DESC. |
| 20035 | */ |
| 20036 | |
| 20037 | static int |
| 20038 | join_read_last_key(JOIN_TAB *tab) |
| 20039 | { |
| 20040 | int error; |
| 20041 | TABLE *table= tab->table; |
| 20042 | |
| 20043 | if (!table->file->inited && |
| 20044 | unlikely((error= table->file->ha_index_init(tab->ref.key, tab->sorted)))) |
| 20045 | { |
| 20046 | (void) report_error(table, error); |
| 20047 | return 1; |
| 20048 | } |
| 20049 | |
| 20050 | if (unlikely(cp_buffer_from_ref(tab->join->thd, table, &tab->ref))) |
| 20051 | return -1; |
| 20052 | if (unlikely((error= |
| 20053 | table->file->prepare_index_key_scan_map(tab->ref.key_buff, |
| 20054 | make_prev_keypart_map(tab->ref.key_parts)))) ) |
| 20055 | { |
| 20056 | report_error(table,error); |
| 20057 | return -1; |
| 20058 | } |
| 20059 | if (unlikely((error= |
| 20060 | table->file->ha_index_read_map(table->record[0], |
| 20061 | tab->ref.key_buff, |
| 20062 | make_prev_keypart_map(tab->ref.key_parts), |
| 20063 | HA_READ_PREFIX_LAST)))) |
| 20064 | { |
| 20065 | if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE) |
| 20066 | return report_error(table, error); |
| 20067 | return -1; /* purecov: inspected */ |
| 20068 | } |
| 20069 | return 0; |
| 20070 | } |
| 20071 | |
| 20072 | |
| 20073 | /* ARGSUSED */ |
| 20074 | static int |
| 20075 | join_no_more_records(READ_RECORD *info __attribute__((unused))) |
| 20076 | { |
| 20077 | return -1; |
| 20078 | } |
| 20079 | |
| 20080 | |
| 20081 | static int |
| 20082 | join_read_next_same(READ_RECORD *info) |
| 20083 | { |
| 20084 | int error; |
| 20085 | TABLE *table= info->table; |
| 20086 | JOIN_TAB *tab=table->reginfo.join_tab; |
| 20087 | |
| 20088 | if (unlikely((error= table->file->ha_index_next_same(table->record[0], |
| 20089 | tab->ref.key_buff, |
| 20090 | tab->ref.key_length)))) |
| 20091 | { |
| 20092 | if (error != HA_ERR_END_OF_FILE) |
| 20093 | return report_error(table, error); |
| 20094 | table->status= STATUS_GARBAGE; |
| 20095 | return -1; |
| 20096 | } |
| 20097 | return 0; |
| 20098 | } |
| 20099 | |
| 20100 | |
| 20101 | static int |
| 20102 | join_read_prev_same(READ_RECORD *info) |
| 20103 | { |
| 20104 | int error; |
| 20105 | TABLE *table= info->table; |
| 20106 | JOIN_TAB *tab=table->reginfo.join_tab; |
| 20107 | |
| 20108 | if (unlikely((error= table->file->ha_index_prev(table->record[0])))) |
| 20109 | return report_error(table, error); |
| 20110 | if (key_cmp_if_same(table, tab->ref.key_buff, tab->ref.key, |
| 20111 | tab->ref.key_length)) |
| 20112 | { |
| 20113 | table->status=STATUS_NOT_FOUND; |
| 20114 | error= -1; |
| 20115 | } |
| 20116 | return error; |
| 20117 | } |
| 20118 | |
| 20119 | |
| 20120 | static int |
| 20121 | join_init_quick_read_record(JOIN_TAB *tab) |
| 20122 | { |
| 20123 | if (test_if_quick_select(tab) == -1) |
| 20124 | return -1; /* No possible records */ |
| 20125 | return join_init_read_record(tab); |
| 20126 | } |
| 20127 | |
| 20128 | |
| 20129 | int read_first_record_seq(JOIN_TAB *tab) |
| 20130 | { |
| 20131 | if (unlikely(tab->read_record.table->file->ha_rnd_init_with_error(1))) |
| 20132 | return 1; |
| 20133 | return tab->read_record.read_record(); |
| 20134 | } |
| 20135 | |
| 20136 | static int |
| 20137 | test_if_quick_select(JOIN_TAB *tab) |
| 20138 | { |
| 20139 | DBUG_EXECUTE_IF("show_explain_probe_test_if_quick_select" , |
| 20140 | if (dbug_user_var_equals_int(tab->join->thd, |
| 20141 | "show_explain_probe_select_id" , |
| 20142 | tab->join->select_lex->select_number)) |
| 20143 | dbug_serve_apcs(tab->join->thd, 1); |
| 20144 | ); |
| 20145 | |
| 20146 | |
| 20147 | delete tab->select->quick; |
| 20148 | tab->select->quick=0; |
| 20149 | int res= tab->select->test_quick_select(tab->join->thd, tab->keys, |
| 20150 | (table_map) 0, HA_POS_ERROR, 0, |
| 20151 | FALSE, /*remove where parts*/FALSE); |
| 20152 | if (tab->explain_plan && tab->explain_plan->range_checked_fer) |
| 20153 | tab->explain_plan->range_checked_fer->collect_data(tab->select->quick); |
| 20154 | |
| 20155 | return res; |
| 20156 | } |
| 20157 | |
| 20158 | |
| 20159 | static |
| 20160 | bool test_if_use_dynamic_range_scan(JOIN_TAB *join_tab) |
| 20161 | { |
| 20162 | return (join_tab->use_quick == 2 && test_if_quick_select(join_tab) > 0); |
| 20163 | } |
| 20164 | |
| 20165 | int join_init_read_record(JOIN_TAB *tab) |
| 20166 | { |
| 20167 | /* |
| 20168 | Note: the query plan tree for the below operations is constructed in |
| 20169 | save_agg_explain_data. |
| 20170 | */ |
| 20171 | if (tab->distinct && tab->remove_duplicates()) // Remove duplicates. |
| 20172 | return 1; |
| 20173 | if (tab->filesort && tab->sort_table()) // Sort table. |
| 20174 | return 1; |
| 20175 | |
| 20176 | DBUG_EXECUTE_IF("kill_join_init_read_record" , |
| 20177 | tab->join->thd->set_killed(KILL_QUERY);); |
| 20178 | if (tab->select && tab->select->quick && tab->select->quick->reset()) |
| 20179 | { |
| 20180 | /* Ensures error status is propagated back to client */ |
| 20181 | report_error(tab->table, |
| 20182 | tab->join->thd->killed ? HA_ERR_QUERY_INTERRUPTED : HA_ERR_OUT_OF_MEM); |
| 20183 | return 1; |
| 20184 | } |
| 20185 | /* make sure we won't get ER_QUERY_INTERRUPTED from any code below */ |
| 20186 | DBUG_EXECUTE_IF("kill_join_init_read_record" , |
| 20187 | tab->join->thd->reset_killed();); |
| 20188 | if (!tab->preread_init_done && tab->preread_init()) |
| 20189 | return 1; |
| 20190 | if (init_read_record(&tab->read_record, tab->join->thd, tab->table, |
| 20191 | tab->select, tab->filesort_result, 1,1, FALSE)) |
| 20192 | return 1; |
| 20193 | return tab->read_record.read_record(); |
| 20194 | } |
| 20195 | |
| 20196 | int |
| 20197 | join_read_record_no_init(JOIN_TAB *tab) |
| 20198 | { |
| 20199 | Copy_field *save_copy, *save_copy_end; |
| 20200 | |
| 20201 | /* |
| 20202 | init_read_record resets all elements of tab->read_record(). |
| 20203 | Remember things that we don't want to have reset. |
| 20204 | */ |
| 20205 | save_copy= tab->read_record.copy_field; |
| 20206 | save_copy_end= tab->read_record.copy_field_end; |
| 20207 | |
| 20208 | init_read_record(&tab->read_record, tab->join->thd, tab->table, |
| 20209 | tab->select, tab->filesort_result, 1, 1, FALSE); |
| 20210 | |
| 20211 | tab->read_record.copy_field= save_copy; |
| 20212 | tab->read_record.copy_field_end= save_copy_end; |
| 20213 | tab->read_record.read_record_func= rr_sequential_and_unpack; |
| 20214 | |
| 20215 | return tab->read_record.read_record(); |
| 20216 | } |
| 20217 | |
| 20218 | |
| 20219 | /* |
| 20220 | Helper function for sorting table with filesort. |
| 20221 | */ |
| 20222 | |
| 20223 | bool |
| 20224 | JOIN_TAB::sort_table() |
| 20225 | { |
| 20226 | int rc; |
| 20227 | DBUG_PRINT("info" ,("Sorting for index" )); |
| 20228 | THD_STAGE_INFO(join->thd, stage_creating_sort_index); |
| 20229 | DBUG_ASSERT(join->ordered_index_usage != (filesort->order == join->order ? |
| 20230 | JOIN::ordered_index_order_by : |
| 20231 | JOIN::ordered_index_group_by)); |
| 20232 | rc= create_sort_index(join->thd, join, this, NULL); |
| 20233 | return (rc != 0); |
| 20234 | } |
| 20235 | |
| 20236 | |
| 20237 | static int |
| 20238 | join_read_first(JOIN_TAB *tab) |
| 20239 | { |
| 20240 | int error= 0; |
| 20241 | TABLE *table=tab->table; |
| 20242 | DBUG_ENTER("join_read_first" ); |
| 20243 | |
| 20244 | DBUG_ASSERT(table->no_keyread || |
| 20245 | !table->covering_keys.is_set(tab->index) || |
| 20246 | table->file->keyread == tab->index); |
| 20247 | tab->table->status=0; |
| 20248 | tab->read_record.read_record_func= join_read_next; |
| 20249 | tab->read_record.table=table; |
| 20250 | tab->read_record.index=tab->index; |
| 20251 | tab->read_record.record=table->record[0]; |
| 20252 | if (!table->file->inited) |
| 20253 | error= table->file->ha_index_init(tab->index, tab->sorted); |
| 20254 | if (likely(!error)) |
| 20255 | error= table->file->prepare_index_scan(); |
| 20256 | if (unlikely(error) || |
| 20257 | unlikely(error= tab->table->file->ha_index_first(tab->table->record[0]))) |
| 20258 | { |
| 20259 | if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE) |
| 20260 | report_error(table, error); |
| 20261 | DBUG_RETURN(-1); |
| 20262 | } |
| 20263 | DBUG_RETURN(0); |
| 20264 | } |
| 20265 | |
| 20266 | |
| 20267 | static int |
| 20268 | join_read_next(READ_RECORD *info) |
| 20269 | { |
| 20270 | int error; |
| 20271 | if (unlikely((error= info->table->file->ha_index_next(info->record)))) |
| 20272 | return report_error(info->table, error); |
| 20273 | |
| 20274 | return 0; |
| 20275 | } |
| 20276 | |
| 20277 | |
| 20278 | static int |
| 20279 | join_read_last(JOIN_TAB *tab) |
| 20280 | { |
| 20281 | TABLE *table=tab->table; |
| 20282 | int error= 0; |
| 20283 | DBUG_ENTER("join_read_first" ); |
| 20284 | |
| 20285 | DBUG_ASSERT(table->no_keyread || |
| 20286 | !table->covering_keys.is_set(tab->index) || |
| 20287 | table->file->keyread == tab->index); |
| 20288 | tab->table->status=0; |
| 20289 | tab->read_record.read_record_func= join_read_prev; |
| 20290 | tab->read_record.table=table; |
| 20291 | tab->read_record.index=tab->index; |
| 20292 | tab->read_record.record=table->record[0]; |
| 20293 | if (!table->file->inited) |
| 20294 | error= table->file->ha_index_init(tab->index, 1); |
| 20295 | if (likely(!error)) |
| 20296 | error= table->file->prepare_index_scan(); |
| 20297 | if (unlikely(error) || |
| 20298 | unlikely(error= tab->table->file->ha_index_last(tab->table->record[0]))) |
| 20299 | DBUG_RETURN(report_error(table, error)); |
| 20300 | |
| 20301 | DBUG_RETURN(0); |
| 20302 | } |
| 20303 | |
| 20304 | |
| 20305 | static int |
| 20306 | join_read_prev(READ_RECORD *info) |
| 20307 | { |
| 20308 | int error; |
| 20309 | if (unlikely((error= info->table->file->ha_index_prev(info->record)))) |
| 20310 | return report_error(info->table, error); |
| 20311 | return 0; |
| 20312 | } |
| 20313 | |
| 20314 | |
| 20315 | static int |
| 20316 | join_ft_read_first(JOIN_TAB *tab) |
| 20317 | { |
| 20318 | int error; |
| 20319 | TABLE *table= tab->table; |
| 20320 | |
| 20321 | if (!table->file->inited && |
| 20322 | (error= table->file->ha_index_init(tab->ref.key, 1))) |
| 20323 | { |
| 20324 | (void) report_error(table, error); |
| 20325 | return 1; |
| 20326 | } |
| 20327 | |
| 20328 | table->file->ft_init(); |
| 20329 | |
| 20330 | if (unlikely((error= table->file->ha_ft_read(table->record[0])))) |
| 20331 | return report_error(table, error); |
| 20332 | return 0; |
| 20333 | } |
| 20334 | |
| 20335 | static int |
| 20336 | join_ft_read_next(READ_RECORD *info) |
| 20337 | { |
| 20338 | int error; |
| 20339 | if (unlikely((error= info->table->file->ha_ft_read(info->table->record[0])))) |
| 20340 | return report_error(info->table, error); |
| 20341 | return 0; |
| 20342 | } |
| 20343 | |
| 20344 | |
| 20345 | /** |
| 20346 | Reading of key with key reference and one part that may be NULL. |
| 20347 | */ |
| 20348 | |
| 20349 | int |
| 20350 | join_read_always_key_or_null(JOIN_TAB *tab) |
| 20351 | { |
| 20352 | int res; |
| 20353 | |
| 20354 | /* First read according to key which is NOT NULL */ |
| 20355 | *tab->ref.null_ref_key= 0; // Clear null byte |
| 20356 | if ((res= join_read_always_key(tab)) >= 0) |
| 20357 | return res; |
| 20358 | |
| 20359 | /* Then read key with null value */ |
| 20360 | *tab->ref.null_ref_key= 1; // Set null byte |
| 20361 | return safe_index_read(tab); |
| 20362 | } |
| 20363 | |
| 20364 | |
| 20365 | int |
| 20366 | join_read_next_same_or_null(READ_RECORD *info) |
| 20367 | { |
| 20368 | int error; |
| 20369 | if (unlikely((error= join_read_next_same(info)) >= 0)) |
| 20370 | return error; |
| 20371 | JOIN_TAB *tab= info->table->reginfo.join_tab; |
| 20372 | |
| 20373 | /* Test if we have already done a read after null key */ |
| 20374 | if (*tab->ref.null_ref_key) |
| 20375 | return -1; // All keys read |
| 20376 | *tab->ref.null_ref_key= 1; // Set null byte |
| 20377 | return safe_index_read(tab); // then read null keys |
| 20378 | } |
| 20379 | |
| 20380 | |
| 20381 | /***************************************************************************** |
| 20382 | DESCRIPTION |
| 20383 | Functions that end one nested loop iteration. Different functions |
| 20384 | are used to support GROUP BY clause and to redirect records |
| 20385 | to a table (e.g. in case of SELECT into a temporary table) or to the |
| 20386 | network client. |
| 20387 | |
| 20388 | RETURN VALUES |
| 20389 | NESTED_LOOP_OK - the record has been successfully handled |
| 20390 | NESTED_LOOP_ERROR - a fatal error (like table corruption) |
| 20391 | was detected |
| 20392 | NESTED_LOOP_KILLED - thread shutdown was requested while processing |
| 20393 | the record |
| 20394 | NESTED_LOOP_QUERY_LIMIT - the record has been successfully handled; |
| 20395 | additionally, the nested loop produced the |
| 20396 | number of rows specified in the LIMIT clause |
| 20397 | for the query |
| 20398 | NESTED_LOOP_CURSOR_LIMIT - the record has been successfully handled; |
| 20399 | additionally, there is a cursor and the nested |
| 20400 | loop algorithm produced the number of rows |
| 20401 | that is specified for current cursor fetch |
| 20402 | operation. |
| 20403 | All return values except NESTED_LOOP_OK abort the nested loop. |
| 20404 | *****************************************************************************/ |
| 20405 | |
| 20406 | /* ARGSUSED */ |
| 20407 | static enum_nested_loop_state |
| 20408 | end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), |
| 20409 | bool end_of_records) |
| 20410 | { |
| 20411 | DBUG_ENTER("end_send" ); |
| 20412 | /* |
| 20413 | When all tables are const this function is called with jointab == NULL. |
| 20414 | This function shouldn't be called for the first join_tab as it needs |
| 20415 | to get fields from previous tab. |
| 20416 | */ |
| 20417 | DBUG_ASSERT(join_tab == NULL || join_tab != join->join_tab); |
| 20418 | //TODO pass fields via argument |
| 20419 | List<Item> *fields= join_tab ? (join_tab-1)->fields : join->fields; |
| 20420 | |
| 20421 | if (!end_of_records) |
| 20422 | { |
| 20423 | if (join->table_count && |
| 20424 | join->join_tab->is_using_loose_index_scan()) |
| 20425 | { |
| 20426 | /* Copy non-aggregated fields when loose index scan is used. */ |
| 20427 | copy_fields(&join->tmp_table_param); |
| 20428 | } |
| 20429 | if (join->having && join->having->val_int() == 0) |
| 20430 | DBUG_RETURN(NESTED_LOOP_OK); // Didn't match having |
| 20431 | if (join->procedure) |
| 20432 | { |
| 20433 | if (join->procedure->send_row(join->procedure_fields_list)) |
| 20434 | DBUG_RETURN(NESTED_LOOP_ERROR); |
| 20435 | DBUG_RETURN(NESTED_LOOP_OK); |
| 20436 | } |
| 20437 | if (join->do_send_rows) |
| 20438 | { |
| 20439 | int error; |
| 20440 | /* result < 0 if row was not accepted and should not be counted */ |
| 20441 | if (unlikely((error= join->result->send_data(*fields)))) |
| 20442 | { |
| 20443 | if (error > 0) |
| 20444 | DBUG_RETURN(NESTED_LOOP_ERROR); |
| 20445 | // error < 0 => duplicate row |
| 20446 | join->duplicate_rows++; |
| 20447 | } |
| 20448 | } |
| 20449 | |
| 20450 | ++join->send_records; |
| 20451 | if (join->send_records >= join->unit->select_limit_cnt && |
| 20452 | !join->do_send_rows) |
| 20453 | { |
| 20454 | /* |
| 20455 | If we have used Priority Queue for optimizing order by with limit, |
| 20456 | then stop here, there are no more records to consume. |
| 20457 | When this optimization is used, end_send is called on the next |
| 20458 | join_tab. |
| 20459 | */ |
| 20460 | if (join->order && |
| 20461 | join->select_options & OPTION_FOUND_ROWS && |
| 20462 | join_tab > join->join_tab && |
| 20463 | (join_tab - 1)->filesort && (join_tab - 1)->filesort->using_pq) |
| 20464 | { |
| 20465 | DBUG_PRINT("info" , ("filesort NESTED_LOOP_QUERY_LIMIT" )); |
| 20466 | DBUG_RETURN(NESTED_LOOP_QUERY_LIMIT); |
| 20467 | } |
| 20468 | } |
| 20469 | if (join->send_records >= join->unit->select_limit_cnt && |
| 20470 | join->do_send_rows) |
| 20471 | { |
| 20472 | if (join->select_options & OPTION_FOUND_ROWS) |
| 20473 | { |
| 20474 | JOIN_TAB *jt=join->join_tab; |
| 20475 | if ((join->table_count == 1) && !join->sort_and_group |
| 20476 | && !join->send_group_parts && !join->having && !jt->select_cond && |
| 20477 | !(jt->select && jt->select->quick) && |
| 20478 | (jt->table->file->ha_table_flags() & HA_STATS_RECORDS_IS_EXACT) && |
| 20479 | (jt->ref.key < 0)) |
| 20480 | { |
| 20481 | /* Join over all rows in table; Return number of found rows */ |
| 20482 | TABLE *table=jt->table; |
| 20483 | |
| 20484 | if (jt->filesort_result) // If filesort was used |
| 20485 | { |
| 20486 | join->send_records= jt->filesort_result->found_rows; |
| 20487 | } |
| 20488 | else |
| 20489 | { |
| 20490 | table->file->info(HA_STATUS_VARIABLE); |
| 20491 | join->send_records= table->file->stats.records; |
| 20492 | } |
| 20493 | } |
| 20494 | else |
| 20495 | { |
| 20496 | join->do_send_rows= 0; |
| 20497 | if (join->unit->fake_select_lex) |
| 20498 | join->unit->fake_select_lex->select_limit= 0; |
| 20499 | DBUG_RETURN(NESTED_LOOP_OK); |
| 20500 | } |
| 20501 | } |
| 20502 | DBUG_RETURN(NESTED_LOOP_QUERY_LIMIT); // Abort nicely |
| 20503 | } |
| 20504 | else if (join->send_records >= join->fetch_limit) |
| 20505 | { |
| 20506 | /* |
| 20507 | There is a server side cursor and all rows for |
| 20508 | this fetch request are sent. |
| 20509 | */ |
| 20510 | DBUG_RETURN(NESTED_LOOP_CURSOR_LIMIT); |
| 20511 | } |
| 20512 | } |
| 20513 | else |
| 20514 | { |
| 20515 | if (join->procedure && join->procedure->end_of_records()) |
| 20516 | DBUG_RETURN(NESTED_LOOP_ERROR); |
| 20517 | } |
| 20518 | DBUG_RETURN(NESTED_LOOP_OK); |
| 20519 | } |
| 20520 | |
| 20521 | |
| 20522 | /* |
| 20523 | @brief |
| 20524 | Perform a GROUP BY operation over a stream of rows ordered by their group. The |
| 20525 | result is sent into join->result. |
| 20526 | |
| 20527 | @detail |
| 20528 | Also applies HAVING, etc. |
| 20529 | */ |
| 20530 | |
| 20531 | enum_nested_loop_state |
| 20532 | end_send_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), |
| 20533 | bool end_of_records) |
| 20534 | { |
| 20535 | int idx= -1; |
| 20536 | enum_nested_loop_state ok_code= NESTED_LOOP_OK; |
| 20537 | List<Item> *fields= join_tab ? (join_tab-1)->fields : join->fields; |
| 20538 | DBUG_ENTER("end_send_group" ); |
| 20539 | |
| 20540 | if (!join->items3.is_null() && !join->set_group_rpa) |
| 20541 | { |
| 20542 | join->set_group_rpa= true; |
| 20543 | join->set_items_ref_array(join->items3); |
| 20544 | } |
| 20545 | |
| 20546 | if (!join->first_record || end_of_records || |
| 20547 | (idx=test_if_group_changed(join->group_fields)) >= 0) |
| 20548 | { |
| 20549 | if (!join->group_sent && |
| 20550 | (join->first_record || |
| 20551 | (end_of_records && !join->group && !join->group_optimized_away))) |
| 20552 | { |
| 20553 | if (join->procedure) |
| 20554 | join->procedure->end_group(); |
| 20555 | if (idx < (int) join->send_group_parts) |
| 20556 | { |
| 20557 | int error=0; |
| 20558 | if (join->procedure) |
| 20559 | { |
| 20560 | if (join->having && join->having->val_int() == 0) |
| 20561 | error= -1; // Didn't satisfy having |
| 20562 | else |
| 20563 | { |
| 20564 | if (join->do_send_rows) |
| 20565 | error=join->procedure->send_row(*fields) ? 1 : 0; |
| 20566 | join->send_records++; |
| 20567 | } |
| 20568 | if (end_of_records && join->procedure->end_of_records()) |
| 20569 | error= 1; // Fatal error |
| 20570 | } |
| 20571 | else |
| 20572 | { |
| 20573 | if (!join->first_record) |
| 20574 | { |
| 20575 | List_iterator_fast<Item> it(*join->fields); |
| 20576 | Item *item; |
| 20577 | /* No matching rows for group function */ |
| 20578 | join->clear(); |
| 20579 | |
| 20580 | while ((item= it++)) |
| 20581 | item->no_rows_in_result(); |
| 20582 | } |
| 20583 | if (join->having && join->having->val_int() == 0) |
| 20584 | error= -1; // Didn't satisfy having |
| 20585 | else |
| 20586 | { |
| 20587 | if (join->do_send_rows) |
| 20588 | { |
| 20589 | error=join->result->send_data(*fields); |
| 20590 | if (unlikely(error < 0)) |
| 20591 | { |
| 20592 | /* Duplicate row, don't count */ |
| 20593 | join->duplicate_rows++; |
| 20594 | error= 0; |
| 20595 | } |
| 20596 | } |
| 20597 | join->send_records++; |
| 20598 | join->group_sent= true; |
| 20599 | } |
| 20600 | if (unlikely(join->rollup.state != ROLLUP::STATE_NONE && error <= 0)) |
| 20601 | { |
| 20602 | if (join->rollup_send_data((uint) (idx+1))) |
| 20603 | error= 1; |
| 20604 | } |
| 20605 | } |
| 20606 | if (unlikely(error > 0)) |
| 20607 | DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */ |
| 20608 | if (end_of_records) |
| 20609 | DBUG_RETURN(NESTED_LOOP_OK); |
| 20610 | if (join->send_records >= join->unit->select_limit_cnt && |
| 20611 | join->do_send_rows) |
| 20612 | { |
| 20613 | if (!(join->select_options & OPTION_FOUND_ROWS)) |
| 20614 | DBUG_RETURN(NESTED_LOOP_QUERY_LIMIT); // Abort nicely |
| 20615 | join->do_send_rows=0; |
| 20616 | join->unit->select_limit_cnt = HA_POS_ERROR; |
| 20617 | } |
| 20618 | else if (join->send_records >= join->fetch_limit) |
| 20619 | { |
| 20620 | /* |
| 20621 | There is a server side cursor and all rows |
| 20622 | for this fetch request are sent. |
| 20623 | */ |
| 20624 | /* |
| 20625 | Preventing code duplication. When finished with the group reset |
| 20626 | the group functions and copy_fields. We fall through. bug #11904 |
| 20627 | */ |
| 20628 | ok_code= NESTED_LOOP_CURSOR_LIMIT; |
| 20629 | } |
| 20630 | } |
| 20631 | } |
| 20632 | else |
| 20633 | { |
| 20634 | if (end_of_records) |
| 20635 | DBUG_RETURN(NESTED_LOOP_OK); |
| 20636 | join->first_record=1; |
| 20637 | (void) test_if_group_changed(join->group_fields); |
| 20638 | } |
| 20639 | if (idx < (int) join->send_group_parts) |
| 20640 | { |
| 20641 | /* |
| 20642 | This branch is executed also for cursors which have finished their |
| 20643 | fetch limit - the reason for ok_code. |
| 20644 | */ |
| 20645 | copy_fields(&join->tmp_table_param); |
| 20646 | if (init_sum_functions(join->sum_funcs, join->sum_funcs_end[idx+1])) |
| 20647 | DBUG_RETURN(NESTED_LOOP_ERROR); |
| 20648 | if (join->procedure) |
| 20649 | join->procedure->add(); |
| 20650 | join->group_sent= false; |
| 20651 | DBUG_RETURN(ok_code); |
| 20652 | } |
| 20653 | } |
| 20654 | if (update_sum_func(join->sum_funcs)) |
| 20655 | DBUG_RETURN(NESTED_LOOP_ERROR); |
| 20656 | if (join->procedure) |
| 20657 | join->procedure->add(); |
| 20658 | DBUG_RETURN(NESTED_LOOP_OK); |
| 20659 | } |
| 20660 | |
| 20661 | |
| 20662 | /* ARGSUSED */ |
| 20663 | static enum_nested_loop_state |
| 20664 | end_write(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), |
| 20665 | bool end_of_records) |
| 20666 | { |
| 20667 | TABLE *const table= join_tab->table; |
| 20668 | DBUG_ENTER("end_write" ); |
| 20669 | |
| 20670 | if (!end_of_records) |
| 20671 | { |
| 20672 | copy_fields(join_tab->tmp_table_param); |
| 20673 | if (copy_funcs(join_tab->tmp_table_param->items_to_copy, join->thd)) |
| 20674 | DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */ |
| 20675 | |
| 20676 | if (likely(!join_tab->having || join_tab->having->val_int())) |
| 20677 | { |
| 20678 | int error; |
| 20679 | join->found_records++; |
| 20680 | if ((error= table->file->ha_write_tmp_row(table->record[0]))) |
| 20681 | { |
| 20682 | if (likely(!table->file->is_fatal_error(error, HA_CHECK_DUP))) |
| 20683 | goto end; // Ignore duplicate keys |
| 20684 | bool is_duplicate; |
| 20685 | if (create_internal_tmp_table_from_heap(join->thd, table, |
| 20686 | join_tab->tmp_table_param->start_recinfo, |
| 20687 | &join_tab->tmp_table_param->recinfo, |
| 20688 | error, 1, &is_duplicate)) |
| 20689 | DBUG_RETURN(NESTED_LOOP_ERROR); // Not a table_is_full error |
| 20690 | if (is_duplicate) |
| 20691 | goto end; |
| 20692 | table->s->uniques=0; // To ensure rows are the same |
| 20693 | } |
| 20694 | if (++join_tab->send_records >= |
| 20695 | join_tab->tmp_table_param->end_write_records && |
| 20696 | join->do_send_rows) |
| 20697 | { |
| 20698 | if (!(join->select_options & OPTION_FOUND_ROWS)) |
| 20699 | DBUG_RETURN(NESTED_LOOP_QUERY_LIMIT); |
| 20700 | join->do_send_rows=0; |
| 20701 | join->unit->select_limit_cnt = HA_POS_ERROR; |
| 20702 | } |
| 20703 | } |
| 20704 | } |
| 20705 | end: |
| 20706 | if (unlikely(join->thd->check_killed())) |
| 20707 | { |
| 20708 | join->thd->send_kill_message(); |
| 20709 | DBUG_RETURN(NESTED_LOOP_KILLED); /* purecov: inspected */ |
| 20710 | } |
| 20711 | DBUG_RETURN(NESTED_LOOP_OK); |
| 20712 | } |
| 20713 | |
| 20714 | |
| 20715 | /* |
| 20716 | @brief |
| 20717 | Perform a GROUP BY operation over rows coming in arbitrary order. |
| 20718 | |
| 20719 | This is done by looking up the group in a temp.table and updating group |
| 20720 | values. |
| 20721 | |
| 20722 | @detail |
| 20723 | Also applies HAVING, etc. |
| 20724 | */ |
| 20725 | |
| 20726 | static enum_nested_loop_state |
| 20727 | end_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), |
| 20728 | bool end_of_records) |
| 20729 | { |
| 20730 | TABLE *const table= join_tab->table; |
| 20731 | ORDER *group; |
| 20732 | int error; |
| 20733 | DBUG_ENTER("end_update" ); |
| 20734 | |
| 20735 | if (end_of_records) |
| 20736 | DBUG_RETURN(NESTED_LOOP_OK); |
| 20737 | |
| 20738 | join->found_records++; |
| 20739 | copy_fields(join_tab->tmp_table_param); // Groups are copied twice. |
| 20740 | /* Make a key of group index */ |
| 20741 | for (group=table->group ; group ; group=group->next) |
| 20742 | { |
| 20743 | Item *item= *group->item; |
| 20744 | if (group->fast_field_copier_setup != group->field) |
| 20745 | { |
| 20746 | DBUG_PRINT("info" , ("new setup %p -> %p" , |
| 20747 | group->fast_field_copier_setup, |
| 20748 | group->field)); |
| 20749 | group->fast_field_copier_setup= group->field; |
| 20750 | group->fast_field_copier_func= |
| 20751 | item->setup_fast_field_copier(group->field); |
| 20752 | } |
| 20753 | item->save_org_in_field(group->field, group->fast_field_copier_func); |
| 20754 | /* Store in the used key if the field was 0 */ |
| 20755 | if (item->maybe_null) |
| 20756 | group->buff[-1]= (char) group->field->is_null(); |
| 20757 | } |
| 20758 | if (!table->file->ha_index_read_map(table->record[1], |
| 20759 | join_tab->tmp_table_param->group_buff, |
| 20760 | HA_WHOLE_KEY, |
| 20761 | HA_READ_KEY_EXACT)) |
| 20762 | { /* Update old record */ |
| 20763 | restore_record(table,record[1]); |
| 20764 | update_tmptable_sum_func(join->sum_funcs,table); |
| 20765 | if (unlikely((error= table->file->ha_update_tmp_row(table->record[1], |
| 20766 | table->record[0])))) |
| 20767 | { |
| 20768 | table->file->print_error(error,MYF(0)); /* purecov: inspected */ |
| 20769 | DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */ |
| 20770 | } |
| 20771 | goto end; |
| 20772 | } |
| 20773 | |
| 20774 | init_tmptable_sum_functions(join->sum_funcs); |
| 20775 | if (unlikely(copy_funcs(join_tab->tmp_table_param->items_to_copy, |
| 20776 | join->thd))) |
| 20777 | DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */ |
| 20778 | if (unlikely((error= table->file->ha_write_tmp_row(table->record[0])))) |
| 20779 | { |
| 20780 | if (create_internal_tmp_table_from_heap(join->thd, table, |
| 20781 | join_tab->tmp_table_param->start_recinfo, |
| 20782 | &join_tab->tmp_table_param->recinfo, |
| 20783 | error, 0, NULL)) |
| 20784 | DBUG_RETURN(NESTED_LOOP_ERROR); // Not a table_is_full error |
| 20785 | /* Change method to update rows */ |
| 20786 | if (unlikely((error= table->file->ha_index_init(0, 0)))) |
| 20787 | { |
| 20788 | table->file->print_error(error, MYF(0)); |
| 20789 | DBUG_RETURN(NESTED_LOOP_ERROR); |
| 20790 | } |
| 20791 | |
| 20792 | join_tab->aggr->set_write_func(end_unique_update); |
| 20793 | } |
| 20794 | join_tab->send_records++; |
| 20795 | end: |
| 20796 | if (unlikely(join->thd->check_killed())) |
| 20797 | { |
| 20798 | join->thd->send_kill_message(); |
| 20799 | DBUG_RETURN(NESTED_LOOP_KILLED); /* purecov: inspected */ |
| 20800 | } |
| 20801 | DBUG_RETURN(NESTED_LOOP_OK); |
| 20802 | } |
| 20803 | |
| 20804 | |
| 20805 | /** Like end_update, but this is done with unique constraints instead of keys. */ |
| 20806 | |
| 20807 | static enum_nested_loop_state |
| 20808 | end_unique_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), |
| 20809 | bool end_of_records) |
| 20810 | { |
| 20811 | TABLE *table= join_tab->table; |
| 20812 | int error; |
| 20813 | DBUG_ENTER("end_unique_update" ); |
| 20814 | |
| 20815 | if (end_of_records) |
| 20816 | DBUG_RETURN(NESTED_LOOP_OK); |
| 20817 | |
| 20818 | init_tmptable_sum_functions(join->sum_funcs); |
| 20819 | copy_fields(join_tab->tmp_table_param); // Groups are copied twice. |
| 20820 | if (copy_funcs(join_tab->tmp_table_param->items_to_copy, join->thd)) |
| 20821 | DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */ |
| 20822 | |
| 20823 | if (likely(!(error= table->file->ha_write_tmp_row(table->record[0])))) |
| 20824 | join_tab->send_records++; // New group |
| 20825 | else |
| 20826 | { |
| 20827 | if (unlikely((int) table->file->get_dup_key(error) < 0)) |
| 20828 | { |
| 20829 | table->file->print_error(error,MYF(0)); /* purecov: inspected */ |
| 20830 | DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */ |
| 20831 | } |
| 20832 | if (unlikely(table->file->ha_rnd_pos(table->record[1],table->file->dup_ref))) |
| 20833 | { |
| 20834 | table->file->print_error(error,MYF(0)); /* purecov: inspected */ |
| 20835 | DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */ |
| 20836 | } |
| 20837 | restore_record(table,record[1]); |
| 20838 | update_tmptable_sum_func(join->sum_funcs,table); |
| 20839 | if (unlikely((error= table->file->ha_update_tmp_row(table->record[1], |
| 20840 | table->record[0])))) |
| 20841 | { |
| 20842 | table->file->print_error(error,MYF(0)); /* purecov: inspected */ |
| 20843 | DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */ |
| 20844 | } |
| 20845 | } |
| 20846 | if (unlikely(join->thd->check_killed())) |
| 20847 | { |
| 20848 | join->thd->send_kill_message(); |
| 20849 | DBUG_RETURN(NESTED_LOOP_KILLED); /* purecov: inspected */ |
| 20850 | } |
| 20851 | DBUG_RETURN(NESTED_LOOP_OK); |
| 20852 | } |
| 20853 | |
| 20854 | |
| 20855 | /* |
| 20856 | @brief |
| 20857 | Perform a GROUP BY operation over a stream of rows ordered by their group. |
| 20858 | Write the result into a temporary table. |
| 20859 | |
| 20860 | @detail |
| 20861 | Also applies HAVING, etc. |
| 20862 | |
| 20863 | The rows are written into temptable so e.g. filesort can read them. |
| 20864 | */ |
| 20865 | |
| 20866 | enum_nested_loop_state |
| 20867 | end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), |
| 20868 | bool end_of_records) |
| 20869 | { |
| 20870 | TABLE *table= join_tab->table; |
| 20871 | int idx= -1; |
| 20872 | DBUG_ENTER("end_write_group" ); |
| 20873 | |
| 20874 | if (!join->first_record || end_of_records || |
| 20875 | (idx=test_if_group_changed(join->group_fields)) >= 0) |
| 20876 | { |
| 20877 | if (join->first_record || (end_of_records && !join->group)) |
| 20878 | { |
| 20879 | if (join->procedure) |
| 20880 | join->procedure->end_group(); |
| 20881 | int send_group_parts= join->send_group_parts; |
| 20882 | if (idx < send_group_parts) |
| 20883 | { |
| 20884 | if (!join->first_record) |
| 20885 | { |
| 20886 | /* No matching rows for group function */ |
| 20887 | join->clear(); |
| 20888 | } |
| 20889 | copy_sum_funcs(join->sum_funcs, |
| 20890 | join->sum_funcs_end[send_group_parts]); |
| 20891 | if (!join_tab->having || join_tab->having->val_int()) |
| 20892 | { |
| 20893 | int error= table->file->ha_write_tmp_row(table->record[0]); |
| 20894 | if (unlikely(error) && |
| 20895 | create_internal_tmp_table_from_heap(join->thd, table, |
| 20896 | join_tab->tmp_table_param->start_recinfo, |
| 20897 | &join_tab->tmp_table_param->recinfo, |
| 20898 | error, 0, NULL)) |
| 20899 | DBUG_RETURN(NESTED_LOOP_ERROR); |
| 20900 | } |
| 20901 | if (unlikely(join->rollup.state != ROLLUP::STATE_NONE)) |
| 20902 | { |
| 20903 | if (unlikely(join->rollup_write_data((uint) (idx+1), |
| 20904 | join_tab->tmp_table_param, |
| 20905 | table))) |
| 20906 | { |
| 20907 | DBUG_RETURN(NESTED_LOOP_ERROR); |
| 20908 | } |
| 20909 | } |
| 20910 | if (end_of_records) |
| 20911 | goto end; |
| 20912 | } |
| 20913 | } |
| 20914 | else |
| 20915 | { |
| 20916 | if (end_of_records) |
| 20917 | goto end; |
| 20918 | join->first_record=1; |
| 20919 | (void) test_if_group_changed(join->group_fields); |
| 20920 | } |
| 20921 | if (idx < (int) join->send_group_parts) |
| 20922 | { |
| 20923 | copy_fields(join_tab->tmp_table_param); |
| 20924 | if (unlikely(copy_funcs(join_tab->tmp_table_param->items_to_copy, |
| 20925 | join->thd))) |
| 20926 | DBUG_RETURN(NESTED_LOOP_ERROR); |
| 20927 | if (unlikely(init_sum_functions(join->sum_funcs, |
| 20928 | join->sum_funcs_end[idx+1]))) |
| 20929 | DBUG_RETURN(NESTED_LOOP_ERROR); |
| 20930 | if (unlikely(join->procedure)) |
| 20931 | join->procedure->add(); |
| 20932 | goto end; |
| 20933 | } |
| 20934 | } |
| 20935 | if (unlikely(update_sum_func(join->sum_funcs))) |
| 20936 | DBUG_RETURN(NESTED_LOOP_ERROR); |
| 20937 | if (unlikely(join->procedure)) |
| 20938 | join->procedure->add(); |
| 20939 | end: |
| 20940 | if (unlikely(join->thd->check_killed())) |
| 20941 | { |
| 20942 | join->thd->send_kill_message(); |
| 20943 | DBUG_RETURN(NESTED_LOOP_KILLED); /* purecov: inspected */ |
| 20944 | } |
| 20945 | DBUG_RETURN(NESTED_LOOP_OK); |
| 20946 | } |
| 20947 | |
| 20948 | |
| 20949 | /***************************************************************************** |
| 20950 | Remove calculation with tables that aren't yet read. Remove also tests |
| 20951 | against fields that are read through key where the table is not a |
| 20952 | outer join table. |
| 20953 | We can't remove tests that are made against columns which are stored |
| 20954 | in sorted order. |
| 20955 | *****************************************************************************/ |
| 20956 | |
| 20957 | /** |
| 20958 | Check if "left_item=right_item" equality is guaranteed to be true by use of |
| 20959 | [eq]ref access on left_item->field->table. |
| 20960 | |
| 20961 | SYNOPSIS |
| 20962 | test_if_ref() |
| 20963 | root_cond |
| 20964 | left_item |
| 20965 | right_item |
| 20966 | |
| 20967 | DESCRIPTION |
| 20968 | Check if the given "left_item = right_item" equality is guaranteed to be |
| 20969 | true by use of [eq_]ref access method. |
| 20970 | |
| 20971 | We need root_cond as we can't remove ON expressions even if employed ref |
| 20972 | access guarantees that they are true. This is because TODO |
| 20973 | |
| 20974 | RETURN |
| 20975 | TRUE if right_item is used removable reference key on left_item |
| 20976 | FALSE Otherwise |
| 20977 | |
| 20978 | */ |
| 20979 | |
| 20980 | bool test_if_ref(Item *root_cond, Item_field *left_item,Item *right_item) |
| 20981 | { |
| 20982 | Field *field=left_item->field; |
| 20983 | JOIN_TAB *join_tab= field->table->reginfo.join_tab; |
| 20984 | // No need to change const test |
| 20985 | if (!field->table->const_table && join_tab && |
| 20986 | !join_tab->is_ref_for_hash_join() && |
| 20987 | (!join_tab->first_inner || |
| 20988 | *join_tab->first_inner->on_expr_ref == root_cond)) |
| 20989 | { |
| 20990 | /* |
| 20991 | If ref access uses "Full scan on NULL key" (i.e. it actually alternates |
| 20992 | between ref access and full table scan), then no equality can be |
| 20993 | guaranteed to be true. |
| 20994 | */ |
| 20995 | if (join_tab->ref.is_access_triggered()) |
| 20996 | return FALSE; |
| 20997 | |
| 20998 | Item *ref_item=part_of_refkey(field->table,field); |
| 20999 | if (ref_item && (ref_item->eq(right_item,1) || |
| 21000 | ref_item->real_item()->eq(right_item,1))) |
| 21001 | { |
| 21002 | right_item= right_item->real_item(); |
| 21003 | if (right_item->type() == Item::FIELD_ITEM) |
| 21004 | return (field->eq_def(((Item_field *) right_item)->field)); |
| 21005 | /* remove equalities injected by IN->EXISTS transformation */ |
| 21006 | else if (right_item->type() == Item::CACHE_ITEM) |
| 21007 | return ((Item_cache *)right_item)->eq_def (field); |
| 21008 | if (right_item->const_item() && !(right_item->is_null())) |
| 21009 | { |
| 21010 | /* |
| 21011 | We can remove binary fields and numerical fields except float, |
| 21012 | as float comparison isn't 100 % safe |
| 21013 | We have to keep normal strings to be able to check for end spaces |
| 21014 | */ |
| 21015 | if (field->binary() && |
| 21016 | field->real_type() != MYSQL_TYPE_STRING && |
| 21017 | field->real_type() != MYSQL_TYPE_VARCHAR && |
| 21018 | (field->type() != MYSQL_TYPE_FLOAT || field->decimals() == 0)) |
| 21019 | { |
| 21020 | return !right_item->save_in_field_no_warnings(field, 1); |
| 21021 | } |
| 21022 | } |
| 21023 | } |
| 21024 | } |
| 21025 | return 0; // keep test |
| 21026 | } |
| 21027 | |
| 21028 | |
| 21029 | /** |
| 21030 | Extract a condition that can be checked after reading given table |
| 21031 | @fn make_cond_for_table() |
| 21032 | |
| 21033 | @param cond Condition to analyze |
| 21034 | @param tables Tables for which "current field values" are available |
| 21035 | @param used_table Table that we're extracting the condition for |
| 21036 | tables Tables for which "current field values" are available (this |
| 21037 | includes used_table) |
| 21038 | (may also include PSEUDO_TABLE_BITS, and may be zero) |
| 21039 | @param join_tab_idx_arg |
| 21040 | The index of the JOIN_TAB this Item is being extracted |
| 21041 | for. MAX_TABLES if there is no corresponding JOIN_TAB. |
| 21042 | @param exclude_expensive_cond |
| 21043 | Do not push expensive conditions |
| 21044 | @param retain_ref_cond |
| 21045 | Retain ref conditions |
| 21046 | |
| 21047 | @retval <>NULL Generated condition |
| 21048 | @retval =NULL Already checked, OR error |
| 21049 | |
| 21050 | @details |
| 21051 | Extract the condition that can be checked after reading the table |
| 21052 | specified in 'used_table', given that current-field values for tables |
| 21053 | specified in 'tables' bitmap are available. |
| 21054 | If 'used_table' is 0 |
| 21055 | - extract conditions for all tables in 'tables'. |
| 21056 | - extract conditions are unrelated to any tables |
| 21057 | in the same query block/level(i.e. conditions |
| 21058 | which have used_tables == 0). |
| 21059 | |
| 21060 | The function assumes that |
| 21061 | - Constant parts of the condition has already been checked. |
| 21062 | - Condition that could be checked for tables in 'tables' has already |
| 21063 | been checked. |
| 21064 | |
| 21065 | The function takes into account that some parts of the condition are |
| 21066 | guaranteed to be true by employed 'ref' access methods (the code that |
| 21067 | does this is located at the end, search down for "EQ_FUNC"). |
| 21068 | |
| 21069 | @note |
| 21070 | Make sure to keep the implementations of make_cond_for_table() and |
| 21071 | make_cond_after_sjm() synchronized. |
| 21072 | make_cond_for_info_schema() uses similar algorithm as well. |
| 21073 | */ |
| 21074 | |
| 21075 | static Item * |
| 21076 | make_cond_for_table(THD *thd, Item *cond, table_map tables, |
| 21077 | table_map used_table, |
| 21078 | int join_tab_idx_arg, |
| 21079 | bool exclude_expensive_cond __attribute__((unused)), |
| 21080 | bool retain_ref_cond) |
| 21081 | { |
| 21082 | return make_cond_for_table_from_pred(thd, cond, cond, tables, used_table, |
| 21083 | join_tab_idx_arg, |
| 21084 | exclude_expensive_cond, |
| 21085 | retain_ref_cond); |
| 21086 | } |
| 21087 | |
| 21088 | |
| 21089 | static Item * |
| 21090 | make_cond_for_table_from_pred(THD *thd, Item *root_cond, Item *cond, |
| 21091 | table_map tables, table_map used_table, |
| 21092 | int join_tab_idx_arg, |
| 21093 | bool exclude_expensive_cond __attribute__ |
| 21094 | ((unused)), |
| 21095 | bool retain_ref_cond) |
| 21096 | |
| 21097 | { |
| 21098 | if (used_table && !(cond->used_tables() & used_table)) |
| 21099 | return (COND*) 0; // Already checked |
| 21100 | |
| 21101 | if (cond->type() == Item::COND_ITEM) |
| 21102 | { |
| 21103 | if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC) |
| 21104 | { |
| 21105 | /* Create new top level AND item */ |
| 21106 | Item_cond_and *new_cond=new (thd->mem_root) Item_cond_and(thd); |
| 21107 | if (!new_cond) |
| 21108 | return (COND*) 0; // OOM /* purecov: inspected */ |
| 21109 | List_iterator<Item> li(*((Item_cond*) cond)->argument_list()); |
| 21110 | Item *item; |
| 21111 | while ((item=li++)) |
| 21112 | { |
| 21113 | Item *fix=make_cond_for_table_from_pred(thd, root_cond, item, |
| 21114 | tables, used_table, |
| 21115 | join_tab_idx_arg, |
| 21116 | exclude_expensive_cond, |
| 21117 | retain_ref_cond); |
| 21118 | if (fix) |
| 21119 | new_cond->argument_list()->push_back(fix, thd->mem_root); |
| 21120 | } |
| 21121 | switch (new_cond->argument_list()->elements) { |
| 21122 | case 0: |
| 21123 | return (COND*) 0; // Always true |
| 21124 | case 1: |
| 21125 | return new_cond->argument_list()->head(); |
| 21126 | default: |
| 21127 | /* |
| 21128 | Call fix_fields to propagate all properties of the children to |
| 21129 | the new parent Item. This should not be expensive because all |
| 21130 | children of Item_cond_and should be fixed by now. |
| 21131 | */ |
| 21132 | new_cond->fix_fields(thd, 0); |
| 21133 | new_cond->used_tables_cache= |
| 21134 | ((Item_cond_and*) cond)->used_tables_cache & |
| 21135 | tables; |
| 21136 | return new_cond; |
| 21137 | } |
| 21138 | } |
| 21139 | else |
| 21140 | { // Or list |
| 21141 | Item_cond_or *new_cond=new (thd->mem_root) Item_cond_or(thd); |
| 21142 | if (!new_cond) |
| 21143 | return (COND*) 0; // OOM /* purecov: inspected */ |
| 21144 | List_iterator<Item> li(*((Item_cond*) cond)->argument_list()); |
| 21145 | Item *item; |
| 21146 | while ((item=li++)) |
| 21147 | { |
| 21148 | Item *fix=make_cond_for_table_from_pred(thd, root_cond, item, |
| 21149 | tables, 0L, |
| 21150 | join_tab_idx_arg, |
| 21151 | exclude_expensive_cond, |
| 21152 | retain_ref_cond); |
| 21153 | if (!fix) |
| 21154 | return (COND*) 0; // Always true |
| 21155 | new_cond->argument_list()->push_back(fix, thd->mem_root); |
| 21156 | } |
| 21157 | /* |
| 21158 | Call fix_fields to propagate all properties of the children to |
| 21159 | the new parent Item. This should not be expensive because all |
| 21160 | children of Item_cond_and should be fixed by now. |
| 21161 | */ |
| 21162 | new_cond->fix_fields(thd, 0); |
| 21163 | new_cond->used_tables_cache= ((Item_cond_or*) cond)->used_tables_cache; |
| 21164 | new_cond->top_level_item(); |
| 21165 | return new_cond; |
| 21166 | } |
| 21167 | } |
| 21168 | |
| 21169 | /* |
| 21170 | Because the following test takes a while and it can be done |
| 21171 | table_count times, we mark each item that we have examined with the result |
| 21172 | of the test |
| 21173 | */ |
| 21174 | if ((cond->marker == 3 && !retain_ref_cond) || |
| 21175 | (cond->used_tables() & ~tables)) |
| 21176 | return (COND*) 0; // Can't check this yet |
| 21177 | |
| 21178 | if (cond->marker == 2 || cond->eq_cmp_result() == Item::COND_OK) |
| 21179 | { |
| 21180 | cond->set_join_tab_idx(join_tab_idx_arg); |
| 21181 | return cond; // Not boolean op |
| 21182 | } |
| 21183 | |
| 21184 | if (cond->type() == Item::FUNC_ITEM && |
| 21185 | ((Item_func*) cond)->functype() == Item_func::EQ_FUNC) |
| 21186 | { |
| 21187 | Item *left_item= ((Item_func*) cond)->arguments()[0]->real_item(); |
| 21188 | Item *right_item= ((Item_func*) cond)->arguments()[1]->real_item(); |
| 21189 | if (left_item->type() == Item::FIELD_ITEM && !retain_ref_cond && |
| 21190 | test_if_ref(root_cond, (Item_field*) left_item,right_item)) |
| 21191 | { |
| 21192 | cond->marker=3; // Checked when read |
| 21193 | return (COND*) 0; |
| 21194 | } |
| 21195 | if (right_item->type() == Item::FIELD_ITEM && !retain_ref_cond && |
| 21196 | test_if_ref(root_cond, (Item_field*) right_item,left_item)) |
| 21197 | { |
| 21198 | cond->marker=3; // Checked when read |
| 21199 | return (COND*) 0; |
| 21200 | } |
| 21201 | } |
| 21202 | cond->marker=2; |
| 21203 | cond->set_join_tab_idx(join_tab_idx_arg); |
| 21204 | return cond; |
| 21205 | } |
| 21206 | |
| 21207 | |
| 21208 | /* |
| 21209 | The difference of this from make_cond_for_table() is that we're in the |
| 21210 | following state: |
| 21211 | 1. conditions referring to 'tables' have been checked |
| 21212 | 2. conditions referring to sjm_tables have been checked, too |
| 21213 | 3. We need condition that couldn't be checked in #1 or #2 but |
| 21214 | can be checked when we get both (tables | sjm_tables). |
| 21215 | |
| 21216 | */ |
| 21217 | static COND * |
| 21218 | make_cond_after_sjm(THD *thd, Item *root_cond, Item *cond, table_map tables, |
| 21219 | table_map sjm_tables, bool inside_or_clause) |
| 21220 | { |
| 21221 | /* |
| 21222 | We assume that conditions that refer to only join prefix tables or |
| 21223 | sjm_tables have already been checked. |
| 21224 | */ |
| 21225 | if (!inside_or_clause) |
| 21226 | { |
| 21227 | table_map cond_used_tables= cond->used_tables(); |
| 21228 | if((!(cond_used_tables & ~tables) || |
| 21229 | !(cond_used_tables & ~sjm_tables))) |
| 21230 | return (COND*) 0; // Already checked |
| 21231 | } |
| 21232 | |
| 21233 | /* AND/OR recursive descent */ |
| 21234 | if (cond->type() == Item::COND_ITEM) |
| 21235 | { |
| 21236 | if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC) |
| 21237 | { |
| 21238 | /* Create new top level AND item */ |
| 21239 | Item_cond_and *new_cond= new (thd->mem_root) Item_cond_and(thd); |
| 21240 | if (!new_cond) |
| 21241 | return (COND*) 0; // OOM /* purecov: inspected */ |
| 21242 | List_iterator<Item> li(*((Item_cond*) cond)->argument_list()); |
| 21243 | Item *item; |
| 21244 | while ((item=li++)) |
| 21245 | { |
| 21246 | Item *fix=make_cond_after_sjm(thd, root_cond, item, tables, sjm_tables, |
| 21247 | inside_or_clause); |
| 21248 | if (fix) |
| 21249 | new_cond->argument_list()->push_back(fix, thd->mem_root); |
| 21250 | } |
| 21251 | switch (new_cond->argument_list()->elements) { |
| 21252 | case 0: |
| 21253 | return (COND*) 0; // Always true |
| 21254 | case 1: |
| 21255 | return new_cond->argument_list()->head(); |
| 21256 | default: |
| 21257 | /* |
| 21258 | Item_cond_and do not need fix_fields for execution, its parameters |
| 21259 | are fixed or do not need fix_fields, too |
| 21260 | */ |
| 21261 | new_cond->quick_fix_field(); |
| 21262 | new_cond->used_tables_cache= |
| 21263 | ((Item_cond_and*) cond)->used_tables_cache & |
| 21264 | tables; |
| 21265 | return new_cond; |
| 21266 | } |
| 21267 | } |
| 21268 | else |
| 21269 | { // Or list |
| 21270 | Item_cond_or *new_cond= new (thd->mem_root) Item_cond_or(thd); |
| 21271 | if (!new_cond) |
| 21272 | return (COND*) 0; // OOM /* purecov: inspected */ |
| 21273 | List_iterator<Item> li(*((Item_cond*) cond)->argument_list()); |
| 21274 | Item *item; |
| 21275 | while ((item=li++)) |
| 21276 | { |
| 21277 | Item *fix= make_cond_after_sjm(thd, root_cond, item, tables, sjm_tables, |
| 21278 | /*inside_or_clause= */TRUE); |
| 21279 | if (!fix) |
| 21280 | return (COND*) 0; // Always true |
| 21281 | new_cond->argument_list()->push_back(fix, thd->mem_root); |
| 21282 | } |
| 21283 | /* |
| 21284 | Item_cond_or do not need fix_fields for execution, its parameters |
| 21285 | are fixed or do not need fix_fields, too |
| 21286 | */ |
| 21287 | new_cond->quick_fix_field(); |
| 21288 | new_cond->used_tables_cache= ((Item_cond_or*) cond)->used_tables_cache; |
| 21289 | new_cond->top_level_item(); |
| 21290 | return new_cond; |
| 21291 | } |
| 21292 | } |
| 21293 | |
| 21294 | /* |
| 21295 | Because the following test takes a while and it can be done |
| 21296 | table_count times, we mark each item that we have examined with the result |
| 21297 | of the test |
| 21298 | */ |
| 21299 | |
| 21300 | if (cond->marker == 3 || (cond->used_tables() & ~(tables | sjm_tables))) |
| 21301 | return (COND*) 0; // Can't check this yet |
| 21302 | if (cond->marker == 2 || cond->eq_cmp_result() == Item::COND_OK) |
| 21303 | return cond; // Not boolean op |
| 21304 | |
| 21305 | /* |
| 21306 | Remove equalities that are guaranteed to be true by use of 'ref' access |
| 21307 | method |
| 21308 | */ |
| 21309 | if (((Item_func*) cond)->functype() == Item_func::EQ_FUNC) |
| 21310 | { |
| 21311 | Item *left_item= ((Item_func*) cond)->arguments()[0]->real_item(); |
| 21312 | Item *right_item= ((Item_func*) cond)->arguments()[1]->real_item(); |
| 21313 | if (left_item->type() == Item::FIELD_ITEM && |
| 21314 | test_if_ref(root_cond, (Item_field*) left_item,right_item)) |
| 21315 | { |
| 21316 | cond->marker=3; // Checked when read |
| 21317 | return (COND*) 0; |
| 21318 | } |
| 21319 | if (right_item->type() == Item::FIELD_ITEM && |
| 21320 | test_if_ref(root_cond, (Item_field*) right_item,left_item)) |
| 21321 | { |
| 21322 | cond->marker=3; // Checked when read |
| 21323 | return (COND*) 0; |
| 21324 | } |
| 21325 | } |
| 21326 | cond->marker=2; |
| 21327 | return cond; |
| 21328 | } |
| 21329 | |
| 21330 | |
| 21331 | /* |
| 21332 | @brief |
| 21333 | |
| 21334 | Check if |
| 21335 | - @table uses "ref"-like access |
| 21336 | - it is based on "@field=certain_item" equality |
| 21337 | - the equality will be true for any record returned by the access method |
| 21338 | and return the certain_item if yes. |
| 21339 | |
| 21340 | @detail |
| 21341 | |
| 21342 | Equality won't necessarily hold if: |
| 21343 | - the used index covers only part of the @field. |
| 21344 | Suppose, we have a CHAR(5) field and INDEX(field(3)). if you make a lookup |
| 21345 | for 'abc', you will get both record with 'abc' and with 'abcde'. |
| 21346 | - The type of access is actually ref_or_null, and so @field can be either |
| 21347 | a value or NULL. |
| 21348 | |
| 21349 | @return |
| 21350 | Item that the field will be equal to |
| 21351 | NULL if no such item |
| 21352 | */ |
| 21353 | |
| 21354 | static Item * |
| 21355 | part_of_refkey(TABLE *table,Field *field) |
| 21356 | { |
| 21357 | JOIN_TAB *join_tab= table->reginfo.join_tab; |
| 21358 | if (!join_tab) |
| 21359 | return (Item*) 0; // field from outer non-select (UPDATE,...) |
| 21360 | |
| 21361 | uint ref_parts= join_tab->ref.key_parts; |
| 21362 | if (ref_parts) /* if it's ref/eq_ref/ref_or_null */ |
| 21363 | { |
| 21364 | uint key= join_tab->ref.key; |
| 21365 | KEY *key_info= join_tab->get_keyinfo_by_key_no(key); |
| 21366 | KEY_PART_INFO *key_part= key_info->key_part; |
| 21367 | |
| 21368 | for (uint part=0 ; part < ref_parts ; part++,key_part++) |
| 21369 | { |
| 21370 | if (field->eq(key_part->field)) |
| 21371 | { |
| 21372 | /* |
| 21373 | Found the field in the key. Check that |
| 21374 | 1. ref_or_null doesn't alternate this component between a value and |
| 21375 | a NULL |
| 21376 | 2. index fully covers the key |
| 21377 | */ |
| 21378 | if (part != join_tab->ref.null_ref_part && // (1) |
| 21379 | !(key_part->key_part_flag & HA_PART_KEY_SEG)) // (2) |
| 21380 | { |
| 21381 | return join_tab->ref.items[part]; |
| 21382 | } |
| 21383 | break; |
| 21384 | } |
| 21385 | } |
| 21386 | } |
| 21387 | return (Item*) 0; |
| 21388 | } |
| 21389 | |
| 21390 | |
| 21391 | /** |
| 21392 | Test if one can use the key to resolve ORDER BY. |
| 21393 | |
| 21394 | @param join if not NULL, can use the join's top-level |
| 21395 | multiple-equalities. |
| 21396 | @param order Sort order |
| 21397 | @param table Table to sort |
| 21398 | @param idx Index to check |
| 21399 | @param used_key_parts [out] NULL by default, otherwise return value for |
| 21400 | used key parts. |
| 21401 | |
| 21402 | |
| 21403 | @note |
| 21404 | used_key_parts is set to correct key parts used if return value != 0 |
| 21405 | (On other cases, used_key_part may be changed) |
| 21406 | Note that the value may actually be greater than the number of index |
| 21407 | key parts. This can happen for storage engines that have the primary |
| 21408 | key parts as a suffix for every secondary key. |
| 21409 | |
| 21410 | @retval |
| 21411 | 1 key is ok. |
| 21412 | @retval |
| 21413 | 0 Key can't be used |
| 21414 | @retval |
| 21415 | -1 Reverse key can be used |
| 21416 | */ |
| 21417 | |
| 21418 | static int test_if_order_by_key(JOIN *join, |
| 21419 | ORDER *order, TABLE *table, uint idx, |
| 21420 | uint *used_key_parts) |
| 21421 | { |
| 21422 | KEY_PART_INFO *key_part,*key_part_end; |
| 21423 | key_part=table->key_info[idx].key_part; |
| 21424 | key_part_end=key_part + table->key_info[idx].ext_key_parts; |
| 21425 | key_part_map const_key_parts=table->const_key_parts[idx]; |
| 21426 | uint user_defined_kp= table->key_info[idx].user_defined_key_parts; |
| 21427 | int reverse=0; |
| 21428 | uint key_parts; |
| 21429 | bool have_pk_suffix= false; |
| 21430 | uint pk= table->s->primary_key; |
| 21431 | DBUG_ENTER("test_if_order_by_key" ); |
| 21432 | |
| 21433 | if ((table->file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX) && |
| 21434 | table->key_info[idx].ext_key_part_map && |
| 21435 | pk != MAX_KEY && pk != idx) |
| 21436 | { |
| 21437 | have_pk_suffix= true; |
| 21438 | } |
| 21439 | |
| 21440 | for (; order ; order=order->next, const_key_parts>>=1) |
| 21441 | { |
| 21442 | Item_field *item_field= ((Item_field*) (*order->item)->real_item()); |
| 21443 | Field *field= item_field->field; |
| 21444 | int flag; |
| 21445 | |
| 21446 | /* |
| 21447 | Skip key parts that are constants in the WHERE clause. |
| 21448 | These are already skipped in the ORDER BY by const_expression_in_where() |
| 21449 | */ |
| 21450 | for (; const_key_parts & 1 ; const_key_parts>>= 1) |
| 21451 | key_part++; |
| 21452 | |
| 21453 | /* |
| 21454 | This check was in this function historically (although I think it's |
| 21455 | better to check it outside of this function): |
| 21456 | |
| 21457 | "Test if the primary key parts were all const (i.e. there's one row). |
| 21458 | The sorting doesn't matter" |
| 21459 | |
| 21460 | So, we're checking that |
| 21461 | (1) this is an extended key |
| 21462 | (2) we've reached its end |
| 21463 | */ |
| 21464 | key_parts= (uint)(key_part - table->key_info[idx].key_part); |
| 21465 | if (have_pk_suffix && |
| 21466 | reverse == 0 && // all were =const so far |
| 21467 | key_parts == table->key_info[idx].ext_key_parts && |
| 21468 | table->const_key_parts[pk] == PREV_BITS(uint, |
| 21469 | table->key_info[pk]. |
| 21470 | user_defined_key_parts)) |
| 21471 | { |
| 21472 | key_parts= 0; |
| 21473 | reverse= 1; // Key is ok to use |
| 21474 | goto ok; |
| 21475 | } |
| 21476 | |
| 21477 | if (key_part == key_part_end) |
| 21478 | { |
| 21479 | /* |
| 21480 | There are some items left in ORDER BY that we don't |
| 21481 | */ |
| 21482 | DBUG_RETURN(0); |
| 21483 | } |
| 21484 | |
| 21485 | if (key_part->field != field) |
| 21486 | { |
| 21487 | /* |
| 21488 | Check if there is a multiple equality that allows to infer that field |
| 21489 | and key_part->field are equal |
| 21490 | (see also: compute_part_of_sort_key_for_equals) |
| 21491 | */ |
| 21492 | if (item_field->item_equal && |
| 21493 | item_field->item_equal->contains(key_part->field)) |
| 21494 | field= key_part->field; |
| 21495 | } |
| 21496 | if (key_part->field != field || !field->part_of_sortkey.is_set(idx)) |
| 21497 | DBUG_RETURN(0); |
| 21498 | |
| 21499 | const ORDER::enum_order keypart_order= |
| 21500 | (key_part->key_part_flag & HA_REVERSE_SORT) ? |
| 21501 | ORDER::ORDER_DESC : ORDER::ORDER_ASC; |
| 21502 | /* set flag to 1 if we can use read-next on key, else to -1 */ |
| 21503 | flag= (order->direction == keypart_order) ? 1 : -1; |
| 21504 | if (reverse && flag != reverse) |
| 21505 | DBUG_RETURN(0); |
| 21506 | reverse=flag; // Remember if reverse |
| 21507 | if (key_part < key_part_end) |
| 21508 | key_part++; |
| 21509 | } |
| 21510 | |
| 21511 | key_parts= (uint) (key_part - table->key_info[idx].key_part); |
| 21512 | |
| 21513 | if (reverse == -1 && |
| 21514 | !(table->file->index_flags(idx, user_defined_kp-1, 1) & HA_READ_PREV)) |
| 21515 | reverse= 0; // Index can't be used |
| 21516 | |
| 21517 | if (have_pk_suffix && reverse == -1) |
| 21518 | { |
| 21519 | uint pk_parts= table->key_info[pk].user_defined_key_parts; |
| 21520 | if (!(table->file->index_flags(pk, pk_parts, 1) & HA_READ_PREV)) |
| 21521 | reverse= 0; // Index can't be used |
| 21522 | } |
| 21523 | |
| 21524 | ok: |
| 21525 | if (used_key_parts != NULL) |
| 21526 | *used_key_parts= key_parts; |
| 21527 | DBUG_RETURN(reverse); |
| 21528 | } |
| 21529 | |
| 21530 | |
| 21531 | /** |
| 21532 | Find shortest key suitable for full table scan. |
| 21533 | |
| 21534 | @param table Table to scan |
| 21535 | @param usable_keys Allowed keys |
| 21536 | |
| 21537 | @return |
| 21538 | MAX_KEY no suitable key found |
| 21539 | key index otherwise |
| 21540 | */ |
| 21541 | |
| 21542 | uint find_shortest_key(TABLE *table, const key_map *usable_keys) |
| 21543 | { |
| 21544 | double min_cost= DBL_MAX; |
| 21545 | uint best= MAX_KEY; |
| 21546 | if (!usable_keys->is_clear_all()) |
| 21547 | { |
| 21548 | for (uint nr=0; nr < table->s->keys ; nr++) |
| 21549 | { |
| 21550 | if (usable_keys->is_set(nr)) |
| 21551 | { |
| 21552 | double cost= table->file->keyread_time(nr, 1, table->file->records()); |
| 21553 | if (cost < min_cost) |
| 21554 | { |
| 21555 | min_cost= cost; |
| 21556 | best=nr; |
| 21557 | } |
| 21558 | DBUG_ASSERT(best < MAX_KEY); |
| 21559 | } |
| 21560 | } |
| 21561 | } |
| 21562 | return best; |
| 21563 | } |
| 21564 | |
| 21565 | /** |
| 21566 | Test if a second key is the subkey of the first one. |
| 21567 | |
| 21568 | @param key_part First key parts |
| 21569 | @param ref_key_part Second key parts |
| 21570 | @param ref_key_part_end Last+1 part of the second key |
| 21571 | |
| 21572 | @note |
| 21573 | Second key MUST be shorter than the first one. |
| 21574 | |
| 21575 | @retval |
| 21576 | 1 is a subkey |
| 21577 | @retval |
| 21578 | 0 no sub key |
| 21579 | */ |
| 21580 | |
| 21581 | inline bool |
| 21582 | is_subkey(KEY_PART_INFO *key_part, KEY_PART_INFO *ref_key_part, |
| 21583 | KEY_PART_INFO *ref_key_part_end) |
| 21584 | { |
| 21585 | for (; ref_key_part < ref_key_part_end; key_part++, ref_key_part++) |
| 21586 | if (!key_part->field->eq(ref_key_part->field)) |
| 21587 | return 0; |
| 21588 | return 1; |
| 21589 | } |
| 21590 | |
| 21591 | /** |
| 21592 | Test if we can use one of the 'usable_keys' instead of 'ref' key |
| 21593 | for sorting. |
| 21594 | |
| 21595 | @param ref Number of key, used for WHERE clause |
| 21596 | @param usable_keys Keys for testing |
| 21597 | |
| 21598 | @return |
| 21599 | - MAX_KEY If we can't use other key |
| 21600 | - the number of found key Otherwise |
| 21601 | */ |
| 21602 | |
| 21603 | static uint |
| 21604 | test_if_subkey(ORDER *order, TABLE *table, uint ref, uint ref_key_parts, |
| 21605 | const key_map *usable_keys) |
| 21606 | { |
| 21607 | uint nr; |
| 21608 | uint min_length= (uint) ~0; |
| 21609 | uint best= MAX_KEY; |
| 21610 | KEY_PART_INFO *ref_key_part= table->key_info[ref].key_part; |
| 21611 | KEY_PART_INFO *ref_key_part_end= ref_key_part + ref_key_parts; |
| 21612 | |
| 21613 | /* |
| 21614 | Find the shortest key that |
| 21615 | - produces the required ordering |
| 21616 | - has key #ref (up to ref_key_parts) as its subkey. |
| 21617 | */ |
| 21618 | for (nr= 0 ; nr < table->s->keys ; nr++) |
| 21619 | { |
| 21620 | if (usable_keys->is_set(nr) && |
| 21621 | table->key_info[nr].key_length < min_length && |
| 21622 | table->key_info[nr].user_defined_key_parts >= ref_key_parts && |
| 21623 | is_subkey(table->key_info[nr].key_part, ref_key_part, |
| 21624 | ref_key_part_end) && |
| 21625 | test_if_order_by_key(NULL, order, table, nr)) |
| 21626 | { |
| 21627 | min_length= table->key_info[nr].key_length; |
| 21628 | best= nr; |
| 21629 | } |
| 21630 | } |
| 21631 | return best; |
| 21632 | } |
| 21633 | |
| 21634 | |
| 21635 | /** |
| 21636 | Check if GROUP BY/DISTINCT can be optimized away because the set is |
| 21637 | already known to be distinct. |
| 21638 | |
| 21639 | Used in removing the GROUP BY/DISTINCT of the following types of |
| 21640 | statements: |
| 21641 | @code |
| 21642 | SELECT [DISTINCT] <unique_key_cols>... FROM <single_table_ref> |
| 21643 | [GROUP BY <unique_key_cols>,...] |
| 21644 | @endcode |
| 21645 | |
| 21646 | If (a,b,c is distinct) |
| 21647 | then <any combination of a,b,c>,{whatever} is also distinct |
| 21648 | |
| 21649 | This function checks if all the key parts of any of the unique keys |
| 21650 | of the table are referenced by a list : either the select list |
| 21651 | through find_field_in_item_list or GROUP BY list through |
| 21652 | find_field_in_order_list. |
| 21653 | If the above holds and the key parts cannot contain NULLs then we |
| 21654 | can safely remove the GROUP BY/DISTINCT, |
| 21655 | as no result set can be more distinct than an unique key. |
| 21656 | |
| 21657 | @param table The table to operate on. |
| 21658 | @param find_func function to iterate over the list and search |
| 21659 | for a field |
| 21660 | |
| 21661 | @retval |
| 21662 | 1 found |
| 21663 | @retval |
| 21664 | 0 not found. |
| 21665 | */ |
| 21666 | |
| 21667 | static bool |
| 21668 | list_contains_unique_index(TABLE *table, |
| 21669 | bool (*find_func) (Field *, void *), void *data) |
| 21670 | { |
| 21671 | for (uint keynr= 0; keynr < table->s->keys; keynr++) |
| 21672 | { |
| 21673 | if (keynr == table->s->primary_key || |
| 21674 | (table->key_info[keynr].flags & HA_NOSAME)) |
| 21675 | { |
| 21676 | KEY *keyinfo= table->key_info + keynr; |
| 21677 | KEY_PART_INFO *key_part, *key_part_end; |
| 21678 | |
| 21679 | for (key_part=keyinfo->key_part, |
| 21680 | key_part_end=key_part+ keyinfo->user_defined_key_parts; |
| 21681 | key_part < key_part_end; |
| 21682 | key_part++) |
| 21683 | { |
| 21684 | if (key_part->field->maybe_null() || |
| 21685 | !find_func(key_part->field, data)) |
| 21686 | break; |
| 21687 | } |
| 21688 | if (key_part == key_part_end) |
| 21689 | return 1; |
| 21690 | } |
| 21691 | } |
| 21692 | return 0; |
| 21693 | } |
| 21694 | |
| 21695 | |
| 21696 | /** |
| 21697 | Helper function for list_contains_unique_index. |
| 21698 | Find a field reference in a list of ORDER structures. |
| 21699 | Finds a direct reference of the Field in the list. |
| 21700 | |
| 21701 | @param field The field to search for. |
| 21702 | @param data ORDER *.The list to search in |
| 21703 | |
| 21704 | @retval |
| 21705 | 1 found |
| 21706 | @retval |
| 21707 | 0 not found. |
| 21708 | */ |
| 21709 | |
| 21710 | static bool |
| 21711 | find_field_in_order_list (Field *field, void *data) |
| 21712 | { |
| 21713 | ORDER *group= (ORDER *) data; |
| 21714 | bool part_found= 0; |
| 21715 | for (ORDER *tmp_group= group; tmp_group; tmp_group=tmp_group->next) |
| 21716 | { |
| 21717 | Item *item= (*tmp_group->item)->real_item(); |
| 21718 | if (item->type() == Item::FIELD_ITEM && |
| 21719 | ((Item_field*) item)->field->eq(field)) |
| 21720 | { |
| 21721 | part_found= 1; |
| 21722 | break; |
| 21723 | } |
| 21724 | } |
| 21725 | return part_found; |
| 21726 | } |
| 21727 | |
| 21728 | |
| 21729 | /** |
| 21730 | Helper function for list_contains_unique_index. |
| 21731 | Find a field reference in a dynamic list of Items. |
| 21732 | Finds a direct reference of the Field in the list. |
| 21733 | |
| 21734 | @param[in] field The field to search for. |
| 21735 | @param[in] data List<Item> *.The list to search in |
| 21736 | |
| 21737 | @retval |
| 21738 | 1 found |
| 21739 | @retval |
| 21740 | 0 not found. |
| 21741 | */ |
| 21742 | |
| 21743 | static bool |
| 21744 | find_field_in_item_list (Field *field, void *data) |
| 21745 | { |
| 21746 | List<Item> *fields= (List<Item> *) data; |
| 21747 | bool part_found= 0; |
| 21748 | List_iterator<Item> li(*fields); |
| 21749 | Item *item; |
| 21750 | |
| 21751 | while ((item= li++)) |
| 21752 | { |
| 21753 | if (item->real_item()->type() == Item::FIELD_ITEM && |
| 21754 | ((Item_field*) (item->real_item()))->field->eq(field)) |
| 21755 | { |
| 21756 | part_found= 1; |
| 21757 | break; |
| 21758 | } |
| 21759 | } |
| 21760 | return part_found; |
| 21761 | } |
| 21762 | |
| 21763 | |
| 21764 | /* |
| 21765 | Fill *col_keys with a union of Field::part_of_sortkey of all fields |
| 21766 | that belong to 'table' and are equal to 'item_field'. |
| 21767 | */ |
| 21768 | |
| 21769 | void compute_part_of_sort_key_for_equals(JOIN *join, TABLE *table, |
| 21770 | Item_field *item_field, |
| 21771 | key_map *col_keys) |
| 21772 | { |
| 21773 | col_keys->clear_all(); |
| 21774 | col_keys->merge(item_field->field->part_of_sortkey); |
| 21775 | |
| 21776 | if (!optimizer_flag(join->thd, OPTIMIZER_SWITCH_ORDERBY_EQ_PROP)) |
| 21777 | return; |
| 21778 | |
| 21779 | Item_equal *item_eq= NULL; |
| 21780 | |
| 21781 | if (item_field->item_equal) |
| 21782 | { |
| 21783 | /* |
| 21784 | The item_field is from ORDER structure, but it already has an item_equal |
| 21785 | pointer set (UseMultipleEqualitiesToRemoveTempTable code have set it) |
| 21786 | */ |
| 21787 | item_eq= item_field->item_equal; |
| 21788 | } |
| 21789 | else |
| 21790 | { |
| 21791 | /* |
| 21792 | Walk through join's muliple equalities and find the one that contains |
| 21793 | item_field. |
| 21794 | */ |
| 21795 | if (!join->cond_equal) |
| 21796 | return; |
| 21797 | table_map needed_tbl_map= item_field->used_tables() | table->map; |
| 21798 | List_iterator<Item_equal> li(join->cond_equal->current_level); |
| 21799 | Item_equal *cur_item_eq; |
| 21800 | while ((cur_item_eq= li++)) |
| 21801 | { |
| 21802 | if ((cur_item_eq->used_tables() & needed_tbl_map) && |
| 21803 | cur_item_eq->contains(item_field->field)) |
| 21804 | { |
| 21805 | item_eq= cur_item_eq; |
| 21806 | item_field->item_equal= item_eq; // Save the pointer to our Item_equal. |
| 21807 | break; |
| 21808 | } |
| 21809 | } |
| 21810 | } |
| 21811 | |
| 21812 | if (item_eq) |
| 21813 | { |
| 21814 | Item_equal_fields_iterator it(*item_eq); |
| 21815 | Item *item; |
| 21816 | /* Loop through other members that belong to table table */ |
| 21817 | while ((item= it++)) |
| 21818 | { |
| 21819 | if (item->type() == Item::FIELD_ITEM && |
| 21820 | ((Item_field*)item)->field->table == table) |
| 21821 | { |
| 21822 | col_keys->merge(((Item_field*)item)->field->part_of_sortkey); |
| 21823 | } |
| 21824 | } |
| 21825 | } |
| 21826 | } |
| 21827 | |
| 21828 | |
| 21829 | /** |
| 21830 | Test if we can skip the ORDER BY by using an index. |
| 21831 | |
| 21832 | If we can use an index, the JOIN_TAB / tab->select struct |
| 21833 | is changed to use the index. |
| 21834 | |
| 21835 | The index must cover all fields in <order>, or it will not be considered. |
| 21836 | |
| 21837 | @param no_changes No changes will be made to the query plan. |
| 21838 | |
| 21839 | @todo |
| 21840 | - sergeyp: Results of all index merge selects actually are ordered |
| 21841 | by clustered PK values. |
| 21842 | |
| 21843 | @retval |
| 21844 | 0 We have to use filesort to do the sorting |
| 21845 | @retval |
| 21846 | 1 We can use an index. |
| 21847 | */ |
| 21848 | |
| 21849 | static bool |
| 21850 | test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, |
| 21851 | bool no_changes, const key_map *map) |
| 21852 | { |
| 21853 | int ref_key; |
| 21854 | uint UNINIT_VAR(ref_key_parts); |
| 21855 | int order_direction= 0; |
| 21856 | uint used_key_parts= 0; |
| 21857 | TABLE *table=tab->table; |
| 21858 | SQL_SELECT *select=tab->select; |
| 21859 | key_map usable_keys; |
| 21860 | QUICK_SELECT_I *save_quick= select ? select->quick : 0; |
| 21861 | Item *orig_cond= 0; |
| 21862 | bool orig_cond_saved= false; |
| 21863 | int best_key= -1; |
| 21864 | bool changed_key= false; |
| 21865 | DBUG_ENTER("test_if_skip_sort_order" ); |
| 21866 | |
| 21867 | /* Check that we are always called with first non-const table */ |
| 21868 | DBUG_ASSERT(tab == tab->join->join_tab + tab->join->const_tables); |
| 21869 | |
| 21870 | /* |
| 21871 | Keys disabled by ALTER TABLE ... DISABLE KEYS should have already |
| 21872 | been taken into account. |
| 21873 | */ |
| 21874 | usable_keys= *map; |
| 21875 | |
| 21876 | /* Find indexes that cover all ORDER/GROUP BY fields */ |
| 21877 | for (ORDER *tmp_order=order; tmp_order ; tmp_order=tmp_order->next) |
| 21878 | { |
| 21879 | Item *item= (*tmp_order->item)->real_item(); |
| 21880 | if (item->type() != Item::FIELD_ITEM) |
| 21881 | { |
| 21882 | usable_keys.clear_all(); |
| 21883 | DBUG_RETURN(0); |
| 21884 | } |
| 21885 | |
| 21886 | /* |
| 21887 | Take multiple-equalities into account. Suppose we have |
| 21888 | ORDER BY col1, col10 |
| 21889 | and there are |
| 21890 | multiple-equal(col1, col2, col3), |
| 21891 | multiple-equal(col10, col11). |
| 21892 | |
| 21893 | Then, |
| 21894 | - when item=col1, we find the set of indexes that cover one of {col1, |
| 21895 | col2, col3} |
| 21896 | - when item=col10, we find the set of indexes that cover one of {col10, |
| 21897 | col11} |
| 21898 | |
| 21899 | And we compute an intersection of these sets to find set of indexes that |
| 21900 | cover all ORDER BY components. |
| 21901 | */ |
| 21902 | key_map col_keys; |
| 21903 | compute_part_of_sort_key_for_equals(tab->join, table, (Item_field*)item, |
| 21904 | &col_keys); |
| 21905 | usable_keys.intersect(col_keys); |
| 21906 | if (usable_keys.is_clear_all()) |
| 21907 | goto use_filesort; // No usable keys |
| 21908 | } |
| 21909 | |
| 21910 | ref_key= -1; |
| 21911 | /* Test if constant range in WHERE */ |
| 21912 | if (tab->ref.key >= 0 && tab->ref.key_parts) |
| 21913 | { |
| 21914 | ref_key= tab->ref.key; |
| 21915 | ref_key_parts= tab->ref.key_parts; |
| 21916 | /* |
| 21917 | todo: why does JT_REF_OR_NULL mean filesort? We could find another index |
| 21918 | that satisfies the ordering. I would just set ref_key=MAX_KEY here... |
| 21919 | */ |
| 21920 | if (tab->type == JT_REF_OR_NULL || tab->type == JT_FT) |
| 21921 | goto use_filesort; |
| 21922 | } |
| 21923 | else if (select && select->quick) // Range found by opt_range |
| 21924 | { |
| 21925 | int quick_type= select->quick->get_type(); |
| 21926 | /* |
| 21927 | assume results are not ordered when index merge is used |
| 21928 | TODO: sergeyp: Results of all index merge selects actually are ordered |
| 21929 | by clustered PK values. |
| 21930 | */ |
| 21931 | |
| 21932 | if (quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE || |
| 21933 | quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_INTERSECT || |
| 21934 | quick_type == QUICK_SELECT_I::QS_TYPE_ROR_UNION || |
| 21935 | quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT) |
| 21936 | { |
| 21937 | /* |
| 21938 | we set ref_key=MAX_KEY instead of -1, because test_if_cheaper ordering |
| 21939 | assumes that "ref_key==-1" means doing full index scan. |
| 21940 | (This is not very straightforward and we got into this situation for |
| 21941 | historical reasons. Should be fixed at some point). |
| 21942 | */ |
| 21943 | ref_key= MAX_KEY; |
| 21944 | } |
| 21945 | else |
| 21946 | { |
| 21947 | ref_key= select->quick->index; |
| 21948 | ref_key_parts= select->quick->used_key_parts; |
| 21949 | } |
| 21950 | } |
| 21951 | |
| 21952 | if (ref_key >= 0 && ref_key != MAX_KEY) |
| 21953 | { |
| 21954 | /* Current access method uses index ref_key with ref_key_parts parts */ |
| 21955 | if (!usable_keys.is_set(ref_key)) |
| 21956 | { |
| 21957 | /* However, ref_key doesn't match the needed ordering */ |
| 21958 | uint new_ref_key; |
| 21959 | |
| 21960 | /* |
| 21961 | If using index only read, only consider other possible index only |
| 21962 | keys |
| 21963 | */ |
| 21964 | if (table->covering_keys.is_set(ref_key)) |
| 21965 | usable_keys.intersect(table->covering_keys); |
| 21966 | if (tab->pre_idx_push_select_cond) |
| 21967 | { |
| 21968 | orig_cond= tab->set_cond(tab->pre_idx_push_select_cond); |
| 21969 | orig_cond_saved= true; |
| 21970 | } |
| 21971 | |
| 21972 | if ((new_ref_key= test_if_subkey(order, table, ref_key, ref_key_parts, |
| 21973 | &usable_keys)) < MAX_KEY) |
| 21974 | { |
| 21975 | /* |
| 21976 | Index new_ref_key |
| 21977 | - produces the required ordering, |
| 21978 | - also has the same columns as ref_key for #ref_key_parts (this |
| 21979 | means we will read the same number of rows as with ref_key). |
| 21980 | */ |
| 21981 | |
| 21982 | /* |
| 21983 | If new_ref_key allows to construct a quick select which uses more key |
| 21984 | parts than ref(new_ref_key) would, do that. |
| 21985 | |
| 21986 | Otherwise, construct a ref access (todo: it's not clear what is the |
| 21987 | win in using ref access when we could use quick select also?) |
| 21988 | */ |
| 21989 | if ((table->quick_keys.is_set(new_ref_key) && |
| 21990 | table->quick_key_parts[new_ref_key] > ref_key_parts) || |
| 21991 | !(tab->ref.key >= 0)) |
| 21992 | { |
| 21993 | /* |
| 21994 | The range optimizer constructed QUICK_RANGE for ref_key, and |
| 21995 | we want to use instead new_ref_key as the index. We can't |
| 21996 | just change the index of the quick select, because this may |
| 21997 | result in an inconsistent QUICK_SELECT object. Below we |
| 21998 | create a new QUICK_SELECT from scratch so that all its |
| 21999 | parameters are set correctly by the range optimizer. |
| 22000 | */ |
| 22001 | key_map new_ref_key_map; |
| 22002 | COND *save_cond; |
| 22003 | bool res; |
| 22004 | new_ref_key_map.clear_all(); // Force the creation of quick select |
| 22005 | new_ref_key_map.set_bit(new_ref_key); // only for new_ref_key. |
| 22006 | |
| 22007 | /* Reset quick; This will be restored in 'use_filesort' if needed */ |
| 22008 | select->quick= 0; |
| 22009 | save_cond= select->cond; |
| 22010 | if (select->pre_idx_push_select_cond) |
| 22011 | select->cond= select->pre_idx_push_select_cond; |
| 22012 | res= select->test_quick_select(tab->join->thd, new_ref_key_map, 0, |
| 22013 | (tab->join->select_options & |
| 22014 | OPTION_FOUND_ROWS) ? |
| 22015 | HA_POS_ERROR : |
| 22016 | tab->join->unit->select_limit_cnt,TRUE, |
| 22017 | TRUE, FALSE) <= 0; |
| 22018 | if (res) |
| 22019 | { |
| 22020 | select->cond= save_cond; |
| 22021 | goto use_filesort; |
| 22022 | } |
| 22023 | DBUG_ASSERT(tab->select->quick); |
| 22024 | tab->type= JT_ALL; |
| 22025 | tab->ref.key= -1; |
| 22026 | tab->ref.key_parts= 0; |
| 22027 | tab->use_quick= 1; |
| 22028 | best_key= new_ref_key; |
| 22029 | /* |
| 22030 | We don't restore select->cond as we want to use the |
| 22031 | original condition as index condition pushdown is not |
| 22032 | active for the new index. |
| 22033 | todo: why not perform index condition pushdown for the new index? |
| 22034 | */ |
| 22035 | } |
| 22036 | else |
| 22037 | { |
| 22038 | /* |
| 22039 | We'll use ref access method on key new_ref_key. In general case |
| 22040 | the index search tuple for new_ref_key will be different (e.g. |
| 22041 | when one index is defined as (part1, part2, ...) and another as |
| 22042 | (part1, part2(N), ...) and the WHERE clause contains |
| 22043 | "part1 = const1 AND part2=const2". |
| 22044 | So we build tab->ref from scratch here. |
| 22045 | */ |
| 22046 | KEYUSE *keyuse= tab->keyuse; |
| 22047 | while (keyuse->key != new_ref_key && keyuse->table == tab->table) |
| 22048 | keyuse++; |
| 22049 | if (create_ref_for_key(tab->join, tab, keyuse, FALSE, |
| 22050 | (tab->join->const_table_map | |
| 22051 | OUTER_REF_TABLE_BIT))) |
| 22052 | goto use_filesort; |
| 22053 | |
| 22054 | pick_table_access_method(tab); |
| 22055 | } |
| 22056 | |
| 22057 | ref_key= new_ref_key; |
| 22058 | changed_key= true; |
| 22059 | } |
| 22060 | } |
| 22061 | /* Check if we get the rows in requested sorted order by using the key */ |
| 22062 | if (usable_keys.is_set(ref_key) && |
| 22063 | (order_direction= test_if_order_by_key(tab->join, order,table,ref_key, |
| 22064 | &used_key_parts))) |
| 22065 | goto check_reverse_order; |
| 22066 | } |
| 22067 | { |
| 22068 | uint UNINIT_VAR(best_key_parts); |
| 22069 | uint saved_best_key_parts= 0; |
| 22070 | int best_key_direction= 0; |
| 22071 | JOIN *join= tab->join; |
| 22072 | ha_rows table_records= table->stat_records(); |
| 22073 | |
| 22074 | test_if_cheaper_ordering(tab, order, table, usable_keys, |
| 22075 | ref_key, select_limit, |
| 22076 | &best_key, &best_key_direction, |
| 22077 | &select_limit, &best_key_parts, |
| 22078 | &saved_best_key_parts); |
| 22079 | |
| 22080 | /* |
| 22081 | filesort() and join cache are usually faster than reading in |
| 22082 | index order and not using join cache, except in case that chosen |
| 22083 | index is clustered key. |
| 22084 | */ |
| 22085 | if (best_key < 0 || |
| 22086 | ((select_limit >= table_records) && |
| 22087 | (tab->type == JT_ALL && |
| 22088 | tab->join->table_count > tab->join->const_tables + 1) && |
| 22089 | !(table->file->index_flags(best_key, 0, 1) & HA_CLUSTERED_INDEX))) |
| 22090 | goto use_filesort; |
| 22091 | |
| 22092 | if (select && // psergey: why doesn't this use a quick? |
| 22093 | table->quick_keys.is_set(best_key) && best_key != ref_key) |
| 22094 | { |
| 22095 | key_map tmp_map; |
| 22096 | tmp_map.clear_all(); // Force the creation of quick select |
| 22097 | tmp_map.set_bit(best_key); // only best_key. |
| 22098 | select->quick= 0; |
| 22099 | select->test_quick_select(join->thd, tmp_map, 0, |
| 22100 | join->select_options & OPTION_FOUND_ROWS ? |
| 22101 | HA_POS_ERROR : |
| 22102 | join->unit->select_limit_cnt, |
| 22103 | TRUE, FALSE, FALSE); |
| 22104 | } |
| 22105 | order_direction= best_key_direction; |
| 22106 | /* |
| 22107 | saved_best_key_parts is actual number of used keyparts found by the |
| 22108 | test_if_order_by_key function. It could differ from keyinfo->user_defined_key_parts, |
| 22109 | thus we have to restore it in case of desc order as it affects |
| 22110 | QUICK_SELECT_DESC behaviour. |
| 22111 | */ |
| 22112 | used_key_parts= (order_direction == -1) ? |
| 22113 | saved_best_key_parts : best_key_parts; |
| 22114 | changed_key= true; |
| 22115 | } |
| 22116 | |
| 22117 | check_reverse_order: |
| 22118 | DBUG_ASSERT(order_direction != 0); |
| 22119 | |
| 22120 | if (order_direction == -1) // If ORDER BY ... DESC |
| 22121 | { |
| 22122 | int quick_type; |
| 22123 | if (select && select->quick) |
| 22124 | { |
| 22125 | /* |
| 22126 | Don't reverse the sort order, if it's already done. |
| 22127 | (In some cases test_if_order_by_key() can be called multiple times |
| 22128 | */ |
| 22129 | if (select->quick->reverse_sorted()) |
| 22130 | goto skipped_filesort; |
| 22131 | |
| 22132 | quick_type= select->quick->get_type(); |
| 22133 | if (quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE || |
| 22134 | quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_INTERSECT || |
| 22135 | quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT || |
| 22136 | quick_type == QUICK_SELECT_I::QS_TYPE_ROR_UNION || |
| 22137 | quick_type == QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX) |
| 22138 | { |
| 22139 | tab->limit= 0; |
| 22140 | goto use_filesort; // Use filesort |
| 22141 | } |
| 22142 | } |
| 22143 | } |
| 22144 | |
| 22145 | /* |
| 22146 | Update query plan with access pattern for doing ordered access |
| 22147 | according to what we have decided above. |
| 22148 | */ |
| 22149 | if (!no_changes) // We are allowed to update QEP |
| 22150 | { |
| 22151 | if (best_key >= 0) |
| 22152 | { |
| 22153 | bool quick_created= |
| 22154 | (select && select->quick && select->quick!=save_quick); |
| 22155 | |
| 22156 | /* |
| 22157 | If ref_key used index tree reading only ('Using index' in EXPLAIN), |
| 22158 | and best_key doesn't, then revert the decision. |
| 22159 | */ |
| 22160 | if (table->covering_keys.is_set(best_key)) |
| 22161 | table->file->ha_start_keyread(best_key); |
| 22162 | else |
| 22163 | table->file->ha_end_keyread(); |
| 22164 | |
| 22165 | if (!quick_created) |
| 22166 | { |
| 22167 | if (select) // Throw any existing quick select |
| 22168 | select->quick= 0; // Cleanup either reset to save_quick, |
| 22169 | // or 'delete save_quick' |
| 22170 | tab->index= best_key; |
| 22171 | tab->read_first_record= order_direction > 0 ? |
| 22172 | join_read_first:join_read_last; |
| 22173 | tab->type=JT_NEXT; // Read with index_first(), index_next() |
| 22174 | |
| 22175 | if (tab->pre_idx_push_select_cond) |
| 22176 | { |
| 22177 | tab->set_cond(tab->pre_idx_push_select_cond); |
| 22178 | /* |
| 22179 | orig_cond is a part of pre_idx_push_cond, |
| 22180 | no need to restore it. |
| 22181 | */ |
| 22182 | orig_cond= 0; |
| 22183 | orig_cond_saved= false; |
| 22184 | } |
| 22185 | |
| 22186 | table->file->ha_index_or_rnd_end(); |
| 22187 | if (tab->join->select_options & SELECT_DESCRIBE) |
| 22188 | { |
| 22189 | tab->ref.key= -1; |
| 22190 | tab->ref.key_parts= 0; |
| 22191 | if (select_limit < table->stat_records()) |
| 22192 | tab->limit= select_limit; |
| 22193 | table->file->ha_end_keyread(); |
| 22194 | } |
| 22195 | } |
| 22196 | else if (tab->type != JT_ALL || tab->select->quick) |
| 22197 | { |
| 22198 | /* |
| 22199 | We're about to use a quick access to the table. |
| 22200 | We need to change the access method so as the quick access |
| 22201 | method is actually used. |
| 22202 | */ |
| 22203 | DBUG_ASSERT(tab->select->quick); |
| 22204 | tab->type=JT_ALL; |
| 22205 | tab->use_quick=1; |
| 22206 | tab->ref.key= -1; |
| 22207 | tab->ref.key_parts=0; // Don't use ref key. |
| 22208 | tab->read_first_record= join_init_read_record; |
| 22209 | if (tab->is_using_loose_index_scan()) |
| 22210 | tab->join->tmp_table_param.precomputed_group_by= TRUE; |
| 22211 | |
| 22212 | /* |
| 22213 | Restore the original condition as changes done by pushdown |
| 22214 | condition are not relevant anymore |
| 22215 | */ |
| 22216 | if (tab->select && tab->select->pre_idx_push_select_cond) |
| 22217 | { |
| 22218 | tab->set_cond(tab->select->pre_idx_push_select_cond); |
| 22219 | tab->table->file->cancel_pushed_idx_cond(); |
| 22220 | } |
| 22221 | /* |
| 22222 | TODO: update the number of records in join->best_positions[tablenr] |
| 22223 | */ |
| 22224 | } |
| 22225 | } // best_key >= 0 |
| 22226 | |
| 22227 | if (order_direction == -1) // If ORDER BY ... DESC |
| 22228 | { |
| 22229 | if (select && select->quick) |
| 22230 | { |
| 22231 | /* ORDER BY range_key DESC */ |
| 22232 | QUICK_SELECT_I *tmp= select->quick->make_reverse(used_key_parts); |
| 22233 | if (!tmp) |
| 22234 | { |
| 22235 | tab->limit= 0; |
| 22236 | goto use_filesort; // Reverse sort failed -> filesort |
| 22237 | } |
| 22238 | /* |
| 22239 | Cancel Pushed Index Condition, as it doesn't work for reverse scans. |
| 22240 | */ |
| 22241 | if (tab->select && tab->select->pre_idx_push_select_cond) |
| 22242 | { |
| 22243 | tab->set_cond(tab->select->pre_idx_push_select_cond); |
| 22244 | tab->table->file->cancel_pushed_idx_cond(); |
| 22245 | } |
| 22246 | if (select->quick == save_quick) |
| 22247 | save_quick= 0; // make_reverse() consumed it |
| 22248 | select->set_quick(tmp); |
| 22249 | } |
| 22250 | else if (tab->type != JT_NEXT && tab->type != JT_REF_OR_NULL && |
| 22251 | tab->ref.key >= 0 && tab->ref.key_parts <= used_key_parts) |
| 22252 | { |
| 22253 | /* |
| 22254 | SELECT * FROM t1 WHERE a=1 ORDER BY a DESC,b DESC |
| 22255 | |
| 22256 | Use a traversal function that starts by reading the last row |
| 22257 | with key part (A) and then traverse the index backwards. |
| 22258 | */ |
| 22259 | tab->read_first_record= join_read_last_key; |
| 22260 | tab->read_record.read_record_func= join_read_prev_same; |
| 22261 | /* |
| 22262 | Cancel Pushed Index Condition, as it doesn't work for reverse scans. |
| 22263 | */ |
| 22264 | if (tab->select && tab->select->pre_idx_push_select_cond) |
| 22265 | { |
| 22266 | tab->set_cond(tab->select->pre_idx_push_select_cond); |
| 22267 | tab->table->file->cancel_pushed_idx_cond(); |
| 22268 | } |
| 22269 | } |
| 22270 | } |
| 22271 | else if (select && select->quick) |
| 22272 | select->quick->need_sorted_output(); |
| 22273 | |
| 22274 | } // QEP has been modified |
| 22275 | |
| 22276 | /* |
| 22277 | Cleanup: |
| 22278 | We may have both a 'select->quick' and 'save_quick' (original) |
| 22279 | at this point. Delete the one that we wan't use. |
| 22280 | */ |
| 22281 | |
| 22282 | skipped_filesort: |
| 22283 | // Keep current (ordered) select->quick |
| 22284 | if (select && save_quick != select->quick) |
| 22285 | { |
| 22286 | delete save_quick; |
| 22287 | save_quick= NULL; |
| 22288 | } |
| 22289 | if (orig_cond_saved && !changed_key) |
| 22290 | tab->set_cond(orig_cond); |
| 22291 | if (!no_changes && changed_key && table->file->pushed_idx_cond) |
| 22292 | table->file->cancel_pushed_idx_cond(); |
| 22293 | |
| 22294 | DBUG_RETURN(1); |
| 22295 | |
| 22296 | use_filesort: |
| 22297 | // Restore original save_quick |
| 22298 | if (select && select->quick != save_quick) |
| 22299 | { |
| 22300 | delete select->quick; |
| 22301 | select->quick= save_quick; |
| 22302 | } |
| 22303 | if (orig_cond_saved) |
| 22304 | tab->set_cond(orig_cond); |
| 22305 | |
| 22306 | DBUG_RETURN(0); |
| 22307 | } |
| 22308 | |
| 22309 | |
| 22310 | /* |
| 22311 | If not selecting by given key, create an index how records should be read |
| 22312 | |
| 22313 | SYNOPSIS |
| 22314 | create_sort_index() |
| 22315 | thd Thread handler |
| 22316 | join Join with table to sort |
| 22317 | join_tab What table to sort |
| 22318 | fsort Filesort object. NULL means "use tab->filesort". |
| 22319 | |
| 22320 | IMPLEMENTATION |
| 22321 | - If there is an index that can be used, the first non-const join_tab in |
| 22322 | 'join' is modified to use this index. |
| 22323 | - If no index, create with filesort() an index file that can be used to |
| 22324 | retrieve rows in order (should be done with 'read_record'). |
| 22325 | The sorted data is stored in tab->filesort |
| 22326 | |
| 22327 | RETURN VALUES |
| 22328 | 0 ok |
| 22329 | -1 Some fatal error |
| 22330 | 1 No records |
| 22331 | */ |
| 22332 | |
| 22333 | int |
| 22334 | create_sort_index(THD *thd, JOIN *join, JOIN_TAB *tab, Filesort *fsort) |
| 22335 | { |
| 22336 | TABLE *table; |
| 22337 | SQL_SELECT *select; |
| 22338 | bool quick_created= FALSE; |
| 22339 | SORT_INFO *file_sort= 0; |
| 22340 | DBUG_ENTER("create_sort_index" ); |
| 22341 | |
| 22342 | if (fsort == NULL) |
| 22343 | fsort= tab->filesort; |
| 22344 | |
| 22345 | table= tab->table; |
| 22346 | select= fsort->select; |
| 22347 | |
| 22348 | table->status=0; // May be wrong if quick_select |
| 22349 | |
| 22350 | if (!tab->preread_init_done && tab->preread_init()) |
| 22351 | goto err; |
| 22352 | |
| 22353 | // If table has a range, move it to select |
| 22354 | if (select && tab->ref.key >= 0) |
| 22355 | { |
| 22356 | if (!select->quick) |
| 22357 | { |
| 22358 | if (tab->quick) |
| 22359 | { |
| 22360 | select->quick= tab->quick; |
| 22361 | tab->quick= NULL; |
| 22362 | /* |
| 22363 | We can only use 'Only index' if quick key is same as ref_key |
| 22364 | and in index_merge 'Only index' cannot be used |
| 22365 | */ |
| 22366 | if (((uint) tab->ref.key != select->quick->index)) |
| 22367 | table->file->ha_end_keyread(); |
| 22368 | } |
| 22369 | else |
| 22370 | { |
| 22371 | /* |
| 22372 | We have a ref on a const; Change this to a range that filesort |
| 22373 | can use. |
| 22374 | For impossible ranges (like when doing a lookup on NULL on a NOT NULL |
| 22375 | field, quick will contain an empty record set. |
| 22376 | */ |
| 22377 | if (!(select->quick= (tab->type == JT_FT ? |
| 22378 | get_ft_select(thd, table, tab->ref.key) : |
| 22379 | get_quick_select_for_ref(thd, table, &tab->ref, |
| 22380 | tab->found_records)))) |
| 22381 | goto err; |
| 22382 | quick_created= TRUE; |
| 22383 | } |
| 22384 | fsort->own_select= true; |
| 22385 | } |
| 22386 | else |
| 22387 | { |
| 22388 | DBUG_ASSERT(tab->type == JT_REF || tab->type == JT_EQ_REF); |
| 22389 | // Update ref value |
| 22390 | if (unlikely(cp_buffer_from_ref(thd, table, &tab->ref) && |
| 22391 | thd->is_fatal_error)) |
| 22392 | goto err; // out of memory |
| 22393 | } |
| 22394 | } |
| 22395 | |
| 22396 | |
| 22397 | /* Fill schema tables with data before filesort if it's necessary */ |
| 22398 | if ((join->select_lex->options & OPTION_SCHEMA_TABLE) && |
| 22399 | unlikely(get_schema_tables_result(join, PROCESSED_BY_CREATE_SORT_INDEX))) |
| 22400 | goto err; |
| 22401 | |
| 22402 | if (table->s->tmp_table) |
| 22403 | table->file->info(HA_STATUS_VARIABLE); // Get record count |
| 22404 | file_sort= filesort(thd, table, fsort, fsort->tracker, join, tab->table->map); |
| 22405 | DBUG_ASSERT(tab->filesort_result == 0); |
| 22406 | tab->filesort_result= file_sort; |
| 22407 | tab->records= 0; |
| 22408 | if (file_sort) |
| 22409 | { |
| 22410 | tab->records= join->select_options & OPTION_FOUND_ROWS ? |
| 22411 | file_sort->found_rows : file_sort->return_rows; |
| 22412 | tab->join->join_examined_rows+= file_sort->examined_rows; |
| 22413 | } |
| 22414 | |
| 22415 | if (quick_created) |
| 22416 | { |
| 22417 | /* This will delete the quick select. */ |
| 22418 | select->cleanup(); |
| 22419 | } |
| 22420 | |
| 22421 | table->file->ha_end_keyread(); |
| 22422 | if (tab->type == JT_FT) |
| 22423 | table->file->ha_ft_end(); |
| 22424 | else |
| 22425 | table->file->ha_index_or_rnd_end(); |
| 22426 | |
| 22427 | DBUG_RETURN(file_sort == 0); |
| 22428 | err: |
| 22429 | DBUG_RETURN(-1); |
| 22430 | } |
| 22431 | |
| 22432 | |
| 22433 | /** |
| 22434 | Compare fields from table->record[0] and table->record[1], |
| 22435 | possibly skipping few first fields. |
| 22436 | |
| 22437 | @param table |
| 22438 | @param ptr field to start the comparison from, |
| 22439 | somewhere in the table->field[] array |
| 22440 | |
| 22441 | @retval 1 different |
| 22442 | @retval 0 identical |
| 22443 | */ |
| 22444 | static bool compare_record(TABLE *table, Field **ptr) |
| 22445 | { |
| 22446 | for (; *ptr ; ptr++) |
| 22447 | { |
| 22448 | Field *f= *ptr; |
| 22449 | if (f->is_null() != f->is_null(table->s->rec_buff_length) || |
| 22450 | (!f->is_null() && f->cmp_offset(table->s->rec_buff_length))) |
| 22451 | return 1; |
| 22452 | } |
| 22453 | return 0; |
| 22454 | } |
| 22455 | |
| 22456 | static bool copy_blobs(Field **ptr) |
| 22457 | { |
| 22458 | for (; *ptr ; ptr++) |
| 22459 | { |
| 22460 | if ((*ptr)->flags & BLOB_FLAG) |
| 22461 | if (((Field_blob *) (*ptr))->copy()) |
| 22462 | return 1; // Error |
| 22463 | } |
| 22464 | return 0; |
| 22465 | } |
| 22466 | |
| 22467 | static void free_blobs(Field **ptr) |
| 22468 | { |
| 22469 | for (; *ptr ; ptr++) |
| 22470 | { |
| 22471 | if ((*ptr)->flags & BLOB_FLAG) |
| 22472 | ((Field_blob *) (*ptr))->free(); |
| 22473 | } |
| 22474 | } |
| 22475 | |
| 22476 | |
| 22477 | /* |
| 22478 | @brief |
| 22479 | Remove duplicates from a temporary table. |
| 22480 | |
| 22481 | @detail |
| 22482 | Remove duplicate rows from a temporary table. This is used for e.g. queries |
| 22483 | like |
| 22484 | |
| 22485 | select distinct count(*) as CNT from tbl group by col |
| 22486 | |
| 22487 | Here, we get a group table with count(*) values. It is not possible to |
| 22488 | prevent duplicates from appearing in the table (as we don't know the values |
| 22489 | before we've done the grouping). Because of that, we have this function to |
| 22490 | scan the temptable (maybe, multiple times) and remove the duplicate rows |
| 22491 | |
| 22492 | Rows that do not satisfy 'having' condition are also removed. |
| 22493 | */ |
| 22494 | |
| 22495 | bool |
| 22496 | JOIN_TAB::remove_duplicates() |
| 22497 | |
| 22498 | { |
| 22499 | bool error; |
| 22500 | ulong keylength= 0; |
| 22501 | uint field_count; |
| 22502 | List<Item> *fields= (this-1)->fields; |
| 22503 | THD *thd= join->thd; |
| 22504 | |
| 22505 | DBUG_ENTER("remove_duplicates" ); |
| 22506 | |
| 22507 | DBUG_ASSERT(join->aggr_tables > 0 && table->s->tmp_table != NO_TMP_TABLE); |
| 22508 | THD_STAGE_INFO(join->thd, stage_removing_duplicates); |
| 22509 | |
| 22510 | //join->explain->ops_tracker.report_duplicate_removal(); |
| 22511 | |
| 22512 | table->reginfo.lock_type=TL_WRITE; |
| 22513 | |
| 22514 | /* Calculate how many saved fields there is in list */ |
| 22515 | field_count=0; |
| 22516 | List_iterator<Item> it(*fields); |
| 22517 | Item *item; |
| 22518 | while ((item=it++)) |
| 22519 | { |
| 22520 | if (item->get_tmp_table_field() && ! item->const_item()) |
| 22521 | field_count++; |
| 22522 | } |
| 22523 | |
| 22524 | if (!field_count && !(join->select_options & OPTION_FOUND_ROWS) && !having) |
| 22525 | { // only const items with no OPTION_FOUND_ROWS |
| 22526 | join->unit->select_limit_cnt= 1; // Only send first row |
| 22527 | DBUG_RETURN(false); |
| 22528 | } |
| 22529 | |
| 22530 | Field **first_field=table->field+table->s->fields - field_count; |
| 22531 | for (Field **ptr=first_field; *ptr; ptr++) |
| 22532 | keylength+= (*ptr)->sort_length() + (*ptr)->maybe_null(); |
| 22533 | |
| 22534 | /* |
| 22535 | Disable LIMIT ROWS EXAMINED in order to avoid interrupting prematurely |
| 22536 | duplicate removal, and produce a possibly incomplete query result. |
| 22537 | */ |
| 22538 | thd->lex->limit_rows_examined_cnt= ULONGLONG_MAX; |
| 22539 | if (thd->killed == ABORT_QUERY) |
| 22540 | thd->reset_killed(); |
| 22541 | |
| 22542 | table->file->info(HA_STATUS_VARIABLE); |
| 22543 | if (table->s->db_type() == heap_hton || |
| 22544 | (!table->s->blob_fields && |
| 22545 | ((ALIGN_SIZE(keylength) + HASH_OVERHEAD) * table->file->stats.records < |
| 22546 | thd->variables.sortbuff_size))) |
| 22547 | error=remove_dup_with_hash_index(join->thd, table, field_count, first_field, |
| 22548 | keylength, having); |
| 22549 | else |
| 22550 | error=remove_dup_with_compare(join->thd, table, first_field, having); |
| 22551 | |
| 22552 | if (join->select_lex != join->select_lex->master_unit()->fake_select_lex) |
| 22553 | thd->lex->set_limit_rows_examined(); |
| 22554 | free_blobs(first_field); |
| 22555 | DBUG_RETURN(error); |
| 22556 | } |
| 22557 | |
| 22558 | |
| 22559 | static int remove_dup_with_compare(THD *thd, TABLE *table, Field **first_field, |
| 22560 | Item *having) |
| 22561 | { |
| 22562 | handler *file=table->file; |
| 22563 | uchar *record=table->record[0]; |
| 22564 | int error; |
| 22565 | DBUG_ENTER("remove_dup_with_compare" ); |
| 22566 | |
| 22567 | if (unlikely(file->ha_rnd_init_with_error(1))) |
| 22568 | DBUG_RETURN(1); |
| 22569 | |
| 22570 | error= file->ha_rnd_next(record); |
| 22571 | for (;;) |
| 22572 | { |
| 22573 | if (unlikely(thd->check_killed())) |
| 22574 | { |
| 22575 | thd->send_kill_message(); |
| 22576 | error=0; |
| 22577 | goto err; |
| 22578 | } |
| 22579 | if (unlikely(error)) |
| 22580 | { |
| 22581 | if (error == HA_ERR_END_OF_FILE) |
| 22582 | break; |
| 22583 | goto err; |
| 22584 | } |
| 22585 | if (having && !having->val_int()) |
| 22586 | { |
| 22587 | if (unlikely((error= file->ha_delete_row(record)))) |
| 22588 | goto err; |
| 22589 | error= file->ha_rnd_next(record); |
| 22590 | continue; |
| 22591 | } |
| 22592 | if (unlikely(copy_blobs(first_field))) |
| 22593 | { |
| 22594 | my_message(ER_OUTOFMEMORY, ER_THD(thd,ER_OUTOFMEMORY), |
| 22595 | MYF(ME_FATALERROR)); |
| 22596 | error=0; |
| 22597 | goto err; |
| 22598 | } |
| 22599 | store_record(table,record[1]); |
| 22600 | |
| 22601 | /* Read through rest of file and mark duplicated rows deleted */ |
| 22602 | bool found=0; |
| 22603 | for (;;) |
| 22604 | { |
| 22605 | if (unlikely((error= file->ha_rnd_next(record)))) |
| 22606 | { |
| 22607 | if (error == HA_ERR_END_OF_FILE) |
| 22608 | break; |
| 22609 | goto err; |
| 22610 | } |
| 22611 | if (compare_record(table, first_field) == 0) |
| 22612 | { |
| 22613 | if (unlikely((error= file->ha_delete_row(record)))) |
| 22614 | goto err; |
| 22615 | } |
| 22616 | else if (!found) |
| 22617 | { |
| 22618 | found=1; |
| 22619 | if (unlikely((error= file->remember_rnd_pos()))) |
| 22620 | goto err; |
| 22621 | } |
| 22622 | } |
| 22623 | if (!found) |
| 22624 | break; // End of file |
| 22625 | /* Restart search on saved row */ |
| 22626 | if (unlikely((error= file->restart_rnd_next(record)))) |
| 22627 | goto err; |
| 22628 | } |
| 22629 | |
| 22630 | file->extra(HA_EXTRA_NO_CACHE); |
| 22631 | DBUG_RETURN(0); |
| 22632 | err: |
| 22633 | file->extra(HA_EXTRA_NO_CACHE); |
| 22634 | if (error) |
| 22635 | file->print_error(error,MYF(0)); |
| 22636 | DBUG_RETURN(1); |
| 22637 | } |
| 22638 | |
| 22639 | |
| 22640 | /** |
| 22641 | Generate a hash index for each row to quickly find duplicate rows. |
| 22642 | |
| 22643 | @note |
| 22644 | Note that this will not work on tables with blobs! |
| 22645 | */ |
| 22646 | |
| 22647 | static int remove_dup_with_hash_index(THD *thd, TABLE *table, |
| 22648 | uint field_count, |
| 22649 | Field **first_field, |
| 22650 | ulong key_length, |
| 22651 | Item *having) |
| 22652 | { |
| 22653 | uchar *key_buffer, *key_pos, *record=table->record[0]; |
| 22654 | int error; |
| 22655 | handler *file= table->file; |
| 22656 | ulong = ALIGN_SIZE(key_length)-key_length; |
| 22657 | uint *field_lengths, *field_length; |
| 22658 | HASH hash; |
| 22659 | Field **ptr; |
| 22660 | DBUG_ENTER("remove_dup_with_hash_index" ); |
| 22661 | |
| 22662 | if (unlikely(!my_multi_malloc(MYF(MY_WME), |
| 22663 | &key_buffer, |
| 22664 | (uint) ((key_length + extra_length) * |
| 22665 | (long) file->stats.records), |
| 22666 | &field_lengths, |
| 22667 | (uint) (field_count*sizeof(*field_lengths)), |
| 22668 | NullS))) |
| 22669 | DBUG_RETURN(1); |
| 22670 | |
| 22671 | for (ptr= first_field, field_length=field_lengths ; *ptr ; ptr++) |
| 22672 | (*field_length++)= (*ptr)->sort_length(); |
| 22673 | |
| 22674 | if (unlikely(my_hash_init(&hash, &my_charset_bin, |
| 22675 | (uint) file->stats.records, 0, |
| 22676 | key_length, (my_hash_get_key) 0, 0, 0))) |
| 22677 | { |
| 22678 | my_free(key_buffer); |
| 22679 | DBUG_RETURN(1); |
| 22680 | } |
| 22681 | |
| 22682 | if (unlikely((error= file->ha_rnd_init(1)))) |
| 22683 | goto err; |
| 22684 | |
| 22685 | key_pos=key_buffer; |
| 22686 | for (;;) |
| 22687 | { |
| 22688 | uchar *org_key_pos; |
| 22689 | if (unlikely(thd->check_killed())) |
| 22690 | { |
| 22691 | thd->send_kill_message(); |
| 22692 | error=0; |
| 22693 | goto err; |
| 22694 | } |
| 22695 | if (unlikely((error= file->ha_rnd_next(record)))) |
| 22696 | { |
| 22697 | if (error == HA_ERR_END_OF_FILE) |
| 22698 | break; |
| 22699 | goto err; |
| 22700 | } |
| 22701 | if (having && !having->val_int()) |
| 22702 | { |
| 22703 | if (unlikely((error= file->ha_delete_row(record)))) |
| 22704 | goto err; |
| 22705 | continue; |
| 22706 | } |
| 22707 | |
| 22708 | /* copy fields to key buffer */ |
| 22709 | org_key_pos= key_pos; |
| 22710 | field_length=field_lengths; |
| 22711 | for (ptr= first_field ; *ptr ; ptr++) |
| 22712 | { |
| 22713 | (*ptr)->make_sort_key(key_pos, *field_length); |
| 22714 | key_pos+= (*ptr)->maybe_null() + *field_length++; |
| 22715 | } |
| 22716 | /* Check if it exists before */ |
| 22717 | if (my_hash_search(&hash, org_key_pos, key_length)) |
| 22718 | { |
| 22719 | /* Duplicated found ; Remove the row */ |
| 22720 | if (unlikely((error= file->ha_delete_row(record)))) |
| 22721 | goto err; |
| 22722 | } |
| 22723 | else |
| 22724 | { |
| 22725 | if (my_hash_insert(&hash, org_key_pos)) |
| 22726 | goto err; |
| 22727 | } |
| 22728 | key_pos+=extra_length; |
| 22729 | } |
| 22730 | my_free(key_buffer); |
| 22731 | my_hash_free(&hash); |
| 22732 | file->extra(HA_EXTRA_NO_CACHE); |
| 22733 | (void) file->ha_rnd_end(); |
| 22734 | DBUG_RETURN(0); |
| 22735 | |
| 22736 | err: |
| 22737 | my_free(key_buffer); |
| 22738 | my_hash_free(&hash); |
| 22739 | file->extra(HA_EXTRA_NO_CACHE); |
| 22740 | (void) file->ha_rnd_end(); |
| 22741 | if (unlikely(error)) |
| 22742 | file->print_error(error,MYF(0)); |
| 22743 | DBUG_RETURN(1); |
| 22744 | } |
| 22745 | |
| 22746 | |
| 22747 | /* |
| 22748 | eq_ref: Create the lookup key and check if it is the same as saved key |
| 22749 | |
| 22750 | SYNOPSIS |
| 22751 | cmp_buffer_with_ref() |
| 22752 | tab Join tab of the accessed table |
| 22753 | table The table to read. This is usually tab->table, except for |
| 22754 | semi-join when we might need to make a lookup in a temptable |
| 22755 | instead. |
| 22756 | tab_ref The structure with methods to collect index lookup tuple. |
| 22757 | This is usually table->ref, except for the case of when we're |
| 22758 | doing lookup into semi-join materialization table. |
| 22759 | |
| 22760 | DESCRIPTION |
| 22761 | Used by eq_ref access method: create the index lookup key and check if |
| 22762 | we've used this key at previous lookup (If yes, we don't need to repeat |
| 22763 | the lookup - the record has been already fetched) |
| 22764 | |
| 22765 | RETURN |
| 22766 | TRUE No cached record for the key, or failed to create the key (due to |
| 22767 | out-of-domain error) |
| 22768 | FALSE The created key is the same as the previous one (and the record |
| 22769 | is already in table->record) |
| 22770 | */ |
| 22771 | |
| 22772 | static bool |
| 22773 | cmp_buffer_with_ref(THD *thd, TABLE *table, TABLE_REF *tab_ref) |
| 22774 | { |
| 22775 | bool no_prev_key; |
| 22776 | if (!tab_ref->disable_cache) |
| 22777 | { |
| 22778 | if (!(no_prev_key= tab_ref->key_err)) |
| 22779 | { |
| 22780 | /* Previous access found a row. Copy its key */ |
| 22781 | memcpy(tab_ref->key_buff2, tab_ref->key_buff, tab_ref->key_length); |
| 22782 | } |
| 22783 | } |
| 22784 | else |
| 22785 | no_prev_key= TRUE; |
| 22786 | if ((tab_ref->key_err= cp_buffer_from_ref(thd, table, tab_ref)) || |
| 22787 | no_prev_key) |
| 22788 | return 1; |
| 22789 | return memcmp(tab_ref->key_buff2, tab_ref->key_buff, tab_ref->key_length) |
| 22790 | != 0; |
| 22791 | } |
| 22792 | |
| 22793 | |
| 22794 | bool |
| 22795 | cp_buffer_from_ref(THD *thd, TABLE *table, TABLE_REF *ref) |
| 22796 | { |
| 22797 | enum enum_check_fields save_count_cuted_fields= thd->count_cuted_fields; |
| 22798 | thd->count_cuted_fields= CHECK_FIELD_IGNORE; |
| 22799 | my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->write_set); |
| 22800 | bool result= 0; |
| 22801 | |
| 22802 | for (store_key **copy=ref->key_copy ; *copy ; copy++) |
| 22803 | { |
| 22804 | if ((*copy)->copy() & 1) |
| 22805 | { |
| 22806 | result= 1; |
| 22807 | break; |
| 22808 | } |
| 22809 | } |
| 22810 | thd->count_cuted_fields= save_count_cuted_fields; |
| 22811 | dbug_tmp_restore_column_map(table->write_set, old_map); |
| 22812 | return result; |
| 22813 | } |
| 22814 | |
| 22815 | |
| 22816 | /***************************************************************************** |
| 22817 | Group and order functions |
| 22818 | *****************************************************************************/ |
| 22819 | |
| 22820 | /** |
| 22821 | Resolve an ORDER BY or GROUP BY column reference. |
| 22822 | |
| 22823 | Given a column reference (represented by 'order') from a GROUP BY or ORDER |
| 22824 | BY clause, find the actual column it represents. If the column being |
| 22825 | resolved is from the GROUP BY clause, the procedure searches the SELECT |
| 22826 | list 'fields' and the columns in the FROM list 'tables'. If 'order' is from |
| 22827 | the ORDER BY clause, only the SELECT list is being searched. |
| 22828 | |
| 22829 | If 'order' is resolved to an Item, then order->item is set to the found |
| 22830 | Item. If there is no item for the found column (that is, it was resolved |
| 22831 | into a table field), order->item is 'fixed' and is added to all_fields and |
| 22832 | ref_pointer_array. |
| 22833 | |
| 22834 | ref_pointer_array and all_fields are updated. |
| 22835 | |
| 22836 | @param[in] thd Pointer to current thread structure |
| 22837 | @param[in,out] ref_pointer_array All select, group and order by fields |
| 22838 | @param[in] tables List of tables to search in (usually |
| 22839 | FROM clause) |
| 22840 | @param[in] order Column reference to be resolved |
| 22841 | @param[in] fields List of fields to search in (usually |
| 22842 | SELECT list) |
| 22843 | @param[in,out] all_fields All select, group and order by fields |
| 22844 | @param[in] is_group_field True if order is a GROUP field, false if |
| 22845 | ORDER by field |
| 22846 | @param[in] add_to_all_fields If the item is to be added to all_fields and |
| 22847 | ref_pointer_array, this flag can be set to |
| 22848 | false to stop the automatic insertion. |
| 22849 | @param[in] from_window_spec If true then order is from a window spec |
| 22850 | |
| 22851 | @retval |
| 22852 | FALSE if OK |
| 22853 | @retval |
| 22854 | TRUE if error occurred |
| 22855 | */ |
| 22856 | |
| 22857 | static bool |
| 22858 | find_order_in_list(THD *thd, Ref_ptr_array ref_pointer_array, |
| 22859 | TABLE_LIST *tables, |
| 22860 | ORDER *order, List<Item> &fields, List<Item> &all_fields, |
| 22861 | bool is_group_field, bool add_to_all_fields, |
| 22862 | bool from_window_spec) |
| 22863 | { |
| 22864 | Item *order_item= *order->item; /* The item from the GROUP/ORDER caluse. */ |
| 22865 | Item::Type order_item_type; |
| 22866 | Item **select_item; /* The corresponding item from the SELECT clause. */ |
| 22867 | Field *from_field; /* The corresponding field from the FROM clause. */ |
| 22868 | uint counter; |
| 22869 | enum_resolution_type resolution; |
| 22870 | |
| 22871 | /* |
| 22872 | Local SP variables may be int but are expressions, not positions. |
| 22873 | (And they can't be used before fix_fields is called for them). |
| 22874 | */ |
| 22875 | if (order_item->type() == Item::INT_ITEM && order_item->basic_const_item() && |
| 22876 | !from_window_spec) |
| 22877 | { /* Order by position */ |
| 22878 | uint count; |
| 22879 | if (order->counter_used) |
| 22880 | count= order->counter; // counter was once resolved |
| 22881 | else |
| 22882 | count= (uint) order_item->val_int(); |
| 22883 | if (!count || count > fields.elements) |
| 22884 | { |
| 22885 | my_error(ER_BAD_FIELD_ERROR, MYF(0), |
| 22886 | order_item->full_name(), thd->where); |
| 22887 | return TRUE; |
| 22888 | } |
| 22889 | thd->change_item_tree((Item **)&order->item, (Item *)&ref_pointer_array[count - 1]); |
| 22890 | order->in_field_list= 1; |
| 22891 | order->counter= count; |
| 22892 | order->counter_used= 1; |
| 22893 | return FALSE; |
| 22894 | } |
| 22895 | /* Lookup the current GROUP/ORDER field in the SELECT clause. */ |
| 22896 | select_item= find_item_in_list(order_item, fields, &counter, |
| 22897 | REPORT_EXCEPT_NOT_FOUND, &resolution); |
| 22898 | if (!select_item) |
| 22899 | return TRUE; /* The item is not unique, or some other error occurred. */ |
| 22900 | |
| 22901 | |
| 22902 | /* Check whether the resolved field is not ambiguos. */ |
| 22903 | if (select_item != not_found_item) |
| 22904 | { |
| 22905 | Item *view_ref= NULL; |
| 22906 | /* |
| 22907 | If we have found field not by its alias in select list but by its |
| 22908 | original field name, we should additionally check if we have conflict |
| 22909 | for this name (in case if we would perform lookup in all tables). |
| 22910 | */ |
| 22911 | if (resolution == RESOLVED_BEHIND_ALIAS && !order_item->fixed && |
| 22912 | order_item->fix_fields(thd, order->item)) |
| 22913 | return TRUE; |
| 22914 | |
| 22915 | /* Lookup the current GROUP field in the FROM clause. */ |
| 22916 | order_item_type= order_item->type(); |
| 22917 | from_field= (Field*) not_found_field; |
| 22918 | if ((is_group_field && order_item_type == Item::FIELD_ITEM) || |
| 22919 | order_item_type == Item::REF_ITEM) |
| 22920 | { |
| 22921 | from_field= find_field_in_tables(thd, (Item_ident*) order_item, tables, |
| 22922 | NULL, &view_ref, IGNORE_ERRORS, FALSE, |
| 22923 | FALSE); |
| 22924 | if (!from_field) |
| 22925 | from_field= (Field*) not_found_field; |
| 22926 | } |
| 22927 | |
| 22928 | if (from_field == not_found_field || |
| 22929 | (from_field != view_ref_found ? |
| 22930 | /* it is field of base table => check that fields are same */ |
| 22931 | ((*select_item)->type() == Item::FIELD_ITEM && |
| 22932 | ((Item_field*) (*select_item))->field->eq(from_field)) : |
| 22933 | /* |
| 22934 | in is field of view table => check that references on translation |
| 22935 | table are same |
| 22936 | */ |
| 22937 | ((*select_item)->type() == Item::REF_ITEM && |
| 22938 | view_ref->type() == Item::REF_ITEM && |
| 22939 | ((Item_ref *) (*select_item))->ref == |
| 22940 | ((Item_ref *) view_ref)->ref))) |
| 22941 | { |
| 22942 | /* |
| 22943 | If there is no such field in the FROM clause, or it is the same field |
| 22944 | as the one found in the SELECT clause, then use the Item created for |
| 22945 | the SELECT field. As a result if there was a derived field that |
| 22946 | 'shadowed' a table field with the same name, the table field will be |
| 22947 | chosen over the derived field. |
| 22948 | */ |
| 22949 | order->item= &ref_pointer_array[counter]; |
| 22950 | order->in_field_list=1; |
| 22951 | return FALSE; |
| 22952 | } |
| 22953 | else |
| 22954 | { |
| 22955 | /* |
| 22956 | There is a field with the same name in the FROM clause. This |
| 22957 | is the field that will be chosen. In this case we issue a |
| 22958 | warning so the user knows that the field from the FROM clause |
| 22959 | overshadows the column reference from the SELECT list. |
| 22960 | */ |
| 22961 | push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, |
| 22962 | ER_NON_UNIQ_ERROR, |
| 22963 | ER_THD(thd, ER_NON_UNIQ_ERROR), |
| 22964 | ((Item_ident*) order_item)->field_name.str, |
| 22965 | thd->where); |
| 22966 | } |
| 22967 | } |
| 22968 | else if (from_window_spec) |
| 22969 | { |
| 22970 | Item **found_item= find_item_in_list(order_item, all_fields, &counter, |
| 22971 | REPORT_EXCEPT_NOT_FOUND, &resolution, |
| 22972 | all_fields.elements - fields.elements); |
| 22973 | if (found_item != not_found_item) |
| 22974 | { |
| 22975 | order->item= &ref_pointer_array[all_fields.elements-1-counter]; |
| 22976 | order->in_field_list= 0; |
| 22977 | return FALSE; |
| 22978 | } |
| 22979 | } |
| 22980 | |
| 22981 | order->in_field_list=0; |
| 22982 | /* |
| 22983 | The call to order_item->fix_fields() means that here we resolve |
| 22984 | 'order_item' to a column from a table in the list 'tables', or to |
| 22985 | a column in some outer query. Exactly because of the second case |
| 22986 | we come to this point even if (select_item == not_found_item), |
| 22987 | inspite of that fix_fields() calls find_item_in_list() one more |
| 22988 | time. |
| 22989 | |
| 22990 | We check order_item->fixed because Item_func_group_concat can put |
| 22991 | arguments for which fix_fields already was called. |
| 22992 | */ |
| 22993 | if (!order_item->fixed && |
| 22994 | (order_item->fix_fields(thd, order->item) || |
| 22995 | (order_item= *order->item)->check_cols(1) || |
| 22996 | thd->is_error())) |
| 22997 | return TRUE; /* Wrong field. */ |
| 22998 | |
| 22999 | if (!add_to_all_fields) |
| 23000 | return FALSE; |
| 23001 | |
| 23002 | uint el= all_fields.elements; |
| 23003 | /* Add new field to field list. */ |
| 23004 | all_fields.push_front(order_item, thd->mem_root); |
| 23005 | ref_pointer_array[el]= order_item; |
| 23006 | /* |
| 23007 | If the order_item is a SUM_FUNC_ITEM, when fix_fields is called |
| 23008 | ref_by is set to order->item which is the address of order_item. |
| 23009 | But this needs to be address of order_item in the all_fields list. |
| 23010 | As a result, when it gets replaced with Item_aggregate_ref |
| 23011 | object in Item::split_sum_func2, we will be able to retrieve the |
| 23012 | newly created object. |
| 23013 | */ |
| 23014 | if (order_item->type() == Item::SUM_FUNC_ITEM) |
| 23015 | ((Item_sum *)order_item)->ref_by= all_fields.head_ref(); |
| 23016 | |
| 23017 | order->item= &ref_pointer_array[el]; |
| 23018 | return FALSE; |
| 23019 | } |
| 23020 | |
| 23021 | |
| 23022 | /** |
| 23023 | Change order to point at item in select list. |
| 23024 | |
| 23025 | If item isn't a number and doesn't exits in the select list, add it the |
| 23026 | the field list. |
| 23027 | */ |
| 23028 | |
| 23029 | int setup_order(THD *thd, Ref_ptr_array ref_pointer_array, TABLE_LIST *tables, |
| 23030 | List<Item> &fields, List<Item> &all_fields, ORDER *order, |
| 23031 | bool from_window_spec) |
| 23032 | { |
| 23033 | enum_parsing_place context_analysis_place= |
| 23034 | thd->lex->current_select->context_analysis_place; |
| 23035 | thd->where="order clause" ; |
| 23036 | for (; order; order=order->next) |
| 23037 | { |
| 23038 | if (find_order_in_list(thd, ref_pointer_array, tables, order, fields, |
| 23039 | all_fields, false, true, from_window_spec)) |
| 23040 | return 1; |
| 23041 | if ((*order->item)->with_window_func && |
| 23042 | context_analysis_place != IN_ORDER_BY) |
| 23043 | { |
| 23044 | my_error(ER_WINDOW_FUNCTION_IN_WINDOW_SPEC, MYF(0)); |
| 23045 | return 1; |
| 23046 | } |
| 23047 | } |
| 23048 | return 0; |
| 23049 | } |
| 23050 | |
| 23051 | |
| 23052 | /** |
| 23053 | Intitialize the GROUP BY list. |
| 23054 | |
| 23055 | @param thd Thread handler |
| 23056 | @param ref_pointer_array We store references to all fields that was |
| 23057 | not in 'fields' here. |
| 23058 | @param fields All fields in the select part. Any item in |
| 23059 | 'order' that is part of these list is replaced |
| 23060 | by a pointer to this fields. |
| 23061 | @param all_fields Total list of all unique fields used by the |
| 23062 | select. All items in 'order' that was not part |
| 23063 | of fields will be added first to this list. |
| 23064 | @param order The fields we should do GROUP/PARTITION BY on |
| 23065 | @param hidden_group_fields Pointer to flag that is set to 1 if we added |
| 23066 | any fields to all_fields. |
| 23067 | @param from_window_spec If true then list is from a window spec |
| 23068 | |
| 23069 | @todo |
| 23070 | change ER_WRONG_FIELD_WITH_GROUP to more detailed |
| 23071 | ER_NON_GROUPING_FIELD_USED |
| 23072 | |
| 23073 | @retval |
| 23074 | 0 ok |
| 23075 | @retval |
| 23076 | 1 error (probably out of memory) |
| 23077 | */ |
| 23078 | |
| 23079 | int |
| 23080 | setup_group(THD *thd, Ref_ptr_array ref_pointer_array, TABLE_LIST *tables, |
| 23081 | List<Item> &fields, List<Item> &all_fields, ORDER *order, |
| 23082 | bool *hidden_group_fields, bool from_window_spec) |
| 23083 | { |
| 23084 | enum_parsing_place context_analysis_place= |
| 23085 | thd->lex->current_select->context_analysis_place; |
| 23086 | *hidden_group_fields=0; |
| 23087 | ORDER *ord; |
| 23088 | |
| 23089 | if (!order) |
| 23090 | return 0; /* Everything is ok */ |
| 23091 | |
| 23092 | uint org_fields=all_fields.elements; |
| 23093 | |
| 23094 | thd->where="group statement" ; |
| 23095 | for (ord= order; ord; ord= ord->next) |
| 23096 | { |
| 23097 | if (find_order_in_list(thd, ref_pointer_array, tables, ord, fields, |
| 23098 | all_fields, true, true, from_window_spec)) |
| 23099 | return 1; |
| 23100 | (*ord->item)->marker= UNDEF_POS; /* Mark found */ |
| 23101 | if ((*ord->item)->with_sum_func && context_analysis_place == IN_GROUP_BY) |
| 23102 | { |
| 23103 | my_error(ER_WRONG_GROUP_FIELD, MYF(0), (*ord->item)->full_name()); |
| 23104 | return 1; |
| 23105 | } |
| 23106 | if ((*ord->item)->with_window_func) |
| 23107 | { |
| 23108 | if (context_analysis_place == IN_GROUP_BY) |
| 23109 | my_error(ER_WRONG_PLACEMENT_OF_WINDOW_FUNCTION, MYF(0)); |
| 23110 | else |
| 23111 | my_error(ER_WINDOW_FUNCTION_IN_WINDOW_SPEC, MYF(0)); |
| 23112 | return 1; |
| 23113 | } |
| 23114 | } |
| 23115 | if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY) |
| 23116 | { |
| 23117 | /* |
| 23118 | Don't allow one to use fields that is not used in GROUP BY |
| 23119 | For each select a list of field references that aren't under an |
| 23120 | aggregate function is created. Each field in this list keeps the |
| 23121 | position of the select list expression which it belongs to. |
| 23122 | |
| 23123 | First we check an expression from the select list against the GROUP BY |
| 23124 | list. If it's found there then it's ok. It's also ok if this expression |
| 23125 | is a constant or an aggregate function. Otherwise we scan the list |
| 23126 | of non-aggregated fields and if we'll find at least one field reference |
| 23127 | that belongs to this expression and doesn't occur in the GROUP BY list |
| 23128 | we throw an error. If there are no fields in the created list for a |
| 23129 | select list expression this means that all fields in it are used under |
| 23130 | aggregate functions. |
| 23131 | */ |
| 23132 | Item *item; |
| 23133 | Item_field *field; |
| 23134 | int cur_pos_in_select_list= 0; |
| 23135 | List_iterator<Item> li(fields); |
| 23136 | List_iterator<Item_field> naf_it(thd->lex->current_select->join->non_agg_fields); |
| 23137 | |
| 23138 | field= naf_it++; |
| 23139 | while (field && (item=li++)) |
| 23140 | { |
| 23141 | if (item->type() != Item::SUM_FUNC_ITEM && item->marker >= 0 && |
| 23142 | !item->const_item() && |
| 23143 | !(item->real_item()->type() == Item::FIELD_ITEM && |
| 23144 | item->used_tables() & OUTER_REF_TABLE_BIT)) |
| 23145 | { |
| 23146 | while (field) |
| 23147 | { |
| 23148 | /* Skip fields from previous expressions. */ |
| 23149 | if (field->marker < cur_pos_in_select_list) |
| 23150 | goto next_field; |
| 23151 | /* Found a field from the next expression. */ |
| 23152 | if (field->marker > cur_pos_in_select_list) |
| 23153 | break; |
| 23154 | /* |
| 23155 | Check whether the field occur in the GROUP BY list. |
| 23156 | Throw the error later if the field isn't found. |
| 23157 | */ |
| 23158 | for (ord= order; ord; ord= ord->next) |
| 23159 | if ((*ord->item)->eq((Item*)field, 0)) |
| 23160 | goto next_field; |
| 23161 | /* |
| 23162 | TODO: change ER_WRONG_FIELD_WITH_GROUP to more detailed |
| 23163 | ER_NON_GROUPING_FIELD_USED |
| 23164 | */ |
| 23165 | my_error(ER_WRONG_FIELD_WITH_GROUP, MYF(0), field->full_name()); |
| 23166 | return 1; |
| 23167 | next_field: |
| 23168 | field= naf_it++; |
| 23169 | } |
| 23170 | } |
| 23171 | cur_pos_in_select_list++; |
| 23172 | } |
| 23173 | } |
| 23174 | if (org_fields != all_fields.elements) |
| 23175 | *hidden_group_fields=1; // group fields is not used |
| 23176 | return 0; |
| 23177 | } |
| 23178 | |
| 23179 | /** |
| 23180 | Add fields with aren't used at start of field list. |
| 23181 | |
| 23182 | @return |
| 23183 | FALSE if ok |
| 23184 | */ |
| 23185 | |
| 23186 | static bool |
| 23187 | setup_new_fields(THD *thd, List<Item> &fields, |
| 23188 | List<Item> &all_fields, ORDER *new_field) |
| 23189 | { |
| 23190 | Item **item; |
| 23191 | uint counter; |
| 23192 | enum_resolution_type not_used; |
| 23193 | DBUG_ENTER("setup_new_fields" ); |
| 23194 | |
| 23195 | thd->column_usage= MARK_COLUMNS_READ; // Not really needed, but... |
| 23196 | for (; new_field ; new_field= new_field->next) |
| 23197 | { |
| 23198 | if ((item= find_item_in_list(*new_field->item, fields, &counter, |
| 23199 | IGNORE_ERRORS, ¬_used))) |
| 23200 | new_field->item=item; /* Change to shared Item */ |
| 23201 | else |
| 23202 | { |
| 23203 | thd->where="procedure list" ; |
| 23204 | if ((*new_field->item)->fix_fields(thd, new_field->item)) |
| 23205 | DBUG_RETURN(1); /* purecov: inspected */ |
| 23206 | all_fields.push_front(*new_field->item, thd->mem_root); |
| 23207 | new_field->item=all_fields.head_ref(); |
| 23208 | } |
| 23209 | } |
| 23210 | DBUG_RETURN(0); |
| 23211 | } |
| 23212 | |
| 23213 | /** |
| 23214 | Create a group by that consist of all non const fields. |
| 23215 | |
| 23216 | Try to use the fields in the order given by 'order' to allow one to |
| 23217 | optimize away 'order by'. |
| 23218 | |
| 23219 | @retval |
| 23220 | 0 OOM error if thd->is_fatal_error is set. Otherwise group was eliminated |
| 23221 | # Pointer to new group |
| 23222 | */ |
| 23223 | |
| 23224 | ORDER * |
| 23225 | create_distinct_group(THD *thd, Ref_ptr_array ref_pointer_array, |
| 23226 | ORDER *order_list, List<Item> &fields, |
| 23227 | List<Item> &all_fields, |
| 23228 | bool *all_order_by_fields_used) |
| 23229 | { |
| 23230 | List_iterator<Item> li(fields); |
| 23231 | Item *item; |
| 23232 | Ref_ptr_array orig_ref_pointer_array= ref_pointer_array; |
| 23233 | ORDER *order,*group,**prev; |
| 23234 | uint idx= 0; |
| 23235 | |
| 23236 | *all_order_by_fields_used= 1; |
| 23237 | while ((item=li++)) |
| 23238 | item->marker=0; /* Marker that field is not used */ |
| 23239 | |
| 23240 | prev= &group; group=0; |
| 23241 | for (order=order_list ; order; order=order->next) |
| 23242 | { |
| 23243 | if (order->in_field_list) |
| 23244 | { |
| 23245 | ORDER *ord=(ORDER*) thd->memdup((char*) order,sizeof(ORDER)); |
| 23246 | if (!ord) |
| 23247 | return 0; |
| 23248 | *prev=ord; |
| 23249 | prev= &ord->next; |
| 23250 | (*ord->item)->marker=1; |
| 23251 | } |
| 23252 | else |
| 23253 | *all_order_by_fields_used= 0; |
| 23254 | } |
| 23255 | |
| 23256 | li.rewind(); |
| 23257 | while ((item=li++)) |
| 23258 | { |
| 23259 | if (!item->const_item() && !item->with_sum_func && !item->marker) |
| 23260 | { |
| 23261 | /* |
| 23262 | Don't put duplicate columns from the SELECT list into the |
| 23263 | GROUP BY list. |
| 23264 | */ |
| 23265 | ORDER *ord_iter; |
| 23266 | for (ord_iter= group; ord_iter; ord_iter= ord_iter->next) |
| 23267 | if ((*ord_iter->item)->eq(item, 1)) |
| 23268 | goto next_item; |
| 23269 | |
| 23270 | ORDER *ord=(ORDER*) thd->calloc(sizeof(ORDER)); |
| 23271 | if (!ord) |
| 23272 | return 0; |
| 23273 | |
| 23274 | if (item->type() == Item::FIELD_ITEM && |
| 23275 | item->field_type() == MYSQL_TYPE_BIT) |
| 23276 | { |
| 23277 | /* |
| 23278 | Because HEAP tables can't index BIT fields we need to use an |
| 23279 | additional hidden field for grouping because later it will be |
| 23280 | converted to a LONG field. Original field will remain of the |
| 23281 | BIT type and will be returned [el]client. |
| 23282 | */ |
| 23283 | Item_field *new_item= new (thd->mem_root) Item_field(thd, (Item_field*)item); |
| 23284 | if (!new_item) |
| 23285 | return 0; |
| 23286 | int el= all_fields.elements; |
| 23287 | orig_ref_pointer_array[el]= new_item; |
| 23288 | all_fields.push_front(new_item, thd->mem_root); |
| 23289 | ord->item=&orig_ref_pointer_array[el]; |
| 23290 | } |
| 23291 | else |
| 23292 | { |
| 23293 | /* |
| 23294 | We have here only field_list (not all_field_list), so we can use |
| 23295 | simple indexing of ref_pointer_array (order in the array and in the |
| 23296 | list are same) |
| 23297 | */ |
| 23298 | ord->item= &ref_pointer_array[idx]; |
| 23299 | } |
| 23300 | ord->direction= ORDER::ORDER_ASC; |
| 23301 | *prev=ord; |
| 23302 | prev= &ord->next; |
| 23303 | } |
| 23304 | next_item: |
| 23305 | idx++; |
| 23306 | } |
| 23307 | *prev=0; |
| 23308 | return group; |
| 23309 | } |
| 23310 | |
| 23311 | |
| 23312 | /** |
| 23313 | Update join with count of the different type of fields. |
| 23314 | */ |
| 23315 | |
| 23316 | void |
| 23317 | count_field_types(SELECT_LEX *select_lex, TMP_TABLE_PARAM *param, |
| 23318 | List<Item> &fields, bool reset_with_sum_func) |
| 23319 | { |
| 23320 | List_iterator<Item> li(fields); |
| 23321 | Item *field; |
| 23322 | |
| 23323 | param->field_count=param->sum_func_count=param->func_count= |
| 23324 | param->hidden_field_count=0; |
| 23325 | param->quick_group=1; |
| 23326 | while ((field=li++)) |
| 23327 | { |
| 23328 | Item::Type real_type= field->real_item()->type(); |
| 23329 | if (real_type == Item::FIELD_ITEM) |
| 23330 | param->field_count++; |
| 23331 | else if (real_type == Item::SUM_FUNC_ITEM) |
| 23332 | { |
| 23333 | if (! field->const_item()) |
| 23334 | { |
| 23335 | Item_sum *sum_item=(Item_sum*) field->real_item(); |
| 23336 | if (!sum_item->depended_from() || |
| 23337 | sum_item->depended_from() == select_lex) |
| 23338 | { |
| 23339 | if (!sum_item->quick_group) |
| 23340 | param->quick_group=0; // UDF SUM function |
| 23341 | param->sum_func_count++; |
| 23342 | |
| 23343 | for (uint i=0 ; i < sum_item->get_arg_count() ; i++) |
| 23344 | { |
| 23345 | if (sum_item->get_arg(i)->real_item()->type() == Item::FIELD_ITEM) |
| 23346 | param->field_count++; |
| 23347 | else |
| 23348 | param->func_count++; |
| 23349 | } |
| 23350 | } |
| 23351 | param->func_count++; |
| 23352 | } |
| 23353 | } |
| 23354 | else |
| 23355 | { |
| 23356 | param->func_count++; |
| 23357 | if (reset_with_sum_func) |
| 23358 | field->with_sum_func=0; |
| 23359 | } |
| 23360 | } |
| 23361 | } |
| 23362 | |
| 23363 | |
| 23364 | /** |
| 23365 | Return 1 if second is a subpart of first argument. |
| 23366 | |
| 23367 | If first parts has different direction, change it to second part |
| 23368 | (group is sorted like order) |
| 23369 | */ |
| 23370 | |
| 23371 | static bool |
| 23372 | test_if_subpart(ORDER *a,ORDER *b) |
| 23373 | { |
| 23374 | for (; a && b; a=a->next,b=b->next) |
| 23375 | { |
| 23376 | if ((*a->item)->eq(*b->item,1)) |
| 23377 | a->direction=b->direction; |
| 23378 | else |
| 23379 | return 0; |
| 23380 | } |
| 23381 | return MY_TEST(!b); |
| 23382 | } |
| 23383 | |
| 23384 | /** |
| 23385 | Return table number if there is only one table in sort order |
| 23386 | and group and order is compatible, else return 0. |
| 23387 | */ |
| 23388 | |
| 23389 | static TABLE * |
| 23390 | get_sort_by_table(ORDER *a,ORDER *b, List<TABLE_LIST> &tables, |
| 23391 | table_map const_tables) |
| 23392 | { |
| 23393 | TABLE_LIST *table; |
| 23394 | List_iterator<TABLE_LIST> ti(tables); |
| 23395 | table_map map= (table_map) 0; |
| 23396 | DBUG_ENTER("get_sort_by_table" ); |
| 23397 | |
| 23398 | if (!a) |
| 23399 | a=b; // Only one need to be given |
| 23400 | else if (!b) |
| 23401 | b=a; |
| 23402 | |
| 23403 | for (; a && b; a=a->next,b=b->next) |
| 23404 | { |
| 23405 | /* Skip elements of a that are constant */ |
| 23406 | while (!((*a->item)->used_tables() & ~const_tables)) |
| 23407 | { |
| 23408 | if (!(a= a->next)) |
| 23409 | break; |
| 23410 | } |
| 23411 | |
| 23412 | /* Skip elements of b that are constant */ |
| 23413 | while (!((*b->item)->used_tables() & ~const_tables)) |
| 23414 | { |
| 23415 | if (!(b= b->next)) |
| 23416 | break; |
| 23417 | } |
| 23418 | |
| 23419 | if (!a || !b) |
| 23420 | break; |
| 23421 | |
| 23422 | if (!(*a->item)->eq(*b->item,1)) |
| 23423 | DBUG_RETURN(0); |
| 23424 | map|=a->item[0]->used_tables(); |
| 23425 | } |
| 23426 | if (!map || (map & (RAND_TABLE_BIT | OUTER_REF_TABLE_BIT))) |
| 23427 | DBUG_RETURN(0); |
| 23428 | |
| 23429 | map&= ~const_tables; |
| 23430 | while ((table= ti++) && !(map & table->table->map)) ; |
| 23431 | if (map != table->table->map) |
| 23432 | DBUG_RETURN(0); // More than one table |
| 23433 | DBUG_PRINT("exit" ,("sort by table: %d" ,table->table->tablenr)); |
| 23434 | DBUG_RETURN(table->table); |
| 23435 | } |
| 23436 | |
| 23437 | |
| 23438 | /** |
| 23439 | calc how big buffer we need for comparing group entries. |
| 23440 | */ |
| 23441 | |
| 23442 | void calc_group_buffer(TMP_TABLE_PARAM *param, ORDER *group) |
| 23443 | { |
| 23444 | uint key_length=0, parts=0, null_parts=0; |
| 23445 | |
| 23446 | for (; group ; group=group->next) |
| 23447 | { |
| 23448 | Item *group_item= *group->item; |
| 23449 | Field *field= group_item->get_tmp_table_field(); |
| 23450 | if (field) |
| 23451 | { |
| 23452 | enum_field_types type; |
| 23453 | if ((type= field->type()) == MYSQL_TYPE_BLOB) |
| 23454 | key_length+=MAX_BLOB_WIDTH; // Can't be used as a key |
| 23455 | else if (type == MYSQL_TYPE_VARCHAR || type == MYSQL_TYPE_VAR_STRING) |
| 23456 | key_length+= field->field_length + HA_KEY_BLOB_LENGTH; |
| 23457 | else if (type == MYSQL_TYPE_BIT) |
| 23458 | { |
| 23459 | /* Bit is usually stored as a longlong key for group fields */ |
| 23460 | key_length+= 8; // Big enough |
| 23461 | } |
| 23462 | else |
| 23463 | key_length+= field->pack_length(); |
| 23464 | } |
| 23465 | else |
| 23466 | { |
| 23467 | switch (group_item->cmp_type()) { |
| 23468 | case REAL_RESULT: |
| 23469 | key_length+= sizeof(double); |
| 23470 | break; |
| 23471 | case INT_RESULT: |
| 23472 | key_length+= sizeof(longlong); |
| 23473 | break; |
| 23474 | case DECIMAL_RESULT: |
| 23475 | key_length+= my_decimal_get_binary_size(group_item->max_length - |
| 23476 | (group_item->decimals ? 1 : 0), |
| 23477 | group_item->decimals); |
| 23478 | break; |
| 23479 | case TIME_RESULT: |
| 23480 | { |
| 23481 | /* |
| 23482 | As items represented as DATE/TIME fields in the group buffer |
| 23483 | have STRING_RESULT result type, we increase the length |
| 23484 | by 8 as maximum pack length of such fields. |
| 23485 | */ |
| 23486 | key_length+= 8; |
| 23487 | break; |
| 23488 | } |
| 23489 | case STRING_RESULT: |
| 23490 | { |
| 23491 | enum enum_field_types type= group_item->field_type(); |
| 23492 | if (type == MYSQL_TYPE_BLOB) |
| 23493 | key_length+= MAX_BLOB_WIDTH; // Can't be used as a key |
| 23494 | else |
| 23495 | { |
| 23496 | /* |
| 23497 | Group strings are taken as varstrings and require an length field. |
| 23498 | A field is not yet created by create_tmp_field() |
| 23499 | and the sizes should match up. |
| 23500 | */ |
| 23501 | key_length+= group_item->max_length + HA_KEY_BLOB_LENGTH; |
| 23502 | } |
| 23503 | break; |
| 23504 | } |
| 23505 | default: |
| 23506 | /* This case should never be choosen */ |
| 23507 | DBUG_ASSERT(0); |
| 23508 | my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR)); |
| 23509 | } |
| 23510 | } |
| 23511 | parts++; |
| 23512 | if (group_item->maybe_null) |
| 23513 | null_parts++; |
| 23514 | } |
| 23515 | param->group_length= key_length + null_parts; |
| 23516 | param->group_parts= parts; |
| 23517 | param->group_null_parts= null_parts; |
| 23518 | } |
| 23519 | |
| 23520 | static void calc_group_buffer(JOIN *join, ORDER *group) |
| 23521 | { |
| 23522 | if (group) |
| 23523 | join->group= 1; |
| 23524 | calc_group_buffer(&join->tmp_table_param, group); |
| 23525 | } |
| 23526 | |
| 23527 | |
| 23528 | /** |
| 23529 | allocate group fields or take prepared (cached). |
| 23530 | |
| 23531 | @param main_join join of current select |
| 23532 | @param curr_join current join (join of current select or temporary copy |
| 23533 | of it) |
| 23534 | |
| 23535 | @retval |
| 23536 | 0 ok |
| 23537 | @retval |
| 23538 | 1 failed |
| 23539 | */ |
| 23540 | |
| 23541 | static bool |
| 23542 | make_group_fields(JOIN *main_join, JOIN *curr_join) |
| 23543 | { |
| 23544 | if (main_join->group_fields_cache.elements) |
| 23545 | { |
| 23546 | curr_join->group_fields= main_join->group_fields_cache; |
| 23547 | curr_join->sort_and_group= 1; |
| 23548 | } |
| 23549 | else |
| 23550 | { |
| 23551 | if (alloc_group_fields(curr_join, curr_join->group_list)) |
| 23552 | return (1); |
| 23553 | main_join->group_fields_cache= curr_join->group_fields; |
| 23554 | } |
| 23555 | return (0); |
| 23556 | } |
| 23557 | |
| 23558 | |
| 23559 | /** |
| 23560 | Get a list of buffers for saving last group. |
| 23561 | |
| 23562 | Groups are saved in reverse order for easier check loop. |
| 23563 | */ |
| 23564 | |
| 23565 | static bool |
| 23566 | alloc_group_fields(JOIN *join,ORDER *group) |
| 23567 | { |
| 23568 | if (group) |
| 23569 | { |
| 23570 | for (; group ; group=group->next) |
| 23571 | { |
| 23572 | Cached_item *tmp=new_Cached_item(join->thd, *group->item, TRUE); |
| 23573 | if (!tmp || join->group_fields.push_front(tmp)) |
| 23574 | return TRUE; |
| 23575 | } |
| 23576 | } |
| 23577 | join->sort_and_group=1; /* Mark for do_select */ |
| 23578 | return FALSE; |
| 23579 | } |
| 23580 | |
| 23581 | |
| 23582 | |
| 23583 | /* |
| 23584 | Test if a single-row cache of items changed, and update the cache. |
| 23585 | |
| 23586 | @details Test if a list of items that typically represents a result |
| 23587 | row has changed. If the value of some item changed, update the cached |
| 23588 | value for this item. |
| 23589 | |
| 23590 | @param list list of <item, cached_value> pairs stored as Cached_item. |
| 23591 | |
| 23592 | @return -1 if no item changed |
| 23593 | @return index of the first item that changed |
| 23594 | */ |
| 23595 | |
| 23596 | int test_if_item_cache_changed(List<Cached_item> &list) |
| 23597 | { |
| 23598 | DBUG_ENTER("test_if_item_cache_changed" ); |
| 23599 | List_iterator<Cached_item> li(list); |
| 23600 | int idx= -1,i; |
| 23601 | Cached_item *buff; |
| 23602 | |
| 23603 | for (i=(int) list.elements-1 ; (buff=li++) ; i--) |
| 23604 | { |
| 23605 | if (buff->cmp()) |
| 23606 | idx=i; |
| 23607 | } |
| 23608 | DBUG_PRINT("info" , ("idx: %d" , idx)); |
| 23609 | DBUG_RETURN(idx); |
| 23610 | } |
| 23611 | |
| 23612 | |
| 23613 | /* |
| 23614 | @return |
| 23615 | -1 - Group not changed |
| 23616 | value>=0 - Number of the component where the group changed |
| 23617 | */ |
| 23618 | |
| 23619 | int |
| 23620 | test_if_group_changed(List<Cached_item> &list) |
| 23621 | { |
| 23622 | DBUG_ENTER("test_if_group_changed" ); |
| 23623 | List_iterator<Cached_item> li(list); |
| 23624 | int idx= -1,i; |
| 23625 | Cached_item *buff; |
| 23626 | |
| 23627 | for (i=(int) list.elements-1 ; (buff=li++) ; i--) |
| 23628 | { |
| 23629 | if (buff->cmp()) |
| 23630 | idx=i; |
| 23631 | } |
| 23632 | DBUG_PRINT("info" , ("idx: %d" , idx)); |
| 23633 | DBUG_RETURN(idx); |
| 23634 | } |
| 23635 | |
| 23636 | |
| 23637 | /** |
| 23638 | Setup copy_fields to save fields at start of new group. |
| 23639 | |
| 23640 | Setup copy_fields to save fields at start of new group |
| 23641 | |
| 23642 | Only FIELD_ITEM:s and FUNC_ITEM:s needs to be saved between groups. |
| 23643 | Change old item_field to use a new field with points at saved fieldvalue |
| 23644 | This function is only called before use of send_result_set_metadata. |
| 23645 | |
| 23646 | @param thd THD pointer |
| 23647 | @param param temporary table parameters |
| 23648 | @param ref_pointer_array array of pointers to top elements of filed list |
| 23649 | @param res_selected_fields new list of items of select item list |
| 23650 | @param res_all_fields new list of all items |
| 23651 | @param elements number of elements in select item list |
| 23652 | @param all_fields all fields list |
| 23653 | |
| 23654 | @todo |
| 23655 | In most cases this result will be sent to the user. |
| 23656 | This should be changed to use copy_int or copy_real depending |
| 23657 | on how the value is to be used: In some cases this may be an |
| 23658 | argument in a group function, like: IF(ISNULL(col),0,COUNT(*)) |
| 23659 | |
| 23660 | @retval |
| 23661 | 0 ok |
| 23662 | @retval |
| 23663 | !=0 error |
| 23664 | */ |
| 23665 | |
| 23666 | bool |
| 23667 | setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param, |
| 23668 | Ref_ptr_array ref_pointer_array, |
| 23669 | List<Item> &res_selected_fields, List<Item> &res_all_fields, |
| 23670 | uint elements, List<Item> &all_fields) |
| 23671 | { |
| 23672 | Item *pos; |
| 23673 | List_iterator_fast<Item> li(all_fields); |
| 23674 | Copy_field *copy= NULL; |
| 23675 | Copy_field *copy_start __attribute__((unused)); |
| 23676 | res_selected_fields.empty(); |
| 23677 | res_all_fields.empty(); |
| 23678 | List_iterator_fast<Item> itr(res_all_fields); |
| 23679 | List<Item> ; |
| 23680 | uint i, border= all_fields.elements - elements; |
| 23681 | DBUG_ENTER("setup_copy_fields" ); |
| 23682 | |
| 23683 | if (param->field_count && |
| 23684 | !(copy=param->copy_field= new (thd->mem_root) Copy_field[param->field_count])) |
| 23685 | goto err2; |
| 23686 | |
| 23687 | param->copy_funcs.empty(); |
| 23688 | copy_start= copy; |
| 23689 | for (i= 0; (pos= li++); i++) |
| 23690 | { |
| 23691 | Field *field; |
| 23692 | uchar *tmp; |
| 23693 | Item *real_pos= pos->real_item(); |
| 23694 | /* |
| 23695 | Aggregate functions can be substituted for fields (by e.g. temp tables). |
| 23696 | We need to filter those substituted fields out. |
| 23697 | */ |
| 23698 | if (real_pos->type() == Item::FIELD_ITEM && |
| 23699 | !(real_pos != pos && |
| 23700 | ((Item_ref *)pos)->ref_type() == Item_ref::AGGREGATE_REF)) |
| 23701 | { |
| 23702 | Item_field *item; |
| 23703 | if (!(item= new (thd->mem_root) Item_field(thd, ((Item_field*) real_pos)))) |
| 23704 | goto err; |
| 23705 | if (pos->type() == Item::REF_ITEM) |
| 23706 | { |
| 23707 | /* preserve the names of the ref when dereferncing */ |
| 23708 | Item_ref *ref= (Item_ref *) pos; |
| 23709 | item->db_name= ref->db_name; |
| 23710 | item->table_name= ref->table_name; |
| 23711 | item->name= ref->name; |
| 23712 | } |
| 23713 | pos= item; |
| 23714 | if (item->field->flags & BLOB_FLAG) |
| 23715 | { |
| 23716 | if (!(pos= new (thd->mem_root) Item_copy_string(thd, pos))) |
| 23717 | goto err; |
| 23718 | /* |
| 23719 | Item_copy_string::copy for function can call |
| 23720 | Item_copy_string::val_int for blob via Item_ref. |
| 23721 | But if Item_copy_string::copy for blob isn't called before, |
| 23722 | it's value will be wrong |
| 23723 | so let's insert Item_copy_string for blobs in the beginning of |
| 23724 | copy_funcs |
| 23725 | (to see full test case look at having.test, BUG #4358) |
| 23726 | */ |
| 23727 | if (param->copy_funcs.push_front(pos, thd->mem_root)) |
| 23728 | goto err; |
| 23729 | } |
| 23730 | else |
| 23731 | { |
| 23732 | /* |
| 23733 | set up save buffer and change result_field to point at |
| 23734 | saved value |
| 23735 | */ |
| 23736 | field= item->field; |
| 23737 | item->result_field=field->make_new_field(thd->mem_root, |
| 23738 | field->table, 1); |
| 23739 | /* |
| 23740 | We need to allocate one extra byte for null handling and |
| 23741 | another extra byte to not get warnings from purify in |
| 23742 | Field_string::val_int |
| 23743 | */ |
| 23744 | if (!(tmp= (uchar*) thd->alloc(field->pack_length()+2))) |
| 23745 | goto err; |
| 23746 | if (copy) |
| 23747 | { |
| 23748 | DBUG_ASSERT (param->field_count > (uint) (copy - copy_start)); |
| 23749 | copy->set(tmp, item->result_field); |
| 23750 | item->result_field->move_field(copy->to_ptr,copy->to_null_ptr,1); |
| 23751 | #ifdef HAVE_valgrind |
| 23752 | copy->to_ptr[copy->from_length]= 0; |
| 23753 | #endif |
| 23754 | copy++; |
| 23755 | } |
| 23756 | } |
| 23757 | } |
| 23758 | else if ((real_pos->type() == Item::FUNC_ITEM || |
| 23759 | real_pos->real_type() == Item::SUBSELECT_ITEM || |
| 23760 | real_pos->type() == Item::CACHE_ITEM || |
| 23761 | real_pos->type() == Item::COND_ITEM) && |
| 23762 | !real_pos->with_sum_func) |
| 23763 | { // Save for send fields |
| 23764 | pos= real_pos; |
| 23765 | /* TODO: |
| 23766 | In most cases this result will be sent to the user. |
| 23767 | This should be changed to use copy_int or copy_real depending |
| 23768 | on how the value is to be used: In some cases this may be an |
| 23769 | argument in a group function, like: IF(ISNULL(col),0,COUNT(*)) |
| 23770 | */ |
| 23771 | if (!(pos=new (thd->mem_root) Item_copy_string(thd, pos))) |
| 23772 | goto err; |
| 23773 | if (i < border) // HAVING, ORDER and GROUP BY |
| 23774 | { |
| 23775 | if (extra_funcs.push_back(pos, thd->mem_root)) |
| 23776 | goto err; |
| 23777 | } |
| 23778 | else if (param->copy_funcs.push_back(pos, thd->mem_root)) |
| 23779 | goto err; |
| 23780 | } |
| 23781 | res_all_fields.push_back(pos, thd->mem_root); |
| 23782 | ref_pointer_array[((i < border)? all_fields.elements-i-1 : i-border)]= |
| 23783 | pos; |
| 23784 | } |
| 23785 | param->copy_field_end= copy; |
| 23786 | |
| 23787 | for (i= 0; i < border; i++) |
| 23788 | itr++; |
| 23789 | itr.sublist(res_selected_fields, elements); |
| 23790 | /* |
| 23791 | Put elements from HAVING, ORDER BY and GROUP BY last to ensure that any |
| 23792 | reference used in these will resolve to a item that is already calculated |
| 23793 | */ |
| 23794 | param->copy_funcs.append(&extra_funcs); |
| 23795 | |
| 23796 | DBUG_RETURN(0); |
| 23797 | |
| 23798 | err: |
| 23799 | if (copy) |
| 23800 | delete [] param->copy_field; // This is never 0 |
| 23801 | param->copy_field= 0; |
| 23802 | err2: |
| 23803 | DBUG_RETURN(TRUE); |
| 23804 | } |
| 23805 | |
| 23806 | |
| 23807 | /** |
| 23808 | Make a copy of all simple SELECT'ed items. |
| 23809 | |
| 23810 | This is done at the start of a new group so that we can retrieve |
| 23811 | these later when the group changes. |
| 23812 | */ |
| 23813 | |
| 23814 | void |
| 23815 | copy_fields(TMP_TABLE_PARAM *param) |
| 23816 | { |
| 23817 | Copy_field *ptr=param->copy_field; |
| 23818 | Copy_field *end=param->copy_field_end; |
| 23819 | |
| 23820 | DBUG_ASSERT((ptr != NULL && end >= ptr) || (ptr == NULL && end == NULL)); |
| 23821 | |
| 23822 | for (; ptr != end; ptr++) |
| 23823 | (*ptr->do_copy)(ptr); |
| 23824 | |
| 23825 | List_iterator_fast<Item> it(param->copy_funcs); |
| 23826 | Item_copy_string *item; |
| 23827 | while ((item = (Item_copy_string*) it++)) |
| 23828 | item->copy(); |
| 23829 | } |
| 23830 | |
| 23831 | |
| 23832 | /** |
| 23833 | Make an array of pointers to sum_functions to speed up |
| 23834 | sum_func calculation. |
| 23835 | |
| 23836 | @retval |
| 23837 | 0 ok |
| 23838 | @retval |
| 23839 | 1 Error |
| 23840 | */ |
| 23841 | |
| 23842 | bool JOIN::alloc_func_list() |
| 23843 | { |
| 23844 | uint func_count, group_parts; |
| 23845 | DBUG_ENTER("alloc_func_list" ); |
| 23846 | |
| 23847 | func_count= tmp_table_param.sum_func_count; |
| 23848 | /* |
| 23849 | If we are using rollup, we need a copy of the summary functions for |
| 23850 | each level |
| 23851 | */ |
| 23852 | if (rollup.state != ROLLUP::STATE_NONE) |
| 23853 | func_count*= (send_group_parts+1); |
| 23854 | |
| 23855 | group_parts= send_group_parts; |
| 23856 | /* |
| 23857 | If distinct, reserve memory for possible |
| 23858 | disctinct->group_by optimization |
| 23859 | */ |
| 23860 | if (select_distinct) |
| 23861 | { |
| 23862 | group_parts+= fields_list.elements; |
| 23863 | /* |
| 23864 | If the ORDER clause is specified then it's possible that |
| 23865 | it also will be optimized, so reserve space for it too |
| 23866 | */ |
| 23867 | if (order) |
| 23868 | { |
| 23869 | ORDER *ord; |
| 23870 | for (ord= order; ord; ord= ord->next) |
| 23871 | group_parts++; |
| 23872 | } |
| 23873 | } |
| 23874 | |
| 23875 | /* This must use calloc() as rollup_make_fields depends on this */ |
| 23876 | sum_funcs= (Item_sum**) thd->calloc(sizeof(Item_sum**) * (func_count+1) + |
| 23877 | sizeof(Item_sum***) * (group_parts+1)); |
| 23878 | sum_funcs_end= (Item_sum***) (sum_funcs+func_count+1); |
| 23879 | DBUG_RETURN(sum_funcs == 0); |
| 23880 | } |
| 23881 | |
| 23882 | |
| 23883 | /** |
| 23884 | Initialize 'sum_funcs' array with all Item_sum objects. |
| 23885 | |
| 23886 | @param field_list All items |
| 23887 | @param send_result_set_metadata Items in select list |
| 23888 | @param before_group_by Set to 1 if this is called before GROUP BY handling |
| 23889 | @param recompute Set to TRUE if sum_funcs must be recomputed |
| 23890 | |
| 23891 | @retval |
| 23892 | 0 ok |
| 23893 | @retval |
| 23894 | 1 error |
| 23895 | */ |
| 23896 | |
| 23897 | bool JOIN::make_sum_func_list(List<Item> &field_list, |
| 23898 | List<Item> &send_result_set_metadata, |
| 23899 | bool before_group_by, bool recompute) |
| 23900 | { |
| 23901 | List_iterator_fast<Item> it(field_list); |
| 23902 | Item_sum **func; |
| 23903 | Item *item; |
| 23904 | DBUG_ENTER("make_sum_func_list" ); |
| 23905 | |
| 23906 | if (*sum_funcs && !recompute) |
| 23907 | DBUG_RETURN(FALSE); /* We have already initialized sum_funcs. */ |
| 23908 | |
| 23909 | func= sum_funcs; |
| 23910 | while ((item=it++)) |
| 23911 | { |
| 23912 | if (item->type() == Item::SUM_FUNC_ITEM && !item->const_item() && |
| 23913 | (!((Item_sum*) item)->depended_from() || |
| 23914 | ((Item_sum *)item)->depended_from() == select_lex)) |
| 23915 | *func++= (Item_sum*) item; |
| 23916 | } |
| 23917 | if (before_group_by && rollup.state == ROLLUP::STATE_INITED) |
| 23918 | { |
| 23919 | rollup.state= ROLLUP::STATE_READY; |
| 23920 | if (rollup_make_fields(field_list, send_result_set_metadata, &func)) |
| 23921 | DBUG_RETURN(TRUE); // Should never happen |
| 23922 | } |
| 23923 | else if (rollup.state == ROLLUP::STATE_NONE) |
| 23924 | { |
| 23925 | for (uint i=0 ; i <= send_group_parts ;i++) |
| 23926 | sum_funcs_end[i]= func; |
| 23927 | } |
| 23928 | else if (rollup.state == ROLLUP::STATE_READY) |
| 23929 | DBUG_RETURN(FALSE); // Don't put end marker |
| 23930 | *func=0; // End marker |
| 23931 | DBUG_RETURN(FALSE); |
| 23932 | } |
| 23933 | |
| 23934 | |
| 23935 | /** |
| 23936 | Change all funcs and sum_funcs to fields in tmp table, and create |
| 23937 | new list of all items. |
| 23938 | |
| 23939 | @param thd THD pointer |
| 23940 | @param ref_pointer_array array of pointers to top elements of filed list |
| 23941 | @param res_selected_fields new list of items of select item list |
| 23942 | @param res_all_fields new list of all items |
| 23943 | @param elements number of elements in select item list |
| 23944 | @param all_fields all fields list |
| 23945 | |
| 23946 | @retval |
| 23947 | 0 ok |
| 23948 | @retval |
| 23949 | !=0 error |
| 23950 | */ |
| 23951 | |
| 23952 | static bool |
| 23953 | change_to_use_tmp_fields(THD *thd, Ref_ptr_array ref_pointer_array, |
| 23954 | List<Item> &res_selected_fields, |
| 23955 | List<Item> &res_all_fields, |
| 23956 | uint elements, List<Item> &all_fields) |
| 23957 | { |
| 23958 | List_iterator_fast<Item> it(all_fields); |
| 23959 | Item *item_field,*item; |
| 23960 | DBUG_ENTER("change_to_use_tmp_fields" ); |
| 23961 | |
| 23962 | res_selected_fields.empty(); |
| 23963 | res_all_fields.empty(); |
| 23964 | |
| 23965 | uint border= all_fields.elements - elements; |
| 23966 | for (uint i= 0; (item= it++); i++) |
| 23967 | { |
| 23968 | Field *field; |
| 23969 | if (item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM) |
| 23970 | item_field= item; |
| 23971 | else if (item->type() == Item::FIELD_ITEM) |
| 23972 | { |
| 23973 | if (!(item_field= item->get_tmp_table_item(thd))) |
| 23974 | DBUG_RETURN(true); |
| 23975 | } |
| 23976 | else if (item->type() == Item::FUNC_ITEM && |
| 23977 | ((Item_func*)item)->functype() == Item_func::SUSERVAR_FUNC) |
| 23978 | { |
| 23979 | field= item->get_tmp_table_field(); |
| 23980 | if (field != NULL) |
| 23981 | { |
| 23982 | /* |
| 23983 | Replace "@:=<expression>" with "@:=<tmp table |
| 23984 | column>". Otherwise, we would re-evaluate <expression>, and |
| 23985 | if expression were a subquery, this would access |
| 23986 | already-unlocked tables. |
| 23987 | */ |
| 23988 | Item_func_set_user_var* suv= |
| 23989 | new (thd->mem_root) Item_func_set_user_var(thd, (Item_func_set_user_var*) item); |
| 23990 | Item_field *new_field= new (thd->mem_root) Item_temptable_field(thd, field); |
| 23991 | if (!suv || !new_field) |
| 23992 | DBUG_RETURN(true); // Fatal error |
| 23993 | List<Item> list; |
| 23994 | list.push_back(new_field, thd->mem_root); |
| 23995 | suv->set_arguments(thd, list); |
| 23996 | item_field= suv; |
| 23997 | } |
| 23998 | else |
| 23999 | item_field= item; |
| 24000 | } |
| 24001 | else if ((field= item->get_tmp_table_field())) |
| 24002 | { |
| 24003 | if (item->type() == Item::SUM_FUNC_ITEM && field->table->group) |
| 24004 | item_field= ((Item_sum*) item)->result_item(thd, field); |
| 24005 | else |
| 24006 | item_field= (Item *) new (thd->mem_root) Item_temptable_field(thd, field); |
| 24007 | if (!item_field) |
| 24008 | DBUG_RETURN(true); // Fatal error |
| 24009 | |
| 24010 | if (item->real_item()->type() != Item::FIELD_ITEM) |
| 24011 | field->orig_table= 0; |
| 24012 | item_field->name= item->name; |
| 24013 | if (item->type() == Item::REF_ITEM) |
| 24014 | { |
| 24015 | Item_field *ifield= (Item_field *) item_field; |
| 24016 | Item_ref *iref= (Item_ref *) item; |
| 24017 | ifield->table_name= iref->table_name; |
| 24018 | ifield->db_name= iref->db_name; |
| 24019 | } |
| 24020 | #ifndef DBUG_OFF |
| 24021 | if (!item_field->name.str) |
| 24022 | { |
| 24023 | char buff[256]; |
| 24024 | String str(buff,sizeof(buff),&my_charset_bin); |
| 24025 | str.length(0); |
| 24026 | str.extra_allocation(1024); |
| 24027 | item->print(&str, QT_ORDINARY); |
| 24028 | item_field->name.str= thd->strmake(str.ptr(), str.length()); |
| 24029 | item_field->name.length= str.length(); |
| 24030 | } |
| 24031 | #endif |
| 24032 | } |
| 24033 | else |
| 24034 | item_field= item; |
| 24035 | |
| 24036 | res_all_fields.push_back(item_field, thd->mem_root); |
| 24037 | ref_pointer_array[((i < border)? all_fields.elements-i-1 : i-border)]= |
| 24038 | item_field; |
| 24039 | } |
| 24040 | |
| 24041 | List_iterator_fast<Item> itr(res_all_fields); |
| 24042 | for (uint i= 0; i < border; i++) |
| 24043 | itr++; |
| 24044 | itr.sublist(res_selected_fields, elements); |
| 24045 | DBUG_RETURN(false); |
| 24046 | } |
| 24047 | |
| 24048 | |
| 24049 | /** |
| 24050 | Change all sum_func refs to fields to point at fields in tmp table. |
| 24051 | Change all funcs to be fields in tmp table. |
| 24052 | |
| 24053 | @param thd THD pointer |
| 24054 | @param ref_pointer_array array of pointers to top elements of filed list |
| 24055 | @param res_selected_fields new list of items of select item list |
| 24056 | @param res_all_fields new list of all items |
| 24057 | @param elements number of elements in select item list |
| 24058 | @param all_fields all fields list |
| 24059 | |
| 24060 | @retval |
| 24061 | 0 ok |
| 24062 | @retval |
| 24063 | 1 error |
| 24064 | */ |
| 24065 | |
| 24066 | static bool |
| 24067 | change_refs_to_tmp_fields(THD *thd, Ref_ptr_array ref_pointer_array, |
| 24068 | List<Item> &res_selected_fields, |
| 24069 | List<Item> &res_all_fields, uint elements, |
| 24070 | List<Item> &all_fields) |
| 24071 | { |
| 24072 | List_iterator_fast<Item> it(all_fields); |
| 24073 | Item *item, *new_item; |
| 24074 | res_selected_fields.empty(); |
| 24075 | res_all_fields.empty(); |
| 24076 | |
| 24077 | uint i, border= all_fields.elements - elements; |
| 24078 | for (i= 0; (item= it++); i++) |
| 24079 | { |
| 24080 | if (item->type() == Item::SUM_FUNC_ITEM && item->const_item()) |
| 24081 | new_item= item; |
| 24082 | else |
| 24083 | { |
| 24084 | if (!(new_item= item->get_tmp_table_item(thd))) |
| 24085 | return 1; |
| 24086 | } |
| 24087 | |
| 24088 | if (res_all_fields.push_back(new_item, thd->mem_root)) |
| 24089 | return 1; |
| 24090 | ref_pointer_array[((i < border)? all_fields.elements-i-1 : i-border)]= |
| 24091 | new_item; |
| 24092 | } |
| 24093 | |
| 24094 | List_iterator_fast<Item> itr(res_all_fields); |
| 24095 | for (i= 0; i < border; i++) |
| 24096 | itr++; |
| 24097 | itr.sublist(res_selected_fields, elements); |
| 24098 | |
| 24099 | return thd->is_fatal_error; |
| 24100 | } |
| 24101 | |
| 24102 | |
| 24103 | |
| 24104 | /****************************************************************************** |
| 24105 | Code for calculating functions |
| 24106 | ******************************************************************************/ |
| 24107 | |
| 24108 | |
| 24109 | /** |
| 24110 | Call ::setup for all sum functions. |
| 24111 | |
| 24112 | @param thd thread handler |
| 24113 | @param func_ptr sum function list |
| 24114 | |
| 24115 | @retval |
| 24116 | FALSE ok |
| 24117 | @retval |
| 24118 | TRUE error |
| 24119 | */ |
| 24120 | |
| 24121 | static bool setup_sum_funcs(THD *thd, Item_sum **func_ptr) |
| 24122 | { |
| 24123 | Item_sum *func; |
| 24124 | DBUG_ENTER("setup_sum_funcs" ); |
| 24125 | while ((func= *(func_ptr++))) |
| 24126 | { |
| 24127 | if (func->aggregator_setup(thd)) |
| 24128 | DBUG_RETURN(TRUE); |
| 24129 | } |
| 24130 | DBUG_RETURN(FALSE); |
| 24131 | } |
| 24132 | |
| 24133 | |
| 24134 | static bool prepare_sum_aggregators(Item_sum **func_ptr, bool need_distinct) |
| 24135 | { |
| 24136 | Item_sum *func; |
| 24137 | DBUG_ENTER("prepare_sum_aggregators" ); |
| 24138 | while ((func= *(func_ptr++))) |
| 24139 | { |
| 24140 | if (func->set_aggregator(need_distinct && func->has_with_distinct() ? |
| 24141 | Aggregator::DISTINCT_AGGREGATOR : |
| 24142 | Aggregator::SIMPLE_AGGREGATOR)) |
| 24143 | DBUG_RETURN(TRUE); |
| 24144 | } |
| 24145 | DBUG_RETURN(FALSE); |
| 24146 | } |
| 24147 | |
| 24148 | |
| 24149 | static void |
| 24150 | init_tmptable_sum_functions(Item_sum **func_ptr) |
| 24151 | { |
| 24152 | Item_sum *func; |
| 24153 | while ((func= *(func_ptr++))) |
| 24154 | func->reset_field(); |
| 24155 | } |
| 24156 | |
| 24157 | |
| 24158 | /** Update record 0 in tmp_table from record 1. */ |
| 24159 | |
| 24160 | static void |
| 24161 | update_tmptable_sum_func(Item_sum **func_ptr, |
| 24162 | TABLE *tmp_table __attribute__((unused))) |
| 24163 | { |
| 24164 | Item_sum *func; |
| 24165 | while ((func= *(func_ptr++))) |
| 24166 | func->update_field(); |
| 24167 | } |
| 24168 | |
| 24169 | |
| 24170 | /** Copy result of sum functions to record in tmp_table. */ |
| 24171 | |
| 24172 | static void |
| 24173 | copy_sum_funcs(Item_sum **func_ptr, Item_sum **end_ptr) |
| 24174 | { |
| 24175 | for (; func_ptr != end_ptr ; func_ptr++) |
| 24176 | (void) (*func_ptr)->save_in_result_field(1); |
| 24177 | return; |
| 24178 | } |
| 24179 | |
| 24180 | |
| 24181 | static bool |
| 24182 | init_sum_functions(Item_sum **func_ptr, Item_sum **end_ptr) |
| 24183 | { |
| 24184 | for (; func_ptr != end_ptr ;func_ptr++) |
| 24185 | { |
| 24186 | if ((*func_ptr)->reset_and_add()) |
| 24187 | return 1; |
| 24188 | } |
| 24189 | /* If rollup, calculate the upper sum levels */ |
| 24190 | for ( ; *func_ptr ; func_ptr++) |
| 24191 | { |
| 24192 | if ((*func_ptr)->aggregator_add()) |
| 24193 | return 1; |
| 24194 | } |
| 24195 | return 0; |
| 24196 | } |
| 24197 | |
| 24198 | |
| 24199 | static bool |
| 24200 | update_sum_func(Item_sum **func_ptr) |
| 24201 | { |
| 24202 | Item_sum *func; |
| 24203 | for (; (func= (Item_sum*) *func_ptr) ; func_ptr++) |
| 24204 | if (func->aggregator_add()) |
| 24205 | return 1; |
| 24206 | return 0; |
| 24207 | } |
| 24208 | |
| 24209 | /** |
| 24210 | Copy result of functions to record in tmp_table. |
| 24211 | |
| 24212 | Uses the thread pointer to check for errors in |
| 24213 | some of the val_xxx() methods called by the |
| 24214 | save_in_result_field() function. |
| 24215 | TODO: make the Item::val_xxx() return error code |
| 24216 | |
| 24217 | @param func_ptr array of the function Items to copy to the tmp table |
| 24218 | @param thd pointer to the current thread for error checking |
| 24219 | @retval |
| 24220 | FALSE if OK |
| 24221 | @retval |
| 24222 | TRUE on error |
| 24223 | */ |
| 24224 | |
| 24225 | bool |
| 24226 | copy_funcs(Item **func_ptr, const THD *thd) |
| 24227 | { |
| 24228 | Item *func; |
| 24229 | for (; (func = *func_ptr) ; func_ptr++) |
| 24230 | { |
| 24231 | if (func->type() == Item::FUNC_ITEM && |
| 24232 | ((Item_func *) func)->with_window_func) |
| 24233 | continue; |
| 24234 | func->save_in_result_field(1); |
| 24235 | /* |
| 24236 | Need to check the THD error state because Item::val_xxx() don't |
| 24237 | return error code, but can generate errors |
| 24238 | TODO: change it for a real status check when Item::val_xxx() |
| 24239 | are extended to return status code. |
| 24240 | */ |
| 24241 | if (unlikely(thd->is_error())) |
| 24242 | return TRUE; |
| 24243 | } |
| 24244 | return FALSE; |
| 24245 | } |
| 24246 | |
| 24247 | |
| 24248 | /** |
| 24249 | Create a condition for a const reference and add this to the |
| 24250 | currenct select for the table. |
| 24251 | */ |
| 24252 | |
| 24253 | static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab) |
| 24254 | { |
| 24255 | DBUG_ENTER("add_ref_to_table_cond" ); |
| 24256 | if (!join_tab->ref.key_parts) |
| 24257 | DBUG_RETURN(FALSE); |
| 24258 | |
| 24259 | Item_cond_and *cond= new (thd->mem_root) Item_cond_and(thd); |
| 24260 | TABLE *table=join_tab->table; |
| 24261 | int error= 0; |
| 24262 | if (!cond) |
| 24263 | DBUG_RETURN(TRUE); |
| 24264 | |
| 24265 | for (uint i=0 ; i < join_tab->ref.key_parts ; i++) |
| 24266 | { |
| 24267 | Field *field=table->field[table->key_info[join_tab->ref.key].key_part[i]. |
| 24268 | fieldnr-1]; |
| 24269 | Item *value=join_tab->ref.items[i]; |
| 24270 | cond->add(new (thd->mem_root) |
| 24271 | Item_func_equal(thd, new (thd->mem_root) Item_field(thd, field), |
| 24272 | value), |
| 24273 | thd->mem_root); |
| 24274 | } |
| 24275 | if (unlikely(thd->is_fatal_error)) |
| 24276 | DBUG_RETURN(TRUE); |
| 24277 | if (!cond->fixed) |
| 24278 | { |
| 24279 | Item *tmp_item= (Item*) cond; |
| 24280 | cond->fix_fields(thd, &tmp_item); |
| 24281 | DBUG_ASSERT(cond == tmp_item); |
| 24282 | } |
| 24283 | if (join_tab->select) |
| 24284 | { |
| 24285 | Item *UNINIT_VAR(cond_copy); |
| 24286 | if (join_tab->select->pre_idx_push_select_cond) |
| 24287 | cond_copy= cond->copy_andor_structure(thd); |
| 24288 | if (join_tab->select->cond) |
| 24289 | error=(int) cond->add(join_tab->select->cond, thd->mem_root); |
| 24290 | join_tab->select->cond= cond; |
| 24291 | if (join_tab->select->pre_idx_push_select_cond) |
| 24292 | { |
| 24293 | Item *new_cond= and_conds(thd, cond_copy, |
| 24294 | join_tab->select->pre_idx_push_select_cond); |
| 24295 | if (!new_cond->fixed && new_cond->fix_fields(thd, &new_cond)) |
| 24296 | error= 1; |
| 24297 | join_tab->pre_idx_push_select_cond= |
| 24298 | join_tab->select->pre_idx_push_select_cond= new_cond; |
| 24299 | } |
| 24300 | join_tab->set_select_cond(cond, __LINE__); |
| 24301 | } |
| 24302 | else if ((join_tab->select= make_select(join_tab->table, 0, 0, cond, |
| 24303 | (SORT_INFO*) 0, 0, &error))) |
| 24304 | join_tab->set_select_cond(cond, __LINE__); |
| 24305 | |
| 24306 | DBUG_RETURN(error ? TRUE : FALSE); |
| 24307 | } |
| 24308 | |
| 24309 | |
| 24310 | /** |
| 24311 | Free joins of subselect of this select. |
| 24312 | |
| 24313 | @param thd THD pointer |
| 24314 | @param select pointer to st_select_lex which subselects joins we will free |
| 24315 | */ |
| 24316 | |
| 24317 | void free_underlaid_joins(THD *thd, SELECT_LEX *select) |
| 24318 | { |
| 24319 | for (SELECT_LEX_UNIT *unit= select->first_inner_unit(); |
| 24320 | unit; |
| 24321 | unit= unit->next_unit()) |
| 24322 | unit->cleanup(); |
| 24323 | } |
| 24324 | |
| 24325 | /**************************************************************************** |
| 24326 | ROLLUP handling |
| 24327 | ****************************************************************************/ |
| 24328 | |
| 24329 | /** |
| 24330 | Replace occurences of group by fields in an expression by ref items. |
| 24331 | |
| 24332 | The function replaces occurrences of group by fields in expr |
| 24333 | by ref objects for these fields unless they are under aggregate |
| 24334 | functions. |
| 24335 | The function also corrects value of the the maybe_null attribute |
| 24336 | for the items of all subexpressions containing group by fields. |
| 24337 | |
| 24338 | @b EXAMPLES |
| 24339 | @code |
| 24340 | SELECT a+1 FROM t1 GROUP BY a WITH ROLLUP |
| 24341 | SELECT SUM(a)+a FROM t1 GROUP BY a WITH ROLLUP |
| 24342 | @endcode |
| 24343 | |
| 24344 | @b IMPLEMENTATION |
| 24345 | |
| 24346 | The function recursively traverses the tree of the expr expression, |
| 24347 | looks for occurrences of the group by fields that are not under |
| 24348 | aggregate functions and replaces them for the corresponding ref items. |
| 24349 | |
| 24350 | @note |
| 24351 | This substitution is needed GROUP BY queries with ROLLUP if |
| 24352 | SELECT list contains expressions over group by attributes. |
| 24353 | |
| 24354 | @param thd reference to the context |
| 24355 | @param expr expression to make replacement |
| 24356 | @param group_list list of references to group by items |
| 24357 | @param changed out: returns 1 if item contains a replaced field item |
| 24358 | |
| 24359 | @todo |
| 24360 | - TODO: Some functions are not null-preserving. For those functions |
| 24361 | updating of the maybe_null attribute is an overkill. |
| 24362 | |
| 24363 | @retval |
| 24364 | 0 if ok |
| 24365 | @retval |
| 24366 | 1 on error |
| 24367 | */ |
| 24368 | |
| 24369 | static bool change_group_ref(THD *thd, Item_func *expr, ORDER *group_list, |
| 24370 | bool *changed) |
| 24371 | { |
| 24372 | if (expr->argument_count()) |
| 24373 | { |
| 24374 | Name_resolution_context *context= &thd->lex->current_select->context; |
| 24375 | Item **arg,**arg_end; |
| 24376 | bool arg_changed= FALSE; |
| 24377 | for (arg= expr->arguments(), |
| 24378 | arg_end= expr->arguments() + expr->argument_count(); |
| 24379 | arg != arg_end; arg++) |
| 24380 | { |
| 24381 | Item *item= *arg; |
| 24382 | if (item->type() == Item::FIELD_ITEM || item->type() == Item::REF_ITEM) |
| 24383 | { |
| 24384 | ORDER *group_tmp; |
| 24385 | for (group_tmp= group_list; group_tmp; group_tmp= group_tmp->next) |
| 24386 | { |
| 24387 | if (item->eq(*group_tmp->item,0)) |
| 24388 | { |
| 24389 | Item *new_item; |
| 24390 | if (!(new_item= new (thd->mem_root) Item_ref(thd, context, |
| 24391 | group_tmp->item, 0, |
| 24392 | &item->name))) |
| 24393 | return 1; // fatal_error is set |
| 24394 | thd->change_item_tree(arg, new_item); |
| 24395 | arg_changed= TRUE; |
| 24396 | } |
| 24397 | } |
| 24398 | } |
| 24399 | else if (item->type() == Item::FUNC_ITEM) |
| 24400 | { |
| 24401 | if (change_group_ref(thd, (Item_func *) item, group_list, &arg_changed)) |
| 24402 | return 1; |
| 24403 | } |
| 24404 | } |
| 24405 | if (arg_changed) |
| 24406 | { |
| 24407 | expr->maybe_null= 1; |
| 24408 | expr->in_rollup= 1; |
| 24409 | *changed= TRUE; |
| 24410 | } |
| 24411 | } |
| 24412 | return 0; |
| 24413 | } |
| 24414 | |
| 24415 | |
| 24416 | /** Allocate memory needed for other rollup functions. */ |
| 24417 | |
| 24418 | bool JOIN::rollup_init() |
| 24419 | { |
| 24420 | uint i,j; |
| 24421 | Item **ref_array; |
| 24422 | |
| 24423 | tmp_table_param.quick_group= 0; // Can't create groups in tmp table |
| 24424 | rollup.state= ROLLUP::STATE_INITED; |
| 24425 | |
| 24426 | /* |
| 24427 | Create pointers to the different sum function groups |
| 24428 | These are updated by rollup_make_fields() |
| 24429 | */ |
| 24430 | tmp_table_param.group_parts= send_group_parts; |
| 24431 | |
| 24432 | Item_null_result **null_items= |
| 24433 | static_cast<Item_null_result**>(thd->alloc(sizeof(Item*)*send_group_parts)); |
| 24434 | |
| 24435 | rollup.null_items= Item_null_array(null_items, send_group_parts); |
| 24436 | rollup.ref_pointer_arrays= |
| 24437 | static_cast<Ref_ptr_array*> |
| 24438 | (thd->alloc((sizeof(Ref_ptr_array) + |
| 24439 | all_fields.elements * sizeof(Item*)) * send_group_parts)); |
| 24440 | rollup.fields= |
| 24441 | static_cast<List<Item>*>(thd->alloc(sizeof(List<Item>) * send_group_parts)); |
| 24442 | |
| 24443 | if (!null_items || !rollup.ref_pointer_arrays || !rollup.fields) |
| 24444 | return true; |
| 24445 | |
| 24446 | ref_array= (Item**) (rollup.ref_pointer_arrays+send_group_parts); |
| 24447 | |
| 24448 | |
| 24449 | /* |
| 24450 | Prepare space for field list for the different levels |
| 24451 | These will be filled up in rollup_make_fields() |
| 24452 | */ |
| 24453 | for (i= 0 ; i < send_group_parts ; i++) |
| 24454 | { |
| 24455 | if (!(rollup.null_items[i]= new (thd->mem_root) Item_null_result(thd))) |
| 24456 | return true; |
| 24457 | |
| 24458 | List<Item> *rollup_fields= &rollup.fields[i]; |
| 24459 | rollup_fields->empty(); |
| 24460 | rollup.ref_pointer_arrays[i]= Ref_ptr_array(ref_array, all_fields.elements); |
| 24461 | ref_array+= all_fields.elements; |
| 24462 | } |
| 24463 | for (i= 0 ; i < send_group_parts; i++) |
| 24464 | { |
| 24465 | for (j=0 ; j < fields_list.elements ; j++) |
| 24466 | rollup.fields[i].push_back(rollup.null_items[i], thd->mem_root); |
| 24467 | } |
| 24468 | List_iterator<Item> it(all_fields); |
| 24469 | Item *item; |
| 24470 | while ((item= it++)) |
| 24471 | { |
| 24472 | ORDER *group_tmp; |
| 24473 | bool found_in_group= 0; |
| 24474 | |
| 24475 | for (group_tmp= group_list; group_tmp; group_tmp= group_tmp->next) |
| 24476 | { |
| 24477 | if (*group_tmp->item == item) |
| 24478 | { |
| 24479 | item->maybe_null= 1; |
| 24480 | item->in_rollup= 1; |
| 24481 | found_in_group= 1; |
| 24482 | break; |
| 24483 | } |
| 24484 | } |
| 24485 | if (item->type() == Item::FUNC_ITEM && !found_in_group) |
| 24486 | { |
| 24487 | bool changed= FALSE; |
| 24488 | if (change_group_ref(thd, (Item_func *) item, group_list, &changed)) |
| 24489 | return 1; |
| 24490 | /* |
| 24491 | We have to prevent creation of a field in a temporary table for |
| 24492 | an expression that contains GROUP BY attributes. |
| 24493 | Marking the expression item as 'with_sum_func' will ensure this. |
| 24494 | */ |
| 24495 | if (changed) |
| 24496 | item->with_sum_func= 1; |
| 24497 | } |
| 24498 | } |
| 24499 | return 0; |
| 24500 | } |
| 24501 | |
| 24502 | /** |
| 24503 | Wrap all constant Items in GROUP BY list. |
| 24504 | |
| 24505 | For ROLLUP queries each constant item referenced in GROUP BY list |
| 24506 | is wrapped up into an Item_func object yielding the same value |
| 24507 | as the constant item. The objects of the wrapper class are never |
| 24508 | considered as constant items and besides they inherit all |
| 24509 | properties of the Item_result_field class. |
| 24510 | This wrapping allows us to ensure writing constant items |
| 24511 | into temporary tables whenever the result of the ROLLUP |
| 24512 | operation has to be written into a temporary table, e.g. when |
| 24513 | ROLLUP is used together with DISTINCT in the SELECT list. |
| 24514 | Usually when creating temporary tables for a intermidiate |
| 24515 | result we do not include fields for constant expressions. |
| 24516 | |
| 24517 | @retval |
| 24518 | 0 if ok |
| 24519 | @retval |
| 24520 | 1 on error |
| 24521 | */ |
| 24522 | |
| 24523 | bool JOIN::rollup_process_const_fields() |
| 24524 | { |
| 24525 | ORDER *group_tmp; |
| 24526 | Item *item; |
| 24527 | List_iterator<Item> it(all_fields); |
| 24528 | |
| 24529 | for (group_tmp= group_list; group_tmp; group_tmp= group_tmp->next) |
| 24530 | { |
| 24531 | if (!(*group_tmp->item)->const_item()) |
| 24532 | continue; |
| 24533 | while ((item= it++)) |
| 24534 | { |
| 24535 | if (*group_tmp->item == item) |
| 24536 | { |
| 24537 | Item* new_item= new (thd->mem_root) Item_func_rollup_const(thd, item); |
| 24538 | if (!new_item) |
| 24539 | return 1; |
| 24540 | new_item->fix_fields(thd, (Item **) 0); |
| 24541 | thd->change_item_tree(it.ref(), new_item); |
| 24542 | for (ORDER *tmp= group_tmp; tmp; tmp= tmp->next) |
| 24543 | { |
| 24544 | if (*tmp->item == item) |
| 24545 | thd->change_item_tree(tmp->item, new_item); |
| 24546 | } |
| 24547 | break; |
| 24548 | } |
| 24549 | } |
| 24550 | it.rewind(); |
| 24551 | } |
| 24552 | return 0; |
| 24553 | } |
| 24554 | |
| 24555 | |
| 24556 | /** |
| 24557 | Fill up rollup structures with pointers to fields to use. |
| 24558 | |
| 24559 | Creates copies of item_sum items for each sum level. |
| 24560 | |
| 24561 | @param fields_arg List of all fields (hidden and real ones) |
| 24562 | @param sel_fields Pointer to selected fields |
| 24563 | @param func Store here a pointer to all fields |
| 24564 | |
| 24565 | @retval |
| 24566 | 0 if ok; |
| 24567 | In this case func is pointing to next not used element. |
| 24568 | @retval |
| 24569 | 1 on error |
| 24570 | */ |
| 24571 | |
| 24572 | bool JOIN::rollup_make_fields(List<Item> &fields_arg, List<Item> &sel_fields, |
| 24573 | Item_sum ***func) |
| 24574 | { |
| 24575 | List_iterator_fast<Item> it(fields_arg); |
| 24576 | Item *first_field= sel_fields.head(); |
| 24577 | uint level; |
| 24578 | |
| 24579 | /* |
| 24580 | Create field lists for the different levels |
| 24581 | |
| 24582 | The idea here is to have a separate field list for each rollup level to |
| 24583 | avoid all runtime checks of which columns should be NULL. |
| 24584 | |
| 24585 | The list is stored in reverse order to get sum function in such an order |
| 24586 | in func that it makes it easy to reset them with init_sum_functions() |
| 24587 | |
| 24588 | Assuming: SELECT a, b, c SUM(b) FROM t1 GROUP BY a,b WITH ROLLUP |
| 24589 | |
| 24590 | rollup.fields[0] will contain list where a,b,c is NULL |
| 24591 | rollup.fields[1] will contain list where b,c is NULL |
| 24592 | ... |
| 24593 | rollup.ref_pointer_array[#] points to fields for rollup.fields[#] |
| 24594 | ... |
| 24595 | sum_funcs_end[0] points to all sum functions |
| 24596 | sum_funcs_end[1] points to all sum functions, except grand totals |
| 24597 | ... |
| 24598 | */ |
| 24599 | |
| 24600 | for (level=0 ; level < send_group_parts ; level++) |
| 24601 | { |
| 24602 | uint i; |
| 24603 | uint pos= send_group_parts - level -1; |
| 24604 | bool real_fields= 0; |
| 24605 | Item *item; |
| 24606 | List_iterator<Item> new_it(rollup.fields[pos]); |
| 24607 | Ref_ptr_array ref_array_start= rollup.ref_pointer_arrays[pos]; |
| 24608 | ORDER *start_group; |
| 24609 | |
| 24610 | /* Point to first hidden field */ |
| 24611 | uint ref_array_ix= fields_arg.elements-1; |
| 24612 | |
| 24613 | |
| 24614 | /* Remember where the sum functions ends for the previous level */ |
| 24615 | sum_funcs_end[pos+1]= *func; |
| 24616 | |
| 24617 | /* Find the start of the group for this level */ |
| 24618 | for (i= 0, start_group= group_list ; |
| 24619 | i++ < pos ; |
| 24620 | start_group= start_group->next) |
| 24621 | ; |
| 24622 | |
| 24623 | it.rewind(); |
| 24624 | while ((item= it++)) |
| 24625 | { |
| 24626 | if (item == first_field) |
| 24627 | { |
| 24628 | real_fields= 1; // End of hidden fields |
| 24629 | ref_array_ix= 0; |
| 24630 | } |
| 24631 | |
| 24632 | if (item->type() == Item::SUM_FUNC_ITEM && !item->const_item() && |
| 24633 | (!((Item_sum*) item)->depended_from() || |
| 24634 | ((Item_sum *)item)->depended_from() == select_lex)) |
| 24635 | |
| 24636 | { |
| 24637 | /* |
| 24638 | This is a top level summary function that must be replaced with |
| 24639 | a sum function that is reset for this level. |
| 24640 | |
| 24641 | NOTE: This code creates an object which is not that nice in a |
| 24642 | sub select. Fortunately it's not common to have rollup in |
| 24643 | sub selects. |
| 24644 | */ |
| 24645 | item= item->copy_or_same(thd); |
| 24646 | ((Item_sum*) item)->make_unique(); |
| 24647 | *(*func)= (Item_sum*) item; |
| 24648 | (*func)++; |
| 24649 | } |
| 24650 | else |
| 24651 | { |
| 24652 | /* Check if this is something that is part of this group by */ |
| 24653 | ORDER *group_tmp; |
| 24654 | for (group_tmp= start_group, i= pos ; |
| 24655 | group_tmp ; group_tmp= group_tmp->next, i++) |
| 24656 | { |
| 24657 | if (*group_tmp->item == item) |
| 24658 | { |
| 24659 | /* |
| 24660 | This is an element that is used by the GROUP BY and should be |
| 24661 | set to NULL in this level |
| 24662 | */ |
| 24663 | Item_null_result *null_item= new (thd->mem_root) Item_null_result(thd); |
| 24664 | if (!null_item) |
| 24665 | return 1; |
| 24666 | item->maybe_null= 1; // Value will be null sometimes |
| 24667 | null_item->result_field= item->get_tmp_table_field(); |
| 24668 | item= null_item; |
| 24669 | break; |
| 24670 | } |
| 24671 | } |
| 24672 | } |
| 24673 | ref_array_start[ref_array_ix]= item; |
| 24674 | if (real_fields) |
| 24675 | { |
| 24676 | (void) new_it++; // Point to next item |
| 24677 | new_it.replace(item); // Replace previous |
| 24678 | ref_array_ix++; |
| 24679 | } |
| 24680 | else |
| 24681 | ref_array_ix--; |
| 24682 | } |
| 24683 | } |
| 24684 | sum_funcs_end[0]= *func; // Point to last function |
| 24685 | return 0; |
| 24686 | } |
| 24687 | |
| 24688 | /** |
| 24689 | Send all rollup levels higher than the current one to the client. |
| 24690 | |
| 24691 | @b SAMPLE |
| 24692 | @code |
| 24693 | SELECT a, b, c SUM(b) FROM t1 GROUP BY a,b WITH ROLLUP |
| 24694 | @endcode |
| 24695 | |
| 24696 | @param idx Level we are on: |
| 24697 | - 0 = Total sum level |
| 24698 | - 1 = First group changed (a) |
| 24699 | - 2 = Second group changed (a,b) |
| 24700 | |
| 24701 | @retval |
| 24702 | 0 ok |
| 24703 | @retval |
| 24704 | 1 If send_data_failed() |
| 24705 | */ |
| 24706 | |
| 24707 | int JOIN::rollup_send_data(uint idx) |
| 24708 | { |
| 24709 | uint i; |
| 24710 | for (i= send_group_parts ; i-- > idx ; ) |
| 24711 | { |
| 24712 | int res= 0; |
| 24713 | /* Get reference pointers to sum functions in place */ |
| 24714 | copy_ref_ptr_array(ref_ptrs, rollup.ref_pointer_arrays[i]); |
| 24715 | if ((!having || having->val_int())) |
| 24716 | { |
| 24717 | if (send_records < unit->select_limit_cnt && do_send_rows && |
| 24718 | (res= result->send_data(rollup.fields[i])) > 0) |
| 24719 | return 1; |
| 24720 | if (!res) |
| 24721 | send_records++; |
| 24722 | } |
| 24723 | } |
| 24724 | /* Restore ref_pointer_array */ |
| 24725 | set_items_ref_array(current_ref_ptrs); |
| 24726 | return 0; |
| 24727 | } |
| 24728 | |
| 24729 | /** |
| 24730 | Write all rollup levels higher than the current one to a temp table. |
| 24731 | |
| 24732 | @b SAMPLE |
| 24733 | @code |
| 24734 | SELECT a, b, SUM(c) FROM t1 GROUP BY a,b WITH ROLLUP |
| 24735 | @endcode |
| 24736 | |
| 24737 | @param idx Level we are on: |
| 24738 | - 0 = Total sum level |
| 24739 | - 1 = First group changed (a) |
| 24740 | - 2 = Second group changed (a,b) |
| 24741 | @param table reference to temp table |
| 24742 | |
| 24743 | @retval |
| 24744 | 0 ok |
| 24745 | @retval |
| 24746 | 1 if write_data_failed() |
| 24747 | */ |
| 24748 | |
| 24749 | int JOIN::rollup_write_data(uint idx, TMP_TABLE_PARAM *tmp_table_param_arg, TABLE *table_arg) |
| 24750 | { |
| 24751 | uint i; |
| 24752 | for (i= send_group_parts ; i-- > idx ; ) |
| 24753 | { |
| 24754 | /* Get reference pointers to sum functions in place */ |
| 24755 | copy_ref_ptr_array(ref_ptrs, rollup.ref_pointer_arrays[i]); |
| 24756 | if ((!having || having->val_int())) |
| 24757 | { |
| 24758 | int write_error; |
| 24759 | Item *item; |
| 24760 | List_iterator_fast<Item> it(rollup.fields[i]); |
| 24761 | while ((item= it++)) |
| 24762 | { |
| 24763 | if (item->type() == Item::NULL_ITEM && item->is_result_field()) |
| 24764 | item->save_in_result_field(1); |
| 24765 | } |
| 24766 | copy_sum_funcs(sum_funcs_end[i+1], sum_funcs_end[i]); |
| 24767 | if (unlikely((write_error= |
| 24768 | table_arg->file->ha_write_tmp_row(table_arg->record[0])))) |
| 24769 | { |
| 24770 | if (create_internal_tmp_table_from_heap(thd, table_arg, |
| 24771 | tmp_table_param_arg->start_recinfo, |
| 24772 | &tmp_table_param_arg->recinfo, |
| 24773 | write_error, 0, NULL)) |
| 24774 | return 1; |
| 24775 | } |
| 24776 | } |
| 24777 | } |
| 24778 | /* Restore ref_pointer_array */ |
| 24779 | set_items_ref_array(current_ref_ptrs); |
| 24780 | return 0; |
| 24781 | } |
| 24782 | |
| 24783 | /** |
| 24784 | clear results if there are not rows found for group |
| 24785 | (end_send_group/end_write_group) |
| 24786 | */ |
| 24787 | |
| 24788 | void JOIN::clear() |
| 24789 | { |
| 24790 | clear_tables(this); |
| 24791 | copy_fields(&tmp_table_param); |
| 24792 | |
| 24793 | if (sum_funcs) |
| 24794 | { |
| 24795 | Item_sum *func, **func_ptr= sum_funcs; |
| 24796 | while ((func= *(func_ptr++))) |
| 24797 | func->clear(); |
| 24798 | } |
| 24799 | } |
| 24800 | |
| 24801 | |
| 24802 | /** |
| 24803 | Print an EXPLAIN line with all NULLs and given message in the 'Extra' column |
| 24804 | |
| 24805 | @retval |
| 24806 | 0 ok |
| 24807 | 1 OOM error or error from send_data() |
| 24808 | */ |
| 24809 | |
| 24810 | int print_explain_message_line(select_result_sink *result, |
| 24811 | uint8 options, bool is_analyze, |
| 24812 | uint select_number, |
| 24813 | const char *select_type, |
| 24814 | ha_rows *rows, |
| 24815 | const char *message) |
| 24816 | { |
| 24817 | THD *thd= result->thd; |
| 24818 | MEM_ROOT *mem_root= thd->mem_root; |
| 24819 | Item *item_null= new (mem_root) Item_null(thd); |
| 24820 | List<Item> item_list; |
| 24821 | |
| 24822 | item_list.push_back(new (mem_root) Item_int(thd, (int32) select_number), |
| 24823 | mem_root); |
| 24824 | item_list.push_back(new (mem_root) Item_string_sys(thd, select_type), |
| 24825 | mem_root); |
| 24826 | /* `table` */ |
| 24827 | item_list.push_back(item_null, mem_root); |
| 24828 | |
| 24829 | /* `partitions` */ |
| 24830 | if (options & DESCRIBE_PARTITIONS) |
| 24831 | item_list.push_back(item_null, mem_root); |
| 24832 | |
| 24833 | /* type, possible_keys, key, key_len, ref */ |
| 24834 | for (uint i=0 ; i < 5; i++) |
| 24835 | item_list.push_back(item_null, mem_root); |
| 24836 | |
| 24837 | /* `rows` */ |
| 24838 | if (rows) |
| 24839 | { |
| 24840 | item_list.push_back(new (mem_root) Item_int(thd, *rows, |
| 24841 | MY_INT64_NUM_DECIMAL_DIGITS), |
| 24842 | mem_root); |
| 24843 | } |
| 24844 | else |
| 24845 | item_list.push_back(item_null, mem_root); |
| 24846 | |
| 24847 | /* `r_rows` */ |
| 24848 | if (is_analyze) |
| 24849 | item_list.push_back(item_null, mem_root); |
| 24850 | |
| 24851 | /* `filtered` */ |
| 24852 | if (is_analyze || options & DESCRIBE_EXTENDED) |
| 24853 | item_list.push_back(item_null, mem_root); |
| 24854 | |
| 24855 | /* `r_filtered` */ |
| 24856 | if (is_analyze) |
| 24857 | item_list.push_back(item_null, mem_root); |
| 24858 | |
| 24859 | /* `Extra` */ |
| 24860 | if (message) |
| 24861 | item_list.push_back(new (mem_root) Item_string_sys(thd, message), |
| 24862 | mem_root); |
| 24863 | else |
| 24864 | item_list.push_back(item_null, mem_root); |
| 24865 | |
| 24866 | if (unlikely(thd->is_fatal_error) || unlikely(result->send_data(item_list))) |
| 24867 | return 1; |
| 24868 | return 0; |
| 24869 | } |
| 24870 | |
| 24871 | |
| 24872 | /* |
| 24873 | Append MRR information from quick select to the given string |
| 24874 | */ |
| 24875 | |
| 24876 | void explain_append_mrr_info(QUICK_RANGE_SELECT *quick, String *res) |
| 24877 | { |
| 24878 | char mrr_str_buf[128]; |
| 24879 | mrr_str_buf[0]=0; |
| 24880 | int len; |
| 24881 | handler *h= quick->head->file; |
| 24882 | len= h->multi_range_read_explain_info(quick->mrr_flags, mrr_str_buf, |
| 24883 | sizeof(mrr_str_buf)); |
| 24884 | if (len > 0) |
| 24885 | { |
| 24886 | //res->append(STRING_WITH_LEN("; ")); |
| 24887 | res->append(mrr_str_buf, len); |
| 24888 | } |
| 24889 | } |
| 24890 | |
| 24891 | |
| 24892 | /////////////////////////////////////////////////////////////////////////////// |
| 24893 | int append_possible_keys(MEM_ROOT *alloc, String_list &list, TABLE *table, |
| 24894 | key_map possible_keys) |
| 24895 | { |
| 24896 | uint j; |
| 24897 | for (j=0 ; j < table->s->keys ; j++) |
| 24898 | { |
| 24899 | if (possible_keys.is_set(j)) |
| 24900 | if (!(list.append_str(alloc, table->key_info[j].name.str))) |
| 24901 | return 1; |
| 24902 | } |
| 24903 | return 0; |
| 24904 | } |
| 24905 | |
| 24906 | |
| 24907 | bool JOIN_TAB::save_explain_data(Explain_table_access *eta, |
| 24908 | table_map prefix_tables, |
| 24909 | bool distinct_arg, JOIN_TAB *first_top_tab) |
| 24910 | { |
| 24911 | int quick_type; |
| 24912 | CHARSET_INFO *cs= system_charset_info; |
| 24913 | THD *thd= join->thd; |
| 24914 | TABLE_LIST *table_list= table->pos_in_table_list; |
| 24915 | QUICK_SELECT_I *cur_quick= NULL; |
| 24916 | my_bool key_read; |
| 24917 | char table_name_buffer[SAFE_NAME_LEN]; |
| 24918 | KEY *key_info= 0; |
| 24919 | uint key_len= 0; |
| 24920 | quick_type= -1; |
| 24921 | |
| 24922 | explain_plan= eta; |
| 24923 | eta->key.clear(); |
| 24924 | eta->quick_info= NULL; |
| 24925 | |
| 24926 | SQL_SELECT *tab_select; |
| 24927 | /* |
| 24928 | We assume that if this table does pre-sorting, then it doesn't do filtering |
| 24929 | with SQL_SELECT. |
| 24930 | */ |
| 24931 | DBUG_ASSERT(!(select && filesort)); |
| 24932 | tab_select= (filesort)? filesort->select : select; |
| 24933 | |
| 24934 | if (filesort) |
| 24935 | { |
| 24936 | if (!(eta->pre_join_sort= |
| 24937 | new (thd->mem_root) Explain_aggr_filesort(thd->mem_root, |
| 24938 | thd->lex->analyze_stmt, |
| 24939 | filesort))) |
| 24940 | return 1; |
| 24941 | } |
| 24942 | |
| 24943 | tracker= &eta->tracker; |
| 24944 | jbuf_tracker= &eta->jbuf_tracker; |
| 24945 | |
| 24946 | /* Enable the table access time tracker only for "ANALYZE stmt" */ |
| 24947 | if (thd->lex->analyze_stmt) |
| 24948 | table->file->set_time_tracker(&eta->op_tracker); |
| 24949 | |
| 24950 | /* No need to save id and select_type here, they are kept in Explain_select */ |
| 24951 | |
| 24952 | /* table */ |
| 24953 | if (table->derived_select_number) |
| 24954 | { |
| 24955 | /* Derived table name generation */ |
| 24956 | size_t len= my_snprintf(table_name_buffer, sizeof(table_name_buffer)-1, |
| 24957 | "<derived%u>" , |
| 24958 | table->derived_select_number); |
| 24959 | eta->table_name.copy(table_name_buffer, len, cs); |
| 24960 | } |
| 24961 | else if (bush_children) |
| 24962 | { |
| 24963 | JOIN_TAB *ctab= bush_children->start; |
| 24964 | /* table */ |
| 24965 | size_t len= my_snprintf(table_name_buffer, |
| 24966 | sizeof(table_name_buffer)-1, |
| 24967 | "<subquery%d>" , |
| 24968 | ctab->emb_sj_nest->sj_subq_pred->get_identifier()); |
| 24969 | eta->table_name.copy(table_name_buffer, len, cs); |
| 24970 | } |
| 24971 | else |
| 24972 | { |
| 24973 | TABLE_LIST *real_table= table->pos_in_table_list; |
| 24974 | /* |
| 24975 | When multi-table UPDATE/DELETE does updates/deletes to a VIEW, the view |
| 24976 | is merged in a certain particular way (grep for DT_MERGE_FOR_INSERT). |
| 24977 | |
| 24978 | As a result, view's underlying tables have $tbl->pos_in_table_list={view}. |
| 24979 | We don't want to print view name in EXPLAIN, we want underlying table's |
| 24980 | alias (like specified in the view definition). |
| 24981 | */ |
| 24982 | if (real_table->merged_for_insert) |
| 24983 | { |
| 24984 | TABLE_LIST *view_child= real_table->view->select_lex.table_list.first; |
| 24985 | for (;view_child; view_child= view_child->next_local) |
| 24986 | { |
| 24987 | if (view_child->table == table) |
| 24988 | { |
| 24989 | real_table= view_child; |
| 24990 | break; |
| 24991 | } |
| 24992 | } |
| 24993 | } |
| 24994 | eta->table_name.copy(real_table->alias.str, real_table->alias.length, cs); |
| 24995 | } |
| 24996 | |
| 24997 | /* "partitions" column */ |
| 24998 | { |
| 24999 | #ifdef WITH_PARTITION_STORAGE_ENGINE |
| 25000 | partition_info *part_info; |
| 25001 | if (!table->derived_select_number && |
| 25002 | (part_info= table->part_info)) |
| 25003 | { //TODO: all thd->mem_root here should be fixed |
| 25004 | make_used_partitions_str(thd->mem_root, part_info, &eta->used_partitions, |
| 25005 | eta->used_partitions_list); |
| 25006 | eta->used_partitions_set= true; |
| 25007 | } |
| 25008 | else |
| 25009 | eta->used_partitions_set= false; |
| 25010 | #else |
| 25011 | /* just produce empty column if partitioning is not compiled in */ |
| 25012 | eta->used_partitions_set= false; |
| 25013 | #endif |
| 25014 | } |
| 25015 | |
| 25016 | /* "type" column */ |
| 25017 | enum join_type tab_type= type; |
| 25018 | if ((type == JT_ALL || type == JT_HASH) && |
| 25019 | tab_select && tab_select->quick && use_quick != 2) |
| 25020 | { |
| 25021 | cur_quick= tab_select->quick; |
| 25022 | quick_type= cur_quick->get_type(); |
| 25023 | if ((quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE) || |
| 25024 | (quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_INTERSECT) || |
| 25025 | (quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT) || |
| 25026 | (quick_type == QUICK_SELECT_I::QS_TYPE_ROR_UNION)) |
| 25027 | tab_type= type == JT_ALL ? JT_INDEX_MERGE : JT_HASH_INDEX_MERGE; |
| 25028 | else |
| 25029 | tab_type= type == JT_ALL ? JT_RANGE : JT_HASH_RANGE; |
| 25030 | } |
| 25031 | eta->type= tab_type; |
| 25032 | |
| 25033 | /* Build "possible_keys" value */ |
| 25034 | // psergey-todo: why does this use thd MEM_ROOT??? Doesn't this |
| 25035 | // break ANALYZE ? thd->mem_root will be freed, and after that we will |
| 25036 | // attempt to print the query plan? |
| 25037 | if (append_possible_keys(thd->mem_root, eta->possible_keys, table, keys)) |
| 25038 | return 1; |
| 25039 | // psergey-todo: ^ check for error return code |
| 25040 | |
| 25041 | /* Build "key", "key_len", and "ref" */ |
| 25042 | if (tab_type == JT_NEXT) |
| 25043 | { |
| 25044 | key_info= table->key_info+index; |
| 25045 | key_len= key_info->key_length; |
| 25046 | } |
| 25047 | else if (ref.key_parts) |
| 25048 | { |
| 25049 | key_info= get_keyinfo_by_key_no(ref.key); |
| 25050 | key_len= ref.key_length; |
| 25051 | } |
| 25052 | |
| 25053 | /* |
| 25054 | In STRAIGHT_JOIN queries, there can be join tabs with JT_CONST type |
| 25055 | that still have quick selects. |
| 25056 | */ |
| 25057 | if (tab_select && tab_select->quick && tab_type != JT_CONST) |
| 25058 | { |
| 25059 | if (!(eta->quick_info= tab_select->quick->get_explain(thd->mem_root))) |
| 25060 | return 1; |
| 25061 | } |
| 25062 | |
| 25063 | if (key_info) /* 'index' or 'ref' access */ |
| 25064 | { |
| 25065 | eta->key.set(thd->mem_root, key_info, key_len); |
| 25066 | |
| 25067 | if (ref.key_parts && tab_type != JT_FT) |
| 25068 | { |
| 25069 | store_key **key_ref= ref.key_copy; |
| 25070 | for (uint kp= 0; kp < ref.key_parts; kp++) |
| 25071 | { |
| 25072 | if ((key_part_map(1) << kp) & ref.const_ref_part_map) |
| 25073 | { |
| 25074 | if (!(eta->ref_list.append_str(thd->mem_root, "const" ))) |
| 25075 | return 1; |
| 25076 | } |
| 25077 | else |
| 25078 | { |
| 25079 | if (!(eta->ref_list.append_str(thd->mem_root, (*key_ref)->name()))) |
| 25080 | return 1; |
| 25081 | key_ref++; |
| 25082 | } |
| 25083 | } |
| 25084 | } |
| 25085 | } |
| 25086 | |
| 25087 | if (tab_type == JT_HASH_NEXT) /* full index scan + hash join */ |
| 25088 | { |
| 25089 | eta->hash_next_key.set(thd->mem_root, |
| 25090 | & table->key_info[index], |
| 25091 | table->key_info[index].key_length); |
| 25092 | // psergey-todo: ^ is the above correct? are we necessarily joining on all |
| 25093 | // columns? |
| 25094 | } |
| 25095 | |
| 25096 | if (!key_info) |
| 25097 | { |
| 25098 | if (table_list && /* SJM bushes don't have table_list */ |
| 25099 | table_list->schema_table && |
| 25100 | table_list->schema_table->i_s_requested_object & OPTIMIZE_I_S_TABLE) |
| 25101 | { |
| 25102 | IS_table_read_plan *is_table_read_plan= table_list->is_table_read_plan; |
| 25103 | const char *tmp_buff; |
| 25104 | int f_idx; |
| 25105 | StringBuffer<64> key_name_buf; |
| 25106 | if (is_table_read_plan->trivial_show_command || |
| 25107 | is_table_read_plan->has_db_lookup_value()) |
| 25108 | { |
| 25109 | /* The "key" has the name of the column referring to the database */ |
| 25110 | f_idx= table_list->schema_table->idx_field1; |
| 25111 | tmp_buff= table_list->schema_table->fields_info[f_idx].field_name; |
| 25112 | key_name_buf.append(tmp_buff, strlen(tmp_buff), cs); |
| 25113 | } |
| 25114 | if (is_table_read_plan->trivial_show_command || |
| 25115 | is_table_read_plan->has_table_lookup_value()) |
| 25116 | { |
| 25117 | if (is_table_read_plan->trivial_show_command || |
| 25118 | is_table_read_plan->has_db_lookup_value()) |
| 25119 | key_name_buf.append(','); |
| 25120 | |
| 25121 | f_idx= table_list->schema_table->idx_field2; |
| 25122 | tmp_buff= table_list->schema_table->fields_info[f_idx].field_name; |
| 25123 | key_name_buf.append(tmp_buff, strlen(tmp_buff), cs); |
| 25124 | } |
| 25125 | |
| 25126 | if (key_name_buf.length()) |
| 25127 | eta->key.set_pseudo_key(thd->mem_root, key_name_buf.c_ptr_safe()); |
| 25128 | } |
| 25129 | } |
| 25130 | |
| 25131 | /* "rows" */ |
| 25132 | if (table_list /* SJM bushes don't have table_list */ && |
| 25133 | table_list->schema_table) |
| 25134 | { |
| 25135 | /* I_S tables have rows=extra=NULL */ |
| 25136 | eta->rows_set= false; |
| 25137 | eta->filtered_set= false; |
| 25138 | } |
| 25139 | else |
| 25140 | { |
| 25141 | double examined_rows= (double)get_examined_rows(); |
| 25142 | |
| 25143 | eta->rows_set= true; |
| 25144 | eta->rows= (ha_rows) examined_rows; |
| 25145 | |
| 25146 | /* "filtered" */ |
| 25147 | float f= 0.0; |
| 25148 | if (examined_rows) |
| 25149 | { |
| 25150 | double pushdown_cond_selectivity= cond_selectivity; |
| 25151 | if (pushdown_cond_selectivity == 1.0) |
| 25152 | f= (float) (100.0 * records_read / examined_rows); |
| 25153 | else |
| 25154 | f= (float) (100.0 * pushdown_cond_selectivity); |
| 25155 | } |
| 25156 | set_if_smaller(f, 100.0); |
| 25157 | eta->filtered_set= true; |
| 25158 | eta->filtered= f; |
| 25159 | } |
| 25160 | |
| 25161 | /* Build "Extra" field and save it */ |
| 25162 | key_read= table->file->keyread_enabled(); |
| 25163 | if ((tab_type == JT_NEXT || tab_type == JT_CONST) && |
| 25164 | table->covering_keys.is_set(index)) |
| 25165 | key_read=1; |
| 25166 | if (quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT && |
| 25167 | !((QUICK_ROR_INTERSECT_SELECT*)cur_quick)->need_to_fetch_row) |
| 25168 | key_read=1; |
| 25169 | |
| 25170 | if (info) |
| 25171 | { |
| 25172 | eta->push_extra(info); |
| 25173 | } |
| 25174 | else if (packed_info & TAB_INFO_HAVE_VALUE) |
| 25175 | { |
| 25176 | if (packed_info & TAB_INFO_USING_INDEX) |
| 25177 | eta->push_extra(ET_USING_INDEX); |
| 25178 | if (packed_info & TAB_INFO_USING_WHERE) |
| 25179 | eta->push_extra(ET_USING_WHERE); |
| 25180 | if (packed_info & TAB_INFO_FULL_SCAN_ON_NULL) |
| 25181 | eta->push_extra(ET_FULL_SCAN_ON_NULL_KEY); |
| 25182 | } |
| 25183 | else |
| 25184 | { |
| 25185 | uint keyno= MAX_KEY; |
| 25186 | if (ref.key_parts) |
| 25187 | keyno= ref.key; |
| 25188 | else if (tab_select && cur_quick) |
| 25189 | keyno = cur_quick->index; |
| 25190 | |
| 25191 | if (keyno != MAX_KEY && keyno == table->file->pushed_idx_cond_keyno && |
| 25192 | table->file->pushed_idx_cond) |
| 25193 | { |
| 25194 | eta->push_extra(ET_USING_INDEX_CONDITION); |
| 25195 | eta->pushed_index_cond= table->file->pushed_idx_cond; |
| 25196 | } |
| 25197 | else if (cache_idx_cond) |
| 25198 | { |
| 25199 | eta->push_extra(ET_USING_INDEX_CONDITION_BKA); |
| 25200 | eta->pushed_index_cond= cache_idx_cond; |
| 25201 | } |
| 25202 | |
| 25203 | if (quick_type == QUICK_SELECT_I::QS_TYPE_ROR_UNION || |
| 25204 | quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT || |
| 25205 | quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_INTERSECT || |
| 25206 | quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE) |
| 25207 | { |
| 25208 | eta->push_extra(ET_USING); |
| 25209 | } |
| 25210 | if (tab_select) |
| 25211 | { |
| 25212 | if (use_quick == 2) |
| 25213 | { |
| 25214 | eta->push_extra(ET_RANGE_CHECKED_FOR_EACH_RECORD); |
| 25215 | eta->range_checked_fer= new (thd->mem_root) Explain_range_checked_fer; |
| 25216 | if (eta->range_checked_fer) |
| 25217 | eta->range_checked_fer-> |
| 25218 | append_possible_keys_stat(thd->mem_root, table, keys); |
| 25219 | } |
| 25220 | else if (tab_select->cond || |
| 25221 | (cache_select && cache_select->cond)) |
| 25222 | { |
| 25223 | const COND *pushed_cond= table->file->pushed_cond; |
| 25224 | |
| 25225 | if ((table->file->ha_table_flags() & |
| 25226 | HA_CAN_TABLE_CONDITION_PUSHDOWN) && |
| 25227 | pushed_cond) |
| 25228 | { |
| 25229 | eta->push_extra(ET_USING_WHERE_WITH_PUSHED_CONDITION); |
| 25230 | } |
| 25231 | else |
| 25232 | { |
| 25233 | eta->where_cond= tab_select->cond; |
| 25234 | eta->cache_cond= cache_select? cache_select->cond : NULL; |
| 25235 | eta->push_extra(ET_USING_WHERE); |
| 25236 | } |
| 25237 | } |
| 25238 | } |
| 25239 | if (table_list /* SJM bushes don't have table_list */ && |
| 25240 | table_list->schema_table && |
| 25241 | table_list->schema_table->i_s_requested_object & OPTIMIZE_I_S_TABLE) |
| 25242 | { |
| 25243 | if (!table_list->table_open_method) |
| 25244 | eta->push_extra(ET_SKIP_OPEN_TABLE); |
| 25245 | else if (table_list->table_open_method == OPEN_FRM_ONLY) |
| 25246 | eta->push_extra(ET_OPEN_FRM_ONLY); |
| 25247 | else |
| 25248 | eta->push_extra(ET_OPEN_FULL_TABLE); |
| 25249 | /* psergey-note: the following has a bug.*/ |
| 25250 | if (table_list->is_table_read_plan->trivial_show_command || |
| 25251 | (table_list->is_table_read_plan->has_db_lookup_value() && |
| 25252 | table_list->is_table_read_plan->has_table_lookup_value())) |
| 25253 | eta->push_extra(ET_SCANNED_0_DATABASES); |
| 25254 | else if (table_list->is_table_read_plan->has_db_lookup_value() || |
| 25255 | table_list->is_table_read_plan->has_table_lookup_value()) |
| 25256 | eta->push_extra(ET_SCANNED_1_DATABASE); |
| 25257 | else |
| 25258 | eta->push_extra(ET_SCANNED_ALL_DATABASES); |
| 25259 | } |
| 25260 | if (key_read) |
| 25261 | { |
| 25262 | if (quick_type == QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX) |
| 25263 | { |
| 25264 | QUICK_GROUP_MIN_MAX_SELECT *qgs= |
| 25265 | (QUICK_GROUP_MIN_MAX_SELECT *) tab_select->quick; |
| 25266 | eta->push_extra(ET_USING_INDEX_FOR_GROUP_BY); |
| 25267 | eta->loose_scan_is_scanning= qgs->loose_scan_is_scanning(); |
| 25268 | } |
| 25269 | else |
| 25270 | eta->push_extra(ET_USING_INDEX); |
| 25271 | } |
| 25272 | if (table->reginfo.not_exists_optimize) |
| 25273 | eta->push_extra(ET_NOT_EXISTS); |
| 25274 | |
| 25275 | if (quick_type == QUICK_SELECT_I::QS_TYPE_RANGE) |
| 25276 | { |
| 25277 | explain_append_mrr_info((QUICK_RANGE_SELECT*)(tab_select->quick), |
| 25278 | &eta->mrr_type); |
| 25279 | if (eta->mrr_type.length() > 0) |
| 25280 | eta->push_extra(ET_USING_MRR); |
| 25281 | } |
| 25282 | |
| 25283 | if (shortcut_for_distinct) |
| 25284 | eta->push_extra(ET_DISTINCT); |
| 25285 | |
| 25286 | if (loosescan_match_tab) |
| 25287 | { |
| 25288 | eta->push_extra(ET_LOOSESCAN); |
| 25289 | } |
| 25290 | |
| 25291 | if (first_weedout_table) |
| 25292 | { |
| 25293 | eta->start_dups_weedout= true; |
| 25294 | eta->push_extra(ET_START_TEMPORARY); |
| 25295 | } |
| 25296 | if (check_weed_out_table) |
| 25297 | { |
| 25298 | eta->push_extra(ET_END_TEMPORARY); |
| 25299 | eta->end_dups_weedout= true; |
| 25300 | } |
| 25301 | |
| 25302 | else if (do_firstmatch) |
| 25303 | { |
| 25304 | if (do_firstmatch == /*join->join_tab*/ first_top_tab - 1) |
| 25305 | eta->push_extra(ET_FIRST_MATCH); |
| 25306 | else |
| 25307 | { |
| 25308 | eta->push_extra(ET_FIRST_MATCH); |
| 25309 | TABLE *prev_table=do_firstmatch->table; |
| 25310 | if (prev_table->derived_select_number) |
| 25311 | { |
| 25312 | char namebuf[NAME_LEN]; |
| 25313 | /* Derived table name generation */ |
| 25314 | size_t len= my_snprintf(namebuf, sizeof(namebuf)-1, |
| 25315 | "<derived%u>" , |
| 25316 | prev_table->derived_select_number); |
| 25317 | eta->firstmatch_table_name.append(namebuf, len); |
| 25318 | } |
| 25319 | else |
| 25320 | eta->firstmatch_table_name.append(&prev_table->pos_in_table_list->alias); |
| 25321 | } |
| 25322 | } |
| 25323 | |
| 25324 | for (uint part= 0; part < ref.key_parts; part++) |
| 25325 | { |
| 25326 | if (ref.cond_guards[part]) |
| 25327 | { |
| 25328 | eta->push_extra(ET_FULL_SCAN_ON_NULL_KEY); |
| 25329 | eta->full_scan_on_null_key= true; |
| 25330 | break; |
| 25331 | } |
| 25332 | } |
| 25333 | |
| 25334 | if (cache) |
| 25335 | { |
| 25336 | eta->push_extra(ET_USING_JOIN_BUFFER); |
| 25337 | if (cache->save_explain_data(&eta->bka_type)) |
| 25338 | return 1; |
| 25339 | } |
| 25340 | } |
| 25341 | |
| 25342 | /* |
| 25343 | In case this is a derived table, here we remember the number of |
| 25344 | subselect that used to produce it. |
| 25345 | */ |
| 25346 | if (!(table_list && table_list->is_with_table_recursive_reference())) |
| 25347 | eta->derived_select_number= table->derived_select_number; |
| 25348 | |
| 25349 | /* The same for non-merged semi-joins */ |
| 25350 | eta->non_merged_sjm_number = get_non_merged_semijoin_select(); |
| 25351 | |
| 25352 | return 0; |
| 25353 | } |
| 25354 | |
| 25355 | |
| 25356 | /* |
| 25357 | Walk through join->aggr_tables and save aggregation/grouping query plan into |
| 25358 | an Explain_select object |
| 25359 | |
| 25360 | @retval |
| 25361 | 0 ok |
| 25362 | 1 error |
| 25363 | */ |
| 25364 | |
| 25365 | bool save_agg_explain_data(JOIN *join, Explain_select *xpl_sel) |
| 25366 | { |
| 25367 | JOIN_TAB *join_tab=join->join_tab + join->exec_join_tab_cnt(); |
| 25368 | Explain_aggr_node *prev_node; |
| 25369 | Explain_aggr_node *node= xpl_sel->aggr_tree; |
| 25370 | bool is_analyze= join->thd->lex->analyze_stmt; |
| 25371 | THD *thd= join->thd; |
| 25372 | |
| 25373 | for (uint i= 0; i < join->aggr_tables; i++, join_tab++) |
| 25374 | { |
| 25375 | // Each aggregate means a temp.table |
| 25376 | prev_node= node; |
| 25377 | if (!(node= new (thd->mem_root) Explain_aggr_tmp_table)) |
| 25378 | return 1; |
| 25379 | node->child= prev_node; |
| 25380 | |
| 25381 | if (join_tab->window_funcs_step) |
| 25382 | { |
| 25383 | Explain_aggr_node *new_node= |
| 25384 | join_tab->window_funcs_step->save_explain_plan(thd->mem_root, |
| 25385 | is_analyze); |
| 25386 | if (!new_node) |
| 25387 | return 1; |
| 25388 | |
| 25389 | prev_node=node; |
| 25390 | node= new_node; |
| 25391 | node->child= prev_node; |
| 25392 | } |
| 25393 | |
| 25394 | /* The below matches execution in join_init_read_record() */ |
| 25395 | if (join_tab->distinct) |
| 25396 | { |
| 25397 | prev_node= node; |
| 25398 | if (!(node= new (thd->mem_root) Explain_aggr_remove_dups)) |
| 25399 | return 1; |
| 25400 | node->child= prev_node; |
| 25401 | } |
| 25402 | |
| 25403 | if (join_tab->filesort) |
| 25404 | { |
| 25405 | Explain_aggr_filesort *eaf = |
| 25406 | new (thd->mem_root) Explain_aggr_filesort(thd->mem_root, is_analyze, join_tab->filesort); |
| 25407 | if (!eaf) |
| 25408 | return 1; |
| 25409 | prev_node= node; |
| 25410 | node= eaf; |
| 25411 | node->child= prev_node; |
| 25412 | } |
| 25413 | } |
| 25414 | xpl_sel->aggr_tree= node; |
| 25415 | return 0; |
| 25416 | } |
| 25417 | |
| 25418 | |
| 25419 | /** |
| 25420 | Save Query Plan Footprint |
| 25421 | |
| 25422 | @note |
| 25423 | Currently, this function may be called multiple times |
| 25424 | |
| 25425 | @retval |
| 25426 | 0 ok |
| 25427 | 1 error |
| 25428 | */ |
| 25429 | |
| 25430 | int JOIN::save_explain_data_intern(Explain_query *output, |
| 25431 | bool need_tmp_table_arg, |
| 25432 | bool need_order_arg, bool distinct_arg, |
| 25433 | const char *message) |
| 25434 | { |
| 25435 | JOIN *join= this; /* Legacy: this code used to be a non-member function */ |
| 25436 | DBUG_ENTER("JOIN::save_explain_data_intern" ); |
| 25437 | DBUG_PRINT("info" , ("Select %p, type %s, message %s" , |
| 25438 | join->select_lex, join->select_lex->type, |
| 25439 | message ? message : "NULL" )); |
| 25440 | DBUG_ASSERT(have_query_plan == QEP_AVAILABLE); |
| 25441 | /* fake_select_lex is created/printed by Explain_union */ |
| 25442 | DBUG_ASSERT(join->select_lex != join->unit->fake_select_lex); |
| 25443 | |
| 25444 | /* There should be no attempts to save query plans for merged selects */ |
| 25445 | DBUG_ASSERT(!join->select_lex->master_unit()->derived || |
| 25446 | join->select_lex->master_unit()->derived->is_materialized_derived() || |
| 25447 | join->select_lex->master_unit()->derived->is_with_table()); |
| 25448 | |
| 25449 | /* Don't log this into the slow query log */ |
| 25450 | |
| 25451 | if (message) |
| 25452 | { |
| 25453 | if (!(explain= new (output->mem_root) |
| 25454 | Explain_select(output->mem_root, |
| 25455 | thd->lex->analyze_stmt))) |
| 25456 | DBUG_RETURN(1); |
| 25457 | #ifndef DBUG_OFF |
| 25458 | explain->select_lex= select_lex; |
| 25459 | #endif |
| 25460 | join->select_lex->set_explain_type(true); |
| 25461 | |
| 25462 | explain->select_id= join->select_lex->select_number; |
| 25463 | explain->select_type= join->select_lex->type; |
| 25464 | explain->linkage= select_lex->linkage; |
| 25465 | explain->using_temporary= need_tmp; |
| 25466 | explain->using_filesort= need_order_arg; |
| 25467 | /* Setting explain->message means that all other members are invalid */ |
| 25468 | explain->message= message; |
| 25469 | |
| 25470 | if (select_lex->master_unit()->derived) |
| 25471 | explain->connection_type= Explain_node::EXPLAIN_NODE_DERIVED; |
| 25472 | if (save_agg_explain_data(this, explain)) |
| 25473 | DBUG_RETURN(1); |
| 25474 | |
| 25475 | output->add_node(explain); |
| 25476 | } |
| 25477 | else if (pushdown_query) |
| 25478 | { |
| 25479 | if (!(explain= new (output->mem_root) |
| 25480 | Explain_select(output->mem_root, |
| 25481 | thd->lex->analyze_stmt))) |
| 25482 | DBUG_RETURN(1); |
| 25483 | select_lex->set_explain_type(true); |
| 25484 | |
| 25485 | explain->select_id= select_lex->select_number; |
| 25486 | explain->select_type= select_lex->type; |
| 25487 | explain->linkage= select_lex->linkage; |
| 25488 | explain->using_temporary= need_tmp; |
| 25489 | explain->using_filesort= need_order_arg; |
| 25490 | explain->message= "Storage engine handles GROUP BY" ; |
| 25491 | |
| 25492 | if (select_lex->master_unit()->derived) |
| 25493 | explain->connection_type= Explain_node::EXPLAIN_NODE_DERIVED; |
| 25494 | output->add_node(explain); |
| 25495 | } |
| 25496 | else |
| 25497 | { |
| 25498 | Explain_select *xpl_sel; |
| 25499 | explain= xpl_sel= |
| 25500 | new (output->mem_root) Explain_select(output->mem_root, |
| 25501 | thd->lex->analyze_stmt); |
| 25502 | if (!explain) |
| 25503 | DBUG_RETURN(1); |
| 25504 | |
| 25505 | table_map used_tables=0; |
| 25506 | |
| 25507 | join->select_lex->set_explain_type(true); |
| 25508 | xpl_sel->select_id= join->select_lex->select_number; |
| 25509 | xpl_sel->select_type= join->select_lex->type; |
| 25510 | xpl_sel->linkage= select_lex->linkage; |
| 25511 | if (select_lex->master_unit()->derived) |
| 25512 | xpl_sel->connection_type= Explain_node::EXPLAIN_NODE_DERIVED; |
| 25513 | |
| 25514 | if (save_agg_explain_data(this, xpl_sel)) |
| 25515 | DBUG_RETURN(1); |
| 25516 | |
| 25517 | xpl_sel->exec_const_cond= exec_const_cond; |
| 25518 | xpl_sel->outer_ref_cond= outer_ref_cond; |
| 25519 | if (tmp_having) |
| 25520 | xpl_sel->having= tmp_having; |
| 25521 | else |
| 25522 | xpl_sel->having= having; |
| 25523 | xpl_sel->having_value= having_value; |
| 25524 | |
| 25525 | JOIN_TAB* const first_top_tab= join->first_breadth_first_tab(); |
| 25526 | JOIN_TAB* prev_bush_root_tab= NULL; |
| 25527 | |
| 25528 | Explain_basic_join *cur_parent= xpl_sel; |
| 25529 | |
| 25530 | for (JOIN_TAB *tab= first_explain_order_tab(join); tab; |
| 25531 | tab= next_explain_order_tab(join, tab)) |
| 25532 | { |
| 25533 | JOIN_TAB *saved_join_tab= NULL; |
| 25534 | TABLE *cur_table= tab->table; |
| 25535 | |
| 25536 | /* Don't show eliminated tables */ |
| 25537 | if (cur_table->map & join->eliminated_tables) |
| 25538 | { |
| 25539 | used_tables|= cur_table->map; |
| 25540 | continue; |
| 25541 | } |
| 25542 | |
| 25543 | |
| 25544 | Explain_table_access *eta= (new (output->mem_root) |
| 25545 | Explain_table_access(output->mem_root)); |
| 25546 | |
| 25547 | if (!eta) |
| 25548 | DBUG_RETURN(1); |
| 25549 | if (tab->bush_root_tab != prev_bush_root_tab) |
| 25550 | { |
| 25551 | if (tab->bush_root_tab) |
| 25552 | { |
| 25553 | /* |
| 25554 | We've entered an SJ-Materialization nest. Create an object for it. |
| 25555 | */ |
| 25556 | if (!(cur_parent= |
| 25557 | new (output->mem_root) Explain_basic_join(output->mem_root))) |
| 25558 | DBUG_RETURN(1); |
| 25559 | |
| 25560 | JOIN_TAB *first_child= tab->bush_root_tab->bush_children->start; |
| 25561 | cur_parent->select_id= |
| 25562 | first_child->emb_sj_nest->sj_subq_pred->get_identifier(); |
| 25563 | } |
| 25564 | else |
| 25565 | { |
| 25566 | /* |
| 25567 | We've just left an SJ-Materialization nest. We are at the join tab |
| 25568 | that 'embeds the nest' |
| 25569 | */ |
| 25570 | DBUG_ASSERT(tab->bush_children); |
| 25571 | eta->sjm_nest= cur_parent; |
| 25572 | cur_parent= xpl_sel; |
| 25573 | } |
| 25574 | } |
| 25575 | prev_bush_root_tab= tab->bush_root_tab; |
| 25576 | |
| 25577 | cur_parent->add_table(eta, output); |
| 25578 | if (tab->save_explain_data(eta, used_tables, distinct_arg, first_top_tab)) |
| 25579 | DBUG_RETURN(1); |
| 25580 | |
| 25581 | if (saved_join_tab) |
| 25582 | tab= saved_join_tab; |
| 25583 | |
| 25584 | // For next iteration |
| 25585 | used_tables|= cur_table->map; |
| 25586 | } |
| 25587 | output->add_node(xpl_sel); |
| 25588 | } |
| 25589 | |
| 25590 | for (SELECT_LEX_UNIT *tmp_unit= join->select_lex->first_inner_unit(); |
| 25591 | tmp_unit; |
| 25592 | tmp_unit= tmp_unit->next_unit()) |
| 25593 | { |
| 25594 | /* |
| 25595 | Display subqueries only if |
| 25596 | (1) they are not parts of ON clauses that were eliminated by table |
| 25597 | elimination. |
| 25598 | (2) they are not merged derived tables |
| 25599 | (3) they are not unreferenced CTE |
| 25600 | */ |
| 25601 | if (!(tmp_unit->item && tmp_unit->item->eliminated) && // (1) |
| 25602 | (!tmp_unit->derived || |
| 25603 | tmp_unit->derived->is_materialized_derived()) && // (2) |
| 25604 | !(tmp_unit->with_element && |
| 25605 | !tmp_unit->with_element->is_referenced())) // (3) |
| 25606 | { |
| 25607 | explain->add_child(tmp_unit->first_select()->select_number); |
| 25608 | } |
| 25609 | } |
| 25610 | |
| 25611 | if (select_lex->is_top_level_node()) |
| 25612 | output->query_plan_ready(); |
| 25613 | |
| 25614 | DBUG_RETURN(0); |
| 25615 | } |
| 25616 | |
| 25617 | |
| 25618 | /* |
| 25619 | This function serves as "shortcut point" for EXPLAIN queries. |
| 25620 | |
| 25621 | The EXPLAIN statement executes just like its SELECT counterpart would |
| 25622 | execute, except that JOIN::exec() will call select_describe() instead of |
| 25623 | actually executing the query. |
| 25624 | |
| 25625 | Inside select_describe(): |
| 25626 | - Query plan is updated with latest QEP choices made at the start of |
| 25627 | JOIN::exec(). |
| 25628 | - the proces of "almost execution" is invoked for the children subqueries. |
| 25629 | |
| 25630 | Overall, select_describe() is a legacy of old EXPLAIN implementation and |
| 25631 | should be removed. |
| 25632 | */ |
| 25633 | |
| 25634 | static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, |
| 25635 | bool distinct,const char *message) |
| 25636 | { |
| 25637 | THD *thd=join->thd; |
| 25638 | select_result *result=join->result; |
| 25639 | DBUG_ENTER("select_describe" ); |
| 25640 | |
| 25641 | /* Update the QPF with latest values of using_temporary, using_filesort */ |
| 25642 | for (SELECT_LEX_UNIT *unit= join->select_lex->first_inner_unit(); |
| 25643 | unit; |
| 25644 | unit= unit->next_unit()) |
| 25645 | { |
| 25646 | /* |
| 25647 | This fix_fields() call is to handle an edge case like this: |
| 25648 | |
| 25649 | SELECT ... UNION SELECT ... ORDER BY (SELECT ...) |
| 25650 | |
| 25651 | for such queries, we'll get here before having called |
| 25652 | subquery_expr->fix_fields(), which will cause failure to |
| 25653 | */ |
| 25654 | if (unit->item && !unit->item->fixed) |
| 25655 | { |
| 25656 | Item *ref= unit->item; |
| 25657 | if (unit->item->fix_fields(thd, &ref)) |
| 25658 | DBUG_VOID_RETURN; |
| 25659 | DBUG_ASSERT(ref == unit->item); |
| 25660 | } |
| 25661 | |
| 25662 | /* |
| 25663 | Save plans for child subqueries, when |
| 25664 | (1) they are not parts of eliminated WHERE/ON clauses. |
| 25665 | (2) they are not VIEWs that were "merged for INSERT". |
| 25666 | (3) they are not unreferenced CTE. |
| 25667 | */ |
| 25668 | if (!(unit->item && unit->item->eliminated) && // (1) |
| 25669 | !(unit->derived && unit->derived->merged_for_insert) && // (2) |
| 25670 | !(unit->with_element && !unit->with_element->is_referenced())) // (3) |
| 25671 | { |
| 25672 | if (mysql_explain_union(thd, unit, result)) |
| 25673 | DBUG_VOID_RETURN; |
| 25674 | } |
| 25675 | } |
| 25676 | DBUG_VOID_RETURN; |
| 25677 | } |
| 25678 | |
| 25679 | |
| 25680 | bool mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result) |
| 25681 | { |
| 25682 | DBUG_ENTER("mysql_explain_union" ); |
| 25683 | bool res= 0; |
| 25684 | SELECT_LEX *first= unit->first_select(); |
| 25685 | |
| 25686 | for (SELECT_LEX *sl= first; sl; sl= sl->next_select()) |
| 25687 | { |
| 25688 | sl->set_explain_type(FALSE); |
| 25689 | sl->options|= SELECT_DESCRIBE; |
| 25690 | } |
| 25691 | |
| 25692 | if (unit->is_unit_op()) |
| 25693 | { |
| 25694 | if (unit->union_needs_tmp_table() && unit->fake_select_lex) |
| 25695 | { |
| 25696 | unit->fake_select_lex->select_number= FAKE_SELECT_LEX_ID; // just for initialization |
| 25697 | unit->fake_select_lex->type= unit_operation_text[unit->common_op()]; |
| 25698 | unit->fake_select_lex->options|= SELECT_DESCRIBE; |
| 25699 | } |
| 25700 | if (!(res= unit->prepare(unit->derived, result, |
| 25701 | SELECT_NO_UNLOCK | SELECT_DESCRIBE))) |
| 25702 | res= unit->exec(); |
| 25703 | } |
| 25704 | else |
| 25705 | { |
| 25706 | thd->lex->current_select= first; |
| 25707 | unit->set_limit(unit->global_parameters()); |
| 25708 | res= mysql_select(thd, |
| 25709 | first->table_list.first, |
| 25710 | first->with_wild, first->item_list, |
| 25711 | first->where, |
| 25712 | first->order_list.elements + first->group_list.elements, |
| 25713 | first->order_list.first, |
| 25714 | first->group_list.first, |
| 25715 | first->having, |
| 25716 | thd->lex->proc_list.first, |
| 25717 | first->options | thd->variables.option_bits | SELECT_DESCRIBE, |
| 25718 | result, unit, first); |
| 25719 | } |
| 25720 | DBUG_RETURN(res || thd->is_error()); |
| 25721 | } |
| 25722 | |
| 25723 | |
| 25724 | static void print_table_array(THD *thd, |
| 25725 | table_map eliminated_tables, |
| 25726 | String *str, TABLE_LIST **table, |
| 25727 | TABLE_LIST **end, |
| 25728 | enum_query_type query_type) |
| 25729 | { |
| 25730 | (*table)->print(thd, eliminated_tables, str, query_type); |
| 25731 | |
| 25732 | for (TABLE_LIST **tbl= table + 1; tbl < end; tbl++) |
| 25733 | { |
| 25734 | TABLE_LIST *curr= *tbl; |
| 25735 | |
| 25736 | /* |
| 25737 | The "eliminated_tables &&" check guards againist the case of |
| 25738 | printing the query for CREATE VIEW. We do that without having run |
| 25739 | JOIN::optimize() and so will have nested_join->used_tables==0. |
| 25740 | */ |
| 25741 | if (eliminated_tables && |
| 25742 | ((curr->table && (curr->table->map & eliminated_tables)) || |
| 25743 | (curr->nested_join && !(curr->nested_join->used_tables & |
| 25744 | ~eliminated_tables)))) |
| 25745 | { |
| 25746 | /* as of 5.5, print_join doesnt put eliminated elements into array */ |
| 25747 | DBUG_ASSERT(0); |
| 25748 | continue; |
| 25749 | } |
| 25750 | |
| 25751 | /* JOIN_TYPE_OUTER is just a marker unrelated to real join */ |
| 25752 | if (curr->outer_join & (JOIN_TYPE_LEFT|JOIN_TYPE_RIGHT)) |
| 25753 | { |
| 25754 | /* MySQL converts right to left joins */ |
| 25755 | str->append(STRING_WITH_LEN(" left join " )); |
| 25756 | } |
| 25757 | else if (curr->straight) |
| 25758 | str->append(STRING_WITH_LEN(" straight_join " )); |
| 25759 | else if (curr->sj_inner_tables) |
| 25760 | str->append(STRING_WITH_LEN(" semi join " )); |
| 25761 | else |
| 25762 | str->append(STRING_WITH_LEN(" join " )); |
| 25763 | |
| 25764 | curr->print(thd, eliminated_tables, str, query_type); |
| 25765 | if (curr->on_expr) |
| 25766 | { |
| 25767 | str->append(STRING_WITH_LEN(" on(" )); |
| 25768 | curr->on_expr->print(str, query_type); |
| 25769 | str->append(')'); |
| 25770 | } |
| 25771 | } |
| 25772 | } |
| 25773 | |
| 25774 | |
| 25775 | /* |
| 25776 | Check if the passed table is |
| 25777 | - a base table which was eliminated, or |
| 25778 | - a join nest which only contained eliminated tables (and so was eliminated, |
| 25779 | too) |
| 25780 | */ |
| 25781 | |
| 25782 | static bool is_eliminated_table(table_map eliminated_tables, TABLE_LIST *tbl) |
| 25783 | { |
| 25784 | return eliminated_tables && |
| 25785 | ((tbl->table && (tbl->table->map & eliminated_tables)) || |
| 25786 | (tbl->nested_join && !(tbl->nested_join->used_tables & |
| 25787 | ~eliminated_tables))); |
| 25788 | } |
| 25789 | |
| 25790 | /** |
| 25791 | Print joins from the FROM clause. |
| 25792 | |
| 25793 | @param thd thread handler |
| 25794 | @param str string where table should be printed |
| 25795 | @param tables list of tables in join |
| 25796 | @query_type type of the query is being generated |
| 25797 | */ |
| 25798 | |
| 25799 | static void print_join(THD *thd, |
| 25800 | table_map eliminated_tables, |
| 25801 | String *str, |
| 25802 | List<TABLE_LIST> *tables, |
| 25803 | enum_query_type query_type) |
| 25804 | { |
| 25805 | /* List is reversed => we should reverse it before using */ |
| 25806 | List_iterator_fast<TABLE_LIST> ti(*tables); |
| 25807 | TABLE_LIST **table; |
| 25808 | DBUG_ENTER("print_join" ); |
| 25809 | |
| 25810 | /* |
| 25811 | If the QT_NO_DATA_EXPANSION flag is specified, we print the |
| 25812 | original table list, including constant tables that have been |
| 25813 | optimized away, as the constant tables may be referenced in the |
| 25814 | expression printed by Item_field::print() when this flag is given. |
| 25815 | Otherwise, only non-const tables are printed. |
| 25816 | |
| 25817 | Example: |
| 25818 | |
| 25819 | Original SQL: |
| 25820 | select * from (select 1) t |
| 25821 | |
| 25822 | Printed without QT_NO_DATA_EXPANSION: |
| 25823 | select '1' AS `1` from dual |
| 25824 | |
| 25825 | Printed with QT_NO_DATA_EXPANSION: |
| 25826 | select `t`.`1` from (select 1 AS `1`) `t` |
| 25827 | */ |
| 25828 | const bool print_const_tables= (query_type & QT_NO_DATA_EXPANSION); |
| 25829 | size_t tables_to_print= 0; |
| 25830 | |
| 25831 | for (TABLE_LIST *t= ti++; t ; t= ti++) |
| 25832 | { |
| 25833 | /* See comment in print_table_array() about the second condition */ |
| 25834 | if (print_const_tables || !t->optimized_away) |
| 25835 | if (!is_eliminated_table(eliminated_tables, t)) |
| 25836 | tables_to_print++; |
| 25837 | } |
| 25838 | if (tables_to_print == 0) |
| 25839 | { |
| 25840 | str->append(STRING_WITH_LEN("dual" )); |
| 25841 | DBUG_VOID_RETURN; // all tables were optimized away |
| 25842 | } |
| 25843 | ti.rewind(); |
| 25844 | |
| 25845 | if (!(table= static_cast<TABLE_LIST **>(thd->alloc(sizeof(TABLE_LIST*) * |
| 25846 | tables_to_print)))) |
| 25847 | DBUG_VOID_RETURN; // out of memory |
| 25848 | |
| 25849 | TABLE_LIST *tmp, **t= table + (tables_to_print - 1); |
| 25850 | while ((tmp= ti++)) |
| 25851 | { |
| 25852 | if (tmp->optimized_away && !print_const_tables) |
| 25853 | continue; |
| 25854 | if (is_eliminated_table(eliminated_tables, tmp)) |
| 25855 | continue; |
| 25856 | *t--= tmp; |
| 25857 | } |
| 25858 | |
| 25859 | DBUG_ASSERT(tables->elements >= 1); |
| 25860 | /* |
| 25861 | Assert that the first table in the list isn't eliminated. This comes from |
| 25862 | the fact that the first table can't be inner table of an outer join. |
| 25863 | */ |
| 25864 | DBUG_ASSERT(!eliminated_tables || |
| 25865 | !(((*table)->table && ((*table)->table->map & eliminated_tables)) || |
| 25866 | ((*table)->nested_join && !((*table)->nested_join->used_tables & |
| 25867 | ~eliminated_tables)))); |
| 25868 | /* |
| 25869 | If the first table is a semi-join nest, swap it with something that is |
| 25870 | not a semi-join nest. |
| 25871 | */ |
| 25872 | if ((*table)->sj_inner_tables) |
| 25873 | { |
| 25874 | TABLE_LIST **end= table + tables_to_print; |
| 25875 | for (TABLE_LIST **t2= table; t2!=end; t2++) |
| 25876 | { |
| 25877 | if (!(*t2)->sj_inner_tables) |
| 25878 | { |
| 25879 | tmp= *t2; |
| 25880 | *t2= *table; |
| 25881 | *table= tmp; |
| 25882 | break; |
| 25883 | } |
| 25884 | } |
| 25885 | } |
| 25886 | print_table_array(thd, eliminated_tables, str, table, |
| 25887 | table + tables_to_print, query_type); |
| 25888 | DBUG_VOID_RETURN; |
| 25889 | } |
| 25890 | |
| 25891 | /** |
| 25892 | @brief Print an index hint |
| 25893 | |
| 25894 | @details Prints out the USE|FORCE|IGNORE index hint. |
| 25895 | |
| 25896 | @param thd the current thread |
| 25897 | @param[out] str appends the index hint here |
| 25898 | @param hint what the hint is (as string : "USE INDEX"| |
| 25899 | "FORCE INDEX"|"IGNORE INDEX") |
| 25900 | @param hint_length the length of the string in 'hint' |
| 25901 | @param indexes a list of index names for the hint |
| 25902 | */ |
| 25903 | |
| 25904 | void |
| 25905 | Index_hint::print(THD *thd, String *str) |
| 25906 | { |
| 25907 | switch (type) |
| 25908 | { |
| 25909 | case INDEX_HINT_IGNORE: str->append(STRING_WITH_LEN("IGNORE INDEX" )); break; |
| 25910 | case INDEX_HINT_USE: str->append(STRING_WITH_LEN("USE INDEX" )); break; |
| 25911 | case INDEX_HINT_FORCE: str->append(STRING_WITH_LEN("FORCE INDEX" )); break; |
| 25912 | } |
| 25913 | str->append (STRING_WITH_LEN(" (" )); |
| 25914 | if (key_name.length) |
| 25915 | { |
| 25916 | if (thd && !my_strnncoll(system_charset_info, |
| 25917 | (const uchar *)key_name.str, key_name.length, |
| 25918 | (const uchar *)primary_key_name, |
| 25919 | strlen(primary_key_name))) |
| 25920 | str->append(primary_key_name); |
| 25921 | else |
| 25922 | append_identifier(thd, str, &key_name); |
| 25923 | } |
| 25924 | str->append(')'); |
| 25925 | } |
| 25926 | |
| 25927 | |
| 25928 | /** |
| 25929 | Print table as it should be in join list. |
| 25930 | |
| 25931 | @param str string where table should be printed |
| 25932 | */ |
| 25933 | |
| 25934 | void TABLE_LIST::print(THD *thd, table_map eliminated_tables, String *str, |
| 25935 | enum_query_type query_type) |
| 25936 | { |
| 25937 | if (nested_join) |
| 25938 | { |
| 25939 | str->append('('); |
| 25940 | print_join(thd, eliminated_tables, str, &nested_join->join_list, query_type); |
| 25941 | str->append(')'); |
| 25942 | } |
| 25943 | else if (jtbm_subselect) |
| 25944 | { |
| 25945 | if (jtbm_subselect->engine->engine_type() == |
| 25946 | subselect_engine::SINGLE_SELECT_ENGINE) |
| 25947 | { |
| 25948 | /* |
| 25949 | We get here when conversion into materialization didn't finish (this |
| 25950 | happens when |
| 25951 | - The subquery is a degenerate case which produces 0 or 1 record |
| 25952 | - subquery's optimization didn't finish because of @@max_join_size |
| 25953 | limits |
| 25954 | - ... maybe some other cases like this |
| 25955 | */ |
| 25956 | str->append(STRING_WITH_LEN(" <materialize> (" )); |
| 25957 | jtbm_subselect->engine->print(str, query_type); |
| 25958 | str->append(')'); |
| 25959 | } |
| 25960 | else |
| 25961 | { |
| 25962 | str->append(STRING_WITH_LEN(" <materialize> (" )); |
| 25963 | subselect_hash_sj_engine *hash_engine; |
| 25964 | hash_engine= (subselect_hash_sj_engine*)jtbm_subselect->engine; |
| 25965 | hash_engine->materialize_engine->print(str, query_type); |
| 25966 | str->append(')'); |
| 25967 | } |
| 25968 | } |
| 25969 | else |
| 25970 | { |
| 25971 | const char *cmp_name; // Name to compare with alias |
| 25972 | if (view_name.str) |
| 25973 | { |
| 25974 | // A view |
| 25975 | |
| 25976 | if (!(belong_to_view && |
| 25977 | belong_to_view->compact_view_format)) |
| 25978 | { |
| 25979 | append_identifier(thd, str, &view_db); |
| 25980 | str->append('.'); |
| 25981 | } |
| 25982 | append_identifier(thd, str, &view_name); |
| 25983 | cmp_name= view_name.str; |
| 25984 | } |
| 25985 | else if (derived) |
| 25986 | { |
| 25987 | if (!is_with_table()) |
| 25988 | { |
| 25989 | // A derived table |
| 25990 | str->append('('); |
| 25991 | derived->print(str, query_type); |
| 25992 | str->append(')'); |
| 25993 | cmp_name= "" ; // Force printing of alias |
| 25994 | } |
| 25995 | else |
| 25996 | { |
| 25997 | append_identifier(thd, str, &table_name); |
| 25998 | cmp_name= table_name.str; |
| 25999 | } |
| 26000 | } |
| 26001 | else |
| 26002 | { |
| 26003 | // A normal table |
| 26004 | |
| 26005 | if (!(belong_to_view && |
| 26006 | belong_to_view->compact_view_format)) |
| 26007 | { |
| 26008 | append_identifier(thd, str, &db); |
| 26009 | str->append('.'); |
| 26010 | } |
| 26011 | if (schema_table) |
| 26012 | { |
| 26013 | append_identifier(thd, str, &schema_table_name); |
| 26014 | cmp_name= schema_table_name.str; |
| 26015 | } |
| 26016 | else |
| 26017 | { |
| 26018 | append_identifier(thd, str, &table_name); |
| 26019 | cmp_name= table_name.str; |
| 26020 | } |
| 26021 | #ifdef WITH_PARTITION_STORAGE_ENGINE |
| 26022 | if (partition_names && partition_names->elements) |
| 26023 | { |
| 26024 | int i, num_parts= partition_names->elements; |
| 26025 | List_iterator<String> name_it(*(partition_names)); |
| 26026 | str->append(STRING_WITH_LEN(" PARTITION (" )); |
| 26027 | for (i= 1; i <= num_parts; i++) |
| 26028 | { |
| 26029 | String *name= name_it++; |
| 26030 | append_identifier(thd, str, name->c_ptr(), name->length()); |
| 26031 | if (i != num_parts) |
| 26032 | str->append(','); |
| 26033 | } |
| 26034 | str->append(')'); |
| 26035 | } |
| 26036 | #endif /* WITH_PARTITION_STORAGE_ENGINE */ |
| 26037 | } |
| 26038 | if (table && table->versioned()) |
| 26039 | vers_conditions.print(str, query_type); |
| 26040 | |
| 26041 | if (my_strcasecmp(table_alias_charset, cmp_name, alias.str)) |
| 26042 | { |
| 26043 | char t_alias_buff[MAX_ALIAS_NAME]; |
| 26044 | LEX_CSTRING t_alias= alias; |
| 26045 | |
| 26046 | str->append(' '); |
| 26047 | if (lower_case_table_names== 1) |
| 26048 | { |
| 26049 | if (alias.str && alias.str[0]) |
| 26050 | { |
| 26051 | strmov(t_alias_buff, alias.str); |
| 26052 | t_alias.length= my_casedn_str(files_charset_info, t_alias_buff); |
| 26053 | t_alias.str= t_alias_buff; |
| 26054 | } |
| 26055 | } |
| 26056 | |
| 26057 | append_identifier(thd, str, &t_alias); |
| 26058 | } |
| 26059 | |
| 26060 | if (index_hints) |
| 26061 | { |
| 26062 | List_iterator<Index_hint> it(*index_hints); |
| 26063 | Index_hint *hint; |
| 26064 | |
| 26065 | while ((hint= it++)) |
| 26066 | { |
| 26067 | str->append (STRING_WITH_LEN(" " )); |
| 26068 | hint->print (thd, str); |
| 26069 | } |
| 26070 | } |
| 26071 | } |
| 26072 | } |
| 26073 | |
| 26074 | |
| 26075 | void st_select_lex::print(THD *thd, String *str, enum_query_type query_type) |
| 26076 | { |
| 26077 | DBUG_ASSERT(thd); |
| 26078 | |
| 26079 | if (tvc) |
| 26080 | { |
| 26081 | tvc->print(thd, str, query_type); |
| 26082 | return; |
| 26083 | } |
| 26084 | |
| 26085 | if ((query_type & QT_SHOW_SELECT_NUMBER) && |
| 26086 | thd->lex->all_selects_list && |
| 26087 | thd->lex->all_selects_list->link_next && |
| 26088 | select_number != UINT_MAX && |
| 26089 | select_number != INT_MAX) |
| 26090 | { |
| 26091 | str->append("/* select#" ); |
| 26092 | str->append_ulonglong(select_number); |
| 26093 | str->append(" */ " ); |
| 26094 | } |
| 26095 | |
| 26096 | str->append(STRING_WITH_LEN("select " )); |
| 26097 | |
| 26098 | if (join && join->cleaned) |
| 26099 | { |
| 26100 | /* |
| 26101 | JOIN already cleaned up so it is dangerous to print items |
| 26102 | because temporary tables they pointed on could be freed. |
| 26103 | */ |
| 26104 | str->append('#'); |
| 26105 | str->append(select_number); |
| 26106 | return; |
| 26107 | } |
| 26108 | |
| 26109 | /* First add options */ |
| 26110 | if (options & SELECT_STRAIGHT_JOIN) |
| 26111 | str->append(STRING_WITH_LEN("straight_join " )); |
| 26112 | if (options & SELECT_HIGH_PRIORITY) |
| 26113 | str->append(STRING_WITH_LEN("high_priority " )); |
| 26114 | if (options & SELECT_DISTINCT) |
| 26115 | str->append(STRING_WITH_LEN("distinct " )); |
| 26116 | if (options & SELECT_SMALL_RESULT) |
| 26117 | str->append(STRING_WITH_LEN("sql_small_result " )); |
| 26118 | if (options & SELECT_BIG_RESULT) |
| 26119 | str->append(STRING_WITH_LEN("sql_big_result " )); |
| 26120 | if (options & OPTION_BUFFER_RESULT) |
| 26121 | str->append(STRING_WITH_LEN("sql_buffer_result " )); |
| 26122 | if (options & OPTION_FOUND_ROWS) |
| 26123 | str->append(STRING_WITH_LEN("sql_calc_found_rows " )); |
| 26124 | switch (sql_cache) |
| 26125 | { |
| 26126 | case SQL_NO_CACHE: |
| 26127 | str->append(STRING_WITH_LEN("sql_no_cache " )); |
| 26128 | break; |
| 26129 | case SQL_CACHE: |
| 26130 | str->append(STRING_WITH_LEN("sql_cache " )); |
| 26131 | break; |
| 26132 | case SQL_CACHE_UNSPECIFIED: |
| 26133 | break; |
| 26134 | default: |
| 26135 | DBUG_ASSERT(0); |
| 26136 | } |
| 26137 | |
| 26138 | //Item List |
| 26139 | bool first= 1; |
| 26140 | List_iterator_fast<Item> it(item_list); |
| 26141 | Item *item; |
| 26142 | while ((item= it++)) |
| 26143 | { |
| 26144 | if (first) |
| 26145 | first= 0; |
| 26146 | else |
| 26147 | str->append(','); |
| 26148 | |
| 26149 | if (is_subquery_function() && item->is_autogenerated_name) |
| 26150 | { |
| 26151 | /* |
| 26152 | Do not print auto-generated aliases in subqueries. It has no purpose |
| 26153 | in a view definition or other contexts where the query is printed. |
| 26154 | */ |
| 26155 | item->print(str, query_type); |
| 26156 | } |
| 26157 | else |
| 26158 | item->print_item_w_name(str, query_type); |
| 26159 | } |
| 26160 | |
| 26161 | /* |
| 26162 | from clause |
| 26163 | TODO: support USING/FORCE/IGNORE index |
| 26164 | */ |
| 26165 | if (table_list.elements) |
| 26166 | { |
| 26167 | str->append(STRING_WITH_LEN(" from " )); |
| 26168 | /* go through join tree */ |
| 26169 | print_join(thd, join? join->eliminated_tables: 0, str, &top_join_list, query_type); |
| 26170 | } |
| 26171 | else if (where) |
| 26172 | { |
| 26173 | /* |
| 26174 | "SELECT 1 FROM DUAL WHERE 2" should not be printed as |
| 26175 | "SELECT 1 WHERE 2": the 1st syntax is valid, but the 2nd is not. |
| 26176 | */ |
| 26177 | str->append(STRING_WITH_LEN(" from DUAL " )); |
| 26178 | } |
| 26179 | |
| 26180 | // Where |
| 26181 | Item *cur_where= where; |
| 26182 | if (join) |
| 26183 | cur_where= join->conds; |
| 26184 | if (cur_where || cond_value != Item::COND_UNDEF) |
| 26185 | { |
| 26186 | str->append(STRING_WITH_LEN(" where " )); |
| 26187 | if (cur_where) |
| 26188 | cur_where->print(str, query_type); |
| 26189 | else |
| 26190 | str->append(cond_value != Item::COND_FALSE ? "1" : "0" ); |
| 26191 | } |
| 26192 | |
| 26193 | // group by & olap |
| 26194 | if (group_list.elements) |
| 26195 | { |
| 26196 | str->append(STRING_WITH_LEN(" group by " )); |
| 26197 | print_order(str, group_list.first, query_type); |
| 26198 | switch (olap) |
| 26199 | { |
| 26200 | case CUBE_TYPE: |
| 26201 | str->append(STRING_WITH_LEN(" with cube" )); |
| 26202 | break; |
| 26203 | case ROLLUP_TYPE: |
| 26204 | str->append(STRING_WITH_LEN(" with rollup" )); |
| 26205 | break; |
| 26206 | default: |
| 26207 | ; //satisfy compiler |
| 26208 | } |
| 26209 | } |
| 26210 | |
| 26211 | // having |
| 26212 | Item *cur_having= having; |
| 26213 | if (join) |
| 26214 | cur_having= join->having; |
| 26215 | |
| 26216 | if (cur_having || having_value != Item::COND_UNDEF) |
| 26217 | { |
| 26218 | str->append(STRING_WITH_LEN(" having " )); |
| 26219 | if (cur_having) |
| 26220 | cur_having->print(str, query_type); |
| 26221 | else |
| 26222 | str->append(having_value != Item::COND_FALSE ? "1" : "0" ); |
| 26223 | } |
| 26224 | |
| 26225 | if (order_list.elements) |
| 26226 | { |
| 26227 | str->append(STRING_WITH_LEN(" order by " )); |
| 26228 | print_order(str, order_list.first, query_type); |
| 26229 | } |
| 26230 | |
| 26231 | // limit |
| 26232 | print_limit(thd, str, query_type); |
| 26233 | |
| 26234 | // lock type |
| 26235 | if (lock_type == TL_READ_WITH_SHARED_LOCKS) |
| 26236 | str->append(" lock in share mode" ); |
| 26237 | else if (lock_type == TL_WRITE) |
| 26238 | str->append(" for update" ); |
| 26239 | |
| 26240 | // PROCEDURE unsupported here |
| 26241 | } |
| 26242 | |
| 26243 | |
| 26244 | /** |
| 26245 | Change the select_result object of the JOIN. |
| 26246 | |
| 26247 | If old_result is not used, forward the call to the current |
| 26248 | select_result in case it is a wrapper around old_result. |
| 26249 | |
| 26250 | Call prepare() and prepare2() on the new select_result if we decide |
| 26251 | to use it. |
| 26252 | |
| 26253 | @param new_result New select_result object |
| 26254 | @param old_result Old select_result object (NULL to force change) |
| 26255 | |
| 26256 | @retval false Success |
| 26257 | @retval true Error |
| 26258 | */ |
| 26259 | |
| 26260 | bool JOIN::change_result(select_result *new_result, select_result *old_result) |
| 26261 | { |
| 26262 | DBUG_ENTER("JOIN::change_result" ); |
| 26263 | if (old_result == NULL || result == old_result) |
| 26264 | { |
| 26265 | result= new_result; |
| 26266 | if (result->prepare(fields_list, select_lex->master_unit()) || |
| 26267 | result->prepare2(this)) |
| 26268 | DBUG_RETURN(true); /* purecov: inspected */ |
| 26269 | DBUG_RETURN(false); |
| 26270 | } |
| 26271 | DBUG_RETURN(result->change_result(new_result)); |
| 26272 | } |
| 26273 | |
| 26274 | |
| 26275 | /** |
| 26276 | @brief |
| 26277 | Set allowed types of join caches that can be used for join operations |
| 26278 | |
| 26279 | @details |
| 26280 | The function sets a bitmap of allowed join buffers types in the field |
| 26281 | allowed_join_cache_types of this JOIN structure: |
| 26282 | bit 1 is set if tjoin buffers are allowed to be incremental |
| 26283 | bit 2 is set if the join buffers are allowed to be hashed |
| 26284 | but 3 is set if the join buffers are allowed to be used for BKA |
| 26285 | join algorithms. |
| 26286 | The allowed types are read from system variables. |
| 26287 | Besides the function sets maximum allowed join cache level that is |
| 26288 | also read from a system variable. |
| 26289 | */ |
| 26290 | |
| 26291 | void JOIN::set_allowed_join_cache_types() |
| 26292 | { |
| 26293 | allowed_join_cache_types= 0; |
| 26294 | if (optimizer_flag(thd, OPTIMIZER_SWITCH_JOIN_CACHE_INCREMENTAL)) |
| 26295 | allowed_join_cache_types|= JOIN_CACHE_INCREMENTAL_BIT; |
| 26296 | if (optimizer_flag(thd, OPTIMIZER_SWITCH_JOIN_CACHE_HASHED)) |
| 26297 | allowed_join_cache_types|= JOIN_CACHE_HASHED_BIT; |
| 26298 | if (optimizer_flag(thd, OPTIMIZER_SWITCH_JOIN_CACHE_BKA)) |
| 26299 | allowed_join_cache_types|= JOIN_CACHE_BKA_BIT; |
| 26300 | allowed_semijoin_with_cache= |
| 26301 | optimizer_flag(thd, OPTIMIZER_SWITCH_SEMIJOIN_WITH_CACHE); |
| 26302 | allowed_outer_join_with_cache= |
| 26303 | optimizer_flag(thd, OPTIMIZER_SWITCH_OUTER_JOIN_WITH_CACHE); |
| 26304 | max_allowed_join_cache_level= thd->variables.join_cache_level; |
| 26305 | } |
| 26306 | |
| 26307 | |
| 26308 | /** |
| 26309 | Save a query execution plan so that the caller can revert to it if needed, |
| 26310 | and reset the current query plan so that it can be reoptimized. |
| 26311 | |
| 26312 | @param save_to The object into which the current query plan state is saved |
| 26313 | */ |
| 26314 | |
| 26315 | void JOIN::save_query_plan(Join_plan_state *save_to) |
| 26316 | { |
| 26317 | if (keyuse.elements) |
| 26318 | { |
| 26319 | DYNAMIC_ARRAY tmp_keyuse; |
| 26320 | /* Swap the current and the backup keyuse internal arrays. */ |
| 26321 | tmp_keyuse= keyuse; |
| 26322 | keyuse= save_to->keyuse; /* keyuse is reset to an empty array. */ |
| 26323 | save_to->keyuse= tmp_keyuse; |
| 26324 | |
| 26325 | for (uint i= 0; i < table_count; i++) |
| 26326 | { |
| 26327 | save_to->join_tab_keyuse[i]= join_tab[i].keyuse; |
| 26328 | join_tab[i].keyuse= NULL; |
| 26329 | save_to->join_tab_checked_keys[i]= join_tab[i].checked_keys; |
| 26330 | join_tab[i].checked_keys.clear_all(); |
| 26331 | } |
| 26332 | } |
| 26333 | memcpy((uchar*) save_to->best_positions, (uchar*) best_positions, |
| 26334 | sizeof(POSITION) * (table_count + 1)); |
| 26335 | memset((uchar*) best_positions, 0, sizeof(POSITION) * (table_count + 1)); |
| 26336 | |
| 26337 | /* Save SJM nests */ |
| 26338 | List_iterator<TABLE_LIST> it(select_lex->sj_nests); |
| 26339 | TABLE_LIST *tlist; |
| 26340 | SJ_MATERIALIZATION_INFO **p_info= save_to->sj_mat_info; |
| 26341 | while ((tlist= it++)) |
| 26342 | { |
| 26343 | *(p_info++)= tlist->sj_mat_info; |
| 26344 | } |
| 26345 | } |
| 26346 | |
| 26347 | |
| 26348 | /** |
| 26349 | Reset a query execution plan so that it can be reoptimized in-place. |
| 26350 | */ |
| 26351 | void JOIN::reset_query_plan() |
| 26352 | { |
| 26353 | for (uint i= 0; i < table_count; i++) |
| 26354 | { |
| 26355 | join_tab[i].keyuse= NULL; |
| 26356 | join_tab[i].checked_keys.clear_all(); |
| 26357 | } |
| 26358 | } |
| 26359 | |
| 26360 | |
| 26361 | /** |
| 26362 | Restore a query execution plan previously saved by the caller. |
| 26363 | |
| 26364 | @param The object from which the current query plan state is restored. |
| 26365 | */ |
| 26366 | |
| 26367 | void JOIN::restore_query_plan(Join_plan_state *restore_from) |
| 26368 | { |
| 26369 | if (restore_from->keyuse.elements) |
| 26370 | { |
| 26371 | DYNAMIC_ARRAY tmp_keyuse; |
| 26372 | tmp_keyuse= keyuse; |
| 26373 | keyuse= restore_from->keyuse; |
| 26374 | restore_from->keyuse= tmp_keyuse; |
| 26375 | |
| 26376 | for (uint i= 0; i < table_count; i++) |
| 26377 | { |
| 26378 | join_tab[i].keyuse= restore_from->join_tab_keyuse[i]; |
| 26379 | join_tab[i].checked_keys= restore_from->join_tab_checked_keys[i]; |
| 26380 | } |
| 26381 | |
| 26382 | } |
| 26383 | memcpy((uchar*) best_positions, (uchar*) restore_from->best_positions, |
| 26384 | sizeof(POSITION) * (table_count + 1)); |
| 26385 | /* Restore SJM nests */ |
| 26386 | List_iterator<TABLE_LIST> it(select_lex->sj_nests); |
| 26387 | TABLE_LIST *tlist; |
| 26388 | SJ_MATERIALIZATION_INFO **p_info= restore_from->sj_mat_info; |
| 26389 | while ((tlist= it++)) |
| 26390 | { |
| 26391 | tlist->sj_mat_info= *(p_info++); |
| 26392 | } |
| 26393 | } |
| 26394 | |
| 26395 | |
| 26396 | /** |
| 26397 | Reoptimize a query plan taking into account an additional conjunct to the |
| 26398 | WHERE clause. |
| 26399 | |
| 26400 | @param added_where An extra conjunct to the WHERE clause to reoptimize with |
| 26401 | @param join_tables The set of tables to reoptimize |
| 26402 | @param save_to If != NULL, save here the state of the current query plan, |
| 26403 | otherwise reuse the existing query plan structures. |
| 26404 | |
| 26405 | @notes |
| 26406 | Given a query plan that was already optimized taking into account some WHERE |
| 26407 | clause 'C', reoptimize this plan with a new WHERE clause 'C AND added_where'. |
| 26408 | The reoptimization works as follows: |
| 26409 | |
| 26410 | 1. Call update_ref_and_keys *only* for the new conditions 'added_where' |
| 26411 | that are about to be injected into the query. |
| 26412 | 2. Expand if necessary the original KEYUSE array JOIN::keyuse to |
| 26413 | accommodate the new REF accesses computed for the 'added_where' condition. |
| 26414 | 3. Add the new KEYUSEs into JOIN::keyuse. |
| 26415 | 4. Re-sort and re-filter the JOIN::keyuse array with the newly added |
| 26416 | KEYUSE elements. |
| 26417 | |
| 26418 | @retval REOPT_NEW_PLAN there is a new plan. |
| 26419 | @retval REOPT_OLD_PLAN no new improved plan was produced, use the old one. |
| 26420 | @retval REOPT_ERROR an irrecovarable error occurred during reoptimization. |
| 26421 | */ |
| 26422 | |
| 26423 | JOIN::enum_reopt_result |
| 26424 | JOIN::reoptimize(Item *added_where, table_map join_tables, |
| 26425 | Join_plan_state *save_to) |
| 26426 | { |
| 26427 | DYNAMIC_ARRAY added_keyuse; |
| 26428 | SARGABLE_PARAM *sargables= 0; /* Used only as a dummy parameter. */ |
| 26429 | uint org_keyuse_elements; |
| 26430 | |
| 26431 | /* Re-run the REF optimizer to take into account the new conditions. */ |
| 26432 | if (update_ref_and_keys(thd, &added_keyuse, join_tab, table_count, added_where, |
| 26433 | ~outer_join, select_lex, &sargables)) |
| 26434 | { |
| 26435 | delete_dynamic(&added_keyuse); |
| 26436 | return REOPT_ERROR; |
| 26437 | } |
| 26438 | |
| 26439 | if (!added_keyuse.elements) |
| 26440 | { |
| 26441 | delete_dynamic(&added_keyuse); |
| 26442 | return REOPT_OLD_PLAN; |
| 26443 | } |
| 26444 | |
| 26445 | if (save_to) |
| 26446 | save_query_plan(save_to); |
| 26447 | else |
| 26448 | reset_query_plan(); |
| 26449 | |
| 26450 | if (!keyuse.buffer && |
| 26451 | my_init_dynamic_array(&keyuse, sizeof(KEYUSE), 20, 64, |
| 26452 | MYF(MY_THREAD_SPECIFIC))) |
| 26453 | { |
| 26454 | delete_dynamic(&added_keyuse); |
| 26455 | return REOPT_ERROR; |
| 26456 | } |
| 26457 | |
| 26458 | org_keyuse_elements= save_to ? save_to->keyuse.elements : keyuse.elements; |
| 26459 | allocate_dynamic(&keyuse, org_keyuse_elements + added_keyuse.elements); |
| 26460 | |
| 26461 | /* If needed, add the access methods from the original query plan. */ |
| 26462 | if (save_to) |
| 26463 | { |
| 26464 | DBUG_ASSERT(!keyuse.elements); |
| 26465 | memcpy(keyuse.buffer, |
| 26466 | save_to->keyuse.buffer, |
| 26467 | (size_t) save_to->keyuse.elements * keyuse.size_of_element); |
| 26468 | keyuse.elements= save_to->keyuse.elements; |
| 26469 | } |
| 26470 | |
| 26471 | /* Add the new access methods to the keyuse array. */ |
| 26472 | memcpy(keyuse.buffer + keyuse.elements * keyuse.size_of_element, |
| 26473 | added_keyuse.buffer, |
| 26474 | (size_t) added_keyuse.elements * added_keyuse.size_of_element); |
| 26475 | keyuse.elements+= added_keyuse.elements; |
| 26476 | /* added_keyuse contents is copied, and it is no longer needed. */ |
| 26477 | delete_dynamic(&added_keyuse); |
| 26478 | |
| 26479 | if (sort_and_filter_keyuse(thd, &keyuse, true)) |
| 26480 | return REOPT_ERROR; |
| 26481 | optimize_keyuse(this, &keyuse); |
| 26482 | |
| 26483 | if (optimize_semijoin_nests(this, join_tables)) |
| 26484 | return REOPT_ERROR; |
| 26485 | |
| 26486 | /* Re-run the join optimizer to compute a new query plan. */ |
| 26487 | if (choose_plan(this, join_tables)) |
| 26488 | return REOPT_ERROR; |
| 26489 | |
| 26490 | return REOPT_NEW_PLAN; |
| 26491 | } |
| 26492 | |
| 26493 | |
| 26494 | /** |
| 26495 | Cache constant expressions in WHERE, HAVING, ON conditions. |
| 26496 | */ |
| 26497 | |
| 26498 | void JOIN::cache_const_exprs() |
| 26499 | { |
| 26500 | bool cache_flag= FALSE; |
| 26501 | bool *analyzer_arg= &cache_flag; |
| 26502 | |
| 26503 | /* No need in cache if all tables are constant. */ |
| 26504 | if (const_tables == table_count) |
| 26505 | return; |
| 26506 | |
| 26507 | if (conds) |
| 26508 | conds->compile(thd, &Item::cache_const_expr_analyzer, (uchar **)&analyzer_arg, |
| 26509 | &Item::cache_const_expr_transformer, (uchar *)&cache_flag); |
| 26510 | cache_flag= FALSE; |
| 26511 | if (having) |
| 26512 | having->compile(thd, &Item::cache_const_expr_analyzer, (uchar **)&analyzer_arg, |
| 26513 | &Item::cache_const_expr_transformer, (uchar *)&cache_flag); |
| 26514 | |
| 26515 | for (JOIN_TAB *tab= first_depth_first_tab(this); tab; |
| 26516 | tab= next_depth_first_tab(this, tab)) |
| 26517 | { |
| 26518 | if (*tab->on_expr_ref) |
| 26519 | { |
| 26520 | cache_flag= FALSE; |
| 26521 | (*tab->on_expr_ref)->compile(thd, &Item::cache_const_expr_analyzer, |
| 26522 | (uchar **)&analyzer_arg, |
| 26523 | &Item::cache_const_expr_transformer, |
| 26524 | (uchar *)&cache_flag); |
| 26525 | } |
| 26526 | } |
| 26527 | } |
| 26528 | |
| 26529 | |
| 26530 | /* |
| 26531 | Get a cost of reading rows_limit rows through index keynr. |
| 26532 | |
| 26533 | @detail |
| 26534 | - If there is a quick select, we try to use it. |
| 26535 | - if there is a ref(const) access, we try to use it, too. |
| 26536 | - quick and ref(const) use different cost formulas, so if both are possible |
| 26537 | we should make a cost-based choice. |
| 26538 | |
| 26539 | @param tab JOIN_TAB with table access (is NULL for single-table |
| 26540 | UPDATE/DELETE) |
| 26541 | @param read_time OUT Cost of reading using quick or ref(const) access. |
| 26542 | |
| 26543 | |
| 26544 | @return |
| 26545 | true There was a possible quick or ref access, its cost is in the OUT |
| 26546 | parameters. |
| 26547 | false No quick or ref(const) possible (and so, the caller will attempt |
| 26548 | to use a full index scan on this index). |
| 26549 | */ |
| 26550 | |
| 26551 | static bool get_range_limit_read_cost(const JOIN_TAB *tab, |
| 26552 | const TABLE *table, |
| 26553 | uint keynr, |
| 26554 | ha_rows rows_limit, |
| 26555 | double *read_time) |
| 26556 | { |
| 26557 | bool res= false; |
| 26558 | /* |
| 26559 | We need to adjust the estimates if we had a quick select (or ref(const)) on |
| 26560 | index keynr. |
| 26561 | */ |
| 26562 | if (table->quick_keys.is_set(keynr)) |
| 26563 | { |
| 26564 | /* |
| 26565 | Start from quick select's rows and cost. These are always cheaper than |
| 26566 | full index scan/cost. |
| 26567 | */ |
| 26568 | double best_rows= (double)table->quick_rows[keynr]; |
| 26569 | double best_cost= (double)table->quick_costs[keynr]; |
| 26570 | |
| 26571 | /* |
| 26572 | Check if ref(const) access was possible on this index. |
| 26573 | */ |
| 26574 | if (tab) |
| 26575 | { |
| 26576 | key_part_map const_parts= 0; |
| 26577 | key_part_map map= 1; |
| 26578 | uint kp; |
| 26579 | /* Find how many key parts would be used by ref(const) */ |
| 26580 | for (kp=0; kp < MAX_REF_PARTS; map=map << 1, kp++) |
| 26581 | { |
| 26582 | if (!(table->const_key_parts[keynr] & map)) |
| 26583 | break; |
| 26584 | const_parts |= map; |
| 26585 | } |
| 26586 | |
| 26587 | if (kp > 0) |
| 26588 | { |
| 26589 | ha_rows ref_rows; |
| 26590 | /* |
| 26591 | Two possible cases: |
| 26592 | 1. ref(const) uses the same #key parts as range access. |
| 26593 | 2. ref(const) uses fewer key parts, becasue there is a |
| 26594 | range_cond(key_part+1). |
| 26595 | */ |
| 26596 | if (kp == table->quick_key_parts[keynr]) |
| 26597 | ref_rows= table->quick_rows[keynr]; |
| 26598 | else |
| 26599 | ref_rows= (ha_rows) table->key_info[keynr].actual_rec_per_key(kp-1); |
| 26600 | |
| 26601 | if (ref_rows > 0) |
| 26602 | { |
| 26603 | double tmp= (double)ref_rows; |
| 26604 | /* Reuse the cost formula from best_access_path: */ |
| 26605 | set_if_smaller(tmp, (double) tab->join->thd->variables.max_seeks_for_key); |
| 26606 | if (table->covering_keys.is_set(keynr)) |
| 26607 | tmp= table->file->keyread_time(keynr, 1, (ha_rows) tmp); |
| 26608 | else |
| 26609 | tmp= table->file->read_time(keynr, 1, |
| 26610 | (ha_rows) MY_MIN(tmp,tab->worst_seeks)); |
| 26611 | if (tmp < best_cost) |
| 26612 | { |
| 26613 | best_cost= tmp; |
| 26614 | best_rows= (double)ref_rows; |
| 26615 | } |
| 26616 | } |
| 26617 | } |
| 26618 | } |
| 26619 | |
| 26620 | if (best_rows > rows_limit) |
| 26621 | { |
| 26622 | /* |
| 26623 | LIMIT clause specifies that we will need to read fewer records than |
| 26624 | quick select will return. Assume that quick select's cost is |
| 26625 | proportional to the number of records we need to return (e.g. if we |
| 26626 | only need 1/3rd of records, it will cost us 1/3rd of quick select's |
| 26627 | read time) |
| 26628 | */ |
| 26629 | best_cost *= rows_limit / best_rows; |
| 26630 | } |
| 26631 | *read_time= best_cost; |
| 26632 | res= true; |
| 26633 | } |
| 26634 | return res; |
| 26635 | } |
| 26636 | |
| 26637 | |
| 26638 | /** |
| 26639 | Find a cheaper access key than a given @a key |
| 26640 | |
| 26641 | @param tab NULL or JOIN_TAB of the accessed table |
| 26642 | @param order Linked list of ORDER BY arguments |
| 26643 | @param table Table if tab == NULL or tab->table |
| 26644 | @param usable_keys Key map to find a cheaper key in |
| 26645 | @param ref_key |
| 26646 | 0 <= key < MAX_KEY - Key that is currently used for finding |
| 26647 | row |
| 26648 | MAX_KEY - means index_merge is used |
| 26649 | -1 - means we're currently not using an |
| 26650 | index to find rows. |
| 26651 | |
| 26652 | @param select_limit LIMIT value |
| 26653 | @param [out] new_key Key number if success, otherwise undefined |
| 26654 | @param [out] new_key_direction Return -1 (reverse) or +1 if success, |
| 26655 | otherwise undefined |
| 26656 | @param [out] new_select_limit Return adjusted LIMIT |
| 26657 | @param [out] new_used_key_parts NULL by default, otherwise return number |
| 26658 | of new_key prefix columns if success |
| 26659 | or undefined if the function fails |
| 26660 | @param [out] saved_best_key_parts NULL by default, otherwise preserve the |
| 26661 | value for further use in QUICK_SELECT_DESC |
| 26662 | |
| 26663 | @note |
| 26664 | This function takes into account table->quick_condition_rows statistic |
| 26665 | (that is calculated by the make_join_statistics function). |
| 26666 | However, single table procedures such as mysql_update() and mysql_delete() |
| 26667 | never call make_join_statistics, so they have to update it manually |
| 26668 | (@see get_index_for_order()). |
| 26669 | */ |
| 26670 | |
| 26671 | static bool |
| 26672 | test_if_cheaper_ordering(const JOIN_TAB *tab, ORDER *order, TABLE *table, |
| 26673 | key_map usable_keys, int ref_key, |
| 26674 | ha_rows select_limit_arg, |
| 26675 | int *new_key, int *new_key_direction, |
| 26676 | ha_rows *new_select_limit, uint *new_used_key_parts, |
| 26677 | uint *saved_best_key_parts) |
| 26678 | { |
| 26679 | DBUG_ENTER("test_if_cheaper_ordering" ); |
| 26680 | /* |
| 26681 | Check whether there is an index compatible with the given order |
| 26682 | usage of which is cheaper than usage of the ref_key index (ref_key>=0) |
| 26683 | or a table scan. |
| 26684 | It may be the case if ORDER/GROUP BY is used with LIMIT. |
| 26685 | */ |
| 26686 | ha_rows best_select_limit= HA_POS_ERROR; |
| 26687 | JOIN *join= tab ? tab->join : NULL; |
| 26688 | uint nr; |
| 26689 | key_map keys; |
| 26690 | uint best_key_parts= 0; |
| 26691 | int best_key_direction= 0; |
| 26692 | ha_rows best_records= 0; |
| 26693 | double read_time; |
| 26694 | int best_key= -1; |
| 26695 | bool is_best_covering= FALSE; |
| 26696 | double fanout= 1; |
| 26697 | ha_rows table_records= table->stat_records(); |
| 26698 | bool group= join && join->group && order == join->group_list; |
| 26699 | ha_rows refkey_rows_estimate= table->quick_condition_rows; |
| 26700 | const bool has_limit= (select_limit_arg != HA_POS_ERROR); |
| 26701 | |
| 26702 | /* |
| 26703 | If not used with LIMIT, only use keys if the whole query can be |
| 26704 | resolved with a key; This is because filesort() is usually faster than |
| 26705 | retrieving all rows through an index. |
| 26706 | */ |
| 26707 | if (select_limit_arg >= table_records) |
| 26708 | { |
| 26709 | keys= *table->file->keys_to_use_for_scanning(); |
| 26710 | keys.merge(table->covering_keys); |
| 26711 | |
| 26712 | /* |
| 26713 | We are adding here also the index specified in FORCE INDEX clause, |
| 26714 | if any. |
| 26715 | This is to allow users to use index in ORDER BY. |
| 26716 | */ |
| 26717 | if (table->force_index) |
| 26718 | keys.merge(group ? table->keys_in_use_for_group_by : |
| 26719 | table->keys_in_use_for_order_by); |
| 26720 | keys.intersect(usable_keys); |
| 26721 | } |
| 26722 | else |
| 26723 | keys= usable_keys; |
| 26724 | |
| 26725 | if (join) |
| 26726 | { |
| 26727 | uint tablenr= (uint)(tab - join->join_tab); |
| 26728 | read_time= join->best_positions[tablenr].read_time; |
| 26729 | for (uint i= tablenr+1; i < join->table_count; i++) |
| 26730 | fanout*= join->best_positions[i].records_read; // fanout is always >= 1 |
| 26731 | } |
| 26732 | else |
| 26733 | read_time= table->file->scan_time(); |
| 26734 | |
| 26735 | /* |
| 26736 | TODO: add cost of sorting here. |
| 26737 | */ |
| 26738 | read_time += COST_EPS; |
| 26739 | |
| 26740 | /* |
| 26741 | Calculate the selectivity of the ref_key for REF_ACCESS. For |
| 26742 | RANGE_ACCESS we use table->quick_condition_rows. |
| 26743 | */ |
| 26744 | if (ref_key >= 0 && ref_key != MAX_KEY && tab->type == JT_REF) |
| 26745 | { |
| 26746 | if (table->quick_keys.is_set(ref_key)) |
| 26747 | refkey_rows_estimate= table->quick_rows[ref_key]; |
| 26748 | else |
| 26749 | { |
| 26750 | const KEY *ref_keyinfo= table->key_info + ref_key; |
| 26751 | refkey_rows_estimate= ref_keyinfo->rec_per_key[tab->ref.key_parts - 1]; |
| 26752 | } |
| 26753 | set_if_bigger(refkey_rows_estimate, 1); |
| 26754 | } |
| 26755 | |
| 26756 | for (nr=0; nr < table->s->keys ; nr++) |
| 26757 | { |
| 26758 | int direction; |
| 26759 | ha_rows select_limit= select_limit_arg; |
| 26760 | uint used_key_parts= 0; |
| 26761 | |
| 26762 | if (keys.is_set(nr) && |
| 26763 | (direction= test_if_order_by_key(join, order, table, nr, |
| 26764 | &used_key_parts))) |
| 26765 | { |
| 26766 | /* |
| 26767 | At this point we are sure that ref_key is a non-ordering |
| 26768 | key (where "ordering key" is a key that will return rows |
| 26769 | in the order required by ORDER BY). |
| 26770 | */ |
| 26771 | DBUG_ASSERT (ref_key != (int) nr); |
| 26772 | |
| 26773 | bool is_covering= (table->covering_keys.is_set(nr) || |
| 26774 | (table->file->index_flags(nr, 0, 1) & |
| 26775 | HA_CLUSTERED_INDEX)); |
| 26776 | /* |
| 26777 | Don't use an index scan with ORDER BY without limit. |
| 26778 | For GROUP BY without limit always use index scan |
| 26779 | if there is a suitable index. |
| 26780 | Why we hold to this asymmetry hardly can be explained |
| 26781 | rationally. It's easy to demonstrate that using |
| 26782 | temporary table + filesort could be cheaper for grouping |
| 26783 | queries too. |
| 26784 | */ |
| 26785 | if (is_covering || |
| 26786 | select_limit != HA_POS_ERROR || |
| 26787 | (ref_key < 0 && (group || table->force_index))) |
| 26788 | { |
| 26789 | double rec_per_key; |
| 26790 | double index_scan_time; |
| 26791 | KEY *keyinfo= table->key_info+nr; |
| 26792 | if (select_limit == HA_POS_ERROR) |
| 26793 | select_limit= table_records; |
| 26794 | if (group) |
| 26795 | { |
| 26796 | /* |
| 26797 | Used_key_parts can be larger than keyinfo->user_defined_key_parts |
| 26798 | when using a secondary index clustered with a primary |
| 26799 | key (e.g. as in Innodb). |
| 26800 | See Bug #28591 for details. |
| 26801 | */ |
| 26802 | uint used_index_parts= keyinfo->user_defined_key_parts; |
| 26803 | uint used_pk_parts= 0; |
| 26804 | if (used_key_parts > used_index_parts) |
| 26805 | used_pk_parts= used_key_parts-used_index_parts; |
| 26806 | rec_per_key= used_key_parts ? |
| 26807 | keyinfo->actual_rec_per_key(used_key_parts-1) : 1; |
| 26808 | /* Take into account the selectivity of the used pk prefix */ |
| 26809 | if (used_pk_parts) |
| 26810 | { |
| 26811 | KEY *pkinfo=tab->table->key_info+table->s->primary_key; |
| 26812 | /* |
| 26813 | If the values of of records per key for the prefixes |
| 26814 | of the primary key are considered unknown we assume |
| 26815 | they are equal to 1. |
| 26816 | */ |
| 26817 | if (used_key_parts == pkinfo->user_defined_key_parts || |
| 26818 | pkinfo->rec_per_key[0] == 0) |
| 26819 | rec_per_key= 1; |
| 26820 | if (rec_per_key > 1) |
| 26821 | { |
| 26822 | rec_per_key*= pkinfo->actual_rec_per_key(used_pk_parts-1); |
| 26823 | rec_per_key/= pkinfo->actual_rec_per_key(0); |
| 26824 | /* |
| 26825 | The value of rec_per_key for the extended key has |
| 26826 | to be adjusted accordingly if some components of |
| 26827 | the secondary key are included in the primary key. |
| 26828 | */ |
| 26829 | for(uint i= 1; i < used_pk_parts; i++) |
| 26830 | { |
| 26831 | if (pkinfo->key_part[i].field->key_start.is_set(nr)) |
| 26832 | { |
| 26833 | /* |
| 26834 | We presume here that for any index rec_per_key[i] != 0 |
| 26835 | if rec_per_key[0] != 0. |
| 26836 | */ |
| 26837 | DBUG_ASSERT(pkinfo->actual_rec_per_key(i)); |
| 26838 | rec_per_key*= pkinfo->actual_rec_per_key(i-1); |
| 26839 | rec_per_key/= pkinfo->actual_rec_per_key(i); |
| 26840 | } |
| 26841 | } |
| 26842 | } |
| 26843 | } |
| 26844 | set_if_bigger(rec_per_key, 1); |
| 26845 | /* |
| 26846 | With a grouping query each group containing on average |
| 26847 | rec_per_key records produces only one row that will |
| 26848 | be included into the result set. |
| 26849 | */ |
| 26850 | if (select_limit > table_records/rec_per_key) |
| 26851 | select_limit= table_records; |
| 26852 | else |
| 26853 | select_limit= (ha_rows) (select_limit*rec_per_key); |
| 26854 | } /* group */ |
| 26855 | |
| 26856 | /* |
| 26857 | If tab=tk is not the last joined table tn then to get first |
| 26858 | L records from the result set we can expect to retrieve |
| 26859 | only L/fanout(tk,tn) where fanout(tk,tn) says how many |
| 26860 | rows in the record set on average will match each row tk. |
| 26861 | Usually our estimates for fanouts are too pessimistic. |
| 26862 | So the estimate for L/fanout(tk,tn) will be too optimistic |
| 26863 | and as result we'll choose an index scan when using ref/range |
| 26864 | access + filesort will be cheaper. |
| 26865 | */ |
| 26866 | select_limit= (ha_rows) (select_limit < fanout ? |
| 26867 | 1 : select_limit/fanout); |
| 26868 | /* |
| 26869 | We assume that each of the tested indexes is not correlated |
| 26870 | with ref_key. Thus, to select first N records we have to scan |
| 26871 | N/selectivity(ref_key) index entries. |
| 26872 | selectivity(ref_key) = #scanned_records/#table_records = |
| 26873 | refkey_rows_estimate/table_records. |
| 26874 | In any case we can't select more than #table_records. |
| 26875 | N/(refkey_rows_estimate/table_records) > table_records |
| 26876 | <=> N > refkey_rows_estimate. |
| 26877 | */ |
| 26878 | if (select_limit > refkey_rows_estimate) |
| 26879 | select_limit= table_records; |
| 26880 | else |
| 26881 | select_limit= (ha_rows) (select_limit * |
| 26882 | (double) table_records / |
| 26883 | refkey_rows_estimate); |
| 26884 | rec_per_key= keyinfo->actual_rec_per_key(keyinfo->user_defined_key_parts-1); |
| 26885 | set_if_bigger(rec_per_key, 1); |
| 26886 | /* |
| 26887 | Here we take into account the fact that rows are |
| 26888 | accessed in sequences rec_per_key records in each. |
| 26889 | Rows in such a sequence are supposed to be ordered |
| 26890 | by rowid/primary key. When reading the data |
| 26891 | in a sequence we'll touch not more pages than the |
| 26892 | table file contains. |
| 26893 | TODO. Use the formula for a disk sweep sequential access |
| 26894 | to calculate the cost of accessing data rows for one |
| 26895 | index entry. |
| 26896 | */ |
| 26897 | index_scan_time= select_limit/rec_per_key * |
| 26898 | MY_MIN(rec_per_key, table->file->scan_time()); |
| 26899 | double range_scan_time; |
| 26900 | if (get_range_limit_read_cost(tab, table, nr, select_limit, |
| 26901 | &range_scan_time)) |
| 26902 | { |
| 26903 | if (range_scan_time < index_scan_time) |
| 26904 | index_scan_time= range_scan_time; |
| 26905 | } |
| 26906 | |
| 26907 | if ((ref_key < 0 && (group || table->force_index || is_covering)) || |
| 26908 | index_scan_time < read_time) |
| 26909 | { |
| 26910 | ha_rows quick_records= table_records; |
| 26911 | ha_rows refkey_select_limit= (ref_key >= 0 && |
| 26912 | !is_hash_join_key_no(ref_key) && |
| 26913 | table->covering_keys.is_set(ref_key)) ? |
| 26914 | refkey_rows_estimate : |
| 26915 | HA_POS_ERROR; |
| 26916 | if ((is_best_covering && !is_covering) || |
| 26917 | (is_covering && refkey_select_limit < select_limit)) |
| 26918 | continue; |
| 26919 | if (table->quick_keys.is_set(nr)) |
| 26920 | quick_records= table->quick_rows[nr]; |
| 26921 | if (best_key < 0 || |
| 26922 | (select_limit <= MY_MIN(quick_records,best_records) ? |
| 26923 | keyinfo->user_defined_key_parts < best_key_parts : |
| 26924 | quick_records < best_records) || |
| 26925 | (!is_best_covering && is_covering)) |
| 26926 | { |
| 26927 | best_key= nr; |
| 26928 | best_key_parts= keyinfo->user_defined_key_parts; |
| 26929 | if (saved_best_key_parts) |
| 26930 | *saved_best_key_parts= used_key_parts; |
| 26931 | best_records= quick_records; |
| 26932 | is_best_covering= is_covering; |
| 26933 | best_key_direction= direction; |
| 26934 | best_select_limit= select_limit; |
| 26935 | } |
| 26936 | } |
| 26937 | } |
| 26938 | } |
| 26939 | } |
| 26940 | |
| 26941 | if (best_key < 0 || best_key == ref_key) |
| 26942 | DBUG_RETURN(FALSE); |
| 26943 | |
| 26944 | *new_key= best_key; |
| 26945 | *new_key_direction= best_key_direction; |
| 26946 | *new_select_limit= has_limit ? best_select_limit : table_records; |
| 26947 | if (new_used_key_parts != NULL) |
| 26948 | *new_used_key_parts= best_key_parts; |
| 26949 | |
| 26950 | DBUG_RETURN(TRUE); |
| 26951 | } |
| 26952 | |
| 26953 | |
| 26954 | /** |
| 26955 | Find a key to apply single table UPDATE/DELETE by a given ORDER |
| 26956 | |
| 26957 | @param order Linked list of ORDER BY arguments |
| 26958 | @param table Table to find a key |
| 26959 | @param select Pointer to access/update select->quick (if any) |
| 26960 | @param limit LIMIT clause parameter |
| 26961 | @param [out] scanned_limit How many records we expect to scan |
| 26962 | Valid if *need_sort=FALSE. |
| 26963 | @param [out] need_sort TRUE if filesort needed |
| 26964 | @param [out] reverse |
| 26965 | TRUE if the key is reversed again given ORDER (undefined if key == MAX_KEY) |
| 26966 | |
| 26967 | @return |
| 26968 | - MAX_KEY if no key found (need_sort == TRUE) |
| 26969 | - MAX_KEY if quick select result order is OK (need_sort == FALSE) |
| 26970 | - key number (either index scan or quick select) (need_sort == FALSE) |
| 26971 | |
| 26972 | @note |
| 26973 | Side effects: |
| 26974 | - may deallocate or deallocate and replace select->quick; |
| 26975 | - may set table->quick_condition_rows and table->quick_rows[...] |
| 26976 | to table->file->stats.records. |
| 26977 | */ |
| 26978 | |
| 26979 | uint get_index_for_order(ORDER *order, TABLE *table, SQL_SELECT *select, |
| 26980 | ha_rows limit, ha_rows *scanned_limit, |
| 26981 | bool *need_sort, bool *reverse) |
| 26982 | { |
| 26983 | if (!order) |
| 26984 | { |
| 26985 | *need_sort= FALSE; |
| 26986 | if (select && select->quick) |
| 26987 | return select->quick->index; // index or MAX_KEY, use quick select as is |
| 26988 | else |
| 26989 | return table->file->key_used_on_scan; // MAX_KEY or index for some engines |
| 26990 | } |
| 26991 | |
| 26992 | if (!is_simple_order(order)) // just to cut further expensive checks |
| 26993 | { |
| 26994 | *need_sort= TRUE; |
| 26995 | return MAX_KEY; |
| 26996 | } |
| 26997 | |
| 26998 | if (select && select->quick) |
| 26999 | { |
| 27000 | if (select->quick->index == MAX_KEY) |
| 27001 | { |
| 27002 | *need_sort= TRUE; |
| 27003 | return MAX_KEY; |
| 27004 | } |
| 27005 | |
| 27006 | uint used_key_parts; |
| 27007 | switch (test_if_order_by_key(NULL, order, table, select->quick->index, |
| 27008 | &used_key_parts)) { |
| 27009 | case 1: // desired order |
| 27010 | *need_sort= FALSE; |
| 27011 | *scanned_limit= MY_MIN(limit, select->quick->records); |
| 27012 | return select->quick->index; |
| 27013 | case 0: // unacceptable order |
| 27014 | *need_sort= TRUE; |
| 27015 | return MAX_KEY; |
| 27016 | case -1: // desired order, but opposite direction |
| 27017 | { |
| 27018 | QUICK_SELECT_I *reverse_quick; |
| 27019 | if ((reverse_quick= |
| 27020 | select->quick->make_reverse(used_key_parts))) |
| 27021 | { |
| 27022 | select->set_quick(reverse_quick); |
| 27023 | *need_sort= FALSE; |
| 27024 | *scanned_limit= MY_MIN(limit, select->quick->records); |
| 27025 | return select->quick->index; |
| 27026 | } |
| 27027 | else |
| 27028 | { |
| 27029 | *need_sort= TRUE; |
| 27030 | return MAX_KEY; |
| 27031 | } |
| 27032 | } |
| 27033 | } |
| 27034 | DBUG_ASSERT(0); |
| 27035 | } |
| 27036 | else if (limit != HA_POS_ERROR) |
| 27037 | { // check if some index scan & LIMIT is more efficient than filesort |
| 27038 | |
| 27039 | /* |
| 27040 | Update quick_condition_rows since single table UPDATE/DELETE procedures |
| 27041 | don't call make_join_statistics() and leave this variable uninitialized. |
| 27042 | */ |
| 27043 | table->quick_condition_rows= table->stat_records(); |
| 27044 | |
| 27045 | int key, direction; |
| 27046 | if (test_if_cheaper_ordering(NULL, order, table, |
| 27047 | table->keys_in_use_for_order_by, -1, |
| 27048 | limit, |
| 27049 | &key, &direction, &limit) && |
| 27050 | !is_key_used(table, key, table->write_set)) |
| 27051 | { |
| 27052 | *need_sort= FALSE; |
| 27053 | *scanned_limit= limit; |
| 27054 | *reverse= (direction < 0); |
| 27055 | return key; |
| 27056 | } |
| 27057 | } |
| 27058 | *need_sort= TRUE; |
| 27059 | return MAX_KEY; |
| 27060 | } |
| 27061 | |
| 27062 | |
| 27063 | /* |
| 27064 | Count how many times the specified conditions are true for first rows_to_read |
| 27065 | rows of the table. |
| 27066 | |
| 27067 | @param thd Thread handle |
| 27068 | @param rows_to_read How many rows to sample |
| 27069 | @param table Table to use |
| 27070 | @conds conds INOUT List of conditions and counters for them |
| 27071 | |
| 27072 | @return Number of we've checked. It can be equal or less than rows_to_read. |
| 27073 | 0 is returned for error or when the table had no rows. |
| 27074 | */ |
| 27075 | |
| 27076 | ulong check_selectivity(THD *thd, |
| 27077 | ulong rows_to_read, |
| 27078 | TABLE *table, |
| 27079 | List<COND_STATISTIC> *conds) |
| 27080 | { |
| 27081 | ulong count= 0; |
| 27082 | COND_STATISTIC *cond; |
| 27083 | List_iterator_fast<COND_STATISTIC> it(*conds); |
| 27084 | handler *file= table->file; |
| 27085 | uchar *record= table->record[0]; |
| 27086 | int error= 0; |
| 27087 | DBUG_ENTER("check_selectivity" ); |
| 27088 | |
| 27089 | DBUG_ASSERT(rows_to_read > 0); |
| 27090 | while ((cond= it++)) |
| 27091 | { |
| 27092 | DBUG_ASSERT(cond->cond); |
| 27093 | DBUG_ASSERT(cond->cond->used_tables() == table->map); |
| 27094 | cond->positive= 0; |
| 27095 | } |
| 27096 | it.rewind(); |
| 27097 | |
| 27098 | if (unlikely(file->ha_rnd_init_with_error(1))) |
| 27099 | DBUG_RETURN(0); |
| 27100 | do |
| 27101 | { |
| 27102 | error= file->ha_rnd_next(record); |
| 27103 | |
| 27104 | if (unlikely(thd->killed)) |
| 27105 | { |
| 27106 | thd->send_kill_message(); |
| 27107 | count= 0; |
| 27108 | goto err; |
| 27109 | } |
| 27110 | if (unlikely(error)) |
| 27111 | { |
| 27112 | if (error == HA_ERR_END_OF_FILE) |
| 27113 | break; |
| 27114 | goto err; |
| 27115 | } |
| 27116 | |
| 27117 | count++; |
| 27118 | while ((cond= it++)) |
| 27119 | { |
| 27120 | if (cond->cond->val_bool()) |
| 27121 | cond->positive++; |
| 27122 | } |
| 27123 | it.rewind(); |
| 27124 | |
| 27125 | } while (count < rows_to_read); |
| 27126 | |
| 27127 | file->ha_rnd_end(); |
| 27128 | DBUG_RETURN(count); |
| 27129 | |
| 27130 | err: |
| 27131 | DBUG_PRINT("error" , ("error %d" , error)); |
| 27132 | file->ha_rnd_end(); |
| 27133 | DBUG_RETURN(0); |
| 27134 | } |
| 27135 | |
| 27136 | /**************************************************************************** |
| 27137 | AGGR_OP implementation |
| 27138 | ****************************************************************************/ |
| 27139 | |
| 27140 | /** |
| 27141 | @brief Instantiate tmp table for aggregation and start index scan if needed |
| 27142 | @todo Tmp table always would be created, even for empty result. Extend |
| 27143 | executor to avoid tmp table creation when no rows were written |
| 27144 | into tmp table. |
| 27145 | @return |
| 27146 | true error |
| 27147 | false ok |
| 27148 | */ |
| 27149 | |
| 27150 | bool |
| 27151 | AGGR_OP::prepare_tmp_table() |
| 27152 | { |
| 27153 | TABLE *table= join_tab->table; |
| 27154 | JOIN *join= join_tab->join; |
| 27155 | int rc= 0; |
| 27156 | |
| 27157 | if (!join_tab->table->is_created()) |
| 27158 | { |
| 27159 | if (instantiate_tmp_table(table, join_tab->tmp_table_param->keyinfo, |
| 27160 | join_tab->tmp_table_param->start_recinfo, |
| 27161 | &join_tab->tmp_table_param->recinfo, |
| 27162 | join->select_options)) |
| 27163 | return true; |
| 27164 | (void) table->file->extra(HA_EXTRA_WRITE_CACHE); |
| 27165 | empty_record(table); |
| 27166 | } |
| 27167 | /* If it wasn't already, start index scan for grouping using table index. */ |
| 27168 | if (!table->file->inited && table->group && |
| 27169 | join_tab->tmp_table_param->sum_func_count && table->s->keys) |
| 27170 | rc= table->file->ha_index_init(0, 0); |
| 27171 | else |
| 27172 | { |
| 27173 | /* Start index scan in scanning mode */ |
| 27174 | rc= table->file->ha_rnd_init(true); |
| 27175 | } |
| 27176 | if (rc) |
| 27177 | { |
| 27178 | table->file->print_error(rc, MYF(0)); |
| 27179 | return true; |
| 27180 | } |
| 27181 | return false; |
| 27182 | } |
| 27183 | |
| 27184 | |
| 27185 | /** |
| 27186 | @brief Prepare table if necessary and call write_func to save record |
| 27187 | |
| 27188 | @param end_of_records the end_of_record signal to pass to the writer |
| 27189 | |
| 27190 | @return return one of enum_nested_loop_state. |
| 27191 | */ |
| 27192 | |
| 27193 | enum_nested_loop_state |
| 27194 | AGGR_OP::put_record(bool end_of_records) |
| 27195 | { |
| 27196 | // Lasy tmp table creation/initialization |
| 27197 | if (!join_tab->table->file->inited) |
| 27198 | if (prepare_tmp_table()) |
| 27199 | return NESTED_LOOP_ERROR; |
| 27200 | enum_nested_loop_state rc= (*write_func)(join_tab->join, join_tab, |
| 27201 | end_of_records); |
| 27202 | return rc; |
| 27203 | } |
| 27204 | |
| 27205 | |
| 27206 | /** |
| 27207 | @brief Finish rnd/index scan after accumulating records, switch ref_array, |
| 27208 | and send accumulated records further. |
| 27209 | @return return one of enum_nested_loop_state. |
| 27210 | */ |
| 27211 | |
| 27212 | enum_nested_loop_state |
| 27213 | AGGR_OP::end_send() |
| 27214 | { |
| 27215 | enum_nested_loop_state rc= NESTED_LOOP_OK; |
| 27216 | TABLE *table= join_tab->table; |
| 27217 | JOIN *join= join_tab->join; |
| 27218 | |
| 27219 | // All records were stored, send them further |
| 27220 | int tmp, new_errno= 0; |
| 27221 | |
| 27222 | if ((rc= put_record(true)) < NESTED_LOOP_OK) |
| 27223 | return rc; |
| 27224 | |
| 27225 | if ((tmp= table->file->extra(HA_EXTRA_NO_CACHE))) |
| 27226 | { |
| 27227 | DBUG_PRINT("error" ,("extra(HA_EXTRA_NO_CACHE) failed" )); |
| 27228 | new_errno= tmp; |
| 27229 | } |
| 27230 | if ((tmp= table->file->ha_index_or_rnd_end())) |
| 27231 | { |
| 27232 | DBUG_PRINT("error" ,("ha_index_or_rnd_end() failed" )); |
| 27233 | new_errno= tmp; |
| 27234 | } |
| 27235 | if (new_errno) |
| 27236 | { |
| 27237 | table->file->print_error(new_errno,MYF(0)); |
| 27238 | return NESTED_LOOP_ERROR; |
| 27239 | } |
| 27240 | |
| 27241 | // Update ref array |
| 27242 | join_tab->join->set_items_ref_array(*join_tab->ref_array); |
| 27243 | if (join_tab->window_funcs_step) |
| 27244 | { |
| 27245 | if (join_tab->window_funcs_step->exec(join)) |
| 27246 | return NESTED_LOOP_ERROR; |
| 27247 | } |
| 27248 | |
| 27249 | table->reginfo.lock_type= TL_UNLOCK; |
| 27250 | |
| 27251 | bool in_first_read= true; |
| 27252 | while (rc == NESTED_LOOP_OK) |
| 27253 | { |
| 27254 | int error; |
| 27255 | if (in_first_read) |
| 27256 | { |
| 27257 | in_first_read= false; |
| 27258 | error= join_init_read_record(join_tab); |
| 27259 | } |
| 27260 | else |
| 27261 | error= join_tab->read_record.read_record(); |
| 27262 | |
| 27263 | if (unlikely(error > 0 || (join->thd->is_error()))) // Fatal error |
| 27264 | rc= NESTED_LOOP_ERROR; |
| 27265 | else if (error < 0) |
| 27266 | break; |
| 27267 | else if (unlikely(join->thd->killed)) // Aborted by user |
| 27268 | { |
| 27269 | join->thd->send_kill_message(); |
| 27270 | rc= NESTED_LOOP_KILLED; |
| 27271 | } |
| 27272 | else |
| 27273 | { |
| 27274 | /* |
| 27275 | In case we have window functions present, an extra step is required |
| 27276 | to compute all the fields from the temporary table. |
| 27277 | In case we have a compound expression such as: expr + expr, |
| 27278 | where one of the terms has a window function inside it, only |
| 27279 | after computing window function values we actually know the true |
| 27280 | final result of the compounded expression. |
| 27281 | |
| 27282 | Go through all the func items and save their values once again in the |
| 27283 | corresponding temp table fields. Do this for each row in the table. |
| 27284 | */ |
| 27285 | if (join_tab->window_funcs_step) |
| 27286 | { |
| 27287 | Item **func_ptr= join_tab->tmp_table_param->items_to_copy; |
| 27288 | Item *func; |
| 27289 | for (; (func = *func_ptr) ; func_ptr++) |
| 27290 | { |
| 27291 | if (func->with_window_func) |
| 27292 | func->save_in_result_field(true); |
| 27293 | } |
| 27294 | } |
| 27295 | rc= evaluate_join_record(join, join_tab, 0); |
| 27296 | } |
| 27297 | } |
| 27298 | |
| 27299 | // Finish rnd scn after sending records |
| 27300 | if (join_tab->table->file->inited) |
| 27301 | join_tab->table->file->ha_rnd_end(); |
| 27302 | |
| 27303 | return rc; |
| 27304 | } |
| 27305 | |
| 27306 | |
| 27307 | /** |
| 27308 | @brief |
| 27309 | Remove marked top conjuncts of a condition |
| 27310 | |
| 27311 | @param thd The thread handle |
| 27312 | @param cond The condition which subformulas are to be removed |
| 27313 | |
| 27314 | @details |
| 27315 | The function removes all top conjuncts marked with the flag |
| 27316 | FULL_EXTRACTION_FL from the condition 'cond'. The resulting |
| 27317 | formula is returned a the result of the function |
| 27318 | If 'cond' s marked with such flag the function returns 0. |
| 27319 | The function clear the extraction flags for the removed |
| 27320 | formulas |
| 27321 | |
| 27322 | @retval |
| 27323 | condition without removed subformulas |
| 27324 | 0 if the whole 'cond' is removed |
| 27325 | */ |
| 27326 | |
| 27327 | Item *remove_pushed_top_conjuncts(THD *thd, Item *cond) |
| 27328 | { |
| 27329 | if (cond->get_extraction_flag() == FULL_EXTRACTION_FL) |
| 27330 | { |
| 27331 | cond->clear_extraction_flag(); |
| 27332 | return 0; |
| 27333 | } |
| 27334 | if (cond->type() == Item::COND_ITEM) |
| 27335 | { |
| 27336 | if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC) |
| 27337 | { |
| 27338 | List_iterator<Item> li(*((Item_cond*) cond)->argument_list()); |
| 27339 | Item *item; |
| 27340 | while ((item= li++)) |
| 27341 | { |
| 27342 | if (item->get_extraction_flag() == FULL_EXTRACTION_FL) |
| 27343 | { |
| 27344 | item->clear_extraction_flag(); |
| 27345 | li.remove(); |
| 27346 | } |
| 27347 | } |
| 27348 | switch (((Item_cond*) cond)->argument_list()->elements) |
| 27349 | { |
| 27350 | case 0: |
| 27351 | return 0; |
| 27352 | case 1: |
| 27353 | return ((Item_cond*) cond)->argument_list()->head(); |
| 27354 | default: |
| 27355 | return cond; |
| 27356 | } |
| 27357 | } |
| 27358 | } |
| 27359 | return cond; |
| 27360 | } |
| 27361 | |
| 27362 | /** |
| 27363 | @} (end of group Query_Optimizer) |
| 27364 | */ |
| 27365 | |