diff options
author | Igor Babaev <igor@askmonty.org> | 2017-02-09 19:33:28 -0800 |
---|---|---|
committer | Igor Babaev <igor@askmonty.org> | 2017-02-09 19:34:01 -0800 |
commit | 78b5e8d6ca35be35cf2f10769c19cd7dacad09d2 (patch) | |
tree | c161313228a6dd6bae2964dc99f72c613e9f0d47 /sql | |
parent | 766ab173297b061f54476e5148da0ef02901d44f (diff) | |
download | mariadb-git-78b5e8d6ca35be35cf2f10769c19cd7dacad09d2.tar.gz |
Fixed bug mdev-11745.
Due to this bug many queries that contained a window function
with MIN/MAX aggregation returned wrong results.
Calculation of a MIN/MAX aggregate function uses cache objects
and a comparator object that are created and set up in
Item_sum_hybrid::fix_fields () by a call of Item_sum_hybrid::setup_hybrid().
The latter binds the objects to the first argument of the
MIN/MAX function. Meanwhile window function perform aggregation
over fields of a temporary table. So binding must be done rather to
these fields. The earliest moment when setup the objects used in
MIN/max functions can be done is after all calls of the method
split_sum_func().
This patch introduces this late setup, but only for aggregate
functions used in window functions.
Probably it makes sense to use this late setup for all MIN/MAX
objects.
Diffstat (limited to 'sql')
-rw-r--r-- | sql/item_sum.cc | 3 | ||||
-rw-r--r-- | sql/item_sum.h | 3 | ||||
-rw-r--r-- | sql/item_windowfunc.cc | 1 |
3 files changed, 6 insertions, 1 deletions
diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 2ca1be31ae1..098b1ea8750 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -1161,7 +1161,8 @@ Item_sum_hybrid::fix_fields(THD *thd, Item **ref) case TIME_RESULT: DBUG_ASSERT(0); }; - setup_hybrid(thd, args[0], NULL); + if (!is_window_func_sum_expr()) + setup_hybrid(thd, args[0], NULL); /* MIN/MAX can return NULL for empty set indepedent of the used column */ maybe_null= 1; result_field=0; diff --git a/sql/item_sum.h b/sql/item_sum.h index a838bd0bc10..57375b29114 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -576,6 +576,8 @@ public: bool check_vcol_func_processor(void *arg); virtual void setup_window_func(THD *thd, Window_spec *window_spec) {} 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) {}; }; @@ -1053,6 +1055,7 @@ protected: void no_rows_in_result(); void restore_to_before_no_rows_in_result(); Field *create_tmp_field(bool group, TABLE *table); + void setup_caches(THD *thd) { setup_hybrid(thd, arguments()[0], NULL); } }; diff --git a/sql/item_windowfunc.cc b/sql/item_windowfunc.cc index a13967eaaad..fb2ad666018 100644 --- a/sql/item_windowfunc.cc +++ b/sql/item_windowfunc.cc @@ -150,6 +150,7 @@ void Item_window_func::split_sum_func(THD *thd, Ref_ptr_array ref_pointer_array, Item **p_item= &window_func()->arguments()[i]; (*p_item)->split_sum_func2(thd, ref_pointer_array, fields, p_item, flags); } + window_func()->setup_caches(thd); } |