diff options
author | Tor Didriksen <tor.didriksen@sun.com> | 2009-10-28 11:07:30 +0100 |
---|---|---|
committer | Tor Didriksen <tor.didriksen@sun.com> | 2009-10-28 11:07:30 +0100 |
commit | b2baeed4a7a19ee498e963fe374cf254d230d2bc (patch) | |
tree | 569cf4691c918df46c9d933b2e5ef9f56a1217b4 /sql/item_sum.h | |
parent | 55b8f07a9922f26cc64dbeac2f1cb78519621f16 (diff) | |
download | mariadb-git-b2baeed4a7a19ee498e963fe374cf254d230d2bc.tar.gz |
Bug#48060 Memory leak - Item::val_bool() (item.cc:184) from optimizer_subquery grammar
Item_sum::set_aggregator() may be called multiple times during query preparation.
On subsequent calls: verify that the aggregator type is the same,
and re-use the existing Aggregator.
sql/item_sum.cc:
In Item_sum::set_aggregator(): re-use existing Aggregator if already set.
Remove some friend declarations, add some accessor functions.
Cleanup some DBUG_ENTER and DBUG_RETURN code.
sql/item_sum.h:
Make some member fields private, add accessors instead.
Remove some un-necessary friend declarations.
Remove some default arguments from constructors.
sql/opt_sum.cc:
Use accessor functions in Item_sum.
sql/sql_select.cc:
Fix mis-spelled DBUG_ENTER text.
Use accessor functions in Item_sum.
sql/sql_yacc.yy:
Use explicit true/false rather than default arguments when constructing
Item_sum_xxx objects.
Diffstat (limited to 'sql/item_sum.h')
-rw-r--r-- | sql/item_sum.h | 43 |
1 files changed, 23 insertions, 20 deletions
diff --git a/sql/item_sum.h b/sql/item_sum.h index 62addf4e033..6d7418204fc 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -302,13 +302,14 @@ class st_select_lex; class Item_sum :public Item_result_field { -public: +protected: /** Aggregator class instance. Not set initially. Allocated only after it is determined if the incoming data are already distinct. */ Aggregator *aggr; +private: /** Used in making ROLLUP. Set for the ROLLUP copies of the original Item_sum and passed to create_tmp_field() to cause it to work @@ -324,6 +325,11 @@ public: */ bool with_distinct; +public: + + bool has_force_copy_fields() const { return force_copy_fields; } + bool has_with_distinct() const { return with_distinct; } + enum Sumfunctype { COUNT_FUNC, COUNT_DISTINCT_FUNC, SUM_FUNC, SUM_DISTINCT_FUNC, AVG_FUNC, AVG_DISTINCT_FUNC, MIN_FUNC, MAX_FUNC, STD_FUNC, @@ -447,12 +453,12 @@ public: may be initialized to 0 by clear() and to NULL by no_rows_in_result(). */ - void no_rows_in_result() + virtual void no_rows_in_result() { if (!aggr) - set_aggregator(with_distinct ? - Aggregator::DISTINCT_AGGREGATOR : - Aggregator::SIMPLE_AGGREGATOR); + set_aggregator(with_distinct ? + Aggregator::DISTINCT_AGGREGATOR : + Aggregator::SIMPLE_AGGREGATOR); reset(); } virtual void make_unique() { force_copy_fields= TRUE; } @@ -511,11 +517,12 @@ public: */ int set_aggregator(Aggregator::Aggregator_type aggregator); + virtual void clear()= 0; virtual bool add()= 0; - virtual bool setup(THD *thd) {return 0;} + virtual bool setup(THD *thd) { return false; } - void cleanup (); + virtual void cleanup(); }; @@ -533,9 +540,6 @@ class Unique; class Aggregator_distinct : public Aggregator { friend class Item_sum_sum; - friend class Item_sum_count; - friend class Item_sum_avg; -protected: /* flag to prevent consecutive runs of endup(). Normally in endup there are @@ -567,7 +571,7 @@ protected: uint32 *field_lengths; /* - used in conjunction with 'table' to support the access to Field classes + Used in conjunction with 'table' to support the access to Field classes for COUNT(DISTINCT). Needed by copy_fields()/copy_funcs(). */ TMP_TABLE_PARAM *tmp_table_param; @@ -637,7 +641,6 @@ public: class Item_sum_num :public Item_sum { - friend class Aggregator_distinct; protected: /* val_xxx() functions may be called several times during the execution of a @@ -692,14 +695,14 @@ protected: void fix_length_and_dec(); public: - Item_sum_sum(Item *item_par, bool distinct= FALSE) :Item_sum_num(item_par) + Item_sum_sum(Item *item_par, bool distinct) :Item_sum_num(item_par) { set_distinct(distinct); } Item_sum_sum(THD *thd, Item_sum_sum *item); enum Sumfunctype sum_func () const { - return with_distinct ? SUM_DISTINCT_FUNC : SUM_FUNC; + return has_with_distinct() ? SUM_DISTINCT_FUNC : SUM_FUNC; } void clear(); bool add(); @@ -713,7 +716,7 @@ public: void no_rows_in_result() {} const char *func_name() const { - return with_distinct ? "sum(distinct " : "sum("; + return has_with_distinct() ? "sum(distinct " : "sum("; } Item *copy_or_same(THD* thd); }; @@ -752,7 +755,7 @@ class Item_sum_count :public Item_sum_int {} enum Sumfunctype sum_func () const { - return with_distinct ? COUNT_DISTINCT_FUNC : COUNT_FUNC; + return has_with_distinct() ? COUNT_DISTINCT_FUNC : COUNT_FUNC; } void no_rows_in_result() { count=0; } void make_const(longlong count_arg) @@ -765,7 +768,7 @@ class Item_sum_count :public Item_sum_int void update_field(); const char *func_name() const { - return with_distinct ? "count(distinct " : "count("; + return has_with_distinct() ? "count(distinct " : "count("; } Item *copy_or_same(THD* thd); }; @@ -806,7 +809,7 @@ public: uint prec_increment; uint f_precision, f_scale, dec_bin_size; - Item_sum_avg(Item *item_par, bool distinct= FALSE) + Item_sum_avg(Item *item_par, bool distinct) :Item_sum_sum(item_par, distinct), count(0) {} Item_sum_avg(THD *thd, Item_sum_avg *item) @@ -816,7 +819,7 @@ public: void fix_length_and_dec(); enum Sumfunctype sum_func () const { - return with_distinct ? AVG_DISTINCT_FUNC : AVG_FUNC; + return has_with_distinct() ? AVG_DISTINCT_FUNC : AVG_FUNC; } void clear(); bool add(); @@ -832,7 +835,7 @@ public: void no_rows_in_result() {} const char *func_name() const { - return with_distinct ? "avg(distinct " : "avg("; + return has_with_distinct() ? "avg(distinct " : "avg("; } Item *copy_or_same(THD* thd); Field *create_tmp_field(bool group, TABLE *table, uint convert_blob_length); |