1 /* Copyright (c) 2002, 2016, Oracle and/or its affiliates.
2 Copyright (c) 2010, 2021, MariaDB
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 St, Fifth Floor, Boston, MA 02110-1335 USA */
16
17 /**
18 @file
19
20 @brief
21 subselect Item
22
23 @todo
24 - add function from mysql_select that use JOIN* as parameter to JOIN
25 methods (sql_select.h/sql_select.cc)
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 /*
35 It is necessary to include set_var.h instead of item.h because there
36 are dependencies on include order for set_var.h and item.h. This
37 will be resolved later.
38 */
39 #include "sql_class.h" // set_var.h: THD
40 #include "set_var.h"
41 #include "sql_select.h"
42 #include "sql_parse.h" // check_stack_overrun
43 #include "sql_cte.h"
44 #include "sql_test.h"
45
46 double get_post_group_estimate(JOIN* join, double join_op_rows);
47
48 LEX_CSTRING exists_outer_expr_name= { STRING_WITH_LEN("<exists outer expr>") };
49
50 LEX_CSTRING no_matter_name= {STRING_WITH_LEN("<no matter>") };
51
52 int check_and_do_in_subquery_rewrites(JOIN *join);
53
Item_subselect(THD * thd_arg)54 Item_subselect::Item_subselect(THD *thd_arg):
55 Item_result_field(thd_arg), Used_tables_and_const_cache(),
56 value_assigned(0), own_engine(0), thd(0), old_engine(0),
57 have_to_be_excluded(0),
58 inside_first_fix_fields(0), done_first_fix_fields(FALSE),
59 expr_cache(0), forced_const(FALSE), expensive_fl(FALSE),
60 substitution(0), engine(0), eliminated(FALSE),
61 changed(0), is_correlated(FALSE), with_recursive_reference(0)
62 {
63 DBUG_ENTER("Item_subselect::Item_subselect");
64 DBUG_PRINT("enter", ("this: %p", this));
65 sortbuffer.str= 0;
66
67 #ifndef DBUG_OFF
68 exec_counter= 0;
69 #endif
70 reset();
71 /*
72 Item value is NULL if select_result_interceptor didn't change this value
73 (i.e. some rows will be found returned)
74 */
75 null_value= TRUE;
76 DBUG_VOID_RETURN;
77 }
78
79
init(st_select_lex * select_lex,select_result_interceptor * result)80 void Item_subselect::init(st_select_lex *select_lex,
81 select_result_interceptor *result)
82 {
83 /*
84 Please see Item_singlerow_subselect::invalidate_and_restore_select_lex(),
85 which depends on alterations to the parse tree implemented here.
86 */
87
88 DBUG_ENTER("Item_subselect::init");
89 DBUG_PRINT("enter", ("select_lex: %p this: %p",
90 select_lex, this));
91
92 select_lex->parent_lex->relink_hack(select_lex);
93
94 unit= select_lex->master_unit();
95
96 if (unit->item)
97 {
98 engine= unit->item->engine;
99 parsing_place= unit->item->parsing_place;
100 if (unit->item->substype() == EXISTS_SUBS &&
101 ((Item_exists_subselect *)unit->item)->exists_transformed)
102 {
103 /* it is permanent transformation of EXISTS to IN */
104 unit->item= this;
105 engine->change_result(this, result, FALSE);
106 }
107 else
108 {
109 /*
110 Item can be changed in JOIN::prepare while engine in JOIN::optimize
111 => we do not copy old_engine here
112 */
113 unit->thd->change_item_tree((Item**)&unit->item, this);
114 engine->change_result(this, result, TRUE);
115 }
116 }
117 else
118 {
119 SELECT_LEX *outer_select= unit->outer_select();
120 /*
121 do not take into account expression inside aggregate functions because
122 they can access original table fields
123 */
124 parsing_place= (outer_select->in_sum_expr ?
125 NO_MATTER :
126 outer_select->parsing_place);
127 if (unit->is_unit_op() &&
128 (unit->first_select()->next_select() || unit->fake_select_lex))
129 engine= new subselect_union_engine(unit, result, this);
130 else
131 engine= new subselect_single_select_engine(select_lex, result, this);
132 }
133 DBUG_PRINT("info", ("engine: %p", engine));
134 DBUG_VOID_RETURN;
135 }
136
137 st_select_lex *
get_select_lex()138 Item_subselect::get_select_lex()
139 {
140 return unit->first_select();
141 }
142
cleanup()143 void Item_subselect::cleanup()
144 {
145 DBUG_ENTER("Item_subselect::cleanup");
146 Item_result_field::cleanup();
147 if (old_engine)
148 {
149 if (engine)
150 engine->cleanup();
151 engine= old_engine;
152 old_engine= 0;
153 }
154 if (engine)
155 engine->cleanup();
156 reset();
157 filesort_buffer.free_sort_buffer();
158 my_free(sortbuffer.str);
159 sortbuffer.str= 0;
160
161 value_assigned= 0;
162 expr_cache= 0;
163 forced_const= FALSE;
164 DBUG_PRINT("info", ("exec_counter: %d", exec_counter));
165 #ifndef DBUG_OFF
166 exec_counter= 0;
167 #endif
168 DBUG_VOID_RETURN;
169 }
170
171
cleanup()172 void Item_singlerow_subselect::cleanup()
173 {
174 DBUG_ENTER("Item_singlerow_subselect::cleanup");
175 value= 0; row= 0;
176 Item_subselect::cleanup();
177 DBUG_VOID_RETURN;
178 }
179
180
cleanup()181 void Item_in_subselect::cleanup()
182 {
183 DBUG_ENTER("Item_in_subselect::cleanup");
184 if (left_expr_cache)
185 {
186 left_expr_cache->delete_elements();
187 delete left_expr_cache;
188 left_expr_cache= NULL;
189 }
190 /*
191 TODO: This breaks the commented assert in add_strategy().
192 in_strategy&= ~SUBS_STRATEGY_CHOSEN;
193 */
194 first_execution= TRUE;
195 pushed_cond_guards= NULL;
196 Item_subselect::cleanup();
197 DBUG_VOID_RETURN;
198 }
199
200
cleanup()201 void Item_allany_subselect::cleanup()
202 {
203 /*
204 The MAX/MIN transformation through injection is reverted through the
205 change_item_tree() mechanism. Revert the select_lex object of the
206 query to its initial state.
207 */
208 for (SELECT_LEX *sl= unit->first_select();
209 sl; sl= sl->next_select())
210 if (test_set_strategy(SUBS_MAXMIN_INJECTED))
211 sl->with_sum_func= false;
212 Item_in_subselect::cleanup();
213 }
214
215
~Item_subselect()216 Item_subselect::~Item_subselect()
217 {
218 DBUG_ENTER("Item_subselect::~Item_subselect");
219 DBUG_PRINT("enter", ("this: %p", this));
220 if (own_engine)
221 delete engine;
222 else
223 if (engine) // can be empty in case of EOM
224 engine->cleanup();
225 engine= NULL;
226 DBUG_VOID_RETURN;
227 }
228
229 bool
select_transformer(JOIN * join)230 Item_subselect::select_transformer(JOIN *join)
231 {
232 DBUG_ENTER("Item_subselect::select_transformer");
233 DBUG_ASSERT(thd == join->thd);
234 DBUG_RETURN(false);
235 }
236
237
fix_fields(THD * thd_param,Item ** ref)238 bool Item_subselect::fix_fields(THD *thd_param, Item **ref)
239 {
240 char const *save_where= thd_param->where;
241 uint8 uncacheable;
242 bool res;
243
244 thd= thd_param;
245
246 DBUG_ASSERT(unit->thd == thd);
247
248 {
249 SELECT_LEX *upper= unit->outer_select();
250 if (upper->parsing_place == IN_HAVING)
251 upper->subquery_in_having= 1;
252 /* The subquery is an expression cache candidate */
253 upper->expr_cache_may_be_used[upper->parsing_place]= TRUE;
254 }
255
256 status_var_increment(thd_param->status_var.feature_subquery);
257
258 DBUG_ASSERT(fixed == 0);
259 engine->set_thd((thd= thd_param));
260 if (!done_first_fix_fields)
261 {
262 done_first_fix_fields= TRUE;
263 inside_first_fix_fields= TRUE;
264 upper_refs.empty();
265 /*
266 psergey-todo: remove _first_fix_fields calls, we need changes on every
267 execution
268 */
269 }
270
271 eliminated= FALSE;
272 parent_select= thd_param->lex->current_select;
273
274 if (check_stack_overrun(thd, STACK_MIN_SIZE, (uchar*)&res))
275 return TRUE;
276
277 for (SELECT_LEX *sl= unit->first_select(); sl; sl= sl->next_select())
278 {
279 if (sl->tvc)
280 {
281 if (!(sl= wrap_tvc_into_select(thd, sl)))
282 {
283 res= TRUE;
284 goto end;
285 }
286 if (sl == unit->first_select() && !sl->next_select())
287 unit->fake_select_lex= 0;
288 }
289 }
290
291 if (!(res= engine->prepare(thd)))
292 {
293 // all transformation is done (used by prepared statements)
294 changed= 1;
295 inside_first_fix_fields= FALSE;
296
297 /*
298 Substitute the current item with an Item_in_optimizer that was
299 created by Item_in_subselect::select_in_like_transformer and
300 call fix_fields for the substituted item which in turn calls
301 engine->prepare for the subquery predicate.
302 */
303 if (substitution)
304 {
305 /*
306 If the top item of the WHERE/HAVING condition changed,
307 set correct WHERE/HAVING for PS.
308 */
309 if (unit->outer_select()->where == (*ref))
310 unit->outer_select()->where= substitution;
311 else if (unit->outer_select()->having == (*ref))
312 unit->outer_select()->having= substitution;
313
314 (*ref)= substitution;
315 substitution->name= name;
316 if (have_to_be_excluded)
317 engine->exclude();
318 substitution= 0;
319 thd->where= "checking transformed subquery";
320 res= (*ref)->fix_fields_if_needed(thd, ref);
321 goto end;
322
323 }
324 // Is it one field subselect?
325 if (engine->cols() > max_columns)
326 {
327 my_error(ER_OPERAND_COLUMNS, MYF(0), 1);
328 res= TRUE;
329 goto end;
330 }
331 if (fix_length_and_dec())
332 {
333 res= TRUE;
334 goto end;
335 }
336 }
337 else
338 goto end;
339
340 if ((uncacheable= engine->uncacheable() & ~UNCACHEABLE_EXPLAIN) ||
341 with_recursive_reference)
342 {
343 const_item_cache= 0;
344 if (uncacheable & UNCACHEABLE_RAND)
345 used_tables_cache|= RAND_TABLE_BIT;
346 }
347 fixed= 1;
348
349 end:
350 done_first_fix_fields= FALSE;
351 inside_first_fix_fields= FALSE;
352 thd->where= save_where;
353 return res;
354 }
355
356
enumerate_field_refs_processor(void * arg)357 bool Item_subselect::enumerate_field_refs_processor(void *arg)
358 {
359 List_iterator<Ref_to_outside> it(upper_refs);
360 Ref_to_outside *upper;
361
362 while ((upper= it++))
363 {
364 if (upper->item &&
365 upper->item->walk(&Item::enumerate_field_refs_processor, FALSE, arg))
366 return TRUE;
367 }
368 return FALSE;
369 }
370
mark_as_eliminated_processor(void * arg)371 bool Item_subselect::mark_as_eliminated_processor(void *arg)
372 {
373 eliminated= TRUE;
374 return FALSE;
375 }
376
377
378 /**
379 Remove a subselect item from its unit so that the unit no longer
380 represents a subquery.
381
382 @param arg unused parameter
383
384 @return
385 FALSE to force the evaluation of the processor for the subsequent items.
386 */
387
eliminate_subselect_processor(void * arg)388 bool Item_subselect::eliminate_subselect_processor(void *arg)
389 {
390 unit->item= NULL;
391 unit->exclude();
392 eliminated= TRUE;
393 return FALSE;
394 }
395
396
397 /**
398 Adjust the master select of the subquery to be the fake_select which
399 represents the whole UNION right above the subquery, instead of the
400 last query of the UNION.
401
402 @param arg pointer to the fake select
403
404 @return
405 FALSE to force the evaluation of the processor for the subsequent items.
406 */
407
set_fake_select_as_master_processor(void * arg)408 bool Item_subselect::set_fake_select_as_master_processor(void *arg)
409 {
410 SELECT_LEX *fake_select= (SELECT_LEX*) arg;
411 /*
412 Move the st_select_lex_unit of a subquery from a global ORDER BY clause to
413 become a direct child of the fake_select of a UNION. In this way the
414 ORDER BY that is applied to the temporary table that contains the result of
415 the whole UNION, and all columns in the subquery are resolved against this
416 table. The transformation is applied only for immediate child subqueries of
417 a UNION query.
418 */
419 if (unit->outer_select()->master_unit()->fake_select_lex == fake_select)
420 {
421 /*
422 Set the master of the subquery to be the fake select (i.e. the whole
423 UNION), instead of the last query in the UNION.
424 */
425 fake_select->add_slave(unit);
426 DBUG_ASSERT(unit->outer_select() == fake_select);
427 /* Adjust the name resolution context hierarchy accordingly. */
428 for (SELECT_LEX *sl= unit->first_select(); sl; sl= sl->next_select())
429 sl->context.outer_context= &(fake_select->context);
430 /*
431 Undo Item_subselect::eliminate_subselect_processor because at that phase
432 we don't know yet that the ORDER clause will be moved to the fake select.
433 */
434 unit->item= this;
435 eliminated= FALSE;
436 }
437 return FALSE;
438 }
439
440
mark_as_dependent(THD * thd,st_select_lex * select,Item * item)441 bool Item_subselect::mark_as_dependent(THD *thd, st_select_lex *select,
442 Item *item)
443 {
444 if (inside_first_fix_fields)
445 {
446 is_correlated= TRUE;
447 Ref_to_outside *upper;
448 if (!(upper= new (thd->stmt_arena->mem_root) Ref_to_outside()))
449 return TRUE;
450 upper->select= select;
451 upper->item= item;
452 if (upper_refs.push_back(upper, thd->stmt_arena->mem_root))
453 return TRUE;
454 }
455 return FALSE;
456 }
457
458
459 /*
460 @brief
461 Update the table bitmaps for the outer references used within a subquery
462 */
463
update_table_bitmaps_processor(void * arg)464 bool Item_subselect::update_table_bitmaps_processor(void *arg)
465 {
466 List_iterator<Ref_to_outside> it(upper_refs);
467 Ref_to_outside *upper;
468
469 while ((upper= it++))
470 {
471 if (upper->item &&
472 upper->item->walk(&Item::update_table_bitmaps_processor, FALSE, arg))
473 return TRUE;
474 }
475 return FALSE;
476 }
477
478
479 /*
480 Adjust attributes after our parent select has been merged into grandparent
481
482 DESCRIPTION
483 Subquery is a composite object which may be correlated, that is, it may
484 have
485 1. references to tables of the parent select (i.e. one that has the clause
486 with the subquery predicate)
487 2. references to tables of the grandparent select
488 3. references to tables of further ancestors.
489
490 Before the pullout, this item indicates:
491 - #1 with table bits in used_tables()
492 - #2 and #3 with OUTER_REF_TABLE_BIT.
493
494 After parent has been merged with grandparent:
495 - references to parent and grandparent tables should be indicated with
496 table bits.
497 - references to greatgrandparent and further ancestors - with
498 OUTER_REF_TABLE_BIT.
499 */
500
fix_after_pullout(st_select_lex * new_parent,Item ** ref,bool merge)501 void Item_subselect::fix_after_pullout(st_select_lex *new_parent,
502 Item **ref, bool merge)
503 {
504 recalc_used_tables(new_parent, TRUE);
505 parent_select= new_parent;
506 }
507
508
509 class Field_fixer: public Field_enumerator
510 {
511 public:
512 table_map used_tables; /* Collect used_tables here */
513 st_select_lex *new_parent; /* Select we're in */
visit_field(Item_field * item)514 virtual void visit_field(Item_field *item)
515 {
516 //for (TABLE_LIST *tbl= new_parent->leaf_tables; tbl; tbl= tbl->next_local)
517 //{
518 // if (tbl->table == field->table)
519 // {
520 used_tables|= item->field->table->map;
521 // return;
522 // }
523 //}
524 //used_tables |= OUTER_REF_TABLE_BIT;
525 }
526 };
527
528
529 /*
530 Recalculate used_tables_cache
531 */
532
recalc_used_tables(st_select_lex * new_parent,bool after_pullout)533 void Item_subselect::recalc_used_tables(st_select_lex *new_parent,
534 bool after_pullout)
535 {
536 List_iterator_fast<Ref_to_outside> it(upper_refs);
537 Ref_to_outside *upper;
538 DBUG_ENTER("recalc_used_tables");
539
540 used_tables_cache= 0;
541 while ((upper= it++))
542 {
543 bool found= FALSE;
544 /*
545 Check if
546 1. the upper reference refers to the new immediate parent select, or
547 2. one of the further ancestors.
548
549 We rely on the fact that the tree of selects is modified by some kind of
550 'flattening', i.e. a process where child selects are merged into their
551 parents.
552 The merged selects are removed from the select tree but keep pointers to
553 their parents.
554 */
555 for (st_select_lex *sel= upper->select; sel; sel= sel->outer_select())
556 {
557 /*
558 If we've reached the new parent select by walking upwards from
559 reference's original select, this means that the reference is now
560 referring to the direct parent:
561 */
562 if (sel == new_parent)
563 {
564 found= TRUE;
565 /*
566 upper->item may be NULL when we've referred to a grouping function,
567 in which case we don't care about what it's table_map really is,
568 because item->with_sum_func==1 will ensure correct placement of the
569 item.
570 */
571 if (upper->item)
572 {
573 // Now, iterate over fields and collect used_tables() attribute:
574 Field_fixer fixer;
575 fixer.used_tables= 0;
576 fixer.new_parent= new_parent;
577 upper->item->walk(&Item::enumerate_field_refs_processor, 0, &fixer);
578 used_tables_cache |= fixer.used_tables;
579 upper->item->walk(&Item::update_table_bitmaps_processor, FALSE, NULL);
580 /*
581 if (after_pullout)
582 upper->item->fix_after_pullout(new_parent, &(upper->item));
583 upper->item->update_used_tables();
584 */
585 }
586 }
587 }
588 if (!found)
589 used_tables_cache|= OUTER_REF_TABLE_BIT;
590 }
591 /*
592 Don't update const_tables_cache yet as we don't yet know which of the
593 parent's tables are constant. Parent will call update_used_tables() after
594 he has done const table detection, and that will be our chance to update
595 const_tables_cache.
596 */
597 DBUG_PRINT("exit", ("used_tables_cache: %llx", used_tables_cache));
598 DBUG_VOID_RETURN;
599 }
600
601
602 /**
603 Determine if a subquery is expensive to execute during query optimization.
604
605 @details The cost of execution of a subquery is estimated based on an
606 estimate of the number of rows the subquery will access during execution.
607 This measure is used instead of JOIN::read_time, because it is considered
608 to be much more reliable than the cost estimate.
609
610 @return true if the subquery is expensive
611 @return false otherwise
612 */
is_expensive()613 bool Item_subselect::is_expensive()
614 {
615 double examined_rows= 0;
616 bool all_are_simple= true;
617
618 if (!expensive_fl && is_evaluated())
619 return false;
620
621 /* check extremely simple select */
622 if (!unit->first_select()->next_select()) // no union
623 {
624 /*
625 such single selects works even without optimization because
626 can not makes loops
627 */
628 SELECT_LEX *sl= unit->first_select();
629 JOIN *join = sl->join;
630 if (join && !join->tables_list && !sl->first_inner_unit())
631 return (expensive_fl= false);
632 }
633
634
635 for (SELECT_LEX *sl= unit->first_select(); sl; sl= sl->next_select())
636 {
637 JOIN *cur_join= sl->join;
638
639 /* not optimized subquery */
640 if (!cur_join)
641 return (expensive_fl= true);
642
643 /*
644 If the subquery is not optimised or in the process of optimization
645 it supposed to be expensive
646 */
647 if (cur_join->optimization_state != JOIN::OPTIMIZATION_DONE)
648 return (expensive_fl= true);
649
650 if (!cur_join->tables_list && !sl->first_inner_unit())
651 continue;
652
653 /*
654 Subqueries whose result is known after optimization are not expensive.
655 Such subqueries have all tables optimized away, thus have no join plan.
656 */
657 if ((cur_join->zero_result_cause || !cur_join->tables_list))
658 continue;
659
660 /*
661 This is not simple SELECT in union so we can not go by simple condition
662 */
663 all_are_simple= false;
664
665 /*
666 If a subquery is not optimized we cannot estimate its cost. A subquery is
667 considered optimized if it has a join plan.
668 */
669 if (!cur_join->join_tab)
670 return (expensive_fl= true);
671
672 if (sl->first_inner_unit())
673 {
674 /*
675 Subqueries that contain subqueries are considered expensive.
676 @todo: accumulate the cost of subqueries.
677 */
678 return (expensive_fl= true);
679 }
680
681 examined_rows+= cur_join->get_examined_rows();
682 }
683
684 // here we are sure that subquery is optimized so thd is set
685 return (expensive_fl= !all_are_simple &&
686 (examined_rows > thd->variables.expensive_subquery_limit));
687 }
688
689
690 static
walk_items_for_table_list(Item_processor processor,bool walk_subquery,void * argument,List<TABLE_LIST> & join_list)691 int walk_items_for_table_list(Item_processor processor,
692 bool walk_subquery, void *argument,
693 List<TABLE_LIST>& join_list)
694 {
695 List_iterator<TABLE_LIST> li(join_list);
696 int res;
697 while (TABLE_LIST *table= li++)
698 {
699 if (table->on_expr)
700 {
701 if ((res= table->on_expr->walk(processor, walk_subquery, argument)))
702 return res;
703 }
704 if (table->nested_join)
705 {
706 if ((res= walk_items_for_table_list(processor, walk_subquery, argument,
707 table->nested_join->join_list)))
708 return res;
709 }
710 }
711 return 0;
712 }
713
714
unknown_splocal_processor(void * argument)715 bool Item_subselect::unknown_splocal_processor(void *argument)
716 {
717 SELECT_LEX *sl= unit->first_select();
718 if (sl->top_join_list.elements)
719 return 0;
720 if (sl->tvc && sl->tvc->walk_values(&Item::unknown_splocal_processor,
721 false, argument))
722 return true;
723 for (SELECT_LEX *lex= unit->first_select(); lex; lex= lex->next_select())
724 {
725 /*
726 TODO: walk through GROUP BY and ORDER yet eventually.
727 This will require checking aliases in SELECT list:
728 SELECT 1 AS a GROUP BY a;
729 SELECT 1 AS a ORDER BY a;
730 */
731 List_iterator<Item> li(lex->item_list);
732 Item *item;
733 if (lex->where && (lex->where)->walk(&Item::unknown_splocal_processor,
734 false, argument))
735 return true;
736 if (lex->having && (lex->having)->walk(&Item::unknown_splocal_processor,
737 false, argument))
738 return true;
739 while ((item=li++))
740 {
741 if (item->walk(&Item::unknown_splocal_processor, false, argument))
742 return true;
743 }
744 }
745 return false;
746 }
747
748
walk(Item_processor processor,bool walk_subquery,void * argument)749 bool Item_subselect::walk(Item_processor processor, bool walk_subquery,
750 void *argument)
751 {
752 if (!(unit->uncacheable & ~UNCACHEABLE_DEPENDENT) && engine->is_executed() &&
753 !unit->describe)
754 {
755 /*
756 The subquery has already been executed (for real, it wasn't EXPLAIN's
757 fake execution) so it should not matter what it has inside.
758
759 The actual reason for not walking inside is that parts of the subquery
760 (e.g. JTBM join nests and their IN-equality conditions may have been
761 invalidated by irreversible cleanups (those happen after an uncorrelated
762 subquery has been executed).
763 */
764 return (this->*processor)(argument);
765 }
766
767 if (walk_subquery)
768 {
769 for (SELECT_LEX *lex= unit->first_select(); lex; lex= lex->next_select())
770 {
771 List_iterator<Item> li(lex->item_list);
772 Item *item;
773 ORDER *order;
774
775 if (lex->where && (lex->where)->walk(processor, walk_subquery, argument))
776 return 1;
777 if (lex->having && (lex->having)->walk(processor, walk_subquery,
778 argument))
779 return 1;
780
781 if (walk_items_for_table_list(processor, walk_subquery, argument,
782 *lex->join_list))
783 return 1;
784
785 while ((item=li++))
786 {
787 if (item->walk(processor, walk_subquery, argument))
788 return 1;
789 }
790 for (order= lex->order_list.first ; order; order= order->next)
791 {
792 if ((*order->item)->walk(processor, walk_subquery, argument))
793 return 1;
794 }
795 for (order= lex->group_list.first ; order; order= order->next)
796 {
797 if ((*order->item)->walk(processor, walk_subquery, argument))
798 return 1;
799 }
800 }
801 }
802 return (this->*processor)(argument);
803 }
804
805
exec()806 bool Item_subselect::exec()
807 {
808 subselect_engine *org_engine= engine;
809
810 DBUG_ENTER("Item_subselect::exec");
811 DBUG_ASSERT(fixed);
812
813 DBUG_EXECUTE_IF("Item_subselect",
814 Item::Print print(this,
815 enum_query_type(QT_TO_SYSTEM_CHARSET |
816 QT_WITHOUT_INTRODUCERS));
817
818 push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
819 ER_UNKNOWN_ERROR, "DBUG: Item_subselect::exec %.*b",
820 print.length(),print.ptr());
821 );
822 /*
823 Do not execute subselect in case of a fatal error
824 or if the query has been killed.
825 */
826 if (unlikely(thd->is_error() || thd->killed))
827 DBUG_RETURN(true);
828
829 DBUG_ASSERT(!thd->lex->context_analysis_only);
830 /*
831 Simulate a failure in sub-query execution. Used to test e.g.
832 out of memory or query being killed conditions.
833 */
834 DBUG_EXECUTE_IF("subselect_exec_fail", DBUG_RETURN(true););
835
836 bool res= engine->exec();
837
838 #ifndef DBUG_OFF
839 ++exec_counter;
840 #endif
841 if (engine != org_engine)
842 {
843 /*
844 If the subquery engine changed during execution due to lazy subquery
845 optimization, or because the original engine found a more efficient other
846 engine, re-execute the subquery with the new engine.
847 */
848 DBUG_RETURN(exec());
849 }
850 DBUG_RETURN(res);
851 }
852
853
get_cache_parameters(List<Item> & parameters)854 void Item_subselect::get_cache_parameters(List<Item> ¶meters)
855 {
856 Collect_deps_prm prm= {¶meters, // parameters
857 unit->first_select()->nest_level_base, // nest_level_base
858 0, // count
859 unit->first_select()->nest_level, // nest_level
860 TRUE // collect
861 };
862 walk(&Item::collect_outer_ref_processor, TRUE, &prm);
863 }
864
optimize(double * out_rows,double * cost)865 int Item_in_subselect::optimize(double *out_rows, double *cost)
866 {
867 int res;
868 DBUG_ENTER("Item_in_subselect::optimize");
869 DBUG_ASSERT(fixed);
870 SELECT_LEX *save_select= thd->lex->current_select;
871 JOIN *join= unit->first_select()->join;
872
873 thd->lex->current_select= join->select_lex;
874 if ((res= join->optimize()))
875 DBUG_RETURN(res);
876
877 /* Calculate #rows and cost of join execution */
878 join->get_partial_cost_and_fanout(join->table_count - join->const_tables,
879 table_map(-1),
880 cost, out_rows);
881
882 /*
883 Adjust join output cardinality. There can be these cases:
884 - Have no GROUP BY and no aggregate funcs: we won't get into this
885 function because such join will be processed as a merged semi-join
886 (TODO: does it really mean we don't need to handle such cases here at
887 all? put ASSERT)
888 - Have no GROUP BY but have aggregate funcs: output is 1 record.
889 - Have GROUP BY and have (or not) aggregate funcs: need to adjust output
890 cardinality.
891 */
892 thd->lex->current_select= save_select;
893 if (!join->group_list && !join->group_optimized_away &&
894 join->tmp_table_param.sum_func_count)
895 {
896 DBUG_PRINT("info",("Materialized join will have only 1 row (it has "
897 "aggregates but no GROUP BY"));
898 *out_rows= 1;
899 }
900
901 /* Now with grouping */
902 if (join->group_list_for_estimates)
903 {
904 DBUG_PRINT("info",("Materialized join has grouping, trying to estimate it"));
905 double output_rows= get_post_group_estimate(join, *out_rows);
906 DBUG_PRINT("info",("Got value of %g", output_rows));
907 *out_rows= output_rows;
908 }
909
910 DBUG_RETURN(res);
911
912 }
913
914
915 /**
916 Check if an expression cache is needed for this subquery
917
918 @param thd Thread handle
919
920 @details
921 The function checks whether a cache is needed for a subquery and whether
922 the result of the subquery can be put in cache.
923
924 @retval TRUE cache is needed
925 @retval FALSE otherwise
926 */
927
expr_cache_is_needed(THD * thd)928 bool Item_subselect::expr_cache_is_needed(THD *thd)
929 {
930 return ((engine->uncacheable() & UNCACHEABLE_DEPENDENT) &&
931 engine->cols() == 1 &&
932 optimizer_flag(thd, OPTIMIZER_SWITCH_SUBQUERY_CACHE) &&
933 !(engine->uncacheable() & (UNCACHEABLE_RAND |
934 UNCACHEABLE_SIDEEFFECT)) &&
935 !with_recursive_reference);
936 }
937
938
939 /**
940 Check if the left IN argument contains NULL values.
941
942 @retval TRUE there are NULLs
943 @retval FALSE otherwise
944 */
945
left_expr_has_null()946 inline bool Item_in_subselect::left_expr_has_null()
947 {
948 return (*(optimizer->get_cache()))->null_value_inside;
949 }
950
951
952 /**
953 Check if an expression cache is needed for this subquery
954
955 @param thd Thread handle
956
957 @details
958 The function checks whether a cache is needed for a subquery and whether
959 the result of the subquery can be put in cache.
960
961 @note
962 This method allows many columns in the subquery because it is supported by
963 Item_in_optimizer and result of the IN subquery will be scalar in this
964 case.
965
966 @retval TRUE cache is needed
967 @retval FALSE otherwise
968 */
969
expr_cache_is_needed(THD * thd)970 bool Item_in_subselect::expr_cache_is_needed(THD *thd)
971 {
972 return (optimizer_flag(thd, OPTIMIZER_SWITCH_SUBQUERY_CACHE) &&
973 !(engine->uncacheable() & (UNCACHEABLE_RAND |
974 UNCACHEABLE_SIDEEFFECT)) &&
975 !with_recursive_reference);
976 }
977
978
979 /*
980 Compute the IN predicate if the left operand's cache changed.
981 */
982
exec()983 bool Item_in_subselect::exec()
984 {
985 DBUG_ENTER("Item_in_subselect::exec");
986 DBUG_ASSERT(fixed);
987 /*
988 Initialize the cache of the left predicate operand. This has to be done as
989 late as now, because Cached_item directly contains a resolved field (not
990 an item, and in some cases (when temp tables are created), these fields
991 end up pointing to the wrong field. One solution is to change Cached_item
992 to not resolve its field upon creation, but to resolve it dynamically
993 from a given Item_ref object.
994 TODO: the cache should be applied conditionally based on:
995 - rules - e.g. only if the left operand is known to be ordered, and/or
996 - on a cost-based basis, that takes into account the cost of a cache
997 lookup, the cache hit rate, and the savings per cache hit.
998 */
999 if (!left_expr_cache && (test_strategy(SUBS_MATERIALIZATION)))
1000 init_left_expr_cache();
1001
1002 /*
1003 If the new left operand is already in the cache, reuse the old result.
1004 Use the cached result only if this is not the first execution of IN
1005 because the cache is not valid for the first execution.
1006 */
1007 if (!first_execution && left_expr_cache &&
1008 test_if_item_cache_changed(*left_expr_cache) < 0)
1009 DBUG_RETURN(FALSE);
1010
1011 /*
1012 The exec() method below updates item::value, and item::null_value, thus if
1013 we don't call it, the next call to item::val_int() will return whatever
1014 result was computed by its previous call.
1015 */
1016 DBUG_RETURN(Item_subselect::exec());
1017 }
1018
1019
type() const1020 Item::Type Item_subselect::type() const
1021 {
1022 return SUBSELECT_ITEM;
1023 }
1024
1025
fix_length_and_dec()1026 bool Item_subselect::fix_length_and_dec()
1027 {
1028 if (engine->fix_length_and_dec(0))
1029 return TRUE;
1030 return FALSE;
1031 }
1032
1033
used_tables() const1034 table_map Item_subselect::used_tables() const
1035 {
1036 return (table_map) ((engine->uncacheable() & ~UNCACHEABLE_EXPLAIN)?
1037 used_tables_cache : 0L);
1038 }
1039
1040
const_item() const1041 bool Item_subselect::const_item() const
1042 {
1043 DBUG_ASSERT(thd);
1044 return (thd->lex->context_analysis_only || with_recursive_reference ?
1045 FALSE :
1046 forced_const || const_item_cache);
1047 }
1048
get_tmp_table_item(THD * thd_arg)1049 Item *Item_subselect::get_tmp_table_item(THD *thd_arg)
1050 {
1051 if (!Item_subselect::with_sum_func() && !const_item())
1052 return new (thd->mem_root) Item_temptable_field(thd_arg, result_field);
1053 return copy_or_same(thd_arg);
1054 }
1055
update_used_tables()1056 void Item_subselect::update_used_tables()
1057 {
1058 if (!forced_const)
1059 {
1060 recalc_used_tables(parent_select, FALSE);
1061 if (!(engine->uncacheable() & ~UNCACHEABLE_EXPLAIN))
1062 {
1063 // did all used tables become static?
1064 if (!(used_tables_cache & ~engine->upper_select_const_tables()) &&
1065 ! with_recursive_reference)
1066 const_item_cache= 1;
1067 }
1068 }
1069 }
1070
1071
print(String * str,enum_query_type query_type)1072 void Item_subselect::print(String *str, enum_query_type query_type)
1073 {
1074 if (query_type & QT_ITEM_SUBSELECT_ID_ONLY)
1075 {
1076 str->append(STRING_WITH_LEN("(subquery#"));
1077 if (unit && unit->first_select())
1078 {
1079 char buf[64];
1080 ll2str(unit->first_select()->select_number, buf, 10, 0);
1081 str->append(buf);
1082 }
1083 else
1084 str->append("NULL"); // TODO: what exactly does this mean?
1085
1086 str->append(")");
1087 return;
1088 }
1089 if (engine)
1090 {
1091 str->append('(');
1092 engine->print(str, query_type);
1093 str->append(')');
1094 }
1095 else
1096 str->append("(...)");
1097 }
1098
1099
Item_singlerow_subselect(THD * thd,st_select_lex * select_lex)1100 Item_singlerow_subselect::Item_singlerow_subselect(THD *thd, st_select_lex *select_lex):
1101 Item_subselect(thd), value(0)
1102 {
1103 DBUG_ENTER("Item_singlerow_subselect::Item_singlerow_subselect");
1104 init(select_lex, new (thd->mem_root) select_singlerow_subselect(thd, this));
1105 maybe_null= 1;
1106 max_columns= UINT_MAX;
1107 DBUG_VOID_RETURN;
1108 }
1109
1110 st_select_lex *
invalidate_and_restore_select_lex()1111 Item_singlerow_subselect::invalidate_and_restore_select_lex()
1112 {
1113 DBUG_ENTER("Item_singlerow_subselect::invalidate_and_restore_select_lex");
1114 st_select_lex *result= get_select_lex();
1115
1116 DBUG_ASSERT(result);
1117
1118 /*
1119 This code restore the parse tree in it's state before the execution of
1120 Item_singlerow_subselect::Item_singlerow_subselect(),
1121 and in particular decouples this object from the SELECT_LEX,
1122 so that the SELECT_LEX can be used with a different flavor
1123 or Item_subselect instead, as part of query rewriting.
1124 */
1125 unit->item= NULL;
1126
1127 DBUG_RETURN(result);
1128 }
1129
Item_maxmin_subselect(THD * thd,Item_subselect * parent,st_select_lex * select_lex,bool max_arg)1130 Item_maxmin_subselect::Item_maxmin_subselect(THD *thd,
1131 Item_subselect *parent,
1132 st_select_lex *select_lex,
1133 bool max_arg):
1134 Item_singlerow_subselect(thd), was_values(TRUE)
1135 {
1136 DBUG_ENTER("Item_maxmin_subselect::Item_maxmin_subselect");
1137 max= max_arg;
1138 init(select_lex,
1139 new (thd->mem_root) select_max_min_finder_subselect(thd,
1140 this, max_arg, parent->substype() == Item_subselect::ALL_SUBS));
1141 max_columns= 1;
1142 maybe_null= 1;
1143 max_columns= 1;
1144
1145 /*
1146 Following information was collected during performing fix_fields()
1147 of Items belonged to subquery, which will be not repeated
1148 */
1149 used_tables_cache= parent->get_used_tables_cache();
1150 const_item_cache= parent->const_item();
1151
1152 DBUG_VOID_RETURN;
1153 }
1154
cleanup()1155 void Item_maxmin_subselect::cleanup()
1156 {
1157 DBUG_ENTER("Item_maxmin_subselect::cleanup");
1158 Item_singlerow_subselect::cleanup();
1159
1160 /*
1161 By default it is TRUE to avoid TRUE reporting by
1162 Item_func_not_all/Item_func_nop_all if this item was never called.
1163
1164 Engine exec() set it to FALSE by reset_value_registration() call.
1165 select_max_min_finder_subselect::send_data() set it back to TRUE if some
1166 value will be found.
1167 */
1168 was_values= TRUE;
1169 DBUG_VOID_RETURN;
1170 }
1171
1172
print(String * str,enum_query_type query_type)1173 void Item_maxmin_subselect::print(String *str, enum_query_type query_type)
1174 {
1175 str->append(max?"<max>":"<min>", 5);
1176 Item_singlerow_subselect::print(str, query_type);
1177 }
1178
1179
no_rows_in_result()1180 void Item_maxmin_subselect::no_rows_in_result()
1181 {
1182 /*
1183 Subquery predicates outside of the SELECT list must be evaluated in order
1184 to possibly filter the special result row generated for implicit grouping
1185 if the subquery is in the HAVING clause.
1186 If the predicate is constant, we need its actual value in the only result
1187 row for queries with implicit grouping.
1188 */
1189 if (parsing_place != SELECT_LIST || const_item())
1190 return;
1191 value= get_cache(thd);
1192 null_value= 0;
1193 was_values= 0;
1194 make_const();
1195 }
1196
1197
no_rows_in_result()1198 void Item_singlerow_subselect::no_rows_in_result()
1199 {
1200 /*
1201 Subquery predicates outside of the SELECT list must be evaluated in order
1202 to possibly filter the special result row generated for implicit grouping
1203 if the subquery is in the HAVING clause.
1204 If the predicate is constant, we need its actual value in the only result
1205 row for queries with implicit grouping.
1206 */
1207 if (parsing_place != SELECT_LIST || const_item())
1208 return;
1209 value= get_cache(thd);
1210 reset();
1211 make_const();
1212 }
1213
1214
reset()1215 void Item_singlerow_subselect::reset()
1216 {
1217 Item_subselect::reset();
1218 if (value)
1219 {
1220 for(uint i= 0; i < engine->cols(); i++)
1221 row[i]->set_null();
1222 }
1223 }
1224
1225
1226 /**
1227 @todo
1228 - We can't change name of Item_field or Item_ref, because it will
1229 prevent its correct resolving, but we should save name of
1230 removed item => we do not make optimization if top item of
1231 list is field or reference.
1232 - switch off this optimization for prepare statement,
1233 because we do not rollback these changes.
1234 Make rollback for it, or special name resolving mode in 5.0.
1235
1236 @param join Join object of the subquery (i.e. 'child' join).
1237
1238 @retval false The subquery was transformed
1239 */
1240 bool
select_transformer(JOIN * join)1241 Item_singlerow_subselect::select_transformer(JOIN *join)
1242 {
1243 DBUG_ENTER("Item_singlerow_subselect::select_transformer");
1244 if (changed)
1245 DBUG_RETURN(false);
1246 DBUG_ASSERT(join->thd == thd);
1247
1248 SELECT_LEX *select_lex= join->select_lex;
1249 Query_arena *arena= thd->stmt_arena;
1250
1251 if (!select_lex->master_unit()->is_unit_op() &&
1252 !select_lex->table_list.elements &&
1253 select_lex->item_list.elements == 1 &&
1254 !select_lex->item_list.head()->with_sum_func() &&
1255 /*
1256 We can't change name of Item_field or Item_ref, because it will
1257 prevent its correct resolving, but we should save name of
1258 removed item => we do not make optimization if top item of
1259 list is field or reference.
1260 TODO: solve above problem
1261 */
1262 !(select_lex->item_list.head()->type() == FIELD_ITEM ||
1263 select_lex->item_list.head()->type() == REF_ITEM) &&
1264 !join->conds && !join->having &&
1265 /*
1266 switch off this optimization for prepare statement,
1267 because we do not rollback this changes
1268 TODO: make rollback for it, or special name resolving mode in 5.0.
1269 */
1270 !arena->is_stmt_prepare_or_first_sp_execute()
1271 )
1272 {
1273 have_to_be_excluded= 1;
1274 if (thd->lex->describe)
1275 {
1276 char warn_buff[MYSQL_ERRMSG_SIZE];
1277 sprintf(warn_buff, ER_THD(thd, ER_SELECT_REDUCED),
1278 select_lex->select_number);
1279 push_warning(thd, Sql_condition::WARN_LEVEL_NOTE,
1280 ER_SELECT_REDUCED, warn_buff);
1281 }
1282 substitution= select_lex->item_list.head();
1283 /*
1284 as far as we moved content to upper level we have to fix dependences & Co
1285 */
1286 substitution->fix_after_pullout(select_lex->outer_select(),
1287 &substitution, TRUE);
1288 }
1289 DBUG_RETURN(false);
1290 }
1291
1292
store(uint i,Item * item)1293 void Item_singlerow_subselect::store(uint i, Item *item)
1294 {
1295 row[i]->store(item);
1296 row[i]->cache_value();
1297 }
1298
type_handler() const1299 const Type_handler *Item_singlerow_subselect::type_handler() const
1300 {
1301 return engine->type_handler();
1302 }
1303
fix_length_and_dec()1304 bool Item_singlerow_subselect::fix_length_and_dec()
1305 {
1306 if ((max_columns= engine->cols()) == 1)
1307 {
1308 if (engine->fix_length_and_dec(row= &value))
1309 return TRUE;
1310 }
1311 else
1312 {
1313 if (!(row= (Item_cache**) current_thd->alloc(sizeof(Item_cache*) *
1314 max_columns)) ||
1315 engine->fix_length_and_dec(row))
1316 return TRUE;
1317 value= *row;
1318 }
1319 unsigned_flag= value->unsigned_flag;
1320 /*
1321 If there are not tables in subquery then ability to have NULL value
1322 depends on SELECT list (if single row subquery have tables then it
1323 always can be NULL if there are not records fetched).
1324 */
1325 if (engine->no_tables())
1326 maybe_null= engine->may_be_null();
1327 else
1328 {
1329 for (uint i= 0; i < max_columns; i++)
1330 row[i]->maybe_null= TRUE;
1331 }
1332 return FALSE;
1333 }
1334
1335
1336 /**
1337 Add an expression cache for this subquery if it is needed
1338
1339 @param thd_arg Thread handle
1340
1341 @details
1342 The function checks whether an expression cache is needed for this item
1343 and if if so wraps the item into an item of the class
1344 Item_cache_wrapper with an appropriate expression cache set up there.
1345
1346 @note
1347 used from Item::transform()
1348
1349 @return
1350 new wrapper item if an expression cache is needed,
1351 this item - otherwise
1352 */
1353
expr_cache_insert_transformer(THD * tmp_thd,uchar * unused)1354 Item* Item_singlerow_subselect::expr_cache_insert_transformer(THD *tmp_thd,
1355 uchar *unused)
1356 {
1357 DBUG_ENTER("Item_singlerow_subselect::expr_cache_insert_transformer");
1358
1359 DBUG_ASSERT(thd == tmp_thd);
1360
1361 if (expr_cache)
1362 DBUG_RETURN(expr_cache);
1363
1364 if (expr_cache_is_needed(tmp_thd) &&
1365 (expr_cache= set_expr_cache(tmp_thd)))
1366 {
1367 init_expr_cache_tracker(tmp_thd);
1368 DBUG_RETURN(expr_cache);
1369 }
1370 DBUG_RETURN(this);
1371 }
1372
1373
cols() const1374 uint Item_singlerow_subselect::cols() const
1375 {
1376 return engine->cols();
1377 }
1378
check_cols(uint c)1379 bool Item_singlerow_subselect::check_cols(uint c)
1380 {
1381 if (c != engine->cols())
1382 {
1383 my_error(ER_OPERAND_COLUMNS, MYF(0), c);
1384 return 1;
1385 }
1386 return 0;
1387 }
1388
null_inside()1389 bool Item_singlerow_subselect::null_inside()
1390 {
1391 for (uint i= 0; i < max_columns ; i++)
1392 {
1393 if (row[i]->null_value)
1394 return 1;
1395 }
1396 return 0;
1397 }
1398
bring_value()1399 void Item_singlerow_subselect::bring_value()
1400 {
1401 if (!exec() && assigned())
1402 {
1403 null_value= true;
1404 for (uint i= 0; i < max_columns ; i++)
1405 {
1406 if (!row[i]->null_value)
1407 {
1408 null_value= false;
1409 return;
1410 }
1411 }
1412 }
1413 else
1414 reset();
1415 }
1416
val_real()1417 double Item_singlerow_subselect::val_real()
1418 {
1419 DBUG_ASSERT(fixed == 1);
1420 if (forced_const)
1421 return value->val_real();
1422 if (!exec() && !value->null_value)
1423 {
1424 null_value= FALSE;
1425 return value->val_real();
1426 }
1427 else
1428 {
1429 reset();
1430 return 0;
1431 }
1432 }
1433
val_int()1434 longlong Item_singlerow_subselect::val_int()
1435 {
1436 DBUG_ASSERT(fixed == 1);
1437 if (forced_const)
1438 {
1439 longlong val= value->val_int();
1440 null_value= value->null_value;
1441 return val;
1442 }
1443 if (!exec() && !value->null_value)
1444 {
1445 null_value= FALSE;
1446 return value->val_int();
1447 }
1448 else
1449 {
1450 reset();
1451 DBUG_ASSERT(null_value);
1452 return 0;
1453 }
1454 }
1455
val_str(String * str)1456 String *Item_singlerow_subselect::val_str(String *str)
1457 {
1458 DBUG_ASSERT(fixed == 1);
1459 if (forced_const)
1460 {
1461 String *res= value->val_str(str);
1462 null_value= value->null_value;
1463 return res;
1464 }
1465 if (!exec() && !value->null_value)
1466 {
1467 null_value= FALSE;
1468 return value->val_str(str);
1469 }
1470 else
1471 {
1472 reset();
1473 DBUG_ASSERT(null_value);
1474 return 0;
1475 }
1476 }
1477
1478
val_native(THD * thd,Native * to)1479 bool Item_singlerow_subselect::val_native(THD *thd, Native *to)
1480 {
1481 DBUG_ASSERT(fixed == 1);
1482 if (forced_const)
1483 return value->val_native(thd, to);
1484 if (!exec() && !value->null_value)
1485 {
1486 null_value= false;
1487 return value->val_native(thd, to);
1488 }
1489 else
1490 {
1491 reset();
1492 return true;
1493 }
1494 }
1495
1496
val_decimal(my_decimal * decimal_value)1497 my_decimal *Item_singlerow_subselect::val_decimal(my_decimal *decimal_value)
1498 {
1499 DBUG_ASSERT(fixed == 1);
1500 if (forced_const)
1501 {
1502 my_decimal *val= value->val_decimal(decimal_value);
1503 null_value= value->null_value;
1504 return val;
1505 }
1506 if (!exec() && !value->null_value)
1507 {
1508 null_value= FALSE;
1509 return value->val_decimal(decimal_value);
1510 }
1511 else
1512 {
1513 reset();
1514 DBUG_ASSERT(null_value);
1515 return 0;
1516 }
1517 }
1518
1519
val_bool()1520 bool Item_singlerow_subselect::val_bool()
1521 {
1522 DBUG_ASSERT(fixed == 1);
1523 if (forced_const)
1524 {
1525 bool val= value->val_bool();
1526 null_value= value->null_value;
1527 return val;
1528 }
1529 if (!exec() && !value->null_value)
1530 {
1531 null_value= FALSE;
1532 return value->val_bool();
1533 }
1534 else
1535 {
1536 reset();
1537 DBUG_ASSERT(null_value);
1538 return 0;
1539 }
1540 }
1541
1542
get_date(THD * thd,MYSQL_TIME * ltime,date_mode_t fuzzydate)1543 bool Item_singlerow_subselect::get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate)
1544 {
1545 DBUG_ASSERT(fixed == 1);
1546 if (forced_const)
1547 {
1548 bool val= value->get_date(thd, ltime, fuzzydate);
1549 null_value= value->null_value;
1550 return val;
1551 }
1552 if (!exec() && !value->null_value)
1553 {
1554 null_value= FALSE;
1555 return value->get_date(thd, ltime, fuzzydate);
1556 }
1557 else
1558 {
1559 reset();
1560 DBUG_ASSERT(null_value);
1561 return 1;
1562 }
1563 }
1564
1565
Item_exists_subselect(THD * thd,st_select_lex * select_lex)1566 Item_exists_subselect::Item_exists_subselect(THD *thd,
1567 st_select_lex *select_lex):
1568 Item_subselect(thd), upper_not(NULL), abort_on_null(0),
1569 emb_on_expr_nest(NULL), optimizer(0), exists_transformed(0)
1570 {
1571 DBUG_ENTER("Item_exists_subselect::Item_exists_subselect");
1572
1573
1574 init(select_lex, new (thd->mem_root) select_exists_subselect(thd, this));
1575 max_columns= UINT_MAX;
1576 null_value= FALSE; //can't be NULL
1577 maybe_null= 0; //can't be NULL
1578 value= 0;
1579 DBUG_VOID_RETURN;
1580 }
1581
1582
print(String * str,enum_query_type query_type)1583 void Item_exists_subselect::print(String *str, enum_query_type query_type)
1584 {
1585 str->append(STRING_WITH_LEN("exists"));
1586 Item_subselect::print(str, query_type);
1587 }
1588
1589
test_limit(st_select_lex_unit * unit_arg)1590 bool Item_in_subselect::test_limit(st_select_lex_unit *unit_arg)
1591 {
1592 if (unlikely(unit_arg->fake_select_lex &&
1593 unit_arg->fake_select_lex->test_limit()))
1594 return(1);
1595
1596 SELECT_LEX *sl= unit_arg->first_select();
1597 for (; sl; sl= sl->next_select())
1598 {
1599 if (unlikely(sl->test_limit()))
1600 return(1);
1601 }
1602 return(0);
1603 }
1604
Item_in_subselect(THD * thd,Item * left_exp,st_select_lex * select_lex)1605 Item_in_subselect::Item_in_subselect(THD *thd, Item * left_exp,
1606 st_select_lex *select_lex):
1607 Item_exists_subselect(thd), left_expr_cache(0), first_execution(TRUE),
1608 in_strategy(SUBS_NOT_TRANSFORMED),
1609 pushed_cond_guards(NULL), do_not_convert_to_sj(FALSE), is_jtbm_merged(FALSE),
1610 is_jtbm_const_tab(FALSE), is_flattenable_semijoin(FALSE),
1611 is_registered_semijoin(FALSE),
1612 upper_item(0),
1613 converted_from_in_predicate(FALSE)
1614 {
1615 DBUG_ENTER("Item_in_subselect::Item_in_subselect");
1616 DBUG_PRINT("info", ("in_strategy: %u", (uint)in_strategy));
1617
1618 left_expr_orig= left_expr= left_exp;
1619 /* prepare to possible disassembling the item in convert_subq_to_sj() */
1620 if (left_exp->type() == Item::ROW_ITEM)
1621 left_expr_orig= new (thd->mem_root)
1622 Item_row(thd, static_cast<Item_row*>(left_exp));
1623 func= &eq_creator;
1624 init(select_lex, new (thd->mem_root) select_exists_subselect(thd, this));
1625 max_columns= UINT_MAX;
1626 maybe_null= 1;
1627 reset();
1628 //if test_limit will fail then error will be reported to client
1629 test_limit(select_lex->master_unit());
1630 DBUG_VOID_RETURN;
1631 }
1632
get_identifier()1633 int Item_in_subselect::get_identifier()
1634 {
1635 return engine->get_identifier();
1636 }
1637
Item_allany_subselect(THD * thd,Item * left_exp,chooser_compare_func_creator fc,st_select_lex * select_lex,bool all_arg)1638 Item_allany_subselect::Item_allany_subselect(THD *thd, Item * left_exp,
1639 chooser_compare_func_creator fc,
1640 st_select_lex *select_lex,
1641 bool all_arg):
1642 Item_in_subselect(thd), func_creator(fc), all(all_arg)
1643 {
1644 DBUG_ENTER("Item_allany_subselect::Item_allany_subselect");
1645 left_expr_orig= left_expr= left_exp;
1646 /* prepare to possible disassembling the item in convert_subq_to_sj() */
1647 if (left_exp->type() == Item::ROW_ITEM)
1648 left_expr_orig= new (thd->mem_root)
1649 Item_row(thd, static_cast<Item_row*>(left_exp));
1650 func= func_creator(all_arg);
1651 init(select_lex, new (thd->mem_root) select_exists_subselect(thd, this));
1652 max_columns= 1;
1653 abort_on_null= 0;
1654 reset();
1655 //if test_limit will fail then error will be reported to client
1656 test_limit(select_lex->master_unit());
1657 DBUG_VOID_RETURN;
1658 }
1659
1660
1661 /**
1662 Initialize length and decimals for EXISTS and inherited (IN/ALL/ANY)
1663 subqueries
1664 */
1665
init_length_and_dec()1666 void Item_exists_subselect::init_length_and_dec()
1667 {
1668 decimals= 0;
1669 max_length= 1;
1670 max_columns= engine->cols();
1671 }
1672
1673
fix_length_and_dec()1674 bool Item_exists_subselect::fix_length_and_dec()
1675 {
1676 DBUG_ENTER("Item_exists_subselect::fix_length_and_dec");
1677 init_length_and_dec();
1678 // If limit is not set or it is constant more than 1
1679 if (!unit->global_parameters()->select_limit ||
1680 (unit->global_parameters()->select_limit->basic_const_item() &&
1681 unit->global_parameters()->select_limit->val_int() > 1))
1682 {
1683 /*
1684 We need only 1 row to determine existence (i.e. any EXISTS that is not
1685 an IN always requires LIMIT 1)
1686 */
1687 Item *item= new (thd->mem_root) Item_int(thd, (int32) 1);
1688 if (!item)
1689 DBUG_RETURN(TRUE);
1690 thd->change_item_tree(&unit->global_parameters()->select_limit,
1691 item);
1692 unit->global_parameters()->explicit_limit= 1; // we set the limit
1693 DBUG_PRINT("info", ("Set limit to 1"));
1694 }
1695 DBUG_RETURN(FALSE);
1696 }
1697
1698
fix_length_and_dec()1699 bool Item_in_subselect::fix_length_and_dec()
1700 {
1701 DBUG_ENTER("Item_in_subselect::fix_length_and_dec");
1702 init_length_and_dec();
1703 /*
1704 Unlike Item_exists_subselect, LIMIT 1 is set later for
1705 Item_in_subselect, depending on the chosen strategy.
1706 */
1707 DBUG_RETURN(FALSE);
1708 }
1709
1710
1711 /**
1712 Add an expression cache for this subquery if it is needed
1713
1714 @param thd_arg Thread handle
1715
1716 @details
1717 The function checks whether an expression cache is needed for this item
1718 and if if so wraps the item into an item of the class
1719 Item_cache_wrapper with an appropriate expression cache set up there.
1720
1721 @note
1722 used from Item::transform()
1723
1724 @return
1725 new wrapper item if an expression cache is needed,
1726 this item - otherwise
1727 */
1728
expr_cache_insert_transformer(THD * tmp_thd,uchar * unused)1729 Item* Item_exists_subselect::expr_cache_insert_transformer(THD *tmp_thd,
1730 uchar *unused)
1731 {
1732 DBUG_ENTER("Item_exists_subselect::expr_cache_insert_transformer");
1733 DBUG_ASSERT(thd == tmp_thd);
1734
1735 if (expr_cache)
1736 DBUG_RETURN(expr_cache);
1737
1738 if (substype() == EXISTS_SUBS && expr_cache_is_needed(tmp_thd) &&
1739 (expr_cache= set_expr_cache(tmp_thd)))
1740 {
1741 init_expr_cache_tracker(tmp_thd);
1742 DBUG_RETURN(expr_cache);
1743 }
1744 DBUG_RETURN(this);
1745 }
1746
1747
no_rows_in_result()1748 void Item_exists_subselect::no_rows_in_result()
1749 {
1750 /*
1751 Subquery predicates outside of the SELECT list must be evaluated in order
1752 to possibly filter the special result row generated for implicit grouping
1753 if the subquery is in the HAVING clause.
1754 If the predicate is constant, we need its actual value in the only result
1755 row for queries with implicit grouping.
1756 */
1757 if (parsing_place != SELECT_LIST || const_item())
1758 return;
1759 value= 0;
1760 null_value= 0;
1761 make_const();
1762 }
1763
val_real()1764 double Item_exists_subselect::val_real()
1765 {
1766 DBUG_ASSERT(fixed == 1);
1767 if (!forced_const && exec())
1768 {
1769 reset();
1770 return 0;
1771 }
1772 return (double) value;
1773 }
1774
val_int()1775 longlong Item_exists_subselect::val_int()
1776 {
1777 DBUG_ASSERT(fixed == 1);
1778 if (!forced_const && exec())
1779 {
1780 reset();
1781 return 0;
1782 }
1783 return value;
1784 }
1785
1786
1787 /**
1788 Return the result of EXISTS as a string value
1789
1790 Converts the true/false result into a string value.
1791 Note that currently this cannot be NULL, so if the query execution fails
1792 it will return 0.
1793
1794 @param decimal_value[out] buffer to hold the resulting string value
1795 @retval Pointer to the converted string.
1796 Can't be a NULL pointer, as currently
1797 EXISTS cannot return NULL.
1798 */
1799
val_str(String * str)1800 String *Item_exists_subselect::val_str(String *str)
1801 {
1802 DBUG_ASSERT(fixed == 1);
1803 if (!forced_const && exec())
1804 reset();
1805 str->set((ulonglong)value,&my_charset_bin);
1806 return str;
1807 }
1808
1809
1810 /**
1811 Return the result of EXISTS as a decimal value
1812
1813 Converts the true/false result into a decimal value.
1814 Note that currently this cannot be NULL, so if the query execution fails
1815 it will return 0.
1816
1817 @param decimal_value[out] Buffer to hold the resulting decimal value
1818 @retval Pointer to the converted decimal.
1819 Can't be a NULL pointer, as currently
1820 EXISTS cannot return NULL.
1821 */
1822
val_decimal(my_decimal * decimal_value)1823 my_decimal *Item_exists_subselect::val_decimal(my_decimal *decimal_value)
1824 {
1825 DBUG_ASSERT(fixed == 1);
1826 if (!forced_const && exec())
1827 reset();
1828 int2my_decimal(E_DEC_FATAL_ERROR, value, 0, decimal_value);
1829 return decimal_value;
1830 }
1831
1832
val_bool()1833 bool Item_exists_subselect::val_bool()
1834 {
1835 DBUG_ASSERT(fixed == 1);
1836 if (!forced_const && exec())
1837 {
1838 reset();
1839 return 0;
1840 }
1841 return value != 0;
1842 }
1843
1844
val_real()1845 double Item_in_subselect::val_real()
1846 {
1847 /*
1848 As far as Item_in_subselect called only from Item_in_optimizer this
1849 method should not be used
1850 */
1851 DBUG_ASSERT(fixed == 1);
1852 if (forced_const)
1853 return value;
1854 DBUG_ASSERT((engine->uncacheable() & ~UNCACHEABLE_EXPLAIN) ||
1855 ! engine->is_executed());
1856 null_value= was_null= FALSE;
1857 if (exec())
1858 {
1859 reset();
1860 return 0;
1861 }
1862 if (was_null && !value)
1863 null_value= TRUE;
1864 return (double) value;
1865 }
1866
1867
val_int()1868 longlong Item_in_subselect::val_int()
1869 {
1870 /*
1871 As far as Item_in_subselect called only from Item_in_optimizer this
1872 method should not be used
1873 */
1874 DBUG_ASSERT(0);
1875 DBUG_ASSERT(fixed == 1);
1876 if (forced_const)
1877 return value;
1878 DBUG_ASSERT((engine->uncacheable() & ~UNCACHEABLE_EXPLAIN) ||
1879 ! engine->is_executed());
1880 null_value= was_null= FALSE;
1881 if (exec())
1882 {
1883 reset();
1884 return 0;
1885 }
1886 if (was_null && !value)
1887 null_value= TRUE;
1888 return value;
1889 }
1890
1891
val_str(String * str)1892 String *Item_in_subselect::val_str(String *str)
1893 {
1894 /*
1895 As far as Item_in_subselect called only from Item_in_optimizer this
1896 method should not be used
1897 */
1898 DBUG_ASSERT(0);
1899 DBUG_ASSERT(fixed == 1);
1900 if (forced_const)
1901 goto value_is_ready;
1902 DBUG_ASSERT((engine->uncacheable() & ~UNCACHEABLE_EXPLAIN) ||
1903 ! engine->is_executed());
1904 null_value= was_null= FALSE;
1905 if (exec())
1906 {
1907 reset();
1908 return 0;
1909 }
1910 if (was_null && !value)
1911 {
1912 null_value= TRUE;
1913 return 0;
1914 }
1915 value_is_ready:
1916 str->set((ulonglong)value, &my_charset_bin);
1917 return str;
1918 }
1919
1920
val_bool()1921 bool Item_in_subselect::val_bool()
1922 {
1923 DBUG_ASSERT(fixed == 1);
1924 if (forced_const)
1925 return value;
1926 DBUG_ASSERT((engine->uncacheable() & ~UNCACHEABLE_EXPLAIN) ||
1927 ! engine->is_executed() || with_recursive_reference);
1928 null_value= was_null= FALSE;
1929 if (exec())
1930 {
1931 reset();
1932 return 0;
1933 }
1934 if (was_null && !value)
1935 null_value= TRUE;
1936 return value;
1937 }
1938
val_decimal(my_decimal * decimal_value)1939 my_decimal *Item_in_subselect::val_decimal(my_decimal *decimal_value)
1940 {
1941 /*
1942 As far as Item_in_subselect called only from Item_in_optimizer this
1943 method should not be used
1944 */
1945 DBUG_ASSERT(0);
1946 if (forced_const)
1947 goto value_is_ready;
1948 DBUG_ASSERT((engine->uncacheable() & ~UNCACHEABLE_EXPLAIN) ||
1949 ! engine->is_executed());
1950 null_value= was_null= FALSE;
1951 DBUG_ASSERT(fixed == 1);
1952 if (exec())
1953 {
1954 reset();
1955 return 0;
1956 }
1957 if (was_null && !value)
1958 null_value= TRUE;
1959 value_is_ready:
1960 int2my_decimal(E_DEC_FATAL_ERROR, value, 0, decimal_value);
1961 return decimal_value;
1962 }
1963
1964
1965 /**
1966 Prepare a single-column IN/ALL/ANY subselect for rewriting.
1967
1968 @param join Join object of the subquery (i.e. 'child' join).
1969
1970 @details
1971
1972 Prepare a single-column subquery to be rewritten. Given the subquery.
1973
1974 If the subquery has no tables it will be turned to an expression between
1975 left part and SELECT list.
1976
1977 In other cases the subquery will be wrapped with Item_in_optimizer which
1978 allow later to turn it to EXISTS or MAX/MIN.
1979
1980 @retval false The subquery was transformed
1981 @retval true Error
1982 */
1983
1984 bool
single_value_transformer(JOIN * join)1985 Item_in_subselect::single_value_transformer(JOIN *join)
1986 {
1987 SELECT_LEX *select_lex= join->select_lex;
1988 DBUG_ENTER("Item_in_subselect::single_value_transformer");
1989 DBUG_ASSERT(thd == join->thd);
1990
1991 /*
1992 Check that the right part of the subselect contains no more than one
1993 column. E.g. in SELECT 1 IN (SELECT * ..) the right part is (SELECT * ...)
1994 */
1995 // psergey: duplicated_subselect_card_check
1996 if (select_lex->item_list.elements > 1)
1997 {
1998 my_error(ER_OPERAND_COLUMNS, MYF(0), 1);
1999 DBUG_RETURN(true);
2000 }
2001
2002 Item* join_having= join->having ? join->having : join->tmp_having;
2003 if (!(join_having || select_lex->with_sum_func ||
2004 select_lex->group_list.elements) &&
2005 select_lex->table_list.elements == 0 && !join->conds &&
2006 !select_lex->master_unit()->is_unit_op())
2007 {
2008 Item *where_item= (Item*) select_lex->item_list.head();
2009 /*
2010 it is single select without tables => possible optimization
2011 remove the dependence mark since the item is moved to upper
2012 select and is not outer anymore.
2013 */
2014 where_item->walk(&Item::remove_dependence_processor, 0,
2015 select_lex->outer_select());
2016 /*
2017 fix_field of substitution item will be done in time of
2018 substituting.
2019 Note that real_item() should be used instead of
2020 original left expression because left_expr can be
2021 runtime created Ref item which is deleted at the end
2022 of the statement. Thus one of 'substitution' arguments
2023 can be broken in case of PS.
2024 */
2025 substitution= func->create(thd, left_expr, where_item);
2026 have_to_be_excluded= 1;
2027 if (thd->lex->describe)
2028 {
2029 char warn_buff[MYSQL_ERRMSG_SIZE];
2030 sprintf(warn_buff, ER_THD(thd, ER_SELECT_REDUCED),
2031 select_lex->select_number);
2032 push_warning(thd, Sql_condition::WARN_LEVEL_NOTE,
2033 ER_SELECT_REDUCED, warn_buff);
2034 }
2035 DBUG_RETURN(false);
2036 }
2037
2038 /*
2039 Wrap the current IN predicate in an Item_in_optimizer. The actual
2040 substitution in the Item tree takes place in Item_subselect::fix_fields.
2041 */
2042 if (!substitution)
2043 {
2044 /* We're invoked for the 1st (or the only) SELECT in the subquery UNION */
2045 substitution= optimizer;
2046
2047 SELECT_LEX *current= thd->lex->current_select;
2048
2049 thd->lex->current_select= current->return_after_parsing();
2050 if (!optimizer || optimizer->fix_left(thd))
2051 {
2052 thd->lex->current_select= current;
2053 DBUG_RETURN(true);
2054 }
2055 thd->lex->current_select= current;
2056
2057 /* We will refer to upper level cache array => we have to save it for SP */
2058 optimizer->keep_top_level_cache();
2059
2060 /*
2061 As far as Item_in_optimizer does not substitute itself on fix_fields
2062 we can use same item for all selects.
2063 */
2064 expr= new (thd->mem_root) Item_direct_ref(thd, &select_lex->context,
2065 (Item**)optimizer->get_cache(),
2066 no_matter_name,
2067 in_left_expr_name);
2068 }
2069
2070 DBUG_RETURN(false);
2071 }
2072
2073
2074 /**
2075 Apply transformation max/min transwormation to ALL/ANY subquery if it is
2076 possible.
2077
2078 @param join Join object of the subquery (i.e. 'child' join).
2079
2080 @details
2081
2082 If this is an ALL/ANY single-value subselect, try to rewrite it with
2083 a MIN/MAX subselect. We can do that if a possible NULL result of the
2084 subselect can be ignored.
2085 E.g. SELECT * FROM t1 WHERE b > ANY (SELECT a FROM t2) can be rewritten
2086 with SELECT * FROM t1 WHERE b > (SELECT MAX(a) FROM t2).
2087 We can't check that this optimization is safe if it's not a top-level
2088 item of the WHERE clause (e.g. because the WHERE clause can contain IS
2089 NULL/IS NOT NULL functions). If so, we rewrite ALL/ANY with NOT EXISTS
2090 later in this method.
2091
2092 @retval false The subquery was transformed
2093 @retval true Error
2094 */
2095
transform_into_max_min(JOIN * join)2096 bool Item_allany_subselect::transform_into_max_min(JOIN *join)
2097 {
2098 DBUG_ENTER("Item_allany_subselect::transform_into_max_min");
2099 if (!test_strategy(SUBS_MAXMIN_INJECTED | SUBS_MAXMIN_ENGINE))
2100 DBUG_RETURN(false);
2101 Item **place= optimizer->arguments() + 1;
2102 SELECT_LEX *select_lex= join->select_lex;
2103 Item *subs;
2104 DBUG_ASSERT(thd == join->thd);
2105
2106 /*
2107 */
2108 DBUG_ASSERT(!substitution);
2109
2110 /*
2111 Check if optimization with aggregate min/max possible
2112 1 There is no aggregate in the subquery
2113 2 It is not UNION
2114 3 There is tables
2115 4 It is not ALL subquery with possible NULLs in the SELECT list
2116 */
2117 if (!select_lex->group_list.elements && /*1*/
2118 !select_lex->having && /*1*/
2119 !select_lex->with_sum_func && /*1*/
2120 !(select_lex->next_select()) && /*2*/
2121 select_lex->table_list.elements && /*3*/
2122 (!select_lex->ref_pointer_array[0]->maybe_null || /*4*/
2123 substype() != Item_subselect::ALL_SUBS)) /*4*/
2124 {
2125 Item_sum_min_max *item;
2126 nesting_map save_allow_sum_func;
2127 if (func->l_op())
2128 {
2129 /*
2130 (ALL && (> || =>)) || (ANY && (< || =<))
2131 for ALL condition is inverted
2132 */
2133 item= new (thd->mem_root) Item_sum_max(thd,
2134 select_lex->ref_pointer_array[0]);
2135 }
2136 else
2137 {
2138 /*
2139 (ALL && (< || =<)) || (ANY && (> || =>))
2140 for ALL condition is inverted
2141 */
2142 item= new (thd->mem_root) Item_sum_min(thd,
2143 select_lex->ref_pointer_array[0]);
2144 }
2145 if (upper_item)
2146 upper_item->set_sum_test(item);
2147 thd->change_item_tree(&select_lex->ref_pointer_array[0], item);
2148 {
2149 List_iterator<Item> it(select_lex->item_list);
2150 it++;
2151 thd->change_item_tree(it.ref(), item);
2152 }
2153
2154 DBUG_EXECUTE("where",
2155 print_where(item, "rewrite with MIN/MAX", QT_ORDINARY););
2156
2157 save_allow_sum_func= thd->lex->allow_sum_func;
2158 thd->lex->allow_sum_func.set_bit(thd->lex->current_select->nest_level);
2159 /*
2160 Item_sum_(max|min) can't substitute other item => we can use 0 as
2161 reference, also Item_sum_(max|min) can't be fixed after creation, so
2162 we do not check item->fixed
2163 */
2164 if (item->fix_fields(thd, 0))
2165 DBUG_RETURN(true);
2166 thd->lex->allow_sum_func= save_allow_sum_func;
2167 /* we added aggregate function => we have to change statistic */
2168 count_field_types(select_lex, &join->tmp_table_param, join->all_fields,
2169 0);
2170 if (join->prepare_stage2())
2171 DBUG_RETURN(true);
2172 subs= new (thd->mem_root) Item_singlerow_subselect(thd, select_lex);
2173
2174 /*
2175 Remove other strategies if any (we already changed the query and
2176 can't apply other strategy).
2177 */
2178 set_strategy(SUBS_MAXMIN_INJECTED);
2179 }
2180 else
2181 {
2182 Item_maxmin_subselect *item;
2183 subs= item= new (thd->mem_root) Item_maxmin_subselect(thd, this, select_lex, func->l_op());
2184 if (upper_item)
2185 upper_item->set_sub_test(item);
2186 /*
2187 Remove other strategies if any (we already changed the query and
2188 can't apply other strategy).
2189 */
2190 set_strategy(SUBS_MAXMIN_ENGINE);
2191 }
2192 /*
2193 The swap is needed for expressions of type 'f1 < ALL ( SELECT ....)'
2194 where we want to evaluate the sub query even if f1 would be null.
2195 */
2196 subs= func->create_swap(thd, expr, subs);
2197 thd->change_item_tree(place, subs);
2198 if (subs->fix_fields(thd, &subs))
2199 DBUG_RETURN(true);
2200 DBUG_ASSERT(subs == (*place)); // There was no substitutions
2201
2202 select_lex->master_unit()->uncacheable&= ~UNCACHEABLE_DEPENDENT_INJECTED;
2203 select_lex->uncacheable&= ~UNCACHEABLE_DEPENDENT_INJECTED;
2204
2205 DBUG_RETURN(false);
2206 }
2207
2208
fix_having(Item * having,SELECT_LEX * select_lex)2209 bool Item_in_subselect::fix_having(Item *having, SELECT_LEX *select_lex)
2210 {
2211 bool fix_res= 0;
2212 DBUG_ASSERT(thd);
2213 if (!having->is_fixed())
2214 {
2215 select_lex->having_fix_field= 1;
2216 fix_res= having->fix_fields(thd, 0);
2217 select_lex->having_fix_field= 0;
2218 }
2219 return fix_res;
2220 }
2221
is_maxmin_applicable(JOIN * join)2222 bool Item_allany_subselect::is_maxmin_applicable(JOIN *join)
2223 {
2224 /*
2225 Check if max/min optimization applicable: It is top item of
2226 WHERE condition.
2227 */
2228 return (abort_on_null || (upper_item && upper_item->is_top_level_item())) &&
2229 !(join->select_lex->master_unit()->uncacheable & ~UNCACHEABLE_EXPLAIN) && !func->eqne_op();
2230 }
2231
2232
2233 /**
2234 Create the predicates needed to transform a single-column IN/ALL/ANY
2235 subselect into a correlated EXISTS via predicate injection.
2236
2237 @param join[in] Join object of the subquery (i.e. 'child' join).
2238 @param where_item[out] the in-to-exists addition to the where clause
2239 @param having_item[out] the in-to-exists addition to the having clause
2240
2241 @details
2242 The correlated predicates are created as follows:
2243
2244 - If the subquery has aggregates, GROUP BY, or HAVING, convert to
2245
2246 SELECT ie FROM ... HAVING subq_having AND
2247 trigcond(oe $cmp$ ref_or_null_helper<ie>)
2248
2249 the addition is wrapped into trigger only when we want to distinguish
2250 between NULL and FALSE results.
2251
2252 - Otherwise (no aggregates/GROUP BY/HAVING) convert it to one of the
2253 following:
2254
2255 = If we don't need to distinguish between NULL and FALSE subquery:
2256
2257 SELECT ie FROM ... WHERE subq_where AND (oe $cmp$ ie)
2258
2259 = If we need to distinguish between those:
2260
2261 SELECT ie FROM ...
2262 WHERE subq_where AND trigcond((oe $cmp$ ie) OR (ie IS NULL))
2263 HAVING trigcond(<is_not_null_test>(ie))
2264
2265 @retval false If the new conditions were created successfully
2266 @retval true Error
2267 */
2268
2269 bool
create_single_in_to_exists_cond(JOIN * join,Item ** where_item,Item ** having_item)2270 Item_in_subselect::create_single_in_to_exists_cond(JOIN *join,
2271 Item **where_item,
2272 Item **having_item)
2273 {
2274 SELECT_LEX *select_lex= join->select_lex;
2275 DBUG_ASSERT(thd == join->thd);
2276 /*
2277 The non-transformed HAVING clause of 'join' may be stored in two ways
2278 during JOIN::optimize: this->tmp_having= this->having; this->having= 0;
2279 */
2280 Item* join_having= join->having ? join->having : join->tmp_having;
2281 DBUG_ENTER("Item_in_subselect::create_single_in_to_exists_cond");
2282
2283 *where_item= NULL;
2284 *having_item= NULL;
2285
2286 if (join_having || select_lex->with_sum_func ||
2287 select_lex->group_list.elements)
2288 {
2289 const char *tmp= this->full_name();
2290 LEX_CSTRING field_name= {tmp, safe_strlen(tmp)};
2291 Item *item= func->create(thd, expr,
2292 new (thd->mem_root) Item_ref_null_helper(
2293 thd,
2294 &select_lex->context,
2295 this,
2296 &select_lex->
2297 ref_pointer_array[0],
2298 {STRING_WITH_LEN("<ref>")},
2299 field_name));
2300 if (!abort_on_null && left_expr->maybe_null)
2301 {
2302 /*
2303 We can encounter "NULL IN (SELECT ...)". Wrap the added condition
2304 within a trig_cond.
2305 */
2306 disable_cond_guard_for_const_null_left_expr(0);
2307 item= new (thd->mem_root) Item_func_trig_cond(thd, item, get_cond_guard(0));
2308 }
2309
2310 if (!join_having)
2311 item->name= in_having_cond;
2312 if (fix_having(item, select_lex))
2313 DBUG_RETURN(true);
2314 *having_item= item;
2315 }
2316 else
2317 {
2318 /*
2319 No need to use real_item for the item, as the ref items that are possible
2320 in the subquery either belong to views or to the parent select.
2321 For such case we need to refer to the reference and not to the original
2322 item.
2323 */
2324 Item *item= (Item*) select_lex->item_list.head();
2325
2326 if (select_lex->table_list.elements ||
2327 !(select_lex->master_unit()->is_unit_op()))
2328 {
2329 Item *having= item;
2330 Item *orig_item= item;
2331
2332 item= func->create(thd, expr, item);
2333 if (!abort_on_null && orig_item->maybe_null)
2334 {
2335 having= new (thd->mem_root) Item_is_not_null_test(thd, this, having);
2336 if (left_expr->maybe_null)
2337 {
2338 disable_cond_guard_for_const_null_left_expr(0);
2339 if (!(having= new (thd->mem_root) Item_func_trig_cond(thd, having,
2340 get_cond_guard(0))))
2341 DBUG_RETURN(true);
2342 }
2343 having->name= in_having_cond;
2344 if (fix_having(having, select_lex))
2345 DBUG_RETURN(true);
2346 *having_item= having;
2347
2348 item= new (thd->mem_root) Item_cond_or(thd, item,
2349 new (thd->mem_root) Item_func_isnull(thd, orig_item));
2350 }
2351 /*
2352 If we may encounter NULL IN (SELECT ...) and care whether subquery
2353 result is NULL or FALSE, wrap condition in a trig_cond.
2354 */
2355 if (!abort_on_null && left_expr->maybe_null)
2356 {
2357 disable_cond_guard_for_const_null_left_expr(0);
2358 if (!(item= new (thd->mem_root) Item_func_trig_cond(thd, item,
2359 get_cond_guard(0))))
2360 DBUG_RETURN(true);
2361 }
2362
2363 /*
2364 TODO: figure out why the following is done here in
2365 single_value_transformer but there is no corresponding action in
2366 row_value_transformer?
2367 */
2368 item->name= in_additional_cond;
2369 if (item->fix_fields_if_needed(thd, 0))
2370 DBUG_RETURN(true);
2371 *where_item= item;
2372 }
2373 else
2374 {
2375 DBUG_ASSERT(select_lex->master_unit()->is_unit_op());
2376 LEX_CSTRING field_name= {STRING_WITH_LEN("<result>") };
2377 Item *new_having=
2378 func->create(thd, expr,
2379 new (thd->mem_root) Item_ref_null_helper(thd,
2380 &select_lex->context,
2381 this,
2382 &select_lex->ref_pointer_array[0],
2383 no_matter_name,
2384 field_name));
2385 if (!abort_on_null && left_expr->maybe_null)
2386 {
2387 disable_cond_guard_for_const_null_left_expr(0);
2388 if (!(new_having= new (thd->mem_root)
2389 Item_func_trig_cond(thd, new_having, get_cond_guard(0))))
2390 DBUG_RETURN(true);
2391 }
2392
2393 new_having->name= in_having_cond;
2394 if (fix_having(new_having, select_lex))
2395 DBUG_RETURN(true);
2396 *having_item= new_having;
2397 }
2398 }
2399
2400 DBUG_RETURN(false);
2401 }
2402
2403
2404 /**
2405 Wrap a multi-column IN/ALL/ANY subselect into an Item_in_optimizer.
2406
2407 @param join Join object of the subquery (i.e. 'child' join).
2408
2409 @details
2410 The subquery predicate is wrapped into an Item_in_optimizer. Later the query
2411 optimization phase chooses whether the subquery under the Item_in_optimizer
2412 will be further transformed into an equivalent correlated EXISTS by injecting
2413 additional predicates, or will be executed via subquery materialization in its
2414 unmodified form.
2415
2416 @retval false The subquery was transformed
2417 @retval true Error
2418 */
2419
2420 bool
row_value_transformer(JOIN * join)2421 Item_in_subselect::row_value_transformer(JOIN *join)
2422 {
2423 SELECT_LEX *select_lex= join->select_lex;
2424 uint cols_num= left_expr->cols();
2425
2426 DBUG_ENTER("Item_in_subselect::row_value_transformer");
2427 DBUG_ASSERT(thd == join->thd);
2428
2429 // psergey: duplicated_subselect_card_check
2430 if (select_lex->item_list.elements != cols_num)
2431 {
2432 my_error(ER_OPERAND_COLUMNS, MYF(0), cols_num);
2433 DBUG_RETURN(true);
2434 }
2435
2436 /*
2437 Wrap the current IN predicate in an Item_in_optimizer. The actual
2438 substitution in the Item tree takes place in Item_subselect::fix_fields.
2439 */
2440 if (!substitution)
2441 {
2442 //first call for this unit
2443 SELECT_LEX_UNIT *master_unit= select_lex->master_unit();
2444 substitution= optimizer;
2445
2446 SELECT_LEX *current= thd->lex->current_select;
2447 thd->lex->current_select= current->return_after_parsing();
2448 if (!optimizer || optimizer->fix_left(thd))
2449 {
2450 thd->lex->current_select= current;
2451 DBUG_RETURN(true);
2452 }
2453
2454 // we will refer to upper level cache array => we have to save it in PS
2455 optimizer->keep_top_level_cache();
2456
2457 thd->lex->current_select= current;
2458 /*
2459 The uncacheable property controls a number of actions, e.g. whether to
2460 save/restore (via init_save_join_tab/restore_tmp) the original JOIN for
2461 plans with a temp table where the original JOIN was overridden by
2462 make_simple_join. The UNCACHEABLE_EXPLAIN is ignored by EXPLAIN, thus
2463 non-correlated subqueries will not appear as such to EXPLAIN.
2464 */
2465 master_unit->uncacheable|= UNCACHEABLE_EXPLAIN;
2466 select_lex->uncacheable|= UNCACHEABLE_EXPLAIN;
2467 }
2468
2469 DBUG_RETURN(false);
2470 }
2471
2472
2473 /**
2474 Create the predicates needed to transform a multi-column IN/ALL/ANY
2475 subselect into a correlated EXISTS via predicate injection.
2476
2477 @details
2478 The correlated predicates are created as follows:
2479
2480 - If the subquery has aggregates, GROUP BY, or HAVING, convert to
2481
2482 (l1, l2, l3) IN (SELECT v1, v2, v3 ... HAVING having)
2483 =>
2484 EXISTS (SELECT ... HAVING having and
2485 (l1 = v1 or is null v1) and
2486 (l2 = v2 or is null v2) and
2487 (l3 = v3 or is null v3) and
2488 is_not_null_test(v1) and
2489 is_not_null_test(v2) and
2490 is_not_null_test(v3))
2491
2492 where is_not_null_test used to register nulls in case if we have
2493 not found matching to return correct NULL value.
2494
2495 - Otherwise (no aggregates/GROUP BY/HAVING) convert the subquery as follows:
2496
2497 (l1, l2, l3) IN (SELECT v1, v2, v3 ... WHERE where)
2498 =>
2499 EXISTS (SELECT ... WHERE where and
2500 (l1 = v1 or is null v1) and
2501 (l2 = v2 or is null v2) and
2502 (l3 = v3 or is null v3)
2503 HAVING is_not_null_test(v1) and
2504 is_not_null_test(v2) and
2505 is_not_null_test(v3))
2506 where is_not_null_test registers NULLs values but reject rows.
2507
2508 in case when we do not need correct NULL, we have simpler construction:
2509 EXISTS (SELECT ... WHERE where and
2510 (l1 = v1) and
2511 (l2 = v2) and
2512 (l3 = v3)
2513
2514 @param join[in] Join object of the subquery (i.e. 'child' join).
2515 @param where_item[out] the in-to-exists addition to the where clause
2516 @param having_item[out] the in-to-exists addition to the having clause
2517
2518 @retval false If the new conditions were created successfully
2519 @retval true Error
2520 */
2521
2522 bool
create_row_in_to_exists_cond(JOIN * join,Item ** where_item,Item ** having_item)2523 Item_in_subselect::create_row_in_to_exists_cond(JOIN * join,
2524 Item **where_item,
2525 Item **having_item)
2526 {
2527 SELECT_LEX *select_lex= join->select_lex;
2528 uint cols_num= left_expr->cols();
2529 /*
2530 The non-transformed HAVING clause of 'join' may be stored in two ways
2531 during JOIN::optimize: this->tmp_having= this->having; this->having= 0;
2532 */
2533 Item* join_having= join->having ? join->having : join->tmp_having;
2534 bool is_having_used= (join_having || select_lex->with_sum_func ||
2535 select_lex->group_list.first ||
2536 !select_lex->table_list.elements);
2537 LEX_CSTRING list_ref= { STRING_WITH_LEN("<list ref>")};
2538 DBUG_ENTER("Item_in_subselect::create_row_in_to_exists_cond");
2539 DBUG_ASSERT(thd == join->thd);
2540
2541 *where_item= NULL;
2542 *having_item= NULL;
2543
2544 if (is_having_used)
2545 {
2546 /* TODO: say here explicitly if the order of AND parts matters or not. */
2547 Item *item_having_part2= 0;
2548 for (uint i= 0; i < cols_num; i++)
2549 {
2550 DBUG_ASSERT((left_expr->is_fixed() &&
2551
2552 select_lex->ref_pointer_array[i]->is_fixed()) ||
2553 (select_lex->ref_pointer_array[i]->type() == REF_ITEM &&
2554 ((Item_ref*)(select_lex->ref_pointer_array[i]))->ref_type() ==
2555 Item_ref::OUTER_REF));
2556 if (select_lex->ref_pointer_array[i]->
2557 check_cols(left_expr->element_index(i)->cols()))
2558 DBUG_RETURN(true);
2559
2560 Item *item_eq=
2561 new (thd->mem_root)
2562 Item_func_eq(thd, new (thd->mem_root)
2563 Item_direct_ref(thd, &select_lex->context,
2564 (*optimizer->get_cache())->
2565 addr(i),
2566 no_matter_name,
2567 in_left_expr_name),
2568 new (thd->mem_root)
2569 Item_ref(thd, &select_lex->context,
2570 &select_lex->ref_pointer_array[i],
2571 no_matter_name,
2572 list_ref));
2573 Item *item_isnull=
2574 new (thd->mem_root)
2575 Item_func_isnull(thd,
2576 new (thd->mem_root)
2577 Item_ref(thd, &select_lex->context,
2578 &select_lex->ref_pointer_array[i],
2579 no_matter_name,
2580 list_ref));
2581 Item *col_item= new (thd->mem_root)
2582 Item_cond_or(thd, item_eq, item_isnull);
2583 if (!abort_on_null && left_expr->element_index(i)->maybe_null &&
2584 get_cond_guard(i))
2585 {
2586 disable_cond_guard_for_const_null_left_expr(i);
2587 if (!(col_item= new (thd->mem_root)
2588 Item_func_trig_cond(thd, col_item, get_cond_guard(i))))
2589 DBUG_RETURN(true);
2590 }
2591 *having_item= and_items(thd, *having_item, col_item);
2592
2593 Item *item_nnull_test=
2594 new (thd->mem_root)
2595 Item_is_not_null_test(thd, this,
2596 new (thd->mem_root)
2597 Item_ref(thd, &select_lex->context,
2598 &select_lex->
2599 ref_pointer_array[i],
2600 no_matter_name,
2601 list_ref));
2602 if (!abort_on_null && left_expr->element_index(i)->maybe_null &&
2603 get_cond_guard(i) )
2604 {
2605 disable_cond_guard_for_const_null_left_expr(i);
2606 if (!(item_nnull_test=
2607 new (thd->mem_root)
2608 Item_func_trig_cond(thd, item_nnull_test, get_cond_guard(i))))
2609 DBUG_RETURN(true);
2610 }
2611 item_having_part2= and_items(thd, item_having_part2, item_nnull_test);
2612 item_having_part2->top_level_item();
2613 }
2614 *having_item= and_items(thd, *having_item, item_having_part2);
2615 }
2616 else
2617 {
2618 for (uint i= 0; i < cols_num; i++)
2619 {
2620 Item *item, *item_isnull;
2621 DBUG_ASSERT((left_expr->is_fixed() &&
2622 select_lex->ref_pointer_array[i]->is_fixed()) ||
2623 (select_lex->ref_pointer_array[i]->type() == REF_ITEM &&
2624 ((Item_ref*)(select_lex->ref_pointer_array[i]))->ref_type() ==
2625 Item_ref::OUTER_REF));
2626 if (select_lex->ref_pointer_array[i]->
2627 check_cols(left_expr->element_index(i)->cols()))
2628 DBUG_RETURN(true);
2629 item= new (thd->mem_root)
2630 Item_func_eq(thd,
2631 new (thd->mem_root)
2632 Item_direct_ref(thd, &select_lex->context,
2633 (*optimizer->get_cache())->
2634 addr(i),
2635 no_matter_name,
2636 in_left_expr_name),
2637 new (thd->mem_root)
2638 Item_direct_ref(thd, &select_lex->context,
2639 &select_lex->
2640 ref_pointer_array[i],
2641 no_matter_name,
2642 list_ref));
2643 if (!abort_on_null && select_lex->ref_pointer_array[i]->maybe_null)
2644 {
2645 Item *having_col_item=
2646 new (thd->mem_root)
2647 Item_is_not_null_test(thd, this,
2648 new (thd->mem_root)
2649 Item_ref(thd, &select_lex->context,
2650 &select_lex->ref_pointer_array[i],
2651 no_matter_name,
2652 list_ref));
2653
2654 item_isnull= new (thd->mem_root)
2655 Item_func_isnull(thd,
2656 new (thd->mem_root)
2657 Item_direct_ref(thd, &select_lex->context,
2658 &select_lex->
2659 ref_pointer_array[i],
2660 no_matter_name,
2661 list_ref));
2662 item= new (thd->mem_root) Item_cond_or(thd, item, item_isnull);
2663 if (left_expr->element_index(i)->maybe_null && get_cond_guard(i))
2664 {
2665 disable_cond_guard_for_const_null_left_expr(i);
2666 if (!(item= new (thd->mem_root)
2667 Item_func_trig_cond(thd, item, get_cond_guard(i))))
2668 DBUG_RETURN(true);
2669 if (!(having_col_item= new (thd->mem_root)
2670 Item_func_trig_cond(thd, having_col_item, get_cond_guard(i))))
2671 DBUG_RETURN(true);
2672 }
2673 *having_item= and_items(thd, *having_item, having_col_item);
2674 }
2675 if (!abort_on_null && left_expr->element_index(i)->maybe_null &&
2676 get_cond_guard(i))
2677 {
2678 if (!(item= new (thd->mem_root)
2679 Item_func_trig_cond(thd, item, get_cond_guard(i))))
2680 DBUG_RETURN(true);
2681 }
2682 *where_item= and_items(thd, *where_item, item);
2683 }
2684 }
2685
2686 if (*where_item)
2687 {
2688 if ((*where_item)->fix_fields_if_needed(thd, 0))
2689 DBUG_RETURN(true);
2690 (*where_item)->top_level_item();
2691 }
2692
2693 if (*having_item)
2694 {
2695 if (!join_having)
2696 (*having_item)->name= in_having_cond;
2697 if (fix_having(*having_item, select_lex))
2698 DBUG_RETURN(true);
2699 (*having_item)->top_level_item();
2700 }
2701
2702 DBUG_RETURN(false);
2703 }
2704
2705
2706 bool
select_transformer(JOIN * join)2707 Item_in_subselect::select_transformer(JOIN *join)
2708 {
2709 return select_in_like_transformer(join);
2710 }
2711
2712 bool
select_transformer(JOIN * join)2713 Item_exists_subselect::select_transformer(JOIN *join)
2714 {
2715 return select_prepare_to_be_in();
2716 }
2717
2718
2719 /**
2720 Create the predicates needed to transform an IN/ALL/ANY subselect into a
2721 correlated EXISTS via predicate injection.
2722
2723 @param join_arg Join object of the subquery.
2724
2725 @retval FALSE ok
2726 @retval TRUE error
2727 */
2728
create_in_to_exists_cond(JOIN * join_arg)2729 bool Item_in_subselect::create_in_to_exists_cond(JOIN *join_arg)
2730 {
2731 bool res;
2732
2733 DBUG_ASSERT(engine->engine_type() == subselect_engine::SINGLE_SELECT_ENGINE ||
2734 engine->engine_type() == subselect_engine::UNION_ENGINE);
2735 /*
2736 TODO: the call to init_cond_guards allocates and initializes an
2737 array of booleans that may not be used later because we may choose
2738 materialization.
2739 The two calls below to create_XYZ_cond depend on this boolean array.
2740 If the dependency is removed, the call can be moved to a later phase.
2741 */
2742 init_cond_guards();
2743 if (left_expr->cols() == 1)
2744 res= create_single_in_to_exists_cond(join_arg,
2745 &(join_arg->in_to_exists_where),
2746 &(join_arg->in_to_exists_having));
2747 else
2748 res= create_row_in_to_exists_cond(join_arg,
2749 &(join_arg->in_to_exists_where),
2750 &(join_arg->in_to_exists_having));
2751
2752 /*
2753 The IN=>EXISTS transformation makes non-correlated subqueries correlated.
2754 */
2755 if (!left_expr->const_item() || left_expr->is_expensive())
2756 {
2757 join_arg->select_lex->uncacheable|= UNCACHEABLE_DEPENDENT_INJECTED;
2758 join_arg->select_lex->master_unit()->uncacheable|=
2759 UNCACHEABLE_DEPENDENT_INJECTED;
2760 }
2761 /*
2762 The uncacheable property controls a number of actions, e.g. whether to
2763 save/restore (via init_save_join_tab/restore_tmp) the original JOIN for
2764 plans with a temp table where the original JOIN was overridden by
2765 make_simple_join. The UNCACHEABLE_EXPLAIN is ignored by EXPLAIN, thus
2766 non-correlated subqueries will not appear as such to EXPLAIN.
2767 */
2768 join_arg->select_lex->master_unit()->uncacheable|= UNCACHEABLE_EXPLAIN;
2769 join_arg->select_lex->uncacheable|= UNCACHEABLE_EXPLAIN;
2770 return (res);
2771 }
2772
2773
2774 /**
2775 Transform an IN/ALL/ANY subselect into a correlated EXISTS via injecting
2776 correlated in-to-exists predicates.
2777
2778 @param join_arg Join object of the subquery.
2779
2780 @retval FALSE ok
2781 @retval TRUE error
2782 */
2783
inject_in_to_exists_cond(JOIN * join_arg)2784 bool Item_in_subselect::inject_in_to_exists_cond(JOIN *join_arg)
2785 {
2786 SELECT_LEX *select_lex= join_arg->select_lex;
2787 Item *where_item= join_arg->in_to_exists_where;
2788 Item *having_item= join_arg->in_to_exists_having;
2789
2790 DBUG_ENTER("Item_in_subselect::inject_in_to_exists_cond");
2791 DBUG_ASSERT(thd == join_arg->thd);
2792
2793 if (select_lex->min_max_opt_list.elements)
2794 {
2795 /*
2796 MIN/MAX optimizations have been applied to Item_sum objects
2797 of the subquery this subquery predicate in opt_sum_query().
2798 Injection of new condition invalidates this optimizations.
2799 Thus those optimizations must be rolled back.
2800 */
2801 List_iterator_fast<Item_sum> it(select_lex->min_max_opt_list);
2802 Item_sum *item;
2803 while ((item= it++))
2804 {
2805 item->clear();
2806 item->reset_forced_const();
2807 }
2808 if (where_item)
2809 where_item->update_used_tables();
2810 if (having_item)
2811 having_item->update_used_tables();
2812 }
2813
2814 if (where_item)
2815 {
2816 List<Item> *and_args= NULL;
2817 /*
2818 If the top-level Item of the WHERE clause is an AND, detach the multiple
2819 equality list that was attached to the end of the AND argument list by
2820 build_equal_items_for_cond(). The multiple equalities must be detached
2821 because fix_fields merges lower level AND arguments into the upper AND.
2822 As a result, the arguments from lower-level ANDs are concatenated after
2823 the multiple equalities. When the multiple equality list is treated as
2824 such, it turns out that it contains non-Item_equal object which is wrong.
2825 */
2826 if (join_arg->conds && join_arg->conds->type() == Item::COND_ITEM &&
2827 ((Item_cond*) join_arg->conds)->functype() == Item_func::COND_AND_FUNC)
2828 {
2829 and_args= ((Item_cond*) join_arg->conds)->argument_list();
2830 if (join_arg->cond_equal)
2831 and_args->disjoin((List<Item> *) &join_arg->cond_equal->current_level);
2832 }
2833
2834 where_item= and_items(thd, join_arg->conds, where_item);
2835 if (where_item->fix_fields_if_needed(thd, 0))
2836 DBUG_RETURN(true);
2837 // TIMOUR TODO: call optimize_cond() for the new where clause
2838 thd->change_item_tree(&select_lex->where, where_item);
2839 select_lex->where->top_level_item();
2840 join_arg->conds= select_lex->where;
2841
2842 /* Attach back the list of multiple equalities to the new top-level AND. */
2843 if (and_args && join_arg->cond_equal)
2844 {
2845 /* The argument list of the top-level AND may change after fix fields. */
2846 and_args= ((Item_cond*) join_arg->conds)->argument_list();
2847 List_iterator<Item_equal> li(join_arg->cond_equal->current_level);
2848 Item_equal *elem;
2849 while ((elem= li++))
2850 {
2851 and_args->push_back(elem, thd->mem_root);
2852 }
2853 }
2854 }
2855
2856 if (having_item)
2857 {
2858 Item* join_having= join_arg->having ? join_arg->having:join_arg->tmp_having;
2859 having_item= and_items(thd, join_having, having_item);
2860 if (fix_having(having_item, select_lex))
2861 DBUG_RETURN(true);
2862 // TIMOUR TODO: call optimize_cond() for the new having clause
2863 thd->change_item_tree(&select_lex->having, having_item);
2864 select_lex->having->top_level_item();
2865 join_arg->having= select_lex->having;
2866 }
2867 join_arg->thd->change_item_tree(&unit->global_parameters()->select_limit,
2868 new (thd->mem_root)
2869 Item_int(thd, (int32) 1));
2870 unit->lim.set_single_row();
2871
2872 DBUG_RETURN(false);
2873 }
2874
2875
2876 /*
2877 If this select can potentially be converted by EXISTS->IN conversion, wrap it
2878 in an Item_in_optimizer object. Final decision whether to do the conversion
2879 is done at a later phase.
2880 */
2881
select_prepare_to_be_in()2882 bool Item_exists_subselect::select_prepare_to_be_in()
2883 {
2884 bool trans_res= FALSE;
2885 DBUG_ENTER("Item_exists_subselect::select_prepare_to_be_in");
2886 if (!optimizer &&
2887 thd->lex->sql_command == SQLCOM_SELECT &&
2888 !unit->first_select()->is_part_of_union() &&
2889 optimizer_flag(thd, OPTIMIZER_SWITCH_EXISTS_TO_IN) &&
2890 (is_top_level_item() ||
2891 (upper_not && upper_not->is_top_level_item())))
2892 {
2893 Query_arena *arena, backup;
2894 bool result;
2895 arena= thd->activate_stmt_arena_if_needed(&backup);
2896 result= (!(optimizer= new (thd->mem_root) Item_in_optimizer(thd, new (thd->mem_root) Item_int(thd, 1), this)));
2897 if (arena)
2898 thd->restore_active_arena(arena, &backup);
2899 if (result)
2900 trans_res= TRUE;
2901 else
2902 substitution= optimizer;
2903 }
2904 DBUG_RETURN(trans_res);
2905 }
2906
2907 /**
2908 Check if 'func' is an equality in form "inner_table.column = outer_expr"
2909
2910 @param func Expression to check
2911 @param allow_subselect If true, the outer_expr part can have a subquery
2912 If false, it cannot.
2913 @param local_field OUT Return "inner_table.column" here
2914 @param outer_expr OUT Return outer_expr here
2915
2916 @return true - 'func' is an Equality.
2917 */
2918
check_equality_for_exist2in(Item_func * func,bool allow_subselect,Item_ident ** local_field,Item ** outer_exp)2919 static bool check_equality_for_exist2in(Item_func *func,
2920 bool allow_subselect,
2921 Item_ident **local_field,
2922 Item **outer_exp)
2923 {
2924 Item **args;
2925 if (func->functype() != Item_func::EQ_FUNC)
2926 return FALSE;
2927 DBUG_ASSERT(func->argument_count() == 2);
2928 args= func->arguments();
2929 if (args[0]->real_type() == Item::FIELD_ITEM &&
2930 args[0]->all_used_tables() != OUTER_REF_TABLE_BIT &&
2931 args[1]->all_used_tables() == OUTER_REF_TABLE_BIT &&
2932 (allow_subselect || !args[1]->with_subquery()))
2933 {
2934 /* It is Item_field or Item_direct_view_ref) */
2935 DBUG_ASSERT(args[0]->type() == Item::FIELD_ITEM ||
2936 args[0]->type() == Item::REF_ITEM);
2937 *local_field= (Item_ident *)args[0];
2938 *outer_exp= args[1];
2939 return TRUE;
2940 }
2941 else if (args[1]->real_type() == Item::FIELD_ITEM &&
2942 args[1]->all_used_tables() != OUTER_REF_TABLE_BIT &&
2943 args[0]->all_used_tables() == OUTER_REF_TABLE_BIT &&
2944 (allow_subselect || !args[0]->with_subquery()))
2945 {
2946 /* It is Item_field or Item_direct_view_ref) */
2947 DBUG_ASSERT(args[1]->type() == Item::FIELD_ITEM ||
2948 args[1]->type() == Item::REF_ITEM);
2949 *local_field= (Item_ident *)args[1];
2950 *outer_exp= args[0];
2951 return TRUE;
2952 }
2953
2954 return FALSE;
2955 }
2956
2957 typedef struct st_eq_field_outer
2958 {
2959 Item **eq_ref;
2960 Item_ident *local_field;
2961 Item *outer_exp;
2962 } EQ_FIELD_OUTER;
2963
2964
2965 /**
2966 Check if 'conds' is a set of AND-ed outer_expr=inner_table.col equalities
2967
2968 @detail
2969 Check if 'conds' has form
2970
2971 outer1=inner_tbl1.col1 AND ... AND outer2=inner_tbl1.col2 AND remainder_cond
2972
2973 if there is just one outer_expr=inner_expr pair, then outer_expr can have a
2974 subselect in it. If there are many such pairs, then none of outer_expr can
2975 have a subselect in it. If we allow this, the query will fail with an error:
2976
2977 This version of MariaDB doesn't yet support 'SUBQUERY in ROW in left
2978 expression of IN/ALL/ANY'
2979
2980 @param conds Condition to be checked
2981 @parm result Array to collect EQ_FIELD_OUTER elements describing
2982 inner-vs-outer equalities the function has found.
2983 @return
2984 false - some inner-vs-outer equalities were found
2985 true - otherwise.
2986 */
2987
find_inner_outer_equalities(Item ** conds,Dynamic_array<EQ_FIELD_OUTER> & result)2988 static bool find_inner_outer_equalities(Item **conds,
2989 Dynamic_array<EQ_FIELD_OUTER> &result)
2990 {
2991 bool found= FALSE;
2992 EQ_FIELD_OUTER element;
2993 if (is_cond_and(*conds))
2994 {
2995 List_iterator<Item> li(*((Item_cond*)*conds)->argument_list());
2996 Item *item;
2997 bool allow_subselect= true;
2998 while ((item= li++))
2999 {
3000 if (item->type() == Item::FUNC_ITEM &&
3001 check_equality_for_exist2in((Item_func *)item,
3002 allow_subselect,
3003 &element.local_field,
3004 &element.outer_exp))
3005 {
3006 found= TRUE;
3007 allow_subselect= false;
3008 element.eq_ref= li.ref();
3009 if (result.append(element))
3010 goto alloc_err;
3011 }
3012 }
3013 }
3014 else if ((*conds)->type() == Item::FUNC_ITEM &&
3015 check_equality_for_exist2in((Item_func *)*conds,
3016 true,
3017 &element.local_field,
3018 &element.outer_exp))
3019 {
3020 found= TRUE;
3021 element.eq_ref= conds;
3022 if (result.append(element))
3023 goto alloc_err;
3024 }
3025
3026 return !found;
3027 alloc_err:
3028 return TRUE;
3029 }
3030
3031 /**
3032 Converts EXISTS subquery to IN subquery if it is possible and has sense
3033
3034 @param opt_arg Pointer on THD
3035
3036 @return TRUE in case of error and FALSE otherwise.
3037 */
3038
exists2in_processor(void * opt_arg)3039 bool Item_exists_subselect::exists2in_processor(void *opt_arg)
3040 {
3041 THD *thd= (THD *)opt_arg;
3042 SELECT_LEX *first_select=unit->first_select(), *save_select;
3043 JOIN *join= first_select->join;
3044 Item **eq_ref= NULL;
3045 Item_ident *local_field= NULL;
3046 Item *outer_exp= NULL;
3047 Item *left_exp= NULL; Item_in_subselect *in_subs;
3048 Query_arena *arena= NULL, backup;
3049 int res= FALSE;
3050 List<Item> outer;
3051 Dynamic_array<EQ_FIELD_OUTER> eqs(5, 5);
3052 bool will_be_correlated;
3053 DBUG_ENTER("Item_exists_subselect::exists2in_processor");
3054
3055 if (!optimizer ||
3056 !optimizer_flag(thd, OPTIMIZER_SWITCH_EXISTS_TO_IN) ||
3057 (!is_top_level_item() && (!upper_not ||
3058 !upper_not->is_top_level_item())) ||
3059 first_select->is_part_of_union() ||
3060 first_select->group_list.elements ||
3061 join->having ||
3062 first_select->with_sum_func ||
3063 !first_select->leaf_tables.elements||
3064 !join->conds ||
3065 with_recursive_reference)
3066 DBUG_RETURN(FALSE);
3067
3068 /*
3069 EXISTS-to-IN coversion and ORDER BY ... LIMIT clause:
3070
3071 - "[ORDER BY ...] LIMIT n" clause with a non-zero n does not affect
3072 the result of the EXISTS(...) predicate, and so we can discard
3073 it during the conversion.
3074 - "[ORDER BY ...] LIMIT m, n" can turn a non-empty resultset into empty
3075 one, so it affects tthe EXISTS(...) result and cannot be discarded.
3076
3077 Disallow exists-to-in conversion if
3078 (1). three is a LIMIT which is not a basic constant
3079 (1a) or is a "LIMIT 0" (see MDEV-19429)
3080 (2). there is an OFFSET clause
3081 */
3082 if ((first_select->select_limit && // (1)
3083 (!first_select->select_limit->basic_const_item() || // (1)
3084 first_select->select_limit->val_uint() == 0)) || // (1a)
3085 first_select->offset_limit) // (2)
3086 {
3087 DBUG_RETURN(FALSE);
3088 }
3089
3090 /* Disallow the conversion if offset + limit exists */
3091
3092 DBUG_ASSERT(first_select->group_list.elements == 0 &&
3093 first_select->having == NULL);
3094
3095 if (find_inner_outer_equalities(&join->conds, eqs))
3096 DBUG_RETURN(FALSE);
3097
3098 DBUG_ASSERT(eqs.elements() != 0);
3099
3100 save_select= thd->lex->current_select;
3101 thd->lex->current_select= first_select;
3102
3103 /* check that the subquery has only dependencies we are going pull out */
3104 {
3105 List<Item> unused;
3106 Collect_deps_prm prm= {&unused, // parameters
3107 unit->first_select()->nest_level_base, // nest_level_base
3108 0, // count
3109 unit->first_select()->nest_level, // nest_level
3110 FALSE // collect
3111 };
3112 walk(&Item::collect_outer_ref_processor, TRUE, &prm);
3113 DBUG_ASSERT(prm.count > 0);
3114 DBUG_ASSERT(prm.count >= (uint)eqs.elements());
3115 will_be_correlated= prm.count > (uint)eqs.elements();
3116 if (upper_not && will_be_correlated)
3117 goto out;
3118 }
3119
3120 if ((uint)eqs.elements() > (first_select->item_list.elements +
3121 first_select->select_n_reserved))
3122 goto out;
3123
3124 arena= thd->activate_stmt_arena_if_needed(&backup);
3125
3126 while (first_select->item_list.elements > (uint)eqs.elements())
3127 {
3128 first_select->item_list.pop();
3129 first_select->join->all_fields.elements--;
3130 }
3131 {
3132 List_iterator<Item> it(first_select->item_list);
3133
3134 for (uint i= 0; i < (uint)eqs.elements(); i++)
3135 {
3136 Item *item= it++;
3137 eq_ref= eqs.at(i).eq_ref;
3138 local_field= eqs.at(i).local_field;
3139 outer_exp= eqs.at(i).outer_exp;
3140 /* Add the field to the SELECT_LIST */
3141 if (item)
3142 it.replace(local_field);
3143 else
3144 {
3145 first_select->item_list.push_back(local_field, thd->mem_root);
3146 first_select->join->all_fields.elements++;
3147 }
3148 first_select->ref_pointer_array[i]= (Item *)local_field;
3149
3150 /* remove the parts from condition */
3151 if (!upper_not || !local_field->maybe_null)
3152 *eq_ref= new (thd->mem_root) Item_int(thd, 1);
3153 else
3154 {
3155 *eq_ref= new (thd->mem_root)
3156 Item_func_isnotnull(thd,
3157 new (thd->mem_root)
3158 Item_field(thd,
3159 ((Item_field*)(local_field->
3160 real_item()))->context,
3161 ((Item_field*)(local_field->
3162 real_item()))->field));
3163 if((*eq_ref)->fix_fields(thd, (Item **)eq_ref))
3164 {
3165 res= TRUE;
3166 goto out;
3167 }
3168 }
3169 outer_exp->fix_after_pullout(unit->outer_select(), &outer_exp, FALSE);
3170 outer_exp->update_used_tables();
3171 outer.push_back(outer_exp, thd->mem_root);
3172 }
3173 }
3174
3175 join->conds->update_used_tables();
3176
3177 /* make IN SUBQUERY and put outer_exp as left part */
3178 if (eqs.elements() == 1)
3179 left_exp= outer_exp;
3180 else
3181 {
3182 if (!(left_exp= new (thd->mem_root) Item_row(thd, outer)))
3183 {
3184 res= TRUE;
3185 goto out;
3186 }
3187 }
3188
3189 /* make EXISTS->IN permanet (see Item_subselect::init()) */
3190 set_exists_transformed();
3191
3192 first_select->select_limit= NULL;
3193 if (!(in_subs= new (thd->mem_root) Item_in_subselect(thd, left_exp,
3194 first_select)))
3195 {
3196 res= TRUE;
3197 goto out;
3198 }
3199 in_subs->set_exists_transformed();
3200 optimizer->arguments()[0]= left_exp;
3201 optimizer->arguments()[1]= in_subs;
3202 in_subs->optimizer= optimizer;
3203 DBUG_ASSERT(is_top_level_item() ||
3204 (upper_not && upper_not->is_top_level_item()));
3205 in_subs->top_level_item();
3206 {
3207 SELECT_LEX *current= thd->lex->current_select;
3208 optimizer->reset_cache(); // renew cache, and we will not keep it
3209 thd->lex->current_select= unit->outer_select();
3210 DBUG_ASSERT(optimizer);
3211 if (optimizer->fix_left(thd))
3212 {
3213 res= TRUE;
3214 /*
3215 We should not restore thd->lex->current_select because it will be
3216 reset on exit from this procedure
3217 */
3218 goto out;
3219 }
3220 /*
3221 As far as Item_ref_in_optimizer do not substitute itself on fix_fields
3222 we can use same item for all selects.
3223 */
3224 in_subs->expr= new (thd->mem_root)
3225 Item_direct_ref(thd, &first_select->context,
3226 (Item**)optimizer->get_cache(),
3227 no_matter_name,
3228 in_left_expr_name);
3229 if (in_subs->fix_fields(thd, optimizer->arguments() + 1))
3230 {
3231 res= TRUE;
3232 /*
3233 We should not restore thd->lex->current_select because it will be
3234 reset on exit from this procedure
3235 */
3236 goto out;
3237 }
3238 {
3239 /* Move dependence list */
3240 List_iterator_fast<Ref_to_outside> it(upper_refs);
3241 Ref_to_outside *upper;
3242 while ((upper= it++))
3243 {
3244 uint i;
3245 for (i= 0; i < (uint)eqs.elements(); i++)
3246 if (eqs.at(i).outer_exp->
3247 walk(&Item::find_item_processor, TRUE, upper->item))
3248 break;
3249 if (i == (uint)eqs.elements() &&
3250 (in_subs->upper_refs.push_back(upper, thd->stmt_arena->mem_root)))
3251 goto out;
3252 }
3253 }
3254 in_subs->update_used_tables();
3255 /*
3256 The engine of the subquery is fixed so above fix_fields() is not
3257 complete and should be fixed
3258 */
3259 in_subs->upper_refs= upper_refs;
3260 upper_refs.empty();
3261 thd->lex->current_select= current;
3262 }
3263
3264 DBUG_ASSERT(unit->item == in_subs);
3265 DBUG_ASSERT(join == first_select->join);
3266 /*
3267 Fix dependency info
3268 */
3269 in_subs->is_correlated= will_be_correlated;
3270 if (!will_be_correlated)
3271 {
3272 first_select->uncacheable&= ~UNCACHEABLE_DEPENDENT_GENERATED;
3273 unit->uncacheable&= ~UNCACHEABLE_DEPENDENT_GENERATED;
3274 }
3275 /*
3276 set possible optimization strategies
3277 */
3278 in_subs->emb_on_expr_nest= emb_on_expr_nest;
3279 res= check_and_do_in_subquery_rewrites(join);
3280 first_select->join->prepare_stage2();
3281
3282 first_select->fix_prepare_information(thd, &join->conds, &join->having);
3283
3284 if (upper_not)
3285 {
3286 Item *exp;
3287 if (eqs.elements() == 1)
3288 {
3289 exp= (optimizer->arguments()[0]->maybe_null ?
3290 (Item*) new (thd->mem_root)
3291 Item_cond_and(thd,
3292 new (thd->mem_root)
3293 Item_func_isnotnull(thd,
3294 new (thd->mem_root)
3295 Item_direct_ref(thd,
3296 &unit->outer_select()->context,
3297 optimizer->arguments(),
3298 no_matter_name,
3299 exists_outer_expr_name)),
3300 optimizer) :
3301 (Item *)optimizer);
3302 }
3303 else
3304 {
3305 List<Item> *and_list= new List<Item>;
3306 if (!and_list)
3307 {
3308 res= TRUE;
3309 goto out;
3310 }
3311 for (size_t i= 0; i < eqs.elements(); i++)
3312 {
3313 if (optimizer->arguments()[0]->maybe_null)
3314 {
3315 and_list->
3316 push_front(new (thd->mem_root)
3317 Item_func_isnotnull(thd,
3318 new (thd->mem_root)
3319 Item_direct_ref(thd,
3320 &unit->outer_select()->context,
3321 optimizer->arguments()[0]->addr((int)i),
3322 no_matter_name,
3323 exists_outer_expr_name)),
3324 thd->mem_root);
3325 }
3326 }
3327 if (and_list->elements > 0)
3328 {
3329 and_list->push_front(optimizer, thd->mem_root);
3330 exp= new (thd->mem_root) Item_cond_and(thd, *and_list);
3331 }
3332 else
3333 exp= optimizer;
3334 }
3335 upper_not->arguments()[0]= exp;
3336 if (exp->fix_fields_if_needed(thd, upper_not->arguments()))
3337 {
3338 res= TRUE;
3339 goto out;
3340 }
3341 }
3342
3343 out:
3344 thd->lex->current_select= save_select;
3345 if (arena)
3346 thd->restore_active_arena(arena, &backup);
3347 DBUG_RETURN(res);
3348 }
3349
3350
3351 /**
3352 Prepare IN/ALL/ANY/SOME subquery transformation and call the appropriate
3353 transformation function.
3354
3355 @param join JOIN object of transforming subquery
3356
3357 @notes
3358 To decide which transformation procedure (scalar or row) applicable here
3359 we have to call fix_fields() for the left expression to be able to call
3360 cols() method on it. Also this method makes arena management for
3361 underlying transformation methods.
3362
3363 @retval false OK
3364 @retval true Error
3365 */
3366
3367 bool
select_in_like_transformer(JOIN * join)3368 Item_in_subselect::select_in_like_transformer(JOIN *join)
3369 {
3370 Query_arena *arena= 0, backup;
3371 SELECT_LEX *current= thd->lex->current_select;
3372 const char *save_where= thd->where;
3373 bool trans_res= true;
3374 bool result;
3375
3376 DBUG_ENTER("Item_in_subselect::select_in_like_transformer");
3377 DBUG_ASSERT(thd == join->thd);
3378 thd->where= "IN/ALL/ANY subquery";
3379
3380 /*
3381 In some optimisation cases we will not need this Item_in_optimizer
3382 object, but we can't know it here, but here we need address correct
3383 reference on left expression.
3384
3385 note: we won't need Item_in_optimizer when handling degenerate cases
3386 like "... IN (SELECT 1)"
3387 */
3388 arena= thd->activate_stmt_arena_if_needed(&backup);
3389 if (!optimizer)
3390 {
3391 optimizer= new (thd->mem_root) Item_in_optimizer(thd, left_expr_orig, this);
3392 if ((result= !optimizer))
3393 goto out;
3394 }
3395
3396 thd->lex->current_select= current->return_after_parsing();
3397 result= optimizer->fix_left(thd);
3398 thd->lex->current_select= current;
3399
3400 if (changed)
3401 {
3402 trans_res= false;
3403 goto out;
3404 }
3405
3406
3407 if (result)
3408 goto out;
3409
3410 /*
3411 Both transformers call fix_fields() only for Items created inside them,
3412 and all that items do not make permanent changes in current item arena
3413 which allow to us call them with changed arena (if we do not know nature
3414 of Item, we have to call fix_fields() for it only with original arena to
3415 avoid memory leak)
3416 */
3417 if (left_expr->cols() == 1)
3418 trans_res= single_value_transformer(join);
3419 else
3420 {
3421 /* we do not support row operation for ALL/ANY/SOME */
3422 if (func != &eq_creator)
3423 {
3424 if (arena)
3425 thd->restore_active_arena(arena, &backup);
3426 my_error(ER_OPERAND_COLUMNS, MYF(0), 1);
3427 DBUG_RETURN(true);
3428 }
3429 trans_res= row_value_transformer(join);
3430 }
3431 out:
3432 if (arena)
3433 thd->restore_active_arena(arena, &backup);
3434 thd->where= save_where;
3435 DBUG_RETURN(trans_res);
3436 }
3437
3438
print(String * str,enum_query_type query_type)3439 void Item_in_subselect::print(String *str, enum_query_type query_type)
3440 {
3441 if (test_strategy(SUBS_IN_TO_EXISTS) &&
3442 !(query_type & QT_PARSABLE))
3443 str->append(STRING_WITH_LEN("<exists>"));
3444 else
3445 {
3446 left_expr->print_parenthesised(str, query_type, precedence());
3447 str->append(STRING_WITH_LEN(" in "));
3448 }
3449 Item_subselect::print(str, query_type);
3450 }
3451
fix_fields(THD * thd,Item ** ref)3452 bool Item_exists_subselect::fix_fields(THD *thd, Item **ref)
3453 {
3454 DBUG_ENTER("Item_exists_subselect::fix_fields");
3455 if (exists_transformed)
3456 DBUG_RETURN( !( (*ref)= new (thd->mem_root) Item_int(thd, 1)));
3457 DBUG_RETURN(Item_subselect::fix_fields(thd, ref));
3458 }
3459
3460
fix_fields(THD * thd_arg,Item ** ref)3461 bool Item_in_subselect::fix_fields(THD *thd_arg, Item **ref)
3462 {
3463 uint outer_cols_num;
3464 List<Item> *inner_cols;
3465 char const *save_where= thd_arg->where;
3466 DBUG_ENTER("Item_in_subselect::fix_fields");
3467
3468 thd= thd_arg;
3469 DBUG_ASSERT(unit->thd == thd);
3470
3471 if (test_strategy(SUBS_SEMI_JOIN))
3472 DBUG_RETURN( !( (*ref)= new (thd->mem_root) Item_int(thd, 1)) );
3473
3474 thd->where= "IN/ALL/ANY subquery";
3475 /*
3476 Check if the outer and inner IN operands match in those cases when we
3477 will not perform IN=>EXISTS transformation. Currently this is when we
3478 use subquery materialization.
3479
3480 The condition below is true when this method was called recursively from
3481 inside JOIN::prepare for the JOIN object created by the call chain
3482 Item_subselect::fix_fields -> subselect_single_select_engine::prepare,
3483 which creates a JOIN object for the subquery and calls JOIN::prepare for
3484 the JOIN of the subquery.
3485 Notice that in some cases, this doesn't happen, and the check_cols()
3486 test for each Item happens later in
3487 Item_in_subselect::row_value_in_to_exists_transformer.
3488 The reason for this mess is that our JOIN::prepare phase works top-down
3489 instead of bottom-up, so we first do name resoluton and semantic checks
3490 for the outer selects, then for the inner.
3491 */
3492 if (engine &&
3493 engine->engine_type() == subselect_engine::SINGLE_SELECT_ENGINE &&
3494 ((subselect_single_select_engine*)engine)->join)
3495 {
3496 outer_cols_num= left_expr->cols();
3497
3498 if (unit->is_unit_op())
3499 inner_cols= &(unit->types);
3500 else
3501 inner_cols= &(unit->first_select()->item_list);
3502 if (outer_cols_num != inner_cols->elements)
3503 {
3504 my_error(ER_OPERAND_COLUMNS, MYF(0), outer_cols_num);
3505 goto err;
3506 }
3507 if (outer_cols_num > 1)
3508 {
3509 List_iterator<Item> inner_col_it(*inner_cols);
3510 Item *inner_col;
3511 for (uint i= 0; i < outer_cols_num; i++)
3512 {
3513 inner_col= inner_col_it++;
3514 if (inner_col->check_cols(left_expr->element_index(i)->cols()))
3515 goto err;
3516 }
3517 }
3518 }
3519
3520 if (left_expr && left_expr->fix_fields_if_needed(thd_arg, &left_expr))
3521 goto err;
3522 else
3523 if (Item_subselect::fix_fields(thd_arg, ref))
3524 goto err;
3525 fixed= TRUE;
3526 thd->where= save_where;
3527 DBUG_RETURN(FALSE);
3528
3529 err:
3530 thd->where= save_where;
3531 DBUG_RETURN(TRUE);
3532 }
3533
3534
fix_after_pullout(st_select_lex * new_parent,Item ** ref,bool merge)3535 void Item_in_subselect::fix_after_pullout(st_select_lex *new_parent,
3536 Item **ref, bool merge)
3537 {
3538 left_expr->fix_after_pullout(new_parent, &left_expr, merge);
3539 Item_subselect::fix_after_pullout(new_parent, ref, merge);
3540 used_tables_cache |= left_expr->used_tables();
3541 }
3542
update_used_tables()3543 void Item_in_subselect::update_used_tables()
3544 {
3545 Item_subselect::update_used_tables();
3546 left_expr->update_used_tables();
3547 //used_tables_cache |= left_expr->used_tables();
3548 used_tables_cache= Item_subselect::used_tables() | left_expr->used_tables();
3549 }
3550
3551
3552 /**
3553 Try to create and initialize an engine to compute a subselect via
3554 materialization.
3555
3556 @details
3557 The method creates a new engine for materialized execution, and initializes
3558 the engine. The initialization may fail
3559 - either because it wasn't possible to create the needed temporary table
3560 and its index,
3561 - or because of a memory allocation error,
3562
3563 @returns
3564 @retval TRUE memory allocation error occurred
3565 @retval FALSE an execution method was chosen successfully
3566 */
3567
setup_mat_engine()3568 bool Item_in_subselect::setup_mat_engine()
3569 {
3570 subselect_hash_sj_engine *mat_engine= NULL;
3571 subselect_single_select_engine *select_engine;
3572
3573 DBUG_ENTER("Item_in_subselect::setup_mat_engine");
3574 DBUG_ASSERT(thd);
3575
3576 /*
3577 The select_engine (that executes transformed IN=>EXISTS subselects) is
3578 pre-created at parse time, and is stored in statement memory (preserved
3579 across PS executions).
3580 */
3581 DBUG_ASSERT(engine->engine_type() == subselect_engine::SINGLE_SELECT_ENGINE);
3582 select_engine= (subselect_single_select_engine*) engine;
3583
3584 /* Create/initialize execution objects. */
3585 if (!(mat_engine= new subselect_hash_sj_engine(thd, this, select_engine)))
3586 DBUG_RETURN(TRUE);
3587
3588 if (mat_engine->prepare(thd) ||
3589 mat_engine->init(&select_engine->join->fields_list,
3590 engine->get_identifier()))
3591 DBUG_RETURN(TRUE);
3592
3593 engine= mat_engine;
3594 DBUG_RETURN(FALSE);
3595 }
3596
3597
3598 /**
3599 Initialize the cache of the left operand of the IN predicate.
3600
3601 @note This method has the same purpose as alloc_group_fields(),
3602 but it takes a different kind of collection of items, and the
3603 list we push to is dynamically allocated.
3604
3605 @retval TRUE if a memory allocation error occurred or the cache is
3606 not applicable to the current query
3607 @retval FALSE if success
3608 */
3609
init_left_expr_cache()3610 bool Item_in_subselect::init_left_expr_cache()
3611 {
3612 JOIN *outer_join;
3613 DBUG_ASSERT(thd);
3614
3615 outer_join= unit->outer_select()->join;
3616 /*
3617 An IN predicate might be evaluated in a query for which all tables have
3618 been optimzied away.
3619 */
3620 if (!outer_join || !outer_join->table_count || !outer_join->tables_list)
3621 return TRUE;
3622
3623 if (!(left_expr_cache= new List<Cached_item>))
3624 return TRUE;
3625
3626 for (uint i= 0; i < left_expr->cols(); i++)
3627 {
3628 Cached_item *cur_item_cache= new_Cached_item(thd,
3629 left_expr->element_index(i),
3630 FALSE);
3631 if (!cur_item_cache || left_expr_cache->push_front(cur_item_cache,
3632 thd->mem_root))
3633 return TRUE;
3634 }
3635 return FALSE;
3636 }
3637
3638
init_cond_guards()3639 bool Item_in_subselect::init_cond_guards()
3640 {
3641 DBUG_ASSERT(thd);
3642 uint cols_num= left_expr->cols();
3643 if (!abort_on_null && !pushed_cond_guards &&
3644 (left_expr->maybe_null || cols_num > 1))
3645 {
3646 if (!(pushed_cond_guards= (bool*)thd->alloc(sizeof(bool) * cols_num)))
3647 return TRUE;
3648 for (uint i= 0; i < cols_num; i++)
3649 pushed_cond_guards[i]= TRUE;
3650 }
3651 return FALSE;
3652 }
3653
3654
3655 bool
select_transformer(JOIN * join)3656 Item_allany_subselect::select_transformer(JOIN *join)
3657 {
3658 DBUG_ENTER("Item_allany_subselect::select_transformer");
3659 DBUG_ASSERT((in_strategy & ~(SUBS_MAXMIN_INJECTED | SUBS_MAXMIN_ENGINE |
3660 SUBS_IN_TO_EXISTS | SUBS_STRATEGY_CHOSEN)) == 0);
3661 if (upper_item)
3662 upper_item->show= 1;
3663 DBUG_RETURN(select_in_like_transformer(join));
3664 }
3665
3666
print(String * str,enum_query_type query_type)3667 void Item_allany_subselect::print(String *str, enum_query_type query_type)
3668 {
3669 if (test_strategy(SUBS_IN_TO_EXISTS) &&
3670 !(query_type & QT_PARSABLE))
3671 str->append(STRING_WITH_LEN("<exists>"));
3672 else
3673 {
3674 left_expr->print(str, query_type);
3675 str->append(' ');
3676 str->append(func->symbol(all));
3677 str->append(all ? " all " : " any ", 5);
3678 }
3679 Item_subselect::print(str, query_type);
3680 }
3681
3682
no_rows_in_result()3683 void Item_allany_subselect::no_rows_in_result()
3684 {
3685 /*
3686 Subquery predicates outside of the SELECT list must be evaluated in order
3687 to possibly filter the special result row generated for implicit grouping
3688 if the subquery is in the HAVING clause.
3689 If the predicate is constant, we need its actual value in the only result
3690 row for queries with implicit grouping.
3691 */
3692 if (parsing_place != SELECT_LIST || const_item())
3693 return;
3694 value= 0;
3695 null_value= 0;
3696 was_null= 0;
3697 make_const();
3698 }
3699
3700
set_thd(THD * thd_arg)3701 void subselect_engine::set_thd(THD *thd_arg)
3702 {
3703 thd= thd_arg;
3704 if (result)
3705 result->set_thd(thd_arg);
3706 }
3707
3708
3709 subselect_single_select_engine::
subselect_single_select_engine(st_select_lex * select,select_result_interceptor * result_arg,Item_subselect * item_arg)3710 subselect_single_select_engine(st_select_lex *select,
3711 select_result_interceptor *result_arg,
3712 Item_subselect *item_arg)
3713 :subselect_engine(item_arg, result_arg),
3714 prepared(0), executed(0),
3715 select_lex(select), join(0)
3716 {
3717 select_lex->master_unit()->item= item_arg;
3718 }
3719
get_identifier()3720 int subselect_single_select_engine::get_identifier()
3721 {
3722 return select_lex->select_number;
3723 }
3724
force_reexecution()3725 void subselect_single_select_engine::force_reexecution()
3726 {
3727 executed= false;
3728 }
3729
cleanup()3730 void subselect_single_select_engine::cleanup()
3731 {
3732 DBUG_ENTER("subselect_single_select_engine::cleanup");
3733 prepared= executed= 0;
3734 join= 0;
3735 result->cleanup();
3736 select_lex->uncacheable&= ~UNCACHEABLE_DEPENDENT_INJECTED;
3737 DBUG_VOID_RETURN;
3738 }
3739
3740
cleanup()3741 void subselect_union_engine::cleanup()
3742 {
3743 DBUG_ENTER("subselect_union_engine::cleanup");
3744 unit->reinit_exec_mechanism();
3745 result->cleanup();
3746 unit->uncacheable&= ~UNCACHEABLE_DEPENDENT_INJECTED;
3747 for (SELECT_LEX *sl= unit->first_select(); sl; sl= sl->next_select())
3748 sl->uncacheable&= ~UNCACHEABLE_DEPENDENT_INJECTED;
3749 DBUG_VOID_RETURN;
3750 }
3751
3752
is_executed() const3753 bool subselect_union_engine::is_executed() const
3754 {
3755 return unit->executed;
3756 }
3757
force_reexecution()3758 void subselect_union_engine::force_reexecution()
3759 {
3760 unit->executed= false;
3761 }
3762
3763
3764 /*
3765 Check if last execution of the subquery engine produced any rows
3766
3767 SYNOPSIS
3768 subselect_union_engine::no_rows()
3769
3770 DESCRIPTION
3771 Check if last execution of the subquery engine produced any rows. The
3772 return value is undefined if last execution ended in an error.
3773
3774 RETURN
3775 TRUE - Last subselect execution has produced no rows
3776 FALSE - Otherwise
3777 */
3778
no_rows()3779 bool subselect_union_engine::no_rows()
3780 {
3781 /* Check if we got any rows when reading UNION result from temp. table: */
3782 if (unit->fake_select_lex)
3783 {
3784 JOIN *join= unit->fake_select_lex->join;
3785 if (join)
3786 return MY_TEST(!join->send_records);
3787 return false;
3788 }
3789 return MY_TEST(!(((select_union_direct *)(unit->get_union_result()))
3790 ->send_records));
3791 }
3792
3793
cleanup()3794 void subselect_uniquesubquery_engine::cleanup()
3795 {
3796 DBUG_ENTER("subselect_uniquesubquery_engine::cleanup");
3797 /*
3798 Note for mergers: we don't have to, and actually must not de-initialize
3799 tab->table->file here.
3800 - We don't have to, because free_tmp_table() will call ha_index_or_rnd_end
3801 - We must not do it, because tab->table may be a derived table which
3802 has been already dropped by close_thread_tables(), while we here are
3803 called from cleanup_items()
3804 */
3805 DBUG_VOID_RETURN;
3806 }
3807
3808
subselect_union_engine(st_select_lex_unit * u,select_result_interceptor * result_arg,Item_subselect * item_arg)3809 subselect_union_engine::subselect_union_engine(st_select_lex_unit *u,
3810 select_result_interceptor *result_arg,
3811 Item_subselect *item_arg)
3812 :subselect_engine(item_arg, result_arg)
3813 {
3814 unit= u;
3815 unit->item= item_arg;
3816 }
3817
3818
3819 /**
3820 Create and prepare the JOIN object that represents the query execution
3821 plan for the subquery.
3822
3823 @details
3824 This method is called from Item_subselect::fix_fields. For prepared
3825 statements it is called both during the PREPARE and EXECUTE phases in the
3826 following ways:
3827 - During PREPARE the optimizer needs some properties
3828 (join->fields_list.elements) of the JOIN to proceed with preparation of
3829 the remaining query (namely to complete ::fix_fields for the subselect
3830 related classes. In the end of PREPARE the JOIN is deleted.
3831 - When we EXECUTE the query, Item_subselect::fix_fields is called again, and
3832 the JOIN object is re-created again, prepared and executed. In the end of
3833 execution it is deleted.
3834 In all cases the JOIN is created in runtime memory (not in the permanent
3835 memory root).
3836
3837 @todo
3838 Re-check what properties of 'join' are needed during prepare, and see if
3839 we can avoid creating a JOIN during JOIN::prepare of the outer join.
3840
3841 @retval 0 if success
3842 @retval 1 if error
3843 */
3844
prepare(THD * thd)3845 int subselect_single_select_engine::prepare(THD *thd)
3846 {
3847 if (prepared)
3848 return 0;
3849 set_thd(thd);
3850 if (select_lex->join)
3851 {
3852 select_lex->cleanup();
3853 }
3854 join= new JOIN(thd, select_lex->item_list,
3855 select_lex->options | SELECT_NO_UNLOCK, result);
3856 if (!join || !result)
3857 return 1; /* Fatal error is set already. */
3858 prepared= 1;
3859 SELECT_LEX *save_select= thd->lex->current_select;
3860 thd->lex->current_select= select_lex;
3861 if (join->prepare(select_lex->table_list.first,
3862 select_lex->where,
3863 select_lex->order_list.elements +
3864 select_lex->group_list.elements,
3865 select_lex->order_list.first,
3866 false,
3867 select_lex->group_list.first,
3868 select_lex->having,
3869 NULL, select_lex,
3870 select_lex->master_unit()))
3871 return 1;
3872 thd->lex->current_select= save_select;
3873 return 0;
3874 }
3875
prepare(THD * thd_arg)3876 int subselect_union_engine::prepare(THD *thd_arg)
3877 {
3878 set_thd(thd_arg);
3879 return unit->prepare(unit->derived, result, SELECT_NO_UNLOCK);
3880 }
3881
prepare(THD *)3882 int subselect_uniquesubquery_engine::prepare(THD *)
3883 {
3884 /* Should never be called. */
3885 DBUG_ASSERT(FALSE);
3886 return 1;
3887 }
3888
3889
3890 /*
3891 Check if last execution of the subquery engine produced any rows
3892
3893 SYNOPSIS
3894 subselect_single_select_engine::no_rows()
3895
3896 DESCRIPTION
3897 Check if last execution of the subquery engine produced any rows. The
3898 return value is undefined if last execution ended in an error.
3899
3900 RETURN
3901 TRUE - Last subselect execution has produced no rows
3902 FALSE - Otherwise
3903 */
3904
no_rows()3905 bool subselect_single_select_engine::no_rows()
3906 {
3907 return !item->assigned();
3908 }
3909
3910
3911 /**
3912 Makes storage for the output values for the subquery and calcuates
3913 their data and column types and their nullability.
3914 */
set_row(List<Item> & item_list,Item_cache ** row)3915 bool subselect_engine::set_row(List<Item> &item_list, Item_cache **row)
3916 {
3917 Item *sel_item;
3918 List_iterator_fast<Item> li(item_list);
3919 set_handler(&type_handler_varchar);
3920 for (uint i= 0; (sel_item= li++); i++)
3921 {
3922 item->max_length= sel_item->max_length;
3923 set_handler(sel_item->type_handler());
3924 item->decimals= sel_item->decimals;
3925 item->unsigned_flag= sel_item->unsigned_flag;
3926 maybe_null= sel_item->maybe_null;
3927 if (!(row[i]= sel_item->get_cache(thd)))
3928 return TRUE;
3929 row[i]->setup(thd, sel_item);
3930 //psergey-backport-timours: row[i]->store(sel_item);
3931 }
3932 if (item_list.elements > 1)
3933 set_handler(&type_handler_row);
3934 return FALSE;
3935 }
3936
fix_length_and_dec(Item_cache ** row)3937 bool subselect_single_select_engine::fix_length_and_dec(Item_cache **row)
3938 {
3939 DBUG_ASSERT(row || select_lex->item_list.elements==1);
3940 if (set_row(select_lex->item_list, row))
3941 return TRUE;
3942 item->collation.set(row[0]->collation);
3943 if (cols() != 1)
3944 maybe_null= 0;
3945 return FALSE;
3946 }
3947
fix_length_and_dec(Item_cache ** row)3948 bool subselect_union_engine::fix_length_and_dec(Item_cache **row)
3949 {
3950 DBUG_ASSERT(row || unit->first_select()->item_list.elements==1);
3951
3952 if (unit->first_select()->item_list.elements == 1)
3953 {
3954 if (set_row(unit->types, row))
3955 return TRUE;
3956 item->collation.set(row[0]->collation);
3957 }
3958 else
3959 {
3960 bool maybe_null_saved= maybe_null;
3961 if (set_row(unit->types, row))
3962 return TRUE;
3963 maybe_null= maybe_null_saved;
3964 }
3965 return FALSE;
3966 }
3967
fix_length_and_dec(Item_cache ** row)3968 bool subselect_uniquesubquery_engine::fix_length_and_dec(Item_cache **row)
3969 {
3970 //this never should be called
3971 DBUG_ASSERT(0);
3972 return FALSE;
3973 }
3974
3975 int read_first_record_seq(JOIN_TAB *tab);
3976 int rr_sequential(READ_RECORD *info);
3977 int join_read_always_key_or_null(JOIN_TAB *tab);
3978 int join_read_next_same_or_null(READ_RECORD *info);
3979
exec()3980 int subselect_single_select_engine::exec()
3981 {
3982 DBUG_ENTER("subselect_single_select_engine::exec");
3983
3984 char const *save_where= thd->where;
3985 SELECT_LEX *save_select= thd->lex->current_select;
3986 thd->lex->current_select= select_lex;
3987
3988 if (join->optimization_state == JOIN::NOT_OPTIMIZED)
3989 {
3990 SELECT_LEX_UNIT *unit= select_lex->master_unit();
3991
3992 unit->set_limit(unit->global_parameters());
3993 if (join->optimize())
3994 {
3995 thd->where= save_where;
3996 executed= 1;
3997 thd->lex->current_select= save_select;
3998 DBUG_RETURN(join->error ? join->error : 1);
3999 }
4000 if (!select_lex->uncacheable && thd->lex->describe &&
4001 !(join->select_options & SELECT_DESCRIBE))
4002 {
4003 item->update_used_tables();
4004 if (item->const_item())
4005 {
4006 /*
4007 It's necessary to keep original JOIN table because
4008 create_sort_index() function may overwrite original
4009 JOIN_TAB::type and wrong optimization method can be
4010 selected on re-execution.
4011 */
4012 select_lex->uncacheable|= UNCACHEABLE_EXPLAIN;
4013 select_lex->master_unit()->uncacheable|= UNCACHEABLE_EXPLAIN;
4014 }
4015 }
4016 if (item->engine_changed(this))
4017 {
4018 thd->lex->current_select= save_select;
4019 DBUG_RETURN(1);
4020 }
4021 }
4022 if (select_lex->uncacheable &&
4023 select_lex->uncacheable != UNCACHEABLE_EXPLAIN
4024 && executed)
4025 {
4026 if (join->reinit())
4027 {
4028 thd->where= save_where;
4029 thd->lex->current_select= save_select;
4030 DBUG_RETURN(1);
4031 }
4032 item->reset();
4033 item->assigned((executed= 0));
4034 }
4035 if (!executed)
4036 {
4037 item->reset_value_registration();
4038 JOIN_TAB *changed_tabs[MAX_TABLES];
4039 JOIN_TAB **last_changed_tab= changed_tabs;
4040 if (item->have_guarded_conds())
4041 {
4042 /*
4043 For at least one of the pushed predicates the following is true:
4044 We should not apply optimizations based on the condition that was
4045 pushed down into the subquery. Those optimizations are ref[_or_null]
4046 accesses. Change them to be full table scans.
4047 */
4048 JOIN_TAB *tab;
4049 for (tab= first_linear_tab(join, WITH_BUSH_ROOTS, WITHOUT_CONST_TABLES);
4050 tab; tab= next_linear_tab(join, tab, WITH_BUSH_ROOTS))
4051 {
4052 if (tab && tab->keyuse)
4053 {
4054 for (uint i= 0; i < tab->ref.key_parts; i++)
4055 {
4056 bool *cond_guard= tab->ref.cond_guards[i];
4057 if (cond_guard && !*cond_guard)
4058 {
4059 /* Change the access method to full table scan */
4060 tab->save_read_first_record= tab->read_first_record;
4061 tab->save_read_record= tab->read_record.read_record_func;
4062 tab->read_record.read_record_func= rr_sequential;
4063 tab->read_first_record= read_first_record_seq;
4064 if (tab->rowid_filter)
4065 tab->table->file->disable_pushed_rowid_filter();
4066 tab->read_record.thd= join->thd;
4067 tab->read_record.ref_length= tab->table->file->ref_length;
4068 tab->read_record.unlock_row= rr_unlock_row;
4069 *(last_changed_tab++)= tab;
4070 break;
4071 }
4072 }
4073 }
4074 }
4075 }
4076
4077 join->exec();
4078
4079 /* Enable the optimizations back */
4080 for (JOIN_TAB **ptab= changed_tabs; ptab != last_changed_tab; ptab++)
4081 {
4082 JOIN_TAB *tab= *ptab;
4083 tab->read_record.ref_length= 0;
4084 tab->read_first_record= tab->save_read_first_record;
4085 tab->read_record.read_record_func= tab->save_read_record;
4086 if (tab->rowid_filter)
4087 tab->table->file->enable_pushed_rowid_filter();
4088 }
4089 executed= 1;
4090 if (!(uncacheable() & ~UNCACHEABLE_EXPLAIN) &&
4091 !item->with_recursive_reference)
4092 item->make_const();
4093 thd->where= save_where;
4094 thd->lex->current_select= save_select;
4095 DBUG_RETURN(join->error || thd->is_fatal_error || thd->is_error());
4096 }
4097 thd->where= save_where;
4098 thd->lex->current_select= save_select;
4099 DBUG_RETURN(0);
4100 }
4101
exec()4102 int subselect_union_engine::exec()
4103 {
4104 char const *save_where= thd->where;
4105 int res= unit->exec();
4106 thd->where= save_where;
4107 return res;
4108 }
4109
4110
4111 /*
4112 Search for at least one row satisfying select condition
4113
4114 SYNOPSIS
4115 subselect_uniquesubquery_engine::scan_table()
4116
4117 DESCRIPTION
4118 Scan the table using sequential access until we find at least one row
4119 satisfying select condition.
4120
4121 The caller must set this->empty_result_set=FALSE before calling this
4122 function. This function will set it to TRUE if it finds a matching row.
4123
4124 RETURN
4125 FALSE - OK
4126 TRUE - Error
4127 */
4128
scan_table()4129 int subselect_uniquesubquery_engine::scan_table()
4130 {
4131 int error;
4132 TABLE *table= tab->table;
4133 DBUG_ENTER("subselect_uniquesubquery_engine::scan_table");
4134
4135 if ((table->file->inited &&
4136 (error= table->file->ha_index_end())) ||
4137 (error= table->file->ha_rnd_init(1)))
4138 {
4139 (void) report_error(table, error);
4140 DBUG_RETURN(true);
4141 }
4142
4143 table->file->extra_opt(HA_EXTRA_CACHE,
4144 get_thd()->variables.read_buff_size);
4145 table->null_row= 0;
4146 for (;;)
4147 {
4148 error=table->file->ha_rnd_next(table->record[0]);
4149 if (unlikely(error))
4150 {
4151 if (error == HA_ERR_END_OF_FILE)
4152 {
4153 error= 0;
4154 break;
4155 }
4156 else
4157 {
4158 error= report_error(table, error);
4159 break;
4160 }
4161 }
4162
4163 if (!cond || cond->val_int())
4164 {
4165 empty_result_set= FALSE;
4166 break;
4167 }
4168 }
4169
4170 table->file->ha_rnd_end();
4171 DBUG_RETURN(error != 0);
4172 }
4173
4174
4175 /**
4176 Copy ref key for index access into the only subquery table.
4177
4178 @details
4179 Copy ref key and check for conversion problems.
4180 If there is an error converting the left IN operand to the column type of
4181 the right IN operand count it as no match. In this case IN has the value of
4182 FALSE. We mark the subquery table cursor as having no more rows (to ensure
4183 that the processing that follows will not find a match) and return FALSE,
4184 so IN is not treated as returning NULL.
4185
4186 @returns
4187 @retval FALSE The outer ref was copied into an index lookup key.
4188 @retval TRUE The outer ref cannot possibly match any row, IN is FALSE.
4189 */
4190
copy_ref_key(bool skip_constants)4191 bool subselect_uniquesubquery_engine::copy_ref_key(bool skip_constants)
4192 {
4193 DBUG_ENTER("subselect_uniquesubquery_engine::copy_ref_key");
4194
4195 for (store_key **copy= tab->ref.key_copy ; *copy ; copy++)
4196 {
4197 enum store_key::store_key_result store_res;
4198 if (skip_constants && (*copy)->store_key_is_const())
4199 continue;
4200 store_res= (*copy)->copy();
4201 tab->ref.key_err= store_res;
4202
4203 if (store_res == store_key::STORE_KEY_FATAL)
4204 {
4205 /*
4206 Error converting the left IN operand to the column type of the right
4207 IN operand.
4208 */
4209 DBUG_RETURN(true);
4210 }
4211 }
4212 DBUG_RETURN(false);
4213 }
4214
4215
4216 /**
4217 Execute subselect via unique index lookup
4218
4219 @details
4220 Find rows corresponding to the ref key using index access.
4221 If some part of the lookup key is NULL, then we're evaluating
4222 NULL IN (SELECT ... )
4223 This is a special case, we don't need to search for NULL in the table,
4224 instead, the result value is
4225 - NULL if select produces empty row set
4226 - FALSE otherwise.
4227
4228 In some cases (IN subselect is a top level item, i.e. abort_on_null==TRUE)
4229 the caller doesn't distinguish between NULL and FALSE result and we just
4230 return FALSE.
4231 Otherwise we make a full table scan to see if there is at least one
4232 matching row.
4233
4234 The result of this function (info about whether a row was found) is
4235 stored in this->empty_result_set.
4236
4237 @returns
4238 @retval 0 OK
4239 @retval 1 notify caller to call Item_subselect::reset(),
4240 in most cases reset() sets the result to NULL
4241 */
4242
exec()4243 int subselect_uniquesubquery_engine::exec()
4244 {
4245 DBUG_ENTER("subselect_uniquesubquery_engine::exec");
4246 int error;
4247 TABLE *table= tab->table;
4248 empty_result_set= TRUE;
4249 table->status= 0;
4250 Item_in_subselect *in_subs= item->get_IN_subquery();
4251 DBUG_ASSERT(in_subs);
4252
4253 if (!tab->preread_init_done && tab->preread_init())
4254 DBUG_RETURN(1);
4255
4256 if (in_subs->left_expr_has_null())
4257 {
4258 /*
4259 The case when all values in left_expr are NULL is handled by
4260 Item_in_optimizer::val_int().
4261 */
4262 if (in_subs->is_top_level_item())
4263 DBUG_RETURN(1); /* notify caller to call reset() and set NULL value. */
4264 else
4265 DBUG_RETURN(scan_table());
4266 }
4267
4268 if (copy_ref_key(true))
4269 {
4270 /* We know that there will be no rows even if we scan. */
4271 in_subs->value= 0;
4272 DBUG_RETURN(0);
4273 }
4274
4275 if (!table->file->inited &&
4276 (error= table->file->ha_index_init(tab->ref.key, 0)))
4277 {
4278 (void) report_error(table, error);
4279 DBUG_RETURN(true);
4280 }
4281
4282 error= table->file->ha_index_read_map(table->record[0],
4283 tab->ref.key_buff,
4284 make_prev_keypart_map(tab->
4285 ref.key_parts),
4286 HA_READ_KEY_EXACT);
4287 if (unlikely(error &&
4288 error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE))
4289 error= report_error(table, error);
4290 else
4291 {
4292 error= 0;
4293 table->null_row= 0;
4294 if (!table->status && (!cond || cond->val_int()))
4295 {
4296 in_subs->value= 1;
4297 empty_result_set= FALSE;
4298 }
4299 else
4300 in_subs->value= 0;
4301 }
4302
4303 DBUG_RETURN(error != 0);
4304 }
4305
4306
4307 /*
4308 TIMOUR: write comment
4309 */
4310
index_lookup()4311 int subselect_uniquesubquery_engine::index_lookup()
4312 {
4313 DBUG_ENTER("subselect_uniquesubquery_engine::index_lookup");
4314 int error;
4315 TABLE *table= tab->table;
4316
4317 if (!table->file->inited)
4318 table->file->ha_index_init(tab->ref.key, 0);
4319 error= table->file->ha_index_read_map(table->record[0],
4320 tab->ref.key_buff,
4321 make_prev_keypart_map(tab->
4322 ref.key_parts),
4323 HA_READ_KEY_EXACT);
4324 DBUG_PRINT("info", ("lookup result: %i", error));
4325
4326 if (unlikely(error && error != HA_ERR_KEY_NOT_FOUND &&
4327 error != HA_ERR_END_OF_FILE))
4328 {
4329 /*
4330 TIMOUR: I don't understand at all when do we need to call report_error.
4331 In most places where we access an index, we don't do this. Why here?
4332 */
4333 error= report_error(table, error);
4334 DBUG_RETURN(error);
4335 }
4336
4337 table->null_row= 0;
4338 if (!error && (!cond || cond->val_int()))
4339 item->get_IN_subquery()->value= 1;
4340 else
4341 item->get_IN_subquery()->value= 0;
4342
4343 DBUG_RETURN(0);
4344 }
4345
4346
4347
~subselect_uniquesubquery_engine()4348 subselect_uniquesubquery_engine::~subselect_uniquesubquery_engine()
4349 {
4350 /* Tell handler we don't need the index anymore */
4351 //psergey-merge-todo: the following was gone in 6.0:
4352 //psergey-merge: don't need this after all: tab->table->file->ha_index_end();
4353 }
4354
4355
4356 /**
4357 Execute subselect via unique index lookup
4358
4359 @details
4360 The engine is used to resolve subqueries in form
4361
4362 oe IN (SELECT key FROM tbl WHERE subq_where)
4363
4364 The value of the predicate is calculated as follows:
4365 1. If oe IS NULL, this is a special case, do a full table scan on
4366 table tbl and search for row that satisfies subq_where. If such
4367 row is found, return NULL, otherwise return FALSE.
4368 2. Make an index lookup via key=oe, search for a row that satisfies
4369 subq_where. If found, return TRUE.
4370 3. If check_null==TRUE, make another lookup via key=NULL, search for a
4371 row that satisfies subq_where. If found, return NULL, otherwise
4372 return FALSE.
4373
4374 @todo
4375 The step #1 can be optimized further when the index has several key
4376 parts. Consider a subquery:
4377
4378 (oe1, oe2) IN (SELECT keypart1, keypart2 FROM tbl WHERE subq_where)
4379
4380 and suppose we need to evaluate it for {oe1, oe2}=={const1, NULL}.
4381 Current code will do a full table scan and obtain correct result. There
4382 is a better option: instead of evaluating
4383
4384 SELECT keypart1, keypart2 FROM tbl WHERE subq_where (1)
4385
4386 and checking if it has produced any matching rows, evaluate
4387
4388 SELECT keypart2 FROM tbl WHERE subq_where AND keypart1=const1 (2)
4389
4390 If this query produces a row, the result is NULL (as we're evaluating
4391 "(const1, NULL) IN { (const1, X), ... }", which has a value of UNKNOWN,
4392 i.e. NULL). If the query produces no rows, the result is FALSE.
4393
4394 We currently evaluate (1) by doing a full table scan. (2) can be
4395 evaluated by doing a "ref" scan on "keypart1=const1", which can be much
4396 cheaper. We can use index statistics to quickly check whether "ref" scan
4397 will be cheaper than full table scan.
4398
4399 @returns
4400 @retval 0 OK
4401 @retval 1 notify caller to call Item_subselect::reset(),
4402 in most cases reset() sets the result to NULL
4403 */
4404
exec()4405 int subselect_indexsubquery_engine::exec()
4406 {
4407 DBUG_ENTER("subselect_indexsubquery_engine");
4408 int error;
4409 bool null_finding= 0;
4410 TABLE *table= tab->table;
4411 Item_in_subselect *in_subs= item->get_IN_subquery();
4412
4413 in_subs->value= 0;
4414 empty_result_set= TRUE;
4415 table->status= 0;
4416
4417 if (check_null)
4418 {
4419 /* We need to check for NULL if there wasn't a matching value */
4420 *tab->ref.null_ref_key= 0; // Search first for not null
4421 in_subs->was_null= 0;
4422 }
4423
4424 if (!tab->preread_init_done && tab->preread_init())
4425 DBUG_RETURN(1);
4426
4427 if (in_subs->left_expr_has_null())
4428 {
4429 /*
4430 The case when all values in left_expr are NULL is handled by
4431 Item_in_optimizer::val_int().
4432 */
4433 if (in_subs->is_top_level_item())
4434 DBUG_RETURN(1); /* notify caller to call reset() and set NULL value. */
4435 else
4436 DBUG_RETURN(scan_table());
4437 }
4438
4439 if (copy_ref_key(true))
4440 {
4441 /* We know that there will be no rows even if we scan. */
4442 in_subs->value= 0;
4443 DBUG_RETURN(0);
4444 }
4445
4446 if (!table->file->inited &&
4447 (error= table->file->ha_index_init(tab->ref.key, 1)))
4448 {
4449 (void) report_error(table, error);
4450 DBUG_RETURN(true);
4451 }
4452
4453 error= table->file->ha_index_read_map(table->record[0],
4454 tab->ref.key_buff,
4455 make_prev_keypart_map(tab->
4456 ref.key_parts),
4457 HA_READ_KEY_EXACT);
4458 if (unlikely(error &&
4459 error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE))
4460 error= report_error(table, error);
4461 else
4462 {
4463 for (;;)
4464 {
4465 error= 0;
4466 table->null_row= 0;
4467 if (!table->status)
4468 {
4469 if ((!cond || cond->val_int()) && (!having || having->val_int()))
4470 {
4471 empty_result_set= FALSE;
4472 if (null_finding)
4473 in_subs->was_null= 1;
4474 else
4475 in_subs->value= 1;
4476 break;
4477 }
4478 error= table->file->ha_index_next_same(table->record[0],
4479 tab->ref.key_buff,
4480 tab->ref.key_length);
4481 if (unlikely(error && error != HA_ERR_END_OF_FILE))
4482 {
4483 error= report_error(table, error);
4484 break;
4485 }
4486 }
4487 else
4488 {
4489 if (!check_null || null_finding)
4490 break; /* We don't need to check nulls */
4491 *tab->ref.null_ref_key= 1;
4492 null_finding= 1;
4493 /* Check if there exists a row with a null value in the index */
4494 if (unlikely((error= (safe_index_read(tab) == 1))))
4495 break;
4496 }
4497 }
4498 }
4499 DBUG_RETURN(error != 0);
4500 }
4501
4502
cols() const4503 uint subselect_single_select_engine::cols() const
4504 {
4505 //psergey-sj-backport: the following assert was gone in 6.0:
4506 //DBUG_ASSERT(select_lex->join != 0); // should be called after fix_fields()
4507 //return select_lex->join->fields_list.elements;
4508 return select_lex->item_list.elements;
4509 }
4510
4511
cols() const4512 uint subselect_union_engine::cols() const
4513 {
4514 DBUG_ASSERT(unit->is_prepared()); // should be called after fix_fields()
4515 return unit->types.elements;
4516 }
4517
4518
uncacheable()4519 uint8 subselect_single_select_engine::uncacheable()
4520 {
4521 return select_lex->uncacheable;
4522 }
4523
4524
uncacheable()4525 uint8 subselect_union_engine::uncacheable()
4526 {
4527 return unit->uncacheable;
4528 }
4529
4530
exclude()4531 void subselect_single_select_engine::exclude()
4532 {
4533 select_lex->master_unit()->exclude_level();
4534 }
4535
exclude()4536 void subselect_union_engine::exclude()
4537 {
4538 unit->exclude_level();
4539 }
4540
4541
exclude()4542 void subselect_uniquesubquery_engine::exclude()
4543 {
4544 //this never should be called
4545 DBUG_ASSERT(0);
4546 }
4547
4548
calc_const_tables(List<TABLE_LIST> & list)4549 table_map subselect_engine::calc_const_tables(List<TABLE_LIST> &list)
4550 {
4551 table_map map= 0;
4552 List_iterator<TABLE_LIST> ti(list);
4553 TABLE_LIST *table;
4554 //for (; table; table= table->next_leaf)
4555 while ((table= ti++))
4556 {
4557 TABLE *tbl= table->table;
4558 if (tbl && tbl->const_table)
4559 map|= tbl->map;
4560 }
4561 return map;
4562 }
4563
4564
upper_select_const_tables()4565 table_map subselect_single_select_engine::upper_select_const_tables()
4566 {
4567 return calc_const_tables(select_lex->outer_select()->leaf_tables);
4568 }
4569
4570
upper_select_const_tables()4571 table_map subselect_union_engine::upper_select_const_tables()
4572 {
4573 return calc_const_tables(unit->outer_select()->leaf_tables);
4574 }
4575
4576
print(String * str,enum_query_type query_type)4577 void subselect_single_select_engine::print(String *str,
4578 enum_query_type query_type)
4579 {
4580 With_clause* with_clause= select_lex->get_with_clause();
4581 THD *thd= get_thd();
4582 if (with_clause)
4583 with_clause->print(thd, str, query_type);
4584 select_lex->print(thd, str, query_type);
4585 }
4586
4587
print(String * str,enum_query_type query_type)4588 void subselect_union_engine::print(String *str, enum_query_type query_type)
4589 {
4590 unit->print(str, query_type);
4591 }
4592
4593
print(String * str,enum_query_type query_type)4594 void subselect_uniquesubquery_engine::print(String *str,
4595 enum_query_type query_type)
4596 {
4597 str->append(STRING_WITH_LEN("<primary_index_lookup>("));
4598 tab->ref.items[0]->print(str, query_type);
4599 str->append(STRING_WITH_LEN(" in "));
4600 if (tab->table->s->table_category == TABLE_CATEGORY_TEMPORARY)
4601 {
4602 /*
4603 Temporary tables' names change across runs, so they can't be used for
4604 EXPLAIN EXTENDED.
4605 */
4606 str->append(STRING_WITH_LEN("<temporary table>"));
4607 }
4608 else
4609 str->append(&tab->table->s->table_name);
4610 KEY *key_info= tab->table->key_info+ tab->ref.key;
4611 str->append(STRING_WITH_LEN(" on "));
4612 str->append(&key_info->name);
4613 if (cond)
4614 {
4615 str->append(STRING_WITH_LEN(" where "));
4616 cond->print(str, query_type);
4617 }
4618 str->append(')');
4619 }
4620
4621 /*
4622 TODO:
4623 The above ::print method should be changed as below. Do it after
4624 all other tests pass.
4625
4626 void subselect_uniquesubquery_engine::print(String *str)
4627 {
4628 KEY *key_info= tab->table->key_info + tab->ref.key;
4629 str->append(STRING_WITH_LEN("<primary_index_lookup>("));
4630 for (uint i= 0; i < key_info->user_defined_key_parts; i++)
4631 tab->ref.items[i]->print(str);
4632 str->append(STRING_WITH_LEN(" in "));
4633 str->append(&tab->table->s->table_name);
4634 str->append(STRING_WITH_LEN(" on "));
4635 str->append(&key_info->name);
4636 if (cond)
4637 {
4638 str->append(STRING_WITH_LEN(" where "));
4639 cond->print(str);
4640 }
4641 str->append(')');
4642 }
4643 */
4644
print(String * str,enum_query_type query_type)4645 void subselect_indexsubquery_engine::print(String *str,
4646 enum_query_type query_type)
4647 {
4648 str->append(STRING_WITH_LEN("<index_lookup>("));
4649 tab->ref.items[0]->print(str, query_type);
4650 str->append(STRING_WITH_LEN(" in "));
4651 str->append(tab->table->s->table_name.str, tab->table->s->table_name.length);
4652 KEY *key_info= tab->table->key_info+ tab->ref.key;
4653 str->append(STRING_WITH_LEN(" on "));
4654 str->append(&key_info->name);
4655 if (check_null)
4656 str->append(STRING_WITH_LEN(" checking NULL"));
4657 if (cond)
4658 {
4659 str->append(STRING_WITH_LEN(" where "));
4660 cond->print(str, query_type);
4661 }
4662 if (having)
4663 {
4664 str->append(STRING_WITH_LEN(" having "));
4665 having->print(str, query_type);
4666 }
4667 str->append(')');
4668 }
4669
4670 /**
4671 change select_result object of engine.
4672
4673 @param si new subselect Item
4674 @param res new select_result object
4675 @param temp temporary assignment
4676
4677 @retval
4678 FALSE OK
4679 @retval
4680 TRUE error
4681 */
4682
4683 bool
change_result(Item_subselect * si,select_result_interceptor * res,bool temp)4684 subselect_single_select_engine::change_result(Item_subselect *si,
4685 select_result_interceptor *res,
4686 bool temp)
4687 {
4688 DBUG_ENTER("subselect_single_select_engine::change_result");
4689 item= si;
4690 if (temp)
4691 {
4692 /*
4693 Here we reuse change_item_tree to roll back assignment. It has
4694 nothing special about Item* pointer so it is safe conversion. We do
4695 not change the interface to be compatible with MySQL.
4696 */
4697 thd->change_item_tree((Item**) &result, (Item*)res);
4698 }
4699 else
4700 result= res;
4701
4702 /*
4703 We can't use 'result' below as gcc 4.2.4's alias optimization
4704 assumes that result was not changed by thd->change_item_tree().
4705 I tried to find a solution to make gcc happy, but could not find anything
4706 that would not require a lot of extra code that would be harder to manage
4707 than the current code.
4708 */
4709 DBUG_RETURN(select_lex->join->change_result(res, NULL));
4710 }
4711
4712
4713 /**
4714 change select_result object of engine.
4715
4716 @param si new subselect Item
4717 @param res new select_result object
4718
4719 @retval
4720 FALSE OK
4721 @retval
4722 TRUE error
4723 */
4724
change_result(Item_subselect * si,select_result_interceptor * res,bool temp)4725 bool subselect_union_engine::change_result(Item_subselect *si,
4726 select_result_interceptor *res,
4727 bool temp)
4728 {
4729 item= si;
4730 int rc= unit->change_result(res, result);
4731 if (temp)
4732 thd->change_item_tree((Item**) &result, (Item*)res);
4733 else
4734 result= res;
4735 return rc;
4736 }
4737
4738
4739 /**
4740 change select_result emulation, never should be called.
4741
4742 @param si new subselect Item
4743 @param res new select_result object
4744
4745 @retval
4746 FALSE OK
4747 @retval
4748 TRUE error
4749 */
4750
4751 bool
change_result(Item_subselect * si,select_result_interceptor * res,bool temp)4752 subselect_uniquesubquery_engine::change_result(Item_subselect *si,
4753 select_result_interceptor *res,
4754 bool temp
4755 __attribute__((unused)))
4756 {
4757 DBUG_ASSERT(0);
4758 return TRUE;
4759 }
4760
4761
4762 /**
4763 Report about presence of tables in subquery.
4764
4765 @retval
4766 TRUE there are not tables used in subquery
4767 @retval
4768 FALSE there are some tables in subquery
4769 */
no_tables()4770 bool subselect_single_select_engine::no_tables()
4771 {
4772 return(select_lex->table_list.elements == 0);
4773 }
4774
4775
4776 /*
4777 Check statically whether the subquery can return NULL
4778
4779 SINOPSYS
4780 subselect_single_select_engine::may_be_null()
4781
4782 RETURN
4783 FALSE can guarantee that the subquery never return NULL
4784 TRUE otherwise
4785 */
may_be_null()4786 bool subselect_single_select_engine::may_be_null()
4787 {
4788 return ((no_tables() && !join->conds && !join->having) ? maybe_null : 1);
4789 }
4790
4791
4792 /**
4793 Report about presence of tables in subquery.
4794
4795 @retval
4796 TRUE there are not tables used in subquery
4797 @retval
4798 FALSE there are some tables in subquery
4799 */
no_tables()4800 bool subselect_union_engine::no_tables()
4801 {
4802 for (SELECT_LEX *sl= unit->first_select(); sl; sl= sl->next_select())
4803 {
4804 if (sl->table_list.elements)
4805 return FALSE;
4806 }
4807 return TRUE;
4808 }
4809
4810
4811 /**
4812 Report about presence of tables in subquery.
4813
4814 @retval
4815 TRUE there are not tables used in subquery
4816 @retval
4817 FALSE there are some tables in subquery
4818 */
4819
no_tables()4820 bool subselect_uniquesubquery_engine::no_tables()
4821 {
4822 /* returning value is correct, but this method should never be called */
4823 DBUG_ASSERT(FALSE);
4824 return 0;
4825 }
4826
4827
4828 /******************************************************************************
4829 WL#1110 - Implementation of class subselect_hash_sj_engine
4830 ******************************************************************************/
4831
4832
4833 /**
4834 Check if an IN predicate should be executed via partial matching using
4835 only schema information.
4836
4837 @details
4838 This test essentially has three results:
4839 - partial matching is applicable, but cannot be executed due to a
4840 limitation in the total number of indexes, as a result we can't
4841 use subquery materialization at all.
4842 - partial matching is either applicable or not, and this can be
4843 determined by looking at 'this->max_keys'.
4844 If max_keys > 1, then we need partial matching because there are
4845 more indexes than just the one we use during materialization to
4846 remove duplicates.
4847
4848 @note
4849 TIMOUR: The schema-based analysis for partial matching can be done once for
4850 prepared statement and remembered. It is done here to remove the need to
4851 save/restore all related variables between each re-execution, thus making
4852 the code simpler.
4853
4854 @retval PARTIAL_MATCH if a partial match should be used
4855 @retval COMPLETE_MATCH if a complete match (index lookup) should be used
4856 */
4857
4858 subselect_hash_sj_engine::exec_strategy
get_strategy_using_schema()4859 subselect_hash_sj_engine::get_strategy_using_schema()
4860 {
4861 Item_in_subselect *item_in= item->get_IN_subquery();
4862
4863 if (item_in->is_top_level_item())
4864 return COMPLETE_MATCH;
4865 else
4866 {
4867 List_iterator<Item> inner_col_it(*item_in->unit->get_column_types(false));
4868 Item *outer_col, *inner_col;
4869
4870 for (uint i= 0; i < item_in->left_expr->cols(); i++)
4871 {
4872 outer_col= item_in->left_expr->element_index(i);
4873 inner_col= inner_col_it++;
4874
4875 if (!inner_col->maybe_null && !outer_col->maybe_null)
4876 bitmap_set_bit(&non_null_key_parts, i);
4877 else
4878 {
4879 bitmap_set_bit(&partial_match_key_parts, i);
4880 ++count_partial_match_columns;
4881 }
4882 }
4883 }
4884
4885 /* If no column contains NULLs use regular hash index lookups. */
4886 if (count_partial_match_columns)
4887 return PARTIAL_MATCH;
4888 return COMPLETE_MATCH;
4889 }
4890
4891
4892 /**
4893 Test whether an IN predicate must be computed via partial matching
4894 based on the NULL statistics for each column of a materialized subquery.
4895
4896 @details The procedure analyzes column NULL statistics, updates the
4897 matching type of columns that cannot be NULL or that contain only NULLs.
4898 Based on this, the procedure determines the final execution strategy for
4899 the [NOT] IN predicate.
4900
4901 @retval PARTIAL_MATCH if a partial match should be used
4902 @retval COMPLETE_MATCH if a complete match (index lookup) should be used
4903 */
4904
4905 subselect_hash_sj_engine::exec_strategy
get_strategy_using_data()4906 subselect_hash_sj_engine::get_strategy_using_data()
4907 {
4908 Item_in_subselect *item_in= item->get_IN_subquery();
4909 select_materialize_with_stats *result_sink=
4910 (select_materialize_with_stats *) result;
4911 Item *outer_col;
4912
4913 /*
4914 If we already determined that a complete match is enough based on schema
4915 information, nothing can be better.
4916 */
4917 if (strategy == COMPLETE_MATCH)
4918 return COMPLETE_MATCH;
4919
4920 for (uint i= 0; i < item_in->left_expr->cols(); i++)
4921 {
4922 if (!bitmap_is_set(&partial_match_key_parts, i))
4923 continue;
4924 outer_col= item_in->left_expr->element_index(i);
4925 /*
4926 If column 'i' doesn't contain NULLs, and the corresponding outer reference
4927 cannot have a NULL value, then 'i' is a non-nullable column.
4928 */
4929 if (result_sink->get_null_count_of_col(i) == 0 && !outer_col->maybe_null)
4930 {
4931 bitmap_clear_bit(&partial_match_key_parts, i);
4932 bitmap_set_bit(&non_null_key_parts, i);
4933 --count_partial_match_columns;
4934 }
4935 if (result_sink->get_null_count_of_col(i) == tmp_table->file->stats.records)
4936 ++count_null_only_columns;
4937 if (result_sink->get_null_count_of_col(i))
4938 ++count_columns_with_nulls;
4939 }
4940
4941 /* If no column contains NULLs use regular hash index lookups. */
4942 if (!count_partial_match_columns)
4943 return COMPLETE_MATCH;
4944 return PARTIAL_MATCH;
4945 }
4946
4947
4948 void
choose_partial_match_strategy(bool has_non_null_key,bool has_covering_null_row,MY_BITMAP * partial_match_key_parts_arg)4949 subselect_hash_sj_engine::choose_partial_match_strategy(
4950 bool has_non_null_key, bool has_covering_null_row,
4951 MY_BITMAP *partial_match_key_parts_arg)
4952 {
4953 ulonglong pm_buff_size;
4954
4955 DBUG_ASSERT(strategy == PARTIAL_MATCH);
4956 /*
4957 Choose according to global optimizer switch. If only one of the switches is
4958 'ON', then the remaining strategy is the only possible one. The only cases
4959 when this will be overridden is when the total size of all buffers for the
4960 merge strategy is bigger than the 'rowid_merge_buff_size' system variable,
4961 or if there isn't enough physical memory to allocate the buffers.
4962 */
4963 if (!optimizer_flag(thd, OPTIMIZER_SWITCH_PARTIAL_MATCH_ROWID_MERGE) &&
4964 optimizer_flag(thd, OPTIMIZER_SWITCH_PARTIAL_MATCH_TABLE_SCAN))
4965 strategy= PARTIAL_MATCH_SCAN;
4966 else if
4967 ( optimizer_flag(thd, OPTIMIZER_SWITCH_PARTIAL_MATCH_ROWID_MERGE) &&
4968 !optimizer_flag(thd, OPTIMIZER_SWITCH_PARTIAL_MATCH_TABLE_SCAN))
4969 strategy= PARTIAL_MATCH_MERGE;
4970
4971 /*
4972 If both switches are ON, or both are OFF, we interpret that as "let the
4973 optimizer decide". Perform a cost based choice between the two partial
4974 matching strategies.
4975 */
4976 /*
4977 TIMOUR: the above interpretation of the switch values could be changed to:
4978 - if both are ON - let the optimizer decide,
4979 - if both are OFF - do not use partial matching, therefore do not use
4980 materialization in non-top-level predicates.
4981 The problem with this is that we know for sure if we need partial matching
4982 only after the subquery is materialized, and this is too late to revert to
4983 the IN=>EXISTS strategy.
4984 */
4985 if (strategy == PARTIAL_MATCH)
4986 {
4987 /*
4988 TIMOUR: Currently we use a super simplistic measure. This will be
4989 addressed in a separate task.
4990 */
4991 if (tmp_table->file->stats.records < 100)
4992 strategy= PARTIAL_MATCH_SCAN;
4993 else
4994 strategy= PARTIAL_MATCH_MERGE;
4995 }
4996
4997 /* Check if there is enough memory for the rowid merge strategy. */
4998 if (strategy == PARTIAL_MATCH_MERGE)
4999 {
5000 pm_buff_size= rowid_merge_buff_size(has_non_null_key,
5001 has_covering_null_row,
5002 partial_match_key_parts_arg);
5003 if (pm_buff_size > thd->variables.rowid_merge_buff_size)
5004 strategy= PARTIAL_MATCH_SCAN;
5005 }
5006 }
5007
5008
5009 /*
5010 Compute the memory size of all buffers proportional to the number of rows
5011 in tmp_table.
5012
5013 @details
5014 If the result is bigger than thd->variables.rowid_merge_buff_size, partial
5015 matching via merging is not applicable.
5016 */
5017
rowid_merge_buff_size(bool has_non_null_key,bool has_covering_null_row,MY_BITMAP * partial_match_key_parts)5018 ulonglong subselect_hash_sj_engine::rowid_merge_buff_size(
5019 bool has_non_null_key, bool has_covering_null_row,
5020 MY_BITMAP *partial_match_key_parts)
5021 {
5022 /* Total size of all buffers used by partial matching. */
5023 ulonglong buff_size;
5024 ha_rows row_count= tmp_table->file->stats.records;
5025 uint rowid_length= tmp_table->file->ref_length;
5026 select_materialize_with_stats *result_sink=
5027 (select_materialize_with_stats *) result;
5028 ha_rows max_null_row;
5029
5030 /* Size of the subselect_rowid_merge_engine::row_num_to_rowid buffer. */
5031 buff_size= row_count * rowid_length * sizeof(uchar);
5032
5033 if (has_non_null_key)
5034 {
5035 /* Add the size of Ordered_key::key_buff of the only non-NULL key. */
5036 buff_size+= row_count * sizeof(rownum_t);
5037 }
5038
5039 if (!has_covering_null_row)
5040 {
5041 for (uint i= 0; i < partial_match_key_parts->n_bits; i++)
5042 {
5043 if (!bitmap_is_set(partial_match_key_parts, i) ||
5044 result_sink->get_null_count_of_col(i) == row_count)
5045 continue; /* In these cases we wouldn't construct Ordered keys. */
5046
5047 /* Add the size of Ordered_key::key_buff */
5048 buff_size+= (row_count - result_sink->get_null_count_of_col(i)) *
5049 sizeof(rownum_t);
5050 /* Add the size of Ordered_key::null_key */
5051 max_null_row= result_sink->get_max_null_of_col(i);
5052 if (max_null_row >= UINT_MAX)
5053 {
5054 /*
5055 There can be at most UINT_MAX bits in a MY_BITMAP that is used to
5056 store NULLs in an Ordered_key. Return a number of bytes bigger than
5057 the maximum allowed memory buffer for partial matching to disable
5058 the rowid merge strategy.
5059 */
5060 return ULONGLONG_MAX;
5061 }
5062 buff_size+= bitmap_buffer_size(max_null_row);
5063 }
5064 }
5065
5066 return buff_size;
5067 }
5068
5069
5070 /*
5071 Initialize a MY_BITMAP with a buffer allocated on the current
5072 memory root.
5073 TIMOUR: move to bitmap C file?
5074 */
5075
5076 static my_bool
my_bitmap_init_memroot(MY_BITMAP * map,uint n_bits,MEM_ROOT * mem_root)5077 my_bitmap_init_memroot(MY_BITMAP *map, uint n_bits, MEM_ROOT *mem_root)
5078 {
5079 my_bitmap_map *bitmap_buf;
5080
5081 if (!(bitmap_buf= (my_bitmap_map*) alloc_root(mem_root,
5082 bitmap_buffer_size(n_bits))) ||
5083 my_bitmap_init(map, bitmap_buf, n_bits, FALSE))
5084 return TRUE;
5085 bitmap_clear_all(map);
5086 return FALSE;
5087 }
5088
5089
5090 /**
5091 Create all structures needed for IN execution that can live between PS
5092 reexecution.
5093
5094 @param tmp_columns the items that produce the data for the temp table
5095 @param subquery_id subquery's identifier (to make "<subquery%d>" name for
5096 EXPLAIN)
5097
5098 @details
5099 - Create a temporary table to store the result of the IN subquery. The
5100 temporary table has one hash index on all its columns.
5101 - Create a new result sink that sends the result stream of the subquery to
5102 the temporary table,
5103
5104 @notice:
5105 Currently Item_subselect::init() already chooses and creates at parse
5106 time an engine with a corresponding JOIN to execute the subquery.
5107
5108 @retval TRUE if error
5109 @retval FALSE otherwise
5110 */
5111
init(List<Item> * tmp_columns,uint subquery_id)5112 bool subselect_hash_sj_engine::init(List<Item> *tmp_columns, uint subquery_id)
5113 {
5114 THD *thd= get_thd();
5115 select_unit *result_sink;
5116 /* Options to create_tmp_table. */
5117 ulonglong tmp_create_options= thd->variables.option_bits | TMP_TABLE_ALL_COLUMNS;
5118 /* | TMP_TABLE_FORCE_MYISAM; TIMOUR: force MYISAM */
5119
5120 DBUG_ENTER("subselect_hash_sj_engine::init");
5121
5122 if (my_bitmap_init_memroot(&non_null_key_parts, tmp_columns->elements,
5123 thd->mem_root) ||
5124 my_bitmap_init_memroot(&partial_match_key_parts, tmp_columns->elements,
5125 thd->mem_root))
5126 DBUG_RETURN(TRUE);
5127
5128 /*
5129 Create and initialize a select result interceptor that stores the
5130 result stream in a temporary table. The temporary table itself is
5131 managed (created/filled/etc) internally by the interceptor.
5132 */
5133 /*
5134 TIMOUR:
5135 Select a more efficient result sink when we know there is no need to collect
5136 data statistics.
5137
5138 if (strategy == COMPLETE_MATCH)
5139 {
5140 if (!(result= new select_union))
5141 DBUG_RETURN(TRUE);
5142 }
5143 else if (strategy == PARTIAL_MATCH)
5144 {
5145 if (!(result= new select_materialize_with_stats))
5146 DBUG_RETURN(TRUE);
5147 }
5148 */
5149 if (!(result_sink= new (thd->mem_root) select_materialize_with_stats(thd)))
5150 DBUG_RETURN(TRUE);
5151
5152 char buf[32];
5153 LEX_CSTRING name;
5154 name.length= my_snprintf(buf, sizeof(buf), "<subquery%u>", subquery_id);
5155 if (!(name.str= (char*) thd->memdup(buf, name.length + 1)))
5156 DBUG_RETURN(TRUE);
5157
5158 result_sink->get_tmp_table_param()->materialized_subquery= true;
5159
5160 if (item->substype() == Item_subselect::IN_SUBS &&
5161 (item->get_IN_subquery()->is_jtbm_merged))
5162 {
5163 result_sink->get_tmp_table_param()->force_not_null_cols= true;
5164 }
5165 if (result_sink->create_result_table(thd, tmp_columns, TRUE,
5166 tmp_create_options,
5167 &name, TRUE, TRUE, FALSE, 0))
5168 DBUG_RETURN(TRUE);
5169
5170 tmp_table= result_sink->table;
5171 result= result_sink;
5172
5173 /*
5174 If the subquery has blobs, or the total key length is bigger than
5175 some length, or the total number of key parts is more than the
5176 allowed maximum (currently MAX_REF_PARTS == 32), then the created
5177 index cannot be used for lookups and we can't use hash semi
5178 join. If this is the case, delete the temporary table since it
5179 will not be used, and tell the caller we failed to initialize the
5180 engine.
5181 */
5182 if (tmp_table->s->keys == 0)
5183 {
5184 //fprintf(stderr, "Q: %s\n", current_thd->query());
5185 DBUG_ASSERT(0);
5186 DBUG_ASSERT(
5187 tmp_table->s->uniques ||
5188 tmp_table->key_info->key_length >= tmp_table->file->max_key_length() ||
5189 tmp_table->key_info->user_defined_key_parts >
5190 tmp_table->file->max_key_parts());
5191 free_tmp_table(thd, tmp_table);
5192 tmp_table= NULL;
5193 delete result;
5194 result= NULL;
5195 DBUG_RETURN(TRUE);
5196 }
5197
5198 /*
5199 Make sure there is only one index on the temp table, and it doesn't have
5200 the extra key part created when s->uniques > 0.
5201
5202 NOTE: item have to be Item_in_subselect, because class constructor
5203 accept Item_in_subselect as the parmeter.
5204 */
5205 DBUG_ASSERT(tmp_table->s->keys == 1 &&
5206 item->get_IN_subquery()->left_expr->cols() ==
5207 tmp_table->key_info->user_defined_key_parts);
5208
5209 if (make_semi_join_conds() ||
5210 /* A unique_engine is used both for complete and partial matching. */
5211 !(lookup_engine= make_unique_engine()))
5212 DBUG_RETURN(TRUE);
5213
5214 /*
5215 Repeat name resolution for 'cond' since cond is not part of any
5216 clause of the query, and it is not 'fixed' during JOIN::prepare.
5217 */
5218 if (semi_join_conds &&
5219 semi_join_conds->fix_fields_if_needed(thd, (Item**)&semi_join_conds))
5220 DBUG_RETURN(TRUE);
5221 /* Let our engine reuse this query plan for materialization. */
5222 materialize_join= materialize_engine->join;
5223 materialize_join->change_result(result, NULL);
5224
5225 DBUG_RETURN(FALSE);
5226 }
5227
5228
5229 /*
5230 Create an artificial condition to post-filter those rows matched by index
5231 lookups that cannot be distinguished by the index lookup procedure.
5232
5233 @notes
5234 The need for post-filtering may occur e.g. because of
5235 truncation. Prepared statements execution requires that fix_fields is
5236 called for every execution. In order to call fix_fields we need to
5237 create a Name_resolution_context and a corresponding TABLE_LIST for
5238 the temporary table for the subquery, so that all column references
5239 to the materialized subquery table can be resolved correctly.
5240
5241 @returns
5242 @retval TRUE memory allocation error occurred
5243 @retval FALSE the conditions were created and resolved (fixed)
5244 */
5245
make_semi_join_conds()5246 bool subselect_hash_sj_engine::make_semi_join_conds()
5247 {
5248 /*
5249 Table reference for tmp_table that is used to resolve column references
5250 (Item_fields) to columns in tmp_table.
5251 */
5252 TABLE_LIST *tmp_table_ref;
5253 /* Name resolution context for all tmp_table columns created below. */
5254 Name_resolution_context *context;
5255 Item_in_subselect *item_in= item->get_IN_subquery();
5256 LEX_CSTRING table_name;
5257 DBUG_ENTER("subselect_hash_sj_engine::make_semi_join_conds");
5258 DBUG_ASSERT(semi_join_conds == NULL);
5259
5260 if (!(semi_join_conds= new (thd->mem_root) Item_cond_and(thd)))
5261 DBUG_RETURN(TRUE);
5262
5263 if (!(tmp_table_ref= (TABLE_LIST*) thd->alloc(sizeof(TABLE_LIST))))
5264 DBUG_RETURN(TRUE);
5265
5266 table_name.str= tmp_table->alias.c_ptr();
5267 table_name.length= tmp_table->alias.length(),
5268 tmp_table_ref->init_one_table(&empty_clex_str, &table_name, NULL, TL_READ);
5269 tmp_table_ref->table= tmp_table;
5270
5271 context= new Name_resolution_context;
5272 context->init();
5273 context->first_name_resolution_table=
5274 context->last_name_resolution_table= tmp_table_ref;
5275 semi_join_conds_context= context;
5276
5277 for (uint i= 0; i < item_in->left_expr->cols(); i++)
5278 {
5279 /* New equi-join condition for the current column. */
5280 Item_func_eq *eq_cond;
5281 /* Item for the corresponding field from the materialized temp table. */
5282 Item_field *right_col_item;
5283
5284 if (!(right_col_item= new (thd->mem_root)
5285 Item_temptable_field(thd, context, tmp_table->field[i])) ||
5286 !(eq_cond= new (thd->mem_root)
5287 Item_func_eq(thd, item_in->left_expr->element_index(i),
5288 right_col_item)) ||
5289 (((Item_cond_and*)semi_join_conds)->add(eq_cond, thd->mem_root)))
5290 {
5291 delete semi_join_conds;
5292 semi_join_conds= NULL;
5293 DBUG_RETURN(TRUE);
5294 }
5295 }
5296 if (semi_join_conds->fix_fields(thd, (Item**)&semi_join_conds))
5297 DBUG_RETURN(TRUE);
5298
5299 DBUG_RETURN(FALSE);
5300 }
5301
5302
5303 /**
5304 Create a new uniquesubquery engine for the execution of an IN predicate.
5305
5306 @details
5307 Create and initialize a new JOIN_TAB, and Table_ref objects to perform
5308 lookups into the indexed temporary table.
5309
5310 @retval A new subselect_hash_sj_engine object
5311 @retval NULL if a memory allocation error occurs
5312 */
5313
5314 subselect_uniquesubquery_engine*
make_unique_engine()5315 subselect_hash_sj_engine::make_unique_engine()
5316 {
5317 Item_in_subselect *item_in= item->get_IN_subquery();
5318 Item_iterator_row it(item_in->left_expr);
5319 /* The only index on the temporary table. */
5320 KEY *tmp_key= tmp_table->key_info;
5321 JOIN_TAB *tab;
5322
5323 DBUG_ENTER("subselect_hash_sj_engine::make_unique_engine");
5324
5325 /*
5326 Create and initialize the JOIN_TAB that represents an index lookup
5327 plan operator into the materialized subquery result. Notice that:
5328 - this JOIN_TAB has no corresponding JOIN (and doesn't need one), and
5329 - here we initialize only those members that are used by
5330 subselect_uniquesubquery_engine, so these objects are incomplete.
5331 */
5332 if (!(tab= (JOIN_TAB*) thd->alloc(sizeof(JOIN_TAB))))
5333 DBUG_RETURN(NULL);
5334
5335 tab->table= tmp_table;
5336 tab->preread_init_done= FALSE;
5337 tab->ref.tmp_table_index_lookup_init(thd, tmp_key, it, FALSE);
5338
5339 DBUG_RETURN(new subselect_uniquesubquery_engine(thd, tab, item_in,
5340 semi_join_conds));
5341 }
5342
5343
~subselect_hash_sj_engine()5344 subselect_hash_sj_engine::~subselect_hash_sj_engine()
5345 {
5346 delete lookup_engine;
5347 delete result;
5348 if (tmp_table)
5349 free_tmp_table(thd, tmp_table);
5350 }
5351
5352
prepare(THD * thd_arg)5353 int subselect_hash_sj_engine::prepare(THD *thd_arg)
5354 {
5355 /*
5356 Create and optimize the JOIN that will be used to materialize
5357 the subquery if not yet created.
5358 */
5359 set_thd(thd_arg);
5360 return materialize_engine->prepare(thd);
5361 }
5362
5363
5364 /**
5365 Cleanup performed after each PS execution.
5366
5367 @details
5368 Called in the end of JOIN::prepare for PS from Item_subselect::cleanup.
5369 */
5370
cleanup()5371 void subselect_hash_sj_engine::cleanup()
5372 {
5373 enum_engine_type lookup_engine_type= lookup_engine->engine_type();
5374 is_materialized= FALSE;
5375 bitmap_clear_all(&non_null_key_parts);
5376 bitmap_clear_all(&partial_match_key_parts);
5377 count_partial_match_columns= 0;
5378 count_null_only_columns= 0;
5379 strategy= UNDEFINED;
5380 materialize_engine->cleanup();
5381 /*
5382 Restore the original Item_in_subselect engine. This engine is created once
5383 at parse time and stored across executions, while all other materialization
5384 related engines are created and chosen for each execution.
5385 */
5386 item->get_IN_subquery()->engine= materialize_engine;
5387 if (lookup_engine_type == TABLE_SCAN_ENGINE ||
5388 lookup_engine_type == ROWID_MERGE_ENGINE)
5389 {
5390 subselect_engine *inner_lookup_engine;
5391 inner_lookup_engine=
5392 ((subselect_partial_match_engine*) lookup_engine)->lookup_engine;
5393 /*
5394 Partial match engines are recreated for each PS execution inside
5395 subselect_hash_sj_engine::exec().
5396 */
5397 delete lookup_engine;
5398 lookup_engine= inner_lookup_engine;
5399 }
5400 DBUG_ASSERT(lookup_engine->engine_type() == UNIQUESUBQUERY_ENGINE);
5401 lookup_engine->cleanup();
5402 result->cleanup(); /* Resets the temp table as well. */
5403 DBUG_ASSERT(tmp_table);
5404 free_tmp_table(thd, tmp_table);
5405 tmp_table= NULL;
5406 }
5407
5408
5409 /*
5410 Get fanout produced by tables specified in the table_map
5411 */
5412
get_fanout_with_deps(JOIN * join,table_map tset)5413 double get_fanout_with_deps(JOIN *join, table_map tset)
5414 {
5415 /* Handle the case of "Impossible WHERE" */
5416 if (join->table_count == 0)
5417 return 0.0;
5418
5419 /* First, recursively get all tables we depend on */
5420 table_map deps_to_check= tset;
5421 table_map checked_deps= 0;
5422 table_map further_deps;
5423 do
5424 {
5425 further_deps= 0;
5426 Table_map_iterator tm_it(deps_to_check);
5427 int tableno;
5428 while ((tableno = tm_it.next_bit()) != Table_map_iterator::BITMAP_END)
5429 {
5430 /* get tableno's dependency tables that are not in needed_set */
5431 further_deps |= join->map2table[tableno]->ref.depend_map & ~checked_deps;
5432 }
5433
5434 checked_deps |= deps_to_check;
5435 deps_to_check= further_deps;
5436 } while (further_deps != 0);
5437
5438
5439 /* Now, walk the join order and calculate the fanout */
5440 double fanout= 1;
5441 for (JOIN_TAB *tab= first_top_level_tab(join, WITHOUT_CONST_TABLES); tab;
5442 tab= next_top_level_tab(join, tab))
5443 {
5444 /*
5445 Ignore SJM nests. They have tab->table==NULL. There is no point to walk
5446 inside them, because GROUP BY clause cannot refer to tables from within
5447 subquery.
5448 */
5449 if (!tab->is_sjm_nest() && (tab->table->map & checked_deps) &&
5450 !tab->emb_sj_nest &&
5451 tab->records_read != 0)
5452 {
5453 fanout *= tab->records_read;
5454 }
5455 }
5456 return fanout;
5457 }
5458
5459
5460 #if 0
5461 void check_out_index_stats(JOIN *join)
5462 {
5463 ORDER *order;
5464 uint n_order_items;
5465
5466 /*
5467 First, collect the keys that we can use in each table.
5468 We can use a key if
5469 - all tables refer to it.
5470 */
5471 key_map key_start_use[MAX_TABLES];
5472 key_map key_infix_use[MAX_TABLES];
5473 table_map key_used=0;
5474 table_map non_key_used= 0;
5475
5476 bzero(&key_start_use, sizeof(key_start_use)); //psergey-todo: safe initialization!
5477 bzero(&key_infix_use, sizeof(key_infix_use));
5478
5479 for (order= join->group_list; order; order= order->next)
5480 {
5481 Item *item= order->item[0];
5482
5483 if (item->real_type() == Item::FIELD_ITEM)
5484 {
5485 if (item->used_tables() & OUTER_REF_TABLE_BIT)
5486 continue; /* outside references are like constants for us */
5487
5488 Field *field= ((Item_field*)item->real_item())->field;
5489 uint table_no= field->table->tablenr;
5490 if (!(non_key_used && table_map(1) << table_no) &&
5491 !field->part_of_key.is_clear_all())
5492 {
5493 key_map infix_map= field->part_of_key;
5494 infix_map.subtract(field->key_start);
5495 key_start_use[table_no].merge(field->key_start);
5496 key_infix_use[table_no].merge(infix_map);
5497 key_used |= table_no;
5498 }
5499 continue;
5500 }
5501 /*
5502 Note: the below will cause clauses like GROUP BY YEAR(date) not to be
5503 handled.
5504 */
5505 non_key_used |= item->used_tables();
5506 }
5507
5508 Table_map_iterator tm_it(key_used & ~non_key_used);
5509 int tableno;
5510 while ((tableno = tm_it.next_bit()) != Table_map_iterator::BITMAP_END)
5511 {
5512 key_map::iterator key_it(key_start_use);
5513 int keyno;
5514 while ((keyno = tm_it.next_bit()) != key_map::iterator::BITMAP_END)
5515 {
5516 for (order= join->group_list; order; order= order->next)
5517 {
5518 Item *item= order->item[0];
5519 if (item->used_tables() & (table_map(1) << tableno))
5520 {
5521 DBUG_ASSERT(item->real_type() == Item::FIELD_ITEM);
5522 }
5523 }
5524 /*
5525 if (continuation)
5526 {
5527 walk through list and find which key parts are occupied;
5528 // note that the above can't be made any faster.
5529 }
5530 else
5531 use rec_per_key[0];
5532
5533 find out the cardinality.
5534 check if cardinality decreases if we use it;
5535 */
5536 }
5537 }
5538 }
5539 #endif
5540
5541
5542 /*
5543 Get an estimate of how many records will be produced after the GROUP BY
5544 operation.
5545
5546 @param join Join we're operating on
5547 @param join_op_rows How many records will be produced by the join
5548 operations (this is what join optimizer produces)
5549
5550 @seealso
5551 See also optimize_semijoin_nests(), grep for "Adjust output cardinality
5552 estimates". Very similar code there that is not joined with this one
5553 because we operate on different data structs and too much effort is
5554 needed to abstract them out.
5555
5556 @return
5557 Number of records we expect to get after the GROUP BY operation
5558 */
5559
get_post_group_estimate(JOIN * join,double join_op_rows)5560 double get_post_group_estimate(JOIN* join, double join_op_rows)
5561 {
5562 table_map tables_in_group_list= table_map(0);
5563
5564 /* Find out which tables are used in GROUP BY list */
5565 for (ORDER *order= join->group_list_for_estimates; order; order= order->next)
5566 {
5567 Item *item= order->item[0];
5568 table_map item_used_tables= item->used_tables();
5569 if (item_used_tables & RAND_TABLE_BIT)
5570 {
5571 /* Each join output record will be in its own group */
5572 return join_op_rows;
5573 }
5574 tables_in_group_list|= item_used_tables;
5575 }
5576 tables_in_group_list &= ~PSEUDO_TABLE_BITS;
5577
5578 /*
5579 Use join fanouts to calculate the max. number of records in the group-list
5580 */
5581 double fanout_rows[MAX_KEY];
5582 bzero(&fanout_rows, sizeof(fanout_rows));
5583 double out_rows;
5584
5585 out_rows= get_fanout_with_deps(join, tables_in_group_list);
5586
5587 #if 0
5588 /* The following will be needed when making use of index stats: */
5589 /*
5590 Also generate max. number of records for each of the tables mentioned
5591 in the group-list. We'll use that a baseline number that we'll try to
5592 reduce by using
5593 - #table-records
5594 - index statistics.
5595 */
5596 Table_map_iterator tm_it(tables_in_group_list);
5597 int tableno;
5598 while ((tableno = tm_it.next_bit()) != Table_map_iterator::BITMAP_END)
5599 {
5600 fanout_rows[tableno]= get_fanout_with_deps(join, table_map(1) << tableno);
5601 }
5602
5603 /*
5604 Try to bring down estimates using index statistics.
5605 */
5606 //check_out_index_stats(join);
5607 #endif
5608
5609 return out_rows;
5610 }
5611
5612
5613 /**
5614 Execute a subquery IN predicate via materialization.
5615
5616 @details
5617 If needed materialize the subquery into a temporary table, then
5618 copmpute the predicate via a lookup into this table.
5619
5620 @retval TRUE if error
5621 @retval FALSE otherwise
5622 */
5623
exec()5624 int subselect_hash_sj_engine::exec()
5625 {
5626 Item_in_subselect *item_in= item->get_IN_subquery();
5627 SELECT_LEX *save_select= thd->lex->current_select;
5628 subselect_partial_match_engine *pm_engine= NULL;
5629 int res= 0;
5630
5631 DBUG_ENTER("subselect_hash_sj_engine::exec");
5632
5633 /*
5634 Optimize and materialize the subquery during the first execution of
5635 the subquery predicate.
5636 */
5637 thd->lex->current_select= materialize_engine->select_lex;
5638 /* The subquery should be optimized, and materialized only once. */
5639 DBUG_ASSERT(materialize_join->optimization_state == JOIN::OPTIMIZATION_DONE &&
5640 !is_materialized);
5641 materialize_join->exec();
5642 if (unlikely((res= MY_TEST(materialize_join->error || thd->is_fatal_error ||
5643 thd->is_error()))))
5644 goto err;
5645
5646 /*
5647 TODO:
5648 - Unlock all subquery tables as we don't need them. To implement this
5649 we need to add new functionality to JOIN::join_free that can unlock
5650 all tables in a subquery (and all its subqueries).
5651 - The temp table used for grouping in the subquery can be freed
5652 immediately after materialization (yet it's done together with
5653 unlocking).
5654 */
5655 is_materialized= TRUE;
5656 /*
5657 If the subquery returned no rows, the temporary table is empty, so we know
5658 directly that the result of IN is FALSE. We first update the table
5659 statistics, then we test if the temporary table for the query result is
5660 empty.
5661 */
5662 tmp_table->file->info(HA_STATUS_VARIABLE);
5663 if (!tmp_table->file->stats.records)
5664 {
5665 /* The value of IN will not change during this execution. */
5666 item_in->reset();
5667 item_in->make_const();
5668 item_in->set_first_execution();
5669 thd->lex->current_select= save_select;
5670 DBUG_RETURN(FALSE);
5671 }
5672
5673 /*
5674 TIMOUR: The schema-based analysis for partial matching can be done once for
5675 prepared statement and remembered. It is done here to remove the need to
5676 save/restore all related variables between each re-execution, thus making
5677 the code simpler.
5678 */
5679 strategy= get_strategy_using_schema();
5680 /* This call may discover that we don't need partial matching at all. */
5681 strategy= get_strategy_using_data();
5682 if (strategy == PARTIAL_MATCH)
5683 {
5684 uint count_pm_keys; /* Total number of keys needed for partial matching. */
5685 MY_BITMAP *nn_key_parts= NULL; /* Key parts of the only non-NULL index. */
5686 uint count_non_null_columns= 0; /* Number of columns in nn_key_parts. */
5687 bool has_covering_null_row;
5688 bool has_covering_null_columns;
5689 select_materialize_with_stats *result_sink=
5690 (select_materialize_with_stats *) result;
5691 uint field_count= tmp_table->s->fields;
5692
5693 if (count_partial_match_columns < field_count)
5694 {
5695 nn_key_parts= &non_null_key_parts;
5696 count_non_null_columns= bitmap_bits_set(nn_key_parts);
5697 }
5698 has_covering_null_row= (result_sink->get_max_nulls_in_row() == field_count);
5699 has_covering_null_columns= (count_non_null_columns +
5700 count_null_only_columns == field_count);
5701
5702 if (has_covering_null_row && has_covering_null_columns)
5703 {
5704 /*
5705 The whole table consist of only NULL values. The result of IN is
5706 a constant UNKNOWN.
5707 */
5708 DBUG_ASSERT(tmp_table->file->stats.records == 1);
5709 item_in->value= 0;
5710 item_in->null_value= 1;
5711 item_in->make_const();
5712 item_in->set_first_execution();
5713 thd->lex->current_select= save_select;
5714 DBUG_RETURN(FALSE);
5715 }
5716
5717 if (has_covering_null_row)
5718 {
5719 DBUG_ASSERT(count_partial_match_columns == field_count);
5720 count_pm_keys= 0;
5721 }
5722 else if (has_covering_null_columns)
5723 count_pm_keys= 1;
5724 else
5725 count_pm_keys= count_partial_match_columns - count_null_only_columns +
5726 (nn_key_parts ? 1 : 0);
5727
5728 choose_partial_match_strategy(MY_TEST(nn_key_parts),
5729 has_covering_null_row,
5730 &partial_match_key_parts);
5731 DBUG_ASSERT(strategy == PARTIAL_MATCH_MERGE ||
5732 strategy == PARTIAL_MATCH_SCAN);
5733 if (strategy == PARTIAL_MATCH_MERGE)
5734 {
5735 pm_engine=
5736 new subselect_rowid_merge_engine((subselect_uniquesubquery_engine*)
5737 lookup_engine, tmp_table,
5738 count_pm_keys,
5739 has_covering_null_row,
5740 has_covering_null_columns,
5741 count_columns_with_nulls,
5742 item, result,
5743 semi_join_conds->argument_list());
5744 if (!pm_engine ||
5745 pm_engine->prepare(thd) ||
5746 ((subselect_rowid_merge_engine*) pm_engine)->
5747 init(nn_key_parts, &partial_match_key_parts))
5748 {
5749 /*
5750 The call to init() would fail if there was not enough memory to allocate
5751 all buffers for the rowid merge strategy. In this case revert to table
5752 scanning which doesn't need any big buffers.
5753 */
5754 delete pm_engine;
5755 pm_engine= NULL;
5756 strategy= PARTIAL_MATCH_SCAN;
5757 }
5758 }
5759
5760 if (strategy == PARTIAL_MATCH_SCAN)
5761 {
5762 if (!(pm_engine=
5763 new subselect_table_scan_engine((subselect_uniquesubquery_engine*)
5764 lookup_engine, tmp_table,
5765 item, result,
5766 semi_join_conds->argument_list(),
5767 has_covering_null_row,
5768 has_covering_null_columns,
5769 count_columns_with_nulls)) ||
5770 pm_engine->prepare(thd))
5771 {
5772 /* This is an irrecoverable error. */
5773 res= 1;
5774 goto err;
5775 }
5776 }
5777 }
5778
5779 if (pm_engine)
5780 lookup_engine= pm_engine;
5781 item_in->change_engine(lookup_engine);
5782
5783 err:
5784 thd->lex->current_select= save_select;
5785 DBUG_RETURN(res);
5786 }
5787
5788
5789 /**
5790 Print the state of this engine into a string for debugging and views.
5791 */
5792
print(String * str,enum_query_type query_type)5793 void subselect_hash_sj_engine::print(String *str, enum_query_type query_type)
5794 {
5795 str->append(STRING_WITH_LEN(" <materialize> ("));
5796 materialize_engine->print(str, query_type);
5797 str->append(STRING_WITH_LEN(" ), "));
5798
5799 if (lookup_engine)
5800 lookup_engine->print(str, query_type);
5801 else
5802 str->append(STRING_WITH_LEN(
5803 "<engine selected at execution time>"
5804 ));
5805 }
5806
fix_length_and_dec(Item_cache ** row)5807 bool subselect_hash_sj_engine::fix_length_and_dec(Item_cache** row)
5808 {
5809 DBUG_ASSERT(FALSE);
5810 return FALSE;
5811 }
5812
exclude()5813 void subselect_hash_sj_engine::exclude()
5814 {
5815 DBUG_ASSERT(FALSE);
5816 }
5817
no_tables()5818 bool subselect_hash_sj_engine::no_tables()
5819 {
5820 DBUG_ASSERT(FALSE);
5821 return FALSE;
5822 }
5823
change_result(Item_subselect * si,select_result_interceptor * res,bool temp)5824 bool subselect_hash_sj_engine::change_result(Item_subselect *si,
5825 select_result_interceptor *res,
5826 bool temp __attribute__((unused)))
5827 {
5828 DBUG_ASSERT(FALSE);
5829 return TRUE;
5830 }
5831
5832
Ordered_key(uint keyid_arg,TABLE * tbl_arg,Item * search_key_arg,ha_rows null_count_arg,ha_rows min_null_row_arg,ha_rows max_null_row_arg,uchar * row_num_to_rowid_arg)5833 Ordered_key::Ordered_key(uint keyid_arg, TABLE *tbl_arg, Item *search_key_arg,
5834 ha_rows null_count_arg, ha_rows min_null_row_arg,
5835 ha_rows max_null_row_arg, uchar *row_num_to_rowid_arg)
5836 : keyid(keyid_arg), tbl(tbl_arg), search_key(search_key_arg),
5837 row_num_to_rowid(row_num_to_rowid_arg), null_count(null_count_arg)
5838 {
5839 DBUG_ASSERT(tbl->file->stats.records > null_count);
5840 key_buff_elements= tbl->file->stats.records - null_count;
5841 cur_key_idx= HA_POS_ERROR;
5842
5843 DBUG_ASSERT((null_count && min_null_row_arg && max_null_row_arg) ||
5844 (!null_count && !min_null_row_arg && !max_null_row_arg));
5845 if (null_count)
5846 {
5847 /* The counters are 1-based, for key access we need 0-based indexes. */
5848 min_null_row= min_null_row_arg - 1;
5849 max_null_row= max_null_row_arg - 1;
5850 }
5851 else
5852 min_null_row= max_null_row= 0;
5853 }
5854
5855
~Ordered_key()5856 Ordered_key::~Ordered_key()
5857 {
5858 my_free(key_buff);
5859 my_bitmap_free(&null_key);
5860 }
5861
5862
5863 /*
5864 Cleanup that needs to be done for each PS (re)execution.
5865 */
5866
cleanup()5867 void Ordered_key::cleanup()
5868 {
5869 /*
5870 Currently these keys are recreated for each PS re-execution, thus
5871 there is nothing to cleanup, the whole object goes away after execution
5872 is over. All handler related initialization/deinitialization is done by
5873 the parent subselect_rowid_merge_engine object.
5874 */
5875 }
5876
5877
5878 /*
5879 Initialize a multi-column index.
5880 */
5881
init(MY_BITMAP * columns_to_index)5882 bool Ordered_key::init(MY_BITMAP *columns_to_index)
5883 {
5884 THD *thd= tbl->in_use;
5885 uint cur_key_col= 0;
5886 Item_field *cur_tmp_field;
5887 Item_func_lt *fn_less_than;
5888
5889 key_column_count= bitmap_bits_set(columns_to_index);
5890 key_columns= (Item_field**) thd->alloc(key_column_count *
5891 sizeof(Item_field*));
5892 compare_pred= (Item_func_lt**) thd->alloc(key_column_count *
5893 sizeof(Item_func_lt*));
5894
5895 if (!key_columns || !compare_pred)
5896 return TRUE; /* Revert to table scan partial match. */
5897
5898 for (uint i= 0; i < columns_to_index->n_bits; i++)
5899 {
5900 if (!bitmap_is_set(columns_to_index, i))
5901 continue;
5902 cur_tmp_field= new (thd->mem_root) Item_field(thd, tbl->field[i]);
5903 /* Create the predicate (tmp_column[i] < outer_ref[i]). */
5904 fn_less_than= new (thd->mem_root) Item_func_lt(thd, cur_tmp_field,
5905 search_key->element_index(i));
5906 fn_less_than->fix_fields(thd, (Item**) &fn_less_than);
5907 key_columns[cur_key_col]= cur_tmp_field;
5908 compare_pred[cur_key_col]= fn_less_than;
5909 ++cur_key_col;
5910 }
5911
5912 if (alloc_keys_buffers())
5913 {
5914 /* TIMOUR revert to partial match via table scan. */
5915 return TRUE;
5916 }
5917 return FALSE;
5918 }
5919
5920
5921 /*
5922 Initialize a single-column index.
5923 */
5924
init(int col_idx)5925 bool Ordered_key::init(int col_idx)
5926 {
5927 THD *thd= tbl->in_use;
5928
5929 key_column_count= 1;
5930
5931 // TIMOUR: check for mem allocation err, revert to scan
5932
5933 key_columns= (Item_field**) thd->alloc(sizeof(Item_field*));
5934 compare_pred= (Item_func_lt**) thd->alloc(sizeof(Item_func_lt*));
5935
5936 key_columns[0]= new (thd->mem_root) Item_field(thd, tbl->field[col_idx]);
5937 /* Create the predicate (tmp_column[i] < outer_ref[i]). */
5938 compare_pred[0]= new (thd->mem_root) Item_func_lt(thd, key_columns[0],
5939 search_key->element_index(col_idx));
5940 compare_pred[0]->fix_fields(thd, (Item**)&compare_pred[0]);
5941
5942 if (alloc_keys_buffers())
5943 {
5944 /* TIMOUR revert to partial match via table scan. */
5945 return TRUE;
5946 }
5947 return FALSE;
5948 }
5949
5950
5951 /*
5952 Allocate the buffers for both the row number, and the NULL-bitmap indexes.
5953 */
5954
alloc_keys_buffers()5955 bool Ordered_key::alloc_keys_buffers()
5956 {
5957 DBUG_ASSERT(key_buff_elements > 0);
5958
5959 if (!(key_buff= (rownum_t*) my_malloc(PSI_INSTRUMENT_ME,
5960 static_cast<size_t>(key_buff_elements * sizeof(rownum_t)),
5961 MYF(MY_WME | MY_THREAD_SPECIFIC))))
5962 return TRUE;
5963
5964 /*
5965 TIMOUR: it is enough to create bitmaps with size
5966 (max_null_row - min_null_row), and then use min_null_row as
5967 lookup offset.
5968 */
5969 /* Notice that max_null_row is max array index, we need count, so +1. */
5970 if (my_bitmap_init(&null_key, NULL, (uint)(max_null_row + 1), FALSE))
5971 return TRUE;
5972
5973 cur_key_idx= HA_POS_ERROR;
5974
5975 return FALSE;
5976 }
5977
5978
5979 /*
5980 Quick sort comparison function that compares two rows of the same table
5981 indentfied with their row numbers.
5982
5983 @retval -1
5984 @retval 0
5985 @retval +1
5986 */
5987
5988 int
cmp_keys_by_row_data(ha_rows a,ha_rows b)5989 Ordered_key::cmp_keys_by_row_data(ha_rows a, ha_rows b)
5990 {
5991 uchar *rowid_a, *rowid_b;
5992 int error;
5993 int cmp_res;
5994 /* The length in bytes of the rowids (positions) of tmp_table. */
5995 uint rowid_length= tbl->file->ref_length;
5996
5997 if (a == b)
5998 return 0;
5999 /* Get the corresponding rowids. */
6000 rowid_a= row_num_to_rowid + a * rowid_length;
6001 rowid_b= row_num_to_rowid + b * rowid_length;
6002 /* Fetch the rows for comparison. */
6003 if (unlikely((error= tbl->file->ha_rnd_pos(tbl->record[0], rowid_a))))
6004 {
6005 /* purecov: begin inspected */
6006 tbl->file->print_error(error, MYF(ME_FATAL)); // Sets fatal_error
6007 return 0;
6008 /* purecov: end */
6009 }
6010 if (unlikely((error= tbl->file->ha_rnd_pos(tbl->record[1], rowid_b))))
6011 {
6012 /* purecov: begin inspected */
6013 tbl->file->print_error(error, MYF(ME_FATAL)); // Sets fatal_error
6014 return 0;
6015 /* purecov: end */
6016 }
6017 /*
6018 Compare the two rows by the corresponding values of the indexed
6019 columns.
6020 */
6021 for (uint i= 0; i < key_column_count; i++)
6022 {
6023 Field *cur_field= key_columns[i]->field;
6024 if ((cmp_res= cur_field->cmp_offset(tbl->s->rec_buff_length)))
6025 return (cmp_res > 0 ? 1 : -1);
6026 }
6027 return 0;
6028 }
6029
6030
6031 int
cmp_keys_by_row_data_and_rownum(Ordered_key * key,rownum_t * a,rownum_t * b)6032 Ordered_key::cmp_keys_by_row_data_and_rownum(Ordered_key *key,
6033 rownum_t* a, rownum_t* b)
6034 {
6035 /* The result of comparing the two keys according to their row data. */
6036 int cmp_row_res= key->cmp_keys_by_row_data(*a, *b);
6037 if (cmp_row_res)
6038 return cmp_row_res;
6039 return (*a < *b) ? -1 : (*a > *b) ? 1 : 0;
6040 }
6041
6042
sort_keys()6043 bool Ordered_key::sort_keys()
6044 {
6045 if (tbl->file->ha_rnd_init_with_error(0))
6046 return TRUE;
6047 my_qsort2(key_buff, (size_t) key_buff_elements, sizeof(rownum_t),
6048 (qsort2_cmp) &cmp_keys_by_row_data_and_rownum, (void*) this);
6049 /* Invalidate the current row position. */
6050 cur_key_idx= HA_POS_ERROR;
6051 tbl->file->ha_rnd_end();
6052 return FALSE;
6053 }
6054
6055
6056 /*
6057 The fraction of rows that do not contain NULL in the columns indexed by
6058 this key.
6059
6060 @retval 1 if there are no NULLs
6061 @retval 0 if only NULLs
6062 */
6063
null_selectivity()6064 double Ordered_key::null_selectivity()
6065 {
6066 /* We should not be processing empty tables. */
6067 DBUG_ASSERT(tbl->file->stats.records);
6068 return (1 - (double) null_count / (double) tbl->file->stats.records);
6069 }
6070
6071
6072 /*
6073 Compare the value(s) of the current key in 'search_key' with the
6074 data of the current table record.
6075
6076 @notes The comparison result follows from the way compare_pred
6077 is created in Ordered_key::init. Currently compare_pred compares
6078 a field in of the current row with the corresponding Item that
6079 contains the search key.
6080
6081 @param row_num Number of the row (not index in the key_buff array)
6082
6083 @retval -1 if (current row < search_key)
6084 @retval 0 if (current row == search_key)
6085 @retval +1 if (current row > search_key)
6086 */
6087
cmp_key_with_search_key(rownum_t row_num)6088 int Ordered_key::cmp_key_with_search_key(rownum_t row_num)
6089 {
6090 /* The length in bytes of the rowids (positions) of tmp_table. */
6091 uint rowid_length= tbl->file->ref_length;
6092 uchar *cur_rowid= row_num_to_rowid + row_num * rowid_length;
6093 int error;
6094 int cmp_res;
6095
6096 if (unlikely((error= tbl->file->ha_rnd_pos(tbl->record[0], cur_rowid))))
6097 {
6098 /* purecov: begin inspected */
6099 tbl->file->print_error(error, MYF(ME_FATAL)); // Sets fatal_error
6100 return 0;
6101 /* purecov: end */
6102 }
6103
6104 for (uint i= 0; i < key_column_count; i++)
6105 {
6106 cmp_res= compare_pred[i]->get_comparator()->compare();
6107 /* Unlike Arg_comparator::compare_row() here there should be no NULLs. */
6108 DBUG_ASSERT(!compare_pred[i]->null_value);
6109 if (cmp_res)
6110 return (cmp_res > 0 ? 1 : -1);
6111 }
6112 return 0;
6113 }
6114
6115
6116 /*
6117 Find a key in a sorted array of keys via binary search.
6118
6119 see create_subq_in_equalities()
6120 */
6121
lookup()6122 bool Ordered_key::lookup()
6123 {
6124 DBUG_ASSERT(key_buff_elements);
6125
6126 ha_rows lo= 0;
6127 ha_rows hi= key_buff_elements - 1;
6128 ha_rows mid;
6129 int cmp_res;
6130
6131 while (lo <= hi)
6132 {
6133 mid= lo + (hi - lo) / 2;
6134 cmp_res= cmp_key_with_search_key(key_buff[mid]);
6135 /*
6136 In order to find the minimum match, check if the pevious element is
6137 equal or smaller than the found one. If equal, we need to search further
6138 to the left.
6139 */
6140 if (!cmp_res && mid > 0)
6141 cmp_res= !cmp_key_with_search_key(key_buff[mid - 1]) ? 1 : 0;
6142
6143 if (cmp_res == -1)
6144 {
6145 /* row[mid] < search_key */
6146 lo= mid + 1;
6147 }
6148 else if (cmp_res == 1)
6149 {
6150 /* row[mid] > search_key */
6151 if (!mid)
6152 goto not_found;
6153 hi= mid - 1;
6154 }
6155 else
6156 {
6157 /* row[mid] == search_key */
6158 cur_key_idx= mid;
6159 return TRUE;
6160 }
6161 }
6162 not_found:
6163 cur_key_idx= HA_POS_ERROR;
6164 return FALSE;
6165 }
6166
6167
6168 /*
6169 Move the current index pointer to the next key with the same column
6170 values as the current key. Since the index is sorted, all such keys
6171 are contiguous.
6172 */
6173
next_same()6174 bool Ordered_key::next_same()
6175 {
6176 DBUG_ASSERT(key_buff_elements);
6177
6178 if (cur_key_idx < key_buff_elements - 1)
6179 {
6180 /*
6181 TIMOUR:
6182 The below is quite inefficient, since as a result we will fetch every
6183 row (except the last one) twice. There must be a more efficient way,
6184 e.g. swapping record[0] and record[1], and reading only the new record.
6185 */
6186 if (!cmp_keys_by_row_data(key_buff[cur_key_idx], key_buff[cur_key_idx + 1]))
6187 {
6188 ++cur_key_idx;
6189 return TRUE;
6190 }
6191 }
6192 return FALSE;
6193 }
6194
6195
print(String * str)6196 void Ordered_key::print(String *str)
6197 {
6198 uint i;
6199 str->append("{idx=");
6200 str->qs_append(keyid);
6201 str->append(", (");
6202 for (i= 0; i < key_column_count - 1; i++)
6203 {
6204 str->append(&key_columns[i]->field->field_name);
6205 str->append(", ");
6206 }
6207 str->append(&key_columns[i]->field->field_name);
6208 str->append("), ");
6209
6210 str->append("null_bitmap: (bits=");
6211 str->qs_append(null_key.n_bits);
6212 str->append(", nulls= ");
6213 str->qs_append((double)null_count);
6214 str->append(", min_null= ");
6215 str->qs_append((double)min_null_row);
6216 str->append(", max_null= ");
6217 str->qs_append((double)max_null_row);
6218 str->append("), ");
6219
6220 str->append('}');
6221 }
6222
6223
subselect_partial_match_engine(subselect_uniquesubquery_engine * engine_arg,TABLE * tmp_table_arg,Item_subselect * item_arg,select_result_interceptor * result_arg,List<Item> * equi_join_conds_arg,bool has_covering_null_row_arg,bool has_covering_null_columns_arg,uint count_columns_with_nulls_arg)6224 subselect_partial_match_engine::subselect_partial_match_engine(
6225 subselect_uniquesubquery_engine *engine_arg,
6226 TABLE *tmp_table_arg, Item_subselect *item_arg,
6227 select_result_interceptor *result_arg,
6228 List<Item> *equi_join_conds_arg,
6229 bool has_covering_null_row_arg,
6230 bool has_covering_null_columns_arg,
6231 uint count_columns_with_nulls_arg)
6232 :subselect_engine(item_arg, result_arg),
6233 tmp_table(tmp_table_arg), lookup_engine(engine_arg),
6234 equi_join_conds(equi_join_conds_arg),
6235 has_covering_null_row(has_covering_null_row_arg),
6236 has_covering_null_columns(has_covering_null_columns_arg),
6237 count_columns_with_nulls(count_columns_with_nulls_arg)
6238 {}
6239
6240
exec()6241 int subselect_partial_match_engine::exec()
6242 {
6243 Item_in_subselect *item_in= item->get_IN_subquery();
6244 int lookup_res;
6245
6246 DBUG_ASSERT(!(item_in->left_expr_has_null() &&
6247 item_in->is_top_level_item()));
6248
6249 if (!item_in->left_expr_has_null())
6250 {
6251 /* Try to find a matching row by index lookup. */
6252 if (lookup_engine->copy_ref_key(false))
6253 {
6254 /* The result is FALSE based on the outer reference. */
6255 item_in->value= 0;
6256 item_in->null_value= 0;
6257 return 0;
6258 }
6259 else
6260 {
6261 /* Search for a complete match. */
6262 if ((lookup_res= lookup_engine->index_lookup()))
6263 {
6264 /* An error occurred during lookup(). */
6265 item_in->value= 0;
6266 item_in->null_value= 0;
6267 return lookup_res;
6268 }
6269 else if (item_in->value || !count_columns_with_nulls)
6270 {
6271 /*
6272 A complete match was found, the result of IN is TRUE.
6273 If no match was found, and there are no NULLs in the materialized
6274 subquery, then the result is guaranteed to be false because this
6275 branch is executed when the outer reference has no NULLs as well.
6276 Notice: (this->item == lookup_engine->item)
6277 */
6278 return 0;
6279 }
6280 }
6281 }
6282
6283 if (has_covering_null_row)
6284 {
6285 /*
6286 If there is a NULL-only row that covers all columns the result of IN
6287 is UNKNOWN.
6288 */
6289 item_in->value= 0;
6290 /*
6291 TIMOUR: which one is the right way to propagate an UNKNOWN result?
6292 Should we also set empty_result_set= FALSE; ???
6293 */
6294 //item_in->was_null= 1;
6295 item_in->null_value= 1;
6296 return 0;
6297 }
6298
6299 /*
6300 There is no complete match. Look for a partial match (UNKNOWN result), or
6301 no match (FALSE).
6302 */
6303 if (tmp_table->file->inited)
6304 tmp_table->file->ha_index_end();
6305
6306 if (partial_match())
6307 {
6308 /* The result of IN is UNKNOWN. */
6309 item_in->value= 0;
6310 /*
6311 TIMOUR: which one is the right way to propagate an UNKNOWN result?
6312 Should we also set empty_result_set= FALSE; ???
6313 */
6314 //item_in->was_null= 1;
6315 item_in->null_value= 1;
6316 }
6317 else
6318 {
6319 /* The result of IN is FALSE. */
6320 item_in->value= 0;
6321 /*
6322 TIMOUR: which one is the right way to propagate an UNKNOWN result?
6323 Should we also set empty_result_set= FALSE; ???
6324 */
6325 //item_in->was_null= 0;
6326 item_in->null_value= 0;
6327 }
6328
6329 return 0;
6330 }
6331
6332
print(String * str,enum_query_type query_type)6333 void subselect_partial_match_engine::print(String *str,
6334 enum_query_type query_type)
6335 {
6336 /*
6337 Should never be called as the actual engine cannot be known at query
6338 optimization time.
6339 DBUG_ASSERT(FALSE);
6340 */
6341 }
6342
6343
6344 /*
6345 @param non_null_key_parts
6346 @param partial_match_key_parts A union of all single-column NULL key parts.
6347
6348 @retval FALSE the engine was initialized successfully
6349 @retval TRUE there was some (memory allocation) error during initialization,
6350 such errors should be interpreted as revert to other strategy
6351 */
6352
6353 bool
init(MY_BITMAP * non_null_key_parts,MY_BITMAP * partial_match_key_parts)6354 subselect_rowid_merge_engine::init(MY_BITMAP *non_null_key_parts,
6355 MY_BITMAP *partial_match_key_parts)
6356 {
6357 THD *thd= get_thd();
6358 /* The length in bytes of the rowids (positions) of tmp_table. */
6359 uint rowid_length= tmp_table->file->ref_length;
6360 ha_rows row_count= tmp_table->file->stats.records;
6361 rownum_t cur_rownum= 0;
6362 select_materialize_with_stats *result_sink=
6363 (select_materialize_with_stats *) result;
6364 uint cur_keyid= 0;
6365 Item *left= item->get_IN_subquery()->left_exp();
6366 int error;
6367
6368 if (merge_keys_count == 0)
6369 {
6370 DBUG_ASSERT(bitmap_bits_set(partial_match_key_parts) == 0 ||
6371 has_covering_null_row);
6372 /* There is nothing to initialize, we will only do regular lookups. */
6373 return FALSE;
6374 }
6375
6376 /*
6377 If all nullable columns contain only NULLs, there must be one index
6378 over all non-null columns.
6379 */
6380 DBUG_ASSERT(!has_covering_null_columns ||
6381 (has_covering_null_columns &&
6382 merge_keys_count == 1 && non_null_key_parts));
6383 /*
6384 Allocate buffers to hold the merged keys and the mapping between rowids and
6385 row numbers. All small buffers are allocated in the runtime memroot. Big
6386 buffers are allocated from the OS via malloc.
6387 */
6388 if (!(merge_keys= (Ordered_key**) thd->alloc(merge_keys_count *
6389 sizeof(Ordered_key*))) ||
6390 !(null_bitmaps= (MY_BITMAP**) thd->alloc(merge_keys_count *
6391 sizeof(MY_BITMAP*))) ||
6392 !(row_num_to_rowid= (uchar*) my_malloc(PSI_INSTRUMENT_ME,
6393 static_cast<size_t>(row_count * rowid_length),
6394 MYF(MY_WME | MY_THREAD_SPECIFIC))))
6395 return TRUE;
6396
6397 /* Create the only non-NULL key if there is any. */
6398 if (non_null_key_parts)
6399 {
6400 non_null_key= new Ordered_key(cur_keyid, tmp_table, left,
6401 0, 0, 0, row_num_to_rowid);
6402 if (non_null_key->init(non_null_key_parts))
6403 return TRUE;
6404 merge_keys[cur_keyid]= non_null_key;
6405 merge_keys[cur_keyid]->first();
6406 ++cur_keyid;
6407 }
6408
6409 /*
6410 If all nullable columns contain NULLs, the only key that is needed is the
6411 only non-NULL key that is already created above.
6412 */
6413 if (!has_covering_null_columns)
6414 {
6415 if (my_bitmap_init_memroot(&matching_keys, merge_keys_count, thd->mem_root) ||
6416 my_bitmap_init_memroot(&matching_outer_cols, merge_keys_count, thd->mem_root))
6417 return TRUE;
6418
6419 /*
6420 Create one single-column NULL-key for each column in
6421 partial_match_key_parts.
6422 */
6423 for (uint i= 0; i < partial_match_key_parts->n_bits; i++)
6424 {
6425 /* Skip columns that have no NULLs, or contain only NULLs. */
6426 if (!bitmap_is_set(partial_match_key_parts, i) ||
6427 result_sink->get_null_count_of_col(i) == row_count)
6428 continue;
6429
6430 merge_keys[cur_keyid]= new Ordered_key(
6431 cur_keyid, tmp_table,
6432 left->element_index(i),
6433 result_sink->get_null_count_of_col(i),
6434 result_sink->get_min_null_of_col(i),
6435 result_sink->get_max_null_of_col(i),
6436 row_num_to_rowid);
6437 if (merge_keys[cur_keyid]->init(i))
6438 return TRUE;
6439 merge_keys[cur_keyid]->first();
6440 ++cur_keyid;
6441 }
6442 }
6443 DBUG_ASSERT(cur_keyid == merge_keys_count);
6444
6445 /* Populate the indexes with data from the temporary table. */
6446 if (unlikely(tmp_table->file->ha_rnd_init_with_error(1)))
6447 return TRUE;
6448 tmp_table->file->extra_opt(HA_EXTRA_CACHE,
6449 current_thd->variables.read_buff_size);
6450 tmp_table->null_row= 0;
6451 while (TRUE)
6452 {
6453 error= tmp_table->file->ha_rnd_next(tmp_table->record[0]);
6454
6455 if (error == HA_ERR_ABORTED_BY_USER)
6456 break;
6457 /*
6458 This is a temp table that we fully own, there should be no other
6459 cause to stop the iteration than EOF.
6460 */
6461 DBUG_ASSERT(!error || error == HA_ERR_END_OF_FILE);
6462 if (unlikely(error == HA_ERR_END_OF_FILE))
6463 {
6464 DBUG_ASSERT(cur_rownum == tmp_table->file->stats.records);
6465 break;
6466 }
6467
6468 /*
6469 Save the position of this record in the row_num -> rowid mapping.
6470 */
6471 tmp_table->file->position(tmp_table->record[0]);
6472 memcpy(row_num_to_rowid + cur_rownum * rowid_length,
6473 tmp_table->file->ref, rowid_length);
6474
6475 /* Add the current row number to the corresponding keys. */
6476 if (non_null_key)
6477 {
6478 /* By definition there are no NULLs in the non-NULL key. */
6479 non_null_key->add_key(cur_rownum);
6480 }
6481
6482 for (uint i= (non_null_key ? 1 : 0); i < merge_keys_count; i++)
6483 {
6484 /*
6485 Check if the first and only indexed column contains NULL in the current
6486 row, and add the row number to the corresponding key.
6487 */
6488 if (merge_keys[i]->get_field(0)->is_null())
6489 merge_keys[i]->set_null(cur_rownum);
6490 else
6491 merge_keys[i]->add_key(cur_rownum);
6492 }
6493 ++cur_rownum;
6494 }
6495
6496 tmp_table->file->ha_rnd_end();
6497
6498 /* Sort all the keys by their NULL selectivity. */
6499 my_qsort(merge_keys, merge_keys_count, sizeof(Ordered_key*),
6500 (qsort_cmp) cmp_keys_by_null_selectivity);
6501
6502 /* Sort the keys in each of the indexes. */
6503 for (uint i= 0; i < merge_keys_count; i++)
6504 if (merge_keys[i]->sort_keys())
6505 return TRUE;
6506
6507 if (init_queue(&pq, merge_keys_count, 0, FALSE,
6508 subselect_rowid_merge_engine::cmp_keys_by_cur_rownum, NULL,
6509 0, 0))
6510 return TRUE;
6511
6512 return FALSE;
6513 }
6514
6515
~subselect_rowid_merge_engine()6516 subselect_rowid_merge_engine::~subselect_rowid_merge_engine()
6517 {
6518 /* None of the resources below is allocated if there are no ordered keys. */
6519 if (merge_keys_count)
6520 {
6521 my_free(row_num_to_rowid);
6522 for (uint i= 0; i < merge_keys_count; i++)
6523 delete merge_keys[i];
6524 delete_queue(&pq);
6525 if (tmp_table->file->inited == handler::RND)
6526 tmp_table->file->ha_rnd_end();
6527 }
6528 }
6529
6530
cleanup()6531 void subselect_rowid_merge_engine::cleanup()
6532 {
6533 }
6534
6535
6536 /*
6537 Quick sort comparison function to compare keys in order of decreasing bitmap
6538 selectivity, so that the most selective keys come first.
6539
6540 @param k1 first key to compare
6541 @param k2 second key to compare
6542
6543 @retval 1 if k1 is less selective than k2
6544 @retval 0 if k1 is equally selective as k2
6545 @retval -1 if k1 is more selective than k2
6546 */
6547
6548 int
cmp_keys_by_null_selectivity(Ordered_key ** k1,Ordered_key ** k2)6549 subselect_rowid_merge_engine::cmp_keys_by_null_selectivity(Ordered_key **k1,
6550 Ordered_key **k2)
6551 {
6552 double k1_sel= (*k1)->null_selectivity();
6553 double k2_sel= (*k2)->null_selectivity();
6554 if (k1_sel < k2_sel)
6555 return 1;
6556 if (k1_sel > k2_sel)
6557 return -1;
6558 return 0;
6559 }
6560
6561
6562 /*
6563 */
6564
6565 int
cmp_keys_by_cur_rownum(void * arg,uchar * k1,uchar * k2)6566 subselect_rowid_merge_engine::cmp_keys_by_cur_rownum(void *arg,
6567 uchar *k1, uchar *k2)
6568 {
6569 rownum_t r1= ((Ordered_key*) k1)->current();
6570 rownum_t r2= ((Ordered_key*) k2)->current();
6571
6572 return (r1 < r2) ? -1 : (r1 > r2) ? 1 : 0;
6573 }
6574
6575
6576 /*
6577 Check if certain table row contains a NULL in all columns for which there is
6578 no match in the corresponding value index.
6579
6580 @note
6581 There is no need to check the columns that contain only NULLs, because
6582 those are guaranteed to match.
6583
6584 @retval TRUE if a NULL row exists
6585 @retval FALSE otherwise
6586 */
6587
test_null_row(rownum_t row_num)6588 bool subselect_rowid_merge_engine::test_null_row(rownum_t row_num)
6589 {
6590 Ordered_key *cur_key;
6591 for (uint i = 0; i < merge_keys_count; i++)
6592 {
6593 cur_key= merge_keys[i];
6594 if (bitmap_is_set(&matching_keys, cur_key->get_keyid()))
6595 {
6596 /*
6597 The key 'i' (with id 'cur_keyid') already matches a value in row
6598 'row_num', thus we skip it as it can't possibly match a NULL.
6599 */
6600 continue;
6601 }
6602 if (!cur_key->is_null(row_num))
6603 return FALSE;
6604 }
6605 return TRUE;
6606 }
6607
6608
6609 /**
6610 Test if a subset of NULL-able columns contains a row of NULLs.
6611 @retval TRUE if such a row exists
6612 @retval FALSE no complementing null row
6613 */
6614
6615 bool subselect_rowid_merge_engine::
exists_complementing_null_row(MY_BITMAP * keys_to_complement)6616 exists_complementing_null_row(MY_BITMAP *keys_to_complement)
6617 {
6618 rownum_t highest_min_row= 0;
6619 rownum_t lowest_max_row= UINT_MAX;
6620 uint count_null_keys, i;
6621 Ordered_key *cur_key;
6622
6623 if (!count_columns_with_nulls)
6624 {
6625 /*
6626 If there are both NULLs and non-NUll values in the outer reference, and
6627 the subquery contains no NULLs, a complementing NULL row cannot exist.
6628 */
6629 return FALSE;
6630 }
6631
6632 for (i= (non_null_key ? 1 : 0), count_null_keys= 0; i < merge_keys_count; i++)
6633 {
6634 cur_key= merge_keys[i];
6635 if (bitmap_is_set(keys_to_complement, cur_key->get_keyid()))
6636 continue;
6637 if (!cur_key->get_null_count())
6638 {
6639 /* If there is column without NULLs, there cannot be a partial match. */
6640 return FALSE;
6641 }
6642 if (cur_key->get_min_null_row() > highest_min_row)
6643 highest_min_row= cur_key->get_min_null_row();
6644 if (cur_key->get_max_null_row() < lowest_max_row)
6645 lowest_max_row= cur_key->get_max_null_row();
6646 null_bitmaps[count_null_keys++]= cur_key->get_null_key();
6647 }
6648
6649 if (lowest_max_row < highest_min_row)
6650 {
6651 /* The intersection of NULL rows is empty. */
6652 return FALSE;
6653 }
6654
6655 return bitmap_exists_intersection((const MY_BITMAP**) null_bitmaps,
6656 count_null_keys,
6657 (uint)highest_min_row, (uint)lowest_max_row);
6658 }
6659
6660
6661 /*
6662 @retval TRUE there is a partial match (UNKNOWN)
6663 @retval FALSE there is no match at all (FALSE)
6664 */
6665
partial_match()6666 bool subselect_rowid_merge_engine::partial_match()
6667 {
6668 Ordered_key *min_key; /* Key that contains the current minimum position. */
6669 rownum_t min_row_num; /* Current row number of min_key. */
6670 Ordered_key *cur_key;
6671 rownum_t cur_row_num;
6672 uint count_nulls_in_search_key= 0;
6673 uint max_null_in_any_row=
6674 ((select_materialize_with_stats *) result)->get_max_nulls_in_row();
6675 bool res= FALSE;
6676
6677 /* If there is a non-NULL key, it must be the first key in the keys array. */
6678 DBUG_ASSERT(!non_null_key || (non_null_key && merge_keys[0] == non_null_key));
6679 /* The prioryty queue for keys must be empty. */
6680 DBUG_ASSERT(!pq.elements);
6681
6682 /* All data accesses during execution are via handler::ha_rnd_pos() */
6683 if (unlikely(tmp_table->file->ha_rnd_init_with_error(0)))
6684 {
6685 res= FALSE;
6686 goto end;
6687 }
6688
6689 /* Check if there is a match for the columns of the only non-NULL key. */
6690 if (non_null_key && !non_null_key->lookup())
6691 {
6692 res= FALSE;
6693 goto end;
6694 }
6695
6696 /*
6697 If all nullable columns contain only NULLs, then there is a guaranteed
6698 partial match, and we don't need to search for a matching row.
6699 */
6700 if (has_covering_null_columns)
6701 {
6702 res= TRUE;
6703 goto end;
6704 }
6705
6706 if (non_null_key)
6707 queue_insert(&pq, (uchar *) non_null_key);
6708 /*
6709 Do not add the non_null_key, since it was already processed above.
6710 */
6711 bitmap_clear_all(&matching_outer_cols);
6712 for (uint i= MY_TEST(non_null_key); i < merge_keys_count; i++)
6713 {
6714 DBUG_ASSERT(merge_keys[i]->get_column_count() == 1);
6715 if (merge_keys[i]->get_search_key(0)->null_value)
6716 {
6717 ++count_nulls_in_search_key;
6718 bitmap_set_bit(&matching_outer_cols, merge_keys[i]->get_keyid());
6719 }
6720 else if (merge_keys[i]->lookup())
6721 queue_insert(&pq, (uchar *) merge_keys[i]);
6722 }
6723
6724 /*
6725 If the outer reference consists of only NULLs, or if it has NULLs in all
6726 nullable columns (above we guarantee there is a match for the non-null
6727 coumns), the result is UNKNOWN.
6728 */
6729 if (count_nulls_in_search_key == merge_keys_count - MY_TEST(non_null_key))
6730 {
6731 res= TRUE;
6732 goto end;
6733 }
6734
6735 /*
6736 If the outer row has NULLs in some columns, and
6737 there is no match for any of the remaining columns, and
6738 there is a subquery row with NULLs in all unmatched columns,
6739 then there is a partial match, otherwise the result is FALSE.
6740 */
6741 if (count_nulls_in_search_key && !pq.elements)
6742 {
6743 DBUG_ASSERT(!non_null_key);
6744 /*
6745 Check if the intersection of all NULL bitmaps of all keys that
6746 are not in matching_outer_cols is non-empty.
6747 */
6748 res= exists_complementing_null_row(&matching_outer_cols);
6749 goto end;
6750 }
6751
6752 /*
6753 If there is no NULL (sub)row that covers all NULL columns, and there is no
6754 match for any of the NULL columns, the result is FALSE. Notice that if there
6755 is a non-null key, and there is only one matching key, the non-null key is
6756 the matching key. This is so, because this method returns FALSE if the
6757 non-null key doesn't have a match.
6758 */
6759 if (!count_nulls_in_search_key &&
6760 (!pq.elements ||
6761 (pq.elements == 1 && non_null_key &&
6762 max_null_in_any_row < merge_keys_count-1)))
6763 {
6764 if (!pq.elements)
6765 {
6766 DBUG_ASSERT(!non_null_key);
6767 /*
6768 The case of a covering null row is handled by
6769 subselect_partial_match_engine::exec()
6770 */
6771 DBUG_ASSERT(max_null_in_any_row != tmp_table->s->fields);
6772 }
6773 res= FALSE;
6774 goto end;
6775 }
6776
6777 DBUG_ASSERT(pq.elements);
6778
6779 min_key= (Ordered_key*) queue_remove_top(&pq);
6780 min_row_num= min_key->current();
6781 bitmap_set_bit(&matching_keys, min_key->get_keyid());
6782 bitmap_union(&matching_keys, &matching_outer_cols);
6783 if (min_key->next_same())
6784 queue_insert(&pq, (uchar *) min_key);
6785
6786 if (pq.elements == 0)
6787 {
6788 /*
6789 Check the only matching row of the only key min_key for NULL matches
6790 in the other columns.
6791 */
6792 res= test_null_row(min_row_num);
6793 goto end;
6794 }
6795
6796 while (TRUE)
6797 {
6798 cur_key= (Ordered_key*) queue_remove_top(&pq);
6799 cur_row_num= cur_key->current();
6800
6801 if (cur_row_num == min_row_num)
6802 bitmap_set_bit(&matching_keys, cur_key->get_keyid());
6803 else
6804 {
6805 /* Follows from the correct use of priority queue. */
6806 DBUG_ASSERT(cur_row_num > min_row_num);
6807 if (test_null_row(min_row_num))
6808 {
6809 res= TRUE;
6810 goto end;
6811 }
6812 else
6813 {
6814 min_key= cur_key;
6815 min_row_num= cur_row_num;
6816 bitmap_clear_all(&matching_keys);
6817 bitmap_set_bit(&matching_keys, min_key->get_keyid());
6818 bitmap_union(&matching_keys, &matching_outer_cols);
6819 }
6820 }
6821
6822 if (cur_key->next_same())
6823 queue_insert(&pq, (uchar *) cur_key);
6824
6825 if (pq.elements == 0)
6826 {
6827 /* Check the last row of the last column in PQ for NULL matches. */
6828 res= test_null_row(min_row_num);
6829 goto end;
6830 }
6831 }
6832
6833 /* We should never get here - all branches must be handled explicitly above. */
6834 DBUG_ASSERT(FALSE);
6835
6836 end:
6837 if (!has_covering_null_columns)
6838 bitmap_clear_all(&matching_keys);
6839 queue_remove_all(&pq);
6840 tmp_table->file->ha_rnd_end();
6841 return res;
6842 }
6843
6844
subselect_table_scan_engine(subselect_uniquesubquery_engine * engine_arg,TABLE * tmp_table_arg,Item_subselect * item_arg,select_result_interceptor * result_arg,List<Item> * equi_join_conds_arg,bool has_covering_null_row_arg,bool has_covering_null_columns_arg,uint count_columns_with_nulls_arg)6845 subselect_table_scan_engine::subselect_table_scan_engine(
6846 subselect_uniquesubquery_engine *engine_arg,
6847 TABLE *tmp_table_arg,
6848 Item_subselect *item_arg,
6849 select_result_interceptor *result_arg,
6850 List<Item> *equi_join_conds_arg,
6851 bool has_covering_null_row_arg,
6852 bool has_covering_null_columns_arg,
6853 uint count_columns_with_nulls_arg)
6854 :subselect_partial_match_engine(engine_arg, tmp_table_arg, item_arg,
6855 result_arg, equi_join_conds_arg,
6856 has_covering_null_row_arg,
6857 has_covering_null_columns_arg,
6858 count_columns_with_nulls_arg)
6859 {}
6860
6861
6862 /*
6863 TIMOUR:
6864 This method is based on subselect_uniquesubquery_engine::scan_table().
6865 Consider refactoring somehow, 80% of the code is the same.
6866
6867 for each row_i in tmp_table
6868 {
6869 count_matches= 0;
6870 for each row element row_i[j]
6871 {
6872 if (outer_ref[j] is NULL || row_i[j] is NULL || outer_ref[j] == row_i[j])
6873 ++count_matches;
6874 }
6875 if (count_matches == outer_ref.elements)
6876 return TRUE
6877 }
6878 return FALSE
6879 */
6880
partial_match()6881 bool subselect_table_scan_engine::partial_match()
6882 {
6883 List_iterator_fast<Item> equality_it(*equi_join_conds);
6884 Item *cur_eq;
6885 uint count_matches;
6886 int error;
6887 bool res;
6888
6889 if (unlikely(tmp_table->file->ha_rnd_init_with_error(1)))
6890 {
6891 res= FALSE;
6892 goto end;
6893 }
6894
6895 tmp_table->file->extra_opt(HA_EXTRA_CACHE,
6896 get_thd()->variables.read_buff_size);
6897 for (;;)
6898 {
6899 error= tmp_table->file->ha_rnd_next(tmp_table->record[0]);
6900 if (unlikely(error))
6901 {
6902 if (error == HA_ERR_END_OF_FILE)
6903 {
6904 error= 0;
6905 break;
6906 }
6907 else
6908 {
6909 error= report_error(tmp_table, error);
6910 break;
6911 }
6912 }
6913
6914 equality_it.rewind();
6915 count_matches= 0;
6916 while ((cur_eq= equality_it++))
6917 {
6918 DBUG_ASSERT(cur_eq->type() == Item::FUNC_ITEM &&
6919 ((Item_func*)cur_eq)->functype() == Item_func::EQ_FUNC);
6920 if (!cur_eq->val_int() && !cur_eq->null_value)
6921 break;
6922 ++count_matches;
6923 }
6924 if (count_matches == tmp_table->s->fields)
6925 {
6926 res= TRUE; /* Found a matching row. */
6927 goto end;
6928 }
6929 }
6930
6931 res= FALSE;
6932 end:
6933 tmp_table->file->ha_rnd_end();
6934 return res;
6935 }
6936
6937
cleanup()6938 void subselect_table_scan_engine::cleanup()
6939 {
6940 }
6941
6942
register_as_with_rec_ref(With_element * with_elem)6943 void Item_subselect::register_as_with_rec_ref(With_element *with_elem)
6944 {
6945 with_elem->sq_with_rec_ref.link_in_list(this, &this->next_with_rec_ref);
6946 with_recursive_reference= true;
6947 }
6948
6949
6950 /*
6951 Create an execution tracker for the expression cache we're using for this
6952 subselect; add the tracker to the query plan.
6953 */
6954
init_expr_cache_tracker(THD * thd)6955 void Item_subselect::init_expr_cache_tracker(THD *thd)
6956 {
6957 if(!expr_cache)
6958 return;
6959
6960 Explain_query *qw= thd->lex->explain;
6961 DBUG_ASSERT(qw);
6962 Explain_node *node= qw->get_node(unit->first_select()->select_number);
6963 if (!node)
6964 return;
6965 DBUG_ASSERT(expr_cache->type() == Item::EXPR_CACHE_ITEM);
6966 node->cache_tracker= ((Item_cache_wrapper *)expr_cache)->init_tracker(qw->mem_root);
6967 }
6968