1
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
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.
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.
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 */
18
/* Sum functions (COUNT, MIN...) */
21
#pragma implementation // gcc: Class implementation
24
#include "mysql_priv.h"
27
Item_sum::Item_sum(List<Item> &list)
29
arg_count=list.elements;
30
if ((args=(Item**) sql_alloc(sizeof(Item*)*arg_count)))
33
List_iterator<Item> li(list);
42
list.empty(); // Fields are used
46
void Item_sum::make_field(Send_field *tmp_field)
48
if (args[0]->type() == Item::FIELD_ITEM && keep_field_type())
49
((Item_field*) args[0])->field->make_field(tmp_field);
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);
61
tmp_field->table_name=(char*)"";
62
tmp_field->col_name=name;
65
void Item_sum::print(String *str)
67
str->append(func_name());
69
for (uint i=0 ; i < arg_count ; i++)
78
void Item_sum::fix_num_length_and_dec()
81
for (uint i=0 ; i < arg_count ; i++)
82
set_if_bigger(decimals,args[i]->decimals);
83
max_length=float_length(decimals);
88
Item_sum_num::val_str(String *str)
93
str->set(nr,decimals);
99
Item_sum_int::val_str(String *str)
101
longlong nr=val_int();
105
uint length= (uint) (longlong10_to_str(nr,buff,-10)-buff);
106
str->copy(buff,length);
112
Item_sum_num::fix_fields(THD *thd,TABLE_LIST *tables)
114
if (!thd->allow_sum_func)
116
my_error(ER_INVALID_GROUP_FUNC_USE,MYF(0));
119
thd->allow_sum_func=0; // No included group funcs
122
for (uint i=0 ; i < arg_count ; i++)
124
if (args[i]->fix_fields(thd,tables))
126
if (decimals < args[i]->decimals)
127
decimals=args[i]->decimals;
128
maybe_null |= args[i]->maybe_null;
131
max_length=float_length(decimals);
133
fix_length_and_dec();
134
thd->allow_sum_func=1; // Allow group functions
140
Item_sum_hybrid::fix_fields(THD *thd,TABLE_LIST *tables)
143
if (!thd->allow_sum_func)
145
my_error(ER_INVALID_GROUP_FUNC_USE,MYF(0));
148
thd->allow_sum_func=0; // No included group funcs
149
if (item->fix_fields(thd,tables))
151
hybrid_type=item->result_type();
152
if (hybrid_type == INT_RESULT)
154
else if (hybrid_type == REAL_RESULT)
155
max_length=float_length(decimals);
157
max_length=item->max_length;
158
decimals=item->decimals;
159
maybe_null=item->maybe_null;
163
fix_length_and_dec();
164
thd->allow_sum_func=1; // Allow group functions
169
/***********************************************************************
170
** reset and add of sum_func
171
***********************************************************************/
173
void Item_sum_sum::reset()
175
null_value=0; sum=0.0; Item_sum_sum::add();
178
bool Item_sum_sum::add()
184
double Item_sum_sum::val()
190
void Item_sum_count::reset()
195
bool Item_sum_count::add()
197
if (!args[0]->maybe_null)
201
(void) args[0]->val_int();
202
if (!args[0]->null_value)
208
longlong Item_sum_count::val_int()
210
return (longlong) count;
217
void Item_sum_avg::reset()
219
sum=0.0; count=0; Item_sum_avg::add();
222
bool Item_sum_avg::add()
224
double nr=args[0]->val();
225
if (!args[0]->null_value)
233
double Item_sum_avg::val()
241
return sum/ulonglong2double(count);
246
** Standard deviation
249
void Item_sum_std::reset()
251
sum=sum_sqr=0.0; count=0; (void) Item_sum_std::add();
254
bool Item_sum_std::add()
256
double nr=args[0]->val();
257
if (!args[0]->null_value)
266
double Item_sum_std::val()
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);
281
void Item_sum_std::reset_field()
283
double nr=args[0]->val();
284
char *res=result_field->ptr;
286
if (args[0]->null_value)
287
bzero(res,sizeof(double)*2+sizeof(longlong));
292
float8store(res+sizeof(double),nr);
294
int8store(res+sizeof(double)*2,tmp);
298
void Item_sum_std::update_field(int offset)
300
double nr,old_nr,old_sqr;
301
longlong field_count;
302
char *res=result_field->ptr;
304
float8get(old_nr,res+offset);
305
float8get(old_sqr,res+offset+sizeof(double));
306
field_count=sint8korr(res+offset+sizeof(double)*2);
309
if (!args[0]->null_value)
315
float8store(res,old_nr);
316
float8store(res+sizeof(double),old_sqr);
317
int8store(res+sizeof(double)*2,field_count);
322
double Item_sum_hybrid::val()
326
if (hybrid_type == STRING_RESULT)
328
String *res; res=val_str(&str_value);
329
return res ? atof(res->c_ptr()) : 0.0;
336
Item_sum_hybrid::val_str(String *str)
340
if (hybrid_type == STRING_RESULT)
342
str->set(sum,decimals);
347
bool Item_sum_min::add()
349
if (hybrid_type != STRING_RESULT)
351
double nr=args[0]->val();
352
if (!args[0]->null_value && (null_value || nr < sum))
360
String *result=args[0]->val_str(&tmp_value);
361
if (!args[0]->null_value &&
363
(binary ? stringcmp(&value,result) : sortcmp(&value,result)) > 0))
373
bool Item_sum_max::add()
375
if (hybrid_type != STRING_RESULT)
377
double nr=args[0]->val();
378
if (!args[0]->null_value && (null_value || nr > sum))
386
String *result=args[0]->val_str(&tmp_value);
387
if (!args[0]->null_value &&
389
(binary ? stringcmp(&value,result) : sortcmp(&value,result)) < 0))
399
/* bit_or and bit_and */
401
longlong Item_sum_bit::val_int()
403
return (longlong) bits;
406
void Item_sum_bit::reset()
408
bits=reset_bits; add();
411
bool Item_sum_or::add()
413
ulonglong value= (ulonglong) args[0]->val_int();
414
if (!args[0]->null_value)
419
bool Item_sum_and::add()
421
ulonglong value= (ulonglong) args[0]->val_int();
422
if (!args[0]->null_value)
427
/************************************************************************
428
** reset result of a Item_sum with is saved in a tmp_table
429
*************************************************************************/
431
void Item_sum_num::reset_field()
433
double nr=args[0]->val();
434
char *res=result_field->ptr;
438
if (args[0]->null_value)
441
result_field->set_null();
444
result_field->set_notnull();
450
void Item_sum_hybrid::reset_field()
452
if (hybrid_type == STRING_RESULT)
454
char buff[MAX_FIELD_WIDTH];
455
String tmp(buff,sizeof(buff)),*res;
457
res=args[0]->val_str(&tmp);
458
if (args[0]->null_value)
460
result_field->set_null();
461
result_field->reset();
465
result_field->set_notnull();
466
result_field->store(res->ptr(),res->length());
469
else if (hybrid_type == INT_RESULT)
471
longlong nr=args[0]->val_int();
475
if (args[0]->null_value)
478
result_field->set_null();
481
result_field->set_notnull();
483
result_field->store(nr);
487
double nr=args[0]->val();
491
if (args[0]->null_value)
494
result_field->set_null();
497
result_field->set_notnull();
499
result_field->store(nr);
504
void Item_sum_sum::reset_field()
506
double nr=args[0]->val(); // Nulls also return 0
507
float8store(result_field->ptr,nr);
509
result_field->set_notnull();
513
void Item_sum_count::reset_field()
515
char *res=result_field->ptr;
518
if (!args[0]->maybe_null)
522
(void) args[0]->val_int();
523
if (!args[0]->null_value)
530
void Item_sum_avg::reset_field()
532
double nr=args[0]->val();
533
char *res=result_field->ptr;
535
if (args[0]->null_value)
536
bzero(res,sizeof(double)+sizeof(longlong));
546
void Item_sum_bit::reset_field()
548
char *res=result_field->ptr;
549
ulonglong nr=(ulonglong) args[0]->val_int();
554
** calc next value and merge it with field_value
557
void Item_sum_sum::update_field(int offset)
560
char *res=result_field->ptr;
562
float8get(old_nr,res+offset);
564
if (!args[0]->null_value)
566
float8store(res,old_nr);
570
void Item_sum_count::update_field(int offset)
573
char *res=result_field->ptr;
575
nr=sint8korr(res+offset);
576
if (!args[0]->maybe_null)
580
(void) args[0]->val_int();
581
if (!args[0]->null_value)
588
void Item_sum_avg::update_field(int offset)
591
longlong field_count;
592
char *res=result_field->ptr;
594
float8get(old_nr,res+offset);
595
field_count=sint8korr(res+offset+sizeof(double));
598
if (!args[0]->null_value)
603
float8store(res,old_nr);
605
int8store(res,field_count);
608
void Item_sum_hybrid::update_field(int offset)
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);
615
min_max_update_real_field(offset);
620
Item_sum_hybrid::min_max_update_str_field(int offset)
622
String *res_str=args[0]->val_str(&value);
624
if (args[0]->null_value)
625
result_field->copy_from_tmp(offset); // Use old value
629
result_field->ptr+=offset; // Get old max/min
630
result_field->val_str(&tmp_value,&tmp_value);
631
result_field->ptr-=offset;
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());
639
char *res=result_field->ptr;
640
memcpy(res,res+offset,result_field->pack_length());
642
result_field->set_notnull();
648
Item_sum_hybrid::min_max_update_real_field(int offset)
652
result_field->ptr+=offset;
653
old_nr=result_field->val_real();
655
if (!args[0]->null_value)
657
if (result_field->is_null(offset) ||
658
(cmp_sign > 0 ? old_nr > nr : old_nr < nr))
660
result_field->set_notnull();
662
else if (result_field->is_null(offset))
663
result_field->set_null();
664
result_field->ptr-=offset;
665
result_field->store(old_nr);
670
Item_sum_hybrid::min_max_update_int_field(int offset)
674
result_field->ptr+=offset;
675
old_nr=result_field->val_int();
676
nr=args[0]->val_int();
677
if (!args[0]->null_value)
679
if (result_field->is_null(offset) ||
680
(cmp_sign > 0 ? old_nr > nr : old_nr < nr))
682
result_field->set_notnull();
684
else if (result_field->is_null(offset))
685
result_field->set_null();
686
result_field->ptr-=offset;
687
result_field->store(old_nr);
691
void Item_sum_or::update_field(int offset)
694
char *res=result_field->ptr;
696
nr=uint8korr(res+offset);
697
nr|= (ulonglong) args[0]->val_int();
702
void Item_sum_and::update_field(int offset)
705
char *res=result_field->ptr;
707
nr=uint8korr(res+offset);
708
nr&= (ulonglong) args[0]->val_int();
713
Item_avg_field::Item_avg_field(Item_sum_avg *item)
716
decimals=item->decimals;
717
max_length=item->max_length;
718
field=item->result_field;
722
double Item_avg_field::val()
726
float8get(nr,field->ptr);
727
char *res=(field->ptr+sizeof(double));
728
count=sint8korr(res);
736
return nr/(double) count;
739
String *Item_avg_field::val_str(String *str)
741
double nr=Item_avg_field::val();
744
str->set(nr,decimals);
748
Item_std_field::Item_std_field(Item_sum_std *item)
751
decimals=item->decimals;
752
max_length=item->max_length;
753
field=item->result_field;
757
double Item_std_field::val()
761
float8get(sum,field->ptr);
762
float8get(sum_sqr,(field->ptr+sizeof(double)));
763
count=sint8korr(field->ptr+sizeof(double)*2);
771
double tmp= (double) count;
772
double tmp2=(sum_sqr - sum*sum/tmp)/tmp;
773
return tmp2 <= 0.0 ? 0.0 : sqrt(tmp2);
776
String *Item_std_field::val_str(String *str)
781
str->set(nr,decimals);
785
/****************************************************************************
786
** COUNT(DISTINCT ...)
787
****************************************************************************/
789
#include "sql_select.h"
791
Item_sum_count_distinct::~Item_sum_count_distinct()
794
free_tmp_table(current_thd, table);
795
delete tmp_table_param;
799
bool Item_sum_count_distinct::fix_fields(THD *thd,TABLE_LIST *tables)
801
if (Item_sum_num::fix_fields(thd,tables) ||
802
!(tmp_table_param= new TMP_TABLE_PARAM))
807
bool Item_sum_count_distinct::setup(THD *thd)
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]))
814
count_field_types(tmp_table_param,list);
817
free_tmp_table(thd, table);
818
tmp_table_param->cleanup();
820
if (!(table=create_tmp_table(thd, tmp_table_param, list, (ORDER*) 0, 1,
821
0, 0, current_lex->options | thd->options)))
823
table->file->extra(HA_EXTRA_NO_ROWS); // Don't update rows
828
void Item_sum_count_distinct::reset()
830
table->file->extra(HA_EXTRA_NO_CACHE);
831
table->file->delete_all_rows();
832
table->file->extra(HA_EXTRA_WRITE_CACHE);
836
bool Item_sum_count_distinct::add()
839
copy_fields(tmp_table_param);
840
copy_funcs(tmp_table_param->funcs);
842
if ((error=table->file->write_row(table->record[0])))
844
if (error != HA_ERR_FOUND_DUPP_KEY &&
845
error != HA_ERR_FOUND_DUPP_UNIQUE)
847
if (create_myisam_from_heap(table, tmp_table_param, error,1))
848
return 1; // Not a table_is_full error
854
longlong Item_sum_count_distinct::val_int()
856
if (!table) // Empty query
858
table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
859
return table->file->records;
862
/****************************************************************************
863
** Functions to handle dynamic loadable aggregates
864
** Original source by: Alexis Mikhailov <root@medinf.chuvashia.su>
865
** Adapted for UDAs by: Andreas F. Bobak <bobak@relog.ch>.
866
** Rewritten by: Monty.
867
****************************************************************************/
871
void Item_udf_sum::reset()
873
DBUG_ENTER("Item_udf_sum::reset");
874
udf.reset(&null_value);
878
bool Item_udf_sum::add()
880
DBUG_ENTER("Item_udf_sum::reset");
881
udf.add(&null_value);
885
double Item_sum_udf_float::val()
887
DBUG_ENTER("Item_sum_udf_float::val");
888
DBUG_PRINT("info",("result_type: %d arg_count: %d",
889
args[0]->result_type(), arg_count));
890
DBUG_RETURN(udf.val(&null_value));
893
String *Item_sum_udf_float::val_str(String *str)
897
return 0; /* purecov: inspected */
899
str->set(nr,decimals);
904
longlong Item_sum_udf_int::val_int()
906
DBUG_ENTER("Item_sum_udf_int::val_int");
907
DBUG_PRINT("info",("result_type: %d arg_count: %d",
908
args[0]->result_type(), arg_count));
909
DBUG_RETURN(udf.val_int(&null_value));
912
String *Item_sum_udf_int::val_str(String *str)
914
longlong nr=val_int();
922
/* Default max_length is max argument length */
924
void Item_sum_udf_str::fix_length_and_dec()
926
DBUG_ENTER("Item_sum_udf_str::fix_length_and_dec");
928
for (uint i = 0; i < arg_count; i++)
929
set_if_bigger(max_length,args[i]->max_length);
933
String *Item_sum_udf_str::val_str(String *str)
935
DBUG_ENTER("Item_sum_udf_str::str");
936
String *res=udf.val_str(str,&str_value);
941
#endif /* HAVE_DLOPEN */