20
20
#include <drizzled/server_includes.h>
21
21
#include <drizzled/sql_select.h>
22
#include <drizzled/error.h>
22
#include <drizzled/drizzled_error_messages.h>
24
bool mysql_union(Session *session, LEX *, select_result *result,
24
bool mysql_union(THD *thd,
25
LEX *lex __attribute__((unused)),
26
select_result *result,
25
27
SELECT_LEX_UNIT *unit, ulong setup_tables_done_option)
28
if (!(res= unit->prepare(session, result, SELECT_NO_UNLOCK |
30
if (!(res= unit->prepare(thd, result, SELECT_NO_UNLOCK |
29
31
setup_tables_done_option)))
38
40
** store records in temporary table for UNION
39
41
***************************************************************************/
41
int select_union::prepare(List<Item> &, SELECT_LEX_UNIT *u)
43
int select_union::prepare(List<Item> &list __attribute__((unused)),
53
56
unit->offset_limit_cnt--;
56
fill_record(session, table->field, values, 1);
57
if (session->is_error())
59
fill_record(thd, table->field, values, 1);
60
63
if ((error= table->file->ha_write_row(table->record[0])))
62
65
/* create_myisam_from_heap will generate error if needed */
63
66
if (table->file->is_fatal_error(error, HA_CHECK_DUP) &&
64
create_myisam_from_heap(session, table, tmp_table_param.start_recinfo,
67
create_myisam_from_heap(thd, table, tmp_table_param.start_recinfo,
65
68
&tmp_table_param.recinfo, error, 1))
113
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,
114
117
bool is_union_distinct, uint64_t options,
115
118
const char *table_alias,
116
119
bool bit_fields_as_long)
120
123
tmp_table_param.field_count= column_types->elements;
121
124
tmp_table_param.bit_fields_as_long= bit_fields_as_long;
123
if (! (table= create_tmp_table(session_arg, &tmp_table_param, *column_types,
126
if (! (table= create_tmp_table(thd_arg, &tmp_table_param, *column_types,
124
127
(order_st*) 0, is_union_distinct, 1,
125
128
options, HA_POS_ERROR, (char*) table_alias)))
153
156
st_select_lex_unit::init_prepare_fake_select_lex()
154
session - thread handler
157
160
options of SELECT
161
st_select_lex_unit::init_prepare_fake_select_lex(Session *session_arg)
164
st_select_lex_unit::init_prepare_fake_select_lex(THD *thd_arg)
163
session_arg->lex->current_select= fake_select_lex;
164
fake_select_lex->table_list.link_in_list((unsigned char *)&result_table_list,
166
thd_arg->lex->current_select= fake_select_lex;
167
fake_select_lex->table_list.link_in_list((uchar *)&result_table_list,
166
169
&result_table_list.next_local);
167
170
fake_select_lex->context.table_list=
168
171
fake_select_lex->context.first_name_resolution_table=
169
172
fake_select_lex->get_table_list();
171
for (order_st *order= (order_st *) global_parameters->order_list.first;
174
order->item= &order->item_ptr;
173
if (!fake_select_lex->first_execution)
175
for (order_st *order= (order_st *) global_parameters->order_list.first;
178
order->item= &order->item_ptr;
176
180
for (order_st *order= (order_st *)global_parameters->order_list.first;
178
182
order=order->next)
180
184
(*order->item)->walk(&Item::change_context_processor, 0,
181
(unsigned char*) &fake_select_lex->context);
185
(uchar*) &fake_select_lex->context);
186
bool st_select_lex_unit::prepare(Session *session_arg, select_result *sel_result,
190
bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
187
191
uint32_t additional_options)
189
SELECT_LEX *lex_select_save= session_arg->lex->current_select;
193
SELECT_LEX *lex_select_save= thd_arg->lex->current_select;
190
194
SELECT_LEX *sl, *first_sl= first_select();
191
195
select_result *tmp_result;
192
196
bool is_union_select;
246
250
bool can_skip_order_by;
247
251
sl->options|= SELECT_NO_UNLOCK;
248
JOIN *join= new JOIN(session_arg, sl->item_list,
249
sl->options | session_arg->options | additional_options,
252
JOIN *join= new JOIN(thd_arg, sl->item_list,
253
sl->options | thd_arg->options | additional_options,
252
256
setup_tables_done_option should be set only for very first SELECT,
274
278
(order_st*) sl->group_list.first,
276
280
(is_union_select ? (order_st*) 0 :
277
(order_st*) session_arg->lex->proc_list.first),
281
(order_st*) thd_arg->lex->proc_list.first),
279
283
/* There are no * in the statement anymore (for PS) */
280
284
sl->with_wild= 0;
282
if (saved_error || (saved_error= session_arg->is_fatal_error))
286
if (saved_error || (saved_error= thd_arg->is_fatal_error))
285
289
Use items list of underlaid select for derived tables to preserve
296
300
field object without table.
298
302
assert(!empty_table);
299
empty_table= (Table*) session->calloc(sizeof(Table));
303
empty_table= (Table*) thd->calloc(sizeof(Table));
301
305
List_iterator_fast<Item> it(sl->item_list);
303
307
while ((item_tmp= it++))
305
309
/* Error's in 'new' will be detected after loop */
306
types.push_back(new Item_type_holder(session_arg, item_tmp));
310
types.push_back(new Item_type_holder(thd_arg, item_tmp));
309
if (session_arg->is_fatal_error)
313
if (thd_arg->is_fatal_error)
310
314
goto err; // out of memory
322
326
Item *type, *item_tmp;
323
327
while ((type= tp++, item_tmp= it++))
325
if (((Item_type_holder*)type)->join_types(session_arg, item_tmp))
329
if (((Item_type_holder*)type)->join_types(thd_arg, item_tmp))
351
create_options= (first_sl->options | session_arg->options |
355
create_options= (first_sl->options | thd_arg->options |
352
356
TMP_TABLE_ALL_COLUMNS);
354
if (union_result->create_result_table(session, &types, test(union_distinct),
358
if (union_result->create_result_table(thd, &types, test(union_distinct),
355
359
create_options, "", false))
357
361
memset(&result_table_list, 0, sizeof(result_table_list));
359
363
result_table_list.table_name= result_table_list.alias= (char*) "union";
360
364
result_table_list.table= table= union_result->table;
362
session_arg->lex->current_select= lex_select_save;
366
thd_arg->lex->current_select= lex_select_save;
363
367
if (!item_list.elements)
365
369
saved_error= table->fill_item_list(&item_list);
375
assert(thd->stmt_arena->is_conventional() == false);
372
377
We're in execution of a prepared statement or stored procedure:
373
378
reset field items to point at fields from the created temporary table.
380
table->reset_item_list(&item_list);
379
session_arg->lex->current_select= lex_select_save;
384
thd_arg->lex->current_select= lex_select_save;
381
return(saved_error || session_arg->is_fatal_error);
386
return(saved_error || thd_arg->is_fatal_error);
384
session_arg->lex->current_select= lex_select_save;
389
thd_arg->lex->current_select= lex_select_save;
389
394
bool st_select_lex_unit::exec()
391
SELECT_LEX *lex_select_save= session->lex->current_select;
396
SELECT_LEX *lex_select_save= thd->lex->current_select;
392
397
SELECT_LEX *select_cursor=first_select();
393
398
uint64_t add_rows=0;
394
399
ha_rows examined_rows= 0;
418
423
for (SELECT_LEX *sl= select_cursor; sl; sl= sl->next_select())
420
425
ha_rows records_at_start= 0;
421
session->lex->current_select= sl;
426
thd->lex->current_select= sl;
424
429
saved_error= sl->join->reinit();
469
474
if (!saved_error)
471
examined_rows+= session->examined_row_count;
476
examined_rows+= thd->examined_row_count;
472
477
if (union_result->flush())
474
session->lex->current_select= lex_select_save;
479
thd->lex->current_select= lex_select_save;
481
session->lex->current_select= lex_select_save;
486
thd->lex->current_select= lex_select_save;
482
487
return(saved_error);
484
489
/* Needed for the following test and for records_at_start in next loop */
497
502
We get this from the difference of between total number of possible
498
503
rows and actual rows added to the temporary table.
500
add_rows+= (uint64_t) (session->limit_found_rows - (uint64_t)
505
add_rows+= (uint64_t) (thd->limit_found_rows - (uint64_t)
501
506
((table->file->stats.records - records_at_start)));
507
512
/* Send result to 'result' */
508
513
saved_error= true;
510
if (!session->is_fatal_error) // Check if EOM
515
if (!thd->is_fatal_error) // Check if EOM
512
517
set_limit(global_parameters);
513
init_prepare_fake_select_lex(session);
518
init_prepare_fake_select_lex(thd);
514
519
JOIN *join= fake_select_lex->join;
522
527
don't let it allocate the join. Perhaps this is because we need
523
528
some special parameter values passed to join constructor?
525
if (!(fake_select_lex->join= new JOIN(session, item_list,
530
if (!(fake_select_lex->join= new JOIN(thd, item_list,
526
531
fake_select_lex->options, result)))
528
533
fake_select_lex->table_list.empty();
537
542
fake_select_lex->item_list= item_list;
538
saved_error= mysql_select(session, &fake_select_lex->ref_pointer_array,
543
saved_error= mysql_select(thd, &fake_select_lex->ref_pointer_array,
539
544
&result_table_list,
540
545
0, item_list, NULL,
541
546
global_parameters->order_list.elements,
557
562
subquery execution rather than EXPLAIN line production. In order
558
563
to reset them back, we re-do all of the actions (yes it is ugly):
560
join->init(session, item_list, fake_select_lex->options, result);
561
saved_error= mysql_select(session, &fake_select_lex->ref_pointer_array,
565
join->init(thd, item_list, fake_select_lex->options, result);
566
saved_error= mysql_select(thd, &fake_select_lex->ref_pointer_array,
562
567
&result_table_list,
563
568
0, item_list, NULL,
564
569
global_parameters->order_list.elements,
578
583
fake_select_lex->table_list.empty();
579
584
if (!saved_error)
581
session->limit_found_rows = (uint64_t)table->file->stats.records + add_rows;
582
session->examined_row_count+= examined_rows;
586
thd->limit_found_rows = (uint64_t)table->file->stats.records + add_rows;
587
thd->examined_row_count+= examined_rows;
585
590
Mark for slow query log if any of the union parts didn't use