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