1 /* Copyright (c) 2001, 2021, Oracle and/or its affiliates.
2 
3    This program is free software; you can redistribute it and/or modify
4    it under the terms of the GNU General Public License, version 2.0,
5    as published by the Free Software Foundation.
6 
7    This program is also distributed with certain software (including
8    but not limited to OpenSSL) that is licensed under separate terms,
9    as designated in a particular file or component or in included license
10    documentation.  The authors of MySQL hereby grant you an additional
11    permission to link the program and your derivative works with the
12    separately licensed software that they have included with MySQL.
13 
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License, version 2.0, for more details.
18 
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
22 
23 /*
24   Process query expressions that are composed of
25 
26   1. UNION of query blocks, and/or
27 
28   2. have ORDER BY / LIMIT clauses in more than one level.
29 
30   An example of 2) is:
31 
32     (SELECT * FROM t1 ORDER BY a LIMIT 10) ORDER BY b LIMIT 5
33 
34   UNION's  were introduced by Monty and Sinisa <sinisa@mysql.com>
35 */
36 
37 #include "sql_union.h"
38 #include "sql_select.h"
39 #include "sql_cursor.h"
40 #include "sql_base.h"                           // fill_record
41 #include "filesort.h"                           // filesort_free_buffers
42 #include "sql_tmp_table.h"                      // tmp tables
43 #include "sql_optimizer.h"                      // JOIN
44 #include "opt_explain.h"                        // explain_no_table
45 #include "opt_explain_format.h"
46 
47 
prepare(List<Item> & list,SELECT_LEX_UNIT * u)48 int Query_result_union::prepare(List<Item> &list, SELECT_LEX_UNIT *u)
49 {
50   unit= u;
51   return 0;
52 }
53 
54 
send_data(List<Item> & values)55 bool Query_result_union::send_data(List<Item> &values)
56 {
57   // Skip "offset" number of rows before producing rows
58   if (unit->offset_limit_cnt > 0)
59   {
60     unit->offset_limit_cnt--;
61     return false;
62   }
63   if (fill_record(thd, table, table->visible_field_ptr(), values, NULL, NULL))
64     return true;                /* purecov: inspected */
65 
66   if (!check_unique_constraint(table))
67     return false;
68 
69   const int error= table->file->ha_write_row(table->record[0]);
70   if (error)
71   {
72     // create_ondisk_from_heap will generate error if needed
73     if (!table->file->is_ignorable_error(error) &&
74         create_ondisk_from_heap(thd, table, tmp_table_param.start_recinfo,
75                                 &tmp_table_param.recinfo, error, true, NULL))
76       return true;            /* purecov: inspected */
77     // Table's engine changed, index is not initialized anymore
78     if (table->hash_field)
79       table->file->ha_index_init(0, false);
80   }
81   return false;
82 }
83 
84 
send_eof()85 bool Query_result_union::send_eof()
86 {
87   return false;
88 }
89 
90 
flush()91 bool Query_result_union::flush()
92 {
93   const int error= table->file->extra(HA_EXTRA_NO_CACHE);
94   if (error)
95   {
96     table->file->print_error(error, MYF(0)); /* purecov: inspected */
97     return true;                             /* purecov: inspected */
98   }
99   return false;
100 }
101 
102 /**
103   Create a temporary table to store the result of Query_result_union.
104 
105   @param thd                thread handle
106   @param column_types       a list of items used to define columns of the
107                             temporary table
108   @param is_union_distinct  if set, the temporary table will eliminate
109                             duplicates on insert
110   @param options            create options
111   @param table_alias        name of the temporary table
112   @param bit_fields_as_long convert bit fields to ulonglong
113 
114   @details
115     Create a temporary table that is used to store the result of a UNION,
116     derived table, or a materialized cursor.
117 
118   @returns false if table created, true if error
119 */
120 
create_result_table(THD * thd_arg,List<Item> * column_types,bool is_union_distinct,ulonglong options,const char * table_alias,bool bit_fields_as_long,bool create_table)121 bool Query_result_union::create_result_table(THD *thd_arg,
122                                              List<Item> *column_types,
123                                              bool is_union_distinct,
124                                              ulonglong options,
125                                              const char *table_alias,
126                                              bool bit_fields_as_long,
127                                              bool create_table)
128 {
129   assert(table == NULL);
130   tmp_table_param= Temp_table_param();
131   count_field_types(thd_arg->lex->current_select(), &tmp_table_param,
132                     *column_types, false, true);
133   tmp_table_param.skip_create_table= !create_table;
134   tmp_table_param.bit_fields_as_long= bit_fields_as_long;
135   tmp_table_param.can_use_pk_for_unique= !is_union_mixed_with_union_all;
136 
137   if (! (table= create_tmp_table(thd_arg, &tmp_table_param, *column_types,
138                                  NULL, is_union_distinct, true,
139                                  options, HA_POS_ERROR, (char*) table_alias)))
140     return true;
141   if (create_table)
142   {
143     table->file->extra(HA_EXTRA_WRITE_CACHE);
144     table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
145     if (table->hash_field)
146       table->file->ha_index_init(0, 0);
147   }
148   return false;
149 }
150 
151 
152 /**
153   Reset and empty the temporary table that stores the materialized query result.
154 
155   @note The cleanup performed here is exactly the same as for the two temp
156   tables of JOIN - exec_tmp_table_[1 | 2].
157 */
158 
cleanup()159 void Query_result_union::cleanup()
160 {
161   if (table == NULL)
162     return;
163   table->file->extra(HA_EXTRA_RESET_STATE);
164   if (table->hash_field)
165     table->file->ha_index_or_rnd_end();
166   table->file->ha_delete_all_rows();
167   free_io_cache(table);
168   filesort_free_buffers(table,0);
169 }
170 
171 
172 /**
173   UNION result that is passed directly to the receiving Query_result
174   without filling a temporary table.
175 
176   Function calls are forwarded to the wrapped Query_result, but some
177   functions are expected to be called only once for each query, so
178   they are only executed for the first query block in the union (except
179   for send_eof(), which is executed only for the last query block).
180 
181   This Query_result is used when a UNION is not DISTINCT and doesn't
182   have a global ORDER BY clause. @see st_select_lex_unit::prepare().
183 */
184 class Query_result_union_direct :public Query_result_union
185 {
186 private:
187   /// Result object that receives all rows
188   Query_result *result;
189   /// The last query block of the union
190   SELECT_LEX *last_select_lex;
191 
192   /// Wrapped result has received metadata
193   bool done_send_result_set_metadata;
194   /// Wrapped result has initialized tables
195   bool done_initialize_tables;
196 
197   /// Accumulated current_found_rows
198   ulonglong current_found_rows;
199 
200   /// Number of rows offset
201   ha_rows offset;
202   /// Number of rows limit + offset, @see Query_result_union_direct::send_data()
203   ha_rows limit;
204 
205 public:
Query_result_union_direct(Query_result * result,SELECT_LEX * last_select_lex)206   Query_result_union_direct(Query_result *result, SELECT_LEX *last_select_lex)
207     :result(result), last_select_lex(last_select_lex),
208     done_send_result_set_metadata(false), done_initialize_tables(false),
209     current_found_rows(0)
210   {}
211   bool change_query_result(Query_result *new_result);
field_count(List<Item> & fields) const212   uint field_count(List<Item> &fields) const
213   {
214     // Only called for top-level Query_results, usually Query_result_send
215     assert(false); /* purecov: inspected */
216     return 0; /* purecov: inspected */
217   }
218   bool postponed_prepare(List<Item> &types);
219   bool send_result_set_metadata(List<Item> &list, uint flags);
220   bool send_data(List<Item> &items);
221   bool initialize_tables (JOIN *join= NULL);
send_error(uint errcode,const char * err)222   void send_error(uint errcode, const char *err)
223   {
224     result->send_error(errcode, err); /* purecov: inspected */
225   }
226   bool send_eof();
flush()227   bool flush() { return false; }
check_simple_select() const228   bool check_simple_select() const
229   {
230     // Only called for top-level Query_results, usually Query_result_send
231     assert(false); /* purecov: inspected */
232     return false; /* purecov: inspected */
233   }
abort_result_set()234   void abort_result_set()
235   {
236     result->abort_result_set(); /* purecov: inspected */
237   }
cleanup()238   void cleanup() {}
set_thd(THD * thd_arg)239   void set_thd(THD *thd_arg)
240   {
241     /*
242       Only called for top-level Query_results, usually Query_result_send,
243       and for the results of subquery engines
244       (select_<something>_subselect).
245     */
246     assert(false); /* purecov: inspected */
247   }
begin_dataset()248   void begin_dataset()
249   {
250     // Only called for sp_cursor::Select_fetch_into_spvars
251     assert(false); /* purecov: inspected */
252   }
253 };
254 
255 
256 /**
257   Replace the current query result with new_result and prepare it.
258 
259   @param new_result New query result
260 
261   @returns false if success, true if error
262 */
change_query_result(Query_result * new_result)263 bool Query_result_union_direct::change_query_result(Query_result *new_result)
264 {
265   result= new_result;
266   return (result->prepare(unit->types, unit) || result->prepare2());
267 }
268 
269 
postponed_prepare(List<Item> & types)270 bool Query_result_union_direct::postponed_prepare(List<Item> &types)
271 {
272   if (result != NULL)
273     return (result->prepare(types, unit) || result->prepare2());
274   else
275     return false;
276 }
277 
278 
send_result_set_metadata(List<Item> & list,uint flags)279 bool Query_result_union_direct::send_result_set_metadata(List<Item> &list,
280                                                          uint flags)
281 {
282   if (done_send_result_set_metadata)
283     return false;
284   done_send_result_set_metadata= true;
285 
286   /*
287     Set global offset and limit to be used in send_data(). These can
288     be variables in prepared statements or stored programs, so they
289     must be reevaluated for each execution.
290    */
291   offset= unit->global_parameters()->get_offset();
292   limit= unit->global_parameters()->get_limit();
293   if (limit + offset >= limit)
294     limit+= offset;
295   else
296     limit= HA_POS_ERROR; /* purecov: inspected */
297 
298   return result->send_result_set_metadata(unit->types, flags);
299 }
300 
301 
send_data(List<Item> & items)302 bool Query_result_union_direct::send_data(List<Item> &items)
303 {
304   if (limit == 0)
305     return false;
306   limit--;
307   if (offset)
308   {
309     offset--;
310     return false;
311   }
312 
313   if (fill_record(thd, table, table->field, items, NULL, NULL))
314     return true; /* purecov: inspected */
315 
316   return result->send_data(unit->item_list);
317 }
318 
319 
initialize_tables(JOIN * join)320 bool Query_result_union_direct::initialize_tables(JOIN *join)
321 {
322   if (done_initialize_tables)
323     return false;
324   done_initialize_tables= true;
325 
326   return result->initialize_tables(join);
327 }
328 
329 
send_eof()330 bool Query_result_union_direct::send_eof()
331 {
332   /*
333     Accumulate the found_rows count for the current query block into the UNION.
334     Number of rows returned from a query block is always non-negative.
335   */
336   ulonglong offset= thd->lex->current_select()->get_offset();
337   current_found_rows+= thd->current_found_rows > offset ?
338                        thd->current_found_rows - offset : 0;
339 
340   if (unit->thd->lex->current_select() == last_select_lex)
341   {
342     /*
343       If SQL_CALC_FOUND_ROWS is not enabled, adjust the current_found_rows
344       according to the global limit and offset defined.
345     */
346     if (!(unit->first_select()->active_options() & OPTION_FOUND_ROWS))
347     {
348       ha_rows global_limit= unit->global_parameters()->get_limit();
349       ha_rows global_offset= unit->global_parameters()->get_offset();
350 
351       if (global_limit != HA_POS_ERROR)
352       {
353         if (global_offset != HA_POS_ERROR)
354           global_limit+= global_offset;
355 
356         if (current_found_rows > global_limit)
357           current_found_rows= global_limit;
358       }
359     }
360     thd->current_found_rows= current_found_rows;
361 
362     // Reset and make ready for re-execution
363     // @todo: Dangerous if we have an error midway?
364     done_send_result_set_metadata= false;
365     done_initialize_tables= false;
366 
367     return result->send_eof();
368   }
369   else
370     return false;
371 }
372 
373 
374 /**
375   Prepare the fake_select_lex query block
376 
377   @param thd		 Thread handler
378 
379   @returns false if success, true if error
380 */
381 
prepare_fake_select_lex(THD * thd_arg)382 bool st_select_lex_unit::prepare_fake_select_lex(THD *thd_arg)
383 {
384   DBUG_ENTER("st_select_lex_unit::prepare_fake_select_lex");
385 
386   assert(thd_arg->lex->current_select() == fake_select_lex);
387 
388   // The UNION result table is input table for this query block
389   fake_select_lex->table_list.link_in_list(&result_table_list,
390                                            &result_table_list.next_local);
391 
392   // Set up the result table for name resolution
393   fake_select_lex->context.table_list=
394     fake_select_lex->context.first_name_resolution_table=
395     fake_select_lex->get_table_list();
396   if (!fake_select_lex->first_execution)
397   {
398     for (ORDER *order= fake_select_lex->order_list.first;
399          order;
400          order= order->next)
401       order->item= &order->item_ptr;
402   }
403   for (ORDER *order= fake_select_lex->order_list.first;
404        order;
405        order=order->next)
406   {
407     (*order->item)->walk(&Item::change_context_processor,
408                          Item::WALK_POSTFIX,
409                          (uchar*) &fake_select_lex->context);
410   }
411   fake_select_lex->set_query_result(query_result());
412 
413   /*
414     For subqueries in form "a IN (SELECT .. UNION SELECT ..):
415     when optimizing the fake_select_lex that reads the results of the union
416     from a temporary table, do not mark the temp. table as constant because
417     the contents in it may vary from one subquery execution to another.
418   */
419   fake_select_lex->make_active_options(
420      (first_select()->active_options() & OPTION_FOUND_ROWS) |
421      OPTION_NO_CONST_TABLES |
422      SELECT_NO_UNLOCK,
423      0);
424   fake_select_lex->fields_list= item_list;
425 
426   /*
427     We need to add up n_sum_items in order to make the correct
428     allocation in setup_ref_array().
429     Don't add more sum_items if we have already done SELECT_LEX::prepare
430     for this (with a different join object)
431   */
432   if (fake_select_lex->ref_pointer_array.is_null())
433     fake_select_lex->n_child_sum_items+= fake_select_lex->n_sum_items;
434 
435   assert(fake_select_lex->with_wild == 0 &&
436          fake_select_lex->master_unit() == this &&
437          !fake_select_lex->group_list.elements &&
438          fake_select_lex->where_cond() == NULL &&
439          fake_select_lex->having_cond() == NULL);
440 
441   if (fake_select_lex->prepare(thd_arg))
442     DBUG_RETURN(true);
443 
444   DBUG_RETURN(false);
445 }
446 
447 
448 /**
449   Prepares all query blocks of a query expression, including fake_select_lex
450 
451   @param thd_arg       Thread handler
452   @param sel_result    Result object where the unit's output should go.
453   @param added_options These options will be added to the query blocks.
454   @param removed_options Options that cannot be used for this query
455 
456   @returns false if success, true if error
457  */
prepare(THD * thd_arg,Query_result * sel_result,ulonglong added_options,ulonglong removed_options)458 bool st_select_lex_unit::prepare(THD *thd_arg, Query_result *sel_result,
459                                  ulonglong added_options,
460                                  ulonglong removed_options)
461 {
462   DBUG_ENTER("st_select_lex_unit::prepare");
463 
464   assert(!is_prepared());
465 
466   SELECT_LEX *lex_select_save= thd_arg->lex->current_select();
467 
468   Query_result *tmp_result;
469   bool instantiate_tmp_table= false;
470 
471   SELECT_LEX *last_select= first_select();
472   while (last_select->next_select())
473     last_select= last_select->next_select();
474 
475   set_query_result(sel_result);
476 
477   thd_arg->lex->set_current_select(first_select());
478 
479   // Save fake_select_lex in case we don't need it for anything but
480   // global parameters.
481   if (saved_fake_select_lex == NULL && // Don't overwrite on PS second prepare
482       fake_select_lex != NULL)
483   {
484     thd->lock_query_plan();
485     saved_fake_select_lex= fake_select_lex;
486     thd->unlock_query_plan();
487   }
488 
489   const bool simple_query_expression= is_simple();
490 
491   // Create query result object for use by underlying query blocks
492   if (!simple_query_expression)
493   {
494     if (is_union() && !union_needs_tmp_table())
495     {
496       if (!(tmp_result= union_result=
497               new Query_result_union_direct(sel_result, last_select)))
498         goto err; /* purecov: inspected */
499       if (fake_select_lex != NULL)
500       {
501         thd->lock_query_plan();
502         fake_select_lex= NULL;
503         thd->unlock_query_plan();
504       }
505       instantiate_tmp_table= false;
506     }
507     else
508     {
509       if (!(tmp_result= union_result= new Query_result_union()))
510         goto err; /* purecov: inspected */
511       instantiate_tmp_table= true;
512     }
513   }
514   else
515   {
516     // Only one query block, and no "fake" object: No extra result needed:
517     tmp_result= sel_result;
518   }
519 
520   first_select()->context.resolve_in_select_list= true;
521 
522   for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
523   {
524     sl->set_query_result(tmp_result);
525     sl->make_active_options(added_options | SELECT_NO_UNLOCK, removed_options);
526     sl->fields_list= sl->item_list;
527 
528     /*
529       setup_tables_done_option should be set only for very first SELECT,
530       because it protect from second setup_tables call for select-like non
531       select commands (DELETE/INSERT/...) and they use only very first
532       SELECT (for union it can be only INSERT ... SELECT).
533     */
534     added_options&= ~OPTION_SETUP_TABLES_DONE;
535 
536     thd_arg->lex->set_current_select(sl);
537 
538     if (sl->prepare(thd_arg))
539       goto err;
540 
541     /*
542       Use items list of underlaid select for derived tables to preserve
543       information about fields lengths and exact types
544     */
545     if (simple_query_expression)
546       types= first_select()->item_list;
547     else if (sl == first_select())
548     {
549       types.empty();
550       List_iterator_fast<Item> it(sl->item_list);
551       Item *item_tmp;
552       while ((item_tmp= it++))
553       {
554         /*
555           If the outer query has a GROUP BY clause, an outer reference to this
556           query block may have been wrapped in a Item_outer_ref, which has not
557           been fixed yet. An Item_type_holder must be created based on a fixed
558           Item, so use the inner Item instead.
559         */
560         assert(item_tmp->fixed ||
561                (item_tmp->type() == Item::REF_ITEM &&
562                 down_cast<Item_ref *>(item_tmp)->ref_type() ==
563                 Item_ref::OUTER_REF));
564         if (!item_tmp->fixed)
565           item_tmp= item_tmp->real_item();
566 
567 	/* Error's in 'new' will be detected after loop */
568 	types.push_back(new Item_type_holder(thd_arg, item_tmp));
569       }
570       if (thd_arg->is_error())
571 	goto err; // out of memory
572     }
573     else
574     {
575       if (types.elements != sl->item_list.elements)
576       {
577 	my_message(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT,
578 		   ER(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT),MYF(0));
579 	goto err;
580       }
581       List_iterator_fast<Item> it(sl->item_list);
582       List_iterator_fast<Item> tp(types);
583       Item *type, *item_tmp;
584       while ((type= tp++, item_tmp= it++))
585       {
586         if (((Item_type_holder*)type)->join_types(thd_arg, item_tmp))
587 	  DBUG_RETURN(true);
588       }
589     }
590   }
591 
592   /*
593     If the query is using Query_result_union_direct, we have postponed
594     preparation of the underlying Query_result until column types are known.
595   */
596   if (union_result != NULL && union_result->postponed_prepare(types))
597     DBUG_RETURN(true);
598 
599   if (!simple_query_expression)
600   {
601     /*
602       Check that it was possible to aggregate all collations together for UNION.
603       We need this in case of UNION DISTINCT, to filter out duplicates using
604       the proper collation.
605 
606       TODO: consider removing this test in case of UNION ALL.
607     */
608     List_iterator_fast<Item> tp(types);
609     Item *type;
610 
611     while ((type= tp++))
612     {
613       if (type->result_type() == STRING_RESULT &&
614           type->collation.derivation == DERIVATION_NONE)
615       {
616         my_error(ER_CANT_AGGREGATE_NCOLLATIONS, MYF(0), "UNION");
617         goto err;
618       }
619     }
620     ulonglong create_options= first_select()->active_options() |
621                               TMP_TABLE_ALL_COLUMNS;
622     /*
623       Force the temporary table to be a MyISAM table if we're going to use
624       fulltext functions (MATCH ... AGAINST .. IN BOOLEAN MODE) when reading
625       from it (this should be removed when fulltext search is moved
626       out of MyISAM).
627     */
628     if (fake_select_lex && fake_select_lex->ftfunc_list->elements)
629       create_options|= TMP_TABLE_FORCE_MYISAM;
630 
631     if (union_distinct)
632     {
633       // Mixed UNION and UNION ALL
634       if (union_distinct != last_select)
635         union_result->is_union_mixed_with_union_all= true;
636     }
637     if (union_result->create_result_table(thd, &types, MY_TEST(union_distinct),
638                                           create_options, "", false,
639                                           instantiate_tmp_table))
640       goto err;
641     new (&result_table_list) TABLE_LIST;
642     result_table_list.db= (char*) "";
643     result_table_list.table_name= result_table_list.alias= (char*) "union";
644     result_table_list.table= table= union_result->table;
645     table->pos_in_table_list= &result_table_list;
646     result_table_list.select_lex= fake_select_lex ?
647                                      fake_select_lex : saved_fake_select_lex;
648     result_table_list.set_tableno(0);
649 
650     result_table_list.set_privileges(SELECT_ACL);
651 
652     if (!item_list.elements)
653     {
654       Prepared_stmt_arena_holder ps_arena_holder(thd);
655       if (table->fill_item_list(&item_list))
656         goto err;            /* purecov: inspected */
657     }
658     else
659     {
660       /*
661         We're in execution of a prepared statement or stored procedure:
662         reset field items to point at fields from the created temporary table.
663       */
664       table->reset_item_list(&item_list);
665     }
666     if (fake_select_lex != NULL)
667     {
668       thd_arg->lex->set_current_select(fake_select_lex);
669 
670       if (prepare_fake_select_lex(thd_arg))
671         goto err;
672     }
673   }
674 
675   thd_arg->lex->set_current_select(lex_select_save);
676 
677   set_prepared();          // All query blocks prepared, update the state
678 
679   DBUG_RETURN(false);
680 
681 err:
682   (void) cleanup(false);
683   DBUG_RETURN(true);
684 }
685 
686 
687 /**
688   Optimize all query blocks of a query expression, including fake_select_lex
689 
690   @param thd    thread handler
691 
692   @returns false if optimization successful, true if error
693 */
694 
optimize(THD * thd)695 bool st_select_lex_unit::optimize(THD *thd)
696 {
697   DBUG_ENTER("st_select_lex_unit::optimize");
698 
699   assert(is_prepared() && !is_optimized());
700 
701   SELECT_LEX *save_select= thd->lex->current_select();
702 
703   for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
704   {
705     thd->lex->set_current_select(sl);
706 
707     // LIMIT is required for optimization
708     set_limit(sl);
709 
710     if (sl->optimize(thd))
711       DBUG_RETURN(true);
712 
713     /*
714       Accumulate estimated number of rows.
715       1. Implicitly grouped query has one row (with HAVING it has zero or one
716          rows).
717       2. If GROUP BY clause is optimized away because it was a constant then
718          query produces at most one row.
719     */
720     if (query_result())
721       query_result()->estimated_rowcount+=
722         sl->is_implicitly_grouped() || sl->join->group_optimized_away ?
723           1 :  sl->join->best_rowcount;
724 
725   }
726   if (fake_select_lex)
727   {
728     thd->lex->set_current_select(fake_select_lex);
729 
730     set_limit(fake_select_lex);
731 
732     /*
733       In EXPLAIN command, constant subqueries that do not use any
734       tables are executed two times:
735        - 1st time is a real evaluation to get the subquery value
736        - 2nd time is to produce EXPLAIN output rows.
737       1st execution sets certain members (e.g. Query_result) to perform
738       subquery execution rather than EXPLAIN line production. In order
739       to reset them back, we re-do all of the actions (yes it is ugly).
740     */
741     assert(fake_select_lex->with_wild == 0 &&
742            fake_select_lex->master_unit() == this &&
743            !fake_select_lex->group_list.elements &&
744            fake_select_lex->get_table_list() == &result_table_list &&
745            fake_select_lex->where_cond() == NULL &&
746            fake_select_lex->having_cond() == NULL);
747 
748     if (fake_select_lex->optimize(thd))
749       DBUG_RETURN(true);
750   }
751   set_optimized();    // All query blocks optimized, update the state
752   thd->lex->set_current_select(save_select);
753 
754   DBUG_RETURN(false);
755 }
756 
757 
758 /**
759   Explain query starting from this unit.
760 
761   @param ethd  THD of explaining thread
762 
763   @return false if success, true if error
764 */
765 
explain(THD * ethd)766 bool st_select_lex_unit::explain(THD *ethd)
767 {
768   DBUG_ENTER("st_select_lex_unit::explain");
769 
770 #ifndef NDEBUG
771   SELECT_LEX *lex_select_save= thd->lex->current_select();
772 #endif
773   Explain_format *fmt= ethd->lex->explain_format;
774   const bool other= (thd != ethd);
775   bool ret= false;
776 
777   if (!other)
778   {
779     assert(!is_simple() && is_optimized());
780     set_executed();
781   }
782 
783   if (fmt->begin_context(CTX_UNION))
784     DBUG_RETURN(true);
785 
786   for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
787   {
788     if (fmt->begin_context(CTX_QUERY_SPEC))
789       DBUG_RETURN(true);
790     if (explain_query_specification(ethd, sl, CTX_JOIN) ||
791         fmt->end_context(CTX_QUERY_SPEC))
792       DBUG_RETURN(true);
793   }
794 
795   if (fake_select_lex != NULL)
796   {
797     // Don't save result as it's needed only for consequent exec.
798     ret= explain_query_specification(ethd, fake_select_lex, CTX_UNION_RESULT);
799   }
800   if (!other)
801     assert(thd->lex->current_select() == lex_select_save);
802 
803   if (ret)
804     DBUG_RETURN(true);
805   fmt->end_context(CTX_UNION);
806 
807   DBUG_RETURN(false);
808 }
809 
810 
811 /**
812   Execute a query expression that may be a UNION and/or have an ordered result.
813 
814   @param thd          thread handle
815 
816   @returns false if success, true if error
817 */
818 
execute(THD * thd)819 bool st_select_lex_unit::execute(THD *thd)
820 {
821   DBUG_ENTER("st_select_lex_unit::exec");
822   assert(!is_simple() && is_optimized());
823 
824   if (is_executed() && !uncacheable)
825     DBUG_RETURN(false);
826 
827   SELECT_LEX *lex_select_save= thd->lex->current_select();
828 
829   bool status= false;          // Execution error status
830 
831   // Set "executed" state, even though execution may end with an error
832   set_executed();
833 
834   if (item)
835   {
836     item->reset_value_registration();
837 
838     if (item->assigned())
839     {
840       item->assigned(false); // Prepare for re-execution of this unit
841       item->reset();
842       if (table->is_created())
843       {
844         table->file->ha_delete_all_rows();
845         table->file->info(HA_STATUS_VARIABLE);
846       }
847     }
848     // re-enable indexes for next subquery execution
849     if (union_distinct && table->file->ha_enable_indexes(HA_KEY_SWITCH_ALL))
850       DBUG_RETURN(true);       /* purecov: inspected */
851   }
852 
853   for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
854   {
855     thd->lex->set_current_select(sl);
856 
857     if (sl->join->is_executed())
858       sl->join->reset();
859 
860     // Set limit and offset for each execution:
861     set_limit(sl);
862 
863     // Execute this query block
864     sl->join->exec();
865     status= sl->join->error != 0;
866 
867     if (sl == union_distinct)
868     {
869       // This is UNION DISTINCT, so there should be a fake_select_lex
870       assert(fake_select_lex != NULL);
871       if (table->file->ha_disable_indexes(HA_KEY_SWITCH_ALL))
872         DBUG_RETURN(true); /* purecov: inspected */
873       table->no_keyread= 1;
874     }
875     if (status)
876       DBUG_RETURN(true);
877 
878     if (union_result->flush())
879       DBUG_RETURN(true); /* purecov: inspected */
880   }
881 
882   if (fake_select_lex != NULL)
883   {
884     thd->lex->set_current_select(fake_select_lex);
885 
886     int error= table->file->info(HA_STATUS_VARIABLE);
887     if (error)
888     {
889       table->file->print_error(error, MYF(0)); /* purecov: inspected */
890       DBUG_RETURN(true);                       /* purecov: inspected */
891     }
892     // Index might have been used to weedout duplicates for UNION DISTINCT
893     table->file->ha_index_or_rnd_end();
894     set_limit(fake_select_lex);
895     JOIN *join= fake_select_lex->join;
896     join->reset();
897     join->exec();
898     status= join->error != 0;
899     fake_select_lex->table_list.empty();
900     thd->current_found_rows= (ulonglong)table->file->stats.records;
901   }
902 
903   thd->lex->set_current_select(lex_select_save);
904   DBUG_RETURN(status);
905 }
906 
907 
908 /**
909   Cleanup this query expression object after preparation or one round
910   of execution. After the cleanup, the object can be reused for a
911   new round of execution, but a new optimization will be needed before
912   the execution.
913 
914   @return false if previous execution was successful, and true otherwise
915 */
916 
cleanup(bool full)917 bool st_select_lex_unit::cleanup(bool full)
918 {
919   DBUG_ENTER("st_select_lex_unit::cleanup");
920 
921   assert(thd == current_thd);
922 
923   if (cleaned >= (full ? UC_CLEAN : UC_PART_CLEAN))
924     DBUG_RETURN(false);
925 
926   cleaned= (full ? UC_CLEAN : UC_PART_CLEAN);
927 
928   bool error= false;
929   for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
930     error|= sl->cleanup(full);
931 
932   if (fake_select_lex)
933     error|= fake_select_lex->cleanup(full);
934 
935   // fake_select_lex's table depends on Temp_table_param inside union_result
936   if (full && union_result)
937   {
938     union_result->cleanup();
939     delete union_result;
940     union_result= NULL; // Safety
941     if (table)
942       free_tmp_table(thd, table);
943     table= NULL; // Safety
944   }
945 
946   /*
947     explain_marker is (mostly) a property determined at prepare time and must
948     thus be preserved for the next execution, if this is a prepared statement.
949   */
950 
951   DBUG_RETURN(error);
952 }
953 
954 
955 #ifndef NDEBUG
assert_not_fully_clean()956 void st_select_lex_unit::assert_not_fully_clean()
957 {
958   assert(cleaned < UC_CLEAN);
959   SELECT_LEX *sl= first_select();
960   for (;;)
961   {
962     if (!sl)
963     {
964       sl= fake_select_lex;
965       if (!sl)
966         break;
967     }
968     for (SELECT_LEX_UNIT *lex_unit= sl->first_inner_unit(); lex_unit ;
969          lex_unit= lex_unit->next_unit())
970       lex_unit->assert_not_fully_clean();
971     if (sl == fake_select_lex)
972       break;
973     else
974       sl= sl->next_select();
975   }
976 }
977 #endif
978 
979 
reinit_exec_mechanism()980 void st_select_lex_unit::reinit_exec_mechanism()
981 {
982   prepared= optimized= executed= false;
983 #ifndef NDEBUG
984   if (is_union())
985   {
986     List_iterator_fast<Item> it(item_list);
987     Item *field;
988     while ((field= it++))
989     {
990       /*
991 	we can't cleanup here, because it broke link to temporary table field,
992 	but have to drop fixed flag to allow next fix_field of this field
993 	during re-executing
994       */
995       field->fixed= 0;
996     }
997   }
998 #endif
999 }
1000 
1001 
1002 /**
1003   Change the query result object used to return the final result of
1004   the unit, replacing occurences of old_result with new_result.
1005 
1006   @param new_result New query result object
1007   @param old_result Old query result object
1008 
1009   @retval false Success
1010   @retval true  Error
1011 */
1012 
1013 bool
change_query_result(Query_result_interceptor * new_result,Query_result_interceptor * old_result)1014 st_select_lex_unit::change_query_result(Query_result_interceptor *new_result,
1015                                         Query_result_interceptor *old_result)
1016 {
1017   for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
1018   {
1019     if (sl->query_result() && sl->change_query_result(new_result, old_result))
1020       return true; /* purecov: inspected */
1021   }
1022   set_query_result(new_result);
1023   return false;
1024 }
1025 
1026 /**
1027   Get column type information for this query expression.
1028 
1029   For a single query block the column types are taken from the list
1030   of selected items of this block.
1031 
1032   For a union this function assumes that st_select_lex_unit::prepare()
1033   has been called and returns the type holders that were created for unioned
1034   column types of all query blocks.
1035 
1036   @note
1037     The implementation of this function should be in sync with
1038     st_select_lex_unit::prepare()
1039 
1040   @returns List of items as specified in function description
1041 */
1042 
get_unit_column_types()1043 List<Item> *st_select_lex_unit::get_unit_column_types()
1044 {
1045   assert(is_prepared());
1046 
1047   return is_union() ? &types : &first_select()->item_list;
1048 }
1049 
1050 
1051 /**
1052   Get field list for this query expression.
1053 
1054   For a UNION of query blocks, return the field list generated during prepare.
1055   For a single query block, return the field list after all possible
1056   intermediate query processing steps are done (optimization is complete).
1057 
1058   @returns List containing fields of the query expression.
1059 */
1060 
get_field_list()1061 List<Item> *st_select_lex_unit::get_field_list()
1062 {
1063   assert(is_optimized());
1064 
1065   return is_union() ? &types : first_select()->join->fields;
1066 }
1067 
1068 
1069 /**
1070   Cleanup after preparation or one round of execution.
1071 
1072   @return false if previous execution was successful, and true otherwise
1073 */
1074 
cleanup(bool full)1075 bool st_select_lex::cleanup(bool full)
1076 {
1077   DBUG_ENTER("st_select_lex::cleanup()");
1078 
1079   bool error= false;
1080   if (join)
1081   {
1082     if (full)
1083     {
1084       assert(join->select_lex == this);
1085       error= join->destroy();
1086       delete join;
1087       join= NULL;
1088     }
1089     else
1090       join->cleanup();
1091   }
1092 
1093   for (SELECT_LEX_UNIT *lex_unit= first_inner_unit(); lex_unit ;
1094        lex_unit= lex_unit->next_unit())
1095   {
1096     error|= lex_unit->cleanup(full);
1097   }
1098   inner_refs_list.empty();
1099   DBUG_RETURN(error);
1100 }
1101 
1102 
cleanup_all_joins()1103 void st_select_lex::cleanup_all_joins()
1104 {
1105   if (join)
1106     join->cleanup();
1107 
1108   for (SELECT_LEX_UNIT *unit= first_inner_unit(); unit; unit= unit->next_unit())
1109   {
1110     for (SELECT_LEX *sl= unit->first_select(); sl; sl= sl->next_select())
1111       sl->cleanup_all_joins();
1112   }
1113 }
1114