00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <config.h>
00021
00022 #include <drizzled/sql_select.h>
00023 #include <drizzled/error.h>
00024 #include <drizzled/item/type_holder.h>
00025 #include <drizzled/sql_base.h>
00026 #include <drizzled/sql_union.h>
00027 #include <drizzled/select_union.h>
00028 #include <drizzled/sql_lex.h>
00029 #include <drizzled/session.h>
00030 #include <drizzled/item/subselect.h>
00031
00032 namespace drizzled {
00033
00034 bool drizzle_union(Session *session, LEX *, select_result *result,
00035 Select_Lex_Unit *unit, uint64_t setup_tables_done_option)
00036 {
00037 bool res= unit->prepare(session, result, SELECT_NO_UNLOCK | setup_tables_done_option);
00038 if (not res)
00039 res= unit->exec();
00040 if (res)
00041 unit->cleanup();
00042 return res;
00043 }
00044
00045
00046
00047
00048
00049
00050 int select_union::prepare(List<Item> &, Select_Lex_Unit *u)
00051 {
00052 unit= u;
00053 return 0;
00054 }
00055
00056
00057 bool select_union::send_data(List<Item> &values)
00058 {
00059 int error= 0;
00060 if (unit->offset_limit_cnt)
00061 {
00062 unit->offset_limit_cnt--;
00063 return 0;
00064 }
00065 fill_record(session, table->getFields(), values, true);
00066 if (session->is_error())
00067 return 1;
00068
00069 if ((error= table->cursor->insertRecord(table->getInsertRecord())))
00070 {
00071
00072 if (table->cursor->is_fatal_error(error, HA_CHECK_DUP))
00073 {
00074 my_error(ER_USE_SQL_BIG_RESULT, MYF(0));
00075 return true;
00076 }
00077 }
00078 return 0;
00079 }
00080
00081
00082 bool select_union::send_eof()
00083 {
00084 return 0;
00085 }
00086
00087
00088 bool select_union::flush()
00089 {
00090 int error;
00091 if ((error=table->cursor->extra(HA_EXTRA_NO_CACHE)))
00092 {
00093 table->print_error(error, MYF(0));
00094 return 1;
00095 }
00096 return 0;
00097 }
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121 bool
00122 select_union::create_result_table(Session *session_arg, List<Item> *column_types,
00123 bool is_union_distinct, uint64_t options,
00124 const char *table_alias)
00125 {
00126 assert(table == NULL);
00127 tmp_table_param.init();
00128 tmp_table_param.field_count= column_types->size();
00129
00130 if (! (table= create_tmp_table(session_arg, &tmp_table_param, *column_types,
00131 (Order*) NULL, is_union_distinct, 1,
00132 options, HA_POS_ERROR, (char*) table_alias)))
00133 {
00134 return true;
00135 }
00136
00137 table->cursor->extra(HA_EXTRA_WRITE_CACHE);
00138 table->cursor->extra(HA_EXTRA_IGNORE_DUP_KEY);
00139
00140 return false;
00141 }
00142
00143
00151 void select_union::cleanup()
00152 {
00153 table->cursor->extra(HA_EXTRA_RESET_STATE);
00154 table->cursor->ha_delete_all_rows();
00155 table->free_io_cache();
00156 table->filesort_free_buffers();
00157 }
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171 void
00172 Select_Lex_Unit::init_prepare_fake_select_lex(Session *session_arg)
00173 {
00174 session_arg->lex().current_select= fake_select_lex;
00175 fake_select_lex->table_list.link_in_list((unsigned char *)&result_table_list,
00176 (unsigned char **)
00177 &result_table_list.next_local);
00178 fake_select_lex->context.table_list=
00179 fake_select_lex->context.first_name_resolution_table=
00180 fake_select_lex->get_table_list();
00181
00182 for (Order *order= (Order *) global_parameters->order_list.first;
00183 order;
00184 order= order->next)
00185 order->item= &order->item_ptr;
00186
00187 for (Order *order= (Order *)global_parameters->order_list.first;
00188 order;
00189 order=order->next)
00190 {
00191 (*order->item)->walk(&Item::change_context_processor, 0,
00192 (unsigned char*) &fake_select_lex->context);
00193 }
00194 }
00195
00196
00197 bool Select_Lex_Unit::prepare(Session *session_arg, select_result *sel_result,
00198 uint64_t additional_options)
00199 {
00200 Select_Lex *lex_select_save= session_arg->lex().current_select;
00201 Select_Lex *sl, *first_sl= first_select();
00202 select_result *tmp_result;
00203 bool is_union_select;
00204 Table *empty_table= 0;
00205
00206 describe= test(additional_options & SELECT_DESCRIBE);
00207
00208
00209
00210
00211
00212 result= sel_result;
00213
00214 if (prepared)
00215 {
00216 if (describe)
00217 {
00218
00219 for (sl= first_sl; sl; sl= sl->next_select())
00220 {
00221 sl->join->result= result;
00222 select_limit_cnt= HA_POS_ERROR;
00223 offset_limit_cnt= 0;
00224 if (result->prepare(sl->join->fields_list, this))
00225 {
00226 return true;
00227 }
00228 sl->join->select_options|= SELECT_DESCRIBE;
00229 sl->join->reinit();
00230 }
00231 }
00232 return false;
00233 }
00234 prepared= 1;
00235 saved_error= false;
00236
00237 session_arg->lex().current_select= sl= first_sl;
00238 found_rows_for_union= first_sl->options & OPTION_FOUND_ROWS;
00239 is_union_select= is_union() || fake_select_lex;
00240
00241
00242
00243 if (is_union_select)
00244 {
00245 tmp_result= union_result= new select_union;
00246 if (describe)
00247 tmp_result= sel_result;
00248 }
00249 else
00250 tmp_result= sel_result;
00251
00252 sl->context.resolve_in_select_list= true;
00253
00254 for (;sl; sl= sl->next_select())
00255 {
00256 bool can_skip_order_by;
00257 sl->options|= SELECT_NO_UNLOCK;
00258 Join *join= new Join(session_arg, sl->item_list,
00259 sl->options | session_arg->options | additional_options,
00260 tmp_result);
00261
00262
00263
00264
00265
00266
00267 additional_options&= ~OPTION_SETUP_TABLES_DONE;
00268 if (!join)
00269 goto err;
00270
00271 session_arg->lex().current_select= sl;
00272
00273 can_skip_order_by= is_union_select && !(sl->braces && sl->explicit_limit);
00274
00275 saved_error= join->prepare(&sl->ref_pointer_array,
00276 (TableList*) sl->table_list.first,
00277 sl->with_wild,
00278 sl->where,
00279 (can_skip_order_by ? 0 :
00280 sl->order_list.size()) +
00281 sl->group_list.size(),
00282 can_skip_order_by ?
00283 (Order*) NULL : (Order *)sl->order_list.first,
00284 (Order*) sl->group_list.first,
00285 sl->having,
00286 sl, this);
00287
00288 sl->with_wild= 0;
00289
00290 if (saved_error || (saved_error= session_arg->is_fatal_error))
00291 goto err;
00292
00293
00294
00295
00296 if (!is_union_select)
00297 types= first_sl->item_list;
00298 else if (sl == first_sl)
00299 {
00300
00301
00302
00303
00304
00305
00306 assert(!empty_table);
00307 empty_table= (Table*) session->mem.calloc(sizeof(Table));
00308 types.clear();
00309 List<Item>::iterator it(sl->item_list.begin());
00310 while (Item* item_tmp= it++)
00311 {
00312
00313 types.push_back(new Item_type_holder(session_arg, item_tmp));
00314 }
00315
00316 if (session_arg->is_fatal_error)
00317 goto err;
00318 }
00319 else
00320 {
00321 if (types.size() != sl->item_list.size())
00322 {
00323 my_message(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT,
00324 ER(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT),MYF(0));
00325 goto err;
00326 }
00327 List<Item>::iterator it(sl->item_list.begin());
00328 List<Item>::iterator tp(types.begin());
00329 Item *type, *item_tmp;
00330 while ((type= tp++, item_tmp= it++))
00331 {
00332 if (((Item_type_holder*)type)->join_types(session_arg, item_tmp))
00333 return true;
00334 }
00335 }
00336 }
00337
00338 if (is_union_select)
00339 {
00340
00341
00342
00343
00344 List<Item>::iterator tp(types.begin());
00345 Item *type;
00346 uint64_t create_options;
00347
00348 while ((type= tp++))
00349 {
00350 if (type->result_type() == STRING_RESULT &&
00351 type->collation.derivation == DERIVATION_NONE)
00352 {
00353 my_error(ER_CANT_AGGREGATE_NCOLLATIONS, MYF(0), "UNION");
00354 goto err;
00355 }
00356 }
00357
00358 create_options= first_sl->options | session_arg->options | TMP_TABLE_ALL_COLUMNS;
00359
00360 if (union_result->create_result_table(session, &types, test(union_distinct), create_options, ""))
00361 goto err;
00362 memset(&result_table_list, 0, sizeof(result_table_list));
00363 result_table_list.setSchemaName("");
00364 result_table_list.alias= "union";
00365 result_table_list.setTableName("union");
00366 result_table_list.table= table= union_result->table;
00367
00368 session_arg->lex().current_select= lex_select_save;
00369 if (item_list.is_empty())
00370 table->fill_item_list(item_list);
00371 else
00372 {
00373
00374
00375
00376
00377 assert(false);
00378 }
00379 }
00380
00381 session_arg->lex().current_select= lex_select_save;
00382
00383 return(saved_error || session_arg->is_fatal_error);
00384
00385 err:
00386 session_arg->lex().current_select= lex_select_save;
00387 return true;
00388 }
00389
00390
00391 bool Select_Lex_Unit::exec()
00392 {
00393 Select_Lex *lex_select_save= session->lex().current_select;
00394 Select_Lex *select_cursor=first_select();
00395 uint64_t add_rows=0;
00396 ha_rows examined_rows= 0;
00397
00398 if (executed && uncacheable.none() && ! describe)
00399 return false;
00400 executed= 1;
00401
00402 if (uncacheable.any() || ! item || ! item->assigned() || describe)
00403 {
00404 if (item)
00405 item->reset_value_registration();
00406 if (optimized && item)
00407 {
00408 if (item->assigned())
00409 {
00410 item->assigned(0);
00411 item->reset();
00412 table->cursor->ha_delete_all_rows();
00413 }
00414
00415 if (union_distinct && table->cursor->ha_enable_indexes(HA_KEY_SWITCH_ALL))
00416 {
00417 assert(0);
00418 }
00419 }
00420 for (Select_Lex *sl= select_cursor; sl; sl= sl->next_select())
00421 {
00422 ha_rows records_at_start= 0;
00423 session->lex().current_select= sl;
00424
00425 if (optimized)
00426 saved_error= sl->join->reinit();
00427 else
00428 {
00429 set_limit(sl);
00430 if (sl == global_parameters || describe)
00431 {
00432 offset_limit_cnt= 0;
00433
00434
00435
00436
00437 if (sl->order_list.first || describe)
00438 select_limit_cnt= HA_POS_ERROR;
00439 }
00440
00441
00442
00443
00444
00445
00446 sl->join->select_options=
00447 (select_limit_cnt == HA_POS_ERROR || sl->braces) ?
00448 sl->options & ~OPTION_FOUND_ROWS : sl->options | found_rows_for_union;
00449
00450 saved_error= sl->join->optimize();
00451 }
00452 if (!saved_error)
00453 {
00454 records_at_start= table->cursor->stats.records;
00455 sl->join->exec();
00456 if (sl == union_distinct)
00457 {
00458 if (table->cursor->ha_disable_indexes(HA_KEY_SWITCH_ALL))
00459 return true;
00460 table->no_keyread=1;
00461 }
00462 saved_error= sl->join->error;
00463 offset_limit_cnt= (ha_rows)(sl->offset_limit ?
00464 sl->offset_limit->val_uint() :
00465 0);
00466 if (!saved_error)
00467 {
00468 examined_rows+= session->examined_row_count;
00469 if (union_result->flush())
00470 {
00471 session->lex().current_select= lex_select_save;
00472 return 1;
00473 }
00474 }
00475 }
00476 if (saved_error)
00477 {
00478 session->lex().current_select= lex_select_save;
00479 return(saved_error);
00480 }
00481
00482 int error= table->cursor->info(HA_STATUS_VARIABLE);
00483 if (error)
00484 {
00485 table->print_error(error, MYF(0));
00486 return 1;
00487 }
00488 if (found_rows_for_union && !sl->braces &&
00489 select_limit_cnt != HA_POS_ERROR)
00490 {
00491
00492
00493
00494
00495
00496
00497 add_rows+= (uint64_t) (session->limit_found_rows - (uint64_t)
00498 ((table->cursor->stats.records - records_at_start)));
00499 }
00500 }
00501 }
00502 optimized= 1;
00503
00504
00505 saved_error= true;
00506 {
00507 if (!session->is_fatal_error)
00508 {
00509 set_limit(global_parameters);
00510 init_prepare_fake_select_lex(session);
00511 Join *join= fake_select_lex->join;
00512 if (!join)
00513 {
00514
00515
00516
00517
00518
00519
00520
00521
00522 fake_select_lex->join= new Join(session, item_list, fake_select_lex->options, result);
00523 fake_select_lex->join->no_const_tables= true;
00524
00525
00526
00527
00528
00529 fake_select_lex->item_list= item_list;
00530 saved_error= select_query(session, &fake_select_lex->ref_pointer_array,
00531 &result_table_list,
00532 0, item_list, NULL,
00533 global_parameters->order_list.size(),
00534 (Order*)global_parameters->order_list.first,
00535 (Order*) NULL, NULL,
00536 fake_select_lex->options | SELECT_NO_UNLOCK,
00537 result, this, fake_select_lex);
00538 }
00539 else
00540 {
00541 if (describe)
00542 {
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552 join->reset(session, item_list, fake_select_lex->options, result);
00553 saved_error= select_query(session, &fake_select_lex->ref_pointer_array,
00554 &result_table_list,
00555 0, item_list, NULL,
00556 global_parameters->order_list.size(),
00557 (Order*)global_parameters->order_list.first,
00558 (Order*) NULL, NULL,
00559 fake_select_lex->options | SELECT_NO_UNLOCK,
00560 result, this, fake_select_lex);
00561 }
00562 else
00563 {
00564 join->examined_rows= 0;
00565 saved_error= join->reinit();
00566 join->exec();
00567 }
00568 }
00569
00570 fake_select_lex->table_list.clear();
00571 if (!saved_error)
00572 {
00573 session->limit_found_rows = (uint64_t)table->cursor->stats.records + add_rows;
00574 session->examined_row_count+= examined_rows;
00575 }
00576
00577
00578
00579
00580 }
00581 }
00582 session->lex().current_select= lex_select_save;
00583 return(saved_error);
00584 }
00585
00586
00587 bool Select_Lex_Unit::cleanup()
00588 {
00589 int error= 0;
00590
00591 if (cleaned)
00592 {
00593 return false;
00594 }
00595 cleaned= 1;
00596
00597 if (union_result)
00598 {
00599 safe_delete(union_result);
00600 table= 0;
00601 }
00602
00603 for (Select_Lex *sl= first_select(); sl; sl= sl->next_select())
00604 error|= sl->cleanup();
00605
00606 if (fake_select_lex)
00607 {
00608 Join *join;
00609 if ((join= fake_select_lex->join))
00610 {
00611 join->tables_list= 0;
00612 join->tables= 0;
00613 }
00614 error|= fake_select_lex->cleanup();
00615 if (fake_select_lex->order_list.size())
00616 {
00617 Order *ord;
00618 for (ord= (Order*)fake_select_lex->order_list.first; ord; ord= ord->next)
00619 (*ord->item)->cleanup();
00620 }
00621 }
00622
00623 return(error);
00624 }
00625
00626
00627 void Select_Lex_Unit::reinit_exec_mechanism()
00628 {
00629 prepared= optimized= executed= 0;
00630 }
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646 bool Select_Lex_Unit::change_result(select_result_interceptor *new_result,
00647 select_result_interceptor *old_result)
00648 {
00649 bool res= false;
00650 for (Select_Lex *sl= first_select(); sl; sl= sl->next_select())
00651 {
00652 if (sl->join && sl->join->result == old_result)
00653 if (sl->join->change_result(new_result))
00654 return true;
00655 }
00656 if (fake_select_lex && fake_select_lex->join)
00657 res= fake_select_lex->join->change_result(new_result);
00658 return (res);
00659 }
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679 List<Item> *Select_Lex_Unit::get_unit_column_types()
00680 {
00681 Select_Lex *sl= first_select();
00682
00683 if (is_union())
00684 {
00685 assert(prepared);
00686
00687 return &types;
00688 }
00689
00690 return &sl->item_list;
00691 }
00692
00693 bool Select_Lex::cleanup()
00694 {
00695 bool error= false;
00696
00697 if (join)
00698 {
00699 assert((Select_Lex*)join->select_lex == this);
00700 error= join->destroy();
00701 safe_delete(join);
00702 }
00703 for (Select_Lex_Unit *lex_unit= first_inner_unit(); lex_unit ;
00704 lex_unit= lex_unit->next_unit())
00705 {
00706 error= (bool) ((uint32_t) error | (uint32_t) lex_unit->cleanup());
00707 }
00708 non_agg_fields.clear();
00709 inner_refs_list.clear();
00710 return(error);
00711 }
00712
00713
00714 void Select_Lex::cleanup_all_joins(bool full)
00715 {
00716 Select_Lex_Unit *unit;
00717 Select_Lex *sl;
00718
00719 if (join)
00720 join->cleanup(full);
00721
00722 for (unit= first_inner_unit(); unit; unit= unit->next_unit())
00723 for (sl= unit->first_select(); sl; sl= sl->next_select())
00724 sl->cleanup_all_joins(full);
00725 }
00726
00727 }