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
19
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)
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)
34
if (!(res= unit->prepare(session, result, SELECT_NO_UNLOCK |
32
if (!(res= unit->prepare(thd, result, SELECT_NO_UNLOCK |
35
33
setup_tables_done_option)))
44
42
** store records in temporary table for UNION
45
43
***************************************************************************/
47
int select_union::prepare(List<Item> &, Select_Lex_Unit *u)
45
int select_union::prepare(List<Item> &list __attribute__((__unused__)),
59
58
unit->offset_limit_cnt--;
62
fill_record(session, table->getFields(), values, true);
63
if (session->is_error())
61
fill_record(thd, table->field, values, 1);
66
if ((error= table->cursor->insertRecord(table->getInsertRecord())))
65
if ((error= table->file->ha_write_row(table->record[0])))
68
67
/* 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));
68
if (table->file->is_fatal_error(error, HA_CHECK_DUP) &&
69
create_myisam_from_heap(thd, table, tmp_table_param.start_recinfo,
70
&tmp_table_param.recinfo, error, 1))
85
83
bool select_union::flush()
88
if ((error=table->cursor->extra(HA_EXTRA_NO_CACHE)))
86
if ((error=table->file->extra(HA_EXTRA_NO_CACHE)))
90
table->print_error(error, MYF(0));
88
table->file->print_error(error, MYF(0));
100
98
select_union::create_result_table()
101
session thread handle
102
100
column_types a list of items used to define columns of the
104
102
is_union_distinct if set, the temporary table will eliminate
105
103
duplicates on insert
106
104
options create options
107
105
table_alias name of the temporary table
106
bit_fields_as_long convert bit fields to uint64_t
110
109
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,
118
select_union::create_result_table(THD *thd_arg, List<Item> *column_types,
120
119
bool is_union_distinct, uint64_t options,
121
const char *table_alias)
120
const char *table_alias,
121
bool bit_fields_as_long)
123
assert(table == NULL);
124
124
tmp_table_param.init();
125
125
tmp_table_param.field_count= column_types->elements;
126
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,
128
if (! (table= create_tmp_table(thd_arg, &tmp_table_param, *column_types,
129
(ORDER*) 0, is_union_distinct, 1,
129
130
options, HA_POS_ERROR, (char*) table_alias)))
134
table->cursor->extra(HA_EXTRA_WRITE_CACHE);
135
table->cursor->extra(HA_EXTRA_IGNORE_DUP_KEY);
132
table->file->extra(HA_EXTRA_WRITE_CACHE);
133
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
148
145
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();
147
table->file->extra(HA_EXTRA_RESET_STATE);
148
table->file->ha_delete_all_rows();
149
free_io_cache(table);
150
filesort_free_buffers(table,0);
158
155
initialization procedures before fake_select_lex preparation()
161
Select_Lex_Unit::init_prepare_fake_select_lex()
162
session - thread handler
158
st_select_lex_unit::init_prepare_fake_select_lex()
165
162
options of SELECT
169
Select_Lex_Unit::init_prepare_fake_select_lex(Session *session_arg)
166
st_select_lex_unit::init_prepare_fake_select_lex(THD *thd_arg)
171
session_arg->lex->current_select= fake_select_lex;
172
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,
174
171
&result_table_list.next_local);
175
fake_select_lex->context.table_list=
176
fake_select_lex->context.first_name_resolution_table=
172
fake_select_lex->context.table_list=
173
fake_select_lex->context.first_name_resolution_table=
177
174
fake_select_lex->get_table_list();
179
for (Order *order= (Order *) global_parameters->order_list.first;
182
order->item= &order->item_ptr;
184
for (Order *order= (Order *)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;
186
184
order=order->next)
188
186
(*order->item)->walk(&Item::change_context_processor, 0,
189
(unsigned char*) &fake_select_lex->context);
187
(uchar*) &fake_select_lex->context);
194
bool Select_Lex_Unit::prepare(Session *session_arg, select_result *sel_result,
195
uint64_t additional_options)
192
bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
193
uint32_t additional_options)
197
Select_Lex *lex_select_save= session_arg->lex->current_select;
198
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();
199
197
select_result *tmp_result;
200
198
bool is_union_select;
201
Table *empty_table= 0;
199
TABLE *empty_table= 0;
203
201
describe= test(additional_options & SELECT_DESCRIBE);
254
252
bool can_skip_order_by;
255
253
sl->options|= SELECT_NO_UNLOCK;
256
Join *join= new Join(session_arg, sl->item_list,
257
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,
260
258
setup_tables_done_option should be set only for very first SELECT,
269
session_arg->lex->current_select= sl;
267
thd_arg->lex->current_select= sl;
271
269
can_skip_order_by= is_union_select && !(sl->braces && sl->explicit_limit);
273
271
saved_error= join->prepare(&sl->ref_pointer_array,
274
(TableList*) sl->table_list.first,
272
(TABLE_LIST*) sl->table_list.first,
277
275
(can_skip_order_by ? 0 :
278
276
sl->order_list.elements) +
279
277
sl->group_list.elements,
280
278
can_skip_order_by ?
281
(Order*) NULL : (Order *)sl->order_list.first,
282
(Order*) 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),
285
285
/* There are no * in the statement anymore (for PS) */
286
286
sl->with_wild= 0;
288
if (saved_error || (saved_error= session_arg->is_fatal_error))
288
if (saved_error || (saved_error= thd_arg->is_fatal_error))
291
291
Use items list of underlaid select for derived tables to preserve
302
302
field object without table.
304
304
assert(!empty_table);
305
empty_table= (Table*) session->calloc(sizeof(Table));
305
empty_table= (TABLE*) thd->calloc(sizeof(TABLE));
307
307
List_iterator_fast<Item> it(sl->item_list);
309
309
while ((item_tmp= it++))
311
311
/* Error's in 'new' will be detected after loop */
312
types.push_back(new Item_type_holder(session_arg, item_tmp));
312
types.push_back(new Item_type_holder(thd_arg, item_tmp));
315
if (session_arg->is_fatal_error)
315
if (thd_arg->is_fatal_error)
316
316
goto err; // out of memory
326
326
List_iterator_fast<Item> it(sl->item_list);
327
List_iterator_fast<Item> tp(types);
327
List_iterator_fast<Item> tp(types);
328
328
Item *type, *item_tmp;
329
329
while ((type= tp++, item_tmp= it++))
331
if (((Item_type_holder*)type)->join_types(session_arg, item_tmp))
331
if (((Item_type_holder*)type)->join_types(thd_arg, item_tmp))
357
create_options= (first_sl->options | session_arg->options |
357
create_options= (first_sl->options | thd_arg->options |
358
358
TMP_TABLE_ALL_COLUMNS);
360
if (union_result->create_result_table(session, &types, test(union_distinct),
360
if (union_result->create_result_table(thd, &types, test(union_distinct),
361
create_options, "", false))
363
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");
363
bzero((char*) &result_table_list, sizeof(result_table_list));
364
result_table_list.db= (char*) "";
365
result_table_list.table_name= result_table_list.alias= (char*) "union";
367
366
result_table_list.table= table= union_result->table;
369
session_arg->lex->current_select= lex_select_save;
368
thd_arg->lex->current_select= lex_select_save;
370
369
if (!item_list.elements)
372
371
saved_error= table->fill_item_list(&item_list);
377
assert(thd->stmt_arena->is_conventional() == false);
379
379
We're in execution of a prepared statement or stored procedure:
380
380
reset field items to point at fields from the created temporary table.
382
table->reset_item_list(&item_list);
386
session_arg->lex->current_select= lex_select_save;
386
thd_arg->lex->current_select= lex_select_save;
388
return(saved_error || session_arg->is_fatal_error);
388
return(saved_error || thd_arg->is_fatal_error);
391
session_arg->lex->current_select= lex_select_save;
391
thd_arg->lex->current_select= lex_select_save;
396
bool Select_Lex_Unit::exec()
396
bool st_select_lex_unit::exec()
398
Select_Lex *lex_select_save= session->lex->current_select;
399
Select_Lex *select_cursor=first_select();
398
SELECT_LEX *lex_select_save= thd->lex->current_select;
399
SELECT_LEX *select_cursor=first_select();
400
400
uint64_t add_rows=0;
401
401
ha_rows examined_rows= 0;
403
if (executed && uncacheable.none() && ! describe)
403
if (executed && !uncacheable && !describe)
407
if (uncacheable.any() || ! item || ! item->assigned() || describe)
407
if (uncacheable || !item || !item->assigned() || describe)
410
410
item->reset_value_registration();
415
415
item->assigned(0); // We will reinit & rexecute unit
417
table->cursor->ha_delete_all_rows();
417
table->file->ha_delete_all_rows();
419
419
/* re-enabling indexes for next subselect iteration */
420
if (union_distinct && table->cursor->ha_enable_indexes(HA_KEY_SWITCH_ALL))
420
if (union_distinct && table->file->ha_enable_indexes(HA_KEY_SWITCH_ALL))
425
for (Select_Lex *sl= select_cursor; sl; sl= sl->next_select())
425
for (SELECT_LEX *sl= select_cursor; sl; sl= sl->next_select())
427
427
ha_rows records_at_start= 0;
428
session->lex->current_select= sl;
428
thd->lex->current_select= sl;
431
431
saved_error= sl->join->reinit();
448
448
we don't calculate found_rows() per union part.
449
449
Otherwise, SQL_CALC_FOUND_ROWS should be done on all sub parts.
451
sl->join->select_options=
451
sl->join->select_options=
452
452
(select_limit_cnt == HA_POS_ERROR || sl->braces) ?
453
453
sl->options & ~OPTION_FOUND_ROWS : sl->options | found_rows_for_union;
455
/* dump_TABLE_LIST_struct(select_lex, select_lex->leaf_tables); */
456
if (sl->join->flatten_subqueries())
459
/* dump_TABLE_LIST_struct(select_lex, select_lex->leaf_tables); */
455
460
saved_error= sl->join->optimize();
457
462
if (!saved_error)
459
records_at_start= table->cursor->stats.records;
464
records_at_start= table->file->stats.records;
460
465
sl->join->exec();
461
466
if (sl == union_distinct)
463
if (table->cursor->ha_disable_indexes(HA_KEY_SWITCH_ALL))
468
if (table->file->ha_disable_indexes(HA_KEY_SWITCH_ALL))
465
470
table->no_keyread=1;
471
476
if (!saved_error)
473
examined_rows+= session->examined_row_count;
478
examined_rows+= thd->examined_row_count;
474
479
if (union_result->flush())
476
session->lex->current_select= lex_select_save;
481
thd->lex->current_select= lex_select_save;
483
session->lex->current_select= lex_select_save;
488
thd->lex->current_select= lex_select_save;
484
489
return(saved_error);
486
491
/* Needed for the following test and for records_at_start in next loop */
487
int error= table->cursor->info(HA_STATUS_VARIABLE);
492
int error= table->file->info(HA_STATUS_VARIABLE);
490
table->print_error(error, MYF(0));
495
table->file->print_error(error, MYF(0));
493
if (found_rows_for_union && !sl->braces &&
498
if (found_rows_for_union && !sl->braces &&
494
499
select_limit_cnt != HA_POS_ERROR)
499
504
We get this from the difference of between total number of possible
500
505
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)));
507
add_rows+= (uint64_t) (thd->limit_found_rows - (uint64_t)
508
((table->file->stats.records - records_at_start)));
509
514
/* Send result to 'result' */
510
515
saved_error= true;
512
if (!session->is_fatal_error) // Check if EOM
517
if (!thd->is_fatal_error) // Check if EOM
514
519
set_limit(global_parameters);
515
init_prepare_fake_select_lex(session);
516
Join *join= fake_select_lex->join;
520
init_prepare_fake_select_lex(thd);
521
JOIN *join= fake_select_lex->join;
520
525
allocate JOIN for fake select only once (prevent
521
select_query automatic allocation)
522
TODO: The above is nonsense. select_query() will not allocate the
526
mysql_select automatic allocation)
527
TODO: The above is nonsense. mysql_select() will not allocate the
523
528
join if one already exists. There must be some other reason why we
524
529
don't let it allocate the join. Perhaps this is because we need
525
530
some special parameter values passed to join constructor?
527
if (!(fake_select_lex->join= new Join(session, item_list,
532
if (!(fake_select_lex->join= new JOIN(thd, item_list,
528
533
fake_select_lex->options, result)))
530
535
fake_select_lex->table_list.empty();
533
538
fake_select_lex->join->no_const_tables= true;
536
Fake Select_Lex should have item list for correctref_array
541
Fake st_select_lex should have item list for correctref_array
539
544
fake_select_lex->item_list= item_list;
540
saved_error= select_query(session, &fake_select_lex->ref_pointer_array,
545
saved_error= mysql_select(thd, &fake_select_lex->ref_pointer_array,
541
546
&result_table_list,
542
547
0, item_list, NULL,
543
548
global_parameters->order_list.elements,
544
(Order*)global_parameters->order_list.first,
549
(ORDER*)global_parameters->order_list.first,
550
(ORDER*) NULL, NULL, (ORDER*) NULL,
546
551
fake_select_lex->options | SELECT_NO_UNLOCK,
547
552
result, this, fake_select_lex);
556
561
- 1st time is a real evaluation to get the subquery value
557
562
- 2nd time is to produce EXPLAIN output rows.
558
563
1st execution sets certain members (e.g. select_result) to perform
559
subquery execution rather than EXPLAIN line production. In order
564
subquery execution rather than EXPLAIN line production. In order
560
565
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= select_query(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,
564
569
&result_table_list,
565
570
0, item_list, NULL,
566
571
global_parameters->order_list.elements,
567
(Order*)global_parameters->order_list.first,
572
(ORDER*)global_parameters->order_list.first,
573
(ORDER*) NULL, NULL, (ORDER*) NULL,
569
574
fake_select_lex->options | SELECT_NO_UNLOCK,
570
575
result, this, fake_select_lex);
580
585
fake_select_lex->table_list.empty();
581
586
if (!saved_error)
583
session->limit_found_rows = (uint64_t)table->cursor->stats.records + add_rows;
584
session->examined_row_count+= examined_rows;
588
thd->limit_found_rows = (uint64_t)table->file->stats.records + add_rows;
589
thd->examined_row_count+= examined_rows;
587
592
Mark for slow query log if any of the union parts didn't use
609
614
delete union_result;
610
615
union_result=0; // Safety
617
free_tmp_table(thd, table);
611
618
table= 0; // Safety
614
for (Select_Lex *sl= first_select(); sl; sl= sl->next_select())
621
for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
615
622
error|= sl->cleanup();
617
624
if (fake_select_lex)
620
627
if ((join= fake_select_lex->join))
622
629
join->tables_list= 0;
645
652
change select_result object of unit
648
Select_Lex_Unit::change_result()
655
st_select_lex_unit::change_result()
649
656
result new select_result object
650
657
old_result old select_result object
657
bool Select_Lex_Unit::change_result(select_result_interceptor *new_result,
664
bool st_select_lex_unit::change_result(select_result_interceptor *new_result,
658
665
select_result_interceptor *old_result)
661
for (Select_Lex *sl= first_select(); sl; sl= sl->next_select())
668
for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
663
670
if (sl->join && sl->join->result == old_result)
664
671
if (sl->join->change_result(new_result))
673
680
Get column type information for this unit.
676
Select_Lex_Unit::get_unit_column_types()
683
st_select_lex_unit::get_unit_column_types()
679
686
For a single-select the column types are taken
680
687
from the list of selected items. For a union this function
681
assumes that Select_Lex_Unit::prepare has been called
688
assumes that st_select_lex_unit::prepare has been called
682
689
and returns the type holders that were created for unioned
683
690
column types of all selects.
686
693
The implementation of this function should be in sync with
687
Select_Lex_Unit::prepare()
694
st_select_lex_unit::prepare()
690
List<Item> *Select_Lex_Unit::get_unit_column_types()
697
List<Item> *st_select_lex_unit::get_unit_column_types()
692
Select_Lex *sl= first_select();
699
SELECT_LEX *sl= first_select();
701
708
return &sl->item_list;
704
bool Select_Lex::cleanup()
711
bool st_select_lex::cleanup()
706
713
bool error= false;
710
assert((Select_Lex*)join->select_lex == this);
717
assert((st_select_lex*)join->select_lex == this);
711
718
error= join->destroy();
715
for (Select_Lex_Unit *lex_unit= first_inner_unit(); lex_unit ;
722
for (SELECT_LEX_UNIT *lex_unit= first_inner_unit(); lex_unit ;
716
723
lex_unit= lex_unit->next_unit())
718
error= (bool) ((uint32_t) error | (uint32_t) lex_unit->cleanup());
725
error= (bool) ((uint) error | (uint) lex_unit->cleanup());
720
727
non_agg_fields.empty();
721
728
inner_refs_list.empty();