1 /* Copyright (c) 2000, 2017, Oracle and/or its affiliates.
2    Copyright (c) 2010, 2020, MariaDB Corporation.
3 
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; version 2 of the License.
7 
8    This program is distributed in the hope that it will be useful,
9    but WITHOUT ANY WARRANTY; without even the implied warranty of
10    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11    GNU General Public License for more details.
12 
13    You should have received a copy of the GNU General Public License
14    along with this program; if not, write to the Free Software
15    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335  USA */
16 
17 
18 /*
19   UNION  of select's
20   UNION's  were introduced by Monty and Sinisa <sinisa@mysql.com>
21 */
22 
23 #include "mariadb.h"
24 #include "sql_priv.h"
25 #include "unireg.h"
26 #include "sql_union.h"
27 #include "sql_select.h"
28 #include "sql_cursor.h"
29 #include "sql_base.h"                           // fill_record
30 #include "filesort.h"                           // filesort_free_buffers
31 #include "sql_view.h"
32 #include "sql_cte.h"
33 #include "item_windowfunc.h"
34 
mysql_union(THD * thd,LEX * lex,select_result * result,SELECT_LEX_UNIT * unit,ulong setup_tables_done_option)35 bool mysql_union(THD *thd, LEX *lex, select_result *result,
36                  SELECT_LEX_UNIT *unit, ulong setup_tables_done_option)
37 {
38   DBUG_ENTER("mysql_union");
39   bool res;
40   if (!(res= unit->prepare(unit->derived, result, SELECT_NO_UNLOCK |
41                            setup_tables_done_option)))
42     res= unit->exec();
43   res|= unit->cleanup();
44   DBUG_RETURN(res);
45 }
46 
47 
48 /***************************************************************************
49 ** store records in temporary table for UNION
50 ***************************************************************************/
51 
prepare(List<Item> & list,SELECT_LEX_UNIT * u)52 int select_unit::prepare(List<Item> &list, SELECT_LEX_UNIT *u)
53 {
54   unit= u;
55   return 0;
56 }
57 
58 /**
59   This called by SELECT_LEX_UNIT::exec when select changed
60 */
61 
change_select()62 void select_unit::change_select()
63 {
64   uint current_select_number= thd->lex->current_select->select_number;
65   DBUG_ENTER("select_unit::change_select");
66   DBUG_PRINT("enter", ("select in unit change: %u -> %u",
67                        curr_sel, current_select_number));
68   DBUG_ASSERT(curr_sel != current_select_number);
69   curr_sel= current_select_number;
70   /* New SELECT processing starts */
71   DBUG_ASSERT(table->file->inited == 0);
72   step= thd->lex->current_select->linkage;
73   switch (step)
74   {
75   case INTERSECT_TYPE:
76     intersect_mark->value= prev_step= curr_step;
77     curr_step= current_select_number;
78     break;
79   case EXCEPT_TYPE:
80     break;
81   default:
82     step= UNION_TYPE;
83     break;
84   }
85   DBUG_VOID_RETURN;
86 }
87 /**
88   Fill temporary tables for UNION/EXCEPT/INTERSECT
89 
90   @Note
91 UNION:
92   just add records to the table (with 'counter' field first if INTERSECT
93   present in the sequence).
94 EXCEPT:
95   looks for the record in the table (with 'counter' field first if
96   INTERSECT present in the sequence) and delete it if found
97 INTESECT:
98   looks for the same record with 'counter' field of previous operation,
99   put as a 'counter' number of the current SELECT.
100     We scan the table and remove all records which marked with not last
101   'counter' after processing all records in send_eof and only if it last
102   SELECT of sequence of INTERSECTS.
103 
104   @param values          List of record items to process.
105 
106   @retval  0 - OK
107   @retval -1 - duplicate
108   @retval  1 - error
109 */
send_data(List<Item> & values)110 int select_unit::send_data(List<Item> &values)
111 {
112   int rc;
113   int not_reported_error= 0;
114   if (unit->offset_limit_cnt)
115   {						// using limit offset,count
116     unit->offset_limit_cnt--;
117     return 0;
118   }
119   if (thd->killed == ABORT_QUERY)
120     return 0;
121   if (table->no_rows_with_nulls)
122     table->null_catch_flags= CHECK_ROW_FOR_NULLS_TO_REJECT;
123   if (intersect_mark)
124   {
125     fill_record(thd, table, table->field + 1, values, TRUE, FALSE);
126     table->field[0]->store((ulonglong) curr_step, 1);
127   }
128   else
129     fill_record(thd, table, table->field, values, TRUE, FALSE);
130   if (unlikely(thd->is_error()))
131   {
132     rc= 1;
133     goto end;
134   }
135   if (table->no_rows_with_nulls)
136   {
137     table->null_catch_flags&= ~CHECK_ROW_FOR_NULLS_TO_REJECT;
138     if (table->null_catch_flags)
139     {
140       rc= 0;
141       goto end;
142     }
143   }
144 
145   // select_unit::change_select() change step & Co correctly for each SELECT
146   switch (step)
147   {
148     case UNION_TYPE:
149     {
150       if (unlikely((write_err=
151                     table->file->ha_write_tmp_row(table->record[0]))))
152       {
153         if (write_err == HA_ERR_FOUND_DUPP_KEY)
154         {
155           /*
156             Inform upper level that we found a duplicate key, that should not
157             be counted as part of limit
158           */
159           rc= -1;
160           goto end;
161         }
162         bool is_duplicate= FALSE;
163         /* create_internal_tmp_table_from_heap will generate error if needed */
164         if (table->file->is_fatal_error(write_err, HA_CHECK_DUP) &&
165             create_internal_tmp_table_from_heap(thd, table,
166                                                 tmp_table_param.start_recinfo,
167                                                 &tmp_table_param.recinfo,
168                                                 write_err, 1, &is_duplicate))
169         {
170           rc= 1;
171           goto end;
172         }
173 
174         if (is_duplicate)
175         {
176           rc= -1;
177           goto end;
178         }
179       }
180       break;
181     }
182     case EXCEPT_TYPE:
183     {
184       int find_res;
185       /*
186         The temporary table uses very first index or constrain for
187         checking unique constrain.
188       */
189       if (!(find_res= table->file->find_unique_row(table->record[0], 0)))
190       {
191         DBUG_ASSERT(!table->triggers);
192         table->status|= STATUS_DELETED;
193         not_reported_error= table->file->ha_delete_tmp_row(table->record[0]);
194         rc= MY_TEST(not_reported_error);
195         goto end;
196       }
197       else
198       {
199         if ((rc= not_reported_error= (find_res != 1)))
200           goto end;
201       }
202       break;
203     }
204     case INTERSECT_TYPE:
205     {
206       int find_res;
207       /*
208         The temporary table uses very first index or constrain for
209         checking unique constrain.
210       */
211       if (!(find_res= table->file->find_unique_row(table->record[0], 0)))
212       {
213         DBUG_ASSERT(!table->triggers);
214         if (table->field[0]->val_int() != prev_step)
215         {
216           rc= 0;
217           goto end;
218         }
219         store_record(table, record[1]);
220         table->field[0]->store(curr_step, 0);
221         not_reported_error= table->file->ha_update_tmp_row(table->record[1],
222                                                             table->record[0]);
223         rc= MY_TEST(not_reported_error);
224         DBUG_ASSERT(rc != HA_ERR_RECORD_IS_THE_SAME);
225         goto end;
226       }
227       else
228       {
229         if ((rc= not_reported_error= (find_res != 1)))
230           goto end;
231       }
232       break;
233     }
234     default:
235       DBUG_ASSERT(0);
236   }
237   rc= 0;
238 
239 end:
240   if (unlikely(not_reported_error))
241   {
242     DBUG_ASSERT(rc);
243     table->file->print_error(not_reported_error, MYF(0));
244   }
245   return rc;
246 }
247 
send_eof()248 bool select_unit::send_eof()
249 {
250   if (step != INTERSECT_TYPE ||
251       (thd->lex->current_select->next_select() &&
252        thd->lex->current_select->next_select()->linkage == INTERSECT_TYPE))
253   {
254     /*
255       it is not INTESECT or next SELECT in the sequence is INTERSECT so no
256       need filtering (the last INTERSECT in this sequence of intersects will
257       filter).
258     */
259     return 0;
260   }
261 
262   /*
263     It is last select in the sequence of INTERSECTs so we should filter out
264     all records except marked with actual counter.
265 
266    TODO: as optimization for simple case this could be moved to
267    'fake_select' WHERE condition
268   */
269   handler *file= table->file;
270   int error;
271 
272   if (unlikely(file->ha_rnd_init_with_error(1)))
273     return 1;
274 
275   do
276   {
277     if (unlikely(error= file->ha_rnd_next(table->record[0])))
278     {
279       if (error == HA_ERR_END_OF_FILE)
280       {
281         error= 0;
282         break;
283       }
284       break;
285     }
286     if (table->field[0]->val_int() != curr_step)
287       error= file->ha_delete_tmp_row(table->record[0]);
288   } while (likely(!error));
289   file->ha_rnd_end();
290 
291   if (unlikely(error))
292     table->file->print_error(error, MYF(0));
293 
294   return(MY_TEST(error));
295 }
296 
297 
send_data(List<Item> & values)298 int select_union_recursive::send_data(List<Item> &values)
299 {
300   int rc= select_unit::send_data(values);
301 
302   if (rc == 0 &&
303       write_err != HA_ERR_FOUND_DUPP_KEY &&
304       write_err != HA_ERR_FOUND_DUPP_UNIQUE)
305   {
306     int err;
307     if ((err= incr_table->file->ha_write_tmp_row(table->record[0])))
308     {
309       bool is_duplicate;
310       rc= create_internal_tmp_table_from_heap(thd, incr_table,
311                                               tmp_table_param.start_recinfo,
312                                               &tmp_table_param.recinfo,
313 					      err, 1, &is_duplicate);
314     }
315   }
316 
317   return rc;
318 }
319 
320 
flush()321 bool select_unit::flush()
322 {
323   int error;
324   if (unlikely((error=table->file->extra(HA_EXTRA_NO_CACHE))))
325   {
326     table->file->print_error(error, MYF(0));
327     return 1;
328   }
329   return 0;
330 }
331 
332 
333 /*
334   Create a temporary table to store the result of select_union.
335 
336   SYNOPSIS
337     select_unit::create_result_table()
338       thd                thread handle
339       column_types       a list of items used to define columns of the
340                          temporary table
341       is_union_distinct  if set, the temporary table will eliminate
342                          duplicates on insert
343       options            create options
344       table_alias        name of the temporary table
345       bit_fields_as_long convert bit fields to ulonglong
346       create_table       whether to physically create result table
347       keep_row_order     keep rows in order as they were inserted
348       hidden             number of hidden fields (for INTERSECT)
349 
350   DESCRIPTION
351     Create a temporary table that is used to store the result of a UNION,
352     derived table, or a materialized cursor.
353 
354   RETURN VALUE
355     0                    The table has been created successfully.
356     1                    create_tmp_table failed.
357 */
358 
359 bool
create_result_table(THD * thd_arg,List<Item> * column_types,bool is_union_distinct,ulonglong options,const LEX_CSTRING * alias,bool bit_fields_as_long,bool create_table,bool keep_row_order,uint hidden)360 select_unit::create_result_table(THD *thd_arg, List<Item> *column_types,
361                                   bool is_union_distinct, ulonglong options,
362                                  const LEX_CSTRING *alias,
363                                   bool bit_fields_as_long, bool create_table,
364                                   bool keep_row_order,
365                                   uint hidden)
366 {
367   DBUG_ASSERT(table == 0);
368   tmp_table_param.init();
369   tmp_table_param.field_count= column_types->elements;
370   tmp_table_param.bit_fields_as_long= bit_fields_as_long;
371   tmp_table_param.hidden_field_count= hidden;
372 
373   if (! (table= create_tmp_table(thd_arg, &tmp_table_param, *column_types,
374                                  (ORDER*) 0, is_union_distinct, 1,
375                                  options, HA_POS_ERROR, alias,
376                                  !create_table, keep_row_order)))
377     return TRUE;
378 
379   table->keys_in_use_for_query.clear_all();
380   for (uint i=0; i < table->s->fields; i++)
381     table->field[i]->flags &= ~(PART_KEY_FLAG | PART_INDIRECT_KEY_FLAG);
382 
383   if (create_table)
384   {
385     table->file->extra(HA_EXTRA_WRITE_CACHE);
386     table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
387   }
388   return FALSE;
389 }
390 
391 bool
create_result_table(THD * thd_arg,List<Item> * column_types,bool is_union_distinct,ulonglong options,const LEX_CSTRING * alias,bool bit_fields_as_long,bool create_table,bool keep_row_order,uint hidden)392 select_union_recursive::create_result_table(THD *thd_arg,
393                                             List<Item> *column_types,
394                                             bool is_union_distinct,
395                                             ulonglong options,
396                                             const LEX_CSTRING *alias,
397                                             bool bit_fields_as_long,
398                                             bool create_table,
399                                             bool keep_row_order,
400                                             uint hidden)
401 {
402   if (select_unit::create_result_table(thd_arg, column_types,
403                                        is_union_distinct, options,
404                                        &empty_clex_str, bit_fields_as_long,
405                                        create_table, keep_row_order,
406                                        hidden))
407     return true;
408 
409   incr_table_param.init();
410   incr_table_param.field_count= column_types->elements;
411   incr_table_param.bit_fields_as_long= bit_fields_as_long;
412   if (! (incr_table= create_tmp_table(thd_arg, &incr_table_param, *column_types,
413                                       (ORDER*) 0, false, 1,
414                                       options, HA_POS_ERROR, &empty_clex_str,
415                                       true, keep_row_order)))
416     return true;
417 
418   incr_table->keys_in_use_for_query.clear_all();
419   for (uint i=0; i < table->s->fields; i++)
420     incr_table->field[i]->flags &= ~(PART_KEY_FLAG | PART_INDIRECT_KEY_FLAG);
421 
422   return false;
423 }
424 
425 
426 /**
427   Reset and empty the temporary table that stores the materialized query
428   result.
429 
430   @note The cleanup performed here is exactly the same as for the two temp
431   tables of JOIN - exec_tmp_table_[1 | 2].
432 */
433 
cleanup()434 void select_unit::cleanup()
435 {
436   table->file->extra(HA_EXTRA_RESET_STATE);
437   table->file->ha_delete_all_rows();
438 }
439 
440 
cleanup()441 void select_union_recursive::cleanup()
442 {
443   if (table)
444   {
445     select_unit::cleanup();
446     free_tmp_table(thd, table);
447   }
448 
449   if (incr_table)
450   {
451     if (incr_table->is_created())
452     {
453       incr_table->file->extra(HA_EXTRA_RESET_STATE);
454       incr_table->file->ha_delete_all_rows();
455     }
456     free_tmp_table(thd, incr_table);
457   }
458 
459   List_iterator<TABLE_LIST> it(rec_table_refs);
460   TABLE_LIST *tbl;
461   while ((tbl= it++))
462   {
463     TABLE *tab= tbl->table;
464     if (tab->is_created())
465     {
466       tab->file->extra(HA_EXTRA_RESET_STATE);
467       tab->file->ha_delete_all_rows();
468     }
469     /*
470       The table will be closed later in close_thread_tables(),
471       because it might be used in the statements like
472       ANALYZE WITH r AS (...) SELECT * from r
473       where r is defined through recursion.
474     */
475     tab->next= thd->rec_tables;
476     thd->rec_tables= tab;
477     tbl->derived_result= 0;
478   }
479 }
480 
481 
482 /**
483   Replace the current result with new_result and prepare it.
484 
485   @param new_result New result pointer
486 
487   @retval FALSE Success
488   @retval TRUE  Error
489 */
490 
change_result(select_result * new_result)491 bool select_union_direct::change_result(select_result *new_result)
492 {
493   result= new_result;
494   return (result->prepare(unit->types, unit) || result->prepare2(NULL));
495 }
496 
497 
postponed_prepare(List<Item> & types)498 bool select_union_direct::postponed_prepare(List<Item> &types)
499 {
500   if (result != NULL)
501     return (result->prepare(types, unit) || result->prepare2(NULL));
502   else
503     return false;
504 }
505 
506 
send_result_set_metadata(List<Item> & list,uint flags)507 bool select_union_direct::send_result_set_metadata(List<Item> &list, uint flags)
508 {
509   if (done_send_result_set_metadata)
510     return false;
511   done_send_result_set_metadata= true;
512 
513   /*
514     Set global offset and limit to be used in send_data(). These can
515     be variables in prepared statements or stored programs, so they
516     must be reevaluated for each execution.
517    */
518   offset= unit->global_parameters()->get_offset();
519   limit= unit->global_parameters()->get_limit();
520   if (limit + offset >= limit)
521     limit+= offset;
522   else
523     limit= HA_POS_ERROR; /* purecov: inspected */
524 
525   return result->send_result_set_metadata(unit->types, flags);
526 }
527 
528 
send_data(List<Item> & items)529 int select_union_direct::send_data(List<Item> &items)
530 {
531   if (!limit)
532     return false;
533   limit--;
534   if (offset)
535   {
536     offset--;
537     return false;
538   }
539 
540   send_records++;
541   fill_record(thd, table, table->field, items, true, false);
542   if (unlikely(thd->is_error()))
543     return true; /* purecov: inspected */
544 
545   return result->send_data(unit->item_list);
546 }
547 
548 
initialize_tables(JOIN * join)549 bool select_union_direct::initialize_tables (JOIN *join)
550 {
551   if (done_initialize_tables)
552     return false;
553   done_initialize_tables= true;
554 
555   return result->initialize_tables(join);
556 }
557 
558 
send_eof()559 bool select_union_direct::send_eof()
560 {
561   // Reset for each SELECT_LEX, so accumulate here
562   limit_found_rows+= thd->limit_found_rows;
563 
564   if (unit->thd->lex->current_select == last_select_lex)
565   {
566     thd->limit_found_rows= limit_found_rows;
567 
568     // Reset and make ready for re-execution
569     done_send_result_set_metadata= false;
570     done_initialize_tables= false;
571 
572     return result->send_eof();
573   }
574   else
575     return false;
576 }
577 
578 
579 /*
580   initialization procedures before fake_select_lex preparation()
581 
582   SYNOPSIS
583     st_select_lex_unit::init_prepare_fake_select_lex()
584     thd		- thread handler
585     first_execution - TRUE at the first execution of the union
586 
587   RETURN
588     options of SELECT
589 */
590 
591 void
init_prepare_fake_select_lex(THD * thd_arg,bool first_execution)592 st_select_lex_unit::init_prepare_fake_select_lex(THD *thd_arg,
593                                                   bool first_execution)
594 {
595   thd_arg->lex->current_select= fake_select_lex;
596   fake_select_lex->table_list.link_in_list(&result_table_list,
597                                            &result_table_list.next_local);
598   fake_select_lex->context.table_list=
599     fake_select_lex->context.first_name_resolution_table=
600     fake_select_lex->get_table_list();
601   /*
602     The flag fake_select_lex->first_execution indicates whether this is
603     called at the first execution of the statement, while first_execution
604     shows whether this is called at the first execution of the union that
605     may form just a subselect.
606   */
607   if ((fake_select_lex->changed_elements & TOUCHED_SEL_COND) &&
608       first_execution)
609   {
610     for (ORDER *order= global_parameters()->order_list.first;
611          order;
612          order= order->next)
613       order->item= &order->item_ptr;
614   }
615   for (ORDER *order= global_parameters()->order_list.first;
616        order;
617        order=order->next)
618   {
619     (*order->item)->walk(&Item::change_context_processor, 0,
620                          &fake_select_lex->context);
621     (*order->item)->walk(&Item::set_fake_select_as_master_processor, 0,
622                          fake_select_lex);
623   }
624 }
625 
626 
prepare_join(THD * thd_arg,SELECT_LEX * sl,select_result * tmp_result,ulong additional_options,bool is_union_select)627 bool st_select_lex_unit::prepare_join(THD *thd_arg, SELECT_LEX *sl,
628                                       select_result *tmp_result,
629                                       ulong additional_options,
630                                       bool is_union_select)
631 {
632   DBUG_ENTER("st_select_lex_unit::prepare_join");
633   TABLE_LIST *derived= sl->master_unit()->derived;
634   bool can_skip_order_by;
635   sl->options|=  SELECT_NO_UNLOCK;
636   JOIN *join= new JOIN(thd_arg, sl->item_list,
637                        (sl->options | thd_arg->variables.option_bits |
638                         additional_options),
639                        tmp_result);
640   if (!join)
641     DBUG_RETURN(true);
642 
643   thd_arg->lex->current_select= sl;
644 
645   can_skip_order_by= is_union_select && !(sl->braces && sl->explicit_limit);
646 
647   saved_error= join->prepare(sl->table_list.first,
648                              sl->with_wild,
649                              (derived && derived->merged ? NULL : sl->where),
650                              (can_skip_order_by ? 0 :
651                               sl->order_list.elements) +
652                              sl->group_list.elements,
653                              can_skip_order_by ?
654                              NULL : sl->order_list.first,
655                              can_skip_order_by,
656                              sl->group_list.first,
657                              sl->having,
658                              (is_union_select ? NULL :
659                               thd_arg->lex->proc_list.first),
660                              sl, this);
661 
662   /* There are no * in the statement anymore (for PS) */
663   sl->with_wild= 0;
664   last_procedure= join->procedure;
665 
666   if (unlikely(saved_error || (saved_error= thd_arg->is_fatal_error)))
667     DBUG_RETURN(true);
668   /*
669     Remove all references from the select_lex_units to the subqueries that
670     are inside the ORDER BY clause.
671   */
672   if (can_skip_order_by)
673   {
674     for (ORDER *ord= (ORDER *)sl->order_list.first; ord; ord= ord->next)
675     {
676       (*ord->item)->walk(&Item::eliminate_subselect_processor, FALSE, NULL);
677     }
678   }
679   DBUG_RETURN(false);
680 }
681 
682 
683 /**
684   Aggregate data type handlers for the "count" leftmost UNION parts.
685 */
join_union_type_handlers(THD * thd_arg,Type_holder * holders,uint count)686 bool st_select_lex_unit::join_union_type_handlers(THD *thd_arg,
687                                                   Type_holder *holders,
688                                                   uint count)
689 {
690   DBUG_ENTER("st_select_lex_unit::join_union_type_handlers");
691   SELECT_LEX *first_sl= first_select(), *sl= first_sl;
692   for (uint i= 0; i < count ; sl= sl->next_select(), i++)
693   {
694     Item *item;
695     List_iterator_fast<Item> it(sl->item_list);
696     for (uint pos= 0; (item= it++); pos++)
697     {
698       const Type_handler *item_type_handler= item->real_type_handler();
699       if (sl == first_sl)
700         holders[pos].set_handler(item_type_handler);
701       else
702       {
703         DBUG_ASSERT(first_sl->item_list.elements == sl->item_list.elements);
704         if (holders[pos].aggregate_for_result(item_type_handler))
705         {
706           my_error(ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION, MYF(0),
707                    holders[pos].type_handler()->name().ptr(),
708                    item_type_handler->name().ptr(),
709                    "UNION");
710           DBUG_RETURN(true);
711         }
712       }
713     }
714   }
715   DBUG_RETURN(false);
716 }
717 
718 
719 /**
720   Aggregate data type attributes for the "count" leftmost UNION parts.
721 */
join_union_type_attributes(THD * thd_arg,Type_holder * holders,uint count)722 bool st_select_lex_unit::join_union_type_attributes(THD *thd_arg,
723                                                     Type_holder *holders,
724                                                     uint count)
725 {
726   DBUG_ENTER("st_select_lex_unit::join_union_type_attributes");
727   SELECT_LEX *sl, *first_sl= first_select();
728   uint item_pos;
729   for (uint pos= 0; pos < first_sl->item_list.elements; pos++)
730   {
731     if (holders[pos].alloc_arguments(thd_arg, count))
732       DBUG_RETURN(true);
733   }
734   for (item_pos= 0, sl= first_sl ;
735        item_pos < count;
736        sl= sl->next_select(), item_pos++)
737   {
738     Item *item_tmp;
739     List_iterator_fast<Item> itx(sl->item_list);
740     for (uint holder_pos= 0 ; (item_tmp= itx++); holder_pos++)
741     {
742       /*
743         If the outer query has a GROUP BY clause, an outer reference to this
744         query block may have been wrapped in a Item_outer_ref, which has not
745         been fixed yet. An Item_type_holder must be created based on a fixed
746         Item, so use the inner Item instead.
747       */
748       DBUG_ASSERT(item_tmp->fixed ||
749                   (item_tmp->type() == Item::REF_ITEM &&
750                    ((Item_ref *)(item_tmp))->ref_type() ==
751                    Item_ref::OUTER_REF));
752       if (!item_tmp->fixed)
753         item_tmp= item_tmp->real_item();
754       holders[holder_pos].add_argument(item_tmp);
755     }
756   }
757   for (uint pos= 0; pos < first_sl->item_list.elements; pos++)
758   {
759     if (holders[pos].aggregate_attributes(thd_arg))
760       DBUG_RETURN(true);
761   }
762   DBUG_RETURN(false);
763 }
764 
765 
766 /**
767   Join data types for the leftmost "count" UNION parts
768   and store corresponding Item_type_holder's into "types".
769 */
join_union_item_types(THD * thd_arg,List<Item> & types,uint count)770 bool st_select_lex_unit::join_union_item_types(THD *thd_arg,
771                                                List<Item> &types,
772                                                uint count)
773 {
774   DBUG_ENTER("st_select_lex_unit::join_union_select_list_types");
775   SELECT_LEX *first_sl= first_select();
776   Type_holder *holders;
777 
778   if (!(holders= new (thd_arg->mem_root)
779                  Type_holder[first_sl->item_list.elements]) ||
780      join_union_type_handlers(thd_arg, holders, count) ||
781      join_union_type_attributes(thd_arg, holders, count))
782     DBUG_RETURN(true);
783 
784   bool is_recursive= with_element && with_element->is_recursive;
785   types.empty();
786   List_iterator_fast<Item> it(first_sl->item_list);
787   Item *item_tmp;
788   for (uint pos= 0; (item_tmp= it++); pos++)
789   {
790     /*
791       SQL standard requires forced nullability only for
792       recursive columns. However type aggregation in our
793       implementation so far does not differentiate between
794       recursive and non-recursive columns of a recursive CTE.
795       TODO: this should be fixed.
796     */
797     bool pos_maybe_null= is_recursive ? true : holders[pos].get_maybe_null();
798 
799     /* Error's in 'new' will be detected after loop */
800     types.push_back(new (thd_arg->mem_root)
801                     Item_type_holder(thd_arg,
802                                      item_tmp,
803                                      holders[pos].type_handler(),
804                                      &holders[pos]/*Type_all_attributes*/,
805                                      pos_maybe_null));
806   }
807   if (unlikely(thd_arg->is_fatal_error))
808     DBUG_RETURN(true); // out of memory
809   DBUG_RETURN(false);
810 }
811 
812 
prepare(TABLE_LIST * derived_arg,select_result * sel_result,ulong additional_options)813 bool st_select_lex_unit::prepare(TABLE_LIST *derived_arg,
814                                  select_result *sel_result,
815                                  ulong additional_options)
816 {
817   SELECT_LEX *lex_select_save= thd->lex->current_select;
818   SELECT_LEX *sl, *first_sl= first_select();
819   bool is_recursive= with_element && with_element->is_recursive;
820   bool is_rec_result_table_created= false;
821   uint union_part_count= 0;
822   select_result *tmp_result;
823   bool is_union_select;
824   bool have_except= FALSE, have_intersect= FALSE;
825   bool instantiate_tmp_table= false;
826   bool single_tvc= !first_sl->next_select() && first_sl->tvc &&
827                    !fake_select_lex;
828   DBUG_ENTER("st_select_lex_unit::prepare");
829   DBUG_ASSERT(thd == current_thd);
830 
831   if (is_recursive && (sl= first_sl->next_select()))
832   {
833     SELECT_LEX *next_sl;
834     for ( ; ; sl= next_sl)
835     {
836       next_sl= sl->next_select();
837       if (!next_sl)
838         break;
839       if (next_sl->with_all_modifier != sl->with_all_modifier)
840       {
841         my_error(ER_NOT_SUPPORTED_YET, MYF(0),
842          "mix of ALL and DISTINCT UNION operations in recursive CTE spec");
843         DBUG_RETURN(TRUE);
844       }
845     }
846   }
847 
848   describe= additional_options & SELECT_DESCRIBE;
849 
850   /*
851     Save fake_select_lex in case we don't need it for anything but
852     global parameters.
853   */
854   if (saved_fake_select_lex == NULL) // Don't overwrite on PS second prepare
855     saved_fake_select_lex= fake_select_lex;
856 
857   /*
858     result object should be reassigned even if preparing already done for
859     max/min subquery (ALL/ANY optimization)
860   */
861   result= sel_result;
862 
863   if (prepared)
864   {
865     if (describe)
866     {
867       /* fast reinit for EXPLAIN */
868       for (sl= first_sl; sl; sl= sl->next_select())
869       {
870 	if (sl->tvc)
871 	{
872 	  sl->tvc->result= result;
873 	  if (result->prepare(sl->item_list, this))
874 	    DBUG_RETURN(TRUE);
875 	  sl->tvc->select_options|= SELECT_DESCRIBE;
876 	}
877 	else
878 	{
879 	  sl->join->result= result;
880 	  select_limit_cnt= HA_POS_ERROR;
881 	  offset_limit_cnt= 0;
882 	  if (!sl->join->procedure &&
883 	      result->prepare(sl->join->fields_list, this))
884 	  {
885 	    DBUG_RETURN(TRUE);
886 	  }
887 	  sl->join->select_options|= SELECT_DESCRIBE;
888 	  sl->join->reinit();
889 	}
890       }
891     }
892     DBUG_RETURN(FALSE);
893   }
894   prepared= 1;
895   saved_error= FALSE;
896 
897   thd->lex->current_select= sl= first_sl;
898   found_rows_for_union= first_sl->options & OPTION_FOUND_ROWS;
899   is_union_select= is_unit_op() || fake_select_lex || single_tvc;
900 
901   /*
902     If we are reading UNION output and the UNION is in the
903     IN/ANY/ALL/EXISTS subquery, then ORDER BY is redundant and hence should
904     be removed.
905     Example:
906      select ... col IN (select col2 FROM t1 union select col3 from t2 ORDER BY 1)
907 
908     (as for ORDER BY ... LIMIT, it currently not supported inside
909      IN/ALL/ANY subqueries)
910     (For non-UNION this removal of ORDER BY clause is done in
911      check_and_do_in_subquery_rewrites())
912   */
913   if (item && is_unit_op() &&
914       (item->is_in_predicate() || item->is_exists_predicate()))
915   {
916     global_parameters()->order_list.first= NULL;
917     global_parameters()->order_list.elements= 0;
918   }
919 
920   for (SELECT_LEX *s= first_sl; s; s= s->next_select())
921   {
922     switch (s->linkage)
923     {
924     case INTERSECT_TYPE:
925       have_intersect= TRUE;
926       break;
927     case EXCEPT_TYPE:
928       have_except= TRUE;
929       break;
930     default:
931       break;
932     }
933   }
934 
935   /* Global option */
936 
937   if (is_union_select || is_recursive)
938   {
939     if ((is_unit_op() && !union_needs_tmp_table() &&
940         !have_except && !have_intersect) || single_tvc)
941     {
942       SELECT_LEX *last= first_select();
943       while (last->next_select())
944         last= last->next_select();
945       if (!(tmp_result= union_result=
946               new (thd->mem_root) select_union_direct(thd, sel_result,
947                                                           last)))
948         goto err; /* purecov: inspected */
949       fake_select_lex= NULL;
950       instantiate_tmp_table= false;
951     }
952     else
953     {
954       if (!is_recursive)
955 	union_result= new (thd->mem_root) select_unit(thd);
956       else
957       {
958         with_element->rec_result=
959           new (thd->mem_root) select_union_recursive(thd);
960         union_result=  with_element->rec_result;
961         if (fake_select_lex)
962 	{
963           if (fake_select_lex->order_list.first ||
964               fake_select_lex->explicit_limit)
965           {
966 	    my_error(ER_NOT_SUPPORTED_YET, MYF(0),
967                      "global ORDER_BY/LIMIT in recursive CTE spec");
968 	    goto err;
969           }
970           fake_select_lex->cleanup();
971           fake_select_lex= NULL;
972         }
973       }
974       if (!(tmp_result= union_result))
975         goto err; /* purecov: inspected */
976       instantiate_tmp_table= true;
977     }
978   }
979   else
980     tmp_result= sel_result;
981 
982   sl->context.resolve_in_select_list= TRUE;
983 
984   if (!is_union_select && !is_recursive)
985   {
986     if (sl->tvc)
987     {
988       if (sl->tvc->prepare(thd, sl, tmp_result, this))
989 	goto err;
990     }
991     else
992     {
993       if (prepare_join(thd, first_sl, tmp_result, additional_options,
994                      is_union_select))
995         goto err;
996 
997       if (derived_arg && derived_arg->table &&
998           derived_arg->derived_type == VIEW_ALGORITHM_MERGE &&
999           derived_arg->table->versioned())
1000       {
1001         /* Got versioning conditions (see vers_setup_conds()), need to update
1002            derived_arg. */
1003         derived_arg->where= first_sl->where;
1004       }
1005     }
1006     types= first_sl->item_list;
1007     goto cont;
1008   }
1009 
1010   for (;sl; sl= sl->next_select(), union_part_count++)
1011   {
1012     if (sl->tvc)
1013     {
1014       if (sl->tvc->to_be_wrapped_as_with_tail() &&
1015           !(thd->lex->context_analysis_only & CONTEXT_ANALYSIS_ONLY_VIEW))
1016 
1017       {
1018         st_select_lex *wrapper_sl= wrap_tvc_with_tail(thd, sl);
1019         if (!wrapper_sl)
1020           goto err;
1021 
1022         if (sl == first_sl)
1023           first_sl= wrapper_sl;
1024         sl= wrapper_sl;
1025 
1026         if (prepare_join(thd, sl, tmp_result, additional_options,
1027                          is_union_select))
1028 	  goto err;
1029       }
1030       else if (sl->tvc->prepare(thd, sl, tmp_result, this))
1031 	goto err;
1032     }
1033     else if (prepare_join(thd, sl, tmp_result, additional_options,
1034                           is_union_select))
1035       goto err;
1036 
1037     /*
1038       setup_tables_done_option should be set only for very first SELECT,
1039       because it protect from secont setup_tables call for select-like non
1040       select commands (DELETE/INSERT/...) and they use only very first
1041       SELECT (for union it can be only INSERT ... SELECT).
1042     */
1043     additional_options&= ~OPTION_SETUP_TABLES_DONE;
1044 
1045     /*
1046       Use items list of underlaid select for derived tables to preserve
1047       information about fields lengths and exact types
1048     */
1049     if (sl == first_sl)
1050     {
1051       if (with_element)
1052       {
1053         if (with_element->rename_columns_of_derived_unit(thd, this))
1054           goto err;
1055         if (check_duplicate_names(thd, sl->item_list, 0))
1056           goto err;
1057       }
1058     }
1059     else
1060     {
1061       if (first_sl->item_list.elements != sl->item_list.elements)
1062       {
1063         my_message(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT,
1064                    ER_THD(thd, ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT),
1065                    MYF(0));
1066         goto err;
1067       }
1068     }
1069     if (is_recursive)
1070     {
1071       if (!with_element->is_anchor(sl))
1072         sl->uncacheable|= UNCACHEABLE_UNITED;
1073       if (!is_rec_result_table_created &&
1074           (!sl->next_select() ||
1075            sl->next_select() == with_element->first_recursive))
1076       {
1077         ulonglong create_options;
1078         create_options= (first_sl->options | thd->variables.option_bits |
1079                          TMP_TABLE_ALL_COLUMNS);
1080         // Join data types for all non-recursive parts of a recursive UNION
1081         if (join_union_item_types(thd, types, union_part_count + 1))
1082           goto err;
1083         if (union_result->create_result_table(thd, &types,
1084                                               MY_TEST(union_distinct),
1085                                               create_options,
1086                                               &derived_arg->alias, false,
1087                                               instantiate_tmp_table, false,
1088                                               0))
1089           goto err;
1090         if (!derived_arg->table)
1091         {
1092           bool res= false;
1093 
1094           if ((!derived_arg->is_with_table_recursive_reference() ||
1095                !derived_arg->derived_result) &&
1096               !(derived_arg->derived_result=
1097                 new (thd->mem_root) select_unit(thd)))
1098             goto err; // out of memory
1099           thd->create_tmp_table_for_derived= TRUE;
1100 
1101           res= derived_arg->derived_result->create_result_table(thd,
1102                                                             &types,
1103                                                             FALSE,
1104                                                             create_options,
1105                                                             &derived_arg->alias,
1106                                                             FALSE, FALSE,
1107                                                             FALSE, 0);
1108           thd->create_tmp_table_for_derived= FALSE;
1109           if (res)
1110             goto err;
1111           derived_arg->derived_result->set_unit(this);
1112           derived_arg->table= derived_arg->derived_result->table;
1113           if (derived_arg->is_with_table_recursive_reference())
1114           {
1115             /* Here 'derived_arg' is the primary recursive table reference */
1116             derived_arg->with->rec_result->
1117               rec_table_refs.push_back(derived_arg);
1118           }
1119         }
1120         with_element->mark_as_with_prepared_anchor();
1121         is_rec_result_table_created= true;
1122       }
1123     }
1124   }
1125   // In case of a non-recursive UNION, join data types for all UNION parts.
1126   if (!is_recursive && join_union_item_types(thd, types, union_part_count))
1127     goto err;
1128 
1129 cont:
1130   /*
1131     If the query is using select_union_direct, we have postponed
1132     preparation of the underlying select_result until column types
1133     are known.
1134   */
1135   if (union_result != NULL && union_result->postponed_prepare(types))
1136     DBUG_RETURN(true);
1137 
1138   if (is_union_select)
1139   {
1140     /*
1141       Check that it was possible to aggregate
1142       all collations together for UNION.
1143     */
1144     List_iterator_fast<Item> tp(types);
1145     Item *type;
1146     ulonglong create_options;
1147     uint save_tablenr= 0;
1148     table_map save_map= 0;
1149     uint save_maybe_null= 0;
1150 
1151     while ((type= tp++))
1152     {
1153       /*
1154         Test if the aggregated data type is OK for a UNION element.
1155         E.g. in case of string data, DERIVATION_NONE is not allowed.
1156       */
1157       if (type->type() == Item::TYPE_HOLDER && type->type_handler()->
1158             union_element_finalize(static_cast<Item_type_holder*>(type)))
1159         goto err;
1160     }
1161 
1162     /*
1163       Disable the usage of fulltext searches in the last union branch.
1164       This is a temporary 5.x limitation because of the way the fulltext
1165       search functions are handled by the optimizer.
1166       This is manifestation of the more general problems of "taking away"
1167       parts of a SELECT statement post-fix_fields(). This is generally not
1168       doable since various flags are collected in various places (e.g.
1169       SELECT_LEX) that carry information about the presence of certain
1170       expressions or constructs in the parts of the query.
1171       When part of the query is taken away it's not clear how to "divide"
1172       the meaning of these accumulated flags and what to carry over to the
1173       recipient query (SELECT_LEX).
1174     */
1175     if (global_parameters()->ftfunc_list->elements &&
1176         global_parameters()->order_list.elements &&
1177         global_parameters() != fake_select_lex)
1178     {
1179       ORDER *ord;
1180       Item_func::Functype ft=  Item_func::FT_FUNC;
1181       for (ord= global_parameters()->order_list.first; ord; ord= ord->next)
1182         if ((*ord->item)->walk (&Item::find_function_processor, FALSE, &ft))
1183         {
1184           my_error (ER_CANT_USE_OPTION_HERE, MYF(0), "MATCH()");
1185           goto err;
1186         }
1187     }
1188 
1189 
1190     create_options= (first_sl->options | thd->variables.option_bits |
1191                      TMP_TABLE_ALL_COLUMNS);
1192     /*
1193       Force the temporary table to be a MyISAM table if we're going to use
1194       fullext functions (MATCH ... AGAINST .. IN BOOLEAN MODE) when reading
1195       from it (this should be removed in 5.2 when fulltext search is moved
1196       out of MyISAM).
1197     */
1198     if (global_parameters()->ftfunc_list->elements)
1199       create_options= create_options | TMP_TABLE_FORCE_MYISAM;
1200 
1201     if (!is_recursive)
1202     {
1203       uint hidden= 0;
1204       if (have_intersect)
1205       {
1206         hidden= 1;
1207         if (!intersect_mark)
1208         {
1209           /*
1210             For intersect we add a hidden column first that contains
1211             the current select number of the time when the row was
1212             added to the temporary table
1213           */
1214 
1215           Query_arena *arena, backup_arena;
1216           arena= thd->activate_stmt_arena_if_needed(&backup_arena);
1217 
1218           intersect_mark= new (thd->mem_root) Item_int(thd, 0);
1219 
1220           if (arena)
1221             thd->restore_active_arena(arena, &backup_arena);
1222 
1223           if (!intersect_mark)
1224             goto err;
1225         }
1226         else
1227           intersect_mark->value= 0; //reset
1228         types.push_front(union_result->intersect_mark= intersect_mark);
1229         union_result->intersect_mark->name.str= "___";
1230         union_result->intersect_mark->name.length= 3;
1231       }
1232       bool error=
1233         union_result->create_result_table(thd, &types,
1234                                           MY_TEST(union_distinct),
1235                                           create_options, &empty_clex_str, false,
1236                                           instantiate_tmp_table, false,
1237                                           hidden);
1238       if (intersect_mark)
1239         types.pop();
1240       if (unlikely(error))
1241         goto err;
1242     }
1243     if (fake_select_lex && !fake_select_lex->first_cond_optimization)
1244     {
1245       save_tablenr= result_table_list.tablenr_exec;
1246       save_map= result_table_list.map_exec;
1247       save_maybe_null= result_table_list.maybe_null_exec;
1248     }
1249     bzero((char*) &result_table_list, sizeof(result_table_list));
1250     result_table_list.db.str= (char*) "";
1251     result_table_list.db.length= 0;
1252     result_table_list.table_name.str= result_table_list.alias.str= "union";
1253     result_table_list.table_name.length= result_table_list.alias.length= sizeof("union")-1;
1254     result_table_list.table= table= union_result->table;
1255     if (fake_select_lex && !fake_select_lex->first_cond_optimization)
1256     {
1257       result_table_list.tablenr_exec= save_tablenr;
1258       result_table_list.map_exec= save_map;
1259       result_table_list.maybe_null_exec= save_maybe_null;
1260     }
1261 
1262     thd->lex->current_select= lex_select_save;
1263     if (!item_list.elements)
1264     {
1265       Query_arena *arena, backup_arena;
1266 
1267       arena= thd->activate_stmt_arena_if_needed(&backup_arena);
1268 
1269       saved_error= table->fill_item_list(&item_list);
1270       // Item_list is inherited from 'types', so there could be the counter
1271       if (intersect_mark)
1272         item_list.pop(); // remove intersect counter
1273 
1274       if (arena)
1275         thd->restore_active_arena(arena, &backup_arena);
1276 
1277       if (unlikely(saved_error))
1278         goto err;
1279 
1280       if (fake_select_lex != NULL &&
1281           (thd->stmt_arena->is_stmt_prepare() ||
1282            (thd->lex->context_analysis_only & CONTEXT_ANALYSIS_ONLY_VIEW)))
1283       {
1284         /* Validate the global parameters of this union */
1285 
1286 	init_prepare_fake_select_lex(thd, TRUE);
1287         /* Should be done only once (the only item_list per statement) */
1288         DBUG_ASSERT(fake_select_lex->join == 0);
1289 	if (!(fake_select_lex->join= new JOIN(thd, item_list, thd->variables.option_bits,
1290 					      result)))
1291 	{
1292 	  fake_select_lex->table_list.empty();
1293 	  DBUG_RETURN(TRUE);
1294 	}
1295 
1296         /*
1297           Fake st_select_lex should have item list for correct ref_array
1298           allocation.
1299         */
1300 	fake_select_lex->item_list= item_list;
1301 
1302 	thd->lex->current_select= fake_select_lex;
1303 
1304         /*
1305           We need to add up n_sum_items in order to make the correct
1306           allocation in setup_ref_array().
1307         */
1308         fake_select_lex->n_child_sum_items+= global_parameters()->n_sum_items;
1309       }
1310     }
1311     else
1312     {
1313       /*
1314         We're in execution of a prepared statement or stored procedure:
1315         reset field items to point at fields from the created temporary table.
1316       */
1317       table->reset_item_list(&item_list, intersect_mark ? 1 : 0);
1318     }
1319     if (fake_select_lex != NULL &&
1320         (thd->stmt_arena->is_stmt_prepare() ||
1321          (thd->lex->context_analysis_only & CONTEXT_ANALYSIS_ONLY_VIEW)))
1322     {
1323       if (!fake_select_lex->join &&
1324           !(fake_select_lex->join=
1325             new JOIN(thd, item_list, thd->variables.option_bits, result)))
1326       {
1327          fake_select_lex->table_list.empty();
1328          DBUG_RETURN(TRUE);
1329       }
1330       saved_error= fake_select_lex->join->
1331         prepare(fake_select_lex->table_list.first, 0, 0,
1332                 global_parameters()->order_list.elements, // og_num
1333                 global_parameters()->order_list.first,    // order
1334                 false, NULL, NULL, NULL, fake_select_lex, this);
1335       fake_select_lex->table_list.empty();
1336     }
1337   }
1338 
1339   thd->lex->current_select= lex_select_save;
1340 
1341   DBUG_RETURN(saved_error || thd->is_fatal_error);
1342 
1343 err:
1344   thd->lex->current_select= lex_select_save;
1345   (void) cleanup();
1346   DBUG_RETURN(TRUE);
1347 }
1348 
1349 
1350 /**
1351   Run optimization phase.
1352 
1353   @return FALSE unit successfully passed optimization phase.
1354   @return TRUE an error occur.
1355 */
optimize()1356 bool st_select_lex_unit::optimize()
1357 {
1358   SELECT_LEX *lex_select_save= thd->lex->current_select;
1359   SELECT_LEX *select_cursor=first_select();
1360   DBUG_ENTER("st_select_lex_unit::optimize");
1361 
1362   if (optimized && !uncacheable && !describe)
1363     DBUG_RETURN(FALSE);
1364 
1365   if (with_element && with_element->is_recursive && optimize_started)
1366     DBUG_RETURN(FALSE);
1367   optimize_started= true;
1368 
1369   if (uncacheable || !item || !item->assigned() || describe)
1370   {
1371     if (item)
1372       item->reset_value_registration();
1373     if (optimized && item)
1374     {
1375       if (item->assigned())
1376       {
1377         item->assigned(0); // We will reinit & rexecute unit
1378         item->reset();
1379       }
1380       if (table->is_created())
1381       {
1382         table->file->ha_delete_all_rows();
1383         table->file->info(HA_STATUS_VARIABLE);
1384       }
1385       /* re-enabling indexes for next subselect iteration */
1386       if (union_distinct && table->file->ha_enable_indexes(HA_KEY_SWITCH_ALL))
1387       {
1388         DBUG_ASSERT(0);
1389       }
1390     }
1391     for (SELECT_LEX *sl= select_cursor; sl; sl= sl->next_select())
1392     {
1393       if (sl->tvc)
1394       {
1395 	sl->tvc->select_options=
1396           (select_limit_cnt == HA_POS_ERROR || sl->braces) ?
1397           sl->options & ~OPTION_FOUND_ROWS : sl->options | found_rows_for_union;
1398 	if (sl->tvc->optimize(thd))
1399         {
1400           thd->lex->current_select= lex_select_save;
1401           DBUG_RETURN(TRUE);
1402         }
1403         if (derived)
1404 	  sl->increase_derived_records(sl->tvc->get_records());
1405 	continue;
1406       }
1407       thd->lex->current_select= sl;
1408 
1409       if (optimized)
1410 	saved_error= sl->join->reinit();
1411       else
1412       {
1413         set_limit(sl);
1414 	if (sl == global_parameters() || describe)
1415 	{
1416 	  offset_limit_cnt= 0;
1417 	  /*
1418 	    We can't use LIMIT at this stage if we are using ORDER BY for the
1419 	    whole query
1420 	  */
1421 	  if (sl->order_list.first || describe)
1422 	    select_limit_cnt= HA_POS_ERROR;
1423         }
1424 
1425         /*
1426           When using braces, SQL_CALC_FOUND_ROWS affects the whole query:
1427           we don't calculate found_rows() per union part.
1428           Otherwise, SQL_CALC_FOUND_ROWS should be done on all sub parts.
1429         */
1430         sl->join->select_options=
1431           (select_limit_cnt == HA_POS_ERROR || sl->braces) ?
1432           sl->options & ~OPTION_FOUND_ROWS : sl->options | found_rows_for_union;
1433 
1434 	saved_error= sl->join->optimize();
1435       }
1436 
1437       if (unlikely(saved_error))
1438       {
1439 	thd->lex->current_select= lex_select_save;
1440 	DBUG_RETURN(saved_error);
1441       }
1442     }
1443   }
1444   optimized= 1;
1445 
1446   thd->lex->current_select= lex_select_save;
1447   DBUG_RETURN(saved_error);
1448 }
1449 
1450 
exec()1451 bool st_select_lex_unit::exec()
1452 {
1453   SELECT_LEX *lex_select_save= thd->lex->current_select;
1454   SELECT_LEX *select_cursor=first_select();
1455   ulonglong add_rows=0;
1456   ha_rows examined_rows= 0;
1457   bool first_execution= !executed;
1458   DBUG_ENTER("st_select_lex_unit::exec");
1459   bool was_executed= executed;
1460 
1461   if (executed && !uncacheable && !describe)
1462     DBUG_RETURN(FALSE);
1463   executed= 1;
1464   if (!(uncacheable & ~UNCACHEABLE_EXPLAIN) && item &&
1465       !item->with_recursive_reference)
1466     item->make_const();
1467 
1468   saved_error= optimize();
1469 
1470   create_explain_query_if_not_exists(thd->lex, thd->mem_root);
1471 
1472   if (!saved_error && !was_executed)
1473     save_union_explain(thd->lex->explain);
1474 
1475   if (unlikely(saved_error))
1476     DBUG_RETURN(saved_error);
1477 
1478   if (union_result)
1479   {
1480     union_result->init();
1481     if (uncacheable & UNCACHEABLE_DEPENDENT &&
1482         union_result->table && union_result->table->is_created())
1483     {
1484       union_result->table->file->ha_delete_all_rows();
1485       union_result->table->file->ha_enable_indexes(HA_KEY_SWITCH_ALL);
1486     }
1487   }
1488 
1489   if (uncacheable || !item || !item->assigned() || describe)
1490   {
1491     if (!fake_select_lex && !(with_element && with_element->is_recursive))
1492       union_result->cleanup();
1493     for (SELECT_LEX *sl= select_cursor; sl; sl= sl->next_select())
1494     {
1495       ha_rows records_at_start= 0;
1496       thd->lex->current_select= sl;
1497       if (union_result)
1498         union_result->change_select();
1499       if (fake_select_lex)
1500       {
1501         if (sl != &thd->lex->select_lex)
1502           fake_select_lex->uncacheable|= sl->uncacheable;
1503         else
1504           fake_select_lex->uncacheable= 0;
1505       }
1506 
1507       {
1508         set_limit(sl);
1509 	if (sl == global_parameters() || describe)
1510 	{
1511 	  offset_limit_cnt= 0;
1512 	  /*
1513 	    We can't use LIMIT at this stage if we are using ORDER BY for the
1514 	    whole query
1515 	  */
1516 	  if (sl->order_list.first || describe)
1517 	    select_limit_cnt= HA_POS_ERROR;
1518         }
1519 
1520         /*
1521           When using braces, SQL_CALC_FOUND_ROWS affects the whole query:
1522           we don't calculate found_rows() per union part.
1523           Otherwise, SQL_CALC_FOUND_ROWS should be done on all sub parts.
1524         */
1525 	if (sl->tvc)
1526 	{
1527 	  sl->tvc->select_options=
1528              (select_limit_cnt == HA_POS_ERROR || sl->braces) ?
1529              sl->options & ~OPTION_FOUND_ROWS : sl->options | found_rows_for_union;
1530 	  saved_error= sl->tvc->optimize(thd);
1531 	}
1532 	else
1533 	{
1534           sl->join->select_options=
1535             (select_limit_cnt == HA_POS_ERROR || sl->braces) ?
1536             sl->options & ~OPTION_FOUND_ROWS : sl->options | found_rows_for_union;
1537 	  saved_error= sl->join->optimize();
1538 	}
1539       }
1540       if (likely(!saved_error))
1541       {
1542 	records_at_start= table->file->stats.records;
1543 	if (sl->tvc)
1544 	  sl->tvc->exec(sl);
1545 	else
1546 	  sl->join->exec();
1547         if (sl == union_distinct && !(with_element && with_element->is_recursive))
1548 	{
1549           // This is UNION DISTINCT, so there should be a fake_select_lex
1550           DBUG_ASSERT(fake_select_lex != NULL);
1551 	  if (unlikely(table->file->ha_disable_indexes(HA_KEY_SWITCH_ALL)))
1552 	    DBUG_RETURN(TRUE);
1553 	  table->no_keyread=1;
1554 	}
1555 	if (!sl->tvc)
1556 	  saved_error= sl->join->error;
1557 	offset_limit_cnt= (ha_rows)(sl->offset_limit ?
1558                                     sl->offset_limit->val_uint() :
1559                                     0);
1560 	if (likely(!saved_error))
1561 	{
1562 	  examined_rows+= thd->get_examined_row_count();
1563           thd->set_examined_row_count(0);
1564 	  if (union_result->flush())
1565 	  {
1566 	    thd->lex->current_select= lex_select_save;
1567 	    DBUG_RETURN(1);
1568 	  }
1569 	}
1570       }
1571       if (unlikely(saved_error))
1572       {
1573 	thd->lex->current_select= lex_select_save;
1574 	DBUG_RETURN(saved_error);
1575       }
1576       if (fake_select_lex != NULL)
1577       {
1578         /* Needed for the following test and for records_at_start in next loop */
1579         int error= table->file->info(HA_STATUS_VARIABLE);
1580         if (unlikely(error))
1581         {
1582           table->file->print_error(error, MYF(0));
1583           DBUG_RETURN(1);
1584         }
1585       }
1586       if (found_rows_for_union && !sl->braces &&
1587           select_limit_cnt != HA_POS_ERROR)
1588       {
1589 	/*
1590 	  This is a union without braces. Remember the number of rows that
1591 	  could also have been part of the result set.
1592 	  We get this from the difference of between total number of possible
1593 	  rows and actual rows added to the temporary table.
1594 	*/
1595 	add_rows+= (ulonglong) (thd->limit_found_rows - (ulonglong)
1596 			      ((table->file->stats.records -  records_at_start)));
1597       }
1598       if (thd->killed == ABORT_QUERY)
1599       {
1600         /*
1601           Stop execution of the remaining queries in the UNIONS, and produce
1602           the current result.
1603         */
1604         push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
1605                             ER_QUERY_EXCEEDED_ROWS_EXAMINED_LIMIT,
1606                             ER_THD(thd, ER_QUERY_EXCEEDED_ROWS_EXAMINED_LIMIT),
1607                             thd->accessed_rows_and_keys,
1608                             thd->lex->limit_rows_examined->val_uint());
1609         thd->reset_killed();
1610         break;
1611       }
1612     }
1613   }
1614 
1615   DBUG_EXECUTE_IF("show_explain_probe_union_read",
1616                    dbug_serve_apcs(thd, 1););
1617   {
1618     List<Item_func_match> empty_list;
1619     empty_list.empty();
1620     /*
1621       Disable LIMIT ROWS EXAMINED in order to produce the possibly incomplete
1622       result of the UNION without interruption due to exceeding the limit.
1623     */
1624     thd->lex->limit_rows_examined_cnt= ULONGLONG_MAX;
1625 
1626     // Check if EOM
1627     if (fake_select_lex != NULL && likely(!thd->is_fatal_error))
1628     {
1629        /* Send result to 'result' */
1630        saved_error= true;
1631 
1632       set_limit(global_parameters());
1633       init_prepare_fake_select_lex(thd, first_execution);
1634       JOIN *join= fake_select_lex->join;
1635       saved_error= false;
1636       if (!join)
1637       {
1638 	/*
1639 	  allocate JOIN for fake select only once (prevent
1640 	  mysql_select automatic allocation)
1641           TODO: The above is nonsense. mysql_select() will not allocate the
1642           join if one already exists. There must be some other reason why we
1643           don't let it allocate the join. Perhaps this is because we need
1644           some special parameter values passed to join constructor?
1645 	*/
1646 	if (unlikely(!(fake_select_lex->join=
1647                        new JOIN(thd, item_list, fake_select_lex->options,
1648                                 result))))
1649 	{
1650 	  fake_select_lex->table_list.empty();
1651 	  goto err;
1652 	}
1653         fake_select_lex->join->no_const_tables= TRUE;
1654 
1655         /*
1656           Fake st_select_lex should have item list for correct ref_array
1657           allocation.
1658         */
1659         fake_select_lex->item_list= item_list;
1660 
1661         /*
1662           We need to add up n_sum_items in order to make the correct
1663           allocation in setup_ref_array().
1664           Don't add more sum_items if we have already done JOIN::prepare
1665           for this (with a different join object)
1666         */
1667         if (fake_select_lex->ref_pointer_array.is_null())
1668           fake_select_lex->n_child_sum_items+= global_parameters()->n_sum_items;
1669 
1670         if (!was_executed)
1671           save_union_explain_part2(thd->lex->explain);
1672 
1673         saved_error= mysql_select(thd,
1674                               &result_table_list,
1675                               0, item_list, NULL,
1676 				  global_parameters()->order_list.elements,
1677 				  global_parameters()->order_list.first,
1678                               NULL, NULL, NULL,
1679                               fake_select_lex->options | SELECT_NO_UNLOCK,
1680                               result, this, fake_select_lex);
1681       }
1682       else
1683       {
1684         if (describe)
1685         {
1686           /*
1687             In EXPLAIN command, constant subqueries that do not use any
1688             tables are executed two times:
1689              - 1st time is a real evaluation to get the subquery value
1690              - 2nd time is to produce EXPLAIN output rows.
1691             1st execution sets certain members (e.g. select_result) to perform
1692             subquery execution rather than EXPLAIN line production. In order
1693             to reset them back, we re-do all of the actions (yes it is ugly):
1694           */ // psergey-todo: is the above really necessary anymore??
1695 	  join->init(thd, item_list, fake_select_lex->options, result);
1696           saved_error= mysql_select(thd,
1697                                 &result_table_list,
1698                                 0, item_list, NULL,
1699 				    global_parameters()->order_list.elements,
1700 				    global_parameters()->order_list.first,
1701                                 NULL, NULL, NULL,
1702                                 fake_select_lex->options | SELECT_NO_UNLOCK,
1703                                 result, this, fake_select_lex);
1704         }
1705         else
1706         {
1707           join->join_examined_rows= 0;
1708           saved_error= join->reinit();
1709           join->exec();
1710         }
1711       }
1712 
1713       fake_select_lex->table_list.empty();
1714       if (likely(!saved_error))
1715       {
1716 	thd->limit_found_rows = (ulonglong)table->file->stats.records + add_rows;
1717         thd->inc_examined_row_count(examined_rows);
1718       }
1719       /*
1720 	Mark for slow query log if any of the union parts didn't use
1721 	indexes efficiently
1722       */
1723     }
1724   }
1725   thd->lex->current_select= lex_select_save;
1726 err:
1727   thd->lex->set_limit_rows_examined();
1728   DBUG_RETURN(saved_error);
1729 }
1730 
1731 
1732 /**
1733   @brief
1734     Execute the union of the specification of a recursive with table
1735 
1736   @details
1737     The method is performed only for the units that are specifications
1738     if recursive with table T. If the specification contains an anchor
1739     part then the first call of this method executes only this part
1740     while the following calls execute the recursive part. If there are
1741     no anchors each call executes the whole unit.
1742     Before the excution the method cleans up the temporary table
1743     to where the new rows of the recursive table are sent.
1744     After the execution the unit these rows are copied to the
1745     temporary tables created for recursive references of T.
1746     If the specification if T is restricted (standards compliant)
1747     then these temporary tables are cleaned up before new rows
1748     are copied into them.
1749 
1750   @retval
1751     false   on success
1752     true    on failure
1753 */
1754 
exec_recursive()1755 bool st_select_lex_unit::exec_recursive()
1756 {
1757   st_select_lex *lex_select_save= thd->lex->current_select;
1758   st_select_lex *start= with_element->first_recursive;
1759   TABLE *incr_table= with_element->rec_result->incr_table;
1760   st_select_lex *end= NULL;
1761   bool is_unrestricted= with_element->is_unrestricted();
1762   List_iterator_fast<TABLE_LIST> li(with_element->rec_result->rec_table_refs);
1763   TMP_TABLE_PARAM *tmp_table_param= &with_element->rec_result->tmp_table_param;
1764   ha_rows examined_rows= 0;
1765   bool was_executed= executed;
1766   TABLE_LIST *rec_tbl;
1767 
1768   DBUG_ENTER("st_select_lex_unit::exec_recursive");
1769 
1770   executed= 1;
1771   create_explain_query_if_not_exists(thd->lex, thd->mem_root);
1772   if (!was_executed)
1773     save_union_explain(thd->lex->explain);
1774 
1775   if (with_element->level == 0)
1776   {
1777     if (!incr_table->is_created() &&
1778         instantiate_tmp_table(incr_table,
1779                               tmp_table_param->keyinfo,
1780                               tmp_table_param->start_recinfo,
1781                               &tmp_table_param->recinfo,
1782                               0))
1783       DBUG_RETURN(1);
1784     incr_table->file->extra(HA_EXTRA_WRITE_CACHE);
1785     incr_table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
1786     start= first_select();
1787     if (with_element->with_anchor)
1788       end= with_element->first_recursive;
1789   }
1790   else if (unlikely((saved_error= incr_table->file->ha_delete_all_rows())))
1791     goto err;
1792 
1793   for (st_select_lex *sl= start ; sl != end; sl= sl->next_select())
1794   {
1795     if (with_element->level)
1796     {
1797       for (TABLE_LIST *derived= with_element->derived_with_rec_ref.first;
1798            derived;
1799            derived= derived->next_with_rec_ref)
1800       {
1801         if (derived->is_materialized_derived())
1802 	{
1803           if (derived->table->is_created())
1804             derived->table->file->ha_delete_all_rows();
1805           derived->table->reginfo.join_tab->preread_init_done= false;
1806         }
1807       }
1808     }
1809     thd->lex->current_select= sl;
1810     set_limit(sl);
1811     if (sl->tvc)
1812       sl->tvc->exec(sl);
1813     else
1814     {
1815       sl->join->exec();
1816       saved_error= sl->join->error;
1817     }
1818     if (likely(!saved_error))
1819     {
1820        examined_rows+= thd->get_examined_row_count();
1821        thd->set_examined_row_count(0);
1822        if (unlikely(union_result->flush()))
1823        {
1824 	 thd->lex->current_select= lex_select_save;
1825 	 DBUG_RETURN(1);
1826        }
1827     }
1828     if (unlikely(saved_error))
1829     {
1830       thd->lex->current_select= lex_select_save;
1831       goto err;
1832 
1833     }
1834   }
1835 
1836   thd->inc_examined_row_count(examined_rows);
1837 
1838   incr_table->file->info(HA_STATUS_VARIABLE);
1839   if (with_element->level && incr_table->file->stats.records == 0)
1840     with_element->set_as_stabilized();
1841   else
1842     with_element->level++;
1843 
1844   while ((rec_tbl= li++))
1845   {
1846     TABLE *rec_table= rec_tbl->table;
1847     saved_error=
1848       incr_table->insert_all_rows_into_tmp_table(thd, rec_table,
1849                                                  tmp_table_param,
1850                                                  !is_unrestricted);
1851     if (!with_element->rec_result->first_rec_table_to_update)
1852       with_element->rec_result->first_rec_table_to_update= rec_table;
1853     if (with_element->level == 1 && rec_table->reginfo.join_tab)
1854       rec_table->reginfo.join_tab->preread_init_done= true;
1855   }
1856   for (Item_subselect *sq= with_element->sq_with_rec_ref.first;
1857        sq;
1858        sq= sq->next_with_rec_ref)
1859   {
1860     sq->reset();
1861     sq->engine->force_reexecution();
1862   }
1863 
1864   thd->lex->current_select= lex_select_save;
1865 err:
1866   thd->lex->set_limit_rows_examined();
1867   DBUG_RETURN(saved_error);
1868 }
1869 
1870 
cleanup()1871 bool st_select_lex_unit::cleanup()
1872 {
1873   bool error= 0;
1874   DBUG_ENTER("st_select_lex_unit::cleanup");
1875 
1876   if (cleaned)
1877   {
1878     DBUG_RETURN(FALSE);
1879   }
1880   if (with_element && with_element->is_recursive && union_result &&
1881       with_element->rec_outer_references)
1882   {
1883     select_union_recursive *result= with_element->rec_result;
1884     if (++result->cleanup_count == with_element->rec_outer_references)
1885     {
1886       /*
1887         Perform cleanup for with_element and for all with elements
1888         mutually recursive with it.
1889       */
1890       cleaned= 1;
1891       with_element->get_next_mutually_recursive()->spec->cleanup();
1892     }
1893     else
1894     {
1895       /*
1896         Just increment by 1 cleanup_count for with_element and
1897         for all with elements mutually recursive with it.
1898       */
1899       With_element *with_elem= with_element;
1900       while ((with_elem= with_elem->get_next_mutually_recursive()) !=
1901              with_element)
1902         with_elem->rec_result->cleanup_count++;
1903       DBUG_RETURN(FALSE);
1904     }
1905   }
1906   columns_are_renamed= false;
1907   cleaned= 1;
1908 
1909   for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
1910     error|= sl->cleanup();
1911 
1912   if (fake_select_lex)
1913   {
1914     error|= fake_select_lex->cleanup();
1915     /*
1916       There are two cases when we should clean order items:
1917       1. UNION with SELECTs which all enclosed into braces
1918         in this case global_parameters == fake_select_lex
1919       2. UNION where last SELECT is not enclosed into braces
1920         in this case global_parameters == 'last select'
1921       So we should use global_parameters->order_list for
1922       proper order list clean up.
1923       Note: global_parameters and fake_select_lex are always
1924             initialized for UNION
1925     */
1926     DBUG_ASSERT(global_parameters());
1927     if (global_parameters()->order_list.elements)
1928     {
1929       ORDER *ord;
1930       for (ord= global_parameters()->order_list.first; ord; ord= ord->next)
1931         (*ord->item)->walk (&Item::cleanup_processor, 0, 0);
1932     }
1933   }
1934 
1935   if (with_element && with_element->is_recursive)
1936   {
1937     if (union_result)
1938     {
1939       ((select_union_recursive *) union_result)->cleanup();
1940       delete union_result;
1941       union_result= 0;
1942     }
1943     with_element->mark_as_cleaned();
1944   }
1945   else
1946   {
1947     if (union_result)
1948     {
1949       delete union_result;
1950       union_result=0; // Safety
1951       if (table)
1952         free_tmp_table(thd, table);
1953       table= 0; // Safety
1954     }
1955   }
1956 
1957   DBUG_RETURN(error);
1958 }
1959 
1960 
reinit_exec_mechanism()1961 void st_select_lex_unit::reinit_exec_mechanism()
1962 {
1963   prepared= optimized= optimized_2= executed= 0;
1964   optimize_started= 0;
1965   if (with_element && with_element->is_recursive)
1966     with_element->reset_recursive_for_exec();
1967 }
1968 
1969 
1970 /**
1971   Change the select_result object used to return the final result of
1972   the unit, replacing occurences of old_result with new_result.
1973 
1974   @param new_result New select_result object
1975   @param old_result Old select_result object
1976 
1977   @retval false Success
1978   @retval true  Error
1979 */
1980 
change_result(select_result_interceptor * new_result,select_result_interceptor * old_result)1981 bool st_select_lex_unit::change_result(select_result_interceptor *new_result,
1982                                        select_result_interceptor *old_result)
1983 {
1984   for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
1985   {
1986     if (sl->join)
1987       if (sl->join->change_result(new_result, old_result))
1988 	return true; /* purecov: inspected */
1989   }
1990   /*
1991     If there were a fake_select_lex->join, we would have to change the
1992     result of that also, but change_result() is called before such an
1993     object is created.
1994   */
1995   DBUG_ASSERT(fake_select_lex == NULL || fake_select_lex->join == NULL);
1996   return false;
1997 }
1998 
1999 /*
2000   Get column type information for this unit.
2001 
2002   SYNOPSIS
2003     st_select_lex_unit::get_column_types()
2004       @param for_cursor if true return the list the fields
2005                         retrieved by the cursor
2006 
2007   DESCRIPTION
2008     For a single-select the column types are taken
2009     from the list of selected items. For a union this function
2010     assumes that st_select_lex_unit::prepare has been called
2011     and returns the type holders that were created for unioned
2012     column types of all selects.
2013 
2014   NOTES
2015     The implementation of this function should be in sync with
2016     st_select_lex_unit::prepare()
2017 */
2018 
get_column_types(bool for_cursor)2019 List<Item> *st_select_lex_unit::get_column_types(bool for_cursor)
2020 {
2021   SELECT_LEX *sl= first_select();
2022   bool is_procedure= !sl->tvc && sl->join->procedure ;
2023 
2024   if (is_procedure)
2025   {
2026     /* Types for "SELECT * FROM t1 procedure analyse()"
2027        are generated during execute */
2028     return &sl->join->procedure_fields_list;
2029   }
2030 
2031 
2032   if (is_unit_op())
2033   {
2034     DBUG_ASSERT(prepared);
2035     /* Types are generated during prepare */
2036     return &types;
2037   }
2038 
2039   return for_cursor ? sl->join->fields :  &sl->item_list;
2040 }
2041 
2042 
cleanup_order(ORDER * order)2043 static void cleanup_order(ORDER *order)
2044 {
2045   for (; order; order= order->next)
2046     order->counter_used= 0;
2047 }
2048 
2049 
cleanup_window_funcs(List<Item_window_func> & win_funcs)2050 static void cleanup_window_funcs(List<Item_window_func> &win_funcs)
2051 {
2052   List_iterator_fast<Item_window_func> it(win_funcs);
2053   Item_window_func *win_func;
2054   while ((win_func= it++))
2055   {
2056     Window_spec *win_spec= win_func->window_spec;
2057     if (!win_spec)
2058       continue;
2059     if (win_spec->save_partition_list)
2060     {
2061       win_spec->partition_list= win_spec->save_partition_list;
2062       win_spec->save_partition_list= NULL;
2063     }
2064     if (win_spec->save_order_list)
2065     {
2066       win_spec->order_list= win_spec->save_order_list;
2067       win_spec->save_order_list= NULL;
2068     }
2069   }
2070 }
2071 
2072 
cleanup()2073 bool st_select_lex::cleanup()
2074 {
2075   bool error= FALSE;
2076   DBUG_ENTER("st_select_lex::cleanup()");
2077 
2078   cleanup_order(order_list.first);
2079   cleanup_order(group_list.first);
2080   cleanup_ftfuncs(this);
2081 
2082   cleanup_window_funcs(window_funcs);
2083 
2084   if (join)
2085   {
2086     List_iterator<TABLE_LIST> ti(leaf_tables);
2087     TABLE_LIST *tbl;
2088     while ((tbl= ti++))
2089     {
2090       if (tbl->is_recursive_with_table() &&
2091           !tbl->is_with_table_recursive_reference())
2092       {
2093         /*
2094           If query is killed before open_and_process_table() for tbl
2095           is called then 'with' is already set, but 'derived' is not.
2096         */
2097         st_select_lex_unit *unit= tbl->with->spec;
2098         error|= (bool) error | (uint) unit->cleanup();
2099       }
2100     }
2101     DBUG_ASSERT((st_select_lex*)join->select_lex == this);
2102     error= join->destroy();
2103     delete join;
2104     join= 0;
2105   }
2106   leaf_tables.empty();
2107   for (SELECT_LEX_UNIT *lex_unit= first_inner_unit(); lex_unit ;
2108        lex_unit= lex_unit->next_unit())
2109   {
2110     if (lex_unit->with_element && lex_unit->with_element->is_recursive &&
2111         lex_unit->with_element->rec_outer_references)
2112       continue;
2113     error= (bool) ((uint) error | (uint) lex_unit->cleanup());
2114   }
2115   inner_refs_list.empty();
2116   exclude_from_table_unique_test= FALSE;
2117   hidden_bit_fields= 0;
2118   DBUG_RETURN(error);
2119 }
2120 
2121 
cleanup_all_joins(bool full)2122 void st_select_lex::cleanup_all_joins(bool full)
2123 {
2124   SELECT_LEX_UNIT *unit;
2125   SELECT_LEX *sl;
2126   DBUG_ENTER("st_select_lex::cleanup_all_joins");
2127 
2128   if (join)
2129     join->cleanup(full);
2130 
2131   for (unit= first_inner_unit(); unit; unit= unit->next_unit())
2132   {
2133     if (unit->with_element && unit->with_element->is_recursive)
2134       continue;
2135     for (sl= unit->first_select(); sl; sl= sl->next_select())
2136       sl->cleanup_all_joins(full);
2137   }
2138   DBUG_VOID_RETURN;
2139 }
2140 
2141 
2142 /**
2143   Set exclude_from_table_unique_test for selects of this unit and all
2144   underlying selects.
2145 
2146   @note used to exclude materialized derived tables (views) from unique
2147   table check.
2148 */
2149 
set_unique_exclude()2150 void st_select_lex_unit::set_unique_exclude()
2151 {
2152   for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
2153   {
2154     sl->exclude_from_table_unique_test= TRUE;
2155     for (SELECT_LEX_UNIT *unit= sl->first_inner_unit();
2156          unit;
2157          unit= unit->next_unit())
2158     {
2159       unit->set_unique_exclude();
2160     }
2161   }
2162 }
2163 
2164 /**
2165   @brief
2166   Check if the derived table is guaranteed to have distinct rows because of
2167   UNION operations used to populate it.
2168 
2169   @detail
2170     UNION operation removes duplicate rows from its output. That is, a query like
2171 
2172       select * from t1 UNION select * from t2
2173 
2174     will not produce duplicate rows in its output, even if table t1 (and/or t2)
2175     contain duplicate rows. EXCEPT and INTERSECT operations also have this
2176     property.
2177 
2178     On the other hand, UNION ALL operation doesn't remove duplicates. (The SQL
2179     standard also defines EXCEPT ALL and INTERSECT ALL, but we don't support
2180     them).
2181 
2182     st_select_lex_unit computes its value left to right. That is, if there is
2183      a st_select_lex_unit object describing
2184 
2185       (select #1) OP1 (select #2) OP2 (select #3)
2186 
2187     then ((select #1) OP1 (select #2)) is computed first, and OP2 is computed
2188     second.
2189 
2190     How can one tell if st_select_lex_unit is guaranteed to have distinct
2191     output rows? This depends on whether the last operation was duplicate-
2192     removing or not:
2193     - UNION ALL is not duplicate-removing
2194     - all other operations are duplicate-removing
2195 */
2196 
check_distinct_in_union()2197 bool st_select_lex_unit::check_distinct_in_union()
2198 {
2199   if (union_distinct && !union_distinct->next_select())
2200     return true;
2201   return false;
2202 }
2203