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 | |