1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2008 Sun Microsystems, Inc.
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; version 2 of the License.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20
#ifndef DRIZZLED_ITEM_SUM_H
21
#define DRIZZLED_ITEM_SUM_H
1
/* Copyright (C) 2000-2006 MySQL 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; version 2 of the License.
7
This program is distributed in the hope that it will be useful,
8
but WITHOUT ANY WARRANTY; without even the implied warranty of
9
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
GNU General Public License for more details.
12
You should have received a copy of the GNU General Public License
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
23
17
/* classes for sum functions */
25
#include <drizzled/tree.h>
26
#include <drizzled/hybrid_type.h>
27
#include <drizzled/item.h>
28
#include <drizzled/item/field.h>
29
#include <drizzled/item/bin_string.h>
30
#include <drizzled/charset_info.h>
35
int group_concat_key_cmp_with_distinct(void* arg, const void* key1,
38
int group_concat_key_cmp_with_order(void* arg, const void* key1,
19
#ifdef USE_PRAGMA_INTERFACE
20
#pragma interface /* gcc class implementation */
45
26
Class Item_sum is the base class used for special expressions that SQL calls
243
226
{ COUNT_FUNC, COUNT_DISTINCT_FUNC, SUM_FUNC, SUM_DISTINCT_FUNC, AVG_FUNC,
244
227
AVG_DISTINCT_FUNC, MIN_FUNC, MAX_FUNC, STD_FUNC,
245
VARIANCE_FUNC, SUM_BIT_FUNC, GROUP_CONCAT_FUNC
228
VARIANCE_FUNC, SUM_BIT_FUNC, UDF_SUM_FUNC, GROUP_CONCAT_FUNC
248
231
Item **args, *tmp_args[2];
249
232
Item **ref_by; /* pointer to a ref to the object used to register it */
250
233
Item_sum *next; /* next in the circular chain of registered objects */
252
Item_sum *in_sum_func; /* embedding set function if any */
253
Select_Lex * aggr_sel; /* select where the function is aggregated */
254
int8_t nest_level; /* number of the nesting level of the set function */
255
int8_t aggr_level; /* nesting level of the aggregating subquery */
256
int8_t max_arg_level; /* max level of unbound column references */
257
int8_t max_sum_func_level;/* max level of aggregation for embedded functions */
235
Item_sum *in_sum_func; /* embedding set function if any */
236
st_select_lex * aggr_sel; /* select where the function is aggregated */
237
int8 nest_level; /* number of the nesting level of the set function */
238
int8 aggr_level; /* nesting level of the aggregating subquery */
239
int8 max_arg_level; /* max level of unbound column references */
240
int8 max_sum_func_level;/* max level of aggregation for embedded functions */
258
241
bool quick_group; /* If incremental update of fields */
260
243
This list is used by the check for mixing non aggregated fields and
382
364
void no_rows_in_result() { clear(); }
384
virtual bool setup(Session *) {return 0;}
366
virtual bool setup(THD *thd __attribute__((__unused__))) {return 0;}
385
367
virtual void make_unique(void) {}
386
Item *get_tmp_table_item(Session *session);
387
virtual Field *create_tmp_field(bool group, Table *table,
388
uint32_t convert_blob_length);
389
bool walk(Item_processor processor, bool walk_subquery, unsigned char *argument);
390
bool init_sum_func_check(Session *session);
391
bool check_sum_func(Session *session, Item **ref);
392
bool register_sum_func(Session *session, Item **ref);
393
Select_Lex *depended_from()
368
Item *get_tmp_table_item(THD *thd);
369
virtual Field *create_tmp_field(bool group, TABLE *table,
370
uint convert_blob_length);
371
bool walk(Item_processor processor, bool walk_subquery, uchar *argument);
372
bool init_sum_func_check(THD *thd);
373
bool check_sum_func(THD *thd, Item **ref);
374
bool register_sum_func(THD *thd, Item **ref);
375
st_select_lex *depended_from()
394
376
{ return (nest_level == aggr_level ? 0 : aggr_sel); }
402
val_xxx() functions may be called several times during the execution of a
384
val_xxx() functions may be called several times during the execution of a
403
385
query. Derived classes that require extensive calculation in val_xxx()
404
maintain cache of aggregate value. This variable governs the validity of
386
maintain cache of aggregate value. This variable governs the validity of
407
389
bool is_evaluated;
409
391
Item_sum_num() :Item_sum(),is_evaluated(false) {}
410
Item_sum_num(Item *item_par)
392
Item_sum_num(Item *item_par)
411
393
:Item_sum(item_par), is_evaluated(false) {}
412
394
Item_sum_num(Item *a, Item* b) :Item_sum(a,b),is_evaluated(false) {}
413
Item_sum_num(List<Item> &list)
395
Item_sum_num(List<Item> &list)
414
396
:Item_sum(list), is_evaluated(false) {}
415
Item_sum_num(Session *session, Item_sum_num *item)
416
:Item_sum(session, item),is_evaluated(item->is_evaluated) {}
417
bool fix_fields(Session *, Item **);
397
Item_sum_num(THD *thd, Item_sum_num *item)
398
:Item_sum(thd, item),is_evaluated(item->is_evaluated) {}
399
bool fix_fields(THD *, Item **);
403
return (int64_t) rint(val_real()); /* Real as default */
419
405
String *val_str(String*str);
420
type::Decimal *val_decimal(type::Decimal *);
406
my_decimal *val_decimal(my_decimal *);
421
407
void reset_field();
617
603
force_copy_fields(0), tree(0), count(0),
618
604
original(0), always_null(false)
619
605
{ quick_group= 0; }
620
Item_sum_count_distinct(Session *session, Item_sum_count_distinct *item)
621
:Item_sum_int(session, item), table(item->table),
606
Item_sum_count_distinct(THD *thd, Item_sum_count_distinct *item)
607
:Item_sum_int(thd, item), table(item->table),
622
608
field_lengths(item->field_lengths),
623
609
tmp_table_param(item->tmp_table_param),
624
force_copy_fields(0), tree(item->tree), count(item->count),
610
force_copy_fields(0), tree(item->tree), count(item->count),
625
611
original(item), tree_key_length(item->tree_key_length),
626
612
always_null(item->always_null)
716
702
Item_result hybrid_type;
717
uint32_t f_precision0, f_scale0;
718
uint32_t f_precision1, f_scale1;
719
uint32_t dec_bin_size0, dec_bin_size1;
721
uint32_t prec_increment;
703
uint f_precision0, f_scale0;
704
uint f_precision1, f_scale1;
705
uint dec_bin_size0, dec_bin_size1;
722
708
Item_variance_field(Item_sum_variance *item);
723
709
enum Type type() const {return FIELD_VARIANCE_ITEM; }
724
710
double val_real();
712
{ /* can't be fix_fields()ed */ return (int64_t) rint(val_real()); }
726
713
String *val_str(String *str)
727
714
{ return val_string_from_real(str); }
728
type::Decimal *val_decimal(type::Decimal *dec_buf)
715
my_decimal *val_decimal(my_decimal *dec_buf)
729
716
{ return val_decimal_from_real(dec_buf); }
730
717
bool is_null() { update_null_value(); return null_value; }
731
718
enum_field_types field_type() const
733
720
return hybrid_type == DECIMAL_RESULT ?
734
DRIZZLE_TYPE_DECIMAL : DRIZZLE_TYPE_DOUBLE;
721
MYSQL_TYPE_NEWDECIMAL : MYSQL_TYPE_DOUBLE;
736
723
void fix_length_and_dec() {}
737
724
enum Item_result result_type () const { return hybrid_type; }
744
731
= sum (ai - avg(a))^2 / count(a) )
745
732
= sum (ai^2 - 2*ai*avg(a) + avg(a)^2) / count(a)
746
= (sum(ai^2) - sum(2*ai*avg(a)) + sum(avg(a)^2))/count(a) =
747
= (sum(ai^2) - 2*avg(a)*sum(a) + count(a)*avg(a)^2)/count(a) =
748
= (sum(ai^2) - 2*sum(a)*sum(a)/count(a) + count(a)*sum(a)^2/count(a)^2 )/count(a) =
749
= (sum(ai^2) - 2*sum(a)^2/count(a) + sum(a)^2/count(a) )/count(a) =
733
= (sum(ai^2) - sum(2*ai*avg(a)) + sum(avg(a)^2))/count(a) =
734
= (sum(ai^2) - 2*avg(a)*sum(a) + count(a)*avg(a)^2)/count(a) =
735
= (sum(ai^2) - 2*sum(a)*sum(a)/count(a) + count(a)*sum(a)^2/count(a)^2 )/count(a) =
736
= (sum(ai^2) - 2*sum(a)^2/count(a) + sum(a)^2/count(a) )/count(a) =
750
737
= (sum(ai^2) - sum(a)^2/count(a))/count(a)
752
739
But, this falls prey to catastrophic cancellation. Instead, use the recurrence formulas
754
M_{1} = x_{1}, ~ M_{k} = M_{k-1} + (x_{k} - M_{k-1}) / k newline
741
M_{1} = x_{1}, ~ M_{k} = M_{k-1} + (x_{k} - M_{k-1}) / k newline
755
742
S_{1} = 0, ~ S_{k} = S_{k-1} + (x_{k} - M_{k-1}) times (x_{k} - M_{k}) newline
756
743
for 2 <= k <= n newline
757
744
ital variance = S_{n} / (n-1)
768
755
double recurrence_m, recurrence_s; /* Used in recurrence relation. */
770
uint32_t f_precision0, f_scale0;
771
uint32_t f_precision1, f_scale1;
772
uint32_t dec_bin_size0, dec_bin_size1;
774
uint32_t prec_increment;
757
uint f_precision0, f_scale0;
758
uint f_precision1, f_scale1;
759
uint dec_bin_size0, dec_bin_size1;
776
Item_sum_variance(Item *item_par, uint32_t sample_arg) :Item_sum_num(item_par),
763
Item_sum_variance(Item *item_par, uint sample_arg) :Item_sum_num(item_par),
777
764
hybrid_type(REAL_RESULT), count(0), sample(sample_arg)
779
Item_sum_variance(Session *session, Item_sum_variance *item);
766
Item_sum_variance(THD *thd, Item_sum_variance *item);
780
767
enum Sumfunctype sum_func () const { return VARIANCE_FUNC; }
783
770
double val_real();
785
type::Decimal *val_decimal(type::Decimal *);
771
my_decimal *val_decimal(my_decimal *);
786
772
void reset_field();
787
773
void update_field();
788
Item *result_item(Field *)
774
Item *result_item(Field *field __attribute__((__unused__)))
789
775
{ return new Item_variance_field(this); }
790
776
void no_rows_in_result() {}
791
777
const char *func_name() const
792
778
{ return sample ? "var_samp(" : "variance("; }
793
Item *copy_or_same(Session* session);
794
Field *create_tmp_field(bool group, Table *table, uint32_t convert_blob_length);
779
Item *copy_or_same(THD* thd);
780
Field *create_tmp_field(bool group, TABLE *table, uint convert_blob_length);
795
781
enum Item_result result_type () const { return REAL_RESULT; }
820
806
class Item_sum_std :public Item_sum_variance
823
Item_sum_std(Item *item_par, uint32_t sample_arg)
809
Item_sum_std(Item *item_par, uint sample_arg)
824
810
:Item_sum_variance(item_par, sample_arg) {}
825
Item_sum_std(Session *session, Item_sum_std *item)
826
:Item_sum_variance(session, item)
811
Item_sum_std(THD *thd, Item_sum_std *item)
812
:Item_sum_variance(thd, item)
828
814
enum Sumfunctype sum_func () const { return STD_FUNC; }
829
815
double val_real();
830
Item *result_item(Field *)
816
Item *result_item(Field *field __attribute__((__unused__)))
831
817
{ return new Item_std_field(this); }
832
818
const char *func_name() const { return "std("; }
833
Item *copy_or_same(Session* session);
819
Item *copy_or_same(THD* thd);
834
820
enum Item_result result_type () const { return REAL_RESULT; }
835
enum_field_types field_type() const { return DRIZZLE_TYPE_DOUBLE;}
821
enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE;}
838
824
// This class is a string or number function depending on num_func
853
839
Item_sum_hybrid(Item *item_par,int sign)
854
840
:Item_sum(item_par), sum(0.0), sum_int(0),
855
hybrid_type(INT_RESULT), hybrid_field_type(DRIZZLE_TYPE_LONGLONG),
841
hybrid_type(INT_RESULT), hybrid_field_type(MYSQL_TYPE_LONGLONG),
856
842
cmp_sign(sign), was_values(true)
857
843
{ collation.set(&my_charset_bin); }
858
Item_sum_hybrid(Session *session, Item_sum_hybrid *item);
859
bool fix_fields(Session *, Item **);
844
Item_sum_hybrid(THD *thd, Item_sum_hybrid *item);
845
bool fix_fields(THD *, Item **);
861
847
double val_real();
862
848
int64_t val_int();
863
type::Decimal *val_decimal(type::Decimal *);
849
my_decimal *val_decimal(my_decimal *);
864
850
void reset_field();
865
851
String *val_str(String *);
866
852
bool keep_field_type(void) const { return 1; }
947
933
Item_sum_and(Item *item_par) :Item_sum_bit(item_par, UINT64_MAX) {}
948
Item_sum_and(Session *session, Item_sum_and *item) :Item_sum_bit(session, item) {}
934
Item_sum_and(THD *thd, Item_sum_and *item) :Item_sum_bit(thd, item) {}
950
936
const char *func_name() const { return "bit_and("; }
951
Item *copy_or_same(Session* session);
937
Item *copy_or_same(THD* thd);
954
940
class Item_sum_xor :public Item_sum_bit
957
Item_sum_xor(Item *item_par) :Item_sum_bit(item_par,0) {}
958
Item_sum_xor(Session *session, Item_sum_xor *item) :Item_sum_bit(session, item) {}
943
Item_sum_xor(Item *item_par) :Item_sum_bit(item_par,0LL) {}
944
Item_sum_xor(THD *thd, Item_sum_xor *item) :Item_sum_bit(thd, item) {}
960
946
const char *func_name() const { return "bit_xor("; }
961
Item *copy_or_same(Session* session);
947
Item *copy_or_same(THD* thd);
952
User defined aggregates
955
class Item_udf_sum : public Item_sum
961
Item_udf_sum(udf_func *udf_arg)
962
:Item_sum(), udf(udf_arg)
964
Item_udf_sum(udf_func *udf_arg, List<Item> &list)
965
:Item_sum(list), udf(udf_arg)
967
Item_udf_sum(THD *thd, Item_udf_sum *item)
968
:Item_sum(thd, item), udf(item->udf)
969
{ udf.not_original= true; }
970
const char *func_name() const { return udf.name(); }
971
bool fix_fields(THD *thd, Item **ref)
975
if (init_sum_func_check(thd))
979
if (udf.fix_fields(thd, this, this->arg_count, this->args))
982
return check_sum_func(thd, ref);
984
enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; }
985
virtual bool have_field_update(void) const { return 0; }
989
void reset_field() {};
990
void update_field() {};
992
virtual void print(String *str, enum_query_type query_type);
996
class Item_sum_udf_float :public Item_udf_sum
999
Item_sum_udf_float(udf_func *udf_arg)
1000
:Item_udf_sum(udf_arg) {}
1001
Item_sum_udf_float(udf_func *udf_arg, List<Item> &list)
1002
:Item_udf_sum(udf_arg, list) {}
1003
Item_sum_udf_float(THD *thd, Item_sum_udf_float *item)
1004
:Item_udf_sum(thd, item) {}
1008
return (int64_t) rint(Item_sum_udf_float::val_real());
1011
String *val_str(String*str);
1012
my_decimal *val_decimal(my_decimal *);
1013
void fix_length_and_dec() { fix_num_length_and_dec(); }
1014
Item *copy_or_same(THD* thd);
1018
class Item_sum_udf_int :public Item_udf_sum
1021
Item_sum_udf_int(udf_func *udf_arg)
1022
:Item_udf_sum(udf_arg) {}
1023
Item_sum_udf_int(udf_func *udf_arg, List<Item> &list)
1024
:Item_udf_sum(udf_arg, list) {}
1025
Item_sum_udf_int(THD *thd, Item_sum_udf_int *item)
1026
:Item_udf_sum(thd, item) {}
1029
{ assert(fixed == 1); return (double) Item_sum_udf_int::val_int(); }
1030
String *val_str(String*str);
1031
my_decimal *val_decimal(my_decimal *);
1032
enum Item_result result_type () const { return INT_RESULT; }
1033
void fix_length_and_dec() { decimals=0; max_length=21; }
1034
Item *copy_or_same(THD* thd);
1038
class Item_sum_udf_str :public Item_udf_sum
1041
Item_sum_udf_str(udf_func *udf_arg)
1042
:Item_udf_sum(udf_arg) {}
1043
Item_sum_udf_str(udf_func *udf_arg, List<Item> &list)
1044
:Item_udf_sum(udf_arg,list) {}
1045
Item_sum_udf_str(THD *thd, Item_sum_udf_str *item)
1046
:Item_udf_sum(thd, item) {}
1047
String *val_str(String *);
1053
res=val_str(&str_value);
1054
return res ? my_strntod(res->charset(),(char*) res->ptr(),res->length(),
1055
&end_not_used, &err_not_used) : 0.0;
1064
if (!(res= val_str(&str_value)))
1065
return 0; /* Null value */
1067
end= (char*) res->ptr()+res->length();
1068
return cs->cset->strtoll10(cs, res->ptr(), &end, &err_not_used);
1070
my_decimal *val_decimal(my_decimal *dec);
1071
enum Item_result result_type () const { return STRING_RESULT; }
1072
void fix_length_and_dec();
1073
Item *copy_or_same(THD* thd);
1077
class Item_sum_udf_decimal :public Item_udf_sum
1080
Item_sum_udf_decimal(udf_func *udf_arg)
1081
:Item_udf_sum(udf_arg) {}
1082
Item_sum_udf_decimal(udf_func *udf_arg, List<Item> &list)
1083
:Item_udf_sum(udf_arg, list) {}
1084
Item_sum_udf_decimal(THD *thd, Item_sum_udf_decimal *item)
1085
:Item_udf_sum(thd, item) {}
1086
String *val_str(String *);
1089
my_decimal *val_decimal(my_decimal *);
1090
enum Item_result result_type () const { return DECIMAL_RESULT; }
1091
void fix_length_and_dec() { fix_num_length_and_dec(); }
1092
Item *copy_or_same(THD* thd);
968
1097
class Item_func_group_concat : public Item_sum
970
Tmp_Table_Param *tmp_table_param;
971
DRIZZLE_ERROR *warning;
1099
TMP_TABLE_PARAM *tmp_table_param;
1100
MYSQL_ERROR *warning;
973
1102
String *separator;
1023
1153
enum_field_types field_type() const
1025
1155
if (max_length/collation.collation->mbmaxlen > CONVERT_IF_BIGGER_TO_BLOB )
1026
return DRIZZLE_TYPE_BLOB;
1156
return MYSQL_TYPE_BLOB;
1028
return DRIZZLE_TYPE_VARCHAR;
1158
return MYSQL_TYPE_VARCHAR;
1032
1162
void reset_field() { assert(0); } // not used
1033
1163
void update_field() { assert(0); } // not used
1034
bool fix_fields(Session *,Item **);
1035
bool setup(Session *session);
1164
bool fix_fields(THD *,Item **);
1165
bool setup(THD *thd);
1036
1166
void make_unique();
1039
type::Decimal *val_decimal(type::Decimal *decimal_value)
1169
String *res; res=val_str(&str_value);
1170
return res ? my_atof(res->c_ptr()) : 0.0;
1177
if (!(res= val_str(&str_value)))
1179
end_ptr= (char*) res->ptr()+ res->length();
1180
return my_strtoll10(res->ptr(), &end_ptr, &error);
1182
my_decimal *val_decimal(my_decimal *decimal_value)
1041
1184
return val_decimal_from_string(decimal_value);
1043
1186
String* val_str(String* str);
1044
Item *copy_or_same(Session* session);
1187
Item *copy_or_same(THD* thd);
1045
1188
void no_rows_in_result() {}
1046
1189
virtual void print(String *str, enum_query_type query_type);
1047
virtual bool change_context_processor(unsigned char *cntx)
1190
virtual bool change_context_processor(uchar *cntx)
1048
1191
{ context= (Name_resolution_context *)cntx; return false; }
1051
} /* namespace drizzled */
1053
#endif /* DRIZZLED_ITEM_SUM_H */