From: Tor Didriksen Date: May 18 2011 1:13pm Subject: bzr push into mysql-trunk branch (tor.didriksen:3372 to 3373) Bug#12552221 List-Archive: http://lists.mysql.com/commits/137626 X-Bug: 12552221 Message-Id: <20110518131305.7430337B2@atum07.norway.sun.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 3373 Tor Didriksen 2011-05-18 Bug#12552221 - MEMORY LEAK IN UPDATE_REF_AND_KEYS Addendum: Use Mem_root_array<> rather than Array<> for sj_subselects. Remove (the now obsolete) Array class. modified: sql/sql_array.h sql/sql_select.cc sql/sql_select.h 3372 Tor Didriksen 2011-05-18 [merge] NULL merge trunk => opt-backporting === 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_select.cc' --- a/sql/sql_select.cc 2011-05-18 11:44:39 +0000 +++ b/sql/sql_select.cc 2011-05-18 13:12: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 11:44:39 +0000 +++ b/sql/sql_select.h 2011-05-18 13:12: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).