12
12
You should have received a copy of the GNU General Public License
13
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
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/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)
22
#include <drizzled/drizzled_error_messages.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)
34
if (!(res= unit->prepare(session, result, SELECT_NO_UNLOCK |
30
if (!(res= unit->prepare(thd, result, SELECT_NO_UNLOCK |
35
31
setup_tables_done_option)))
44
40
** store records in temporary table for UNION
45
41
***************************************************************************/
47
int select_union::prepare(List<Item> &, Select_Lex_Unit *u)
43
int select_union::prepare(List<Item> &list __attribute__((unused)),
59
56
unit->offset_limit_cnt--;
62
fill_record(session, table->getFields(), values, true);
63
if (session->is_error())
59
fill_record(thd, table->field, values, 1);
66
if ((error= table->cursor->insertRecord(table->getInsertRecord())))
63
if ((error= table->file->ha_write_row(table->record[0])))
68
65
/* create_myisam_from_heap will generate error if needed */
69
if (table->cursor->is_fatal_error(error, HA_CHECK_DUP))
71
my_error(ER_USE_SQL_BIG_RESULT, MYF(0));
66
if (table->file->is_fatal_error(error, HA_CHECK_DUP) &&
67
create_myisam_from_heap(thd, table, tmp_table_param.start_recinfo,
68
&tmp_table_param.recinfo, error, 1))
85
81
bool select_union::flush()
88
if ((error=table->cursor->extra(HA_EXTRA_NO_CACHE)))
84
if ((error=table->file->extra(HA_EXTRA_NO_CACHE)))
90
table->print_error(error, MYF(0));
86
table->file->print_error(error, MYF(0));
100
96
select_union::create_result_table()
101
session thread handle
102
98
column_types a list of items used to define columns of the
104
100
is_union_distinct if set, the temporary table will eliminate
105
101
duplicates on insert
106
102
options create options
107
103
table_alias name of the temporary table
104
bit_fields_as_long convert bit fields to uint64_t
110
107
Create a temporary table that is used to store the result of a UNION,
119
select_union::create_result_table(Session *session_arg, List<Item> *column_types,
116
select_union::create_result_table(THD *thd_arg, List<Item> *column_types,
120
117
bool is_union_distinct, uint64_t options,
121
const char *table_alias)
118
const char *table_alias,
119
bool bit_fields_as_long)
123
assert(table == NULL);
124
122
tmp_table_param.init();
125
123
tmp_table_param.field_count= column_types->elements;
124
tmp_table_param.bit_fields_as_long= bit_fields_as_long;
127
if (! (table= create_tmp_table(session_arg, &tmp_table_param, *column_types,
128
(Order*) NULL, is_union_distinct, 1,
126
if (! (table= create_tmp_table(thd_arg, &tmp_table_param, *column_types,
127
(order_st*) 0, is_union_distinct, 1,
129
128
options, HA_POS_ERROR, (char*) table_alias)))
134
table->cursor->extra(HA_EXTRA_WRITE_CACHE);
135
table->cursor->extra(HA_EXTRA_IGNORE_DUP_KEY);
130
table->file->extra(HA_EXTRA_WRITE_CACHE);
131
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
148
143
void select_union::cleanup()
150
table->cursor->extra(HA_EXTRA_RESET_STATE);
151
table->cursor->ha_delete_all_rows();
152
table->free_io_cache();
153
table->filesort_free_buffers();
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);
158
153
initialization procedures before fake_select_lex preparation()
161
Select_Lex_Unit::init_prepare_fake_select_lex()
162
session - thread handler
156
st_select_lex_unit::init_prepare_fake_select_lex()
165
160
options of SELECT
169
Select_Lex_Unit::init_prepare_fake_select_lex(Session *session_arg)
164
st_select_lex_unit::init_prepare_fake_select_lex(THD *thd_arg)
171
session_arg->lex->current_select= fake_select_lex;
166
thd_arg->lex->current_select= fake_select_lex;
172
167
fake_select_lex->table_list.link_in_list((unsigned char *)&result_table_list,
173
168
(unsigned char **)
174
169
&result_table_list.next_local);
175
fake_select_lex->context.table_list=
176
fake_select_lex->context.first_name_resolution_table=
170
fake_select_lex->context.table_list=
171
fake_select_lex->context.first_name_resolution_table=
177
172
fake_select_lex->get_table_list();
179
for (Order *order= (Order *) global_parameters->order_list.first;
174
for (order_st *order= (order_st *) global_parameters->order_list.first;
181
176
order= order->next)
182
177
order->item= &order->item_ptr;
184
for (Order *order= (Order *)global_parameters->order_list.first;
179
for (order_st *order= (order_st *)global_parameters->order_list.first;
186
181
order=order->next)
194
bool Select_Lex_Unit::prepare(Session *session_arg, select_result *sel_result,
195
uint64_t additional_options)
189
bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
190
uint32_t additional_options)
197
Select_Lex *lex_select_save= session_arg->lex->current_select;
198
Select_Lex *sl, *first_sl= first_select();
192
SELECT_LEX *lex_select_save= thd_arg->lex->current_select;
193
SELECT_LEX *sl, *first_sl= first_select();
199
194
select_result *tmp_result;
200
195
bool is_union_select;
201
196
Table *empty_table= 0;
254
249
bool can_skip_order_by;
255
250
sl->options|= SELECT_NO_UNLOCK;
256
Join *join= new Join(session_arg, sl->item_list,
257
sl->options | session_arg->options | additional_options,
251
JOIN *join= new JOIN(thd_arg, sl->item_list,
252
sl->options | thd_arg->options | additional_options,
260
255
setup_tables_done_option should be set only for very first SELECT,
278
273
sl->order_list.elements) +
279
274
sl->group_list.elements,
280
275
can_skip_order_by ?
281
(Order*) NULL : (Order *)sl->order_list.first,
282
(Order*) sl->group_list.first,
276
(order_st*) 0 : (order_st *)sl->order_list.first,
277
(order_st*) sl->group_list.first,
279
(is_union_select ? (order_st*) 0 :
280
(order_st*) thd_arg->lex->proc_list.first),
285
282
/* There are no * in the statement anymore (for PS) */
286
283
sl->with_wild= 0;
288
if (saved_error || (saved_error= session_arg->is_fatal_error))
285
if (saved_error || (saved_error= thd_arg->is_fatal_error))
291
288
Use items list of underlaid select for derived tables to preserve
302
299
field object without table.
304
301
assert(!empty_table);
305
empty_table= (Table*) session->calloc(sizeof(Table));
302
empty_table= (Table*) thd->calloc(sizeof(Table));
307
304
List_iterator_fast<Item> it(sl->item_list);
309
306
while ((item_tmp= it++))
311
308
/* Error's in 'new' will be detected after loop */
312
types.push_back(new Item_type_holder(session_arg, item_tmp));
309
types.push_back(new Item_type_holder(thd_arg, item_tmp));
315
if (session_arg->is_fatal_error)
312
if (thd_arg->is_fatal_error)
316
313
goto err; // out of memory
326
323
List_iterator_fast<Item> it(sl->item_list);
327
List_iterator_fast<Item> tp(types);
324
List_iterator_fast<Item> tp(types);
328
325
Item *type, *item_tmp;
329
326
while ((type= tp++, item_tmp= it++))
331
if (((Item_type_holder*)type)->join_types(session_arg, item_tmp))
328
if (((Item_type_holder*)type)->join_types(thd_arg, item_tmp))
357
create_options= (first_sl->options | session_arg->options |
354
create_options= (first_sl->options | thd_arg->options |
358
355
TMP_TABLE_ALL_COLUMNS);
360
if (union_result->create_result_table(session, &types, test(union_distinct),
357
if (union_result->create_result_table(thd, &types, test(union_distinct),
358
create_options, "", false))
363
360
memset(&result_table_list, 0, sizeof(result_table_list));
364
result_table_list.setSchemaName((char*) "");
365
result_table_list.alias= "union";
366
result_table_list.setTableName((char *) "union");
361
result_table_list.db= (char*) "";
362
result_table_list.table_name= result_table_list.alias= (char*) "union";
367
363
result_table_list.table= table= union_result->table;
369
session_arg->lex->current_select= lex_select_save;
365
thd_arg->lex->current_select= lex_select_save;
370
366
if (!item_list.elements)
372
368
saved_error= table->fill_item_list(&item_list);
386
session_arg->lex->current_select= lex_select_save;
382
thd_arg->lex->current_select= lex_select_save;
388
return(saved_error || session_arg->is_fatal_error);
384
return(saved_error || thd_arg->is_fatal_error);
391
session_arg->lex->current_select= lex_select_save;
387
thd_arg->lex->current_select= lex_select_save;
396
bool Select_Lex_Unit::exec()
392
bool st_select_lex_unit::exec()
398
Select_Lex *lex_select_save= session->lex->current_select;
399
Select_Lex *select_cursor=first_select();
394
SELECT_LEX *lex_select_save= thd->lex->current_select;
395
SELECT_LEX *select_cursor=first_select();
400
396
uint64_t add_rows=0;
401
397
ha_rows examined_rows= 0;
403
if (executed && uncacheable.none() && ! describe)
399
if (executed && !uncacheable && !describe)
407
if (uncacheable.any() || ! item || ! item->assigned() || describe)
403
if (uncacheable || !item || !item->assigned() || describe)
410
406
item->reset_value_registration();
415
411
item->assigned(0); // We will reinit & rexecute unit
417
table->cursor->ha_delete_all_rows();
413
table->file->ha_delete_all_rows();
419
415
/* re-enabling indexes for next subselect iteration */
420
if (union_distinct && table->cursor->ha_enable_indexes(HA_KEY_SWITCH_ALL))
416
if (union_distinct && table->file->ha_enable_indexes(HA_KEY_SWITCH_ALL))
425
for (Select_Lex *sl= select_cursor; sl; sl= sl->next_select())
421
for (SELECT_LEX *sl= select_cursor; sl; sl= sl->next_select())
427
423
ha_rows records_at_start= 0;
428
session->lex->current_select= sl;
424
thd->lex->current_select= sl;
431
427
saved_error= sl->join->reinit();
448
444
we don't calculate found_rows() per union part.
449
445
Otherwise, SQL_CALC_FOUND_ROWS should be done on all sub parts.
451
sl->join->select_options=
447
sl->join->select_options=
452
448
(select_limit_cnt == HA_POS_ERROR || sl->braces) ?
453
449
sl->options & ~OPTION_FOUND_ROWS : sl->options | found_rows_for_union;
451
/* dump_TableList_struct(select_lex, select_lex->leaf_tables); */
452
if (sl->join->flatten_subqueries())
455
/* dump_TableList_struct(select_lex, select_lex->leaf_tables); */
455
456
saved_error= sl->join->optimize();
457
458
if (!saved_error)
459
records_at_start= table->cursor->stats.records;
460
records_at_start= table->file->stats.records;
460
461
sl->join->exec();
461
462
if (sl == union_distinct)
463
if (table->cursor->ha_disable_indexes(HA_KEY_SWITCH_ALL))
464
if (table->file->ha_disable_indexes(HA_KEY_SWITCH_ALL))
465
466
table->no_keyread=1;
471
472
if (!saved_error)
473
examined_rows+= session->examined_row_count;
474
examined_rows+= thd->examined_row_count;
474
475
if (union_result->flush())
476
session->lex->current_select= lex_select_save;
477
thd->lex->current_select= lex_select_save;
483
session->lex->current_select= lex_select_save;
484
thd->lex->current_select= lex_select_save;
484
485
return(saved_error);
486
487
/* Needed for the following test and for records_at_start in next loop */
487
int error= table->cursor->info(HA_STATUS_VARIABLE);
488
int error= table->file->info(HA_STATUS_VARIABLE);
490
table->print_error(error, MYF(0));
491
table->file->print_error(error, MYF(0));
493
if (found_rows_for_union && !sl->braces &&
494
if (found_rows_for_union && !sl->braces &&
494
495
select_limit_cnt != HA_POS_ERROR)
499
500
We get this from the difference of between total number of possible
500
501
rows and actual rows added to the temporary table.
502
add_rows+= (uint64_t) (session->limit_found_rows - (uint64_t)
503
((table->cursor->stats.records - records_at_start)));
503
add_rows+= (uint64_t) (thd->limit_found_rows - (uint64_t)
504
((table->file->stats.records - records_at_start)));
509
510
/* Send result to 'result' */
510
511
saved_error= true;
512
if (!session->is_fatal_error) // Check if EOM
513
if (!thd->is_fatal_error) // Check if EOM
514
515
set_limit(global_parameters);
515
init_prepare_fake_select_lex(session);
516
Join *join= fake_select_lex->join;
516
init_prepare_fake_select_lex(thd);
517
JOIN *join= fake_select_lex->join;
524
525
don't let it allocate the join. Perhaps this is because we need
525
526
some special parameter values passed to join constructor?
527
if (!(fake_select_lex->join= new Join(session, item_list,
528
if (!(fake_select_lex->join= new JOIN(thd, item_list,
528
529
fake_select_lex->options, result)))
530
531
fake_select_lex->table_list.empty();
533
534
fake_select_lex->join->no_const_tables= true;
536
Fake Select_Lex should have item list for correctref_array
537
Fake st_select_lex should have item list for correctref_array
539
540
fake_select_lex->item_list= item_list;
540
saved_error= mysql_select(session, &fake_select_lex->ref_pointer_array,
541
saved_error= mysql_select(thd, &fake_select_lex->ref_pointer_array,
541
542
&result_table_list,
542
543
0, item_list, NULL,
543
544
global_parameters->order_list.elements,
544
(Order*)global_parameters->order_list.first,
545
(order_st*)global_parameters->order_list.first,
546
(order_st*) NULL, NULL, (order_st*) NULL,
546
547
fake_select_lex->options | SELECT_NO_UNLOCK,
547
548
result, this, fake_select_lex);
556
557
- 1st time is a real evaluation to get the subquery value
557
558
- 2nd time is to produce EXPLAIN output rows.
558
559
1st execution sets certain members (e.g. select_result) to perform
559
subquery execution rather than EXPLAIN line production. In order
560
subquery execution rather than EXPLAIN line production. In order
560
561
to reset them back, we re-do all of the actions (yes it is ugly):
562
join->reset(session, item_list, fake_select_lex->options, result);
563
saved_error= mysql_select(session, &fake_select_lex->ref_pointer_array,
563
join->init(thd, item_list, fake_select_lex->options, result);
564
saved_error= mysql_select(thd, &fake_select_lex->ref_pointer_array,
564
565
&result_table_list,
565
566
0, item_list, NULL,
566
567
global_parameters->order_list.elements,
567
(Order*)global_parameters->order_list.first,
568
(order_st*)global_parameters->order_list.first,
569
(order_st*) NULL, NULL, (order_st*) NULL,
569
570
fake_select_lex->options | SELECT_NO_UNLOCK,
570
571
result, this, fake_select_lex);
580
581
fake_select_lex->table_list.empty();
581
582
if (!saved_error)
583
session->limit_found_rows = (uint64_t)table->cursor->stats.records + add_rows;
584
session->examined_row_count+= examined_rows;
584
thd->limit_found_rows = (uint64_t)table->file->stats.records + add_rows;
585
thd->examined_row_count+= examined_rows;
587
588
Mark for slow query log if any of the union parts didn't use
609
610
delete union_result;
610
611
union_result=0; // Safety
613
table->free_tmp_table(thd);
611
614
table= 0; // Safety
614
for (Select_Lex *sl= first_select(); sl; sl= sl->next_select())
617
for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
615
618
error|= sl->cleanup();
617
620
if (fake_select_lex)
620
623
if ((join= fake_select_lex->join))
622
625
join->tables_list= 0;
625
628
error|= fake_select_lex->cleanup();
626
629
if (fake_select_lex->order_list.elements)
629
for (ord= (Order*)fake_select_lex->order_list.first; ord; ord= ord->next)
632
for (ord= (order_st*)fake_select_lex->order_list.first; ord; ord= ord->next)
630
633
(*ord->item)->cleanup();
645
648
change select_result object of unit
648
Select_Lex_Unit::change_result()
651
st_select_lex_unit::change_result()
649
652
result new select_result object
650
653
old_result old select_result object
657
bool Select_Lex_Unit::change_result(select_result_interceptor *new_result,
660
bool st_select_lex_unit::change_result(select_result_interceptor *new_result,
658
661
select_result_interceptor *old_result)
661
for (Select_Lex *sl= first_select(); sl; sl= sl->next_select())
664
for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
663
666
if (sl->join && sl->join->result == old_result)
664
667
if (sl->join->change_result(new_result))
673
676
Get column type information for this unit.
676
Select_Lex_Unit::get_unit_column_types()
679
st_select_lex_unit::get_unit_column_types()
679
682
For a single-select the column types are taken
680
683
from the list of selected items. For a union this function
681
assumes that Select_Lex_Unit::prepare has been called
684
assumes that st_select_lex_unit::prepare has been called
682
685
and returns the type holders that were created for unioned
683
686
column types of all selects.
686
689
The implementation of this function should be in sync with
687
Select_Lex_Unit::prepare()
690
st_select_lex_unit::prepare()
690
List<Item> *Select_Lex_Unit::get_unit_column_types()
693
List<Item> *st_select_lex_unit::get_unit_column_types()
692
Select_Lex *sl= first_select();
695
SELECT_LEX *sl= first_select();
701
704
return &sl->item_list;
704
bool Select_Lex::cleanup()
707
bool st_select_lex::cleanup()
706
709
bool error= false;
710
assert((Select_Lex*)join->select_lex == this);
713
assert((st_select_lex*)join->select_lex == this);
711
714
error= join->destroy();
715
for (Select_Lex_Unit *lex_unit= first_inner_unit(); lex_unit ;
718
for (SELECT_LEX_UNIT *lex_unit= first_inner_unit(); lex_unit ;
716
719
lex_unit= lex_unit->next_unit())
718
error= (bool) ((uint32_t) error | (uint32_t) lex_unit->cleanup());
721
error= (bool) ((uint) error | (uint) lex_unit->cleanup());
720
723
non_agg_fields.empty();
721
724
inner_refs_list.empty();