From: Tor Didriksen Date: May 26 2011 8:39am Subject: bzr push into mysql-trunk branch (tor.didriksen:3119 to 3120) List-Archive: http://lists.mysql.com/commits/138162 Message-Id: <20110526083958.EC1B724B@atum07.norway.sun.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 3120 Tor Didriksen 2011-05-26 [merge] Automerge opt-team => trunk modified: sql/item_subselect.cc sql/sql_array.h sql/sql_base.cc sql/sql_select.cc sql/sql_select.h 3119 Bjorn Munch 2011-05-26 [merge] null upmerge === modified file 'sql/item_subselect.cc' --- a/sql/item_subselect.cc 2011-04-06 11:13:33 +0000 +++ b/sql/item_subselect.cc 2011-05-24 09:36:11 +0000 @@ -3181,23 +3181,24 @@ bool subselect_hash_sj_engine::setup(Lis - here we initialize only those members that are used by subselect_uniquesubquery_engine, so these objects are incomplete. */ - if (!(tab= new (thd->mem_root) JOIN_TAB)) + JOIN_TAB * const tmp_tab= new (thd->mem_root) JOIN_TAB; + if (tmp_tab == NULL) DBUG_RETURN(TRUE); - tab->table= tmp_table; - tab->ref.key= 0; /* The only temp table index. */ - tab->ref.key_length= tmp_key->key_length; - if (!(tab->ref.key_buff= + tmp_tab->table= tmp_table; + tmp_tab->ref.key= 0; /* The only temp table index. */ + tmp_tab->ref.key_length= tmp_key->key_length; + if (!(tmp_tab->ref.key_buff= (uchar*) thd->calloc(ALIGN_SIZE(tmp_key->key_length) * 2)) || - !(tab->ref.key_copy= + !(tmp_tab->ref.key_copy= (store_key**) thd->alloc((sizeof(store_key*) * (tmp_key_parts + 1)))) || - !(tab->ref.items= + !(tmp_tab->ref.items= (Item**) thd->alloc(sizeof(Item*) * tmp_key_parts))) DBUG_RETURN(TRUE); KEY_PART_INFO *cur_key_part= tmp_key->key_part; - store_key **ref_key= tab->ref.key_copy; - uchar *cur_ref_buff= tab->ref.key_buff; + store_key **ref_key= tmp_tab->ref.key_copy; + uchar *cur_ref_buff= tmp_tab->ref.key_buff; /* Create an artificial condition to post-filter those rows matched by index @@ -3235,10 +3236,10 @@ bool subselect_hash_sj_engine::setup(Lis /* Item for the corresponding field from the materialized temp table. */ Item_field *right_col_item; int null_count= test(cur_key_part->field->real_maybe_null()); - tab->ref.items[i]= item_in->left_expr->element_index(i); + tmp_tab->ref.items[i]= item_in->left_expr->element_index(i); if (!(right_col_item= new Item_field(thd, context, cur_key_part->field)) || - !(eq_cond= new Item_func_eq(tab->ref.items[i], right_col_item)) || + !(eq_cond= new Item_func_eq(tmp_tab->ref.items[i], right_col_item)) || ((Item_cond_and*)cond)->add(eq_cond)) { delete cond; @@ -3255,16 +3256,19 @@ bool subselect_hash_sj_engine::setup(Lis */ cur_ref_buff + null_count, null_count ? cur_ref_buff : 0, - cur_key_part->length, tab->ref.items[i]); + cur_key_part->length, tmp_tab->ref.items[i]); cur_ref_buff+= cur_key_part->store_length; } *ref_key= NULL; /* End marker. */ - tab->ref.key_err= 1; - tab->ref.key_parts= tmp_key_parts; + tmp_tab->ref.key_err= 1; + tmp_tab->ref.key_parts= tmp_key_parts; if (cond->fix_fields(thd, &cond)) DBUG_RETURN(TRUE); + // Set 'tab' only when function cannot fail, because of assert in destructor + tab= tmp_tab; + /* Create and optimize the JOIN that will be used to materialize the subquery if not yet created. === modified file 'sql/sql_array.h' --- a/sql/sql_array.h 2010-11-05 22:14:29 +0000 +++ b/sql/sql_array.h 2011-05-18 13:12:02 +0000 @@ -79,75 +79,4 @@ public: } }; - -/* - Array of pointers to Elem that uses memory from MEM_ROOT - - MEM_ROOT has no realloc() so this is supposed to be used for cases when - reallocations are rare. -*/ - -template class Array -{ - enum {alloc_increment = 16}; - Elem **buffer; - uint n_elements, max_element; -public: - Array(MEM_ROOT *mem_root, uint prealloc=16) - { - buffer= (Elem**)alloc_root(mem_root, prealloc * sizeof(Elem**)); - max_element = buffer? prealloc : 0; - n_elements= 0; - } - - Elem& at(int idx) - { - return *(((Elem*)buffer) + idx); - } - - Elem **front() - { - return buffer; - } - - Elem **back() - { - return buffer + n_elements; - } - - bool append(MEM_ROOT *mem_root, Elem *el) - { - if (n_elements == max_element) - { - Elem **newbuf; - if (!(newbuf= (Elem**)alloc_root(mem_root, (n_elements + alloc_increment)* - sizeof(Elem**)))) - { - return FALSE; - } - memcpy(newbuf, buffer, n_elements*sizeof(Elem*)); - buffer= newbuf; - } - buffer[n_elements++]= el; - return FALSE; - } - - int elements() - { - return n_elements; - } - - void clear() - { - n_elements= 0; - } - - typedef int (*CMP_FUNC)(Elem * const *el1, Elem *const *el2); - - void sort(CMP_FUNC cmp_func) - { - my_qsort(buffer, n_elements, sizeof(Elem*), (qsort_cmp)cmp_func); - } -}; - #endif /* SQL_ARRAY_INCLUDED */ === modified file 'sql/sql_base.cc' --- a/sql/sql_base.cc 2011-05-21 08:25:33 +0000 +++ b/sql/sql_base.cc 2011-05-26 08:39:40 +0000 @@ -6876,9 +6876,29 @@ find_field_in_tables(THD *thd, Item_iden if (last_table) last_table= last_table->next_name_resolution_table; +#ifndef DBUG_OFF + uint loop_count= 0; + TABLE_LIST *one_node; +#endif for (; cur_table != last_table ; cur_table= cur_table->next_name_resolution_table) { +#ifndef DBUG_OFF + ++loop_count; + if (loop_count == 1000) // not normal, record one node we meet + one_node= cur_table; + if ((loop_count > 1000) && (one_node == cur_table)) + { + /* + Meeting same node again: cycle, infinite loop. Raise an error which + doesn't stop RQG, so that Roel can continue working while we fix the + bug. We cannot continue the statement though. + */ + my_error(ER_WRONG_FIELD_WITH_GROUP, MYF(0), + "HITTING BUG#12567331 INFINITE LOOP DETECTED - ASK GUILHEM AND ROEL"); + return NULL; + } +#endif Field *cur_field= find_field_in_table_ref(thd, cur_table, name, length, item->name, db, table_name, ref, (thd->lex->sql_command == === modified file 'sql/sql_select.cc' --- a/sql/sql_select.cc 2011-05-18 10:43:46 +0000 +++ b/sql/sql_select.cc 2011-05-26 06:03:02 +0000 @@ -978,7 +978,7 @@ bool resolve_subquery(THD *thd, JOIN *jo /* Register the subquery for further processing in flatten_subqueries() */ select_lex->outer_select()->join-> - sj_subselects.append(thd->mem_root, in_exists_predicate); + sj_subselects.push_back(in_exists_predicate); } else { @@ -4170,11 +4170,11 @@ bool JOIN::flatten_subqueries() Item_exists_subselect **subq_end; DBUG_ENTER("JOIN::flatten_subqueries"); - if (sj_subselects.elements() == 0) + if (sj_subselects.empty()) DBUG_RETURN(FALSE); /* First, convert child join's subqueries. We proceed bottom-up here */ - for (subq= sj_subselects.front(), subq_end= sj_subselects.back(); + for (subq= sj_subselects.begin(), subq_end= sj_subselects.end(); subq != subq_end; subq++) { @@ -4207,7 +4207,7 @@ bool JOIN::flatten_subqueries() { if (tbl->on_expr || tbl->in_outer_join_nest()) { - subq= sj_subselects.front(); + subq= sj_subselects.begin(); arena= thd->activate_stmt_arena_if_needed(&backup); goto skip_conversion; } @@ -4220,11 +4220,14 @@ bool JOIN::flatten_subqueries() - prefer correlated subqueries over uncorrelated; - prefer subqueries that have greater number of outer tables; */ - sj_subselects.sort(subq_sj_candidate_cmp); + my_qsort(sj_subselects.begin(), + sj_subselects.size(), sj_subselects.element_size(), + reinterpret_cast(subq_sj_candidate_cmp)); + // #tables-in-parent-query + #tables-in-subquery < MAX_TABLES /* Replace all subqueries to be flattened with Item_int(1) */ arena= thd->activate_stmt_arena_if_needed(&backup); - for (subq= sj_subselects.front(); + for (subq= sj_subselects.begin(); subq != subq_end && tables + (*subq)->unit->first_select()->join->tables < MAX_TABLES; subq++) @@ -4235,7 +4238,7 @@ bool JOIN::flatten_subqueries() DBUG_RETURN(TRUE); /* purecov: inspected */ } - for (subq= sj_subselects.front(); + for (subq= sj_subselects.begin(); subq != subq_end && tables + (*subq)->unit->first_select()->join->tables < MAX_TABLES; subq++) === modified file 'sql/sql_select.h' --- a/sql/sql_select.h 2011-05-18 10:43:46 +0000 +++ b/sql/sql_select.h 2011-05-26 06:03:02 +0000 @@ -1888,7 +1888,8 @@ public: bool union_part; ///< this subselect is part of union bool optimized; ///< flag to avoid double optimization in EXPLAIN - Array sj_subselects; + // true: No need to run DTORs on pointers. + Mem_root_array sj_subselects; /* Temporary tables used to weed-out semi-join duplicates */ List sj_tmp_tables; @@ -1913,7 +1914,7 @@ public: select_result *result_arg) : keyuse(thd_arg->mem_root), fields_list(fields_arg), - sj_subselects(thd_arg->mem_root, 4) + sj_subselects(thd_arg->mem_root) { init(thd_arg, fields_arg, select_options_arg, result_arg); } No bundle (reason: useless for push emails).