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>
30 #include <drizzled/item/subselect.h>
34 bool drizzle_union(Session *session, LEX *, select_result *result,
35 Select_Lex_Unit *unit, uint64_t setup_tables_done_option)
37 bool res= unit->prepare(session, result, SELECT_NO_UNLOCK | setup_tables_done_option);
50 int select_union::prepare(List<Item> &, Select_Lex_Unit *u)
57 bool select_union::send_data(List<Item> &values)
60 if (unit->offset_limit_cnt)
62 unit->offset_limit_cnt--;
65 fill_record(session, table->getFields(), values,
true);
66 if (session->is_error())
69 if ((error= table->
cursor->insertRecord(table->getInsertRecord())))
74 my_error(ER_USE_SQL_BIG_RESULT, MYF(0));
82 bool select_union::send_eof()
88 bool select_union::flush()
91 if ((error=table->
cursor->extra(HA_EXTRA_NO_CACHE)))
93 table->print_error(error, MYF(0));
122 select_union::create_result_table(Session *session_arg, List<Item> *column_types,
123 bool is_union_distinct, uint64_t options,
124 const char *table_alias)
126 assert(table == NULL);
127 tmp_table_param.init();
128 tmp_table_param.field_count= column_types->size();
130 if (! (table=
create_tmp_table(session_arg, &tmp_table_param, *column_types,
131 (Order*) NULL, is_union_distinct, 1,
132 options, HA_POS_ERROR, (
char*) table_alias)))
137 table->
cursor->extra(HA_EXTRA_WRITE_CACHE);
138 table->
cursor->extra(HA_EXTRA_IGNORE_DUP_KEY);
153 table->
cursor->extra(HA_EXTRA_RESET_STATE);
155 table->free_io_cache();
156 table->filesort_free_buffers();
172 Select_Lex_Unit::init_prepare_fake_select_lex(
Session *session_arg)
174 session_arg->lex().current_select= fake_select_lex;
175 fake_select_lex->table_list.link_in_list((
unsigned char *)&result_table_list,
177 &result_table_list.next_local);
178 fake_select_lex->context.table_list=
179 fake_select_lex->context.first_name_resolution_table=
180 fake_select_lex->get_table_list();
182 for (
Order *order= (
Order *) global_parameters->order_list.first;
185 order->item= &order->item_ptr;
187 for (
Order *order= (
Order *)global_parameters->order_list.first;
191 (*order->item)->walk(&Item::change_context_processor, 0,
192 (
unsigned char*) &fake_select_lex->context);
197 bool Select_Lex_Unit::prepare(Session *session_arg, select_result *sel_result,
198 uint64_t additional_options)
200 Select_Lex *lex_select_save= session_arg->lex().current_select;
201 Select_Lex *sl, *first_sl= first_select();
202 select_result *tmp_result;
203 bool is_union_select;
204 Table *empty_table= 0;
206 describe= test(additional_options & SELECT_DESCRIBE);
219 for (sl= first_sl; sl; sl= sl->next_select())
221 sl->join->result= result;
222 select_limit_cnt= HA_POS_ERROR;
224 if (result->prepare(sl->join->fields_list,
this))
228 sl->join->select_options|= SELECT_DESCRIBE;
237 session_arg->lex().current_select= sl= first_sl;
238 found_rows_for_union= first_sl->options & OPTION_FOUND_ROWS;
239 is_union_select= is_union() || fake_select_lex;
245 tmp_result= union_result=
new select_union;
247 tmp_result= sel_result;
250 tmp_result= sel_result;
252 sl->context.resolve_in_select_list=
true;
254 for (;sl; sl= sl->next_select())
256 bool can_skip_order_by;
257 sl->options|= SELECT_NO_UNLOCK;
258 Join *join=
new Join(session_arg, sl->item_list,
259 sl->options | session_arg->options | additional_options,
267 additional_options&= ~OPTION_SETUP_TABLES_DONE;
271 session_arg->lex().current_select= sl;
273 can_skip_order_by= is_union_select && !(sl->braces && sl->explicit_limit);
275 saved_error= join->prepare(&sl->ref_pointer_array,
276 (TableList*) sl->table_list.first,
279 (can_skip_order_by ? 0 :
280 sl->order_list.size()) +
281 sl->group_list.size(),
283 (Order*) NULL : (Order *)sl->order_list.first,
284 (Order*) sl->group_list.first,
290 if (saved_error || (saved_error= session_arg->is_fatal_error))
296 if (!is_union_select)
297 types= first_sl->item_list;
298 else if (sl == first_sl)
306 assert(!empty_table);
307 empty_table= (Table*) session->mem.calloc(
sizeof(Table));
309 List<Item>::iterator it(sl->item_list.begin());
310 while (Item* item_tmp= it++)
313 types.push_back(
new Item_type_holder(session_arg, item_tmp));
316 if (session_arg->is_fatal_error)
321 if (types.size() != sl->item_list.size())
323 my_message(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT,
324 ER(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT),MYF(0));
327 List<Item>::iterator it(sl->item_list.begin());
328 List<Item>::iterator tp(types.begin());
329 Item *type, *item_tmp;
330 while ((type= tp++, item_tmp= it++))
332 if (((Item_type_holder*)type)->join_types(session_arg, item_tmp))
344 List<Item>::iterator tp(types.begin());
346 uint64_t create_options;
350 if (type->result_type() == STRING_RESULT &&
351 type->collation.derivation == DERIVATION_NONE)
353 my_error(ER_CANT_AGGREGATE_NCOLLATIONS, MYF(0),
"UNION");
358 create_options= first_sl->options | session_arg->options | TMP_TABLE_ALL_COLUMNS;
360 if (union_result->create_result_table(session, &types, test(union_distinct), create_options,
""))
362 memset(&result_table_list, 0,
sizeof(result_table_list));
363 result_table_list.setSchemaName(
"");
364 result_table_list.alias=
"union";
365 result_table_list.setTableName(
"union");
366 result_table_list.table= table= union_result->table;
368 session_arg->lex().current_select= lex_select_save;
369 if (item_list.is_empty())
370 table->fill_item_list(item_list);
381 session_arg->lex().current_select= lex_select_save;
383 return(saved_error || session_arg->is_fatal_error);
386 session_arg->lex().current_select= lex_select_save;
391 bool Select_Lex_Unit::exec()
393 Select_Lex *lex_select_save= session->lex().current_select;
394 Select_Lex *select_cursor=first_select();
396 ha_rows examined_rows= 0;
398 if (executed && uncacheable.none() && ! describe)
402 if (uncacheable.any() || ! item || ! item->assigned() || describe)
405 item->reset_value_registration();
406 if (optimized && item)
408 if (item->assigned())
412 table->cursor->ha_delete_all_rows();
415 if (union_distinct && table->cursor->ha_enable_indexes(HA_KEY_SWITCH_ALL))
420 for (Select_Lex *sl= select_cursor; sl; sl= sl->next_select())
422 ha_rows records_at_start= 0;
423 session->lex().current_select= sl;
426 saved_error= sl->join->reinit();
430 if (sl == global_parameters || describe)
437 if (sl->order_list.first || describe)
438 select_limit_cnt= HA_POS_ERROR;
446 sl->join->select_options=
447 (select_limit_cnt == HA_POS_ERROR || sl->braces) ?
448 sl->options & ~OPTION_FOUND_ROWS : sl->options | found_rows_for_union;
450 saved_error= sl->join->optimize();
454 records_at_start= table->cursor->stats.records;
456 if (sl == union_distinct)
458 if (table->cursor->ha_disable_indexes(HA_KEY_SWITCH_ALL))
462 saved_error= sl->join->error;
463 offset_limit_cnt= (ha_rows)(sl->offset_limit ?
464 sl->offset_limit->val_uint() :
468 examined_rows+= session->examined_row_count;
469 if (union_result->flush())
471 session->lex().current_select= lex_select_save;
478 session->lex().current_select= lex_select_save;
482 int error= table->cursor->info(HA_STATUS_VARIABLE);
485 table->print_error(error, MYF(0));
488 if (found_rows_for_union && !sl->braces &&
489 select_limit_cnt != HA_POS_ERROR)
497 add_rows+= (uint64_t) (session->limit_found_rows - (uint64_t)
498 ((table->cursor->stats.records - records_at_start)));
507 if (!session->is_fatal_error)
509 set_limit(global_parameters);
510 init_prepare_fake_select_lex(session);
511 Join *join= fake_select_lex->join;
522 fake_select_lex->join=
new Join(session, item_list, fake_select_lex->options, result);
523 fake_select_lex->join->no_const_tables=
true;
529 fake_select_lex->item_list= item_list;
530 saved_error=
select_query(session, &fake_select_lex->ref_pointer_array,
533 global_parameters->order_list.size(),
534 (Order*)global_parameters->order_list.first,
536 fake_select_lex->options | SELECT_NO_UNLOCK,
537 result,
this, fake_select_lex);
552 join->reset(session, item_list, fake_select_lex->options, result);
553 saved_error=
select_query(session, &fake_select_lex->ref_pointer_array,
556 global_parameters->order_list.size(),
557 (Order*)global_parameters->order_list.first,
559 fake_select_lex->options | SELECT_NO_UNLOCK,
560 result,
this, fake_select_lex);
564 join->examined_rows= 0;
565 saved_error= join->reinit();
570 fake_select_lex->table_list.clear();
573 session->limit_found_rows = (uint64_t)table->cursor->stats.records + add_rows;
574 session->examined_row_count+= examined_rows;
582 session->lex().current_select= lex_select_save;
587 bool Select_Lex_Unit::cleanup()
599 safe_delete(union_result);
603 for (Select_Lex *sl= first_select(); sl; sl= sl->next_select())
604 error|= sl->cleanup();
609 if ((join= fake_select_lex->join))
611 join->tables_list= 0;
614 error|= fake_select_lex->cleanup();
615 if (fake_select_lex->order_list.size())
618 for (ord= (Order*)fake_select_lex->order_list.first; ord; ord= ord->next)
619 (*ord->item)->cleanup();
627 void Select_Lex_Unit::reinit_exec_mechanism()
629 prepared= optimized= executed= 0;
646 bool Select_Lex_Unit::change_result(select_result_interceptor *new_result,
647 select_result_interceptor *old_result)
650 for (Select_Lex *sl= first_select(); sl; sl= sl->next_select())
652 if (sl->join && sl->join->result == old_result)
653 if (sl->join->change_result(new_result))
656 if (fake_select_lex && fake_select_lex->join)
657 res= fake_select_lex->join->change_result(new_result);
679 List<Item> *Select_Lex_Unit::get_unit_column_types()
681 Select_Lex *sl= first_select();
690 return &sl->item_list;
693 bool Select_Lex::cleanup()
699 assert((Select_Lex*)join->select_lex ==
this);
700 error= join->destroy();
703 for (Select_Lex_Unit *lex_unit= first_inner_unit(); lex_unit ;
704 lex_unit= lex_unit->next_unit())
706 error= (bool) ((uint32_t) error | (uint32_t) lex_unit->cleanup());
708 non_agg_fields.clear();
709 inner_refs_list.clear();
714 void Select_Lex::cleanup_all_joins(
bool full)
716 Select_Lex_Unit *unit;
722 for (unit= first_inner_unit(); unit; unit= unit->next_unit())
723 for (sl= unit->first_select(); sl; sl= sl->next_select())
724 sl->cleanup_all_joins(full);
Table * create_tmp_table(Session *session, Tmp_Table_Param *param, List< Item > &fields, Order *group, bool distinct, bool save_sum_fields, uint64_t select_options, ha_rows rows_limit, const char *alias)
bool select_query(Session *session, Item ***rref_pointer_array, TableList *tables, uint32_t wild_num, List< Item > &fields, COND *conds, uint32_t og_num, Order *order, Order *group, Item *having, uint64_t select_options, select_result *result, Select_Lex_Unit *unit, Select_Lex *select_lex)
virtual bool is_fatal_error(int error, uint32_t flags)