18
18
UNION's were introduced by Monty and Sinisa <sinisa@mysql.com>
20
#include <drizzled/server_includes.h>
21
21
#include <drizzled/sql_select.h>
22
#include <drizzled/drizzled_error_messages.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>
24
bool mysql_union(THD *thd,
25
LEX *lex __attribute__((unused)),
26
select_result *result,
27
SELECT_LEX_UNIT *unit, ulong setup_tables_done_option)
27
bool drizzle_union(Session *session, LEX *, select_result *result,
28
Select_Lex_Unit *unit, uint64_t setup_tables_done_option)
30
if (!(res= unit->prepare(thd, result, SELECT_NO_UNLOCK |
31
if (!(res= unit->prepare(session, result, SELECT_NO_UNLOCK |
31
32
setup_tables_done_option)))
40
41
** store records in temporary table for UNION
41
42
***************************************************************************/
43
int select_union::prepare(List<Item> &list __attribute__((unused)),
44
int select_union::prepare(List<Item> &, Select_Lex_Unit *u)
56
56
unit->offset_limit_cnt--;
59
fill_record(thd, table->field, values, 1);
59
fill_record(session, table->field, values, true);
60
if (session->is_error())
63
if ((error= table->file->ha_write_row(table->record[0])))
63
if ((error= table->cursor->ha_write_row(table->record[0])))
65
65
/* create_myisam_from_heap will generate error if needed */
66
if (table->file->is_fatal_error(error, HA_CHECK_DUP) &&
67
create_myisam_from_heap(thd, table, tmp_table_param.start_recinfo,
66
if (table->cursor->is_fatal_error(error, HA_CHECK_DUP) &&
67
create_myisam_from_heap(session, table, tmp_table_param.start_recinfo,
68
68
&tmp_table_param.recinfo, error, 1))
81
81
bool select_union::flush()
84
if ((error=table->file->extra(HA_EXTRA_NO_CACHE)))
84
if ((error=table->cursor->extra(HA_EXTRA_NO_CACHE)))
86
table->file->print_error(error, MYF(0));
86
table->print_error(error, MYF(0));
116
select_union::create_result_table(THD *thd_arg, List<Item> *column_types,
116
select_union::create_result_table(Session *session_arg, List<Item> *column_types,
117
117
bool is_union_distinct, uint64_t options,
118
118
const char *table_alias,
119
119
bool bit_fields_as_long)
123
123
tmp_table_param.field_count= column_types->elements;
124
124
tmp_table_param.bit_fields_as_long= bit_fields_as_long;
126
if (! (table= create_tmp_table(thd_arg, &tmp_table_param, *column_types,
127
(ORDER*) 0, is_union_distinct, 1,
126
if (! (table= create_tmp_table(session_arg, &tmp_table_param, *column_types,
127
(order_st*) 0, is_union_distinct, 1,
128
128
options, HA_POS_ERROR, (char*) table_alias)))
130
table->file->extra(HA_EXTRA_WRITE_CACHE);
131
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
130
table->cursor->extra(HA_EXTRA_WRITE_CACHE);
131
table->cursor->extra(HA_EXTRA_IGNORE_DUP_KEY);
143
143
void select_union::cleanup()
145
table->file->extra(HA_EXTRA_RESET_STATE);
146
table->file->ha_delete_all_rows();
147
free_io_cache(table);
148
filesort_free_buffers(table,0);
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
153
initialization procedures before fake_select_lex preparation()
156
st_select_lex_unit::init_prepare_fake_select_lex()
156
Select_Lex_Unit::init_prepare_fake_select_lex()
157
session - thread handler
160
160
options of SELECT
164
st_select_lex_unit::init_prepare_fake_select_lex(THD *thd_arg)
164
Select_Lex_Unit::init_prepare_fake_select_lex(Session *session_arg)
166
thd_arg->lex->current_select= fake_select_lex;
167
fake_select_lex->table_list.link_in_list((uchar *)&result_table_list,
166
session_arg->lex->current_select= fake_select_lex;
167
fake_select_lex->table_list.link_in_list((unsigned char *)&result_table_list,
169
169
&result_table_list.next_local);
170
fake_select_lex->context.table_list=
171
fake_select_lex->context.first_name_resolution_table=
170
fake_select_lex->context.table_list=
171
fake_select_lex->context.first_name_resolution_table=
172
172
fake_select_lex->get_table_list();
173
if (!fake_select_lex->first_execution)
175
for (ORDER *order= (ORDER *) global_parameters->order_list.first;
178
order->item= &order->item_ptr;
180
for (ORDER *order= (ORDER *)global_parameters->order_list.first;
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;
182
181
order=order->next)
184
183
(*order->item)->walk(&Item::change_context_processor, 0,
185
(uchar*) &fake_select_lex->context);
184
(unsigned char*) &fake_select_lex->context);
190
bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
191
uint32_t additional_options)
189
bool Select_Lex_Unit::prepare(Session *session_arg, select_result *sel_result,
190
uint64_t additional_options)
193
SELECT_LEX *lex_select_save= thd_arg->lex->current_select;
194
SELECT_LEX *sl, *first_sl= first_select();
192
Select_Lex *lex_select_save= session_arg->lex->current_select;
193
Select_Lex *sl, *first_sl= first_select();
195
194
select_result *tmp_result;
196
195
bool is_union_select;
197
TABLE *empty_table= 0;
196
Table *empty_table= 0;
199
198
describe= test(additional_options & SELECT_DESCRIBE);
250
249
bool can_skip_order_by;
251
250
sl->options|= SELECT_NO_UNLOCK;
252
JOIN *join= new JOIN(thd_arg, sl->item_list,
253
sl->options | thd_arg->options | additional_options,
251
JOIN *join= new JOIN(session_arg, sl->item_list,
252
sl->options | session_arg->options | additional_options,
256
255
setup_tables_done_option should be set only for very first SELECT,
265
thd_arg->lex->current_select= sl;
264
session_arg->lex->current_select= sl;
267
266
can_skip_order_by= is_union_select && !(sl->braces && sl->explicit_limit);
269
268
saved_error= join->prepare(&sl->ref_pointer_array,
270
(TABLE_LIST*) sl->table_list.first,
269
(TableList*) sl->table_list.first,
273
272
(can_skip_order_by ? 0 :
274
273
sl->order_list.elements) +
275
274
sl->group_list.elements,
276
275
can_skip_order_by ?
277
(ORDER*) 0 : (ORDER *)sl->order_list.first,
278
(ORDER*) sl->group_list.first,
276
(order_st*) 0 : (order_st *)sl->order_list.first,
277
(order_st*) sl->group_list.first,
280
(is_union_select ? (ORDER*) 0 :
281
(ORDER*) thd_arg->lex->proc_list.first),
283
280
/* There are no * in the statement anymore (for PS) */
284
281
sl->with_wild= 0;
286
if (saved_error || (saved_error= thd_arg->is_fatal_error))
283
if (saved_error || (saved_error= session_arg->is_fatal_error))
289
286
Use items list of underlaid select for derived tables to preserve
300
297
field object without table.
302
299
assert(!empty_table);
303
empty_table= (TABLE*) thd->calloc(sizeof(TABLE));
300
empty_table= (Table*) session->calloc(sizeof(Table));
305
302
List_iterator_fast<Item> it(sl->item_list);
307
304
while ((item_tmp= it++))
309
306
/* Error's in 'new' will be detected after loop */
310
types.push_back(new Item_type_holder(thd_arg, item_tmp));
307
types.push_back(new Item_type_holder(session_arg, item_tmp));
313
if (thd_arg->is_fatal_error)
310
if (session_arg->is_fatal_error)
314
311
goto err; // out of memory
324
321
List_iterator_fast<Item> it(sl->item_list);
325
List_iterator_fast<Item> tp(types);
322
List_iterator_fast<Item> tp(types);
326
323
Item *type, *item_tmp;
327
324
while ((type= tp++, item_tmp= it++))
329
if (((Item_type_holder*)type)->join_types(thd_arg, item_tmp))
326
if (((Item_type_holder*)type)->join_types(session_arg, item_tmp))
355
create_options= (first_sl->options | thd_arg->options |
352
create_options= (first_sl->options | session_arg->options |
356
353
TMP_TABLE_ALL_COLUMNS);
358
if (union_result->create_result_table(thd, &types, test(union_distinct),
355
if (union_result->create_result_table(session, &types, test(union_distinct),
359
356
create_options, "", false))
361
358
memset(&result_table_list, 0, sizeof(result_table_list));
362
359
result_table_list.db= (char*) "";
363
result_table_list.table_name= result_table_list.alias= (char*) "union";
360
result_table_list.alias= "union";
361
result_table_list.table_name= (char *) "union";
364
362
result_table_list.table= table= union_result->table;
366
thd_arg->lex->current_select= lex_select_save;
364
session_arg->lex->current_select= lex_select_save;
367
365
if (!item_list.elements)
369
367
saved_error= table->fill_item_list(&item_list);
375
assert(thd->stmt_arena->is_conventional() == false);
377
374
We're in execution of a prepared statement or stored procedure:
378
375
reset field items to point at fields from the created temporary table.
380
table->reset_item_list(&item_list);
384
thd_arg->lex->current_select= lex_select_save;
381
session_arg->lex->current_select= lex_select_save;
386
return(saved_error || thd_arg->is_fatal_error);
383
return(saved_error || session_arg->is_fatal_error);
389
thd_arg->lex->current_select= lex_select_save;
386
session_arg->lex->current_select= lex_select_save;
394
bool st_select_lex_unit::exec()
391
bool Select_Lex_Unit::exec()
396
SELECT_LEX *lex_select_save= thd->lex->current_select;
397
SELECT_LEX *select_cursor=first_select();
393
Select_Lex *lex_select_save= session->lex->current_select;
394
Select_Lex *select_cursor=first_select();
398
395
uint64_t add_rows=0;
399
396
ha_rows examined_rows= 0;
401
398
if (executed && !uncacheable && !describe)
405
402
if (uncacheable || !item || !item->assigned() || describe)
413
410
item->assigned(0); // We will reinit & rexecute unit
415
table->file->ha_delete_all_rows();
412
table->cursor->ha_delete_all_rows();
417
414
/* re-enabling indexes for next subselect iteration */
418
if (union_distinct && table->file->ha_enable_indexes(HA_KEY_SWITCH_ALL))
415
if (union_distinct && table->cursor->ha_enable_indexes(HA_KEY_SWITCH_ALL))
423
for (SELECT_LEX *sl= select_cursor; sl; sl= sl->next_select())
420
for (Select_Lex *sl= select_cursor; sl; sl= sl->next_select())
425
422
ha_rows records_at_start= 0;
426
thd->lex->current_select= sl;
423
session->lex->current_select= sl;
429
426
saved_error= sl->join->reinit();
446
443
we don't calculate found_rows() per union part.
447
444
Otherwise, SQL_CALC_FOUND_ROWS should be done on all sub parts.
449
sl->join->select_options=
446
sl->join->select_options=
450
447
(select_limit_cnt == HA_POS_ERROR || sl->braces) ?
451
448
sl->options & ~OPTION_FOUND_ROWS : sl->options | found_rows_for_union;
453
/* dump_TABLE_LIST_struct(select_lex, select_lex->leaf_tables); */
454
if (sl->join->flatten_subqueries())
457
/* dump_TABLE_LIST_struct(select_lex, select_lex->leaf_tables); */
458
450
saved_error= sl->join->optimize();
460
452
if (!saved_error)
462
records_at_start= table->file->stats.records;
454
records_at_start= table->cursor->stats.records;
463
455
sl->join->exec();
464
456
if (sl == union_distinct)
466
if (table->file->ha_disable_indexes(HA_KEY_SWITCH_ALL))
458
if (table->cursor->ha_disable_indexes(HA_KEY_SWITCH_ALL))
468
460
table->no_keyread=1;
474
466
if (!saved_error)
476
examined_rows+= thd->examined_row_count;
468
examined_rows+= session->examined_row_count;
477
469
if (union_result->flush())
479
thd->lex->current_select= lex_select_save;
471
session->lex->current_select= lex_select_save;
486
thd->lex->current_select= lex_select_save;
478
session->lex->current_select= lex_select_save;
487
479
return(saved_error);
489
481
/* Needed for the following test and for records_at_start in next loop */
490
int error= table->file->info(HA_STATUS_VARIABLE);
482
int error= table->cursor->info(HA_STATUS_VARIABLE);
493
table->file->print_error(error, MYF(0));
485
table->print_error(error, MYF(0));
496
if (found_rows_for_union && !sl->braces &&
488
if (found_rows_for_union && !sl->braces &&
497
489
select_limit_cnt != HA_POS_ERROR)
502
494
We get this from the difference of between total number of possible
503
495
rows and actual rows added to the temporary table.
505
add_rows+= (uint64_t) (thd->limit_found_rows - (uint64_t)
506
((table->file->stats.records - records_at_start)));
497
add_rows+= (uint64_t) (session->limit_found_rows - (uint64_t)
498
((table->cursor->stats.records - records_at_start)));
512
504
/* Send result to 'result' */
513
505
saved_error= true;
515
if (!thd->is_fatal_error) // Check if EOM
507
if (!session->is_fatal_error) // Check if EOM
517
509
set_limit(global_parameters);
518
init_prepare_fake_select_lex(thd);
510
init_prepare_fake_select_lex(session);
519
511
JOIN *join= fake_select_lex->join;
527
519
don't let it allocate the join. Perhaps this is because we need
528
520
some special parameter values passed to join constructor?
530
if (!(fake_select_lex->join= new JOIN(thd, item_list,
522
if (!(fake_select_lex->join= new JOIN(session, item_list,
531
523
fake_select_lex->options, result)))
533
525
fake_select_lex->table_list.empty();
536
528
fake_select_lex->join->no_const_tables= true;
539
Fake st_select_lex should have item list for correctref_array
531
Fake Select_Lex should have item list for correctref_array
542
534
fake_select_lex->item_list= item_list;
543
saved_error= mysql_select(thd, &fake_select_lex->ref_pointer_array,
535
saved_error= mysql_select(session, &fake_select_lex->ref_pointer_array,
544
536
&result_table_list,
545
537
0, item_list, NULL,
546
538
global_parameters->order_list.elements,
547
(ORDER*)global_parameters->order_list.first,
548
(ORDER*) NULL, NULL, (ORDER*) NULL,
539
(order_st*)global_parameters->order_list.first,
540
(order_st*) NULL, NULL,
549
541
fake_select_lex->options | SELECT_NO_UNLOCK,
550
542
result, this, fake_select_lex);
559
551
- 1st time is a real evaluation to get the subquery value
560
552
- 2nd time is to produce EXPLAIN output rows.
561
553
1st execution sets certain members (e.g. select_result) to perform
562
subquery execution rather than EXPLAIN line production. In order
554
subquery execution rather than EXPLAIN line production. In order
563
555
to reset them back, we re-do all of the actions (yes it is ugly):
565
join->init(thd, item_list, fake_select_lex->options, result);
566
saved_error= mysql_select(thd, &fake_select_lex->ref_pointer_array,
557
join->reset(session, item_list, fake_select_lex->options, result);
558
saved_error= mysql_select(session, &fake_select_lex->ref_pointer_array,
567
559
&result_table_list,
568
560
0, item_list, NULL,
569
561
global_parameters->order_list.elements,
570
(ORDER*)global_parameters->order_list.first,
571
(ORDER*) NULL, NULL, (ORDER*) NULL,
562
(order_st*)global_parameters->order_list.first,
563
(order_st*) NULL, NULL,
572
564
fake_select_lex->options | SELECT_NO_UNLOCK,
573
565
result, this, fake_select_lex);
583
575
fake_select_lex->table_list.empty();
584
576
if (!saved_error)
586
thd->limit_found_rows = (uint64_t)table->file->stats.records + add_rows;
587
thd->examined_row_count+= examined_rows;
578
session->limit_found_rows = (uint64_t)table->cursor->stats.records + add_rows;
579
session->examined_row_count+= examined_rows;
590
582
Mark for slow query log if any of the union parts didn't use
612
604
delete union_result;
613
605
union_result=0; // Safety
615
free_tmp_table(thd, table);
607
table->free_tmp_table(session);
616
608
table= 0; // Safety
619
for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
611
for (Select_Lex *sl= first_select(); sl; sl= sl->next_select())
620
612
error|= sl->cleanup();
622
614
if (fake_select_lex)
650
642
change select_result object of unit
653
st_select_lex_unit::change_result()
645
Select_Lex_Unit::change_result()
654
646
result new select_result object
655
647
old_result old select_result object
662
bool st_select_lex_unit::change_result(select_result_interceptor *new_result,
654
bool Select_Lex_Unit::change_result(select_result_interceptor *new_result,
663
655
select_result_interceptor *old_result)
666
for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
658
for (Select_Lex *sl= first_select(); sl; sl= sl->next_select())
668
660
if (sl->join && sl->join->result == old_result)
669
661
if (sl->join->change_result(new_result))
678
670
Get column type information for this unit.
681
st_select_lex_unit::get_unit_column_types()
673
Select_Lex_Unit::get_unit_column_types()
684
676
For a single-select the column types are taken
685
677
from the list of selected items. For a union this function
686
assumes that st_select_lex_unit::prepare has been called
678
assumes that Select_Lex_Unit::prepare has been called
687
679
and returns the type holders that were created for unioned
688
680
column types of all selects.
691
683
The implementation of this function should be in sync with
692
st_select_lex_unit::prepare()
684
Select_Lex_Unit::prepare()
695
List<Item> *st_select_lex_unit::get_unit_column_types()
687
List<Item> *Select_Lex_Unit::get_unit_column_types()
697
SELECT_LEX *sl= first_select();
689
Select_Lex *sl= first_select();
706
698
return &sl->item_list;
709
bool st_select_lex::cleanup()
701
bool Select_Lex::cleanup()
711
703
bool error= false;
715
assert((st_select_lex*)join->select_lex == this);
707
assert((Select_Lex*)join->select_lex == this);
716
708
error= join->destroy();
720
for (SELECT_LEX_UNIT *lex_unit= first_inner_unit(); lex_unit ;
712
for (Select_Lex_Unit *lex_unit= first_inner_unit(); lex_unit ;
721
713
lex_unit= lex_unit->next_unit())
723
error= (bool) ((uint) error | (uint) lex_unit->cleanup());
715
error= (bool) ((uint32_t) error | (uint32_t) lex_unit->cleanup());
725
717
non_agg_fields.empty();
726
718
inner_refs_list.empty();