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