mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
Fix for LP#612894 Some aggregate functions (such as MIN MAX) work incorrectly in subqueries after getting NULL value
mysql-test/r/group_by.result: Added test that showed problems that no_rows_in_results() didn't work for expressions mysql-test/r/subselect4.result: Test case for LP#612894 mysql-test/t/group_by.test: Added test that showed problems that no_rows_in_results() didn't work for expressions mysql-test/t/subselect4.test: Test case for LP#612894 sql/item.h: Added restore_to_before_no_rows_in_result() Added function processor for no_rows_in_results() and restore_to_before_no_rows_in_results() to ensure it works with functions Fix that above functions are handled by Item_ref() sql/item_func.h: Ensure that no_rows_in_results() and restore_to_before_no_rows_in_result() are called for all function arguments sql/item_sum.cc: Added restore_to_before_no_rows_in_result() to restore settings after Item_sum_hybrid::no_rows_in_result() was called. This is needed to handle the case where we have made 'make_const()' on the item in opt_sum(), but the item will be reused again in a sub query. Ignore multiple calls to no_rows_in_result() as Item_ref is calling it twice. sql/item_sum.h: Added restore_to_before_no_rows_in_result(); sql/sql_select.cc: Added reset of no_rows_in_result() for JOIN::reinit() sql/sql_select.h: Added marker if no_rows_in_result() is called.
This commit is contained in:
@@ -365,24 +365,26 @@ public:
|
||||
the number of rows in it may vary from one subquery execution to another.
|
||||
*/
|
||||
bool no_const_tables;
|
||||
bool no_rows_in_result_called;
|
||||
|
||||
/**
|
||||
Copy of this JOIN to be used with temporary tables.
|
||||
|
||||
tmp_join is used when the JOIN needs to be "reusable" (e.g. in a subquery
|
||||
that gets re-executed several times) and we know will use temporary tables
|
||||
for materialization. The materialization to a temporary table overwrites the
|
||||
JOIN structure to point to the temporary table after the materialization is
|
||||
done. This is where tmp_join is used : it's a copy of the JOIN before the
|
||||
materialization and is used in restoring before re-execution by overwriting
|
||||
the current JOIN structure with the saved copy.
|
||||
Because of this we should pay extra care of not freeing up helper structures
|
||||
that are referenced by the original contents of the JOIN. We can check for
|
||||
this by making sure the "current" join is not the temporary copy, e.g.
|
||||
!tmp_join || tmp_join != join
|
||||
tmp_join is used when the JOIN needs to be "reusable" (e.g. in a
|
||||
subquery that gets re-executed several times) and we know will use
|
||||
temporary tables for materialization. The materialization to a
|
||||
temporary table overwrites the JOIN structure to point to the
|
||||
temporary table after the materialization is done. This is where
|
||||
tmp_join is used : it's a copy of the JOIN before the
|
||||
materialization and is used in restoring before re-execution by
|
||||
overwriting the current JOIN structure with the saved copy.
|
||||
Because of this we should pay extra care of not freeing up helper
|
||||
structures that are referenced by the original contents of the
|
||||
JOIN. We can check for this by making sure the "current" join is
|
||||
not the temporary copy, e.g. !tmp_join || tmp_join != join
|
||||
|
||||
We should free these sub-structures at JOIN::destroy() if the "current" join
|
||||
has a copy is not that copy.
|
||||
We should free these sub-structures at JOIN::destroy() if the
|
||||
"current" join has a copy is not that copy.
|
||||
*/
|
||||
JOIN *tmp_join;
|
||||
ROLLUP rollup; ///< Used with rollup
|
||||
@@ -512,6 +514,7 @@ public:
|
||||
optimized= 0;
|
||||
cond_equal= 0;
|
||||
group_optimized_away= 0;
|
||||
no_rows_in_result_called= 0;
|
||||
|
||||
all_fields= fields_arg;
|
||||
if (&fields_list != &fields_arg) /* Avoid valgrind-warning */
|
||||
|
Reference in New Issue
Block a user