My Project
|
00001 #ifndef ITEM_SUM_INCLUDED 00002 #define ITEM_SUM_INCLUDED 00003 00004 /* Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. reserved. 00005 reserved. 00006 00007 This program is free software; you can redistribute it and/or modify 00008 it under the terms of the GNU General Public License as published by 00009 the Free Software Foundation; version 2 of the License. 00010 00011 This program is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 GNU General Public License for more details. 00015 00016 You should have received a copy of the GNU General Public License 00017 along with this program; if not, write to the Free Software 00018 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ 00019 00020 00021 /* classes for sum functions */ 00022 00023 #include <my_tree.h> 00024 #include "sql_udf.h" /* udf_handler */ 00025 00026 class Item_sum; 00027 class Aggregator_distinct; 00028 class Aggregator_simple; 00029 00042 class Aggregator : public Sql_alloc 00043 { 00044 friend class Item_sum; 00045 friend class Item_sum_sum; 00046 friend class Item_sum_count; 00047 friend class Item_sum_avg; 00048 00049 /* 00050 All members are protected as this class is not usable outside of an 00051 Item_sum descendant. 00052 */ 00053 protected: 00054 /* the aggregate function class to act on */ 00055 Item_sum *item_sum; 00056 00057 public: 00058 Aggregator (Item_sum *arg): item_sum(arg) {} 00059 virtual ~Aggregator () {} /* Keep gcc happy */ 00060 00061 enum Aggregator_type { SIMPLE_AGGREGATOR, DISTINCT_AGGREGATOR }; 00062 virtual Aggregator_type Aggrtype() = 0; 00063 00069 virtual bool setup(THD *) = 0; 00070 00076 virtual void clear() = 0; 00077 00082 virtual bool add() = 0; 00083 00088 virtual void endup() = 0; 00089 00091 virtual my_decimal *arg_val_decimal(my_decimal * value) = 0; 00093 virtual double arg_val_real() = 0; 00104 virtual bool arg_is_null(bool use_null_value) = 0; 00105 }; 00106 00107 00108 class st_select_lex; 00109 00305 class Item_sum :public Item_result_field 00306 { 00307 friend class Aggregator_distinct; 00308 friend class Aggregator_simple; 00309 00310 protected: 00315 Aggregator *aggr; 00316 00317 private: 00324 bool force_copy_fields; 00325 00331 bool with_distinct; 00332 00333 public: 00334 00335 bool has_force_copy_fields() const { return force_copy_fields; } 00336 bool has_with_distinct() const { return with_distinct; } 00337 00338 enum Sumfunctype 00339 { COUNT_FUNC, COUNT_DISTINCT_FUNC, SUM_FUNC, SUM_DISTINCT_FUNC, AVG_FUNC, 00340 AVG_DISTINCT_FUNC, MIN_FUNC, MAX_FUNC, STD_FUNC, 00341 VARIANCE_FUNC, SUM_BIT_FUNC, UDF_SUM_FUNC, GROUP_CONCAT_FUNC 00342 }; 00343 00344 Item **ref_by; /* pointer to a ref to the object used to register it */ 00345 Item_sum *next; /* next in the circular chain of registered objects */ 00346 Item_sum *in_sum_func; /* embedding set function if any */ 00347 st_select_lex * aggr_sel; /* select where the function is aggregated */ 00348 int8 nest_level; /* number of the nesting level of the set function */ 00349 int8 aggr_level; /* nesting level of the aggregating subquery */ 00350 int8 max_arg_level; /* max level of unbound column references */ 00351 int8 max_sum_func_level;/* max level of aggregation for embedded functions */ 00352 bool quick_group; /* If incremental update of fields */ 00353 /* 00354 This list is used by the check for mixing non aggregated fields and 00355 sum functions in the ONLY_FULL_GROUP_BY_MODE. We save all outer fields 00356 directly or indirectly used under this function it as it's unclear 00357 at the moment of fixing outer field whether it's aggregated or not. 00358 */ 00359 List<Item_field> outer_fields; 00360 00361 protected: 00362 uint arg_count; 00363 Item **args, *tmp_args[2]; 00364 /* 00365 Copy of the arguments list to hold the original set of arguments. 00366 Used in EXPLAIN EXTENDED instead of the current argument list because 00367 the current argument list can be altered by usage of temporary tables. 00368 */ 00369 Item **orig_args, *tmp_orig_args[2]; 00370 table_map used_tables_cache; 00371 bool forced_const; 00372 static ulonglong ram_limitation(THD *thd); 00373 00374 public: 00375 00376 void mark_as_sum_func(); 00377 Item_sum() :next(NULL), quick_group(1), arg_count(0), forced_const(FALSE) 00378 { 00379 mark_as_sum_func(); 00380 init_aggregator(); 00381 } 00382 Item_sum(Item *a) :next(NULL), quick_group(1), arg_count(1), args(tmp_args), 00383 orig_args(tmp_orig_args), forced_const(FALSE) 00384 { 00385 args[0]=a; 00386 mark_as_sum_func(); 00387 init_aggregator(); 00388 } 00389 Item_sum( Item *a, Item *b ) :next(NULL), quick_group(1), arg_count(2), args(tmp_args), 00390 orig_args(tmp_orig_args), forced_const(FALSE) 00391 { 00392 args[0]=a; args[1]=b; 00393 mark_as_sum_func(); 00394 init_aggregator(); 00395 } 00396 Item_sum(List<Item> &list); 00397 //Copy constructor, need to perform subselects with temporary tables 00398 Item_sum(THD *thd, Item_sum *item); 00399 enum Type type() const { return SUM_FUNC_ITEM; } 00400 virtual enum Sumfunctype sum_func () const=0; 00405 inline bool reset_and_add() 00406 { 00407 aggregator_clear(); 00408 return aggregator_add(); 00409 }; 00410 00411 /* 00412 Called when new group is started and results are being saved in 00413 a temporary table. Similarly to reset_and_add() it resets the 00414 value to its default and aggregates the value of its 00415 attribute(s), but must also store it in result_field. 00416 This set of methods (result_item(), reset_field, update_field()) of 00417 Item_sum is used only if quick_group is not null. Otherwise 00418 copy_or_same() is used to obtain a copy of this item. 00419 */ 00420 virtual void reset_field()=0; 00421 /* 00422 Called for each new value in the group, when temporary table is in use. 00423 Similar to add(), but uses temporary table field to obtain current value, 00424 Updated value is then saved in the field. 00425 */ 00426 virtual void update_field()=0; 00427 virtual bool keep_field_type(void) const { return 0; } 00428 virtual void fix_length_and_dec() { maybe_null=1; null_value=1; } 00429 virtual Item *result_item(Field *field) 00430 { return new Item_field(field); } 00431 table_map used_tables() const { return used_tables_cache; } 00432 void update_used_tables (); 00433 bool is_null() { return null_value; } 00434 void make_const () 00435 { 00436 used_tables_cache= 0; 00437 forced_const= TRUE; 00438 } 00439 virtual bool const_item() const { return forced_const; } 00440 virtual bool const_during_execution() const { return false; } 00441 virtual void print(String *str, enum_query_type query_type); 00442 void fix_num_length_and_dec(); 00443 00454 virtual void no_rows_in_result() 00455 { 00456 set_aggregator(with_distinct ? 00457 Aggregator::DISTINCT_AGGREGATOR : 00458 Aggregator::SIMPLE_AGGREGATOR); 00459 aggregator_clear(); 00460 } 00461 virtual void make_unique() { force_copy_fields= TRUE; } 00462 Item *get_tmp_table_item(THD *thd); 00463 virtual Field *create_tmp_field(bool group, TABLE *table); 00464 bool walk(Item_processor processor, bool walk_subquery, uchar *argument); 00465 virtual bool clean_up_after_removal(uchar *arg); 00466 bool init_sum_func_check(THD *thd); 00467 bool check_sum_func(THD *thd, Item **ref); 00468 bool register_sum_func(THD *thd, Item **ref); 00469 st_select_lex *depended_from() 00470 { return (nest_level == aggr_level ? 0 : aggr_sel); } 00471 00472 Item *get_arg(uint i) { return args[i]; } 00473 Item *set_arg(uint i, THD *thd, Item *new_val); 00474 uint get_arg_count() const { return arg_count; } 00475 00476 /* Initialization of distinct related members */ 00477 void init_aggregator() 00478 { 00479 aggr= NULL; 00480 with_distinct= FALSE; 00481 force_copy_fields= FALSE; 00482 } 00483 00488 inline bool aggregator_setup(THD *thd) { return aggr->setup(thd); }; 00489 00494 inline void aggregator_clear() { aggr->clear(); } 00495 00500 inline bool aggregator_add() { return aggr->add(); }; 00501 00502 /* stores the declared DISTINCT flag (from the parser) */ 00503 void set_distinct(bool distinct) 00504 { 00505 with_distinct= distinct; 00506 quick_group= with_distinct ? 0 : 1; 00507 } 00508 00509 /* 00510 Set the type of aggregation : DISTINCT or not. 00511 00512 May be called multiple times. 00513 */ 00514 00515 int set_aggregator(Aggregator::Aggregator_type aggregator); 00516 00517 virtual void clear()= 0; 00518 virtual bool add()= 0; 00519 virtual bool setup(THD *thd) { return false; } 00520 00521 virtual void cleanup(); 00522 }; 00523 00524 00525 class Unique; 00526 00527 00536 class Aggregator_distinct : public Aggregator 00537 { 00538 friend class Item_sum_sum; 00539 00540 /* 00541 flag to prevent consecutive runs of endup(). Normally in endup there are 00542 expensive calculations (like walking the distinct tree for example) 00543 which we must do only once if there are no data changes. 00544 We can re-use the data for the second and subsequent val_xxx() calls. 00545 endup_done set to TRUE also means that the calculated values for 00546 the aggregate functions are correct and don't need recalculation. 00547 */ 00548 bool endup_done; 00549 00550 /* 00551 Used depending on the type of the aggregate function and the presence of 00552 blob columns in it: 00553 - For COUNT(DISTINCT) and no blob fields this points to a real temporary 00554 table. It's used as a hash table. 00555 - For AVG/SUM(DISTINCT) or COUNT(DISTINCT) with blob fields only the 00556 in-memory data structure of a temporary table is constructed. 00557 It's used by the Field classes to transform data into row format. 00558 */ 00559 TABLE *table; 00560 00561 /* 00562 An array of field lengths on row allocated and used only for 00563 COUNT(DISTINCT) with multiple columns and no blobs. Used in 00564 Aggregator_distinct::composite_key_cmp (called from Unique to compare 00565 nodes 00566 */ 00567 uint32 *field_lengths; 00568 00569 /* 00570 Used in conjunction with 'table' to support the access to Field classes 00571 for COUNT(DISTINCT). Needed by copy_fields()/copy_funcs(). 00572 */ 00573 TMP_TABLE_PARAM *tmp_table_param; 00574 00575 /* 00576 If there are no blobs in the COUNT(DISTINCT) arguments, we can use a tree, 00577 which is faster than heap table. In that case, we still use the table 00578 to help get things set up, but we insert nothing in it. 00579 For AVG/SUM(DISTINCT) we always use this tree (as it takes a single 00580 argument) to get the distinct rows. 00581 */ 00582 Unique *tree; 00583 00584 /* 00585 The length of the temp table row. Must be a member of the class as it 00586 gets passed down to simple_raw_key_cmp () as a compare function argument 00587 to Unique. simple_raw_key_cmp () is used as a fast comparison function 00588 when the entire row can be binary compared. 00589 */ 00590 uint tree_key_length; 00591 00592 enum Const_distinct{ 00593 NOT_CONST= 0, 00601 CONST_NULL, 00608 CONST_NOT_NULL 00609 } const_distinct; 00610 00619 bool use_distinct_values; 00620 00621 public: 00622 Aggregator_distinct (Item_sum *sum) : 00623 Aggregator(sum), table(NULL), tmp_table_param(NULL), tree(NULL), 00624 const_distinct(NOT_CONST), use_distinct_values(false) {} 00625 virtual ~Aggregator_distinct (); 00626 Aggregator_type Aggrtype() { return DISTINCT_AGGREGATOR; } 00627 00628 bool setup(THD *); 00629 void clear(); 00630 bool add(); 00631 void endup(); 00632 virtual my_decimal *arg_val_decimal(my_decimal * value); 00633 virtual double arg_val_real(); 00634 virtual bool arg_is_null(bool use_null_value); 00635 00636 bool unique_walk_function(void *element); 00637 static int composite_key_cmp(void* arg, uchar* key1, uchar* key2); 00638 }; 00639 00640 00646 class Aggregator_simple : public Aggregator 00647 { 00648 public: 00649 00650 Aggregator_simple (Item_sum *sum) : 00651 Aggregator(sum) {} 00652 Aggregator_type Aggrtype() { return Aggregator::SIMPLE_AGGREGATOR; } 00653 00654 bool setup(THD * thd) { return item_sum->setup(thd); } 00655 void clear() { item_sum->clear(); } 00656 bool add() { return item_sum->add(); } 00657 void endup() {}; 00658 virtual my_decimal *arg_val_decimal(my_decimal * value); 00659 virtual double arg_val_real(); 00660 virtual bool arg_is_null(bool use_null_value); 00661 }; 00662 00663 00664 class Item_sum_num :public Item_sum 00665 { 00666 protected: 00667 /* 00668 val_xxx() functions may be called several times during the execution of a 00669 query. Derived classes that require extensive calculation in val_xxx() 00670 maintain cache of aggregate value. This variable governs the validity of 00671 that cache. 00672 */ 00673 bool is_evaluated; 00674 public: 00675 Item_sum_num() :Item_sum(),is_evaluated(FALSE) {} 00676 Item_sum_num(Item *item_par) 00677 :Item_sum(item_par), is_evaluated(FALSE) {} 00678 Item_sum_num(Item *a, Item* b) :Item_sum(a,b),is_evaluated(FALSE) {} 00679 Item_sum_num(List<Item> &list) 00680 :Item_sum(list), is_evaluated(FALSE) {} 00681 Item_sum_num(THD *thd, Item_sum_num *item) 00682 :Item_sum(thd, item),is_evaluated(item->is_evaluated) {} 00683 bool fix_fields(THD *, Item **); 00684 longlong val_int() 00685 { 00686 DBUG_ASSERT(fixed == 1); 00687 return (longlong) rint(val_real()); /* Real as default */ 00688 } 00689 String *val_str(String*str); 00690 my_decimal *val_decimal(my_decimal *); 00691 bool get_date(MYSQL_TIME *ltime, uint fuzzydate) 00692 { 00693 return get_date_from_numeric(ltime, fuzzydate); /* Decimal or real */ 00694 } 00695 bool get_time(MYSQL_TIME *ltime) 00696 { 00697 return get_time_from_numeric(ltime); /* Decimal or real */ 00698 } 00699 void reset_field(); 00700 }; 00701 00702 00703 class Item_sum_int :public Item_sum_num 00704 { 00705 public: 00706 Item_sum_int(Item *item_par) :Item_sum_num(item_par) {} 00707 Item_sum_int(List<Item> &list) :Item_sum_num(list) {} 00708 Item_sum_int(THD *thd, Item_sum_int *item) :Item_sum_num(thd, item) {} 00709 double val_real() { DBUG_ASSERT(fixed == 1); return (double) val_int(); } 00710 String *val_str(String*str); 00711 my_decimal *val_decimal(my_decimal *); 00712 bool get_date(MYSQL_TIME *ltime, uint fuzzydate) 00713 { 00714 return get_date_from_int(ltime, fuzzydate); 00715 } 00716 bool get_time(MYSQL_TIME *ltime) 00717 { 00718 return get_time_from_int(ltime); 00719 } 00720 enum Item_result result_type () const { return INT_RESULT; } 00721 void fix_length_and_dec() 00722 { decimals=0; max_length=21; maybe_null=null_value=0; } 00723 }; 00724 00725 00726 class Item_sum_sum :public Item_sum_num 00727 { 00728 protected: 00729 Item_result hybrid_type; 00730 double sum; 00731 my_decimal dec_buffs[2]; 00732 uint curr_dec_buff; 00733 void fix_length_and_dec(); 00734 00735 public: 00736 Item_sum_sum(Item *item_par, bool distinct) :Item_sum_num(item_par) 00737 { 00738 set_distinct(distinct); 00739 } 00740 Item_sum_sum(THD *thd, Item_sum_sum *item); 00741 enum Sumfunctype sum_func () const 00742 { 00743 return has_with_distinct() ? SUM_DISTINCT_FUNC : SUM_FUNC; 00744 } 00745 void clear(); 00746 bool add(); 00747 double val_real(); 00748 longlong val_int(); 00749 String *val_str(String*str); 00750 my_decimal *val_decimal(my_decimal *); 00751 enum Item_result result_type () const { return hybrid_type; } 00752 void reset_field(); 00753 void update_field(); 00754 void no_rows_in_result() {} 00755 const char *func_name() const 00756 { 00757 return has_with_distinct() ? "sum(distinct " : "sum("; 00758 } 00759 Item *copy_or_same(THD* thd); 00760 }; 00761 00762 00763 class Item_sum_count :public Item_sum_int 00764 { 00765 longlong count; 00766 00767 friend class Aggregator_distinct; 00768 00769 void clear(); 00770 bool add(); 00771 void cleanup(); 00772 00773 public: 00774 Item_sum_count(Item *item_par) 00775 :Item_sum_int(item_par),count(0) 00776 {} 00777 00786 Item_sum_count(List<Item> &list) 00787 :Item_sum_int(list),count(0) 00788 { 00789 set_distinct(TRUE); 00790 } 00791 Item_sum_count(THD *thd, Item_sum_count *item) 00792 :Item_sum_int(thd, item), count(item->count) 00793 {} 00794 enum Sumfunctype sum_func () const 00795 { 00796 return has_with_distinct() ? COUNT_DISTINCT_FUNC : COUNT_FUNC; 00797 } 00798 void no_rows_in_result() { count=0; } 00799 void make_const(longlong count_arg) 00800 { 00801 count=count_arg; 00802 Item_sum::make_const(); 00803 } 00804 longlong val_int(); 00805 void reset_field(); 00806 void update_field(); 00807 const char *func_name() const 00808 { 00809 return has_with_distinct() ? "count(distinct " : "count("; 00810 } 00811 Item *copy_or_same(THD* thd); 00812 }; 00813 00814 00815 /* Item to get the value of a stored sum function */ 00816 00817 class Item_sum_avg; 00818 00824 class Item_sum_num_field: public Item_result_field 00825 { 00826 protected: 00827 Field *field; 00828 Item_result hybrid_type; 00829 public: 00830 longlong val_int() 00831 { 00832 /* can't be fix_fields()ed */ 00833 return (longlong) rint(val_real()); 00834 } 00835 bool get_date(MYSQL_TIME *ltime, uint fuzzydate) 00836 { 00837 return get_date_from_numeric(ltime, fuzzydate); /* Decimal or real */ 00838 } 00839 bool get_time(MYSQL_TIME *ltime) 00840 { 00841 return get_time_from_numeric(ltime); /* Decimal or real */ 00842 } 00843 enum_field_types field_type() const 00844 { 00845 return hybrid_type == DECIMAL_RESULT ? 00846 MYSQL_TYPE_NEWDECIMAL : MYSQL_TYPE_DOUBLE; 00847 } 00848 enum Item_result result_type () const { return hybrid_type; } 00849 bool is_null() { update_null_value(); return null_value; } 00850 }; 00851 00852 00853 class Item_avg_field :public Item_sum_num_field 00854 { 00855 public: 00856 uint f_precision, f_scale, dec_bin_size; 00857 uint prec_increment; 00858 Item_avg_field(Item_result res_type, Item_sum_avg *item); 00859 enum Type type() const { return FIELD_AVG_ITEM; } 00860 double val_real(); 00861 my_decimal *val_decimal(my_decimal *); 00862 String *val_str(String*); 00863 void fix_length_and_dec() {} 00864 const char *func_name() const { DBUG_ASSERT(0); return "avg_field"; } 00865 }; 00866 00867 00868 class Item_sum_avg :public Item_sum_sum 00869 { 00870 public: 00871 ulonglong count; 00872 uint prec_increment; 00873 uint f_precision, f_scale, dec_bin_size; 00874 Item_sum_avg(Item *item_par, bool distinct) 00875 :Item_sum_sum(item_par, distinct), count(0) 00876 {} 00877 Item_sum_avg(THD *thd, Item_sum_avg *item) 00878 :Item_sum_sum(thd, item), count(item->count), 00879 prec_increment(item->prec_increment) {} 00880 00881 void fix_length_and_dec(); 00882 enum Sumfunctype sum_func () const 00883 { 00884 return has_with_distinct() ? AVG_DISTINCT_FUNC : AVG_FUNC; 00885 } 00886 void clear(); 00887 bool add(); 00888 double val_real(); 00889 // In SPs we might force the "wrong" type with select into a declare variable 00890 longlong val_int() { return (longlong) rint(val_real()); } 00891 my_decimal *val_decimal(my_decimal *); 00892 String *val_str(String *str); 00893 void reset_field(); 00894 void update_field(); 00895 Item *result_item(Field *field) 00896 { return new Item_avg_field(hybrid_type, this); } 00897 void no_rows_in_result() {} 00898 const char *func_name() const 00899 { 00900 return has_with_distinct() ? "avg(distinct " : "avg("; 00901 } 00902 Item *copy_or_same(THD* thd); 00903 Field *create_tmp_field(bool group, TABLE *table); 00904 void cleanup() 00905 { 00906 count= 0; 00907 Item_sum_sum::cleanup(); 00908 } 00909 }; 00910 00911 class Item_sum_variance; 00912 00913 class Item_variance_field :public Item_sum_num_field 00914 { 00915 protected: 00916 uint f_precision0, f_scale0; 00917 uint f_precision1, f_scale1; 00918 uint dec_bin_size0, dec_bin_size1; 00919 uint sample; 00920 uint prec_increment; 00921 public: 00922 Item_variance_field(Item_sum_variance *item); 00923 enum Type type() const {return FIELD_VARIANCE_ITEM; } 00924 double val_real(); 00925 String *val_str(String *str) 00926 { return val_string_from_real(str); } 00927 my_decimal *val_decimal(my_decimal *dec_buf) 00928 { return val_decimal_from_real(dec_buf); } 00929 void fix_length_and_dec() {} 00930 const char *func_name() const { DBUG_ASSERT(0); return "variance_field"; } 00931 }; 00932 00933 00934 /* 00935 variance(a) = 00936 00937 = sum (ai - avg(a))^2 / count(a) ) 00938 = sum (ai^2 - 2*ai*avg(a) + avg(a)^2) / count(a) 00939 = (sum(ai^2) - sum(2*ai*avg(a)) + sum(avg(a)^2))/count(a) = 00940 = (sum(ai^2) - 2*avg(a)*sum(a) + count(a)*avg(a)^2)/count(a) = 00941 = (sum(ai^2) - 2*sum(a)*sum(a)/count(a) + count(a)*sum(a)^2/count(a)^2 )/count(a) = 00942 = (sum(ai^2) - 2*sum(a)^2/count(a) + sum(a)^2/count(a) )/count(a) = 00943 = (sum(ai^2) - sum(a)^2/count(a))/count(a) 00944 00945 But, this falls prey to catastrophic cancellation. Instead, use the recurrence formulas 00946 00947 M_{1} = x_{1}, ~ M_{k} = M_{k-1} + (x_{k} - M_{k-1}) / k newline 00948 S_{1} = 0, ~ S_{k} = S_{k-1} + (x_{k} - M_{k-1}) times (x_{k} - M_{k}) newline 00949 for 2 <= k <= n newline 00950 ital variance = S_{n} / (n-1) 00951 00952 */ 00953 00954 class Item_sum_variance : public Item_sum_num 00955 { 00956 void fix_length_and_dec(); 00957 00958 public: 00959 Item_result hybrid_type; 00960 int cur_dec; 00961 double recurrence_m, recurrence_s; /* Used in recurrence relation. */ 00962 ulonglong count; 00963 uint f_precision0, f_scale0; 00964 uint f_precision1, f_scale1; 00965 uint dec_bin_size0, dec_bin_size1; 00966 uint sample; 00967 uint prec_increment; 00968 00969 Item_sum_variance(Item *item_par, uint sample_arg) :Item_sum_num(item_par), 00970 hybrid_type(REAL_RESULT), count(0), sample(sample_arg) 00971 {} 00972 Item_sum_variance(THD *thd, Item_sum_variance *item); 00973 enum Sumfunctype sum_func () const { return VARIANCE_FUNC; } 00974 void clear(); 00975 bool add(); 00976 double val_real(); 00977 my_decimal *val_decimal(my_decimal *); 00978 void reset_field(); 00979 void update_field(); 00980 Item *result_item(Field *field) 00981 { return new Item_variance_field(this); } 00982 void no_rows_in_result() {} 00983 const char *func_name() const 00984 { return sample ? "var_samp(" : "variance("; } 00985 Item *copy_or_same(THD* thd); 00986 Field *create_tmp_field(bool group, TABLE *table); 00987 enum Item_result result_type () const { return REAL_RESULT; } 00988 void cleanup() 00989 { 00990 count= 0; 00991 Item_sum_num::cleanup(); 00992 } 00993 }; 00994 00995 class Item_sum_std; 00996 00997 class Item_std_field :public Item_variance_field 00998 { 00999 public: 01000 Item_std_field(Item_sum_std *item); 01001 enum Type type() const { return FIELD_STD_ITEM; } 01002 double val_real(); 01003 my_decimal *val_decimal(my_decimal *); 01004 enum Item_result result_type () const { return REAL_RESULT; } 01005 enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE;} 01006 const char *func_name() const { DBUG_ASSERT(0); return "std_field"; } 01007 }; 01008 01009 /* 01010 standard_deviation(a) = sqrt(variance(a)) 01011 */ 01012 01013 class Item_sum_std :public Item_sum_variance 01014 { 01015 public: 01016 Item_sum_std(Item *item_par, uint sample_arg) 01017 :Item_sum_variance(item_par, sample_arg) {} 01018 Item_sum_std(THD *thd, Item_sum_std *item) 01019 :Item_sum_variance(thd, item) 01020 {} 01021 enum Sumfunctype sum_func () const { return STD_FUNC; } 01022 double val_real(); 01023 Item *result_item(Field *field) 01024 { return new Item_std_field(this); } 01025 const char *func_name() const { return "std("; } 01026 Item *copy_or_same(THD* thd); 01027 enum Item_result result_type () const { return REAL_RESULT; } 01028 enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE;} 01029 }; 01030 01031 // This class is a string or number function depending on num_func 01032 class Arg_comparator; 01033 class Item_cache; 01034 class Item_sum_hybrid :public Item_sum 01035 { 01036 protected: 01037 Item_cache *value, *arg_cache; 01038 Arg_comparator *cmp; 01039 Item_result hybrid_type; 01040 enum_field_types hybrid_field_type; 01041 int cmp_sign; 01042 bool was_values; // Set if we have found at least one row (for max/min only) 01043 01044 public: 01045 Item_sum_hybrid(Item *item_par,int sign) 01046 :Item_sum(item_par), value(0), arg_cache(0), cmp(0), 01047 hybrid_type(INT_RESULT), hybrid_field_type(MYSQL_TYPE_LONGLONG), 01048 cmp_sign(sign), was_values(TRUE) 01049 { collation.set(&my_charset_bin); } 01050 Item_sum_hybrid(THD *thd, Item_sum_hybrid *item) 01051 :Item_sum(thd, item), value(item->value), arg_cache(0), 01052 hybrid_type(item->hybrid_type), hybrid_field_type(item->hybrid_field_type), 01053 cmp_sign(item->cmp_sign), was_values(item->was_values) 01054 { } 01055 bool fix_fields(THD *, Item **); 01056 void setup_hybrid(Item *item, Item *value_arg); 01057 void clear(); 01058 double val_real(); 01059 longlong val_int(); 01060 longlong val_time_temporal(); 01061 longlong val_date_temporal(); 01062 my_decimal *val_decimal(my_decimal *); 01063 bool get_date(MYSQL_TIME *ltime, uint fuzzydate); 01064 bool get_time(MYSQL_TIME *ltime); 01065 void reset_field(); 01066 String *val_str(String *); 01067 bool keep_field_type(void) const { return 1; } 01068 enum Item_result result_type () const { return hybrid_type; } 01069 enum enum_field_types field_type() const { return hybrid_field_type; } 01070 void update_field(); 01071 void min_max_update_str_field(); 01072 void min_max_update_temporal_field(); 01073 void min_max_update_real_field(); 01074 void min_max_update_int_field(); 01075 void min_max_update_decimal_field(); 01076 void cleanup(); 01077 bool any_value() { return was_values; } 01078 void no_rows_in_result(); 01079 Field *create_tmp_field(bool group, TABLE *table); 01080 }; 01081 01082 01083 class Item_sum_min :public Item_sum_hybrid 01084 { 01085 public: 01086 Item_sum_min(Item *item_par) :Item_sum_hybrid(item_par,1) {} 01087 Item_sum_min(THD *thd, Item_sum_min *item) :Item_sum_hybrid(thd, item) {} 01088 enum Sumfunctype sum_func () const {return MIN_FUNC;} 01089 01090 bool add(); 01091 const char *func_name() const { return "min("; } 01092 Item *copy_or_same(THD* thd); 01093 }; 01094 01095 01096 class Item_sum_max :public Item_sum_hybrid 01097 { 01098 public: 01099 Item_sum_max(Item *item_par) :Item_sum_hybrid(item_par,-1) {} 01100 Item_sum_max(THD *thd, Item_sum_max *item) :Item_sum_hybrid(thd, item) {} 01101 enum Sumfunctype sum_func () const {return MAX_FUNC;} 01102 01103 bool add(); 01104 const char *func_name() const { return "max("; } 01105 Item *copy_or_same(THD* thd); 01106 }; 01107 01108 01109 class Item_sum_bit :public Item_sum_int 01110 { 01111 protected: 01112 ulonglong reset_bits,bits; 01113 01114 public: 01115 Item_sum_bit(Item *item_par,ulonglong reset_arg) 01116 :Item_sum_int(item_par),reset_bits(reset_arg),bits(reset_arg) {} 01117 Item_sum_bit(THD *thd, Item_sum_bit *item): 01118 Item_sum_int(thd, item), reset_bits(item->reset_bits), bits(item->bits) {} 01119 enum Sumfunctype sum_func () const {return SUM_BIT_FUNC;} 01120 void clear(); 01121 longlong val_int(); 01122 void reset_field(); 01123 void update_field(); 01124 void fix_length_and_dec() 01125 { decimals= 0; max_length=21; unsigned_flag= 1; maybe_null= null_value= 0; } 01126 void cleanup() 01127 { 01128 bits= reset_bits; 01129 Item_sum_int::cleanup(); 01130 } 01131 }; 01132 01133 01134 class Item_sum_or :public Item_sum_bit 01135 { 01136 public: 01137 Item_sum_or(Item *item_par) :Item_sum_bit(item_par,LL(0)) {} 01138 Item_sum_or(THD *thd, Item_sum_or *item) :Item_sum_bit(thd, item) {} 01139 bool add(); 01140 const char *func_name() const { return "bit_or("; } 01141 Item *copy_or_same(THD* thd); 01142 }; 01143 01144 01145 class Item_sum_and :public Item_sum_bit 01146 { 01147 public: 01148 Item_sum_and(Item *item_par) :Item_sum_bit(item_par, ULONGLONG_MAX) {} 01149 Item_sum_and(THD *thd, Item_sum_and *item) :Item_sum_bit(thd, item) {} 01150 bool add(); 01151 const char *func_name() const { return "bit_and("; } 01152 Item *copy_or_same(THD* thd); 01153 }; 01154 01155 class Item_sum_xor :public Item_sum_bit 01156 { 01157 public: 01158 Item_sum_xor(Item *item_par) :Item_sum_bit(item_par,LL(0)) {} 01159 Item_sum_xor(THD *thd, Item_sum_xor *item) :Item_sum_bit(thd, item) {} 01160 bool add(); 01161 const char *func_name() const { return "bit_xor("; } 01162 Item *copy_or_same(THD* thd); 01163 }; 01164 01165 01166 /* 01167 User defined aggregates 01168 */ 01169 01170 #ifdef HAVE_DLOPEN 01171 01172 class Item_udf_sum : public Item_sum 01173 { 01174 protected: 01175 udf_handler udf; 01176 01177 public: 01178 Item_udf_sum(udf_func *udf_arg) 01179 :Item_sum(), udf(udf_arg) 01180 { quick_group=0; } 01181 Item_udf_sum(udf_func *udf_arg, List<Item> &list) 01182 :Item_sum(list), udf(udf_arg) 01183 { quick_group=0;} 01184 Item_udf_sum(THD *thd, Item_udf_sum *item) 01185 :Item_sum(thd, item), udf(item->udf) 01186 { udf.not_original= TRUE; } 01187 const char *func_name() const { return udf.name(); } 01188 bool fix_fields(THD *thd, Item **ref) 01189 { 01190 DBUG_ASSERT(fixed == 0); 01191 01192 if (init_sum_func_check(thd)) 01193 return TRUE; 01194 01195 fixed= 1; 01196 if (udf.fix_fields(thd, this, this->arg_count, this->args)) 01197 return TRUE; 01198 01199 memcpy (orig_args, args, sizeof (Item *) * arg_count); 01200 return check_sum_func(thd, ref); 01201 } 01202 enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; } 01203 virtual bool have_field_update(void) const { return 0; } 01204 01205 void clear(); 01206 bool add(); 01207 void reset_field() {}; 01208 void update_field() {}; 01209 void cleanup(); 01210 virtual void print(String *str, enum_query_type query_type); 01211 }; 01212 01213 01214 class Item_sum_udf_float :public Item_udf_sum 01215 { 01216 public: 01217 Item_sum_udf_float(udf_func *udf_arg) 01218 :Item_udf_sum(udf_arg) {} 01219 Item_sum_udf_float(udf_func *udf_arg, List<Item> &list) 01220 :Item_udf_sum(udf_arg, list) {} 01221 Item_sum_udf_float(THD *thd, Item_sum_udf_float *item) 01222 :Item_udf_sum(thd, item) {} 01223 longlong val_int() 01224 { 01225 DBUG_ASSERT(fixed == 1); 01226 return (longlong) rint(Item_sum_udf_float::val_real()); 01227 } 01228 double val_real(); 01229 String *val_str(String*str); 01230 my_decimal *val_decimal(my_decimal *); 01231 bool get_date(MYSQL_TIME *ltime, uint fuzzydate) 01232 { 01233 return get_date_from_real(ltime, fuzzydate); 01234 } 01235 bool get_time(MYSQL_TIME *ltime) 01236 { 01237 return get_time_from_real(ltime); 01238 } 01239 void fix_length_and_dec() { fix_num_length_and_dec(); } 01240 Item *copy_or_same(THD* thd); 01241 }; 01242 01243 01244 class Item_sum_udf_int :public Item_udf_sum 01245 { 01246 public: 01247 Item_sum_udf_int(udf_func *udf_arg) 01248 :Item_udf_sum(udf_arg) {} 01249 Item_sum_udf_int(udf_func *udf_arg, List<Item> &list) 01250 :Item_udf_sum(udf_arg, list) {} 01251 Item_sum_udf_int(THD *thd, Item_sum_udf_int *item) 01252 :Item_udf_sum(thd, item) {} 01253 longlong val_int(); 01254 double val_real() 01255 { DBUG_ASSERT(fixed == 1); return (double) Item_sum_udf_int::val_int(); } 01256 String *val_str(String*str); 01257 my_decimal *val_decimal(my_decimal *); 01258 bool get_date(MYSQL_TIME *ltime, uint fuzzydate) 01259 { 01260 return get_date_from_int(ltime, fuzzydate); 01261 } 01262 bool get_time(MYSQL_TIME *ltime) 01263 { 01264 return get_time_from_int(ltime); 01265 } 01266 enum Item_result result_type () const { return INT_RESULT; } 01267 void fix_length_and_dec() { decimals=0; max_length=21; } 01268 Item *copy_or_same(THD* thd); 01269 }; 01270 01271 01272 class Item_sum_udf_str :public Item_udf_sum 01273 { 01274 public: 01275 Item_sum_udf_str(udf_func *udf_arg) 01276 :Item_udf_sum(udf_arg) {} 01277 Item_sum_udf_str(udf_func *udf_arg, List<Item> &list) 01278 :Item_udf_sum(udf_arg,list) {} 01279 Item_sum_udf_str(THD *thd, Item_sum_udf_str *item) 01280 :Item_udf_sum(thd, item) {} 01281 String *val_str(String *); 01282 double val_real() 01283 { 01284 int err_not_used; 01285 char *end_not_used; 01286 String *res; 01287 res=val_str(&str_value); 01288 return res ? my_strntod(res->charset(),(char*) res->ptr(),res->length(), 01289 &end_not_used, &err_not_used) : 0.0; 01290 } 01291 longlong val_int() 01292 { 01293 int err_not_used; 01294 char *end; 01295 String *res; 01296 const CHARSET_INFO *cs; 01297 01298 if (!(res= val_str(&str_value))) 01299 return 0; /* Null value */ 01300 cs= res->charset(); 01301 end= (char*) res->ptr()+res->length(); 01302 return cs->cset->strtoll10(cs, res->ptr(), &end, &err_not_used); 01303 } 01304 my_decimal *val_decimal(my_decimal *dec); 01305 bool get_date(MYSQL_TIME *ltime, uint fuzzydate) 01306 { 01307 return get_date_from_string(ltime, fuzzydate); 01308 } 01309 bool get_time(MYSQL_TIME *ltime) 01310 { 01311 return get_time_from_string(ltime); 01312 } 01313 enum Item_result result_type () const { return STRING_RESULT; } 01314 void fix_length_and_dec(); 01315 Item *copy_or_same(THD* thd); 01316 }; 01317 01318 01319 class Item_sum_udf_decimal :public Item_udf_sum 01320 { 01321 public: 01322 Item_sum_udf_decimal(udf_func *udf_arg) 01323 :Item_udf_sum(udf_arg) {} 01324 Item_sum_udf_decimal(udf_func *udf_arg, List<Item> &list) 01325 :Item_udf_sum(udf_arg, list) {} 01326 Item_sum_udf_decimal(THD *thd, Item_sum_udf_decimal *item) 01327 :Item_udf_sum(thd, item) {} 01328 String *val_str(String *); 01329 double val_real(); 01330 longlong val_int(); 01331 my_decimal *val_decimal(my_decimal *); 01332 bool get_date(MYSQL_TIME *ltime, uint fuzzydate) 01333 { 01334 return get_date_from_decimal(ltime, fuzzydate); 01335 } 01336 bool get_time(MYSQL_TIME *ltime) 01337 { 01338 return get_time_from_decimal(ltime); 01339 } 01340 enum Item_result result_type () const { return DECIMAL_RESULT; } 01341 void fix_length_and_dec() { fix_num_length_and_dec(); } 01342 Item *copy_or_same(THD* thd); 01343 }; 01344 01345 #else /* Dummy functions to get sql_yacc.cc compiled */ 01346 01347 class Item_sum_udf_float :public Item_sum_num 01348 { 01349 public: 01350 Item_sum_udf_float(udf_func *udf_arg) 01351 :Item_sum_num() {} 01352 Item_sum_udf_float(udf_func *udf_arg, List<Item> &list) :Item_sum_num() {} 01353 Item_sum_udf_float(THD *thd, Item_sum_udf_float *item) 01354 :Item_sum_num(thd, item) {} 01355 enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; } 01356 double val_real() { DBUG_ASSERT(fixed == 1); return 0.0; } 01357 void clear() {} 01358 bool add() { return 0; } 01359 void update_field() {} 01360 }; 01361 01362 01363 class Item_sum_udf_int :public Item_sum_num 01364 { 01365 public: 01366 Item_sum_udf_int(udf_func *udf_arg) 01367 :Item_sum_num() {} 01368 Item_sum_udf_int(udf_func *udf_arg, List<Item> &list) :Item_sum_num() {} 01369 Item_sum_udf_int(THD *thd, Item_sum_udf_int *item) 01370 :Item_sum_num(thd, item) {} 01371 enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; } 01372 longlong val_int() { DBUG_ASSERT(fixed == 1); return 0; } 01373 double val_real() { DBUG_ASSERT(fixed == 1); return 0; } 01374 void clear() {} 01375 bool add() { return 0; } 01376 void update_field() {} 01377 }; 01378 01379 01380 class Item_sum_udf_decimal :public Item_sum_num 01381 { 01382 public: 01383 Item_sum_udf_decimal(udf_func *udf_arg) 01384 :Item_sum_num() {} 01385 Item_sum_udf_decimal(udf_func *udf_arg, List<Item> &list) 01386 :Item_sum_num() {} 01387 Item_sum_udf_decimal(THD *thd, Item_sum_udf_float *item) 01388 :Item_sum_num(thd, item) {} 01389 enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; } 01390 double val_real() { DBUG_ASSERT(fixed == 1); return 0.0; } 01391 my_decimal *val_decimal(my_decimal *) { DBUG_ASSERT(fixed == 1); return 0; } 01392 void clear() {} 01393 bool add() { return 0; } 01394 void update_field() {} 01395 }; 01396 01397 01398 class Item_sum_udf_str :public Item_sum_num 01399 { 01400 public: 01401 Item_sum_udf_str(udf_func *udf_arg) 01402 :Item_sum_num() {} 01403 Item_sum_udf_str(udf_func *udf_arg, List<Item> &list) 01404 :Item_sum_num() {} 01405 Item_sum_udf_str(THD *thd, Item_sum_udf_str *item) 01406 :Item_sum_num(thd, item) {} 01407 String *val_str(String *) 01408 { DBUG_ASSERT(fixed == 1); null_value=1; return 0; } 01409 double val_real() { DBUG_ASSERT(fixed == 1); null_value=1; return 0.0; } 01410 longlong val_int() { DBUG_ASSERT(fixed == 1); null_value=1; return 0; } 01411 enum Item_result result_type () const { return STRING_RESULT; } 01412 void fix_length_and_dec() { maybe_null=1; max_length=0; } 01413 enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; } 01414 void clear() {} 01415 bool add() { return 0; } 01416 void update_field() {} 01417 }; 01418 01419 #endif /* HAVE_DLOPEN */ 01420 01421 C_MODE_START 01422 int group_concat_key_cmp_with_distinct(const void* arg, const void* key1, 01423 const void* key2); 01424 int group_concat_key_cmp_with_order(const void* arg, const void* key1, 01425 const void* key2); 01426 int dump_leaf_key(void* key_arg, 01427 element_count count __attribute__((unused)), 01428 void* item_arg); 01429 C_MODE_END 01430 01431 class Item_func_group_concat : public Item_sum 01432 { 01433 TMP_TABLE_PARAM *tmp_table_param; 01434 String result; 01435 String *separator; 01436 TREE tree_base; 01437 TREE *tree; 01438 01446 Unique *unique_filter; 01447 TABLE *table; 01448 ORDER **order; 01449 Name_resolution_context *context; 01451 uint arg_count_order; 01453 uint arg_count_field; 01454 uint row_count; 01455 bool distinct; 01456 bool warning_for_row; 01457 bool always_null; 01458 bool force_copy_fields; 01459 bool no_appended; 01460 /* 01461 Following is 0 normal object and pointer to original one for copy 01462 (to correctly free resources) 01463 */ 01464 Item_func_group_concat *original; 01465 01466 friend int group_concat_key_cmp_with_distinct(const void* arg, 01467 const void* key1, 01468 const void* key2); 01469 friend int group_concat_key_cmp_with_order(const void* arg, 01470 const void* key1, 01471 const void* key2); 01472 friend int dump_leaf_key(void* key_arg, 01473 element_count count __attribute__((unused)), 01474 void* item_arg); 01475 01476 public: 01477 Item_func_group_concat(Name_resolution_context *context_arg, 01478 bool is_distinct, List<Item> *is_select, 01479 const SQL_I_List<ORDER> &is_order, String *is_separator); 01480 01481 Item_func_group_concat(THD *thd, Item_func_group_concat *item); 01482 ~Item_func_group_concat(); 01483 void cleanup(); 01484 01485 enum Sumfunctype sum_func () const {return GROUP_CONCAT_FUNC;} 01486 const char *func_name() const { return "group_concat"; } 01487 virtual Item_result result_type () const { return STRING_RESULT; } 01488 virtual Field *make_string_field(TABLE *table); 01489 enum_field_types field_type() const 01490 { 01491 if (max_length/collation.collation->mbmaxlen > CONVERT_IF_BIGGER_TO_BLOB ) 01492 return MYSQL_TYPE_BLOB; 01493 else 01494 return MYSQL_TYPE_VARCHAR; 01495 } 01496 void clear(); 01497 bool add(); 01498 void reset_field() { DBUG_ASSERT(0); } // not used 01499 void update_field() { DBUG_ASSERT(0); } // not used 01500 bool fix_fields(THD *,Item **); 01501 bool setup(THD *thd); 01502 void make_unique(); 01503 double val_real() 01504 { 01505 String *res; res=val_str(&str_value); 01506 return res ? my_atof(res->c_ptr()) : 0.0; 01507 } 01508 longlong val_int() 01509 { 01510 String *res; 01511 char *end_ptr; 01512 int error; 01513 if (!(res= val_str(&str_value))) 01514 return (longlong) 0; 01515 end_ptr= (char*) res->ptr()+ res->length(); 01516 return my_strtoll10(res->ptr(), &end_ptr, &error); 01517 } 01518 my_decimal *val_decimal(my_decimal *decimal_value) 01519 { 01520 return val_decimal_from_string(decimal_value); 01521 } 01522 bool get_date(MYSQL_TIME *ltime, uint fuzzydate) 01523 { 01524 return get_date_from_string(ltime, fuzzydate); 01525 } 01526 bool get_time(MYSQL_TIME *ltime) 01527 { 01528 return get_time_from_string(ltime); 01529 } 01530 String* val_str(String* str); 01531 Item *copy_or_same(THD* thd); 01532 void no_rows_in_result() {} 01533 virtual void print(String *str, enum_query_type query_type); 01534 virtual bool change_context_processor(uchar *cntx) 01535 { context= (Name_resolution_context *)cntx; return FALSE; } 01536 }; 01537 01538 #endif /* ITEM_SUM_INCLUDED */