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>
22
#include <drizzled/sql_select.h>
23
#include <drizzled/error.h>
24
#include <drizzled/item/type_holder.h>
25
#include <drizzled/sql_base.h>
26
#include <drizzled/sql_union.h>
27
#include <drizzled/select_union.h>
28
#include <drizzled/sql_lex.h>
29
#include <drizzled/session.h>
34
bool drizzle_union(Session *session, LEX *, select_result *result,
35
Select_Lex_Unit *unit, uint64_t setup_tables_done_option)
23
#include "mysql_priv.h"
24
#include "sql_select.h"
25
#include <drizzled/drizzled_error_messages.h>
27
bool mysql_union(THD *thd,
28
LEX *lex __attribute__((unused)),
29
select_result *result,
30
SELECT_LEX_UNIT *unit, ulong setup_tables_done_option)
38
if (!(res= unit->prepare(session, result, SELECT_NO_UNLOCK |
33
if (!(res= unit->prepare(thd, result, SELECT_NO_UNLOCK |
39
34
setup_tables_done_option)))
48
43
** store records in temporary table for UNION
49
44
***************************************************************************/
51
int select_union::prepare(List<Item> &, Select_Lex_Unit *u)
46
int select_union::prepare(List<Item> &list __attribute__((unused)),
63
59
unit->offset_limit_cnt--;
66
fill_record(session, table->getFields(), values, true);
67
if (session->is_error())
62
fill_record(thd, table->field, values, 1);
70
if ((error= table->cursor->insertRecord(table->getInsertRecord())))
66
if ((error= table->file->ha_write_row(table->record[0])))
72
68
/* create_myisam_from_heap will generate error if needed */
73
if (table->cursor->is_fatal_error(error, HA_CHECK_DUP))
75
my_error(ER_USE_SQL_BIG_RESULT, MYF(0));
69
if (table->file->is_fatal_error(error, HA_CHECK_DUP) &&
70
create_myisam_from_heap(thd, table, tmp_table_param.start_recinfo,
71
&tmp_table_param.recinfo, error, 1))
89
84
bool select_union::flush()
92
if ((error=table->cursor->extra(HA_EXTRA_NO_CACHE)))
87
if ((error=table->file->extra(HA_EXTRA_NO_CACHE)))
94
table->print_error(error, MYF(0));
89
table->file->print_error(error, MYF(0));
104
99
select_union::create_result_table()
105
session thread handle
106
101
column_types a list of items used to define columns of the
108
103
is_union_distinct if set, the temporary table will eliminate
109
104
duplicates on insert
110
105
options create options
111
106
table_alias name of the temporary table
107
bit_fields_as_long convert bit fields to uint64_t
114
110
Create a temporary table that is used to store the result of a UNION,
123
select_union::create_result_table(Session *session_arg, List<Item> *column_types,
119
select_union::create_result_table(THD *thd_arg, List<Item> *column_types,
124
120
bool is_union_distinct, uint64_t options,
125
const char *table_alias)
121
const char *table_alias,
122
bool bit_fields_as_long)
127
assert(table == NULL);
128
125
tmp_table_param.init();
129
126
tmp_table_param.field_count= column_types->elements;
127
tmp_table_param.bit_fields_as_long= bit_fields_as_long;
131
if (! (table= create_tmp_table(session_arg, &tmp_table_param, *column_types,
132
(Order*) NULL, is_union_distinct, 1,
129
if (! (table= create_tmp_table(thd_arg, &tmp_table_param, *column_types,
130
(ORDER*) 0, is_union_distinct, 1,
133
131
options, HA_POS_ERROR, (char*) table_alias)))
138
table->cursor->extra(HA_EXTRA_WRITE_CACHE);
139
table->cursor->extra(HA_EXTRA_IGNORE_DUP_KEY);
133
table->file->extra(HA_EXTRA_WRITE_CACHE);
134
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
152
146
void select_union::cleanup()
154
table->cursor->extra(HA_EXTRA_RESET_STATE);
155
table->cursor->ha_delete_all_rows();
156
table->free_io_cache();
157
table->filesort_free_buffers();
148
table->file->extra(HA_EXTRA_RESET_STATE);
149
table->file->ha_delete_all_rows();
150
free_io_cache(table);
151
filesort_free_buffers(table,0);
162
156
initialization procedures before fake_select_lex preparation()
165
Select_Lex_Unit::init_prepare_fake_select_lex()
166
session - thread handler
159
st_select_lex_unit::init_prepare_fake_select_lex()
169
163
options of SELECT
173
Select_Lex_Unit::init_prepare_fake_select_lex(Session *session_arg)
167
st_select_lex_unit::init_prepare_fake_select_lex(THD *thd_arg)
175
session_arg->getLex()->current_select= fake_select_lex;
176
fake_select_lex->table_list.link_in_list((unsigned char *)&result_table_list,
169
thd_arg->lex->current_select= fake_select_lex;
170
fake_select_lex->table_list.link_in_list((uchar *)&result_table_list,
178
172
&result_table_list.next_local);
179
fake_select_lex->context.table_list=
180
fake_select_lex->context.first_name_resolution_table=
173
fake_select_lex->context.table_list=
174
fake_select_lex->context.first_name_resolution_table=
181
175
fake_select_lex->get_table_list();
183
for (Order *order= (Order *) global_parameters->order_list.first;
186
order->item= &order->item_ptr;
188
for (Order *order= (Order *)global_parameters->order_list.first;
176
if (!fake_select_lex->first_execution)
178
for (ORDER *order= (ORDER *) global_parameters->order_list.first;
181
order->item= &order->item_ptr;
183
for (ORDER *order= (ORDER *)global_parameters->order_list.first;
190
185
order=order->next)
192
187
(*order->item)->walk(&Item::change_context_processor, 0,
193
(unsigned char*) &fake_select_lex->context);
188
(uchar*) &fake_select_lex->context);
198
bool Select_Lex_Unit::prepare(Session *session_arg, select_result *sel_result,
199
uint64_t additional_options)
193
bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
194
uint32_t additional_options)
201
Select_Lex *lex_select_save= session_arg->getLex()->current_select;
202
Select_Lex *sl, *first_sl= first_select();
196
SELECT_LEX *lex_select_save= thd_arg->lex->current_select;
197
SELECT_LEX *sl, *first_sl= first_select();
203
198
select_result *tmp_result;
204
199
bool is_union_select;
205
Table *empty_table= 0;
200
TABLE *empty_table= 0;
207
202
describe= test(additional_options & SELECT_DESCRIBE);
258
253
bool can_skip_order_by;
259
254
sl->options|= SELECT_NO_UNLOCK;
260
Join *join= new Join(session_arg, sl->item_list,
261
sl->options | session_arg->options | additional_options,
255
JOIN *join= new JOIN(thd_arg, sl->item_list,
256
sl->options | thd_arg->options | additional_options,
264
259
setup_tables_done_option should be set only for very first SELECT,
273
session_arg->getLex()->current_select= sl;
268
thd_arg->lex->current_select= sl;
275
270
can_skip_order_by= is_union_select && !(sl->braces && sl->explicit_limit);
277
272
saved_error= join->prepare(&sl->ref_pointer_array,
278
(TableList*) sl->table_list.first,
273
(TABLE_LIST*) sl->table_list.first,
281
276
(can_skip_order_by ? 0 :
282
277
sl->order_list.elements) +
283
278
sl->group_list.elements,
284
279
can_skip_order_by ?
285
(Order*) NULL : (Order *)sl->order_list.first,
286
(Order*) sl->group_list.first,
280
(ORDER*) 0 : (ORDER *)sl->order_list.first,
281
(ORDER*) sl->group_list.first,
283
(is_union_select ? (ORDER*) 0 :
284
(ORDER*) thd_arg->lex->proc_list.first),
289
286
/* There are no * in the statement anymore (for PS) */
290
287
sl->with_wild= 0;
292
if (saved_error || (saved_error= session_arg->is_fatal_error))
289
if (saved_error || (saved_error= thd_arg->is_fatal_error))
295
292
Use items list of underlaid select for derived tables to preserve
306
303
field object without table.
308
305
assert(!empty_table);
309
empty_table= (Table*) session->calloc(sizeof(Table));
311
List<Item>::iterator it(sl->item_list.begin());
306
empty_table= (TABLE*) thd->calloc(sizeof(TABLE));
308
List_iterator_fast<Item> it(sl->item_list);
313
310
while ((item_tmp= it++))
315
312
/* Error's in 'new' will be detected after loop */
316
types.push_back(new Item_type_holder(session_arg, item_tmp));
313
types.push_back(new Item_type_holder(thd_arg, item_tmp));
319
if (session_arg->is_fatal_error)
316
if (thd_arg->is_fatal_error)
320
317
goto err; // out of memory
327
324
ER(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT),MYF(0));
330
List<Item>::iterator it(sl->item_list.begin());
331
List<Item>::iterator tp(types.begin());
327
List_iterator_fast<Item> it(sl->item_list);
328
List_iterator_fast<Item> tp(types);
332
329
Item *type, *item_tmp;
333
330
while ((type= tp++, item_tmp= it++))
335
if (((Item_type_holder*)type)->join_types(session_arg, item_tmp))
332
if (((Item_type_holder*)type)->join_types(thd_arg, item_tmp))
361
create_options= (first_sl->options | session_arg->options |
358
create_options= (first_sl->options | thd_arg->options |
362
359
TMP_TABLE_ALL_COLUMNS);
364
if (union_result->create_result_table(session, &types, test(union_distinct),
361
if (union_result->create_result_table(thd, &types, test(union_distinct),
362
create_options, "", false))
367
memset(&result_table_list, 0, sizeof(result_table_list));
368
result_table_list.setSchemaName((char*) "");
369
result_table_list.alias= "union";
370
result_table_list.setTableName((char *) "union");
364
memset((char*) &result_table_list, 0, sizeof(result_table_list));
365
result_table_list.db= (char*) "";
366
result_table_list.table_name= result_table_list.alias= (char*) "union";
371
367
result_table_list.table= table= union_result->table;
373
session_arg->getLex()->current_select= lex_select_save;
369
thd_arg->lex->current_select= lex_select_save;
374
370
if (!item_list.elements)
376
372
saved_error= table->fill_item_list(&item_list);
378
assert(thd->stmt_arena->is_conventional() == false);
383
380
We're in execution of a prepared statement or stored procedure:
384
381
reset field items to point at fields from the created temporary table.
383
table->reset_item_list(&item_list);
390
session_arg->getLex()->current_select= lex_select_save;
387
thd_arg->lex->current_select= lex_select_save;
392
return(saved_error || session_arg->is_fatal_error);
389
return(saved_error || thd_arg->is_fatal_error);
395
session_arg->getLex()->current_select= lex_select_save;
392
thd_arg->lex->current_select= lex_select_save;
400
bool Select_Lex_Unit::exec()
397
bool st_select_lex_unit::exec()
402
Select_Lex *lex_select_save= session->getLex()->current_select;
403
Select_Lex *select_cursor=first_select();
399
SELECT_LEX *lex_select_save= thd->lex->current_select;
400
SELECT_LEX *select_cursor=first_select();
404
401
uint64_t add_rows=0;
405
402
ha_rows examined_rows= 0;
407
if (executed && uncacheable.none() && ! describe)
404
if (executed && !uncacheable && !describe)
411
if (uncacheable.any() || ! item || ! item->assigned() || describe)
408
if (uncacheable || !item || !item->assigned() || describe)
414
411
item->reset_value_registration();
419
416
item->assigned(0); // We will reinit & rexecute unit
421
table->cursor->ha_delete_all_rows();
418
table->file->ha_delete_all_rows();
423
420
/* re-enabling indexes for next subselect iteration */
424
if (union_distinct && table->cursor->ha_enable_indexes(HA_KEY_SWITCH_ALL))
421
if (union_distinct && table->file->ha_enable_indexes(HA_KEY_SWITCH_ALL))
429
for (Select_Lex *sl= select_cursor; sl; sl= sl->next_select())
426
for (SELECT_LEX *sl= select_cursor; sl; sl= sl->next_select())
431
428
ha_rows records_at_start= 0;
432
session->getLex()->current_select= sl;
429
thd->lex->current_select= sl;
435
432
saved_error= sl->join->reinit();
452
449
we don't calculate found_rows() per union part.
453
450
Otherwise, SQL_CALC_FOUND_ROWS should be done on all sub parts.
455
sl->join->select_options=
452
sl->join->select_options=
456
453
(select_limit_cnt == HA_POS_ERROR || sl->braces) ?
457
454
sl->options & ~OPTION_FOUND_ROWS : sl->options | found_rows_for_union;
456
/* dump_TABLE_LIST_struct(select_lex, select_lex->leaf_tables); */
457
if (sl->join->flatten_subqueries())
460
/* dump_TABLE_LIST_struct(select_lex, select_lex->leaf_tables); */
459
461
saved_error= sl->join->optimize();
461
463
if (!saved_error)
463
records_at_start= table->cursor->stats.records;
465
records_at_start= table->file->stats.records;
464
466
sl->join->exec();
465
467
if (sl == union_distinct)
467
if (table->cursor->ha_disable_indexes(HA_KEY_SWITCH_ALL))
469
if (table->file->ha_disable_indexes(HA_KEY_SWITCH_ALL))
469
471
table->no_keyread=1;
475
477
if (!saved_error)
477
examined_rows+= session->examined_row_count;
479
examined_rows+= thd->examined_row_count;
478
480
if (union_result->flush())
480
session->getLex()->current_select= lex_select_save;
482
thd->lex->current_select= lex_select_save;
487
session->getLex()->current_select= lex_select_save;
489
thd->lex->current_select= lex_select_save;
488
490
return(saved_error);
490
492
/* Needed for the following test and for records_at_start in next loop */
491
int error= table->cursor->info(HA_STATUS_VARIABLE);
493
int error= table->file->info(HA_STATUS_VARIABLE);
494
table->print_error(error, MYF(0));
496
table->file->print_error(error, MYF(0));
497
if (found_rows_for_union && !sl->braces &&
499
if (found_rows_for_union && !sl->braces &&
498
500
select_limit_cnt != HA_POS_ERROR)
503
505
We get this from the difference of between total number of possible
504
506
rows and actual rows added to the temporary table.
506
add_rows+= (uint64_t) (session->limit_found_rows - (uint64_t)
507
((table->cursor->stats.records - records_at_start)));
508
add_rows+= (uint64_t) (thd->limit_found_rows - (uint64_t)
509
((table->file->stats.records - records_at_start)));
513
515
/* Send result to 'result' */
514
516
saved_error= true;
516
if (!session->is_fatal_error) // Check if EOM
518
if (!thd->is_fatal_error) // Check if EOM
518
520
set_limit(global_parameters);
519
init_prepare_fake_select_lex(session);
520
Join *join= fake_select_lex->join;
521
init_prepare_fake_select_lex(thd);
522
JOIN *join= fake_select_lex->join;
524
526
allocate JOIN for fake select only once (prevent
525
select_query automatic allocation)
526
TODO: The above is nonsense. select_query() will not allocate the
527
mysql_select automatic allocation)
528
TODO: The above is nonsense. mysql_select() will not allocate the
527
529
join if one already exists. There must be some other reason why we
528
530
don't let it allocate the join. Perhaps this is because we need
529
531
some special parameter values passed to join constructor?
531
if (!(fake_select_lex->join= new Join(session, item_list,
533
if (!(fake_select_lex->join= new JOIN(thd, item_list,
532
534
fake_select_lex->options, result)))
534
fake_select_lex->table_list.clear();
536
fake_select_lex->table_list.empty();
537
539
fake_select_lex->join->no_const_tables= true;
540
Fake Select_Lex should have item list for correctref_array
542
Fake st_select_lex should have item list for correctref_array
543
545
fake_select_lex->item_list= item_list;
544
saved_error= select_query(session, &fake_select_lex->ref_pointer_array,
546
saved_error= mysql_select(thd, &fake_select_lex->ref_pointer_array,
545
547
&result_table_list,
546
548
0, item_list, NULL,
547
549
global_parameters->order_list.elements,
548
(Order*)global_parameters->order_list.first,
550
(ORDER*)global_parameters->order_list.first,
551
(ORDER*) NULL, NULL, (ORDER*) NULL,
550
552
fake_select_lex->options | SELECT_NO_UNLOCK,
551
553
result, this, fake_select_lex);
560
562
- 1st time is a real evaluation to get the subquery value
561
563
- 2nd time is to produce EXPLAIN output rows.
562
564
1st execution sets certain members (e.g. select_result) to perform
563
subquery execution rather than EXPLAIN line production. In order
565
subquery execution rather than EXPLAIN line production. In order
564
566
to reset them back, we re-do all of the actions (yes it is ugly):
566
join->reset(session, item_list, fake_select_lex->options, result);
567
saved_error= select_query(session, &fake_select_lex->ref_pointer_array,
568
join->init(thd, item_list, fake_select_lex->options, result);
569
saved_error= mysql_select(thd, &fake_select_lex->ref_pointer_array,
568
570
&result_table_list,
569
571
0, item_list, NULL,
570
572
global_parameters->order_list.elements,
571
(Order*)global_parameters->order_list.first,
573
(ORDER*)global_parameters->order_list.first,
574
(ORDER*) NULL, NULL, (ORDER*) NULL,
573
575
fake_select_lex->options | SELECT_NO_UNLOCK,
574
576
result, this, fake_select_lex);
584
fake_select_lex->table_list.clear();
586
fake_select_lex->table_list.empty();
585
587
if (!saved_error)
587
session->limit_found_rows = (uint64_t)table->cursor->stats.records + add_rows;
588
session->examined_row_count+= examined_rows;
589
thd->limit_found_rows = (uint64_t)table->file->stats.records + add_rows;
590
thd->examined_row_count+= examined_rows;
591
593
Mark for slow query log if any of the union parts didn't use
611
613
if (union_result)
613
safe_delete(union_result);
616
union_result=0; // Safety
618
free_tmp_table(thd, table);
614
619
table= 0; // Safety
617
for (Select_Lex *sl= first_select(); sl; sl= sl->next_select())
622
for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
618
623
error|= sl->cleanup();
620
625
if (fake_select_lex)
623
628
if ((join= fake_select_lex->join))
625
630
join->tables_list= 0;
660
bool Select_Lex_Unit::change_result(select_result_interceptor *new_result,
665
bool st_select_lex_unit::change_result(select_result_interceptor *new_result,
661
666
select_result_interceptor *old_result)
664
for (Select_Lex *sl= first_select(); sl; sl= sl->next_select())
669
for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
666
671
if (sl->join && sl->join->result == old_result)
667
672
if (sl->join->change_result(new_result))
676
681
Get column type information for this unit.
679
Select_Lex_Unit::get_unit_column_types()
684
st_select_lex_unit::get_unit_column_types()
682
687
For a single-select the column types are taken
683
688
from the list of selected items. For a union this function
684
assumes that Select_Lex_Unit::prepare has been called
689
assumes that st_select_lex_unit::prepare has been called
685
690
and returns the type holders that were created for unioned
686
691
column types of all selects.
689
694
The implementation of this function should be in sync with
690
Select_Lex_Unit::prepare()
695
st_select_lex_unit::prepare()
693
List<Item> *Select_Lex_Unit::get_unit_column_types()
698
List<Item> *st_select_lex_unit::get_unit_column_types()
695
Select_Lex *sl= first_select();
700
SELECT_LEX *sl= first_select();
704
709
return &sl->item_list;
707
bool Select_Lex::cleanup()
712
bool st_select_lex::cleanup()
709
714
bool error= false;
713
assert((Select_Lex*)join->select_lex == this);
718
assert((st_select_lex*)join->select_lex == this);
714
719
error= join->destroy();
717
for (Select_Lex_Unit *lex_unit= first_inner_unit(); lex_unit ;
723
for (SELECT_LEX_UNIT *lex_unit= first_inner_unit(); lex_unit ;
718
724
lex_unit= lex_unit->next_unit())
720
error= (bool) ((uint32_t) error | (uint32_t) lex_unit->cleanup());
726
error= (bool) ((uint) error | (uint) lex_unit->cleanup());
722
non_agg_fields.clear();
723
inner_refs_list.clear();
728
non_agg_fields.empty();
729
inner_refs_list.empty();
728
void Select_Lex::cleanup_all_joins(bool full)
734
void st_select_lex::cleanup_all_joins(bool full)
730
Select_Lex_Unit *unit;
736
SELECT_LEX_UNIT *unit;
734
740
join->cleanup(full);