mirror of
https://github.com/MariaDB/server.git
synced 2026-04-28 11:15:33 +02:00
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
This commit is contained in:
parent
2df1914791
commit
945a595aa3
14 changed files with 96 additions and 36 deletions
|
|
@ -4076,15 +4076,12 @@ Item_cond::fix_fields(THD *thd, Item **ref)
|
|||
DBUG_ASSERT(fixed == 0);
|
||||
List_iterator<Item> li(list);
|
||||
Item *item;
|
||||
TABLE_LIST *save_emb_on_expr_nest= thd->thd_marker.emb_on_expr_nest;
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
uchar buff[sizeof(char*)]; // Max local vars in function
|
||||
#endif
|
||||
not_null_tables_cache= used_tables_cache= 0;
|
||||
const_item_cache= 1;
|
||||
|
||||
if (functype() != COND_AND_FUNC)
|
||||
thd->thd_marker.emb_on_expr_nest= NULL;
|
||||
/*
|
||||
and_table_cache is the value that Item_cond_or() returns for
|
||||
not_null_tables()
|
||||
|
|
@ -4144,7 +4141,6 @@ Item_cond::fix_fields(THD *thd, Item **ref)
|
|||
maybe_null=1;
|
||||
}
|
||||
thd->lex->current_select->cond_count+= list.elements;
|
||||
thd->thd_marker.emb_on_expr_nest= save_emb_on_expr_nest;
|
||||
fix_length_and_dec();
|
||||
fixed= 1;
|
||||
return FALSE;
|
||||
|
|
@ -4414,6 +4410,17 @@ void Item_cond::neg_arguments(THD *thd)
|
|||
}
|
||||
|
||||
|
||||
void Item_cond_and::mark_as_condition_AND_part(TABLE_LIST *embedding)
|
||||
{
|
||||
List_iterator<Item> li(list);
|
||||
Item *item;
|
||||
while ((item=li++))
|
||||
{
|
||||
item->mark_as_condition_AND_part(embedding);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Evaluation of AND(expr, expr, expr ...).
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue