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/drizzled_error_messages.h>
24
bool mysql_union(THD *thd,
25
LEX *lex __attribute__((unused)),
26
select_result *result,
23
#include "mysql_priv.h"
24
#include "sql_select.h"
26
bool mysql_union(THD *thd, LEX *lex, select_result *result,
27
27
SELECT_LEX_UNIT *unit, ulong setup_tables_done_option)
29
DBUG_ENTER("mysql_union");
30
31
if (!(res= unit->prepare(thd, result, SELECT_NO_UNLOCK |
31
32
setup_tables_done_option)))
34
35
res|= unit->cleanup();
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> &list, SELECT_LEX_UNIT *u)
101
101
duplicates on insert
102
102
options create options
103
103
table_alias name of the temporary table
104
bit_fields_as_long convert bit fields to uint64_t
104
bit_fields_as_long convert bit fields to ulonglong
107
107
Create a temporary table that is used to store the result of a UNION,
116
116
select_union::create_result_table(THD *thd_arg, List<Item> *column_types,
117
bool is_union_distinct, uint64_t options,
117
bool is_union_distinct, ulonglong options,
118
118
const char *table_alias,
119
119
bool bit_fields_as_long)
121
DBUG_ASSERT(table == 0);
122
122
tmp_table_param.init();
123
123
tmp_table_param.field_count= column_types->elements;
124
124
tmp_table_param.bit_fields_as_long= bit_fields_as_long;
126
126
if (! (table= create_tmp_table(thd_arg, &tmp_table_param, *column_types,
127
(order_st*) 0, is_union_distinct, 1,
127
(ORDER*) 0, is_union_distinct, 1,
128
128
options, HA_POS_ERROR, (char*) table_alias)))
130
130
table->file->extra(HA_EXTRA_WRITE_CACHE);
131
131
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
164
164
st_select_lex_unit::init_prepare_fake_select_lex(THD *thd_arg)
166
166
thd_arg->lex->current_select= fake_select_lex;
167
fake_select_lex->table_list.link_in_list((unsigned char *)&result_table_list,
167
fake_select_lex->table_list.link_in_list((uchar *)&result_table_list,
169
169
&result_table_list.next_local);
170
170
fake_select_lex->context.table_list=
171
171
fake_select_lex->context.first_name_resolution_table=
172
172
fake_select_lex->get_table_list();
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;
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;
181
182
order=order->next)
183
184
(*order->item)->walk(&Item::change_context_processor, 0,
184
(unsigned char*) &fake_select_lex->context);
185
(uchar*) &fake_select_lex->context);
189
190
bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
190
uint32_t additional_options)
191
ulong additional_options)
192
193
SELECT_LEX *lex_select_save= thd_arg->lex->current_select;
193
194
SELECT_LEX *sl, *first_sl= first_select();
194
195
select_result *tmp_result;
195
196
bool is_union_select;
196
Table *empty_table= 0;
197
TABLE *empty_table= 0;
198
DBUG_ENTER("st_select_lex_unit::prepare");
198
200
describe= test(additional_options & SELECT_DESCRIBE);
215
217
offset_limit_cnt= 0;
216
218
if (result->prepare(sl->join->fields_list, this))
220
222
sl->join->select_options|= SELECT_DESCRIBE;
221
223
sl->join->reinit();
229
231
thd_arg->lex->current_select= sl= first_sl;
230
232
found_rows_for_union= first_sl->options & OPTION_FOUND_ROWS;
266
268
can_skip_order_by= is_union_select && !(sl->braces && sl->explicit_limit);
268
270
saved_error= join->prepare(&sl->ref_pointer_array,
269
(TableList*) sl->table_list.first,
271
(TABLE_LIST*) sl->table_list.first,
272
274
(can_skip_order_by ? 0 :
273
275
sl->order_list.elements) +
274
276
sl->group_list.elements,
275
277
can_skip_order_by ?
276
(order_st*) 0 : (order_st *)sl->order_list.first,
277
(order_st*) sl->group_list.first,
278
(ORDER*) 0 : (ORDER *)sl->order_list.first,
279
(ORDER*) sl->group_list.first,
279
(is_union_select ? (order_st*) 0 :
280
(order_st*) thd_arg->lex->proc_list.first),
281
(is_union_select ? (ORDER*) 0 :
282
(ORDER*) thd_arg->lex->proc_list.first),
282
284
/* There are no * in the statement anymore (for PS) */
283
285
sl->with_wild= 0;
298
300
The main reason of this is that we can't create
299
301
field object without table.
301
assert(!empty_table);
302
empty_table= (Table*) thd->calloc(sizeof(Table));
303
DBUG_ASSERT(!empty_table);
304
empty_table= (TABLE*) thd->calloc(sizeof(TABLE));
304
306
List_iterator_fast<Item> it(sl->item_list);
355
357
TMP_TABLE_ALL_COLUMNS);
357
359
if (union_result->create_result_table(thd, &types, test(union_distinct),
358
create_options, "", false))
360
create_options, "", FALSE))
360
memset(&result_table_list, 0, sizeof(result_table_list));
362
bzero((char*) &result_table_list, sizeof(result_table_list));
361
363
result_table_list.db= (char*) "";
362
364
result_table_list.table_name= result_table_list.alias= (char*) "union";
363
365
result_table_list.table= table= union_result->table;
376
DBUG_ASSERT(thd->stmt_arena->is_conventional() == false);
375
378
We're in execution of a prepared statement or stored procedure:
376
379
reset field items to point at fields from the created temporary table.
381
table->reset_item_list(&item_list);
382
385
thd_arg->lex->current_select= lex_select_save;
384
return(saved_error || thd_arg->is_fatal_error);
387
DBUG_RETURN(saved_error || thd_arg->is_fatal_error);
387
390
thd_arg->lex->current_select= lex_select_save;
394
397
SELECT_LEX *lex_select_save= thd->lex->current_select;
395
398
SELECT_LEX *select_cursor=first_select();
399
ulonglong add_rows=0;
397
400
ha_rows examined_rows= 0;
401
DBUG_ENTER("st_select_lex_unit::exec");
399
403
if (executed && !uncacheable && !describe)
403
407
if (uncacheable || !item || !item->assigned() || describe)
448
452
(select_limit_cnt == HA_POS_ERROR || sl->braces) ?
449
453
sl->options & ~OPTION_FOUND_ROWS : sl->options | found_rows_for_union;
451
/* dump_TableList_struct(select_lex, select_lex->leaf_tables); */
455
/* dump_TABLE_LIST_struct(select_lex, select_lex->leaf_tables); */
452
456
if (sl->join->flatten_subqueries())
455
/* dump_TableList_struct(select_lex, select_lex->leaf_tables); */
459
/* dump_TABLE_LIST_struct(select_lex, select_lex->leaf_tables); */
456
460
saved_error= sl->join->optimize();
458
462
if (!saved_error)
475
479
if (union_result->flush())
477
481
thd->lex->current_select= lex_select_save;
484
488
thd->lex->current_select= lex_select_save;
489
DBUG_RETURN(saved_error);
487
491
/* Needed for the following test and for records_at_start in next loop */
488
492
int error= table->file->info(HA_STATUS_VARIABLE);
491
495
table->file->print_error(error, MYF(0));
494
498
if (found_rows_for_union && !sl->braces &&
495
499
select_limit_cnt != HA_POS_ERROR)
500
504
We get this from the difference of between total number of possible
501
505
rows and actual rows added to the temporary table.
503
add_rows+= (uint64_t) (thd->limit_found_rows - (uint64_t)
507
add_rows+= (ulonglong) (thd->limit_found_rows - (ulonglong)
504
508
((table->file->stats.records - records_at_start)));
529
533
fake_select_lex->options, result)))
531
535
fake_select_lex->table_list.empty();
534
fake_select_lex->join->no_const_tables= true;
538
fake_select_lex->join->no_const_tables= TRUE;
537
541
Fake st_select_lex should have item list for correctref_array
542
546
&result_table_list,
543
547
0, item_list, NULL,
544
548
global_parameters->order_list.elements,
545
(order_st*)global_parameters->order_list.first,
546
(order_st*) NULL, NULL, (order_st*) NULL,
549
(ORDER*)global_parameters->order_list.first,
550
(ORDER*) NULL, NULL, (ORDER*) NULL,
547
551
fake_select_lex->options | SELECT_NO_UNLOCK,
548
552
result, this, fake_select_lex);
565
569
&result_table_list,
566
570
0, item_list, NULL,
567
571
global_parameters->order_list.elements,
568
(order_st*)global_parameters->order_list.first,
569
(order_st*) NULL, NULL, (order_st*) NULL,
572
(ORDER*)global_parameters->order_list.first,
573
(ORDER*) NULL, NULL, (ORDER*) NULL,
570
574
fake_select_lex->options | SELECT_NO_UNLOCK,
571
575
result, this, fake_select_lex);
581
585
fake_select_lex->table_list.empty();
582
586
if (!saved_error)
584
thd->limit_found_rows = (uint64_t)table->file->stats.records + add_rows;
588
thd->limit_found_rows = (ulonglong)table->file->stats.records + add_rows;
585
589
thd->examined_row_count+= examined_rows;
628
633
error|= fake_select_lex->cleanup();
629
634
if (fake_select_lex->order_list.elements)
632
for (ord= (order_st*)fake_select_lex->order_list.first; ord; ord= ord->next)
637
for (ord= (ORDER*)fake_select_lex->order_list.first; ord; ord= ord->next)
633
638
(*ord->item)->cleanup();
641
646
void st_select_lex_unit::reinit_exec_mechanism()
643
648
prepared= optimized= executed= 0;
652
List_iterator_fast<Item> it(item_list);
654
while ((field= it++))
657
we can't cleanup here, because it broke link to temporary table field,
658
but have to drop fixed flag to allow next fix_field of this field
653
674
old_result old select_result object
660
681
bool st_select_lex_unit::change_result(select_result_interceptor *new_result,
661
682
select_result_interceptor *old_result)
664
685
for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
666
687
if (sl->join && sl->join->result == old_result)
667
688
if (sl->join->change_result(new_result))
670
691
if (fake_select_lex && fake_select_lex->join)
671
692
res= fake_select_lex->join->change_result(new_result);