Drizzled Public API Documentation

sum.cc
Go to the documentation of this file.
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 
00023 #include <config.h>
00024 #include <cstdio>
00025 #include <math.h>
00026 #include <drizzled/sql_select.h>
00027 #include <drizzled/error.h>
00028 #include <drizzled/hybrid_type_traits.h>
00029 #include <drizzled/hybrid_type_traits_integer.h>
00030 #include <drizzled/hybrid_type_traits_decimal.h>
00031 #include <drizzled/sql_base.h>
00032 #include <drizzled/session.h>
00033 #include <drizzled/item/sum.h>
00034 #include <drizzled/field/decimal.h>
00035 #include <drizzled/field/double.h>
00036 #include <drizzled/field/int64.h>
00037 #include <drizzled/field/date.h>
00038 #include <drizzled/field/datetime.h>
00039 #include <drizzled/unique.h>
00040 #include <drizzled/type/decimal.h>
00041 #include <drizzled/internal/m_string.h>
00042 #include <drizzled/item/subselect.h>
00043 #include <drizzled/sql_lex.h>
00044 #include <drizzled/system_variables.h>
00045 #include <drizzled/create_field.h>
00046 
00047 #include <algorithm>
00048 
00049 using namespace std;
00050 
00051 namespace drizzled {
00052 
00053 extern plugin::StorageEngine *heap_engine;
00054 
00077 bool Item_sum::init_sum_func_check(Session *session)
00078 {
00079   if (!session->lex().allow_sum_func)
00080   {
00081     my_message(ER_INVALID_GROUP_FUNC_USE, ER(ER_INVALID_GROUP_FUNC_USE),
00082                MYF(0));
00083     return true;
00084   }
00085   /* Set a reference to the nesting set function if there is  any */
00086   in_sum_func= session->lex().in_sum_func;
00087   /* Save a pointer to object to be used in items for nested set functions */
00088   session->lex().in_sum_func= this;
00089   nest_level= session->lex().current_select->nest_level;
00090   ref_by= 0;
00091   aggr_level= -1;
00092   aggr_sel= NULL;
00093   max_arg_level= -1;
00094   max_sum_func_level= -1;
00095   outer_fields.clear();
00096   return false;
00097 }
00098 
00148 bool Item_sum::check_sum_func(Session *session, Item **ref)
00149 {
00150   bool invalid= false;
00151   nesting_map allow_sum_func= session->lex().allow_sum_func;
00152   /*
00153     The value of max_arg_level is updated if an argument of the set function
00154     contains a column reference resolved  against a subquery whose level is
00155     greater than the current value of max_arg_level.
00156     max_arg_level cannot be greater than nest level.
00157     nest level is always >= 0
00158   */
00159   if (nest_level == max_arg_level)
00160   {
00161     /*
00162       The function must be aggregated in the current subquery,
00163       If it is there under a construct where it is not allowed
00164       we report an error.
00165     */
00166     invalid= !(allow_sum_func & (1 << max_arg_level));
00167   }
00168   else if (max_arg_level >= 0 || !(allow_sum_func & (1 << nest_level)))
00169   {
00170     /*
00171       The set function can be aggregated only in outer subqueries.
00172       Try to find a subquery where it can be aggregated;
00173       If we fail to find such a subquery report an error.
00174     */
00175     if (register_sum_func(session, ref))
00176       return true;
00177     invalid= aggr_level < 0 && !(allow_sum_func & (1 << nest_level));
00178     if (!invalid && false)
00179       invalid= aggr_level < 0 && max_arg_level < nest_level;
00180   }
00181   if (!invalid && aggr_level < 0)
00182   {
00183     aggr_level= nest_level;
00184     aggr_sel= session->lex().current_select;
00185   }
00186   /*
00187     By this moment we either found a subquery where the set function is
00188     to be aggregated  and assigned a value that is  >= 0 to aggr_level,
00189     or set the value of 'invalid' to TRUE to report later an error.
00190   */
00191   /*
00192     Additionally we have to check whether possible nested set functions
00193     are acceptable here: they are not, if the level of aggregation of
00194     some of them is less than aggr_level.
00195   */
00196   if (!invalid)
00197     invalid= aggr_level <= max_sum_func_level;
00198   if (invalid)
00199   {
00200     my_message(ER_INVALID_GROUP_FUNC_USE, ER(ER_INVALID_GROUP_FUNC_USE),
00201                MYF(0));
00202     return true;
00203   }
00204 
00205   if (in_sum_func)
00206   {
00207     /*
00208       If the set function is nested adjust the value of
00209       max_sum_func_level for the nesting set function.
00210       We take into account only enclosed set functions that are to be
00211       aggregated on the same level or above of the nest level of
00212       the enclosing set function.
00213       But we must always pass up the max_sum_func_level because it is
00214       the maximum nested level of all directly and indirectly enclosed
00215       set functions. We must do that even for set functions that are
00216       aggregated inside of their enclosing set function's nest level
00217       because the enclosing function may contain another enclosing
00218       function that is to be aggregated outside or on the same level
00219       as its parent's nest level.
00220     */
00221     if (in_sum_func->nest_level >= aggr_level)
00222       set_if_bigger(in_sum_func->max_sum_func_level, aggr_level);
00223     set_if_bigger(in_sum_func->max_sum_func_level, max_sum_func_level);
00224   }
00225 
00226   /*
00227     Check that non-aggregated fields and sum functions aren't mixed in the
00228     same select in the ONLY_FULL_GROUP_BY mode.
00229   */
00230   if (outer_fields.size())
00231   {
00232     Item_field *field;
00233     /*
00234       Here we compare the nesting level of the select to which an outer field
00235       belongs to with the aggregation level of the sum function. All fields in
00236       the outer_fields list are checked.
00237 
00238       If the nesting level is equal to the aggregation level then the field is
00239         aggregated by this sum function.
00240       If the nesting level is less than the aggregation level then the field
00241         belongs to an outer select. In this case if there is an embedding sum
00242         function add current field to functions outer_fields list. If there is
00243         no embedding function then the current field treated as non aggregated
00244         and the select it belongs to is marked accordingly.
00245       If the nesting level is greater than the aggregation level then it means
00246         that this field was added by an inner sum function.
00247         Consider an example:
00248 
00249           select avg ( <-- we are here, checking outer.f1
00250             select (
00251               select sum(outer.f1 + inner.f1) from inner
00252             ) from outer)
00253           from most_outer;
00254 
00255         In this case we check that no aggregate functions are used in the
00256         select the field belongs to. If there are some then an error is
00257         raised.
00258     */
00259     List<Item_field>::iterator of(outer_fields.begin());
00260     while ((field= of++))
00261     {
00262       Select_Lex *sel= field->cached_table->select_lex;
00263       if (sel->nest_level < aggr_level)
00264       {
00265         if (in_sum_func)
00266         {
00267           /*
00268             Let upper function decide whether this field is a non
00269             aggregated one.
00270           */
00271           in_sum_func->outer_fields.push_back(field);
00272         }
00273         else
00274         {
00275           sel->full_group_by_flag.set(NON_AGG_FIELD_USED);
00276         }
00277       }
00278       if (sel->nest_level > aggr_level &&
00279           (sel->full_group_by_flag.test(SUM_FUNC_USED)) &&
00280           ! sel->group_list.elements)
00281       {
00282         my_message(ER_MIX_OF_GROUP_FUNC_AND_FIELDS,
00283                    ER(ER_MIX_OF_GROUP_FUNC_AND_FIELDS), MYF(0));
00284         return true;
00285       }
00286     }
00287   }
00288   aggr_sel->full_group_by_flag.set(SUM_FUNC_USED);
00289   update_used_tables();
00290   session->lex().in_sum_func= in_sum_func;
00291   return false;
00292 }
00293 
00319 bool Item_sum::register_sum_func(Session *session, Item **ref)
00320 {
00321   Select_Lex *sl;
00322   nesting_map allow_sum_func= session->lex().allow_sum_func;
00323   for (sl= session->lex().current_select->master_unit()->outer_select() ;
00324        sl && sl->nest_level > max_arg_level;
00325        sl= sl->master_unit()->outer_select() )
00326   {
00327     if (aggr_level < 0 && (allow_sum_func & (1 << sl->nest_level)))
00328     {
00329       /* Found the most nested subquery where the function can be aggregated */
00330       aggr_level= sl->nest_level;
00331       aggr_sel= sl;
00332     }
00333   }
00334   if (sl && (allow_sum_func & (1 << sl->nest_level)))
00335   {
00336     /*
00337       We reached the subquery of level max_arg_level and checked
00338       that the function can be aggregated here.
00339       The set function will be aggregated in this subquery.
00340     */
00341     aggr_level= sl->nest_level;
00342     aggr_sel= sl;
00343 
00344   }
00345   if (aggr_level >= 0)
00346   {
00347     ref_by= ref;
00348     /* Add the object to the list of registered objects assigned to aggr_sel */
00349     if (!aggr_sel->inner_sum_func_list)
00350       next= this;
00351     else
00352     {
00353       next= aggr_sel->inner_sum_func_list->next;
00354       aggr_sel->inner_sum_func_list->next= this;
00355     }
00356     aggr_sel->inner_sum_func_list= this;
00357     aggr_sel->with_sum_func= 1;
00358 
00359     /*
00360       Mark Item_subselect(s) as containing aggregate function all the way up
00361       to aggregate function's calculation context.
00362       Note that we must not mark the Item of calculation context itself
00363       because with_sum_func on the calculation context Select_Lex is
00364       already set above.
00365 
00366       with_sum_func being set for an Item means that this Item refers
00367       (somewhere in it, e.g. one of its arguments if it's a function) directly
00368       or through intermediate items to an aggregate function that is calculated
00369       in a context "outside" of the Item (e.g. in the current or outer select).
00370 
00371       with_sum_func being set for an Select_Lex means that this Select_Lex
00372       has aggregate functions directly referenced (i.e. not through a sub-select).
00373     */
00374     for (sl= session->lex().current_select;
00375          sl && sl != aggr_sel && sl->master_unit()->item;
00376          sl= sl->master_unit()->outer_select() )
00377       sl->master_unit()->item->with_sum_func= 1;
00378   }
00379   session->lex().current_select->mark_as_dependent(aggr_sel);
00380   return false;
00381 }
00382 
00383 
00384 Item_sum::Item_sum(List<Item> &list) :arg_count(list.size()),
00385   forced_const(false)
00386 {
00387   if ((args=(Item**) memory::sql_alloc(sizeof(Item*)*arg_count)))
00388   {
00389     uint32_t i=0;
00390     List<Item>::iterator li(list.begin());
00391     Item *item;
00392 
00393     while ((item=li++))
00394     {
00395       args[i++]= item;
00396     }
00397   }
00398   mark_as_sum_func();
00399   list.clear();         // Fields are used
00400 }
00401 
00402 
00407 Item_sum::Item_sum(Session *session, Item_sum *item):
00408   Item_result_field(session, item), arg_count(item->arg_count),
00409   aggr_sel(item->aggr_sel),
00410   nest_level(item->nest_level), aggr_level(item->aggr_level),
00411   quick_group(item->quick_group), used_tables_cache(item->used_tables_cache),
00412   forced_const(item->forced_const)
00413 {
00414   if (arg_count <= 2)
00415     args= tmp_args;
00416   else
00417     args= new (session->mem) Item*[arg_count];
00418   memcpy(args, item->args, sizeof(Item*)*arg_count);
00419 }
00420 
00421 
00422 void Item_sum::mark_as_sum_func()
00423 {
00424   Select_Lex *cur_select= getSession().lex().current_select;
00425   cur_select->n_sum_items++;
00426   cur_select->with_sum_func= 1;
00427   with_sum_func= 1;
00428 }
00429 
00430 
00431 void Item_sum::make_field(SendField *tmp_field)
00432 {
00433   if (args[0]->type() == Item::FIELD_ITEM && keep_field_type())
00434   {
00435     ((Item_field*) args[0])->field->make_field(tmp_field);
00436     /* For expressions only col_name should be non-empty string. */
00437     tmp_field->db_name= "";
00438     tmp_field->org_table_name= "";
00439     tmp_field->table_name= "";
00440     tmp_field->org_col_name= "";
00441     tmp_field->col_name= name;
00442     if (maybe_null)
00443       tmp_field->flags&= ~NOT_NULL_FLAG;
00444   }
00445   else
00446     init_make_field(tmp_field, field_type());
00447 }
00448 
00449 
00450 void Item_sum::print(String *str)
00451 {
00452   str->append(func_name());
00453   for (uint32_t i=0 ; i < arg_count ; i++)
00454   {
00455     if (i)
00456       str->append(',');
00457     args[i]->print(str);
00458   }
00459   str->append(')');
00460 }
00461 
00462 void Item_sum::fix_num_length_and_dec()
00463 {
00464   decimals=0;
00465   for (uint32_t i=0 ; i < arg_count ; i++)
00466     set_if_bigger(decimals,args[i]->decimals);
00467   max_length=float_length(decimals);
00468 }
00469 
00470 Item *Item_sum::get_tmp_table_item(Session *session)
00471 {
00472   Item_sum* sum_item= (Item_sum *) copy_or_same(session);
00473   if (sum_item && sum_item->result_field)    // If not a const sum func
00474   {
00475     Field *result_field_tmp= sum_item->result_field;
00476     for (uint32_t i=0 ; i < sum_item->arg_count ; i++)
00477     {
00478       Item *arg= sum_item->args[i];
00479       if (!arg->const_item())
00480       {
00481   if (arg->type() == Item::FIELD_ITEM)
00482     ((Item_field*) arg)->field= result_field_tmp++;
00483   else
00484     sum_item->args[i]= new Item_field(result_field_tmp++);
00485       }
00486     }
00487   }
00488   return sum_item;
00489 }
00490 
00491 
00492 bool Item_sum::walk (Item_processor processor, bool walk_subquery,
00493                      unsigned char *argument)
00494 {
00495   if (arg_count)
00496   {
00497     Item **arg,**arg_end;
00498     for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++)
00499     {
00500       if ((*arg)->walk(processor, walk_subquery, argument))
00501   return 1;
00502     }
00503   }
00504   return (this->*processor)(argument);
00505 }
00506 
00507 
00508 Field *Item_sum::create_tmp_field(bool ,
00509                                   Table *table,
00510                                   uint32_t convert_blob_length)
00511 {
00512   Field *field= NULL;
00513 
00514   switch (result_type()) {
00515   case REAL_RESULT:
00516     field= new Field_double(max_length, maybe_null, name, decimals, true);
00517     break;
00518 
00519   case INT_RESULT:
00520     field= new field::Int64(max_length, maybe_null, name, unsigned_flag);
00521     break;
00522 
00523   case STRING_RESULT:
00524     if (max_length/collation.collation->mbmaxlen <= 255 ||
00525         convert_blob_length > Field_varstring::MAX_SIZE ||
00526         !convert_blob_length)
00527     {
00528       return make_string_field(table);
00529     }
00530 
00531     table->setVariableWidth();
00532     field= new Field_varstring(convert_blob_length, maybe_null,
00533                                name, collation.collation);
00534     break;
00535 
00536   case DECIMAL_RESULT:
00537     field= new Field_decimal(max_length, maybe_null, name,
00538                              decimals, unsigned_flag);
00539     break;
00540 
00541   case ROW_RESULT:
00542     // This case should never be choosen
00543     assert(0);
00544     return 0;
00545   }
00546 
00547   if (field)
00548     field->init(table);
00549 
00550   return field;
00551 }
00552 
00553 
00554 void Item_sum::update_used_tables ()
00555 {
00556   if (!forced_const)
00557   {
00558     used_tables_cache= 0;
00559     for (uint32_t i=0 ; i < arg_count ; i++)
00560     {
00561       args[i]->update_used_tables();
00562       used_tables_cache|= args[i]->used_tables();
00563     }
00564 
00565     used_tables_cache&= PSEUDO_TABLE_BITS;
00566 
00567     /* the aggregate function is aggregated into its local context */
00568     used_tables_cache |=  (1 << aggr_sel->join->tables) - 1;
00569   }
00570 }
00571 
00572 
00573 String *
00574 Item_sum_num::val_str(String *str)
00575 {
00576   return val_string_from_real(str);
00577 }
00578 
00579 
00580 int64_t Item_sum_num::val_int()
00581 {
00582   assert(fixed == 1);
00583   return (int64_t) rint(val_real());             /* Real as default */
00584 }
00585 
00586 
00587 type::Decimal *Item_sum_num::val_decimal(type::Decimal *decimal_value)
00588 {
00589   return val_decimal_from_real(decimal_value);
00590 }
00591 
00592 
00593 String *
00594 Item_sum_int::val_str(String *str)
00595 {
00596   return val_string_from_int(str);
00597 }
00598 
00599 
00600 type::Decimal *Item_sum_int::val_decimal(type::Decimal *decimal_value)
00601 {
00602   return val_decimal_from_int(decimal_value);
00603 }
00604 
00605 
00606 bool
00607 Item_sum_num::fix_fields(Session *session, Item **ref)
00608 {
00609   assert(fixed == 0);
00610 
00611   if (init_sum_func_check(session))
00612     return true;
00613 
00614   decimals=0;
00615   maybe_null=0;
00616   for (uint32_t i=0 ; i < arg_count ; i++)
00617   {
00618     if (args[i]->fix_fields(session, args + i) || args[i]->check_cols(1))
00619       return true;
00620     set_if_bigger(decimals, args[i]->decimals);
00621     maybe_null |= args[i]->maybe_null;
00622   }
00623   result_field=0;
00624   max_length=float_length(decimals);
00625   null_value=1;
00626   fix_length_and_dec();
00627 
00628   if (check_sum_func(session, ref))
00629     return true;
00630 
00631   fixed= 1;
00632   return false;
00633 }
00634 
00635 
00636 Item_sum_hybrid::Item_sum_hybrid(Session *session, Item_sum_hybrid *item)
00637   :Item_sum(session, item), value(item->value), hybrid_type(item->hybrid_type),
00638   hybrid_field_type(item->hybrid_field_type), cmp_sign(item->cmp_sign),
00639   was_values(item->was_values)
00640 {
00641   /* copy results from old value */
00642   switch (hybrid_type) {
00643   case INT_RESULT:
00644     sum_int= item->sum_int;
00645     break;
00646   case DECIMAL_RESULT:
00647     class_decimal2decimal(&item->sum_dec, &sum_dec);
00648     break;
00649   case REAL_RESULT:
00650     sum= item->sum;
00651     break;
00652   case STRING_RESULT:
00653     /*
00654       This can happen with ROLLUP. Note that the value is already
00655       copied at function call.
00656     */
00657     break;
00658   case ROW_RESULT:
00659     assert(0);
00660   }
00661   collation.set(item->collation);
00662 }
00663 
00664 bool
00665 Item_sum_hybrid::fix_fields(Session *session, Item **ref)
00666 {
00667   assert(fixed == 0);
00668 
00669   Item *item= args[0];
00670 
00671   if (init_sum_func_check(session))
00672     return true;
00673 
00674   // 'item' can be changed during fix_fields
00675   if ((!item->fixed && item->fix_fields(session, args)) ||
00676       (item= args[0])->check_cols(1))
00677     return true;
00678   decimals=item->decimals;
00679 
00680   switch (hybrid_type= item->result_type()) {
00681   case INT_RESULT:
00682     max_length= 20;
00683     sum_int= 0;
00684     break;
00685   case DECIMAL_RESULT:
00686     max_length= item->max_length;
00687     sum_dec.set_zero();
00688     break;
00689   case REAL_RESULT:
00690     max_length= float_length(decimals);
00691     sum= 0.0;
00692     break;
00693   case STRING_RESULT:
00694     max_length= item->max_length;
00695     break;
00696   case ROW_RESULT:
00697     assert(0);
00698   };
00699   /* MIN/MAX can return NULL for empty set indepedent of the used column */
00700   maybe_null= 1;
00701   unsigned_flag=item->unsigned_flag;
00702   collation.set(item->collation);
00703   result_field=0;
00704   null_value=1;
00705   fix_length_and_dec();
00706   item= item->real_item();
00707   if (item->type() == Item::FIELD_ITEM)
00708     hybrid_field_type= ((Item_field*) item)->field->type();
00709   else
00710     hybrid_field_type= Item::field_type();
00711 
00712   if (check_sum_func(session, ref))
00713     return true;
00714 
00715   fixed= 1;
00716   return false;
00717 }
00718 
00719 Field *Item_sum_hybrid::create_tmp_field(bool group, Table *table,
00720            uint32_t convert_blob_length)
00721 {
00722   Field *field;
00723   if (args[0]->type() == Item::FIELD_ITEM)
00724   {
00725     field= ((Item_field*) args[0])->field;
00726 
00727     if ((field= create_tmp_field_from_field(&getSession(), field, name, table,
00728               NULL, convert_blob_length)))
00729       field->flags&= ~NOT_NULL_FLAG;
00730     return field;
00731   }
00732   /*
00733     DATE/TIME fields have STRING_RESULT result types.
00734     In order to preserve field type, it's needed to handle DATE/TIME
00735     fields creations separately.
00736   */
00737   switch (args[0]->field_type()) {
00738   case DRIZZLE_TYPE_DATE:
00739     field= new Field_date(maybe_null, name);
00740     break;
00741   case DRIZZLE_TYPE_TIMESTAMP:
00742   case DRIZZLE_TYPE_DATETIME:
00743     field= new Field_datetime(maybe_null, name);
00744     break;
00745   default:
00746     return Item_sum::create_tmp_field(group, table, convert_blob_length);
00747   }
00748 
00749   if (field)
00750     field->init(table);
00751 
00752   return field;
00753 }
00754 
00755 
00756 /***********************************************************************
00757 ** reset and add of sum_func
00758 ***********************************************************************/
00759 
00764 Item_sum_sum::Item_sum_sum(Session *session, Item_sum_sum *item)
00765   :Item_sum_num(session, item), hybrid_type(item->hybrid_type),
00766    curr_dec_buff(item->curr_dec_buff)
00767 {
00768   /* TODO: check if the following assignments are really needed */
00769   if (hybrid_type == DECIMAL_RESULT)
00770   {
00771     class_decimal2decimal(item->dec_buffs, dec_buffs);
00772     class_decimal2decimal(item->dec_buffs + 1, dec_buffs + 1);
00773   }
00774   else
00775     sum= item->sum;
00776 }
00777 
00778 Item *Item_sum_sum::copy_or_same(Session* session)
00779 {
00780   return new (session->mem) Item_sum_sum(session, this);
00781 }
00782 
00783 
00784 void Item_sum_sum::clear()
00785 {
00786   null_value=1;
00787   if (hybrid_type == DECIMAL_RESULT)
00788   {
00789     curr_dec_buff= 0;
00790     dec_buffs->set_zero();
00791   }
00792   else
00793     sum= 0.0;
00794   return;
00795 }
00796 
00797 
00798 void Item_sum_sum::fix_length_and_dec()
00799 {
00800   maybe_null=null_value=1;
00801   decimals= args[0]->decimals;
00802   switch (args[0]->result_type()) {
00803   case REAL_RESULT:
00804   case STRING_RESULT:
00805     hybrid_type= REAL_RESULT;
00806     sum= 0.0;
00807     break;
00808   case INT_RESULT:
00809   case DECIMAL_RESULT:
00810     {
00811       /* SUM result can't be longer than length(arg) + length(MAX_ROWS) */
00812       int precision= args[0]->decimal_precision() + DECIMAL_LONGLONG_DIGITS;
00813       max_length= class_decimal_precision_to_length(precision, decimals,
00814                                                  unsigned_flag);
00815       curr_dec_buff= 0;
00816       hybrid_type= DECIMAL_RESULT;
00817       dec_buffs->set_zero();
00818       break;
00819     }
00820   case ROW_RESULT:
00821     assert(0);
00822   }
00823 }
00824 
00825 
00826 bool Item_sum_sum::add()
00827 {
00828   if (hybrid_type == DECIMAL_RESULT)
00829   {
00830     type::Decimal value, *val= args[0]->val_decimal(&value);
00831     if (!args[0]->null_value)
00832     {
00833       class_decimal_add(E_DEC_FATAL_ERROR, dec_buffs + (curr_dec_buff^1),
00834                      val, dec_buffs + curr_dec_buff);
00835       curr_dec_buff^= 1;
00836       null_value= 0;
00837     }
00838   }
00839   else
00840   {
00841     sum+= args[0]->val_real();
00842     if (!args[0]->null_value)
00843       null_value= 0;
00844   }
00845   return 0;
00846 }
00847 
00848 
00849 int64_t Item_sum_sum::val_int()
00850 {
00851   assert(fixed == 1);
00852   if (hybrid_type == DECIMAL_RESULT)
00853   {
00854     int64_t result;
00855     (dec_buffs + curr_dec_buff)->val_int32(E_DEC_FATAL_ERROR, unsigned_flag, &result);
00856     return result;
00857   }
00858   return (int64_t) rint(val_real());
00859 }
00860 
00861 
00862 double Item_sum_sum::val_real()
00863 {
00864   assert(fixed == 1);
00865   if (hybrid_type == DECIMAL_RESULT)
00866     class_decimal2double(E_DEC_FATAL_ERROR, dec_buffs + curr_dec_buff, &sum);
00867   return sum;
00868 }
00869 
00870 
00871 String *Item_sum_sum::val_str(String *str)
00872 {
00873   if (hybrid_type == DECIMAL_RESULT)
00874     return val_string_from_decimal(str);
00875   return val_string_from_real(str);
00876 }
00877 
00878 
00879 type::Decimal *Item_sum_sum::val_decimal(type::Decimal *val)
00880 {
00881   if (hybrid_type == DECIMAL_RESULT)
00882     return (dec_buffs + curr_dec_buff);
00883   return val_decimal_from_real(val);
00884 }
00885 
00886 /***************************************************************************/
00887 
00888 /* Declarations for auxilary C-callbacks */
00889 
00890 static int simple_raw_key_cmp(void* arg, const void* key1, const void* key2)
00891 {
00892     return memcmp(key1, key2, *(uint32_t *) arg);
00893 }
00894 
00895 
00896 static int item_sum_distinct_walk(void *element,
00897                                   uint32_t ,
00898                                   void *item)
00899 {
00900   return ((Item_sum_distinct*) (item))->unique_walk_function(element);
00901 }
00902 
00903 /* Item_sum_distinct */
00904 
00905 Item_sum_distinct::Item_sum_distinct(Item *item_arg)
00906   :Item_sum_num(item_arg), tree(0)
00907 {
00908   /*
00909     quick_group is an optimizer hint, which means that GROUP BY can be
00910     handled with help of index on grouped columns.
00911     By setting quick_group to zero we force creation of temporary table
00912     to perform GROUP BY.
00913   */
00914   quick_group= 0;
00915 }
00916 
00917 
00918 Item_sum_distinct::Item_sum_distinct(Session *session, Item_sum_distinct *original)
00919   :Item_sum_num(session, original), val(original->val), tree(0),
00920   table_field_type(original->table_field_type)
00921 {
00922   quick_group= 0;
00923 }
00924 
00925 
00933 struct Hybrid_type_traits_fast_decimal: public
00934        Hybrid_type_traits_integer
00935 {
00936   virtual Item_result type() const { return DECIMAL_RESULT; }
00937   virtual void fix_length_and_dec(Item *item, Item *arg) const
00938   { Hybrid_type_traits_decimal::instance()->fix_length_and_dec(item, arg); }
00939 
00940   virtual void div(Hybrid_type *val, uint64_t u) const
00941   {
00942     int2_class_decimal(E_DEC_FATAL_ERROR, val->integer, 0, val->dec_buf);
00943     val->used_dec_buf_no= 0;
00944     val->traits= Hybrid_type_traits_decimal::instance();
00945     val->traits->div(val, u);
00946   }
00947   static const Hybrid_type_traits_fast_decimal *instance();
00948   Hybrid_type_traits_fast_decimal() {};
00949 };
00950 
00951 static const Hybrid_type_traits_fast_decimal fast_decimal_traits_instance;
00952 
00953 const Hybrid_type_traits_fast_decimal
00954   *Hybrid_type_traits_fast_decimal::instance()
00955 {
00956   return &fast_decimal_traits_instance;
00957 }
00958 
00959 
00960 void Item_sum_distinct::fix_length_and_dec()
00961 {
00962   assert(args[0]->fixed);
00963 
00964   null_value= maybe_null= true;
00965   table_field_type= args[0]->field_type();
00966 
00967   /* Adjust tmp table type according to the chosen aggregation type */
00968   switch (args[0]->result_type()) {
00969   case STRING_RESULT:
00970   case REAL_RESULT:
00971     val.traits= Hybrid_type_traits::instance();
00972     table_field_type= DRIZZLE_TYPE_DOUBLE;
00973     break;
00974   case INT_RESULT:
00975     /*
00976       Preserving int8, int16, int32 field types gives ~10% performance boost
00977       as the size of result tree becomes significantly smaller.
00978       Another speed up we gain by using int64_t for intermediate
00979       calculations. The range of int64 is enough to hold sum 2^32 distinct
00980       integers each <= 2^32.
00981     */
00982     if (table_field_type == DRIZZLE_TYPE_LONG)
00983     {
00984       val.traits= Hybrid_type_traits_fast_decimal::instance();
00985       break;
00986     }
00987     table_field_type= DRIZZLE_TYPE_LONGLONG;
00988     /* fallthrough */
00989   case DECIMAL_RESULT:
00990     val.traits= Hybrid_type_traits_decimal::instance();
00991     if (table_field_type != DRIZZLE_TYPE_LONGLONG)
00992       table_field_type= DRIZZLE_TYPE_DECIMAL;
00993     break;
00994   case ROW_RESULT:
00995     assert(0);
00996   }
00997 
00998   val.traits->fix_length_and_dec(this, args[0]);
00999 }
01000 
01001 
01002 enum Item_result Item_sum_distinct::result_type () const
01003 {
01004   return val.traits->type();
01005 }
01006 
01007 
01012 bool Item_sum_distinct::setup(Session *session)
01013 {
01014   /* It's legal to call setup() more than once when in a subquery */
01015   if (tree)
01016     return false;
01017 
01018   /*
01019     Virtual table and the tree are created anew on each re-execution of
01020     PS/SP. Hence all further allocations are performed in the runtime
01021     mem.
01022   */
01023   null_value= maybe_null= 1;
01024   quick_group= 0;
01025 
01026   assert(args[0]->fixed);
01027 
01028   std::list<CreateField> field_list;
01029   field_list.push_back(CreateField());
01030   CreateField& field_def = field_list.back();
01031   field_def.init_for_tmp_table(table_field_type, args[0]->max_length, args[0]->decimals, args[0]->maybe_null);
01032   table= &session->getInstanceTable(field_list);
01033 
01034   /* XXX: check that the case of CHAR(0) works OK */
01035   tree_key_length= table->getShare()->getRecordLength() - table->getShare()->null_bytes;
01036 
01037   /*
01038     Unique handles all unique elements in a tree until they can't fit
01039     in.  Then the tree is dumped to the temporary file. We can use
01040     simple_raw_key_cmp because the table contains numbers only; decimals
01041     are converted to binary representation as well.
01042   */
01043   tree= new Unique(simple_raw_key_cmp, &tree_key_length, tree_key_length, (size_t)session->variables.max_heap_table_size);
01044   is_evaluated= false;
01045   return false;
01046 }
01047 
01048 bool Item_sum_distinct::add()
01049 {
01050   args[0]->save_in_field(table->getField(0), false);
01051   is_evaluated= false;
01052   if (!table->getField(0)->is_null())
01053   {
01054     assert(tree);
01055     null_value= 0;
01056     /*
01057       '0' values are also stored in the tree. This doesn't matter
01058       for SUM(DISTINCT), but is important for AVG(DISTINCT)
01059     */
01060     return tree->unique_add(table->getField(0)->ptr);
01061   }
01062   return 0;
01063 }
01064 
01065 
01066 bool Item_sum_distinct::unique_walk_function(void *element)
01067 {
01068   memcpy(table->getField(0)->ptr, element, tree_key_length);
01069   ++count;
01070   val.traits->add(&val, table->getField(0));
01071   return 0;
01072 }
01073 
01074 
01075 void Item_sum_distinct::clear()
01076 {
01077   assert(tree != 0);                        /* we always have a tree */
01078   null_value= 1;
01079   tree->reset();
01080   is_evaluated= false;
01081   return;
01082 }
01083 
01084 void Item_sum_distinct::cleanup()
01085 {
01086   Item_sum_num::cleanup();
01087   delete tree;
01088   tree= 0;
01089   table= 0;
01090   is_evaluated= false;
01091 }
01092 
01093 Item_sum_distinct::~Item_sum_distinct()
01094 {
01095   delete tree;
01096   /* no need to free the table */
01097 }
01098 
01099 
01100 void Item_sum_distinct::calculate_val_and_count()
01101 {
01102   if (!is_evaluated)
01103   {
01104     count= 0;
01105     val.traits->set_zero(&val);
01106     /*
01107       We don't have a tree only if 'setup()' hasn't been called;
01108       this is the case of sql_select.cc:return_zero_rows.
01109      */
01110     if (tree)
01111     {
01112       table->getField(0)->set_notnull();
01113       tree->walk(item_sum_distinct_walk, (void*) this);
01114     }
01115     is_evaluated= true;
01116   }
01117 }
01118 
01119 
01120 double Item_sum_distinct::val_real()
01121 {
01122   calculate_val_and_count();
01123   return val.traits->val_real(&val);
01124 }
01125 
01126 
01127 type::Decimal *Item_sum_distinct::val_decimal(type::Decimal *to)
01128 {
01129   calculate_val_and_count();
01130   if (null_value)
01131     return 0;
01132   return val.traits->val_decimal(&val, to);
01133 }
01134 
01135 
01136 int64_t Item_sum_distinct::val_int()
01137 {
01138   calculate_val_and_count();
01139   return val.traits->val_int(&val, unsigned_flag);
01140 }
01141 
01142 
01143 String *Item_sum_distinct::val_str(String *str)
01144 {
01145   calculate_val_and_count();
01146   if (null_value)
01147     return 0;
01148   return val.traits->val_str(&val, str, decimals);
01149 }
01150 
01151 /* end of Item_sum_distinct */
01152 
01153 /* Item_sum_avg_distinct */
01154 
01155 void
01156 Item_sum_avg_distinct::fix_length_and_dec()
01157 {
01158   Item_sum_distinct::fix_length_and_dec();
01159   prec_increment= getSession().variables.div_precincrement;
01160   /*
01161     AVG() will divide val by count. We need to reserve digits
01162     after decimal point as the result can be fractional.
01163   */
01164   decimals= min(decimals + prec_increment, (unsigned int)NOT_FIXED_DEC);
01165 }
01166 
01167 
01168 void
01169 Item_sum_avg_distinct::calculate_val_and_count()
01170 {
01171   if (!is_evaluated)
01172   {
01173     Item_sum_distinct::calculate_val_and_count();
01174     if (count)
01175       val.traits->div(&val, count);
01176     is_evaluated= true;
01177   }
01178 }
01179 
01180 
01181 Item *Item_sum_count::copy_or_same(Session* session)
01182 {
01183   return new (session->mem) Item_sum_count(session, this);
01184 }
01185 
01186 
01187 void Item_sum_count::clear()
01188 {
01189   count= 0;
01190 }
01191 
01192 
01193 bool Item_sum_count::add()
01194 {
01195   if (!args[0]->maybe_null || !args[0]->is_null())
01196     count++;
01197   return 0;
01198 }
01199 
01200 int64_t Item_sum_count::val_int()
01201 {
01202   assert(fixed == 1);
01203   return (int64_t) count;
01204 }
01205 
01206 
01207 void Item_sum_count::cleanup()
01208 {
01209   count= 0;
01210   Item_sum_int::cleanup();
01211   return;
01212 }
01213 
01214 
01215 /*
01216   Avgerage
01217 */
01218 void Item_sum_avg::fix_length_and_dec()
01219 {
01220   Item_sum_sum::fix_length_and_dec();
01221   maybe_null=null_value=1;
01222   prec_increment= getSession().variables.div_precincrement;
01223 
01224   if (hybrid_type == DECIMAL_RESULT)
01225   {
01226     int precision= args[0]->decimal_precision() + prec_increment;
01227     decimals= min(args[0]->decimals + prec_increment, (unsigned int) DECIMAL_MAX_SCALE);
01228     max_length= class_decimal_precision_to_length(precision, decimals,
01229                                                unsigned_flag);
01230     f_precision= min(precision+DECIMAL_LONGLONG_DIGITS, DECIMAL_MAX_PRECISION);
01231     f_scale=  args[0]->decimals;
01232     dec_bin_size= class_decimal_get_binary_size(f_precision, f_scale);
01233   }
01234   else {
01235     decimals= min(args[0]->decimals + prec_increment, (unsigned int) NOT_FIXED_DEC);
01236     max_length= args[0]->max_length + prec_increment;
01237   }
01238 }
01239 
01240 
01241 Item *Item_sum_avg::copy_or_same(Session* session)
01242 {
01243   return new (session->mem) Item_sum_avg(session, this);
01244 }
01245 
01246 
01247 Field *Item_sum_avg::create_tmp_field(bool group, Table *table,
01248                                       uint32_t )
01249 {
01250   Field *field;
01251   if (group)
01252   {
01253     /*
01254       We must store both value and counter in the temporary table in one field.
01255       The easiest way is to do this is to store both value in a string
01256       and unpack on access.
01257     */
01258     table->setVariableWidth();
01259     field= new Field_varstring(((hybrid_type == DECIMAL_RESULT) ?
01260                                 dec_bin_size : sizeof(double)) + sizeof(int64_t),
01261                                0, name, &my_charset_bin);
01262   }
01263   else if (hybrid_type == DECIMAL_RESULT)
01264     field= new Field_decimal(max_length, maybe_null, name,
01265                              decimals, unsigned_flag);
01266   else
01267     field= new Field_double(max_length, maybe_null, name, decimals, true);
01268   if (field)
01269     field->init(table);
01270   return field;
01271 }
01272 
01273 
01274 void Item_sum_avg::clear()
01275 {
01276   Item_sum_sum::clear();
01277   count=0;
01278 }
01279 
01280 
01281 bool Item_sum_avg::add()
01282 {
01283   if (Item_sum_sum::add())
01284     return true;
01285   if (!args[0]->null_value)
01286     count++;
01287   return false;
01288 }
01289 
01290 double Item_sum_avg::val_real()
01291 {
01292   assert(fixed == 1);
01293   if (!count)
01294   {
01295     null_value=1;
01296     return 0.0;
01297   }
01298   return Item_sum_sum::val_real() / uint64_t2double(count);
01299 }
01300 
01301 
01302 int64_t Item_sum_avg::val_int()
01303 {
01304   return (int64_t) rint(val_real());
01305 }
01306 
01307 
01308 type::Decimal *Item_sum_avg::val_decimal(type::Decimal *val)
01309 {
01310   type::Decimal sum_buff, cnt;
01311   const type::Decimal *sum_dec;
01312   assert(fixed == 1);
01313   if (!count)
01314   {
01315     null_value=1;
01316     return NULL;
01317   }
01318 
01319   /*
01320     For non-DECIMAL hybrid_type the division will be done in
01321     Item_sum_avg::val_real().
01322   */
01323   if (hybrid_type != DECIMAL_RESULT)
01324     return val_decimal_from_real(val);
01325 
01326   sum_dec= dec_buffs + curr_dec_buff;
01327   int2_class_decimal(E_DEC_FATAL_ERROR, count, 0, &cnt);
01328   class_decimal_div(E_DEC_FATAL_ERROR, val, sum_dec, &cnt, prec_increment);
01329   return val;
01330 }
01331 
01332 
01333 String *Item_sum_avg::val_str(String *str)
01334 {
01335   if (hybrid_type == DECIMAL_RESULT)
01336     return val_string_from_decimal(str);
01337   return val_string_from_real(str);
01338 }
01339 
01340 
01341 /*
01342   Standard deviation
01343 */
01344 
01345 double Item_sum_std::val_real()
01346 {
01347   assert(fixed == 1);
01348   double nr= Item_sum_variance::val_real();
01349   assert(nr >= 0.0);
01350   return sqrt(nr);
01351 }
01352 
01353 Item *Item_sum_std::copy_or_same(Session* session)
01354 {
01355   return new (session->mem) Item_sum_std(session, this);
01356 }
01357 
01358 
01359 /*
01360   Variance
01361 */
01362 
01363 
01370 /*
01371   These two functions are used by the Item_sum_variance and the
01372   Item_variance_field classes, which are unrelated, and each need to calculate
01373   variance.  The difference between the two classes is that the first is used
01374   for a mundane SELECT, while the latter is used in a GROUPing SELECT.
01375 */
01376 static void variance_fp_recurrence_next(double *m, double *s, uint64_t *count, double nr)
01377 {
01378   *count += 1;
01379 
01380   if (*count == 1)
01381   {
01382     *m= nr;
01383     *s= 0;
01384   }
01385   else
01386   {
01387     double m_kminusone= *m;
01388     *m= m_kminusone + (nr - m_kminusone) / (double) *count;
01389     *s= *s + (nr - m_kminusone) * (nr - *m);
01390   }
01391 }
01392 
01393 
01394 static double variance_fp_recurrence_result(double s, uint64_t count, bool is_sample_variance)
01395 {
01396   if (count == 1)
01397     return 0.0;
01398 
01399   if (is_sample_variance)
01400     return s / (count - 1);
01401 
01402   /* else, is a population variance */
01403   return s / count;
01404 }
01405 
01406 
01407 Item_sum_variance::Item_sum_variance(Session *session, Item_sum_variance *item):
01408   Item_sum_num(session, item), hybrid_type(item->hybrid_type),
01409     count(item->count), sample(item->sample),
01410     prec_increment(item->prec_increment)
01411 {
01412   recurrence_m= item->recurrence_m;
01413   recurrence_s= item->recurrence_s;
01414 }
01415 
01416 
01417 void Item_sum_variance::fix_length_and_dec()
01418 {
01419   maybe_null= null_value= 1;
01420   prec_increment= getSession().variables.div_precincrement;
01421 
01422   /*
01423     According to the SQL2003 standard (Part 2, Foundations; sec 10.9,
01424     aggregate function; paragraph 7h of Syntax Rules), "the declared
01425     type of the result is an implementation-defined aproximate numeric
01426     type.
01427   */
01428   hybrid_type= REAL_RESULT;
01429 
01430   switch (args[0]->result_type()) {
01431   case REAL_RESULT:
01432   case STRING_RESULT:
01433     decimals= min(args[0]->decimals + 4, (int)NOT_FIXED_DEC);
01434     break;
01435   case INT_RESULT:
01436   case DECIMAL_RESULT:
01437     {
01438       int precision= args[0]->decimal_precision()*2 + prec_increment;
01439       decimals= min(args[0]->decimals + prec_increment, (unsigned int) DECIMAL_MAX_SCALE);
01440       max_length= class_decimal_precision_to_length(precision, decimals,
01441                                                  unsigned_flag);
01442 
01443       break;
01444     }
01445   case ROW_RESULT:
01446     assert(0);
01447   }
01448 }
01449 
01450 
01451 Item *Item_sum_variance::copy_or_same(Session* session)
01452 {
01453   return new (session->mem) Item_sum_variance(session, this);
01454 }
01455 
01456 
01462 Field *Item_sum_variance::create_tmp_field(bool group, Table *table,
01463                                            uint32_t )
01464 {
01465   Field *field;
01466   if (group)
01467   {
01468     /*
01469       We must store both value and counter in the temporary table in one field.
01470       The easiest way is to do this is to store both value in a string
01471       and unpack on access.
01472     */
01473     table->setVariableWidth();
01474     field= new Field_varstring(sizeof(double)*2 + sizeof(int64_t), 0, name, &my_charset_bin);
01475   }
01476   else
01477     field= new Field_double(max_length, maybe_null, name, decimals, true);
01478 
01479   if (field != NULL)
01480     field->init(table);
01481 
01482   return field;
01483 }
01484 
01485 
01486 void Item_sum_variance::clear()
01487 {
01488   count= 0;
01489 }
01490 
01491 bool Item_sum_variance::add()
01492 {
01493   /*
01494     Why use a temporary variable?  We don't know if it is null until we
01495     evaluate it, which has the side-effect of setting null_value .
01496   */
01497   double nr= args[0]->val_real();
01498 
01499   if (!args[0]->null_value)
01500     variance_fp_recurrence_next(&recurrence_m, &recurrence_s, &count, nr);
01501   return 0;
01502 }
01503 
01504 double Item_sum_variance::val_real()
01505 {
01506   assert(fixed == 1);
01507 
01508   /*
01509     'sample' is a 1/0 boolean value.  If it is 1/true, id est this is a sample
01510     variance call, then we should set nullness when the count of the items
01511     is one or zero.  If it's zero, i.e. a population variance, then we only
01512     set nullness when the count is zero.
01513 
01514     Another way to read it is that 'sample' is the numerical threshhold, at and
01515     below which a 'count' number of items is called NULL.
01516   */
01517   assert((sample == 0) || (sample == 1));
01518   if (count <= sample)
01519   {
01520     null_value=1;
01521     return 0.0;
01522   }
01523 
01524   null_value=0;
01525   return variance_fp_recurrence_result(recurrence_s, count, sample);
01526 }
01527 
01528 
01529 int64_t Item_sum_variance::val_int()
01530 {
01531   /* can't be fix_fields()ed */
01532   return (int64_t) rint(val_real());
01533 }
01534 
01535 
01536 type::Decimal *Item_sum_variance::val_decimal(type::Decimal *dec_buf)
01537 {
01538   assert(fixed == 1);
01539   return val_decimal_from_real(dec_buf);
01540 }
01541 
01542 
01543 void Item_sum_variance::reset_field()
01544 {
01545   double nr;
01546   unsigned char *res= result_field->ptr;
01547 
01548   nr= args[0]->val_real();              /* sets null_value as side-effect */
01549 
01550   if (args[0]->null_value)
01551     memset(res, 0, sizeof(double)*2+sizeof(int64_t));
01552   else
01553   {
01554     /* Serialize format is (double)m, (double)s, (int64_t)count */
01555     uint64_t tmp_count;
01556     double tmp_s;
01557     float8store(res, nr);               /* recurrence variable m */
01558     tmp_s= 0.0;
01559     float8store(res + sizeof(double), tmp_s);
01560     tmp_count= 1;
01561     int8store(res + sizeof(double)*2, tmp_count);
01562   }
01563 }
01564 
01565 
01566 void Item_sum_variance::update_field()
01567 {
01568   uint64_t field_count;
01569   unsigned char *res=result_field->ptr;
01570 
01571   double nr= args[0]->val_real();       /* sets null_value as side-effect */
01572 
01573   if (args[0]->null_value)
01574     return;
01575 
01576   /* Serialize format is (double)m, (double)s, (int64_t)count */
01577   double field_recurrence_m, field_recurrence_s;
01578   float8get(field_recurrence_m, res);
01579   float8get(field_recurrence_s, res + sizeof(double));
01580   field_count=sint8korr(res+sizeof(double)*2);
01581 
01582   variance_fp_recurrence_next(&field_recurrence_m, &field_recurrence_s, &field_count, nr);
01583 
01584   float8store(res, field_recurrence_m);
01585   float8store(res + sizeof(double), field_recurrence_s);
01586   res+= sizeof(double)*2;
01587   int8store(res,field_count);
01588 }
01589 
01590 
01591 /* min & max */
01592 
01593 void Item_sum_hybrid::clear()
01594 {
01595   switch (hybrid_type) {
01596   case INT_RESULT:
01597     sum_int= 0;
01598     break;
01599   case DECIMAL_RESULT:
01600     sum_dec.set_zero();
01601     break;
01602   case REAL_RESULT:
01603     sum= 0.0;
01604     break;
01605   default:
01606     value.length(0);
01607   }
01608   null_value= 1;
01609 }
01610 
01611 double Item_sum_hybrid::val_real()
01612 {
01613   assert(fixed == 1);
01614   if (null_value)
01615     return 0.0;
01616 
01617   switch (hybrid_type) {
01618   case STRING_RESULT:
01619     {
01620       char *end_not_used;
01621       int err_not_used;
01622       String *res;  res=val_str(&str_value);
01623       return (res ? my_strntod(res->charset(), (char*) res->ptr(), res->length(),
01624                                &end_not_used, &err_not_used) : 0.0);
01625     }
01626   case INT_RESULT:
01627     return (double) sum_int;
01628   case DECIMAL_RESULT:
01629     class_decimal2double(E_DEC_FATAL_ERROR, &sum_dec, &sum);
01630     return sum;
01631   case REAL_RESULT:
01632     return sum;
01633   case ROW_RESULT:
01634     // This case should never be choosen
01635     break;
01636   }
01637 
01638   assert(0);
01639   return 0;
01640 }
01641 
01642 int64_t Item_sum_hybrid::val_int()
01643 {
01644   assert(fixed == 1);
01645   if (null_value)
01646     return 0;
01647   switch (hybrid_type) {
01648   case INT_RESULT:
01649     return sum_int;
01650   case DECIMAL_RESULT:
01651   {
01652     int64_t result;
01653     sum_dec.val_int32(E_DEC_FATAL_ERROR, unsigned_flag, &result);
01654     return sum_int;
01655   }
01656   default:
01657     return (int64_t) rint(Item_sum_hybrid::val_real());
01658   }
01659 }
01660 
01661 
01662 type::Decimal *Item_sum_hybrid::val_decimal(type::Decimal *val)
01663 {
01664   assert(fixed == 1);
01665   if (null_value)
01666     return 0;
01667 
01668   switch (hybrid_type) {
01669   case STRING_RESULT:
01670     val->store(E_DEC_FATAL_ERROR, &value);
01671     break;
01672   case REAL_RESULT:
01673     double2_class_decimal(E_DEC_FATAL_ERROR, sum, val);
01674     break;
01675   case DECIMAL_RESULT:
01676     val= &sum_dec;
01677     break;
01678   case INT_RESULT:
01679     int2_class_decimal(E_DEC_FATAL_ERROR, sum_int, unsigned_flag, val);
01680     break;
01681   case ROW_RESULT:
01682     // This case should never be choosen
01683     assert(0);
01684     break;
01685   }
01686 
01687   return val;         // Keep compiler happy
01688 }
01689 
01690 
01691 String *
01692 Item_sum_hybrid::val_str(String *str)
01693 {
01694   assert(fixed == 1);
01695   if (null_value)
01696     return 0;
01697 
01698   switch (hybrid_type) {
01699   case STRING_RESULT:
01700     return &value;
01701   case REAL_RESULT:
01702     str->set_real(sum,decimals, &my_charset_bin);
01703     break;
01704   case DECIMAL_RESULT:
01705     class_decimal2string(&sum_dec, 0, str);
01706     return str;
01707   case INT_RESULT:
01708     str->set_int(sum_int, unsigned_flag, &my_charset_bin);
01709     break;
01710   case ROW_RESULT:
01711   default:
01712     // This case should never be choosen
01713     break;
01714   }
01715 
01716   return str;         // Keep compiler happy
01717 }
01718 
01719 
01720 void Item_sum_hybrid::cleanup()
01721 {
01722   Item_sum::cleanup();
01723   forced_const= false;
01724 
01725   /*
01726     by default it is TRUE to avoid TRUE reporting by
01727     Item_func_not_all/Item_func_nop_all if this item was never called.
01728 
01729     no_rows_in_result() set it to FALSE if was not results found.
01730     If some results found it will be left unchanged.
01731   */
01732   was_values= true;
01733   return;
01734 }
01735 
01736 void Item_sum_hybrid::no_rows_in_result()
01737 {
01738   was_values= false;
01739   clear();
01740 }
01741 
01742 
01743 Item *Item_sum_min::copy_or_same(Session* session)
01744 {
01745   return new (session->mem) Item_sum_min(session, this);
01746 }
01747 
01748 
01749 bool Item_sum_min::add()
01750 {
01751   switch (hybrid_type) {
01752   case STRING_RESULT:
01753     {
01754       String *result=args[0]->val_str(&tmp_value);
01755       if (!args[0]->null_value &&
01756           (null_value || sortcmp(&value,result,collation.collation) > 0))
01757       {
01758         value.copy(*result);
01759         null_value=0;
01760       }
01761     }
01762     break;
01763   case INT_RESULT:
01764     {
01765       int64_t nr=args[0]->val_int();
01766       if (!args[0]->null_value && (null_value ||
01767                                    (unsigned_flag &&
01768                                     (uint64_t) nr < (uint64_t) sum_int) ||
01769                                    (!unsigned_flag && nr < sum_int)))
01770       {
01771         sum_int=nr;
01772         null_value=0;
01773       }
01774     }
01775     break;
01776   case DECIMAL_RESULT:
01777     {
01778       type::Decimal value_buff, *val= args[0]->val_decimal(&value_buff);
01779       if (!args[0]->null_value &&
01780           (null_value || (class_decimal_cmp(&sum_dec, val) > 0)))
01781       {
01782         class_decimal2decimal(val, &sum_dec);
01783         null_value= 0;
01784       }
01785     }
01786     break;
01787   case REAL_RESULT:
01788     {
01789       double nr= args[0]->val_real();
01790       if (!args[0]->null_value && (null_value || nr < sum))
01791       {
01792         sum=nr;
01793         null_value=0;
01794       }
01795     }
01796     break;
01797   case ROW_RESULT:
01798     // This case should never be choosen
01799     assert(0);
01800     break;
01801   }
01802   return 0;
01803 }
01804 
01805 
01806 Item *Item_sum_max::copy_or_same(Session* session)
01807 {
01808   return new (session->mem) Item_sum_max(session, this);
01809 }
01810 
01811 
01812 bool Item_sum_max::add()
01813 {
01814   switch (hybrid_type) {
01815   case STRING_RESULT:
01816     {
01817       String *result=args[0]->val_str(&tmp_value);
01818       if (!args[0]->null_value &&
01819           (null_value || sortcmp(&value,result,collation.collation) < 0))
01820       {
01821         value.copy(*result);
01822         null_value=0;
01823       }
01824     }
01825     break;
01826   case INT_RESULT:
01827     {
01828       int64_t nr=args[0]->val_int();
01829       if (!args[0]->null_value && (null_value ||
01830                                    (unsigned_flag &&
01831                                     (uint64_t) nr > (uint64_t) sum_int) ||
01832                                    (!unsigned_flag && nr > sum_int)))
01833       {
01834         sum_int=nr;
01835         null_value=0;
01836       }
01837     }
01838     break;
01839   case DECIMAL_RESULT:
01840     {
01841       type::Decimal value_buff, *val= args[0]->val_decimal(&value_buff);
01842       if (!args[0]->null_value &&
01843           (null_value || (class_decimal_cmp(val, &sum_dec) > 0)))
01844       {
01845         class_decimal2decimal(val, &sum_dec);
01846         null_value= 0;
01847       }
01848     }
01849     break;
01850   case REAL_RESULT:
01851     {
01852       double nr= args[0]->val_real();
01853       if (!args[0]->null_value && (null_value || nr > sum))
01854       {
01855         sum=nr;
01856         null_value=0;
01857       }
01858     }
01859     break;
01860   case ROW_RESULT:
01861     // This case should never be choosen
01862     assert(0);
01863     break;
01864   }
01865 
01866   return 0;
01867 }
01868 
01869 
01870 /* bit_or and bit_and */
01871 
01872 int64_t Item_sum_bit::val_int()
01873 {
01874   assert(fixed == 1);
01875   return (int64_t) bits;
01876 }
01877 
01878 
01879 void Item_sum_bit::clear()
01880 {
01881   bits= reset_bits;
01882 }
01883 
01884 Item *Item_sum_or::copy_or_same(Session* session)
01885 {
01886   return new (session->mem) Item_sum_or(session, this);
01887 }
01888 
01889 
01890 bool Item_sum_or::add()
01891 {
01892   uint64_t value= (uint64_t) args[0]->val_int();
01893   if (!args[0]->null_value)
01894     bits|=value;
01895   return 0;
01896 }
01897 
01898 Item *Item_sum_xor::copy_or_same(Session* session)
01899 {
01900   return new (session->mem) Item_sum_xor(session, this);
01901 }
01902 
01903 
01904 bool Item_sum_xor::add()
01905 {
01906   uint64_t value= (uint64_t) args[0]->val_int();
01907   if (!args[0]->null_value)
01908     bits^=value;
01909   return 0;
01910 }
01911 
01912 Item *Item_sum_and::copy_or_same(Session* session)
01913 {
01914   return new (session->mem) Item_sum_and(session, this);
01915 }
01916 
01917 
01918 bool Item_sum_and::add()
01919 {
01920   uint64_t value= (uint64_t) args[0]->val_int();
01921   if (!args[0]->null_value)
01922     bits&=value;
01923   return 0;
01924 }
01925 
01926 /************************************************************************
01927 ** reset result of a Item_sum with is saved in a tmp_table
01928 *************************************************************************/
01929 
01930 void Item_sum_num::reset_field()
01931 {
01932   double nr= args[0]->val_real();
01933   unsigned char *res=result_field->ptr;
01934 
01935   if (maybe_null)
01936   {
01937     if (args[0]->null_value)
01938     {
01939       nr=0.0;
01940       result_field->set_null();
01941     }
01942     else
01943       result_field->set_notnull();
01944   }
01945   float8store(res,nr);
01946 }
01947 
01948 
01949 void Item_sum_hybrid::reset_field()
01950 {
01951   switch(hybrid_type) {
01952   case STRING_RESULT:
01953     {
01954       char buff[MAX_FIELD_WIDTH];
01955       String tmp(buff,sizeof(buff),result_field->charset()),*res;
01956 
01957       res=args[0]->val_str(&tmp);
01958       if (args[0]->null_value)
01959       {
01960         result_field->set_null();
01961         result_field->reset();
01962       }
01963       else
01964       {
01965         result_field->set_notnull();
01966         result_field->store(res->ptr(),res->length(),tmp.charset());
01967       }
01968       break;
01969     }
01970   case INT_RESULT:
01971     {
01972       int64_t nr=args[0]->val_int();
01973 
01974       if (maybe_null)
01975       {
01976         if (args[0]->null_value)
01977         {
01978           nr=0;
01979           result_field->set_null();
01980         }
01981         else
01982           result_field->set_notnull();
01983       }
01984       result_field->store(nr, unsigned_flag);
01985       break;
01986     }
01987   case REAL_RESULT:
01988     {
01989       double nr= args[0]->val_real();
01990 
01991       if (maybe_null)
01992       {
01993         if (args[0]->null_value)
01994         {
01995           nr=0.0;
01996           result_field->set_null();
01997         }
01998         else
01999           result_field->set_notnull();
02000       }
02001       result_field->store(nr);
02002       break;
02003     }
02004   case DECIMAL_RESULT:
02005     {
02006       type::Decimal value_buff, *arg_dec= args[0]->val_decimal(&value_buff);
02007 
02008       if (maybe_null)
02009       {
02010         if (args[0]->null_value)
02011           result_field->set_null();
02012         else
02013           result_field->set_notnull();
02014       }
02015       /*
02016         We must store zero in the field as we will use the field value in
02017         add()
02018       */
02019       if (!arg_dec)                               // Null
02020         arg_dec= &decimal_zero;
02021       result_field->store_decimal(arg_dec);
02022       break;
02023     }
02024   case ROW_RESULT:
02025     assert(0);
02026   }
02027 }
02028 
02029 
02030 void Item_sum_sum::reset_field()
02031 {
02032   if (hybrid_type == DECIMAL_RESULT)
02033   {
02034     type::Decimal value, *arg_val= args[0]->val_decimal(&value);
02035     if (!arg_val)                               // Null
02036       arg_val= &decimal_zero;
02037     result_field->store_decimal(arg_val);
02038   }
02039   else
02040   {
02041     assert(hybrid_type == REAL_RESULT);
02042     double nr= args[0]->val_real();     // Nulls also return 0
02043     float8store(result_field->ptr, nr);
02044   }
02045   if (args[0]->null_value)
02046     result_field->set_null();
02047   else
02048     result_field->set_notnull();
02049 }
02050 
02051 
02052 void Item_sum_count::reset_field()
02053 {
02054   unsigned char *res=result_field->ptr;
02055   int64_t nr=0;
02056 
02057   if (!args[0]->maybe_null || !args[0]->is_null())
02058     nr=1;
02059   int8store(res,nr);
02060 }
02061 
02062 
02063 void Item_sum_avg::reset_field()
02064 {
02065   unsigned char *res=result_field->ptr;
02066   if (hybrid_type == DECIMAL_RESULT)
02067   {
02068     int64_t tmp;
02069     type::Decimal value, *arg_dec= args[0]->val_decimal(&value);
02070     if (args[0]->null_value)
02071     {
02072       arg_dec= &decimal_zero;
02073       tmp= 0;
02074     }
02075     else
02076       tmp= 1;
02077     arg_dec->val_binary(E_DEC_FATAL_ERROR, res, f_precision, f_scale);
02078     res+= dec_bin_size;
02079     int8store(res, tmp);
02080   }
02081   else
02082   {
02083     double nr= args[0]->val_real();
02084 
02085     if (args[0]->null_value)
02086       memset(res, 0, sizeof(double)+sizeof(int64_t));
02087     else
02088     {
02089       int64_t tmp= 1;
02090       float8store(res,nr);
02091       res+=sizeof(double);
02092       int8store(res,tmp);
02093     }
02094   }
02095 }
02096 
02097 
02098 void Item_sum_bit::reset_field()
02099 {
02100   reset();
02101   int8store(result_field->ptr, bits);
02102 }
02103 
02104 void Item_sum_bit::update_field()
02105 {
02106   unsigned char *res=result_field->ptr;
02107   bits= uint8korr(res);
02108   add();
02109   int8store(res, bits);
02110 }
02111 
02112 
02117 void Item_sum_sum::update_field()
02118 {
02119   if (hybrid_type == DECIMAL_RESULT)
02120   {
02121     type::Decimal value, *arg_val= args[0]->val_decimal(&value);
02122     if (!args[0]->null_value)
02123     {
02124       if (!result_field->is_null())
02125       {
02126         type::Decimal field_value,
02127                    *field_val= result_field->val_decimal(&field_value);
02128         class_decimal_add(E_DEC_FATAL_ERROR, dec_buffs, arg_val, field_val);
02129         result_field->store_decimal(dec_buffs);
02130       }
02131       else
02132       {
02133         result_field->store_decimal(arg_val);
02134         result_field->set_notnull();
02135       }
02136     }
02137   }
02138   else
02139   {
02140     double old_nr,nr;
02141     unsigned char *res=result_field->ptr;
02142 
02143     float8get(old_nr,res);
02144     nr= args[0]->val_real();
02145     if (!args[0]->null_value)
02146     {
02147       old_nr+=nr;
02148       result_field->set_notnull();
02149     }
02150     float8store(res,old_nr);
02151   }
02152 }
02153 
02154 
02155 void Item_sum_count::update_field()
02156 {
02157   int64_t nr;
02158   unsigned char *res=result_field->ptr;
02159 
02160   nr=sint8korr(res);
02161   if (!args[0]->maybe_null || !args[0]->is_null())
02162     nr++;
02163   int8store(res,nr);
02164 }
02165 
02166 
02167 void Item_sum_avg::update_field()
02168 {
02169   int64_t field_count;
02170   unsigned char *res=result_field->ptr;
02171   if (hybrid_type == DECIMAL_RESULT)
02172   {
02173     type::Decimal value, *arg_val= args[0]->val_decimal(&value);
02174     if (!args[0]->null_value)
02175     {
02176       binary2_class_decimal(E_DEC_FATAL_ERROR, res,
02177                         dec_buffs + 1, f_precision, f_scale);
02178       field_count= sint8korr(res + dec_bin_size);
02179       class_decimal_add(E_DEC_FATAL_ERROR, dec_buffs, arg_val, dec_buffs + 1);
02180       dec_buffs->val_binary(E_DEC_FATAL_ERROR, res, f_precision, f_scale);
02181       res+= dec_bin_size;
02182       field_count++;
02183       int8store(res, field_count);
02184     }
02185   }
02186   else
02187   {
02188     double nr;
02189 
02190     nr= args[0]->val_real();
02191     if (!args[0]->null_value)
02192     {
02193       double old_nr;
02194       float8get(old_nr, res);
02195       field_count= sint8korr(res + sizeof(double));
02196       old_nr+= nr;
02197       float8store(res,old_nr);
02198       res+= sizeof(double);
02199       field_count++;
02200       int8store(res, field_count);
02201     }
02202   }
02203 }
02204 
02205 
02206 void Item_sum_hybrid::update_field()
02207 {
02208   switch (hybrid_type) {
02209   case STRING_RESULT:
02210     min_max_update_str_field();
02211     break;
02212   case INT_RESULT:
02213     min_max_update_int_field();
02214     break;
02215   case DECIMAL_RESULT:
02216     min_max_update_decimal_field();
02217     break;
02218   case REAL_RESULT:
02219   case ROW_RESULT:
02220     min_max_update_real_field();
02221   }
02222 }
02223 
02224 
02225 void
02226 Item_sum_hybrid::min_max_update_str_field()
02227 {
02228   String *res_str=args[0]->val_str(&value);
02229 
02230   if (!args[0]->null_value)
02231   {
02232     result_field->val_str_internal(&tmp_value);
02233 
02234     if (result_field->is_null() ||
02235   (cmp_sign * sortcmp(res_str,&tmp_value,collation.collation)) < 0)
02236       result_field->store(res_str->ptr(),res_str->length(),res_str->charset());
02237     result_field->set_notnull();
02238   }
02239 }
02240 
02241 
02242 void
02243 Item_sum_hybrid::min_max_update_real_field()
02244 {
02245   double nr,old_nr;
02246 
02247   old_nr=result_field->val_real();
02248   nr= args[0]->val_real();
02249   if (!args[0]->null_value)
02250   {
02251     if (result_field->is_null(0) ||
02252   (cmp_sign > 0 ? old_nr > nr : old_nr < nr))
02253       old_nr=nr;
02254     result_field->set_notnull();
02255   }
02256   else if (result_field->is_null(0))
02257     result_field->set_null();
02258   result_field->store(old_nr);
02259 }
02260 
02261 
02262 void
02263 Item_sum_hybrid::min_max_update_int_field()
02264 {
02265   int64_t nr,old_nr;
02266 
02267   old_nr=result_field->val_int();
02268   nr=args[0]->val_int();
02269   if (!args[0]->null_value)
02270   {
02271     if (result_field->is_null(0))
02272       old_nr=nr;
02273     else
02274     {
02275       bool res=(unsigned_flag ?
02276     (uint64_t) old_nr > (uint64_t) nr :
02277     old_nr > nr);
02278       /* (cmp_sign > 0 && res) || (!(cmp_sign > 0) && !res) */
02279       if ((cmp_sign > 0) ^ (!res))
02280   old_nr=nr;
02281     }
02282     result_field->set_notnull();
02283   }
02284   else if (result_field->is_null(0))
02285     result_field->set_null();
02286   result_field->store(old_nr, unsigned_flag);
02287 }
02288 
02289 
02294 void
02295 Item_sum_hybrid::min_max_update_decimal_field()
02296 {
02297   /* TODO: optimize: do not get result_field in case of args[0] is NULL */
02298   type::Decimal old_val, nr_val;
02299   const type::Decimal *old_nr= result_field->val_decimal(&old_val);
02300   const type::Decimal *nr= args[0]->val_decimal(&nr_val);
02301   if (!args[0]->null_value)
02302   {
02303     if (result_field->is_null(0))
02304       old_nr=nr;
02305     else
02306     {
02307       bool res= class_decimal_cmp(old_nr, nr) > 0;
02308       /* (cmp_sign > 0 && res) || (!(cmp_sign > 0) && !res) */
02309       if ((cmp_sign > 0) ^ (!res))
02310         old_nr=nr;
02311     }
02312     result_field->set_notnull();
02313   }
02314   else if (result_field->is_null(0))
02315     result_field->set_null();
02316   result_field->store_decimal(old_nr);
02317 }
02318 
02319 
02320 Item_avg_field::Item_avg_field(Item_result res_type, Item_sum_avg *item)
02321 {
02322   name=item->name;
02323   decimals=item->decimals;
02324   max_length= item->max_length;
02325   unsigned_flag= item->unsigned_flag;
02326   field=item->result_field;
02327   maybe_null=1;
02328   hybrid_type= res_type;
02329   prec_increment= item->prec_increment;
02330   if (hybrid_type == DECIMAL_RESULT)
02331   {
02332     f_scale= item->f_scale;
02333     f_precision= item->f_precision;
02334     dec_bin_size= item->dec_bin_size;
02335   }
02336 }
02337 
02338 double Item_avg_field::val_real()
02339 {
02340   // fix_fields() never calls for this Item
02341   double nr;
02342   int64_t count;
02343   unsigned char *res;
02344 
02345   if (hybrid_type == DECIMAL_RESULT)
02346     return val_real_from_decimal();
02347 
02348   float8get(nr,field->ptr);
02349   res= (field->ptr+sizeof(double));
02350   count= sint8korr(res);
02351 
02352   if ((null_value= !count))
02353     return 0.0;
02354   return nr/(double) count;
02355 }
02356 
02357 
02358 int64_t Item_avg_field::val_int()
02359 {
02360   return (int64_t) rint(val_real());
02361 }
02362 
02363 
02364 type::Decimal *Item_avg_field::val_decimal(type::Decimal *dec_buf)
02365 {
02366   // fix_fields() never calls for this Item
02367   if (hybrid_type == REAL_RESULT)
02368     return val_decimal_from_real(dec_buf);
02369 
02370   int64_t count= sint8korr(field->ptr + dec_bin_size);
02371   if ((null_value= !count))
02372     return 0;
02373 
02374   type::Decimal dec_count, dec_field;
02375   binary2_class_decimal(E_DEC_FATAL_ERROR,
02376                     field->ptr, &dec_field, f_precision, f_scale);
02377   int2_class_decimal(E_DEC_FATAL_ERROR, count, 0, &dec_count);
02378   class_decimal_div(E_DEC_FATAL_ERROR, dec_buf,
02379                  &dec_field, &dec_count, prec_increment);
02380   return dec_buf;
02381 }
02382 
02383 
02384 String *Item_avg_field::val_str(String *str)
02385 {
02386   // fix_fields() never calls for this Item
02387   if (hybrid_type == DECIMAL_RESULT)
02388     return val_string_from_decimal(str);
02389   return val_string_from_real(str);
02390 }
02391 
02392 
02393 Item_std_field::Item_std_field(Item_sum_std *item)
02394   : Item_variance_field(item)
02395 {
02396 }
02397 
02398 
02399 double Item_std_field::val_real()
02400 {
02401   double nr;
02402   // fix_fields() never calls for this Item
02403   nr= Item_variance_field::val_real();
02404   assert(nr >= 0.0);
02405   return sqrt(nr);
02406 }
02407 
02408 
02409 type::Decimal *Item_std_field::val_decimal(type::Decimal *dec_buf)
02410 {
02411   /*
02412     We can't call val_decimal_from_real() for DECIMAL_RESULT as
02413     Item_variance_field::val_real() would cause an infinite loop
02414   */
02415   type::Decimal tmp_dec, *dec;
02416   double nr;
02417   if (hybrid_type == REAL_RESULT)
02418     return val_decimal_from_real(dec_buf);
02419 
02420   dec= Item_variance_field::val_decimal(dec_buf);
02421   if (!dec)
02422     return 0;
02423   class_decimal2double(E_DEC_FATAL_ERROR, dec, &nr);
02424   assert(nr >= 0.0);
02425   nr= sqrt(nr);
02426   double2_class_decimal(E_DEC_FATAL_ERROR, nr, &tmp_dec);
02427   class_decimal_round(E_DEC_FATAL_ERROR, &tmp_dec, decimals, false, dec_buf);
02428   return dec_buf;
02429 }
02430 
02431 
02432 Item_variance_field::Item_variance_field(Item_sum_variance *item)
02433 {
02434   name=item->name;
02435   decimals=item->decimals;
02436   max_length=item->max_length;
02437   unsigned_flag= item->unsigned_flag;
02438   field=item->result_field;
02439   maybe_null=1;
02440   sample= item->sample;
02441   prec_increment= item->prec_increment;
02442   if ((hybrid_type= item->hybrid_type) == DECIMAL_RESULT)
02443   {
02444     f_scale0= item->f_scale0;
02445     f_precision0= item->f_precision0;
02446     dec_bin_size0= item->dec_bin_size0;
02447     f_scale1= item->f_scale1;
02448     f_precision1= item->f_precision1;
02449     dec_bin_size1= item->dec_bin_size1;
02450   }
02451 }
02452 
02453 
02454 int64_t Item_variance_field::val_int()
02455 {
02456   /* can't be fix_fields()ed */
02457   return (int64_t) rint(val_real());
02458 }
02459 
02460 
02461 double Item_variance_field::val_real()
02462 {
02463   // fix_fields() never calls for this Item
02464   if (hybrid_type == DECIMAL_RESULT)
02465     return val_real_from_decimal();
02466 
02467   double recurrence_s;
02468   uint64_t count;
02469   float8get(recurrence_s, (field->ptr + sizeof(double)));
02470   count=sint8korr(field->ptr+sizeof(double)*2);
02471 
02472   if ((null_value= (count <= sample)))
02473     return 0.0;
02474 
02475   return variance_fp_recurrence_result(recurrence_s, count, sample);
02476 }
02477 
02478 
02479 /****************************************************************************
02480 ** COUNT(DISTINCT ...)
02481 ****************************************************************************/
02482 
02483 int simple_str_key_cmp(void* arg, unsigned char* key1, unsigned char* key2)
02484 {
02485   Field *f= (Field*) arg;
02486   return f->cmp(key1, key2);
02487 }
02488 
02496 int composite_key_cmp(void* arg, unsigned char* key1, unsigned char* key2)
02497 {
02498   Item_sum_count_distinct* item = (Item_sum_count_distinct*)arg;
02499   Field **field    = item->table->getFields();
02500   Field **field_end= field + item->table->getShare()->sizeFields();
02501   uint32_t *lengths=item->field_lengths;
02502   for (; field < field_end; ++field)
02503   {
02504     Field* f = *field;
02505     int len = *lengths++;
02506     int res = f->cmp(key1, key2);
02507     if (res)
02508       return res;
02509     key1 += len;
02510     key2 += len;
02511   }
02512   return 0;
02513 }
02514 
02515 static int count_distinct_walk(void *,
02516                                uint32_t ,
02517                                void *arg)
02518 {
02519   (*((uint64_t*)arg))++;
02520   return 0;
02521 }
02522 
02523 void Item_sum_count_distinct::cleanup()
02524 {
02525   Item_sum_int::cleanup();
02526 
02527   /* Free objects only if we own them. */
02528   if (!original)
02529   {
02530     /*
02531       We need to delete the table and the tree in cleanup() as
02532       they were allocated in the runtime memroot. Using the runtime
02533       memroot reduces memory footprint for PS/SP and simplifies setup().
02534     */
02535     delete tree;
02536     tree= 0;
02537     is_evaluated= false;
02538     if (table)
02539     {
02540       table= 0;
02541     }
02542     delete tmp_table_param;
02543     tmp_table_param= 0;
02544   }
02545   always_null= false;
02546   return;
02547 }
02548 
02549 
02555 void Item_sum_count_distinct::make_unique()
02556 {
02557   table=0;
02558   original= 0;
02559   force_copy_fields= 1;
02560   tree= 0;
02561   is_evaluated= false;
02562   tmp_table_param= 0;
02563   always_null= false;
02564 }
02565 
02566 
02567 Item_sum_count_distinct::~Item_sum_count_distinct()
02568 {
02569   cleanup();
02570 }
02571 
02572 
02573 bool Item_sum_count_distinct::setup(Session *session)
02574 {
02575   List<Item> list;
02576   Select_Lex *select_lex= session->lex().current_select;
02577 
02578   /*
02579     Setup can be called twice for ROLLUP items. This is a bug.
02580     Please add assert(tree == 0) here when it's fixed.
02581     It's legal to call setup() more than once when in a subquery
02582   */
02583   if (tree || table || tmp_table_param)
02584     return false;
02585 
02586   tmp_table_param= new Tmp_Table_Param;
02587 
02588   /* Create a table with an unique key over all parameters */
02589   for (uint32_t i= 0; i < arg_count; i++)
02590   {
02591     Item *item=args[i];
02592     list.push_back(item);
02593     if (item->const_item() && item->is_null())
02594       always_null= 1;
02595   }
02596   if (always_null)
02597     return false;
02598   count_field_types(select_lex, tmp_table_param, list, 0);
02599   tmp_table_param->force_copy_fields= force_copy_fields;
02600   assert(table == 0);
02601 
02602   if (!(table= create_tmp_table(session, tmp_table_param, list, NULL, 1, 0, (select_lex->options | session->options), HA_POS_ERROR, "")))
02603   {
02604     return true;
02605   }
02606   table->cursor->extra(HA_EXTRA_NO_ROWS);   // Don't update rows
02607   table->no_rows=1;
02608 
02609   if (table->getShare()->db_type() == heap_engine)
02610   {
02611     /*
02612       No blobs, otherwise it would have been MyISAM: set up a compare
02613       function and its arguments to use with Unique.
02614     */
02615     qsort_cmp2 compare_key;
02616     void* cmp_arg;
02617     Field **field= table->getFields();
02618     Field **field_end= field + table->getShare()->sizeFields();
02619     bool all_binary= true;
02620 
02621     for (tree_key_length= 0; field < field_end; ++field)
02622     {
02623       Field *f= *field;
02624       enum enum_field_types f_type= f->type();
02625       tree_key_length+= f->pack_length();
02626       if (f_type == DRIZZLE_TYPE_VARCHAR)
02627       {
02628         all_binary= false;
02629         break;
02630       }
02631     }
02632     if (all_binary)
02633     {
02634       cmp_arg= (void*) &tree_key_length;
02635       compare_key= (qsort_cmp2) simple_raw_key_cmp;
02636     }
02637     else
02638     {
02639       if (table->getShare()->sizeFields() == 1)
02640       {
02641         /*
02642           If we have only one field, which is the most common use of
02643           count(distinct), it is much faster to use a simpler key
02644           compare method that can take advantage of not having to worry
02645           about other fields.
02646         */
02647         compare_key= (qsort_cmp2) simple_str_key_cmp;
02648         cmp_arg= (void*) table->getField(0);
02649         /* tree_key_length has been set already */
02650       }
02651       else
02652       {
02653         uint32_t *length;
02654         compare_key= (qsort_cmp2) composite_key_cmp;
02655         cmp_arg= this;
02656         field_lengths= new (session->mem) uint32_t[table->getShare()->sizeFields()];
02657         for (tree_key_length= 0, length= field_lengths, field= table->getFields();
02658              field < field_end; ++field, ++length)
02659         {
02660           *length= (*field)->pack_length();
02661           tree_key_length+= *length;
02662         }
02663       }
02664     }
02665     assert(tree == 0);
02666     tree= new Unique(compare_key, cmp_arg, tree_key_length,
02667                      (size_t)session->variables.max_heap_table_size);
02668     /*
02669       The only time tree_key_length could be 0 is if someone does
02670       count(distinct) on a char(0) field - stupid thing to do,
02671       but this has to be handled - otherwise someone can crash
02672       the server with a DoS attack
02673     */
02674     is_evaluated= false;
02675     if (! tree)
02676       return true;
02677   }
02678   return false;
02679 }
02680 
02681 
02682 Item *Item_sum_count_distinct::copy_or_same(Session* session)
02683 {
02684   return new (session->mem) Item_sum_count_distinct(session, this);
02685 }
02686 
02687 
02688 void Item_sum_count_distinct::clear()
02689 {
02690   /* tree and table can be both null only if always_null */
02691   is_evaluated= false;
02692   if (tree)
02693   {
02694     tree->reset();
02695   }
02696   else if (table)
02697   {
02698     table->cursor->extra(HA_EXTRA_NO_CACHE);
02699     table->cursor->ha_delete_all_rows();
02700     table->cursor->extra(HA_EXTRA_WRITE_CACHE);
02701   }
02702 }
02703 
02704 bool Item_sum_count_distinct::add()
02705 {
02706   int error;
02707   if (always_null)
02708     return 0;
02709   copy_fields(tmp_table_param);
02710   if (copy_funcs(tmp_table_param->items_to_copy, table->in_use))
02711     return true;
02712 
02713   for (Field **field= table->getFields() ; *field ; field++)
02714   {
02715     if ((*field)->is_real_null(0))
02716     {
02717       return 0;         // Don't count NULL
02718     }
02719   }
02720 
02721   is_evaluated= false;
02722   if (tree)
02723   {
02724     /*
02725       The first few bytes of record (at least one) are just markers
02726       for deleted and NULLs. We want to skip them since they will
02727       bloat the tree without providing any valuable info. Besides,
02728       key_length used to initialize the tree didn't include space for them.
02729     */
02730     return tree->unique_add(table->record[0] + table->getShare()->null_bytes);
02731   }
02732   if ((error= table->cursor->insertRecord(table->record[0])) &&
02733       table->cursor->is_fatal_error(error, HA_CHECK_DUP))
02734     return true;
02735   return false;
02736 }
02737 
02738 
02739 int64_t Item_sum_count_distinct::val_int()
02740 {
02741   int error;
02742   assert(fixed == 1);
02743   if (!table)         // Empty query
02744     return 0L;
02745   if (tree)
02746   {
02747     if (is_evaluated)
02748       return count;
02749 
02750     if (tree->elements == 0)
02751       return (int64_t) tree->elements_in_tree(); // everything fits in memory
02752     count= 0;
02753     tree->walk(count_distinct_walk, (void*) &count);
02754     is_evaluated= true;
02755     return (int64_t) count;
02756   }
02757 
02758   error= table->cursor->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
02759 
02760   if(error)
02761   {
02762     table->print_error(error, MYF(0));
02763   }
02764 
02765   return table->cursor->stats.records;
02766 }
02767 
02768 /*****************************************************************************
02769  GROUP_CONCAT function
02770 
02771  SQL SYNTAX:
02772   GROUP_CONCAT([DISTINCT] expr,... [order_st BY col [ASC|DESC],...]
02773     [SEPARATOR str_const])
02774 
02775  concat of values from "group by" operation
02776 
02777  BUGS
02778    Blobs doesn't work with DISTINCT or order_st BY
02779 *****************************************************************************/
02780 
02781 
02797 int group_concat_key_cmp_with_distinct(void* arg, const void* key1,
02798                                        const void* key2)
02799 {
02800   Item_func_group_concat *item_func= (Item_func_group_concat*)arg;
02801   Table *table= item_func->table;
02802 
02803   for (uint32_t i= 0; i < item_func->arg_count_field; i++)
02804   {
02805     Item *item= item_func->args[i];
02806     /*
02807       If field_item is a const item then either get_tp_table_field returns 0
02808       or it is an item over a const table.
02809     */
02810     if (item->const_item())
02811       continue;
02812     /*
02813       We have to use get_tmp_table_field() instead of
02814       real_item()->get_tmp_table_field() because we want the field in
02815       the temporary table, not the original field
02816     */
02817     Field *field= item->get_tmp_table_field();
02818     int res;
02819     uint32_t offset= field->offset(field->getTable()->record[0])-table->getShare()->null_bytes;
02820     if((res= field->cmp((unsigned char*)key1 + offset, (unsigned char*)key2 + offset)))
02821       return res;
02822   }
02823   return 0;
02824 }
02825 
02826 
02831 int group_concat_key_cmp_with_order(void* arg, const void* key1,
02832                                     const void* key2)
02833 {
02834   Item_func_group_concat* grp_item= (Item_func_group_concat*) arg;
02835   Order **order_item, **end;
02836   Table *table= grp_item->table;
02837 
02838   for (order_item= grp_item->order, end=order_item+ grp_item->arg_count_order;
02839        order_item < end;
02840        order_item++)
02841   {
02842     Item *item= *(*order_item)->item;
02843     /*
02844       We have to use get_tmp_table_field() instead of
02845       real_item()->get_tmp_table_field() because we want the field in
02846       the temporary table, not the original field
02847     */
02848     Field *field= item->get_tmp_table_field();
02849     /*
02850       If item is a const item then either get_tp_table_field returns 0
02851       or it is an item over a const table.
02852     */
02853     if (field && !item->const_item())
02854     {
02855       int res;
02856       uint32_t offset= (field->offset(field->getTable()->record[0]) -
02857                     table->getShare()->null_bytes);
02858       if ((res= field->cmp((unsigned char*)key1 + offset, (unsigned char*)key2 + offset)))
02859         return (*order_item)->asc ? res : -res;
02860     }
02861   }
02862   /*
02863     We can't return 0 because in that case the tree class would remove this
02864     item as double value. This would cause problems for case-changes and
02865     if the returned values are not the same we do the sort on.
02866   */
02867   return 1;
02868 }
02869 
02870 
02875 int dump_leaf_key(unsigned char* key, uint32_t ,
02876                   Item_func_group_concat *item)
02877 {
02878   Table *table= item->table;
02879   String tmp((char *)table->getUpdateRecord(), table->getShare()->getRecordLength(), default_charset_info);
02880   String *result= &item->result;
02881   Item **arg= item->args, **arg_end= item->args + item->arg_count_field;
02882   uint32_t old_length= result->length();
02883 
02884   if (item->no_appended)
02885     item->no_appended= false;
02886   else
02887     result->append(*item->separator);
02888 
02889   tmp.length(0);
02890 
02891   for (; arg < arg_end; arg++)
02892   {
02893     String *res;
02894     if (! (*arg)->const_item())
02895     {
02896       /*
02897   We have to use get_tmp_table_field() instead of
02898   real_item()->get_tmp_table_field() because we want the field in
02899   the temporary table, not the original field
02900         We also can't use table->field array to access the fields
02901         because it contains both order and arg list fields.
02902       */
02903       Field *field= (*arg)->get_tmp_table_field();
02904       uint32_t offset= (field->offset(field->getTable()->record[0]) -
02905                     table->getShare()->null_bytes);
02906       assert(offset < table->getShare()->getRecordLength());
02907       res= field->val_str_internal(&tmp, key + offset);
02908     }
02909     else
02910       res= (*arg)->val_str(&tmp);
02911     if (res)
02912       result->append(*res);
02913   }
02914 
02915   /* stop if length of result more than max_length */
02916   if (result->length() > item->max_length)
02917   {
02918     int well_formed_error;
02919     const charset_info_st& cs= *item->collation.collation;
02920     const char *ptr= result->ptr();
02921     /*
02922       It's ok to use item->result.length() as the fourth argument
02923       as this is never used to limit the length of the data.
02924       Cut is done with the third argument.
02925     */
02926     uint32_t add_length= cs.cset->well_formed_len(cs, str_ref(ptr + old_length, ptr + item->max_length), result->length(), &well_formed_error);
02927     result->length(old_length + add_length);
02928     item->count_cut_values++;
02929     item->warning_for_row= true;
02930     return 1;
02931   }
02932   return 0;
02933 }
02934 
02935 
02945 Item_func_group_concat::
02946 Item_func_group_concat(Name_resolution_context *context_arg,
02947                        bool distinct_arg, List<Item> *select_list,
02948                        SQL_LIST *order_list, String *separator_arg)
02949   :tmp_table_param(0), warning(0),
02950    separator(separator_arg), tree(NULL), unique_filter(NULL), table(0),
02951    order(0), context(context_arg),
02952    arg_count_order(order_list ? order_list->elements : 0),
02953    arg_count_field(select_list->size()),
02954    count_cut_values(0),
02955    distinct(distinct_arg),
02956    warning_for_row(false),
02957    force_copy_fields(0), original(0)
02958 {
02959   Item *item_select;
02960   Item **arg_ptr;
02961 
02962   quick_group= false;
02963   arg_count= arg_count_field + arg_count_order;
02964 
02965   /*
02966     We need to allocate:
02967     args - arg_count_field+arg_count_order
02968            (for possible order items in temporare tables)
02969     order - arg_count_order
02970   */
02971   if (!(args= (Item**) memory::sql_alloc(sizeof(Item*) * arg_count +
02972                                  sizeof(Order*)*arg_count_order)))
02973     return;
02974 
02975   order= (Order**)(args + arg_count);
02976 
02977   /* fill args items of show and sort */
02978   List<Item>::iterator li(select_list->begin());
02979 
02980   for (arg_ptr=args ; (item_select= li++) ; arg_ptr++)
02981     *arg_ptr= item_select;
02982 
02983   if (arg_count_order)
02984   {
02985     Order **order_ptr= order;
02986     for (Order *order_item= (Order*) order_list->first;
02987          order_item != NULL;
02988          order_item= order_item->next)
02989     {
02990       (*order_ptr++)= order_item;
02991       *arg_ptr= *order_item->item;
02992       order_item->item= arg_ptr++;
02993     }
02994   }
02995 }
02996 
02997 
02998 Item_func_group_concat::Item_func_group_concat(Session *session,
02999                                                Item_func_group_concat *item)
03000   :Item_sum(session, item),
03001   tmp_table_param(item->tmp_table_param),
03002   warning(item->warning),
03003   separator(item->separator),
03004   tree(item->tree),
03005   unique_filter(item->unique_filter),
03006   table(item->table),
03007   order(item->order),
03008   context(item->context),
03009   arg_count_order(item->arg_count_order),
03010   arg_count_field(item->arg_count_field),
03011   count_cut_values(item->count_cut_values),
03012   distinct(item->distinct),
03013   warning_for_row(item->warning_for_row),
03014   always_null(item->always_null),
03015   force_copy_fields(item->force_copy_fields),
03016   original(item)
03017 {
03018   quick_group= item->quick_group;
03019   result.set_charset(collation.collation);
03020 }
03021 
03022 
03023 
03024 void Item_func_group_concat::cleanup()
03025 {
03026   Item_sum::cleanup();
03027 
03028   /* Adjust warning message to include total number of cut values */
03029   if (warning)
03030   {
03031     char warn_buff[DRIZZLE_ERRMSG_SIZE];
03032     snprintf(warn_buff, sizeof(warn_buff), ER(ER_CUT_VALUE_GROUP_CONCAT), count_cut_values);
03033     warning->set_msg(&getSession(), warn_buff);
03034     warning= 0;
03035   }
03036 
03037   /*
03038     Free table and tree if they belong to this item (if item have not pointer
03039     to original item from which was made copy => it own its objects )
03040   */
03041   if (!original)
03042   {
03043     delete tmp_table_param;
03044     tmp_table_param= 0;
03045     if (table)
03046     {
03047       Session *session= table->in_use;
03048       table= 0;
03049       if (tree)
03050       {
03051         tree->delete_tree();
03052         tree= 0;
03053       }
03054 
03055       delete unique_filter;
03056       unique_filter= NULL;
03057 
03058       if (warning)
03059       {
03060         char warn_buff[DRIZZLE_ERRMSG_SIZE];
03061         snprintf(warn_buff, sizeof(warn_buff), ER(ER_CUT_VALUE_GROUP_CONCAT), count_cut_values);
03062         warning->set_msg(session, warn_buff);
03063         warning= 0;
03064       }
03065     }
03066     assert(tree == 0 && warning == 0);
03067   }
03068   return;
03069 }
03070 
03071 
03072 Item *Item_func_group_concat::copy_or_same(Session* session)
03073 {
03074   return new (session->mem) Item_func_group_concat(session, this);
03075 }
03076 
03077 
03078 void Item_func_group_concat::clear()
03079 {
03080   result.length(0);
03081   result.copy();
03082   null_value= true;
03083   warning_for_row= false;
03084   no_appended= true;
03085   if (tree)
03086     tree->reset_tree();
03087   if (distinct)
03088     unique_filter->reset();
03089   /* No need to reset the table as we never call write_row */
03090 }
03091 
03092 
03093 bool Item_func_group_concat::add()
03094 {
03095   if (always_null)
03096     return 0;
03097   copy_fields(tmp_table_param);
03098   if (copy_funcs(tmp_table_param->items_to_copy, table->in_use))
03099     return true;
03100 
03101   for (uint32_t i= 0; i < arg_count_field; i++)
03102   {
03103     Item *show_item= args[i];
03104     if (!show_item->const_item())
03105     {
03106       Field *f= show_item->get_tmp_table_field();
03107       if (f->is_null_in_record((const unsigned char*) table->record[0]))
03108         return 0;                               // Skip row if it contains null
03109     }
03110   }
03111 
03112   null_value= false;
03113   bool row_eligible= true;
03114 
03115   if (distinct)
03116   {
03117     /* Filter out duplicate rows. */
03118     uint32_t count= unique_filter->elements_in_tree();
03119     unique_filter->unique_add(table->record[0] + table->getShare()->null_bytes);
03120     if (count == unique_filter->elements_in_tree())
03121       row_eligible= false;
03122   }
03123 
03124   Tree_Element *el= 0;                          // Only for safety
03125   if (row_eligible && tree)
03126     el= tree->tree_insert(table->record[0] + table->getShare()->null_bytes, 0,
03127                     tree->getCustomArg());
03128   /*
03129     If the row is not a duplicate (el->count == 1)
03130     we can dump the row here in case of GROUP_CONCAT(DISTINCT...)
03131     instead of doing tree traverse later.
03132   */
03133   if (row_eligible && !warning_for_row &&
03134       (!tree || (el->count == 1 && distinct && !arg_count_order)))
03135     dump_leaf_key(table->record[0] + table->getShare()->null_bytes, 1, this);
03136 
03137   return 0;
03138 }
03139 
03140 
03141 bool
03142 Item_func_group_concat::fix_fields(Session *session, Item **ref)
03143 {
03144   uint32_t i;                       /* for loop variable */
03145   assert(fixed == 0);
03146 
03147   if (init_sum_func_check(session))
03148     return true;
03149 
03150   maybe_null= 1;
03151 
03152   /*
03153     Fix fields for select list and order_st clause
03154   */
03155 
03156   for (i=0 ; i < arg_count ; i++)
03157   {
03158     if ((!args[i]->fixed &&
03159          args[i]->fix_fields(session, args + i)) ||
03160         args[i]->check_cols(1))
03161       return true;
03162   }
03163 
03164   if (agg_item_charsets(collation, func_name(),
03165                         args,
03166       /* skip charset aggregation for order columns */
03167       arg_count - arg_count_order,
03168       MY_COLL_ALLOW_CONV, 1))
03169     return 1;
03170 
03171   result.set_charset(collation.collation);
03172   result_field= 0;
03173   null_value= 1;
03174   max_length= (size_t)session->variables.group_concat_max_len;
03175 
03176   if (check_sum_func(session, ref))
03177     return true;
03178 
03179   fixed= 1;
03180   return false;
03181 }
03182 
03183 
03184 bool Item_func_group_concat::setup(Session *session)
03185 {
03186   List<Item> list;
03187   Select_Lex *select_lex= session->lex().current_select;
03188 
03189   /*
03190     Currently setup() can be called twice. Please add
03191     assertion here when this is fixed.
03192   */
03193   if (table || tree)
03194     return false;
03195 
03196   tmp_table_param= new Tmp_Table_Param;
03197 
03198   /* We'll convert all blobs to varchar fields in the temporary table */
03199   tmp_table_param->convert_blob_length= max_length *
03200                                         collation.collation->mbmaxlen;
03201   /* Push all not constant fields to the list and create a temp table */
03202   always_null= 0;
03203   for (uint32_t i= 0; i < arg_count_field; i++)
03204   {
03205     Item *item= args[i];
03206     list.push_back(item);
03207     if (item->const_item())
03208     {
03209       if (item->is_null())
03210       {
03211         always_null= 1;
03212         return false;
03213       }
03214     }
03215   }
03216 
03217   List<Item> all_fields(list);
03218   /*
03219     Try to find every order_st expression in the list of GROUP_CONCAT
03220     arguments. If an expression is not found, prepend it to
03221     "all_fields". The resulting field list is used as input to create
03222     tmp table columns.
03223   */
03224   if (arg_count_order &&
03225       setup_order(session, args, context->table_list, list, all_fields, *order))
03226     return true;
03227 
03228   count_field_types(select_lex, tmp_table_param, all_fields, 0);
03229   tmp_table_param->force_copy_fields= force_copy_fields;
03230   assert(table == 0);
03231   if (arg_count_order > 0 || distinct)
03232   {
03233     /*
03234       Currently we have to force conversion of BLOB values to VARCHAR's
03235       if we are to store them in TREE objects used for ORDER BY and
03236       DISTINCT. This leads to truncation if the BLOB's size exceeds
03237       Field_varstring::MAX_SIZE.
03238     */
03239     set_if_smaller(tmp_table_param->convert_blob_length,
03240                    Field_varstring::MAX_SIZE);
03241   }
03242 
03243   /*
03244     We have to create a temporary table to get descriptions of fields
03245     (types, sizes and so on).
03246 
03247     Note that in the table, we first have the ORDER BY fields, then the
03248     field list.
03249   */
03250   if (!(table= create_tmp_table(session, tmp_table_param, all_fields,
03251                                 (Order*) 0, 0, true,
03252                                 (select_lex->options | session->options),
03253                                 HA_POS_ERROR, (char*) "")))
03254   {
03255     return true;
03256   }
03257 
03258   table->cursor->extra(HA_EXTRA_NO_ROWS);
03259   table->no_rows= 1;
03260 
03261   /*
03262      Need sorting or uniqueness: init tree and choose a function to sort.
03263      Don't reserve space for NULLs: if any of gconcat arguments is NULL,
03264      the row is not added to the result.
03265   */
03266   uint32_t tree_key_length= table->getShare()->getRecordLength() - table->getShare()->null_bytes;
03267 
03268   if (arg_count_order)
03269   {
03270     tree= &tree_base;
03271     /*
03272       Create a tree for sorting. The tree is used to sort (according to the
03273       syntax of this function). If there is no ORDER BY clause, we don't
03274       create this tree.
03275     */
03276      tree->init_tree((uint32_t) min(session->variables.max_heap_table_size,
03277                                    (uint64_t)(session->variables.sortbuff_size/16)), 
03278               0,
03279               tree_key_length,
03280               group_concat_key_cmp_with_order , false, NULL, (void*) this);
03281   }
03282 
03283   if (distinct)
03284     unique_filter= new Unique(group_concat_key_cmp_with_distinct,
03285                               (void*)this,
03286                               tree_key_length,
03287                               (size_t)session->variables.max_heap_table_size);
03288 
03289   return false;
03290 }
03291 
03292 
03293 /* This is used by rollup to create a separate usable copy of the function */
03294 
03295 void Item_func_group_concat::make_unique()
03296 {
03297   tmp_table_param= 0;
03298   table=0;
03299   original= 0;
03300   force_copy_fields= 1;
03301   tree= 0;
03302 }
03303 
03304 double Item_func_group_concat::val_real()
03305 {
03306   String *res;  res=val_str(&str_value);
03307   return res ? internal::my_atof(res->c_ptr()) : 0.0;
03308 }
03309 
03310 int64_t Item_func_group_concat::val_int()
03311 {
03312   String *res;
03313   char *end_ptr;
03314   int error;
03315   if (!(res= val_str(&str_value)))
03316     return (int64_t) 0;
03317   end_ptr= (char*) res->ptr()+ res->length();
03318   return internal::my_strtoll10(res->ptr(), &end_ptr, &error);
03319 }
03320 
03321 String* Item_func_group_concat::val_str(String* )
03322 {
03323   assert(fixed == 1);
03324   if (null_value)
03325     return 0;
03326   if (no_appended && tree)
03327     /* Tree is used for sorting as in ORDER BY */
03328     tree->tree_walk((tree_walk_action)&dump_leaf_key, (void*)this, left_root_right);
03329   if (count_cut_values && !warning)
03330   {
03331     /*
03332       ER_CUT_VALUE_GROUP_CONCAT needs an argument, but this gets set in
03333       Item_func_group_concat::cleanup().
03334     */
03335     assert(table);
03336     warning= push_warning(table->in_use, DRIZZLE_ERROR::WARN_LEVEL_WARN,
03337                           ER_CUT_VALUE_GROUP_CONCAT,
03338                           ER(ER_CUT_VALUE_GROUP_CONCAT));
03339   }
03340   return &result;
03341 }
03342 
03343 
03344 void Item_func_group_concat::print(String *str)
03345 {
03346   str->append(STRING_WITH_LEN("group_concat("));
03347   if (distinct)
03348     str->append(STRING_WITH_LEN("distinct "));
03349   for (uint32_t i= 0; i < arg_count_field; i++)
03350   {
03351     if (i)
03352       str->append(',');
03353     args[i]->print(str);
03354   }
03355   if (arg_count_order)
03356   {
03357     str->append(STRING_WITH_LEN(" order by "));
03358     for (uint32_t i= 0 ; i < arg_count_order ; i++)
03359     {
03360       if (i)
03361         str->append(',');
03362       (*order[i]->item)->print(str);
03363       if (order[i]->asc)
03364         str->append(STRING_WITH_LEN(" ASC"));
03365       else
03366         str->append(STRING_WITH_LEN(" DESC"));
03367     }
03368   }
03369   str->append(STRING_WITH_LEN(" separator \'"));
03370   str->append(*separator);
03371   str->append(STRING_WITH_LEN("\')"));
03372 }
03373 
03374 
03375 Item_func_group_concat::~Item_func_group_concat()
03376 {
03377   if (!original && unique_filter)
03378     delete unique_filter;
03379 }
03380 
03381 } /* namespace drizzled */