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