From ee9a19fb054085fcea006a25ec957e0d5cb01ce8 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Wed, 25 Dec 2019 12:23:24 +0400 Subject: MDEV-21392 Cleanup redundant overriding in Item_sum_num --- sql/item_sum.cc | 22 +------ sql/item_sum.h | 97 +++++++++++++++++------------ sql/item_windowfunc.h | 164 +++++++++++++++++++++++++++++--------------------- sql/sql_window.cc | 6 +- 4 files changed, 156 insertions(+), 133 deletions(-) (limited to 'sql') diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 08ee190e96c..91b75b776e2 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -1093,19 +1093,6 @@ void Aggregator_distinct::endup() } -String * -Item_sum_num::val_str(String *str) -{ - return val_string_from_real(str); -} - - -my_decimal *Item_sum_num::val_decimal(my_decimal *decimal_value) -{ - return val_decimal_from_real(decimal_value); -} - - String * Item_sum_int::val_str(String *str) { @@ -2188,7 +2175,7 @@ static double variance_fp_recurrence_result(double s, ulonglong count, bool is_s Item_sum_variance::Item_sum_variance(THD *thd, Item_sum_variance *item): - Item_sum_num(thd, item), + Item_sum_double(thd, item), count(item->count), sample(item->sample), prec_increment(item->prec_increment) { @@ -2314,13 +2301,6 @@ double Item_sum_variance::val_real() } -my_decimal *Item_sum_variance::val_decimal(my_decimal *dec_buf) -{ - DBUG_ASSERT(fixed == 1); - return val_decimal_from_real(dec_buf); -} - - void Item_sum_variance::reset_field() { double nr; diff --git a/sql/item_sum.h b/sql/item_sum.h index a3e10c25763..243b6f28944 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -578,6 +578,7 @@ public: void mark_as_window_func_sum_expr() { window_func_sum_expr_flag= true; } bool is_window_func_sum_expr() { return window_func_sum_expr_flag; } virtual void setup_caches(THD *thd) {}; + virtual void set_partition_row_count(ulonglong count) { DBUG_ASSERT(0); } }; @@ -713,33 +714,45 @@ public: class Item_sum_num :public Item_sum { -protected: - /* - val_xxx() functions may be called several times during the execution of a - query. Derived classes that require extensive calculation in val_xxx() - maintain cache of aggregate value. This variable governs the validity of - that cache. - */ - bool is_evaluated; public: - Item_sum_num(THD *thd): Item_sum(thd), is_evaluated(FALSE) {} + Item_sum_num(THD *thd): Item_sum(thd) {} Item_sum_num(THD *thd, Item *item_par): - Item_sum(thd, item_par), is_evaluated(FALSE) {} + Item_sum(thd, item_par) {} Item_sum_num(THD *thd, Item *a, Item* b): - Item_sum(thd, a, b), is_evaluated(FALSE) {} + Item_sum(thd, a, b) {} Item_sum_num(THD *thd, List &list): - Item_sum(thd, list), is_evaluated(FALSE) {} + Item_sum(thd, list) {} Item_sum_num(THD *thd, Item_sum_num *item): - Item_sum(thd, item),is_evaluated(item->is_evaluated) {} + Item_sum(thd, item) {} bool fix_fields(THD *, Item **); - longlong val_int() { return val_int_from_real(); /* Real as default */ } - String *val_str(String*str); - my_decimal *val_decimal(my_decimal *); + void reset_field(); +}; + + +class Item_sum_double :public Item_sum_num +{ +public: + Item_sum_double(THD *thd): Item_sum_num(thd) {} + Item_sum_double(THD *thd, Item *item_par): Item_sum_num(thd, item_par) {} + Item_sum_double(THD *thd, List &list): Item_sum_num(thd, list) {} + Item_sum_double(THD *thd, Item_sum_double *item) :Item_sum_num(thd, item) {} + longlong val_int() + { + return val_int_from_real(); + } + String *val_str(String*str) + { + return val_string_from_real(str); + } + my_decimal *val_decimal(my_decimal *to) + { + return val_decimal_from_real(to); + } bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate) { - return type_handler()->Item_get_date(this, ltime, fuzzydate); + return get_date_from_real(ltime, fuzzydate); } - void reset_field(); + const Type_handler *type_handler() const { return &type_handler_double; } }; @@ -753,6 +766,10 @@ public: double val_real() { DBUG_ASSERT(fixed == 1); return (double) val_int(); } String *val_str(String*str); my_decimal *val_decimal(my_decimal *); + bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate) + { + return get_date_from_int(ltime, fuzzydate); + } const Type_handler *type_handler() const { return &type_handler_longlong; } bool fix_length_and_dec() { decimals=0; max_length=21; maybe_null=null_value=0; return FALSE; } @@ -794,6 +811,10 @@ public: longlong val_int(); String *val_str(String*str); my_decimal *val_decimal(my_decimal *); + bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate) + { + return type_handler()->Item_get_date(this, ltime, fuzzydate); + } const Type_handler *type_handler() const { return Type_handler_hybrid_field_type::type_handler(); } void fix_length_and_dec_double(); @@ -964,7 +985,7 @@ But, this falls prey to catastrophic cancellation. Instead, use the recurrence */ -class Item_sum_variance : public Item_sum_num +class Item_sum_variance : public Item_sum_double { bool fix_length_and_dec(); @@ -975,7 +996,7 @@ public: uint prec_increment; Item_sum_variance(THD *thd, Item *item_par, uint sample_arg): - Item_sum_num(thd, item_par), count(0), + Item_sum_double(thd, item_par), count(0), sample(sample_arg) {} Item_sum_variance(THD *thd, Item_sum_variance *item); @@ -985,7 +1006,6 @@ public: void clear(); bool add(); double val_real(); - my_decimal *val_decimal(my_decimal *); void reset_field(); void update_field(); Item *result_item(THD *thd, Field *field); @@ -994,11 +1014,10 @@ public: { return sample ? "var_samp(" : "variance("; } Item *copy_or_same(THD* thd); Field *create_tmp_field(bool group, TABLE *table); - const Type_handler *type_handler() const { return &type_handler_double; } void cleanup() { count= 0; - Item_sum_num::cleanup(); + Item_sum_double::cleanup(); } Item *get_copy(THD *thd) { return get_item_copy(thd, this); } @@ -1679,15 +1698,15 @@ public: #else /* Dummy functions to get sql_yacc.cc compiled */ -class Item_sum_udf_float :public Item_sum_num +class Item_sum_udf_float :public Item_sum_double { public: Item_sum_udf_float(THD *thd, udf_func *udf_arg): - Item_sum_num(thd) {} + Item_sum_double(thd) {} Item_sum_udf_float(THD *thd, udf_func *udf_arg, List &list): - Item_sum_num(thd) {} + Item_sum_double(thd) {} Item_sum_udf_float(THD *thd, Item_sum_udf_float *item) - :Item_sum_num(thd, item) {} + :Item_sum_double(thd, item) {} enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; } double val_real() { DBUG_ASSERT(fixed == 1); return 0.0; } void clear() {} @@ -1696,15 +1715,15 @@ class Item_sum_udf_float :public Item_sum_num }; -class Item_sum_udf_int :public Item_sum_num +class Item_sum_udf_int :public Item_sum_double { public: Item_sum_udf_int(THD *thd, udf_func *udf_arg): - Item_sum_num(thd) {} + Item_sum_double(thd) {} Item_sum_udf_int(THD *thd, udf_func *udf_arg, List &list): - Item_sum_num(thd) {} + Item_sum_double(thd) {} Item_sum_udf_int(THD *thd, Item_sum_udf_int *item) - :Item_sum_num(thd, item) {} + :Item_sum_double(thd, item) {} enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; } longlong val_int() { DBUG_ASSERT(fixed == 1); return 0; } double val_real() { DBUG_ASSERT(fixed == 1); return 0; } @@ -1714,15 +1733,15 @@ public: }; -class Item_sum_udf_decimal :public Item_sum_num +class Item_sum_udf_decimal :public Item_sum_double { public: Item_sum_udf_decimal(THD *thd, udf_func *udf_arg): - Item_sum_num(thd) {} + Item_sum_double(thd) {} Item_sum_udf_decimal(THD *thd, udf_func *udf_arg, List &list): - Item_sum_num(thd) {} + Item_sum_double(thd) {} Item_sum_udf_decimal(THD *thd, Item_sum_udf_float *item) - :Item_sum_num(thd, item) {} + :Item_sum_double(thd, item) {} enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; } double val_real() { DBUG_ASSERT(fixed == 1); return 0.0; } my_decimal *val_decimal(my_decimal *) { DBUG_ASSERT(fixed == 1); return 0; } @@ -1732,15 +1751,15 @@ class Item_sum_udf_decimal :public Item_sum_num }; -class Item_sum_udf_str :public Item_sum_num +class Item_sum_udf_str :public Item_sum_double { public: Item_sum_udf_str(THD *thd, udf_func *udf_arg): - Item_sum_num(thd) {} + Item_sum_double(thd) {} Item_sum_udf_str(THD *thd, udf_func *udf_arg, List &list): - Item_sum_num(thd) {} + Item_sum_double(thd) {} Item_sum_udf_str(THD *thd, Item_sum_udf_str *item) - :Item_sum_num(thd, item) {} + :Item_sum_double(thd, item) {} String *val_str(String *) { DBUG_ASSERT(fixed == 1); null_value=1; return 0; } double val_real() { DBUG_ASSERT(fixed == 1); null_value=1; return 0.0; } diff --git a/sql/item_windowfunc.h b/sql/item_windowfunc.h index cc67c02f1ee..971b316ca99 100644 --- a/sql/item_windowfunc.h +++ b/sql/item_windowfunc.h @@ -438,27 +438,38 @@ class Item_sum_lag : public Item_sum_hybrid_simple { return get_item_copy(thd, this); } }; -/* - A base window function (aggregate) that also holds a counter for the number - of rows. -*/ -class Item_sum_window_with_row_count : public Item_sum_num -{ - public: - Item_sum_window_with_row_count(THD *thd) : Item_sum_num(thd), - partition_row_count_(0) {} - - Item_sum_window_with_row_count(THD *thd, Item *arg) : - Item_sum_num(thd, arg), partition_row_count_(0) {}; - void set_row_count(ulonglong count) { partition_row_count_ = count; } - - protected: +class Partition_row_count +{ +public: + Partition_row_count() :partition_row_count_(0) { } + void set_partition_row_count(ulonglong count) + { + partition_row_count_ = count; + } + double calc_val_real(bool *null_value, + ulonglong current_row_count) + { + if ((*null_value= (partition_row_count_ == 0))) + return 0; + return static_cast(current_row_count) / partition_row_count_; + } +protected: longlong get_row_count() { return partition_row_count_; } - private: ulonglong partition_row_count_; }; + +class Current_row_count +{ +public: + Current_row_count() :current_row_count_(0) { } +protected: + ulonglong get_row_number() { return current_row_count_ ; } + ulonglong current_row_count_; +}; + + /* @detail "The relative rank of a row R is defined as (RK-1)/(NR-1), where RK is @@ -470,11 +481,12 @@ class Item_sum_window_with_row_count : public Item_sum_num This is held within the row_count context. - Second pass to compute rank of current row and the value of the function */ -class Item_sum_percent_rank: public Item_sum_window_with_row_count +class Item_sum_percent_rank: public Item_sum_double, + public Partition_row_count { public: Item_sum_percent_rank(THD *thd) - : Item_sum_window_with_row_count(thd), cur_rank(1), peer_tracker(NULL) {} + : Item_sum_double(thd), cur_rank(1), peer_tracker(NULL) {} longlong val_int() { @@ -527,6 +539,12 @@ class Item_sum_percent_rank: public Item_sum_window_with_row_count } void setup_window_func(THD *thd, Window_spec *window_spec); + + void set_partition_row_count(ulonglong count) + { + Partition_row_count::set_partition_row_count(count); + } + Item *get_copy(THD *thd) { return get_item_copy(thd, this); } @@ -561,25 +579,17 @@ class Item_sum_percent_rank: public Item_sum_window_with_row_count two passes. */ -class Item_sum_cume_dist: public Item_sum_window_with_row_count +class Item_sum_cume_dist: public Item_sum_double, + public Partition_row_count, + public Current_row_count { public: - Item_sum_cume_dist(THD *thd) : Item_sum_window_with_row_count(thd), - current_row_count_(0) {} - - Item_sum_cume_dist(THD *thd, Item *arg) : Item_sum_window_with_row_count(thd,arg), - current_row_count_(0) {} + Item_sum_cume_dist(THD *thd) :Item_sum_double(thd) { } + Item_sum_cume_dist(THD *thd, Item *arg) :Item_sum_double(thd, arg) { } double val_real() { - if (get_row_count() == 0) - { - null_value= true; - return 0; - } - ulonglong partition_row_count= get_row_count(); - null_value= false; - return static_cast(current_row_count_) / partition_row_count; + return calc_val_real(&null_value, current_row_count_); } bool add() @@ -596,7 +606,7 @@ class Item_sum_cume_dist: public Item_sum_window_with_row_count void clear() { current_row_count_= 0; - set_row_count(0); + partition_row_count_= 0; } const char*func_name() const @@ -614,29 +624,24 @@ class Item_sum_cume_dist: public Item_sum_window_with_row_count return FALSE; } - Item *get_copy(THD *thd) - { return get_item_copy(thd, this); } - - ulonglong get_row_number() + void set_partition_row_count(ulonglong count) { - return current_row_count_ ; + Partition_row_count::set_partition_row_count(count); } - private: - ulonglong current_row_count_; + Item *get_copy(THD *thd) + { return get_item_copy(thd, this); } + }; -class Item_sum_ntile : public Item_sum_window_with_row_count +class Item_sum_ntile : public Item_sum_int, + public Partition_row_count, + public Current_row_count { public: Item_sum_ntile(THD* thd, Item* num_quantiles_expr) : - Item_sum_window_with_row_count(thd, num_quantiles_expr), - current_row_count_(0) {}; - - double val_real() - { - return (double) val_int(); - } + Item_sum_int(thd, num_quantiles_expr) + { } longlong val_int() { @@ -677,7 +682,7 @@ class Item_sum_ntile : public Item_sum_window_with_row_count void clear() { current_row_count_= 0; - set_row_count(0); + partition_row_count_= 0; } const char*func_name() const @@ -687,21 +692,25 @@ class Item_sum_ntile : public Item_sum_window_with_row_count void update_field() {} - const Type_handler *type_handler() const { return &type_handler_longlong; } - + void set_partition_row_count(ulonglong count) + { + Partition_row_count::set_partition_row_count(count); + } + Item *get_copy(THD *thd) { return get_item_copy(thd, this); } private: longlong get_num_quantiles() { return args[0]->val_int(); } - ulong current_row_count_; }; -class Item_sum_percentile_disc : public Item_sum_cume_dist, - public Type_handler_hybrid_field_type +class Item_sum_percentile_disc : public Item_sum_num, + public Type_handler_hybrid_field_type, + public Partition_row_count, + public Current_row_count { public: - Item_sum_percentile_disc(THD *thd, Item* arg) : Item_sum_cume_dist(thd, arg), + Item_sum_percentile_disc(THD *thd, Item* arg) : Item_sum_num(thd, arg), Type_handler_hybrid_field_type(&type_handler_longlong), value(NULL), val_calculated(FALSE), first_call(TRUE), prev_value(0), order_item(NULL){} @@ -750,6 +759,17 @@ public: return value->val_str(str); } + bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate) + { + if (get_row_count() == 0 || get_arg(0)->is_null()) + { + null_value= true; + return 0; + } + null_value= false; + return value->get_date(ltime, fuzzydate); + } + bool add() { Item *arg= get_arg(0); @@ -783,8 +803,8 @@ public: if (value->null_value) return false; - Item_sum_cume_dist::add(); - double val= Item_sum_cume_dist::val_real(); + current_row_count_++; + double val= calc_val_real(&null_value, current_row_count_); if (val >= prev_value && !val_calculated) val_calculated= true; @@ -801,7 +821,8 @@ public: val_calculated= false; first_call= true; value->clear(); - Item_sum_cume_dist::clear(); + partition_row_count_= 0; + current_row_count_= 0; } const char*func_name() const @@ -810,7 +831,6 @@ public: } void update_field() {} - void set_type_handler(Window_spec *window_spec); const Type_handler *type_handler() const {return Type_handler_hybrid_field_type::type_handler();} @@ -821,6 +841,11 @@ public: return FALSE; } + void set_partition_row_count(ulonglong count) + { + Partition_row_count::set_partition_row_count(count); + } + Item *get_copy(THD *thd) { return get_item_copy(thd, this); } void setup_window_func(THD *thd, Window_spec *window_spec); @@ -835,12 +860,12 @@ private: Item *order_item; }; -class Item_sum_percentile_cont : public Item_sum_cume_dist, - public Type_handler_hybrid_field_type +class Item_sum_percentile_cont : public Item_sum_double, + public Partition_row_count, + public Current_row_count { public: - Item_sum_percentile_cont(THD *thd, Item* arg) : Item_sum_cume_dist(thd, arg), - Type_handler_hybrid_field_type(&type_handler_double), + Item_sum_percentile_cont(THD *thd, Item* arg) : Item_sum_double(thd, arg), floor_value(NULL), ceil_value(NULL), first_call(TRUE),prev_value(0), ceil_val_calculated(FALSE), floor_val_calculated(FALSE), order_item(NULL){} @@ -910,7 +935,7 @@ public: return false; } - Item_sum_cume_dist::add(); + current_row_count_++; double val= 1 + prev_value * (get_row_count()-1); if (!floor_val_calculated && get_row_number() == floor(val)) @@ -933,7 +958,8 @@ public: ceil_value->clear(); floor_val_calculated= false; ceil_val_calculated= false; - Item_sum_cume_dist::clear(); + partition_row_count_= 0; + current_row_count_= 0; } const char*func_name() const @@ -941,9 +967,6 @@ public: return "percentile_cont"; } void update_field() {} - void set_type_handler(Window_spec *window_spec); - const Type_handler *type_handler() const - {return Type_handler_hybrid_field_type::type_handler();} bool fix_length_and_dec() { @@ -952,6 +975,11 @@ public: return FALSE; } + void set_partition_row_count(ulonglong count) + { + Partition_row_count::set_partition_row_count(count); + } + Item *get_copy(THD *thd) { return get_item_copy(thd, this); } void setup_window_func(THD *thd, Window_spec *window_spec); diff --git a/sql/sql_window.cc b/sql/sql_window.cc index a6c9dd3fea7..7e319c96000 100644 --- a/sql/sql_window.cc +++ b/sql/sql_window.cc @@ -1779,11 +1779,7 @@ protected: List_iterator_fast it(sum_functions); Item_sum* item; while ((item= it++)) - { - Item_sum_window_with_row_count* item_with_row_count = - static_cast(item); - item_with_row_count->set_row_count(num_rows_in_partition); - } + item->set_partition_row_count(num_rows_in_partition); } }; -- cgit v1.2.1