From: Roy Lyseng Date: November 6 2012 1:25pm Subject: bzr push into mysql-5.6 branch (roy.lyseng:4534 to 4535) Bug#15831502 List-Archive: http://lists.mysql.com/commits/145198 X-Bug: 15831502 Message-Id: <201211061325.qA6DPs98010040@khepri07.no.oracle.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 4535 Roy Lyseng 2012-11-06 Bug#15831502 Assert failed in Item_outer_ref::fix_after_pullout on subquery Preparatory patch: Remove an unused argument to Item::fix_after_pullout() The "ref" argument to this function is unused, and I see no reason that we should ever have to use it again. modified: sql/item.cc sql/item.h sql/item_cmpfunc.cc sql/item_cmpfunc.h sql/item_func.cc sql/item_func.h sql/item_row.cc sql/item_row.h sql/item_subselect.cc sql/item_subselect.h sql/sql_optimizer.cc 4534 Tor Didriksen 2012-11-06 Bug#14842865 ~5% INCREASED EXEC. TIME FOR DBT3/Q13 Optimize check_enough_stack_size() for the normal case, with few '%' wildcards: don't check for every recursive call, and don't check for the first few cases. modified: include/m_ctype.h regex/my_regex.h regex/regcomp.c sql/mysqld.cc sql/mysqld.h strings/ctype-bin.c strings/ctype-mb.c strings/ctype-simple.c strings/ctype-uca.c strings/ctype-utf8.c strings/ctype.c === modified file 'sql/item.cc' --- a/sql/item.cc 2012-10-29 08:52:44 +0000 +++ b/sql/item.cc 2012-11-06 13:22:32 +0000 @@ -2874,8 +2874,7 @@ table_map Item_field::resolved_used_tabl } void Item_ident::fix_after_pullout(st_select_lex *parent_select, - st_select_lex *removed_select, - Item **ref) + st_select_lex *removed_select) { /* Some field items may be created for use in execution only, without @@ -7886,25 +7885,23 @@ bool Item_outer_ref::fix_fields(THD *thd } void Item_outer_ref::fix_after_pullout(st_select_lex *parent_select, - st_select_lex *removed_select, - Item **ref_arg) + st_select_lex *removed_select) { if (depended_from == parent_select) { - *ref_arg= outer_ref; - outer_ref->fix_after_pullout(parent_select, removed_select, ref_arg); + //*ref_arg= outer_ref; + outer_ref->fix_after_pullout(parent_select, removed_select); } // @todo: Find an actual test case for this funcion. DBUG_ASSERT(false); } void Item_ref::fix_after_pullout(st_select_lex *parent_select, - st_select_lex *removed_select, - Item **ref_arg) + st_select_lex *removed_select) { - (*ref)->fix_after_pullout(parent_select, removed_select, ref); + (*ref)->fix_after_pullout(parent_select, removed_select); - Item_ident::fix_after_pullout(parent_select, removed_select, ref_arg); + Item_ident::fix_after_pullout(parent_select, removed_select); } === modified file 'sql/item.h' --- a/sql/item.h 2012-10-09 09:28:46 +0000 +++ b/sql/item.h 2012-11-06 13:22:32 +0000 @@ -775,12 +775,10 @@ public: @param parent_select select_lex that tables are moved to. @param removed_select select_lex that tables are moved away from, child of parent_select. - @param ref updated with new ref whenever the function substitutes - this item with another. */ virtual void fix_after_pullout(st_select_lex *parent_select, - st_select_lex *removed_select, - Item **ref) {}; + st_select_lex *removed_select) + {}; /* should be used in case where we are sure that we do not need complete fix_fields() procedure. @@ -2076,7 +2074,7 @@ public: virtual table_map resolved_used_tables() const= 0; const char *full_name() const; virtual void fix_after_pullout(st_select_lex *parent_select, - st_select_lex *removed_select, Item **ref); + st_select_lex *removed_select); void cleanup(); bool remove_dependence_processor(uchar * arg); virtual void print(String *str, enum_query_type query_type); @@ -3159,7 +3157,7 @@ public: void make_field(Send_field *field); bool fix_fields(THD *, Item **); void fix_after_pullout(st_select_lex *parent_select, - st_select_lex *removed_select, Item **ref); + st_select_lex *removed_select); type_conversion_status save_in_field(Field *field, bool no_conversions); void save_org_in_field(Field *field); enum Item_result result_type () const { return (*ref)->result_type(); } @@ -3405,7 +3403,7 @@ public: } bool fix_fields(THD *, Item **); void fix_after_pullout(st_select_lex *parent_select, - st_select_lex *removed_select, Item **ref); + st_select_lex *removed_select); table_map used_tables() const { return (*ref)->const_item() ? 0 : OUTER_REF_TABLE_BIT; === modified file 'sql/item_cmpfunc.cc' --- a/sql/item_cmpfunc.cc 2012-10-30 14:53:53 +0000 +++ b/sql/item_cmpfunc.cc 2012-11-06 13:22:32 +0000 @@ -1917,8 +1917,7 @@ bool Item_in_optimizer::fix_fields(THD * void Item_in_optimizer::fix_after_pullout(st_select_lex *parent_select, - st_select_lex *removed_select, - Item **ref) + st_select_lex *removed_select) { used_tables_cache= get_initial_pseudo_tables(); not_null_tables_cache= 0; @@ -1930,7 +1929,7 @@ void Item_in_optimizer::fix_after_pullou So, just forward the call to the Item_in_subselect object. */ - args[1]->fix_after_pullout(parent_select, removed_select, &args[1]); + args[1]->fix_after_pullout(parent_select, removed_select); used_tables_cache|= args[1]->used_tables(); not_null_tables_cache|= args[1]->not_null_tables(); @@ -4816,8 +4815,7 @@ Item_cond::fix_fields(THD *thd, Item **r void Item_cond::fix_after_pullout(st_select_lex *parent_select, - st_select_lex *removed_select, - Item **ref) + st_select_lex *removed_select) { List_iterator li(list); Item *item; @@ -4832,8 +4830,7 @@ void Item_cond::fix_after_pullout(st_sel while ((item=li++)) { - item->fix_after_pullout(parent_select, removed_select, li.ref()); - item= *li.ref(); + item->fix_after_pullout(parent_select, removed_select); used_tables_cache|= item->used_tables(); const_item_cache&= item->const_item(); if (functype() == COND_AND_FUNC && abort_on_null) === modified file 'sql/item_cmpfunc.h' --- a/sql/item_cmpfunc.h 2012-10-30 14:53:53 +0000 +++ b/sql/item_cmpfunc.h 2012-11-06 13:22:32 +0000 @@ -283,7 +283,7 @@ public: bool fix_fields(THD *, Item **); bool fix_left(THD *thd, Item **ref); void fix_after_pullout(st_select_lex *parent_select, - st_select_lex *removed_select, Item **ref); + st_select_lex *removed_select); bool is_null(); longlong val_int(); void cleanup(); @@ -1665,7 +1665,7 @@ public: } bool fix_fields(THD *, Item **ref); void fix_after_pullout(st_select_lex *parent_select, - st_select_lex *removed_select, Item **ref); + st_select_lex *removed_select); enum Type type() const { return COND_ITEM; } List* argument_list() { return &list; } === modified file 'sql/item_func.cc' --- a/sql/item_func.cc 2012-10-30 07:59:01 +0000 +++ b/sql/item_func.cc 2012-11-06 13:22:32 +0000 @@ -237,8 +237,7 @@ Item_func::fix_fields(THD *thd, Item **r void Item_func::fix_after_pullout(st_select_lex *parent_select, - st_select_lex *removed_select, - Item **ref) + st_select_lex *removed_select) { Item **arg,**arg_end; @@ -250,8 +249,8 @@ void Item_func::fix_after_pullout(st_sel { for (arg=args, arg_end=args+arg_count; arg != arg_end ; arg++) { - (*arg)->fix_after_pullout(parent_select, removed_select, arg); - Item *item= *arg; + Item *const item= *arg; + item->fix_after_pullout(parent_select, removed_select); used_tables_cache|= item->used_tables(); not_null_tables_cache|= item->not_null_tables(); === modified file 'sql/item_func.h' --- a/sql/item_func.h 2012-10-24 08:43:19 +0000 +++ b/sql/item_func.h 2012-11-06 13:22:32 +0000 @@ -122,7 +122,7 @@ public: Item_func(THD *thd, Item_func *item); bool fix_fields(THD *, Item **ref); void fix_after_pullout(st_select_lex *parent_select, - st_select_lex *removed_select, Item **ref); + st_select_lex *removed_select); table_map used_tables() const; /** Returns the pseudo tables depended upon in order to evaluate this === modified file 'sql/item_row.cc' --- a/sql/item_row.cc 2012-08-22 13:01:21 +0000 +++ b/sql/item_row.cc 2012-11-06 13:22:32 +0000 @@ -140,14 +140,13 @@ void Item_row::update_used_tables() } void Item_row::fix_after_pullout(st_select_lex *parent_select, - st_select_lex *removed_select, - Item **ref) + st_select_lex *removed_select) { used_tables_cache= 0; const_item_cache= 1; for (uint i= 0; i < arg_count; i++) { - items[i]->fix_after_pullout(parent_select, removed_select, &items[i]); + items[i]->fix_after_pullout(parent_select, removed_select); used_tables_cache|= items[i]->used_tables(); const_item_cache&= items[i]->const_item(); } === modified file 'sql/item_row.h' --- a/sql/item_row.h 2011-12-09 21:08:37 +0000 +++ b/sql/item_row.h 2012-11-06 13:22:32 +0000 @@ -75,7 +75,7 @@ public: bool fix_fields(THD *thd, Item **ref); void fix_after_pullout(st_select_lex *parent_select, - st_select_lex *removed_select, Item **ref); + st_select_lex *removed_select); void cleanup(); void split_sum_func(THD *thd, Ref_ptr_array ref_pointer_array, List &fields); === modified file 'sql/item_subselect.cc' --- a/sql/item_subselect.cc 2012-10-30 07:59:01 +0000 +++ b/sql/item_subselect.cc 2012-11-06 13:22:32 +0000 @@ -627,8 +627,7 @@ bool Item_subselect::exec() */ void Item_subselect::fix_after_pullout(st_select_lex *parent_select, - st_select_lex *removed_select, - Item **ref) + st_select_lex *removed_select) { /* Clear usage information for this subquery predicate object */ @@ -641,17 +640,15 @@ void Item_subselect::fix_after_pullout(s for (SELECT_LEX *sel= unit->first_select(); sel; sel= sel->next_select()) { if (sel->where) - sel->where->fix_after_pullout(parent_select, removed_select, - &sel->where); + sel->where->fix_after_pullout(parent_select, removed_select); if (sel->having) - sel->having->fix_after_pullout(parent_select, removed_select, - &sel->having); + sel->having->fix_after_pullout(parent_select, removed_select); List_iterator li(sel->item_list); Item *item; while ((item=li++)) - item->fix_after_pullout(parent_select, removed_select, li.ref()); + item->fix_after_pullout(parent_select, removed_select); /* No need to call fix_after_pullout() for outer-join conditions, as these @@ -663,14 +660,12 @@ void Item_subselect::fix_after_pullout(s for (ORDER *order= (ORDER*) sel->order_list.first; order; order= order->next) - (*order->item)->fix_after_pullout(parent_select, removed_select, - order->item); + (*order->item)->fix_after_pullout(parent_select, removed_select); for (ORDER *group= (ORDER*) sel->group_list.first; group; group= group->next) - (*group->item)->fix_after_pullout(parent_select, removed_select, - group->item); + (*group->item)->fix_after_pullout(parent_select, removed_select); } } @@ -2327,12 +2322,11 @@ bool Item_in_subselect::fix_fields(THD * void Item_in_subselect::fix_after_pullout(st_select_lex *parent_select, - st_select_lex *removed_select, - Item **ref) + st_select_lex *removed_select) { - Item_subselect::fix_after_pullout(parent_select, removed_select, ref); + Item_subselect::fix_after_pullout(parent_select, removed_select); - left_expr->fix_after_pullout(parent_select, removed_select, &left_expr); + left_expr->fix_after_pullout(parent_select, removed_select); used_tables_cache|= left_expr->used_tables(); } === modified file 'sql/item_subselect.h' --- a/sql/item_subselect.h 2012-08-27 11:23:37 +0000 +++ b/sql/item_subselect.h 2012-11-06 13:22:32 +0000 @@ -130,7 +130,7 @@ public: } bool fix_fields(THD *thd, Item **ref); void fix_after_pullout(st_select_lex *parent_select, - st_select_lex *removed_select, Item **ref); + st_select_lex *removed_select); virtual bool exec(); virtual void fix_length_and_dec(); table_map used_tables() const; @@ -176,8 +176,7 @@ public: friend int Item_field::fix_outer_field(THD *, Field **, Item **); friend bool Item_ref::fix_fields(THD *, Item **); friend void Item_ident::fix_after_pullout(st_select_lex *parent_select, - st_select_lex *removed_select, - Item **ref); + st_select_lex *removed_selec); friend void mark_select_range_as_dependent(THD*, st_select_lex*, st_select_lex*, Field*, Item*, Item_ident*); @@ -469,7 +468,7 @@ public: virtual void print(String *str, enum_query_type query_type); bool fix_fields(THD *thd, Item **ref); void fix_after_pullout(st_select_lex *parent_select, - st_select_lex *removed_select, Item **ref); + st_select_lex *removed_select); bool init_left_expr_cache(); /** === modified file 'sql/sql_optimizer.cc' --- a/sql/sql_optimizer.cc 2012-10-30 07:59:01 +0000 +++ b/sql/sql_optimizer.cc 2012-11-06 13:22:32 +0000 @@ -6406,8 +6406,7 @@ static void fix_list_after_tbl_changes(s while ((table= it++)) { if (table->join_cond()) - table->join_cond()->fix_after_pullout(parent_select, removed_select, - table->join_cond_ref()); + table->join_cond()->fix_after_pullout(parent_select, removed_select); if (table->nested_join) fix_list_after_tbl_changes(parent_select, removed_select, &table->nested_join->join_list); @@ -6741,8 +6740,7 @@ static bool convert_subquery_to_semijoin Walk through sj nest's WHERE and ON expressions and call item->fix_table_changes() for all items. */ - sj_nest->sj_on_expr->fix_after_pullout(parent_lex, subq_lex, - &sj_nest->sj_on_expr); + sj_nest->sj_on_expr->fix_after_pullout(parent_lex, subq_lex); fix_list_after_tbl_changes(parent_lex, subq_lex, &sj_nest->nested_join->join_list); No bundle (reason: useless for push emails).