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     assert(cleaned == UC_DIRTY);
706     thd->lex->set_current_select(sl);
707 
708     // LIMIT is required for optimization
709     set_limit(sl);
710 
711     if (sl->optimize(thd))
712       DBUG_RETURN(true);
713 
714     /*
715       Accumulate estimated number of rows.
716       1. Implicitly grouped query has one row (with HAVING it has zero or one
717          rows).
718       2. If GROUP BY clause is optimized away because it was a constant then
719          query produces at most one row.
720     */
721     if (query_result())
722       query_result()->estimated_rowcount+=
723         sl->is_implicitly_grouped() || sl->join->group_optimized_away ?
724           1 :  sl->join->best_rowcount;
725 
726   }
727   if (fake_select_lex)
728   {
729     thd->lex->set_current_select(fake_select_lex);
730 
731     set_limit(fake_select_lex);
732 
733     /*
734       In EXPLAIN command, constant subqueries that do not use any
735       tables are executed two times:
736        - 1st time is a real evaluation to get the subquery value
737        - 2nd time is to produce EXPLAIN output rows.
738       1st execution sets certain members (e.g. Query_result) to perform
739       subquery execution rather than EXPLAIN line production. In order
740       to reset them back, we re-do all of the actions (yes it is ugly).
741     */
742     assert(fake_select_lex->with_wild == 0 &&
743            fake_select_lex->master_unit() == this &&
744            !fake_select_lex->group_list.elements &&
745            fake_select_lex->get_table_list() == &result_table_list &&
746            fake_select_lex->where_cond() == NULL &&
747            fake_select_lex->having_cond() == NULL);
748 
749     if (fake_select_lex->optimize(thd))
750       DBUG_RETURN(true);
751   }
752   set_optimized();    // All query blocks optimized, update the state
753   thd->lex->set_current_select(save_select);
754 
755   DBUG_RETURN(false);
756 }
757 
758 
759 /**
760   Explain query starting from this unit.
761 
762   @param ethd  THD of explaining thread
763 
764   @return false if success, true if error
765 */
766 
explain(THD * ethd)767 bool st_select_lex_unit::explain(THD *ethd)
768 {
769   DBUG_ENTER("st_select_lex_unit::explain");
770 
771 #ifndef NDEBUG
772   SELECT_LEX *lex_select_save= thd->lex->current_select();
773 #endif
774   Explain_format *fmt= ethd->lex->explain_format;
775   const bool other= (thd != ethd);
776   bool ret= false;
777 
778   if (!other)
779   {
780     assert(!is_simple() && is_optimized());
781     set_executed();
782   }
783 
784   if (fmt->begin_context(CTX_UNION))
785     DBUG_RETURN(true);
786 
787   for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
788   {
789     if (fmt->begin_context(CTX_QUERY_SPEC))
790       DBUG_RETURN(true);
791     if (explain_query_specification(ethd, sl, CTX_JOIN) ||
792         fmt->end_context(CTX_QUERY_SPEC))
793       DBUG_RETURN(true);
794   }
795 
796   if (fake_select_lex != NULL)
797   {
798     // Don't save result as it's needed only for consequent exec.
799     ret= explain_query_specification(ethd, fake_select_lex, CTX_UNION_RESULT);
800   }
801   if (!other)
802     assert(thd->lex->current_select() == lex_select_save);
803 
804   if (ret)
805     DBUG_RETURN(true);
806   fmt->end_context(CTX_UNION);
807 
808   DBUG_RETURN(false);
809 }
810 
811 
812 /**
813   Execute a query expression that may be a UNION and/or have an ordered result.
814 
815   @param thd          thread handle
816 
817   @returns false if success, true if error
818 */
819 
execute(THD * thd)820 bool st_select_lex_unit::execute(THD *thd)
821 {
822   DBUG_ENTER("st_select_lex_unit::exec");
823   assert(!is_simple() && is_optimized());
824 
825   if (is_executed() && !uncacheable)
826     DBUG_RETURN(false);
827 
828   SELECT_LEX *lex_select_save= thd->lex->current_select();
829 
830   bool status= false;          // Execution error status
831 
832   // Set "executed" state, even though execution may end with an error
833   set_executed();
834 
835   if (item)
836   {
837     item->reset_value_registration();
838 
839     if (item->assigned())
840     {
841       item->assigned(false); // Prepare for re-execution of this unit
842       item->reset();
843       if (table->is_created())
844       {
845         table->file->ha_delete_all_rows();
846         table->file->info(HA_STATUS_VARIABLE);
847       }
848     }
849     // re-enable indexes for next subquery execution
850     if (union_distinct && table->file->ha_enable_indexes(HA_KEY_SWITCH_ALL))
851       DBUG_RETURN(true);       /* purecov: inspected */
852   }
853 
854   for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
855   {
856     thd->lex->set_current_select(sl);
857 
858     if (sl->join->is_executed())
859       sl->join->reset();
860 
861     // Set limit and offset for each execution:
862     set_limit(sl);
863 
864     // Execute this query block
865     sl->join->exec();
866     status= sl->join->error != 0;
867 
868     if (sl == union_distinct)
869     {
870       // This is UNION DISTINCT, so there should be a fake_select_lex
871       assert(fake_select_lex != NULL);
872       if (table->file->ha_disable_indexes(HA_KEY_SWITCH_ALL))
873         DBUG_RETURN(true); /* purecov: inspected */
874       table->no_keyread= 1;
875     }
876     if (status)
877       DBUG_RETURN(true);
878 
879     if (union_result->flush())
880       DBUG_RETURN(true); /* purecov: inspected */
881   }
882 
883   if (fake_select_lex != NULL)
884   {
885     thd->lex->set_current_select(fake_select_lex);
886 
887     int error= table->file->info(HA_STATUS_VARIABLE);
888     if (error)
889     {
890       table->file->print_error(error, MYF(0)); /* purecov: inspected */
891       DBUG_RETURN(true);                       /* purecov: inspected */
892     }
893     // Index might have been used to weedout duplicates for UNION DISTINCT
894     table->file->ha_index_or_rnd_end();
895     set_limit(fake_select_lex);
896     JOIN *join= fake_select_lex->join;
897     join->reset();
898     join->exec();
899     status= join->error != 0;
900     fake_select_lex->table_list.empty();
901     thd->current_found_rows= (ulonglong)table->file->stats.records;
902   }
903 
904   thd->lex->set_current_select(lex_select_save);
905   DBUG_RETURN(status);
906 }
907 
908 
909 /**
910   Cleanup this query expression object after preparation or one round
911   of execution. After the cleanup, the object can be reused for a
912   new round of execution, but a new optimization will be needed before
913   the execution.
914 
915   @return false if previous execution was successful, and true otherwise
916 */
917 
cleanup(bool full)918 bool st_select_lex_unit::cleanup(bool full)
919 {
920   DBUG_ENTER("st_select_lex_unit::cleanup");
921 
922   assert(thd == current_thd);
923 
924   if (cleaned >= (full ? UC_CLEAN : UC_PART_CLEAN))
925   {
926 #ifndef NDEBUG
927     if (cleaned == UC_CLEAN)
928       for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
929         assert(!sl->join);
930 #endif
931     DBUG_RETURN(false);
932   }
933 
934   cleaned= (full ? UC_CLEAN : UC_PART_CLEAN);
935 
936   bool error= false;
937   for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
938     error|= sl->cleanup(full);
939 
940   if (fake_select_lex)
941     error|= fake_select_lex->cleanup(full);
942 
943   // fake_select_lex's table depends on Temp_table_param inside union_result
944   if (full && union_result)
945   {
946     union_result->cleanup();
947     delete union_result;
948     union_result= NULL; // Safety
949     if (table)
950       free_tmp_table(thd, table);
951     table= NULL; // Safety
952   }
953 
954   /*
955     explain_marker is (mostly) a property determined at prepare time and must
956     thus be preserved for the next execution, if this is a prepared statement.
957   */
958 
959   DBUG_RETURN(error);
960 }
961 
962 
963 #ifndef NDEBUG
assert_not_fully_clean()964 void st_select_lex_unit::assert_not_fully_clean()
965 {
966   assert(cleaned < UC_CLEAN);
967   SELECT_LEX *sl= first_select();
968   for (;;)
969   {
970     if (!sl)
971     {
972       sl= fake_select_lex;
973       if (!sl)
974         break;
975     }
976     for (SELECT_LEX_UNIT *lex_unit= sl->first_inner_unit(); lex_unit ;
977          lex_unit= lex_unit->next_unit())
978       lex_unit->assert_not_fully_clean();
979     if (sl == fake_select_lex)
980       break;
981     else
982       sl= sl->next_select();
983   }
984 }
985 #endif
986 
987 
reinit_exec_mechanism()988 void st_select_lex_unit::reinit_exec_mechanism()
989 {
990   prepared= optimized= executed= false;
991 #ifndef NDEBUG
992   if (is_union())
993   {
994     List_iterator_fast<Item> it(item_list);
995     Item *field;
996     while ((field= it++))
997     {
998       /*
999 	we can't cleanup here, because it broke link to temporary table field,
1000 	but have to drop fixed flag to allow next fix_field of this field
1001 	during re-executing
1002       */
1003       field->fixed= 0;
1004     }
1005   }
1006 #endif
1007 }
1008 
1009 
1010 /**
1011   Change the query result object used to return the final result of
1012   the unit, replacing occurences of old_result with new_result.
1013 
1014   @param new_result New query result object
1015   @param old_result Old query result object
1016 
1017   @retval false Success
1018   @retval true  Error
1019 */
1020 
1021 bool
change_query_result(Query_result_interceptor * new_result,Query_result_interceptor * old_result)1022 st_select_lex_unit::change_query_result(Query_result_interceptor *new_result,
1023                                         Query_result_interceptor *old_result)
1024 {
1025   for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
1026   {
1027     if (sl->query_result() && sl->change_query_result(new_result, old_result))
1028       return true; /* purecov: inspected */
1029   }
1030   set_query_result(new_result);
1031   return false;
1032 }
1033 
1034 /**
1035   Get column type information for this query expression.
1036 
1037   For a single query block the column types are taken from the list
1038   of selected items of this block.
1039 
1040   For a union this function assumes that st_select_lex_unit::prepare()
1041   has been called and returns the type holders that were created for unioned
1042   column types of all query blocks.
1043 
1044   @note
1045     The implementation of this function should be in sync with
1046     st_select_lex_unit::prepare()
1047 
1048   @returns List of items as specified in function description
1049 */
1050 
get_unit_column_types()1051 List<Item> *st_select_lex_unit::get_unit_column_types()
1052 {
1053   assert(is_prepared());
1054 
1055   return is_union() ? &types : &first_select()->item_list;
1056 }
1057 
1058 
1059 /**
1060   Get field list for this query expression.
1061 
1062   For a UNION of query blocks, return the field list generated during prepare.
1063   For a single query block, return the field list after all possible
1064   intermediate query processing steps are done (optimization is complete).
1065 
1066   @returns List containing fields of the query expression.
1067 */
1068 
get_field_list()1069 List<Item> *st_select_lex_unit::get_field_list()
1070 {
1071   assert(is_optimized());
1072 
1073   return is_union() ? &types : first_select()->join->fields;
1074 }
1075 
1076 
1077 /**
1078   Cleanup after preparation or one round of execution.
1079 
1080   @return false if previous execution was successful, and true otherwise
1081 */
1082 
cleanup(bool full)1083 bool st_select_lex::cleanup(bool full)
1084 {
1085   DBUG_ENTER("st_select_lex::cleanup()");
1086 
1087   bool error= false;
1088   if (join)
1089   {
1090     if (full)
1091     {
1092       assert(join->select_lex == this);
1093       error= join->destroy();
1094       delete join;
1095       join= NULL;
1096     }
1097     else
1098       join->cleanup();
1099   }
1100 
1101   for (SELECT_LEX_UNIT *lex_unit= first_inner_unit(); lex_unit ;
1102        lex_unit= lex_unit->next_unit())
1103   {
1104     error|= lex_unit->cleanup(full);
1105   }
1106   inner_refs_list.empty();
1107   DBUG_RETURN(error);
1108 }
1109 
1110 
cleanup_all_joins()1111 void st_select_lex::cleanup_all_joins()
1112 {
1113   if (join)
1114     join->cleanup();
1115 
1116   for (SELECT_LEX_UNIT *unit= first_inner_unit(); unit; unit= unit->next_unit())
1117   {
1118     for (SELECT_LEX *sl= unit->first_select(); sl; sl= sl->next_select())
1119       sl->cleanup_all_joins();
1120   }
1121 }
1122