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