home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 January / Chip_2001-01_cd1.bin / tema / mysql / mysql-3.23.28g-win-source.exe / sql / item_sum.cpp < prev    next >
C/C++ Source or Header  |  2000-08-31  |  19KB  |  946 lines

  1. /* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
  2.    
  3.    This program is free software; you can redistribute it and/or modify
  4.    it under the terms of the GNU General Public License as published by
  5.    the Free Software Foundation; either version 2 of the License, or
  6.    (at your option) any later version.
  7.    
  8.    This program is distributed in the hope that it will be useful,
  9.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11.    GNU General Public License for more details.
  12.    
  13.    You should have received a copy of the GNU General Public License
  14.    along with this program; if not, write to the Free Software
  15.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  16.  
  17.  
  18. /* Sum functions (COUNT, MIN...) */
  19.  
  20. #ifdef __GNUC__
  21. #pragma implementation                // gcc: Class implementation
  22. #endif
  23.  
  24. #include "mysql_priv.h"
  25.  
  26.  
  27. Item_sum::Item_sum(List<Item> &list)
  28. {
  29.   arg_count=list.elements;
  30.   if ((args=(Item**) sql_alloc(sizeof(Item*)*arg_count)))
  31.   {
  32.     uint i=0;
  33.     List_iterator<Item> li(list);
  34.     Item *item;
  35.  
  36.     while ((item=li++))
  37.     {
  38.       args[i++]= item;
  39.     }
  40.   }
  41.   with_sum_func=1;
  42.   list.empty();                    // Fields are used
  43. }
  44.  
  45.  
  46. void Item_sum::make_field(Send_field *tmp_field)
  47. {
  48.   if (args[0]->type() == Item::FIELD_ITEM && keep_field_type())
  49.     ((Item_field*) args[0])->field->make_field(tmp_field);
  50.   else
  51.   {
  52.     tmp_field->flags=0;
  53.     if (!maybe_null)
  54.       tmp_field->flags|= NOT_NULL_FLAG;
  55.     tmp_field->length=max_length;
  56.     tmp_field->decimals=decimals;
  57.     tmp_field->type=(result_type() == INT_RESULT ? FIELD_TYPE_LONG :
  58.              result_type() == REAL_RESULT ? FIELD_TYPE_DOUBLE :
  59.              FIELD_TYPE_VAR_STRING);
  60.   }
  61.   tmp_field->table_name=(char*)"";
  62.   tmp_field->col_name=name;
  63. }
  64.  
  65. void Item_sum::print(String *str)
  66. {
  67.   str->append(func_name());
  68.   str->append('(');
  69.   for (uint i=0 ; i < arg_count ; i++)
  70.   {
  71.     if (i)
  72.       str->append(',');
  73.     args[i]->print(str);
  74.   }
  75.   str->append(')');
  76. }
  77.  
  78. void Item_sum::fix_num_length_and_dec()
  79. {
  80.   decimals=0;
  81.   for (uint i=0 ; i < arg_count ; i++)
  82.     set_if_bigger(decimals,args[i]->decimals);
  83.   max_length=float_length(decimals);
  84. }
  85.  
  86.  
  87. String *
  88. Item_sum_num::val_str(String *str)
  89. {
  90.   double nr=val();
  91.   if (null_value)
  92.     return 0;
  93.   str->set(nr,decimals);
  94.   return str;
  95. }
  96.  
  97.  
  98. String *
  99. Item_sum_int::val_str(String *str)
  100. {
  101.   longlong nr=val_int();
  102.   if (null_value)
  103.     return 0;
  104.   char buff[21];
  105.   uint length= (uint) (longlong10_to_str(nr,buff,-10)-buff);
  106.   str->copy(buff,length);
  107.   return str;
  108. }
  109.  
  110.  
  111. bool
  112. Item_sum_num::fix_fields(THD *thd,TABLE_LIST *tables)
  113. {
  114.   if (!thd->allow_sum_func)
  115.   {
  116.     my_error(ER_INVALID_GROUP_FUNC_USE,MYF(0));
  117.     return 1;
  118.   }
  119.   thd->allow_sum_func=0;            // No included group funcs
  120.   decimals=0;
  121.   maybe_null=0;
  122.   for (uint i=0 ; i < arg_count ; i++)
  123.   {
  124.     if (args[i]->fix_fields(thd,tables))
  125.       return 1;
  126.     if (decimals < args[i]->decimals)
  127.       decimals=args[i]->decimals;
  128.     maybe_null |= args[i]->maybe_null;
  129.   }
  130.   result_field=0;
  131.   max_length=float_length(decimals);
  132.   null_value=1;
  133.   fix_length_and_dec();
  134.   thd->allow_sum_func=1;            // Allow group functions
  135.   return 0;
  136. }
  137.  
  138.  
  139. bool
  140. Item_sum_hybrid::fix_fields(THD *thd,TABLE_LIST *tables)
  141. {
  142.   Item *item=args[0];
  143.   if (!thd->allow_sum_func)
  144.   {
  145.     my_error(ER_INVALID_GROUP_FUNC_USE,MYF(0));
  146.     return 1;
  147.   }
  148.   thd->allow_sum_func=0;            // No included group funcs
  149.   if (item->fix_fields(thd,tables))
  150.     return 1;
  151.   hybrid_type=item->result_type();
  152.   if (hybrid_type == INT_RESULT)
  153.     max_length=21;
  154.   else if (hybrid_type == REAL_RESULT)
  155.     max_length=float_length(decimals);
  156.   else
  157.     max_length=item->max_length;
  158.   decimals=item->decimals;
  159.   maybe_null=item->maybe_null;
  160.   binary=item->binary;
  161.   result_field=0;
  162.   null_value=1;
  163.   fix_length_and_dec();
  164.   thd->allow_sum_func=1;            // Allow group functions
  165.   return 0;
  166. }
  167.  
  168.  
  169. /***********************************************************************
  170. ** reset and add of sum_func
  171. ***********************************************************************/
  172.  
  173. void Item_sum_sum::reset()
  174. {
  175.   null_value=0; sum=0.0; Item_sum_sum::add();
  176. }
  177.  
  178. bool Item_sum_sum::add()
  179. {
  180.   sum+=args[0]->val();
  181.   return 0;
  182. }
  183.  
  184. double Item_sum_sum::val()
  185. {
  186.   return sum;
  187. }
  188.  
  189.  
  190. void Item_sum_count::reset()
  191. {
  192.   count=0; add();
  193. }
  194.  
  195. bool Item_sum_count::add()
  196. {
  197.   if (!args[0]->maybe_null)
  198.     count++;
  199.   else
  200.   {
  201.     (void) args[0]->val_int();
  202.     if (!args[0]->null_value)
  203.       count++;
  204.   }
  205.   return 0;
  206. }
  207.  
  208. longlong Item_sum_count::val_int()
  209. {
  210.   return (longlong) count;
  211. }
  212.  
  213. /*
  214. ** Avgerage
  215. */
  216.  
  217. void Item_sum_avg::reset()
  218. {
  219.   sum=0.0; count=0; Item_sum_avg::add();
  220. }
  221.  
  222. bool Item_sum_avg::add()
  223. {
  224.   double nr=args[0]->val();
  225.   if (!args[0]->null_value)
  226.   {
  227.     sum+=nr;
  228.     count++;
  229.   }
  230.   return 0;
  231. }
  232.  
  233. double Item_sum_avg::val()
  234. {
  235.   if (!count)
  236.   {
  237.     null_value=1;
  238.     return 0.0;
  239.   }
  240.   null_value=0;
  241.   return sum/ulonglong2double(count);
  242. }
  243.  
  244.  
  245. /*
  246. ** Standard deviation
  247. */
  248.  
  249. void Item_sum_std::reset()
  250. {
  251.   sum=sum_sqr=0.0; count=0; (void) Item_sum_std::add();
  252. }
  253.  
  254. bool Item_sum_std::add()
  255. {
  256.   double nr=args[0]->val();
  257.   if (!args[0]->null_value)
  258.   {
  259.     sum+=nr;
  260.     sum_sqr+=nr*nr;
  261.     count++;
  262.   }
  263.   return 0;
  264. }
  265.  
  266. double Item_sum_std::val()
  267. {
  268.   if (!count)
  269.   {
  270.     null_value=1;
  271.     return 0.0;
  272.   }
  273.   null_value=0;
  274.   /* Avoid problems when the precision isn't good enough */
  275.   double tmp=ulonglong2double(count);
  276.   double tmp2=(sum_sqr - sum*sum/tmp)/tmp;
  277.   return tmp2 <= 0.0 ? 0.0 : sqrt(tmp2);
  278. }
  279.  
  280.  
  281. void Item_sum_std::reset_field()
  282. {
  283.   double nr=args[0]->val();
  284.   char *res=result_field->ptr;
  285.  
  286.   if (args[0]->null_value)
  287.     bzero(res,sizeof(double)*2+sizeof(longlong));
  288.   else
  289.   {
  290.     float8store(res,nr);
  291.     nr*=nr;
  292.     float8store(res+sizeof(double),nr);
  293.     longlong tmp=1;
  294.     int8store(res+sizeof(double)*2,tmp);
  295.   }
  296. }
  297.  
  298. void Item_sum_std::update_field(int offset)
  299. {
  300.   double nr,old_nr,old_sqr;
  301.   longlong field_count;
  302.   char *res=result_field->ptr;
  303.  
  304.   float8get(old_nr,res+offset);
  305.   float8get(old_sqr,res+offset+sizeof(double));
  306.   field_count=sint8korr(res+offset+sizeof(double)*2);
  307.  
  308.   nr=args[0]->val();
  309.   if (!args[0]->null_value)
  310.   {
  311.     old_nr+=nr;
  312.     old_sqr+=nr*nr;
  313.     field_count++;
  314.   }
  315.   float8store(res,old_nr);
  316.   float8store(res+sizeof(double),old_sqr);
  317.   int8store(res+sizeof(double)*2,field_count);
  318. }
  319.  
  320. /* min & max */
  321.  
  322. double Item_sum_hybrid::val()
  323. {
  324.   if (null_value)
  325.     return 0.0;
  326.   if (hybrid_type == STRING_RESULT)
  327.   {
  328.     String *res;  res=val_str(&str_value);
  329.     return res ? atof(res->c_ptr()) : 0.0;
  330.   }
  331.   return sum;
  332. }
  333.  
  334.  
  335. String *
  336. Item_sum_hybrid::val_str(String *str)
  337. {
  338.   if (null_value)
  339.     return 0;
  340.   if (hybrid_type == STRING_RESULT)
  341.     return &value;
  342.   str->set(sum,decimals);
  343.   return str;
  344. }
  345.  
  346.  
  347. bool Item_sum_min::add()
  348. {
  349.   if (hybrid_type != STRING_RESULT)
  350.   {
  351.     double nr=args[0]->val();
  352.     if (!args[0]->null_value && (null_value || nr < sum))
  353.     {
  354.       sum=nr;
  355.       null_value=0;
  356.     }
  357.   }
  358.   else
  359.   {
  360.     String *result=args[0]->val_str(&tmp_value);
  361.     if (!args[0]->null_value &&
  362.     (null_value ||
  363.      (binary ? stringcmp(&value,result) : sortcmp(&value,result)) > 0))
  364.     {
  365.       value.copy(*result);
  366.       null_value=0;
  367.     }
  368.   }
  369.   return 0;
  370. }
  371.  
  372.  
  373. bool Item_sum_max::add()
  374. {
  375.   if (hybrid_type != STRING_RESULT)
  376.   {
  377.     double nr=args[0]->val();
  378.     if (!args[0]->null_value && (null_value || nr > sum))
  379.     {
  380.       sum=nr;
  381.       null_value=0;
  382.     }
  383.   }
  384.   else
  385.   {
  386.     String *result=args[0]->val_str(&tmp_value);
  387.     if (!args[0]->null_value &&
  388.     (null_value ||
  389.      (binary ? stringcmp(&value,result) : sortcmp(&value,result)) < 0))
  390.     {
  391.       value.copy(*result);
  392.       null_value=0;
  393.     }
  394.   }
  395.   return 0;
  396. }
  397.  
  398.  
  399. /* bit_or and bit_and */
  400.  
  401. longlong Item_sum_bit::val_int()
  402. {
  403.   return (longlong) bits;
  404. }
  405.  
  406. void Item_sum_bit::reset()
  407. {
  408.   bits=reset_bits; add();
  409. }
  410.  
  411. bool Item_sum_or::add()
  412. {
  413.   ulonglong value= (ulonglong) args[0]->val_int();
  414.   if (!args[0]->null_value)
  415.     bits|=value;
  416.   return 0;
  417. }
  418.  
  419. bool Item_sum_and::add()
  420. {
  421.   ulonglong value= (ulonglong) args[0]->val_int();
  422.   if (!args[0]->null_value)
  423.     bits&=value;
  424.   return 0;
  425. }
  426.  
  427. /************************************************************************
  428. ** reset result of a Item_sum with is saved in a tmp_table
  429. *************************************************************************/
  430.  
  431. void Item_sum_num::reset_field()
  432. {
  433.   double nr=args[0]->val();
  434.   char *res=result_field->ptr;
  435.  
  436.   if (maybe_null)
  437.   {
  438.     if (args[0]->null_value)
  439.     {
  440.       nr=0.0;
  441.       result_field->set_null();
  442.     }
  443.     else
  444.       result_field->set_notnull();
  445.   }
  446.   float8store(res,nr);
  447. }
  448.  
  449.  
  450. void Item_sum_hybrid::reset_field()
  451. {
  452.   if (hybrid_type == STRING_RESULT)
  453.   {
  454.     char buff[MAX_FIELD_WIDTH];
  455.     String tmp(buff,sizeof(buff)),*res;
  456.  
  457.     res=args[0]->val_str(&tmp);
  458.     if (args[0]->null_value)
  459.     {
  460.       result_field->set_null();
  461.       result_field->reset();
  462.     }
  463.     else
  464.     {
  465.       result_field->set_notnull();
  466.       result_field->store(res->ptr(),res->length());
  467.     }
  468.   }
  469.   else if (hybrid_type == INT_RESULT)
  470.   {
  471.     longlong nr=args[0]->val_int();
  472.  
  473.     if (maybe_null)
  474.     {
  475.       if (args[0]->null_value)
  476.       {
  477.     nr=0;
  478.     result_field->set_null();
  479.       }
  480.       else
  481.     result_field->set_notnull();
  482.     }
  483.     result_field->store(nr);
  484.   }
  485.   else                        // REAL_RESULT
  486.   {
  487.     double nr=args[0]->val();
  488.  
  489.     if (maybe_null)
  490.     {
  491.       if (args[0]->null_value)
  492.       {
  493.     nr=0.0;
  494.     result_field->set_null();
  495.       }
  496.       else
  497.     result_field->set_notnull();
  498.     }
  499.     result_field->store(nr);
  500.   }
  501. }
  502.  
  503.  
  504. void Item_sum_sum::reset_field()
  505. {
  506.   double nr=args[0]->val();            // Nulls also return 0
  507.   float8store(result_field->ptr,nr);
  508.   null_value=0;
  509.   result_field->set_notnull();
  510. }
  511.  
  512.  
  513. void Item_sum_count::reset_field()
  514. {
  515.   char *res=result_field->ptr;
  516.   longlong nr=0;
  517.  
  518.   if (!args[0]->maybe_null)
  519.     nr=1;
  520.   else
  521.   {
  522.     (void) args[0]->val_int();
  523.     if (!args[0]->null_value)
  524.       nr=1;
  525.   }
  526.   int8store(res,nr);
  527. }
  528.  
  529.  
  530. void Item_sum_avg::reset_field()
  531. {
  532.   double nr=args[0]->val();
  533.   char *res=result_field->ptr;
  534.  
  535.   if (args[0]->null_value)
  536.     bzero(res,sizeof(double)+sizeof(longlong));
  537.   else
  538.   {
  539.     float8store(res,nr);
  540.     res+=sizeof(double);
  541.     longlong tmp=1;
  542.     int8store(res,tmp);
  543.   }
  544. }
  545.  
  546. void Item_sum_bit::reset_field()
  547. {
  548.   char *res=result_field->ptr;
  549.   ulonglong nr=(ulonglong) args[0]->val_int();
  550.   int8store(res,nr);
  551. }
  552.  
  553. /*
  554. ** calc next value and merge it with field_value
  555. */
  556.  
  557. void Item_sum_sum::update_field(int offset)
  558. {
  559.   double old_nr,nr;
  560.   char *res=result_field->ptr;
  561.  
  562.   float8get(old_nr,res+offset);
  563.   nr=args[0]->val();
  564.   if (!args[0]->null_value)
  565.     old_nr+=nr;
  566.   float8store(res,old_nr);
  567. }
  568.  
  569.  
  570. void Item_sum_count::update_field(int offset)
  571. {
  572.   longlong nr;
  573.   char *res=result_field->ptr;
  574.  
  575.   nr=sint8korr(res+offset);
  576.   if (!args[0]->maybe_null)
  577.     nr++;
  578.   else
  579.   {
  580.     (void) args[0]->val_int();
  581.     if (!args[0]->null_value)
  582.       nr++;
  583.   }
  584.   int8store(res,nr);
  585. }
  586.  
  587.  
  588. void Item_sum_avg::update_field(int offset)
  589. {
  590.   double nr,old_nr;
  591.   longlong field_count;
  592.   char *res=result_field->ptr;
  593.  
  594.   float8get(old_nr,res+offset);
  595.   field_count=sint8korr(res+offset+sizeof(double));
  596.  
  597.   nr=args[0]->val();
  598.   if (!args[0]->null_value)
  599.   {
  600.     old_nr+=nr;
  601.     field_count++;
  602.   }
  603.   float8store(res,old_nr);
  604.   res+=sizeof(double);
  605.   int8store(res,field_count);
  606. }
  607.  
  608. void Item_sum_hybrid::update_field(int offset)
  609. {
  610.   if (hybrid_type == STRING_RESULT)
  611.     min_max_update_str_field(offset);
  612.   else if (hybrid_type == INT_RESULT)
  613.     min_max_update_int_field(offset);
  614.   else
  615.     min_max_update_real_field(offset);
  616. }
  617.  
  618.  
  619. void
  620. Item_sum_hybrid::min_max_update_str_field(int offset)
  621. {
  622.   String *res_str=args[0]->val_str(&value);
  623.  
  624.   if (args[0]->null_value)
  625.     result_field->copy_from_tmp(offset);    // Use old value
  626.   else
  627.   {
  628.     res_str->strip_sp();
  629.     result_field->ptr+=offset;            // Get old max/min
  630.     result_field->val_str(&tmp_value,&tmp_value);
  631.     result_field->ptr-=offset;
  632.  
  633.     if (result_field->is_null() ||
  634.     (cmp_sign * (binary ? stringcmp(res_str,&tmp_value) :
  635.          sortcmp(res_str,&tmp_value)) < 0))
  636.       result_field->store(res_str->ptr(),res_str->length());
  637.     else
  638.     {                        // Use old value
  639.       char *res=result_field->ptr;
  640.       memcpy(res,res+offset,result_field->pack_length());
  641.     }
  642.     result_field->set_notnull();
  643.   }
  644. }
  645.  
  646.  
  647. void
  648. Item_sum_hybrid::min_max_update_real_field(int offset)
  649. {
  650.   double nr,old_nr;
  651.  
  652.   result_field->ptr+=offset;
  653.   old_nr=result_field->val_real();
  654.   nr=args[0]->val();
  655.   if (!args[0]->null_value)
  656.   {
  657.     if (result_field->is_null(offset) ||
  658.     (cmp_sign > 0 ? old_nr > nr : old_nr < nr))
  659.       old_nr=nr;
  660.     result_field->set_notnull();
  661.   }
  662.   else if (result_field->is_null(offset))
  663.     result_field->set_null();
  664.   result_field->ptr-=offset;
  665.   result_field->store(old_nr);
  666. }
  667.  
  668.  
  669. void
  670. Item_sum_hybrid::min_max_update_int_field(int offset)
  671. {
  672.   longlong nr,old_nr;
  673.  
  674.   result_field->ptr+=offset;
  675.   old_nr=result_field->val_int();
  676.   nr=args[0]->val_int();
  677.   if (!args[0]->null_value)
  678.   {
  679.     if (result_field->is_null(offset) ||
  680.     (cmp_sign > 0 ? old_nr > nr : old_nr < nr))
  681.       old_nr=nr;
  682.     result_field->set_notnull();
  683.   }
  684.   else if (result_field->is_null(offset))
  685.     result_field->set_null();
  686.   result_field->ptr-=offset;
  687.   result_field->store(old_nr);
  688. }
  689.  
  690.  
  691. void Item_sum_or::update_field(int offset)
  692. {
  693.   ulonglong nr;
  694.   char *res=result_field->ptr;
  695.  
  696.   nr=uint8korr(res+offset);
  697.   nr|= (ulonglong) args[0]->val_int();
  698.   int8store(res,nr);
  699. }
  700.  
  701.  
  702. void Item_sum_and::update_field(int offset)
  703. {
  704.   ulonglong nr;
  705.   char *res=result_field->ptr;
  706.  
  707.   nr=uint8korr(res+offset);
  708.   nr&= (ulonglong) args[0]->val_int();
  709.   int8store(res,nr);
  710. }
  711.  
  712.  
  713. Item_avg_field::Item_avg_field(Item_sum_avg *item)
  714. {
  715.   name=item->name;
  716.   decimals=item->decimals;
  717.   max_length=item->max_length;
  718.   field=item->result_field;
  719.   maybe_null=1;
  720. }
  721.  
  722. double Item_avg_field::val()
  723. {
  724.   double nr;
  725.   longlong count;
  726.   float8get(nr,field->ptr);
  727.   char *res=(field->ptr+sizeof(double));
  728.   count=sint8korr(res);
  729.  
  730.   if (!count)
  731.   {
  732.     null_value=1;
  733.     return 0.0;
  734.   }
  735.   null_value=0;
  736.   return nr/(double) count;
  737. }
  738.  
  739. String *Item_avg_field::val_str(String *str)
  740. {
  741.   double nr=Item_avg_field::val();
  742.   if (null_value)
  743.     return 0;
  744.   str->set(nr,decimals);
  745.   return str;
  746. }
  747.  
  748. Item_std_field::Item_std_field(Item_sum_std *item)
  749. {
  750.   name=item->name;
  751.   decimals=item->decimals;
  752.   max_length=item->max_length;
  753.   field=item->result_field;
  754.   maybe_null=1;
  755. }
  756.  
  757. double Item_std_field::val()
  758. {
  759.   double sum,sum_sqr;
  760.   longlong count;
  761.   float8get(sum,field->ptr);
  762.   float8get(sum_sqr,(field->ptr+sizeof(double)));
  763.   count=sint8korr(field->ptr+sizeof(double)*2);
  764.  
  765.   if (!count)
  766.   {
  767.     null_value=1;
  768.     return 0.0;
  769.   }
  770.   null_value=0;
  771.   double tmp= (double) count;
  772.   double tmp2=(sum_sqr - sum*sum/tmp)/tmp;
  773.   return tmp2 <= 0.0 ? 0.0 : sqrt(tmp2);
  774. }
  775.  
  776. String *Item_std_field::val_str(String *str)
  777. {
  778.   double nr=val();
  779.   if (null_value)
  780.     return 0;
  781.   str->set(nr,decimals);
  782.   return str;
  783. }
  784.  
  785. /****************************************************************************
  786. ** COUNT(DISTINCT ...)
  787. ****************************************************************************/
  788.  
  789. #include "sql_select.h"
  790.  
  791. Item_sum_count_distinct::~Item_sum_count_distinct()
  792. {
  793.   if (table)
  794.     free_tmp_table(current_thd, table);
  795.   delete tmp_table_param;
  796. }
  797.  
  798.  
  799. bool Item_sum_count_distinct::fix_fields(THD *thd,TABLE_LIST *tables)
  800. {
  801.   if (Item_sum_num::fix_fields(thd,tables) ||
  802.       !(tmp_table_param= new TMP_TABLE_PARAM))
  803.     return 1;
  804.   return 0;
  805. }
  806.  
  807. bool Item_sum_count_distinct::setup(THD *thd)
  808. {
  809.   List<Item> list;
  810.   /* Create a table with an unique key over all parameters */
  811.   for (uint i=0; i < arg_count ; i++)
  812.     if (list.push_back(args[i]))
  813.       return 1;
  814.   count_field_types(tmp_table_param,list);
  815.   if (table)
  816.   {
  817.     free_tmp_table(thd, table);
  818.     tmp_table_param->cleanup();
  819.   }
  820.   if (!(table=create_tmp_table(thd, tmp_table_param, list, (ORDER*) 0, 1,
  821.                    0, 0, current_lex->options | thd->options)))
  822.     return 1;
  823.   table->file->extra(HA_EXTRA_NO_ROWS);        // Don't update rows
  824.   return 0;
  825. }
  826.  
  827.  
  828. void Item_sum_count_distinct::reset()
  829. {
  830.   table->file->extra(HA_EXTRA_NO_CACHE);
  831.   table->file->delete_all_rows();
  832.   table->file->extra(HA_EXTRA_WRITE_CACHE);
  833.   (void) add();
  834. }
  835.  
  836. bool Item_sum_count_distinct::add()
  837. {
  838.   int error;
  839.   copy_fields(tmp_table_param);
  840.   copy_funcs(tmp_table_param->funcs);
  841.  
  842.   for (Field **field=table->field ; *field ; field++)
  843.     if ((*field)->is_real_null(0))
  844.       return 0;                    // Don't count NULL
  845.  
  846.   if ((error=table->file->write_row(table->record[0])))
  847.   {
  848.     if (error != HA_ERR_FOUND_DUPP_KEY &&
  849.     error != HA_ERR_FOUND_DUPP_UNIQUE)
  850.     {
  851.       if (create_myisam_from_heap(table, tmp_table_param, error,1))
  852.     return 1;                // Not a table_is_full error
  853.     }
  854.   }
  855.   return 0;
  856. }
  857.  
  858. longlong Item_sum_count_distinct::val_int()
  859. {
  860.   if (!table)                    // Empty query
  861.     return LL(0);
  862.   table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
  863.   return table->file->records;
  864. }
  865.  
  866. /****************************************************************************
  867. ** Functions to handle dynamic loadable aggregates
  868. ** Original source by: Alexis Mikhailov <root@medinf.chuvashia.su>
  869. ** Adapted for UDAs by: Andreas F. Bobak <bobak@relog.ch>.
  870. ** Rewritten by: Monty.
  871. ****************************************************************************/
  872.  
  873. #ifdef HAVE_DLOPEN
  874.  
  875. void Item_udf_sum::reset()
  876. {
  877.   DBUG_ENTER("Item_udf_sum::reset");
  878.   udf.reset(&null_value);
  879.   DBUG_VOID_RETURN;
  880. }
  881.  
  882. bool Item_udf_sum::add()
  883. {
  884.   DBUG_ENTER("Item_udf_sum::reset");
  885.   udf.add(&null_value);
  886.   DBUG_RETURN(0);
  887. }
  888.  
  889. double Item_sum_udf_float::val()
  890. {
  891.   DBUG_ENTER("Item_sum_udf_float::val");
  892.   DBUG_PRINT("info",("result_type: %d  arg_count: %d",
  893.              args[0]->result_type(), arg_count));
  894.   DBUG_RETURN(udf.val(&null_value));
  895. }
  896.  
  897. String *Item_sum_udf_float::val_str(String *str)
  898. {
  899.   double nr=val();
  900.   if (null_value)
  901.     return 0;                    /* purecov: inspected */
  902.   else
  903.     str->set(nr,decimals);
  904.   return str;
  905. }
  906.  
  907.  
  908. longlong Item_sum_udf_int::val_int()
  909. {
  910.   DBUG_ENTER("Item_sum_udf_int::val_int");
  911.   DBUG_PRINT("info",("result_type: %d  arg_count: %d",
  912.              args[0]->result_type(), arg_count));
  913.   DBUG_RETURN(udf.val_int(&null_value));
  914. }
  915.  
  916. String *Item_sum_udf_int::val_str(String *str)
  917. {
  918.   longlong nr=val_int();
  919.   if (null_value)
  920.     return 0;
  921.   else
  922.     str->set(nr);
  923.   return str;
  924. }
  925.  
  926. /* Default max_length is max argument length */
  927.  
  928. void Item_sum_udf_str::fix_length_and_dec()
  929. {
  930.   DBUG_ENTER("Item_sum_udf_str::fix_length_and_dec");
  931.   max_length=0;
  932.   for (uint i = 0; i < arg_count; i++)
  933.     set_if_bigger(max_length,args[i]->max_length);
  934.   DBUG_VOID_RETURN;
  935. }
  936.  
  937. String *Item_sum_udf_str::val_str(String *str)
  938. {
  939.   DBUG_ENTER("Item_sum_udf_str::str");
  940.   String *res=udf.val_str(str,&str_value);
  941.   null_value = !res;
  942.   DBUG_RETURN(res);
  943. }
  944.  
  945. #endif /* HAVE_DLOPEN */
  946.