13
13
along with this program; if not, write to the Free Software
14
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
18
19
UNION's were introduced by Monty and Sinisa <sinisa@mysql.com>
20
#include <drizzled/server_includes.h>
21
#include <drizzled/sql_select.h>
22
#include <drizzled/error.h>
23
#include <drizzled/item/type_holder.h>
24
#include <drizzled/sql_base.h>
26
bool mysql_union(Session *session, LEX *, select_result *result,
27
Select_Lex_Unit *unit, uint64_t setup_tables_done_option)
23
#include "mysql_priv.h"
24
#include "sql_select.h"
26
bool mysql_union(THD *thd,
27
LEX *lex __attribute__((__unused__)),
28
select_result *result,
29
SELECT_LEX_UNIT *unit, ulong setup_tables_done_option)
30
if (!(res= unit->prepare(session, result, SELECT_NO_UNLOCK |
32
if (!(res= unit->prepare(thd, result, SELECT_NO_UNLOCK |
31
33
setup_tables_done_option)))
40
42
** store records in temporary table for UNION
41
43
***************************************************************************/
43
int select_union::prepare(List<Item> &, Select_Lex_Unit *u)
45
int select_union::prepare(List<Item> &list __attribute__((__unused__)),
55
58
unit->offset_limit_cnt--;
58
fill_record(session, table->field, values, 1);
59
if (session->is_error())
61
fill_record(thd, table->field, values, 1);
62
65
if ((error= table->file->ha_write_row(table->record[0])))
64
67
/* create_myisam_from_heap will generate error if needed */
65
68
if (table->file->is_fatal_error(error, HA_CHECK_DUP) &&
66
create_myisam_from_heap(session, table, tmp_table_param.start_recinfo,
69
create_myisam_from_heap(thd, table, tmp_table_param.start_recinfo,
67
70
&tmp_table_param.recinfo, error, 1))
95
98
select_union::create_result_table()
97
100
column_types a list of items used to define columns of the
99
102
is_union_distinct if set, the temporary table will eliminate
100
103
duplicates on insert
101
104
options create options
102
105
table_alias name of the temporary table
103
bit_fields_as_long convert bit fields to uint64_t
106
bit_fields_as_long convert bit fields to ulonglong
106
109
Create a temporary table that is used to store the result of a UNION,
115
select_union::create_result_table(Session *session_arg, List<Item> *column_types,
116
bool is_union_distinct, uint64_t options,
118
select_union::create_result_table(THD *thd_arg, List<Item> *column_types,
119
bool is_union_distinct, ulonglong options,
117
120
const char *table_alias,
118
121
bool bit_fields_as_long)
122
125
tmp_table_param.field_count= column_types->elements;
123
126
tmp_table_param.bit_fields_as_long= bit_fields_as_long;
125
if (! (table= create_tmp_table(session_arg, &tmp_table_param, *column_types,
126
(order_st*) 0, is_union_distinct, 1,
128
if (! (table= create_tmp_table(thd_arg, &tmp_table_param, *column_types,
129
(ORDER*) 0, is_union_distinct, 1,
127
130
options, HA_POS_ERROR, (char*) table_alias)))
129
132
table->file->extra(HA_EXTRA_WRITE_CACHE);
152
155
initialization procedures before fake_select_lex preparation()
155
Select_Lex_Unit::init_prepare_fake_select_lex()
156
session - thread handler
158
st_select_lex_unit::init_prepare_fake_select_lex()
159
162
options of SELECT
163
Select_Lex_Unit::init_prepare_fake_select_lex(Session *session_arg)
166
st_select_lex_unit::init_prepare_fake_select_lex(THD *thd_arg)
165
session_arg->lex->current_select= fake_select_lex;
166
fake_select_lex->table_list.link_in_list((unsigned char *)&result_table_list,
168
thd_arg->lex->current_select= fake_select_lex;
169
fake_select_lex->table_list.link_in_list((uchar *)&result_table_list,
168
171
&result_table_list.next_local);
169
fake_select_lex->context.table_list=
170
fake_select_lex->context.first_name_resolution_table=
172
fake_select_lex->context.table_list=
173
fake_select_lex->context.first_name_resolution_table=
171
174
fake_select_lex->get_table_list();
173
for (order_st *order= (order_st *) global_parameters->order_list.first;
176
order->item= &order->item_ptr;
178
for (order_st *order= (order_st *)global_parameters->order_list.first;
175
if (!fake_select_lex->first_execution)
177
for (ORDER *order= (ORDER *) global_parameters->order_list.first;
180
order->item= &order->item_ptr;
182
for (ORDER *order= (ORDER *)global_parameters->order_list.first;
180
184
order=order->next)
182
186
(*order->item)->walk(&Item::change_context_processor, 0,
183
(unsigned char*) &fake_select_lex->context);
187
(uchar*) &fake_select_lex->context);
188
bool Select_Lex_Unit::prepare(Session *session_arg, select_result *sel_result,
189
uint64_t additional_options)
192
bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
193
ulong additional_options)
191
Select_Lex *lex_select_save= session_arg->lex->current_select;
192
Select_Lex *sl, *first_sl= first_select();
195
SELECT_LEX *lex_select_save= thd_arg->lex->current_select;
196
SELECT_LEX *sl, *first_sl= first_select();
193
197
select_result *tmp_result;
194
198
bool is_union_select;
195
Table *empty_table= 0;
199
TABLE *empty_table= 0;
197
201
describe= test(additional_options & SELECT_DESCRIBE);
248
252
bool can_skip_order_by;
249
253
sl->options|= SELECT_NO_UNLOCK;
250
JOIN *join= new JOIN(session_arg, sl->item_list,
251
sl->options | session_arg->options | additional_options,
254
JOIN *join= new JOIN(thd_arg, sl->item_list,
255
sl->options | thd_arg->options | additional_options,
254
258
setup_tables_done_option should be set only for very first SELECT,
263
session_arg->lex->current_select= sl;
267
thd_arg->lex->current_select= sl;
265
269
can_skip_order_by= is_union_select && !(sl->braces && sl->explicit_limit);
267
271
saved_error= join->prepare(&sl->ref_pointer_array,
268
(TableList*) sl->table_list.first,
272
(TABLE_LIST*) sl->table_list.first,
271
275
(can_skip_order_by ? 0 :
272
276
sl->order_list.elements) +
273
277
sl->group_list.elements,
274
278
can_skip_order_by ?
275
(order_st*) 0 : (order_st *)sl->order_list.first,
276
(order_st*) sl->group_list.first,
279
(ORDER*) 0 : (ORDER *)sl->order_list.first,
280
(ORDER*) sl->group_list.first,
282
(is_union_select ? (ORDER*) 0 :
283
(ORDER*) thd_arg->lex->proc_list.first),
279
285
/* There are no * in the statement anymore (for PS) */
280
286
sl->with_wild= 0;
282
if (saved_error || (saved_error= session_arg->is_fatal_error))
288
if (saved_error || (saved_error= thd_arg->is_fatal_error))
285
291
Use items list of underlaid select for derived tables to preserve
296
302
field object without table.
298
304
assert(!empty_table);
299
empty_table= (Table*) session->calloc(sizeof(Table));
305
empty_table= (TABLE*) thd->calloc(sizeof(TABLE));
301
307
List_iterator_fast<Item> it(sl->item_list);
303
309
while ((item_tmp= it++))
305
311
/* Error's in 'new' will be detected after loop */
306
types.push_back(new Item_type_holder(session_arg, item_tmp));
312
types.push_back(new Item_type_holder(thd_arg, item_tmp));
309
if (session_arg->is_fatal_error)
315
if (thd_arg->is_fatal_error)
310
316
goto err; // out of memory
320
326
List_iterator_fast<Item> it(sl->item_list);
321
List_iterator_fast<Item> tp(types);
327
List_iterator_fast<Item> tp(types);
322
328
Item *type, *item_tmp;
323
329
while ((type= tp++, item_tmp= it++))
325
if (((Item_type_holder*)type)->join_types(session_arg, item_tmp))
331
if (((Item_type_holder*)type)->join_types(thd_arg, item_tmp))
351
create_options= (first_sl->options | session_arg->options |
357
create_options= (first_sl->options | thd_arg->options |
352
358
TMP_TABLE_ALL_COLUMNS);
354
if (union_result->create_result_table(session, &types, test(union_distinct),
360
if (union_result->create_result_table(thd, &types, test(union_distinct),
355
361
create_options, "", false))
357
memset(&result_table_list, 0, sizeof(result_table_list));
363
bzero((char*) &result_table_list, sizeof(result_table_list));
358
364
result_table_list.db= (char*) "";
359
365
result_table_list.table_name= result_table_list.alias= (char*) "union";
360
366
result_table_list.table= table= union_result->table;
362
session_arg->lex->current_select= lex_select_save;
368
thd_arg->lex->current_select= lex_select_save;
363
369
if (!item_list.elements)
365
371
saved_error= table->fill_item_list(&item_list);
377
assert(thd->stmt_arena->is_conventional() == false);
372
379
We're in execution of a prepared statement or stored procedure:
373
380
reset field items to point at fields from the created temporary table.
382
table->reset_item_list(&item_list);
379
session_arg->lex->current_select= lex_select_save;
386
thd_arg->lex->current_select= lex_select_save;
381
return(saved_error || session_arg->is_fatal_error);
388
return(saved_error || thd_arg->is_fatal_error);
384
session_arg->lex->current_select= lex_select_save;
391
thd_arg->lex->current_select= lex_select_save;
389
bool Select_Lex_Unit::exec()
396
bool st_select_lex_unit::exec()
391
Select_Lex *lex_select_save= session->lex->current_select;
392
Select_Lex *select_cursor=first_select();
398
SELECT_LEX *lex_select_save= thd->lex->current_select;
399
SELECT_LEX *select_cursor=first_select();
400
ulonglong add_rows=0;
394
401
ha_rows examined_rows= 0;
396
403
if (executed && !uncacheable && !describe)
400
407
if (uncacheable || !item || !item->assigned() || describe)
418
for (Select_Lex *sl= select_cursor; sl; sl= sl->next_select())
425
for (SELECT_LEX *sl= select_cursor; sl; sl= sl->next_select())
420
427
ha_rows records_at_start= 0;
421
session->lex->current_select= sl;
428
thd->lex->current_select= sl;
424
431
saved_error= sl->join->reinit();
441
448
we don't calculate found_rows() per union part.
442
449
Otherwise, SQL_CALC_FOUND_ROWS should be done on all sub parts.
444
sl->join->select_options=
451
sl->join->select_options=
445
452
(select_limit_cnt == HA_POS_ERROR || sl->braces) ?
446
453
sl->options & ~OPTION_FOUND_ROWS : sl->options | found_rows_for_union;
455
/* dump_TABLE_LIST_struct(select_lex, select_lex->leaf_tables); */
448
456
if (sl->join->flatten_subqueries())
459
/* dump_TABLE_LIST_struct(select_lex, select_lex->leaf_tables); */
451
460
saved_error= sl->join->optimize();
453
462
if (!saved_error)
467
476
if (!saved_error)
469
examined_rows+= session->examined_row_count;
478
examined_rows+= thd->examined_row_count;
470
479
if (union_result->flush())
472
session->lex->current_select= lex_select_save;
481
thd->lex->current_select= lex_select_save;
479
session->lex->current_select= lex_select_save;
488
thd->lex->current_select= lex_select_save;
480
489
return(saved_error);
482
491
/* Needed for the following test and for records_at_start in next loop */
495
504
We get this from the difference of between total number of possible
496
505
rows and actual rows added to the temporary table.
498
add_rows+= (uint64_t) (session->limit_found_rows - (uint64_t)
507
add_rows+= (ulonglong) (thd->limit_found_rows - (ulonglong)
499
508
((table->file->stats.records - records_at_start)));
505
514
/* Send result to 'result' */
506
515
saved_error= true;
508
if (!session->is_fatal_error) // Check if EOM
517
if (!thd->is_fatal_error) // Check if EOM
510
519
set_limit(global_parameters);
511
init_prepare_fake_select_lex(session);
520
init_prepare_fake_select_lex(thd);
512
521
JOIN *join= fake_select_lex->join;
520
529
don't let it allocate the join. Perhaps this is because we need
521
530
some special parameter values passed to join constructor?
523
if (!(fake_select_lex->join= new JOIN(session, item_list,
532
if (!(fake_select_lex->join= new JOIN(thd, item_list,
524
533
fake_select_lex->options, result)))
526
535
fake_select_lex->table_list.empty();
529
538
fake_select_lex->join->no_const_tables= true;
532
Fake Select_Lex should have item list for correctref_array
541
Fake st_select_lex should have item list for correctref_array
535
544
fake_select_lex->item_list= item_list;
536
saved_error= mysql_select(session, &fake_select_lex->ref_pointer_array,
545
saved_error= mysql_select(thd, &fake_select_lex->ref_pointer_array,
537
546
&result_table_list,
538
547
0, item_list, NULL,
539
548
global_parameters->order_list.elements,
540
(order_st*)global_parameters->order_list.first,
541
(order_st*) NULL, NULL,
549
(ORDER*)global_parameters->order_list.first,
550
(ORDER*) NULL, NULL, (ORDER*) NULL,
542
551
fake_select_lex->options | SELECT_NO_UNLOCK,
543
552
result, this, fake_select_lex);
552
561
- 1st time is a real evaluation to get the subquery value
553
562
- 2nd time is to produce EXPLAIN output rows.
554
563
1st execution sets certain members (e.g. select_result) to perform
555
subquery execution rather than EXPLAIN line production. In order
564
subquery execution rather than EXPLAIN line production. In order
556
565
to reset them back, we re-do all of the actions (yes it is ugly):
558
join->init(session, item_list, fake_select_lex->options, result);
559
saved_error= mysql_select(session, &fake_select_lex->ref_pointer_array,
567
join->init(thd, item_list, fake_select_lex->options, result);
568
saved_error= mysql_select(thd, &fake_select_lex->ref_pointer_array,
560
569
&result_table_list,
561
570
0, item_list, NULL,
562
571
global_parameters->order_list.elements,
563
(order_st*)global_parameters->order_list.first,
564
(order_st*) NULL, NULL,
572
(ORDER*)global_parameters->order_list.first,
573
(ORDER*) NULL, NULL, (ORDER*) NULL,
565
574
fake_select_lex->options | SELECT_NO_UNLOCK,
566
575
result, this, fake_select_lex);
576
585
fake_select_lex->table_list.empty();
577
586
if (!saved_error)
579
session->limit_found_rows = (uint64_t)table->file->stats.records + add_rows;
580
session->examined_row_count+= examined_rows;
588
thd->limit_found_rows = (ulonglong)table->file->stats.records + add_rows;
589
thd->examined_row_count+= examined_rows;
583
592
Mark for slow query log if any of the union parts didn't use
605
614
delete union_result;
606
615
union_result=0; // Safety
608
table->free_tmp_table(session);
617
free_tmp_table(thd, table);
609
618
table= 0; // Safety
612
for (Select_Lex *sl= first_select(); sl; sl= sl->next_select())
621
for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
613
622
error|= sl->cleanup();
615
624
if (fake_select_lex)
643
652
change select_result object of unit
646
Select_Lex_Unit::change_result()
655
st_select_lex_unit::change_result()
647
656
result new select_result object
648
657
old_result old select_result object
655
bool Select_Lex_Unit::change_result(select_result_interceptor *new_result,
664
bool st_select_lex_unit::change_result(select_result_interceptor *new_result,
656
665
select_result_interceptor *old_result)
659
for (Select_Lex *sl= first_select(); sl; sl= sl->next_select())
668
for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
661
670
if (sl->join && sl->join->result == old_result)
662
671
if (sl->join->change_result(new_result))
671
680
Get column type information for this unit.
674
Select_Lex_Unit::get_unit_column_types()
683
st_select_lex_unit::get_unit_column_types()
677
686
For a single-select the column types are taken
678
687
from the list of selected items. For a union this function
679
assumes that Select_Lex_Unit::prepare has been called
688
assumes that st_select_lex_unit::prepare has been called
680
689
and returns the type holders that were created for unioned
681
690
column types of all selects.
684
693
The implementation of this function should be in sync with
685
Select_Lex_Unit::prepare()
694
st_select_lex_unit::prepare()
688
List<Item> *Select_Lex_Unit::get_unit_column_types()
697
List<Item> *st_select_lex_unit::get_unit_column_types()
690
Select_Lex *sl= first_select();
699
SELECT_LEX *sl= first_select();
699
708
return &sl->item_list;
702
bool Select_Lex::cleanup()
711
bool st_select_lex::cleanup()
704
713
bool error= false;
708
assert((Select_Lex*)join->select_lex == this);
717
assert((st_select_lex*)join->select_lex == this);
709
718
error= join->destroy();
713
for (Select_Lex_Unit *lex_unit= first_inner_unit(); lex_unit ;
722
for (SELECT_LEX_UNIT *lex_unit= first_inner_unit(); lex_unit ;
714
723
lex_unit= lex_unit->next_unit())
716
error= (bool) ((uint32_t) error | (uint32_t) lex_unit->cleanup());
725
error= (bool) ((uint) error | (uint) lex_unit->cleanup());
718
727
non_agg_fields.empty();
719
728
inner_refs_list.empty();