Drizzled Public API Documentation

sql_union.cc

00001 /* Copyright (C) 2000-2003 MySQL AB
00002 
00003    This program is free software; you can redistribute it and/or modify
00004    it under the terms of the GNU General Public License as published by
00005    the Free Software Foundation; version 2 of the License.
00006 
00007    This program is distributed in the hope that it will be useful,
00008    but WITHOUT ANY WARRANTY; without even the implied warranty of
00009    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00010    GNU General Public License for more details.
00011 
00012    You should have received a copy of the GNU General Public License
00013    along with this program; if not, write to the Free Software
00014    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
00015 
00016 /*
00017   UNION  of select's
00018   UNION's  were introduced by Monty and Sinisa <sinisa@mysql.com>
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 ** store records in temporary table for UNION
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   {           // using limit offset,count
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     /* create_myisam_from_heap will generate error if needed */
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   Create a temporary table to store the result of select_union.
00103 
00104   SYNOPSIS
00105     select_union::create_result_table()
00106       session                thread handle
00107       column_types       a list of items used to define columns of the
00108                          temporary table
00109       is_union_distinct  if set, the temporary table will eliminate
00110                          duplicates on insert
00111       options            create options
00112       table_alias        name of the temporary table
00113 
00114   DESCRIPTION
00115     Create a temporary table that is used to store the result of a UNION,
00116     derived table, or a materialized cursor.
00117 
00118   RETURN VALUE
00119     0                    The table has been created successfully.
00120     1                    create_tmp_table failed.
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   initialization procedures before fake_select_lex preparation()
00164 
00165   SYNOPSIS
00166     Select_Lex_Unit::init_prepare_fake_select_lex()
00167     session   - thread handler
00168 
00169   RETURN
00170     options of SELECT
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     result object should be reassigned even if preparing already done for
00212     max/min subquery (ALL/ANY optimization)
00213   */
00214   result= sel_result;
00215 
00216   if (prepared)
00217   {
00218     if (describe)
00219     {
00220       /* fast reinit for EXPLAIN */
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   /* Global option */
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       setup_tables_done_option should be set only for very first SELECT,
00266       because it protect from secont setup_tables call for select-like non
00267       select commands (DELETE/INSERT/...) and they use only very first
00268       SELECT (for union it can be only INSERT ... SELECT).
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     /* There are no * in the statement anymore (for PS) */
00291     sl->with_wild= 0;
00292 
00293     if (saved_error || (saved_error= session_arg->is_fatal_error))
00294       goto err;
00295     /*
00296       Use items list of underlaid select for derived tables to preserve
00297       information about fields lengths and exact types
00298     */
00299     if (!is_union_select)
00300       types= first_sl->item_list;
00301     else if (sl == first_sl)
00302     {
00303       /*
00304         We need to create an empty table object. It is used
00305         to create tmp_table fields in Item_type_holder.
00306         The main reason of this is that we can't create
00307         field object without table.
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   /* Error's in 'new' will be detected after loop */
00317   types.push_back(new Item_type_holder(session_arg, item_tmp));
00318       }
00319 
00320       if (session_arg->is_fatal_error)
00321   goto err; // out of memory
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       Check that it was possible to aggregate
00346       all collations together for UNION.
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         We're in execution of a prepared statement or stored procedure:
00385         reset field items to point at fields from the created temporary table.
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); // We will reinit & rexecute unit
00421         item->reset();
00422         table->cursor->ha_delete_all_rows();
00423       }
00424       /* re-enabling indexes for next subselect iteration */
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       We can't use LIMIT at this stage if we are using ORDER BY for the
00445       whole query
00446     */
00447     if (sl->order_list.first || describe)
00448       select_limit_cnt= HA_POS_ERROR;
00449         }
00450 
00451         /*
00452           When using braces, SQL_CALC_FOUND_ROWS affects the whole query:
00453           we don't calculate found_rows() per union part.
00454           Otherwise, SQL_CALC_FOUND_ROWS should be done on all sub parts.
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       /* Needed for the following test and for records_at_start in next loop */
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     This is a union without braces. Remember the number of rows that
00503     could also have been part of the result set.
00504     We get this from the difference of between total number of possible
00505     rows and actual rows added to the temporary table.
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   /* Send result to 'result' */
00515   saved_error= true;
00516   {
00517     if (!session->is_fatal_error)       // Check if EOM
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     allocate JOIN for fake select only once (prevent
00526     select_query automatic allocation)
00527           TODO: The above is nonsense. select_query() will not allocate the
00528           join if one already exists. There must be some other reason why we
00529           don't let it allocate the join. Perhaps this is because we need
00530           some special parameter values passed to join constructor?
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     Fake Select_Lex should have item list for correctref_array
00542     allocation.
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             In EXPLAIN command, constant subqueries that do not use any
00560             tables are executed two times:
00561              - 1st time is a real evaluation to get the subquery value
00562              - 2nd time is to produce EXPLAIN output rows.
00563             1st execution sets certain members (e.g. select_result) to perform
00564             subquery execution rather than EXPLAIN line production. In order
00565             to reset them back, we re-do all of the actions (yes it is ugly):
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   Mark for slow query log if any of the union parts didn't use
00593   indexes efficiently
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; // Safety
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   change select_result object of unit
00650 
00651   SYNOPSIS
00652     Select_Lex_Unit::change_result()
00653     result  new select_result object
00654     old_result  old select_result object
00655 
00656   RETURN
00657     false - OK
00658     true  - error
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   Get column type information for this unit.
00678 
00679   SYNOPSIS
00680     Select_Lex_Unit::get_unit_column_types()
00681 
00682   DESCRIPTION
00683     For a single-select the column types are taken
00684     from the list of selected items. For a union this function
00685     assumes that Select_Lex_Unit::prepare has been called
00686     and returns the type holders that were created for unioned
00687     column types of all selects.
00688 
00689   NOTES
00690     The implementation of this function should be in sync with
00691     Select_Lex_Unit::prepare()
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     /* Types are generated during prepare */
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 } /* namespace drizzled */