1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +03:00

Fix bug lp:782305

Analysis:
Both the wrong result and the valgrind warning were a result
of incomplete cleanup of the MIN/MAX subquery rewrite. At the
first execution of the query, the non-aggregate subquery is
transformed into an aggregate MIN/MAX subquery. During the
fix_fields phase of the MIN/MAX function, it sets the property
st_select_lex::with_sum_func to true.

The second execution of the query finds this flag to be ON.
When optimization reaches the same MIN/MAX subquery
transformation, it tests if the subquery is an aggregate or not.
Since select_lex->with_sum_func == true from the previous
execution, the transformation executes the second branch that
handles aggregate subqueries. This substitutes the subquery
Item into a Item_maxmin_subselect. At the same time elsewhere
it is assumed that the subquery Item is of type
Item_allany_subselect. Ultimately this results in casting the
actual object to the wrong class, and calling the wrong
any_value() method from empty_underlying_subquery().

Solution:
Cleanup the st_select_lex::with_sum_func property in the case
when the MIN/MAX transformation was performed for a non-aggregate
subquery, so that the transformation can be repeated.
This commit is contained in:
unknown
2011-07-18 23:45:38 +03:00
parent cc0195d6a1
commit c9e236828e
5 changed files with 94 additions and 9 deletions

View File

@@ -366,7 +366,10 @@ TABLE_LIST * const NO_JOIN_NEST=(TABLE_LIST*)0x1;
#define SUBS_PARTIAL_MATCH_ROWID_MERGE 8
#define SUBS_PARTIAL_MATCH_TABLE_SCAN 16
/* ALL/ANY will be transformed with max/min optimization */
#define SUBS_MAXMIN 32
/* The subquery has not aggregates, transform it into a MAX/MIN query. */
#define SUBS_MAXMIN_INJECTED 32
/* The subquery has aggregates, use a special max/min subselect engine. */
#define SUBS_MAXMIN_ENGINE 64
/**
@@ -555,6 +558,7 @@ public:
Item_allany_subselect(Item * left_expr, chooser_compare_func_creator fc,
st_select_lex *select_lex, bool all);
void cleanup();
// only ALL subquery has upper not
subs_type substype() { return all?ALL_SUBS:ANY_SUBS; }
bool select_transformer(JOIN *join);