diff options
author | Sergey Petrunya <psergey@askmonty.org> | 2011-08-29 19:57:41 +0400 |
---|---|---|
committer | Sergey Petrunya <psergey@askmonty.org> | 2011-08-29 19:57:41 +0400 |
commit | 945a595aa36ccf90f89cf1ca8cddefe47b394dd3 (patch) | |
tree | 7ae47179a4e87d4b9f638224434ee6d30c916e91 /sql/item_subselect.h | |
parent | 2df1914791030714196c3d829187891a97be54dc (diff) | |
download | mariadb-git-945a595aa36ccf90f89cf1ca8cddefe47b394dd3.tar.gz |
BUG#834534: Assertion `0' failed in replace_where_subcondition with semijoin subquery in HAVING
- The problem was that the code that made the check whether the subquery is an AND-part of the WHERE
clause didn't work correctly for nested subqueries. In particular, grand-child subquery in HAVING was
treated as if it was in the WHERE, which eventually caused an assert when replace_where_subcondition
looked for the subquery predicate in the WHERE and couldn't find it there.
- The fix: Removed implementation of "thd_marker approach". thd->thd_marker was used to determine the
location of subquery predicate: setup_conds() would set accordingly it when making the
{where|on_expr}->fix_fields(...)
call so that AND-parts of the WHERE/ON clauses can determine they are the AND-parts.
Item_cond_or::fix_fields(), Item_func::fix_fields(), Item_subselect::fix_fields (this one was missed),
and all other items-that-contain-items had to reset thd->thd_marker before calling fix_fields() for
their children items, so that the children can see they are not AND-parts of WHERE/ON.
- The "thd_marker approach" required that a lot of code in different locations maintains correct value of
thd->thd_marker, so it was replaced with:
- The new approach with mark_as_condition_AND_part does not keep context in thd->thd_marker. Instead,
setup_conds() now calls
{where|on_expr}->mark_as_condition_AND_part()
and implementations of that function make sure that:
- parts of AND-expressions get the mark_as_condition_AND_part() call
- Item_in_subselect objects record that they are AND-parts of WHERE/ON
Diffstat (limited to 'sql/item_subselect.h')
-rw-r--r-- | sql/item_subselect.h | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/sql/item_subselect.h b/sql/item_subselect.h index f9e7a5ef568..85ce7745751 100644 --- a/sql/item_subselect.h +++ b/sql/item_subselect.h @@ -428,7 +428,6 @@ public: join nest pointer - the predicate is an AND-part of ON expression of a join nest NULL - for all other locations - See also THD::emb_on_expr_nest. */ TABLE_LIST *emb_on_expr_nest; /* @@ -447,7 +446,7 @@ public: /* A bitmap of possible execution strategies for an IN predicate. */ uchar in_strategy; - + bool is_jtbm_merged; /* @@ -459,7 +458,7 @@ public: TRUE<=>registered in the list of semijoins in outer select */ bool is_registered_semijoin; - + /* Used to determine how this subselect item is represented in the item tree, in case there is a need to locate it there and replace with something else. @@ -489,7 +488,8 @@ public: Item_in_subselect() :Item_exists_subselect(), left_expr_cache(0), first_execution(TRUE), abort_on_null(0), optimizer(0), - pushed_cond_guards(NULL), func(NULL), in_strategy(SUBS_NOT_TRANSFORMED), + pushed_cond_guards(NULL), func(NULL), emb_on_expr_nest(NULL), + in_strategy(SUBS_NOT_TRANSFORMED), is_jtbm_merged(FALSE), upper_item(0) {} @@ -533,6 +533,12 @@ public: user. */ int get_identifier(); + + void mark_as_condition_AND_part(TABLE_LIST *embedding) + { + emb_on_expr_nest= embedding; + } + friend class Item_ref_null_helper; friend class Item_is_not_null_test; friend class Item_in_optimizer; |