summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorIgor Babaev <igor@askmonty.org>2017-02-09 19:33:28 -0800
committerIgor Babaev <igor@askmonty.org>2017-02-09 19:34:01 -0800
commit78b5e8d6ca35be35cf2f10769c19cd7dacad09d2 (patch)
treec161313228a6dd6bae2964dc99f72c613e9f0d47 /sql
parent766ab173297b061f54476e5148da0ef02901d44f (diff)
downloadmariadb-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.cc3
-rw-r--r--sql/item_sum.h3
-rw-r--r--sql/item_windowfunc.cc1
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);
}