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