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> &parameters)
855 {
856   Collect_deps_prm prm= {&parameters,      // 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