1
/* Copyright (C) 2000-2003 MySQL AB
3
This program is free software; you can redistribute it and/or modify
4
it under the terms of the GNU General Public License as published by
5
the Free Software Foundation; version 2 of the License.
7
This program is distributed in the hope that it will be useful,
8
but WITHOUT ANY WARRANTY; without even the implied warranty of
9
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
GNU General Public License for more details.
12
You should have received a copy of the GNU General Public License
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
18
UNION's were introduced by Monty and Sinisa <sinisa@mysql.com>
21
#include <drizzled/sql_select.h>
22
#include <drizzled/error.h>
23
#include <drizzled/item/type_holder.h>
24
#include <drizzled/sql_base.h>
25
#include <drizzled/sql_union.h>
30
bool drizzle_union(Session *session, LEX *, select_result *result,
31
Select_Lex_Unit *unit, uint64_t setup_tables_done_option)
34
if (!(res= unit->prepare(session, result, SELECT_NO_UNLOCK |
35
setup_tables_done_option)))
38
res|= unit->cleanup();
43
/***************************************************************************
44
** store records in temporary table for UNION
45
***************************************************************************/
47
int select_union::prepare(List<Item> &, Select_Lex_Unit *u)
54
bool select_union::send_data(List<Item> &values)
57
if (unit->offset_limit_cnt)
58
{ // using limit offset,count
59
unit->offset_limit_cnt--;
62
fill_record(session, table->field, values, true);
63
if (session->is_error())
66
if ((error= table->cursor->ha_write_row(table->record[0])))
68
/* create_myisam_from_heap will generate error if needed */
69
if (table->cursor->is_fatal_error(error, HA_CHECK_DUP) &&
70
create_myisam_from_heap(session, table, tmp_table_param.start_recinfo,
71
&tmp_table_param.recinfo, error, 1))
78
bool select_union::send_eof()
84
bool select_union::flush()
87
if ((error=table->cursor->extra(HA_EXTRA_NO_CACHE)))
89
table->print_error(error, MYF(0));
96
Create a temporary table to store the result of select_union.
99
select_union::create_result_table()
100
session thread handle
101
column_types a list of items used to define columns of the
103
is_union_distinct if set, the temporary table will eliminate
105
options create options
106
table_alias name of the temporary table
109
Create a temporary table that is used to store the result of a UNION,
110
derived table, or a materialized cursor.
113
0 The table has been created successfully.
114
1 create_tmp_table failed.
118
select_union::create_result_table(Session *session_arg, List<Item> *column_types,
119
bool is_union_distinct, uint64_t options,
120
const char *table_alias)
122
assert(table == NULL);
123
tmp_table_param.init();
124
tmp_table_param.field_count= column_types->elements;
126
if (! (table= create_tmp_table(session_arg, &tmp_table_param, *column_types,
127
(order_st*) NULL, is_union_distinct, 1,
128
options, HA_POS_ERROR, (char*) table_alias)))
130
table->cursor->extra(HA_EXTRA_WRITE_CACHE);
131
table->cursor->extra(HA_EXTRA_IGNORE_DUP_KEY);
137
Reset and empty the temporary table that stores the materialized query result.
139
@note The cleanup performed here is exactly the same as for the two temp
140
tables of JOIN - exec_tmp_table_[1 | 2].
143
void select_union::cleanup()
145
table->cursor->extra(HA_EXTRA_RESET_STATE);
146
table->cursor->ha_delete_all_rows();
147
table->free_io_cache();
148
table->filesort_free_buffers();
153
initialization procedures before fake_select_lex preparation()
156
Select_Lex_Unit::init_prepare_fake_select_lex()
157
session - thread handler
164
Select_Lex_Unit::init_prepare_fake_select_lex(Session *session_arg)
166
session_arg->lex->current_select= fake_select_lex;
167
fake_select_lex->table_list.link_in_list((unsigned char *)&result_table_list,
169
&result_table_list.next_local);
170
fake_select_lex->context.table_list=
171
fake_select_lex->context.first_name_resolution_table=
172
fake_select_lex->get_table_list();
174
for (order_st *order= (order_st *) global_parameters->order_list.first;
177
order->item= &order->item_ptr;
179
for (order_st *order= (order_st *)global_parameters->order_list.first;
183
(*order->item)->walk(&Item::change_context_processor, 0,
184
(unsigned char*) &fake_select_lex->context);
189
bool Select_Lex_Unit::prepare(Session *session_arg, select_result *sel_result,
190
uint64_t additional_options)
192
Select_Lex *lex_select_save= session_arg->lex->current_select;
193
Select_Lex *sl, *first_sl= first_select();
194
select_result *tmp_result;
195
bool is_union_select;
196
Table *empty_table= 0;
198
describe= test(additional_options & SELECT_DESCRIBE);
201
result object should be reassigned even if preparing already done for
202
max/min subquery (ALL/ANY optimization)
210
/* fast reinit for EXPLAIN */
211
for (sl= first_sl; sl; sl= sl->next_select())
213
sl->join->result= result;
214
select_limit_cnt= HA_POS_ERROR;
216
if (result->prepare(sl->join->fields_list, this))
220
sl->join->select_options|= SELECT_DESCRIBE;
229
session_arg->lex->current_select= sl= first_sl;
230
found_rows_for_union= first_sl->options & OPTION_FOUND_ROWS;
231
is_union_select= is_union() || fake_select_lex;
237
if (!(tmp_result= union_result= new select_union))
240
tmp_result= sel_result;
243
tmp_result= sel_result;
245
sl->context.resolve_in_select_list= true;
247
for (;sl; sl= sl->next_select())
249
bool can_skip_order_by;
250
sl->options|= SELECT_NO_UNLOCK;
251
JOIN *join= new JOIN(session_arg, sl->item_list,
252
sl->options | session_arg->options | additional_options,
255
setup_tables_done_option should be set only for very first SELECT,
256
because it protect from secont setup_tables call for select-like non
257
select commands (DELETE/INSERT/...) and they use only very first
258
SELECT (for union it can be only INSERT ... SELECT).
260
additional_options&= ~OPTION_SETUP_TABLES_DONE;
264
session_arg->lex->current_select= sl;
266
can_skip_order_by= is_union_select && !(sl->braces && sl->explicit_limit);
268
saved_error= join->prepare(&sl->ref_pointer_array,
269
(TableList*) sl->table_list.first,
272
(can_skip_order_by ? 0 :
273
sl->order_list.elements) +
274
sl->group_list.elements,
276
(order_st*) NULL : (order_st *)sl->order_list.first,
277
(order_st*) sl->group_list.first,
280
/* There are no * in the statement anymore (for PS) */
283
if (saved_error || (saved_error= session_arg->is_fatal_error))
286
Use items list of underlaid select for derived tables to preserve
287
information about fields lengths and exact types
289
if (!is_union_select)
290
types= first_sl->item_list;
291
else if (sl == first_sl)
294
We need to create an empty table object. It is used
295
to create tmp_table fields in Item_type_holder.
296
The main reason of this is that we can't create
297
field object without table.
299
assert(!empty_table);
300
empty_table= (Table*) session->calloc(sizeof(Table));
302
List_iterator_fast<Item> it(sl->item_list);
304
while ((item_tmp= it++))
306
/* Error's in 'new' will be detected after loop */
307
types.push_back(new Item_type_holder(session_arg, item_tmp));
310
if (session_arg->is_fatal_error)
311
goto err; // out of memory
315
if (types.elements != sl->item_list.elements)
317
my_message(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT,
318
ER(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT),MYF(0));
321
List_iterator_fast<Item> it(sl->item_list);
322
List_iterator_fast<Item> tp(types);
323
Item *type, *item_tmp;
324
while ((type= tp++, item_tmp= it++))
326
if (((Item_type_holder*)type)->join_types(session_arg, item_tmp))
335
Check that it was possible to aggregate
336
all collations together for UNION.
338
List_iterator_fast<Item> tp(types);
340
uint64_t create_options;
344
if (type->result_type() == STRING_RESULT &&
345
type->collation.derivation == DERIVATION_NONE)
347
my_error(ER_CANT_AGGREGATE_NCOLLATIONS, MYF(0), "UNION");
352
create_options= (first_sl->options | session_arg->options |
353
TMP_TABLE_ALL_COLUMNS);
355
if (union_result->create_result_table(session, &types, test(union_distinct),
358
memset(&result_table_list, 0, sizeof(result_table_list));
359
result_table_list.db= (char*) "";
360
result_table_list.alias= "union";
361
result_table_list.table_name= (char *) "union";
362
result_table_list.table= table= union_result->table;
364
session_arg->lex->current_select= lex_select_save;
365
if (!item_list.elements)
367
saved_error= table->fill_item_list(&item_list);
374
We're in execution of a prepared statement or stored procedure:
375
reset field items to point at fields from the created temporary table.
381
session_arg->lex->current_select= lex_select_save;
383
return(saved_error || session_arg->is_fatal_error);
386
session_arg->lex->current_select= lex_select_save;
391
bool Select_Lex_Unit::exec()
393
Select_Lex *lex_select_save= session->lex->current_select;
394
Select_Lex *select_cursor=first_select();
396
ha_rows examined_rows= 0;
398
if (executed && !uncacheable && !describe)
402
if (uncacheable || !item || !item->assigned() || describe)
405
item->reset_value_registration();
406
if (optimized && item)
408
if (item->assigned())
410
item->assigned(0); // We will reinit & rexecute unit
412
table->cursor->ha_delete_all_rows();
414
/* re-enabling indexes for next subselect iteration */
415
if (union_distinct && table->cursor->ha_enable_indexes(HA_KEY_SWITCH_ALL))
420
for (Select_Lex *sl= select_cursor; sl; sl= sl->next_select())
422
ha_rows records_at_start= 0;
423
session->lex->current_select= sl;
426
saved_error= sl->join->reinit();
430
if (sl == global_parameters || describe)
434
We can't use LIMIT at this stage if we are using ORDER BY for the
437
if (sl->order_list.first || describe)
438
select_limit_cnt= HA_POS_ERROR;
442
When using braces, SQL_CALC_FOUND_ROWS affects the whole query:
443
we don't calculate found_rows() per union part.
444
Otherwise, SQL_CALC_FOUND_ROWS should be done on all sub parts.
446
sl->join->select_options=
447
(select_limit_cnt == HA_POS_ERROR || sl->braces) ?
448
sl->options & ~OPTION_FOUND_ROWS : sl->options | found_rows_for_union;
450
saved_error= sl->join->optimize();
454
records_at_start= table->cursor->stats.records;
456
if (sl == union_distinct)
458
if (table->cursor->ha_disable_indexes(HA_KEY_SWITCH_ALL))
462
saved_error= sl->join->error;
463
offset_limit_cnt= (ha_rows)(sl->offset_limit ?
464
sl->offset_limit->val_uint() :
468
examined_rows+= session->examined_row_count;
469
if (union_result->flush())
471
session->lex->current_select= lex_select_save;
478
session->lex->current_select= lex_select_save;
481
/* Needed for the following test and for records_at_start in next loop */
482
int error= table->cursor->info(HA_STATUS_VARIABLE);
485
table->print_error(error, MYF(0));
488
if (found_rows_for_union && !sl->braces &&
489
select_limit_cnt != HA_POS_ERROR)
492
This is a union without braces. Remember the number of rows that
493
could also have been part of the result set.
494
We get this from the difference of between total number of possible
495
rows and actual rows added to the temporary table.
497
add_rows+= (uint64_t) (session->limit_found_rows - (uint64_t)
498
((table->cursor->stats.records - records_at_start)));
504
/* Send result to 'result' */
507
if (!session->is_fatal_error) // Check if EOM
509
set_limit(global_parameters);
510
init_prepare_fake_select_lex(session);
511
JOIN *join= fake_select_lex->join;
515
allocate JOIN for fake select only once (prevent
516
mysql_select automatic allocation)
517
TODO: The above is nonsense. mysql_select() will not allocate the
518
join if one already exists. There must be some other reason why we
519
don't let it allocate the join. Perhaps this is because we need
520
some special parameter values passed to join constructor?
522
if (!(fake_select_lex->join= new JOIN(session, item_list,
523
fake_select_lex->options, result)))
525
fake_select_lex->table_list.empty();
528
fake_select_lex->join->no_const_tables= true;
531
Fake Select_Lex should have item list for correctref_array
534
fake_select_lex->item_list= item_list;
535
saved_error= mysql_select(session, &fake_select_lex->ref_pointer_array,
538
global_parameters->order_list.elements,
539
(order_st*)global_parameters->order_list.first,
540
(order_st*) NULL, NULL,
541
fake_select_lex->options | SELECT_NO_UNLOCK,
542
result, this, fake_select_lex);
549
In EXPLAIN command, constant subqueries that do not use any
550
tables are executed two times:
551
- 1st time is a real evaluation to get the subquery value
552
- 2nd time is to produce EXPLAIN output rows.
553
1st execution sets certain members (e.g. select_result) to perform
554
subquery execution rather than EXPLAIN line production. In order
555
to reset them back, we re-do all of the actions (yes it is ugly):
557
join->reset(session, item_list, fake_select_lex->options, result);
558
saved_error= mysql_select(session, &fake_select_lex->ref_pointer_array,
561
global_parameters->order_list.elements,
562
(order_st*)global_parameters->order_list.first,
563
(order_st*) NULL, NULL,
564
fake_select_lex->options | SELECT_NO_UNLOCK,
565
result, this, fake_select_lex);
569
join->examined_rows= 0;
570
saved_error= join->reinit();
575
fake_select_lex->table_list.empty();
578
session->limit_found_rows = (uint64_t)table->cursor->stats.records + add_rows;
579
session->examined_row_count+= examined_rows;
582
Mark for slow query log if any of the union parts didn't use
587
session->lex->current_select= lex_select_save;
592
bool Select_Lex_Unit::cleanup()
605
union_result=0; // Safety
607
table->free_tmp_table(session);
611
for (Select_Lex *sl= first_select(); sl; sl= sl->next_select())
612
error|= sl->cleanup();
617
if ((join= fake_select_lex->join))
619
join->tables_list= 0;
622
error|= fake_select_lex->cleanup();
623
if (fake_select_lex->order_list.elements)
626
for (ord= (order_st*)fake_select_lex->order_list.first; ord; ord= ord->next)
627
(*ord->item)->cleanup();
635
void Select_Lex_Unit::reinit_exec_mechanism()
637
prepared= optimized= executed= 0;
642
change select_result object of unit
645
Select_Lex_Unit::change_result()
646
result new select_result object
647
old_result old select_result object
654
bool Select_Lex_Unit::change_result(select_result_interceptor *new_result,
655
select_result_interceptor *old_result)
658
for (Select_Lex *sl= first_select(); sl; sl= sl->next_select())
660
if (sl->join && sl->join->result == old_result)
661
if (sl->join->change_result(new_result))
664
if (fake_select_lex && fake_select_lex->join)
665
res= fake_select_lex->join->change_result(new_result);
670
Get column type information for this unit.
673
Select_Lex_Unit::get_unit_column_types()
676
For a single-select the column types are taken
677
from the list of selected items. For a union this function
678
assumes that Select_Lex_Unit::prepare has been called
679
and returns the type holders that were created for unioned
680
column types of all selects.
683
The implementation of this function should be in sync with
684
Select_Lex_Unit::prepare()
687
List<Item> *Select_Lex_Unit::get_unit_column_types()
689
Select_Lex *sl= first_select();
694
/* Types are generated during prepare */
698
return &sl->item_list;
701
bool Select_Lex::cleanup()
707
assert((Select_Lex*)join->select_lex == this);
708
error= join->destroy();
712
for (Select_Lex_Unit *lex_unit= first_inner_unit(); lex_unit ;
713
lex_unit= lex_unit->next_unit())
715
error= (bool) ((uint32_t) error | (uint32_t) lex_unit->cleanup());
717
non_agg_fields.empty();
718
inner_refs_list.empty();
723
void Select_Lex::cleanup_all_joins(bool full)
725
Select_Lex_Unit *unit;
731
for (unit= first_inner_unit(); unit; unit= unit->next_unit())
732
for (sl= unit->first_select(); sl; sl= sl->next_select())
733
sl->cleanup_all_joins(full);
736
} /* namespace drizzled */