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)
298 types= first_sl->item_list;
300 else if (sl == first_sl)
309 assert(!empty_table);
310 empty_table= (Table*) session->mem.calloc(
sizeof(Table));
312 List<Item>::iterator it(sl->item_list.begin());
313 while (Item* item_tmp= it++)
316 types.push_back(
new Item_type_holder(session_arg, item_tmp));
319 if (session_arg->is_fatal_error)
324 if (types.size() != sl->item_list.size())
326 my_message(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT,
327 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());
332 Item *type, *item_tmp;
333 while ((type= tp++, item_tmp= it++))
335 if (((Item_type_holder*)type)->join_types(session_arg, item_tmp))
347 List<Item>::iterator tp(types.begin());
349 uint64_t create_options;
353 if (type->result_type() == STRING_RESULT &&
354 type->collation.derivation == DERIVATION_NONE)
356 my_error(ER_CANT_AGGREGATE_NCOLLATIONS, MYF(0),
"UNION");
361 create_options= first_sl->options | session_arg->options | TMP_TABLE_ALL_COLUMNS;
363 if (union_result->create_result_table(session, &types, test(union_distinct), create_options,
""))
365 memset(&result_table_list, 0,
sizeof(result_table_list));
366 result_table_list.setSchemaName(
"");
367 result_table_list.alias=
"union";
368 result_table_list.setTableName(
"union");
369 result_table_list.table= table= union_result->table;
371 session_arg->lex().current_select= lex_select_save;
372 if (item_list.is_empty())
373 table->fill_item_list(item_list);
384 session_arg->lex().current_select= lex_select_save;
386 return(saved_error || session_arg->is_fatal_error);
389 session_arg->lex().current_select= lex_select_save;
394 bool Select_Lex_Unit::exec()
396 Select_Lex *lex_select_save= session->lex().current_select;
397 Select_Lex *select_cursor=first_select();
399 ha_rows examined_rows= 0;
401 if (executed && uncacheable.none() && ! describe)
405 if (uncacheable.any() || ! item || ! item->assigned() || describe)
408 item->reset_value_registration();
409 if (optimized && item)
411 if (item->assigned())
415 table->cursor->ha_delete_all_rows();
418 if (union_distinct && table->cursor->ha_enable_indexes(HA_KEY_SWITCH_ALL))
423 for (Select_Lex *sl= select_cursor; sl; sl= sl->next_select())
425 ha_rows records_at_start= 0;
426 session->lex().current_select= sl;
429 saved_error= sl->join->reinit();
433 if (sl == global_parameters || describe)
440 if (sl->order_list.first || describe)
441 select_limit_cnt= HA_POS_ERROR;
449 sl->join->select_options=
450 (select_limit_cnt == HA_POS_ERROR || sl->braces) ?
451 sl->options & ~OPTION_FOUND_ROWS : sl->options | found_rows_for_union;
453 saved_error= sl->join->optimize();
457 records_at_start= table->cursor->stats.records;
459 if (sl == union_distinct)
461 if (table->cursor->ha_disable_indexes(HA_KEY_SWITCH_ALL))
465 saved_error= sl->join->error;
466 offset_limit_cnt= (ha_rows)(sl->offset_limit ?
467 sl->offset_limit->val_uint() :
471 examined_rows+= session->examined_row_count;
472 if (union_result->flush())
474 session->lex().current_select= lex_select_save;
481 session->lex().current_select= lex_select_save;
485 int error= table->cursor->info(HA_STATUS_VARIABLE);
488 table->print_error(error, MYF(0));
491 if (found_rows_for_union && !sl->braces &&
492 select_limit_cnt != HA_POS_ERROR)
500 add_rows+= (uint64_t) (session->limit_found_rows - (uint64_t)
501 ((table->cursor->stats.records - records_at_start)));
510 if (!session->is_fatal_error)
512 set_limit(global_parameters);
513 init_prepare_fake_select_lex(session);
514 Join *join= fake_select_lex->join;
525 fake_select_lex->join=
new Join(session, item_list, fake_select_lex->options, result);
526 fake_select_lex->join->no_const_tables=
true;
532 fake_select_lex->item_list= item_list;
533 saved_error=
select_query(session, &fake_select_lex->ref_pointer_array,
536 global_parameters->order_list.size(),
537 (Order*)global_parameters->order_list.first,
539 fake_select_lex->options | SELECT_NO_UNLOCK,
540 result,
this, fake_select_lex);
555 join->reset(session, item_list, fake_select_lex->options, result);
556 saved_error=
select_query(session, &fake_select_lex->ref_pointer_array,
559 global_parameters->order_list.size(),
560 (Order*)global_parameters->order_list.first,
562 fake_select_lex->options | SELECT_NO_UNLOCK,
563 result,
this, fake_select_lex);
567 join->examined_rows= 0;
568 saved_error= join->reinit();
573 fake_select_lex->table_list.clear();
576 session->limit_found_rows = (uint64_t)table->cursor->stats.records + add_rows;
577 session->examined_row_count+= examined_rows;
585 session->lex().current_select= lex_select_save;
590 bool Select_Lex_Unit::cleanup()
602 safe_delete(union_result);
606 for (Select_Lex *sl= first_select(); sl; sl= sl->next_select())
607 error|= sl->cleanup();
612 if ((join= fake_select_lex->join))
614 join->tables_list= 0;
617 error|= fake_select_lex->cleanup();
618 if (fake_select_lex->order_list.size())
621 for (ord= (Order*)fake_select_lex->order_list.first; ord; ord= ord->next)
622 (*ord->item)->cleanup();
630 void Select_Lex_Unit::reinit_exec_mechanism()
632 prepared= optimized= executed= 0;
649 bool Select_Lex_Unit::change_result(select_result_interceptor *new_result,
650 select_result_interceptor *old_result)
653 for (Select_Lex *sl= first_select(); sl; sl= sl->next_select())
655 if (sl->join && sl->join->result == old_result)
656 if (sl->join->change_result(new_result))
659 if (fake_select_lex && fake_select_lex->join)
660 res= fake_select_lex->join->change_result(new_result);
682 List<Item> *Select_Lex_Unit::get_unit_column_types()
684 Select_Lex *sl= first_select();
693 return &sl->item_list;
696 bool Select_Lex::cleanup()
702 assert((Select_Lex*)join->select_lex ==
this);
703 error= join->destroy();
706 for (Select_Lex_Unit *lex_unit= first_inner_unit(); lex_unit ;
707 lex_unit= lex_unit->next_unit())
709 error= (bool) ((uint32_t) error | (uint32_t) lex_unit->cleanup());
711 non_agg_fields.clear();
712 inner_refs_list.clear();
717 void Select_Lex::cleanup_all_joins(
bool full)
719 Select_Lex_Unit *unit;
725 for (unit= first_inner_unit(); unit; unit= unit->next_unit())
726 for (sl= unit->first_select(); sl; sl= sl->next_select())
727 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)