diff options
author | Igor Babaev <igor@askmonty.org> | 2019-04-17 21:37:29 -0700 |
---|---|---|
committer | Igor Babaev <igor@askmonty.org> | 2019-04-17 21:37:29 -0700 |
commit | 59ed5f3aa4bc5a02a65f93b1d054ccc0fb2cd248 (patch) | |
tree | fb923464b33c0127e627d7e20b4ccc83f01648f1 /sql | |
parent | e7029e864f4b2c8fa88362677ee8150cc479f07f (diff) | |
download | mariadb-git-59ed5f3aa4bc5a02a65f93b1d054ccc0fb2cd248.tar.gz |
MDEV-19164 Assertion `fixed' failed in Item_func_inet_aton::val_int
When pushing a condition from HAVING into WHERE the function
st_select_lex::pushdown_from_having_into_where() transforms column
references in the pushed condition then performs cleanup of
items of the condition and finally calls fix_fields() for the condition
items. The cleanup is performed by a call of the method walk() with
cleanup_processor as the first parameter. Unfortunately this sequence
of calls does not work if the condition contains cached items, because
fix_fields() cannot go through Item_cache items and this leaves
underlying items unfixed.
The solution of this problem used in this patch is just does not allow
to process Item_cache objects when performing cleanup of the pushed
condition. In order to let the traversal procedure walk() not to process
Item_cache objects the third parameter of the used call of walk()
is set to a fictitious pointer (void *) 1. And Item_cache::walk() is
changed to prevent any action when it gets such value as the third
parameter.
Diffstat (limited to 'sql')
-rw-r--r-- | sql/item.h | 10 | ||||
-rw-r--r-- | sql/sql_lex.cc | 6 |
2 files changed, 11 insertions, 5 deletions
diff --git a/sql/item.h b/sql/item.h index 97d31e6ba34..0d407353d60 100644 --- a/sql/item.h +++ b/sql/item.h @@ -714,6 +714,8 @@ public: /****************************************************************************/ +#define STOP_PTR ((void *) 1) + class Item: public Value_source, public Type_all_attributes { @@ -1829,8 +1831,10 @@ public: /*========= Item processors, to be used with Item::walk() ========*/ virtual bool remove_dependence_processor(void *arg) { return 0; } virtual bool cleanup_processor(void *arg); - virtual bool cleanup_excluding_fields_processor(void *arg) { return cleanup_processor(arg); } - virtual bool cleanup_excluding_const_fields_processor(void *arg) { return cleanup_processor(arg); } + virtual bool cleanup_excluding_fields_processor (void *arg) + { return cleanup_processor(arg); } + virtual bool cleanup_excluding_const_fields_processor (void *arg) + { return cleanup_processor(arg); } virtual bool collect_item_field_processor(void *arg) { return 0; } virtual bool collect_outer_ref_processor(void *arg) {return 0; } virtual bool check_inner_refs_processor(void *arg) { return 0; } @@ -6535,6 +6539,8 @@ public: virtual void set_null(); bool walk(Item_processor processor, bool walk_subquery, void *arg) { + if (arg == STOP_PTR) + return FALSE; if (example && example->walk(processor, walk_subquery, arg)) return TRUE; return (this->*processor)(arg); diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index f74541b34a4..8ea0bc50956 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -10112,7 +10112,7 @@ Item *remove_pushed_top_conjuncts_for_having(THD *thd, Item *cond) Multiple equalities are not removed but marked with DELETION_FL flag. They will be deleted later in substitite_for_best_equal_field() called for the HAVING condition. - 5. Unwrap fields wrapped in Item_ref wrappers contain in the condition + 5. Unwrap fields wrapped in Item_ref wrappers contained in the condition of attach_to_conds so the condition could be pushed into WHERE. @note @@ -10203,7 +10203,7 @@ Item *st_select_lex::pushdown_from_having_into_where(THD *thd, Item *having) join->having_equal= 0; /* - 5. Unwrap fields wrapped in Item_ref wrappers contain in the condition + 5. Unwrap fields wrapped in Item_ref wrappers contained in the condition of attach_to_conds so the condition could be pushed into WHERE. */ it.rewind(); @@ -10213,7 +10213,7 @@ Item *st_select_lex::pushdown_from_having_into_where(THD *thd, Item *having) &Item::field_transformer_for_having_pushdown, (uchar *)this); - if (item->walk(&Item::cleanup_processor, 0, 0) || + if (item->walk(&Item:: cleanup_processor, 0, STOP_PTR) || item->fix_fields(thd, NULL)) { attach_to_conds.empty(); |