From: Sergey Petrunia Date: October 5 2008 12:35am Subject: Re: bzr commit into mysql-5.1 branch (kgeorge:2662) Bug#34773 List-Archive: http://lists.mysql.com/commits/55351 Message-Id: <20081005003551.GE13462@pslp2.localdomain> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7BIT On Thu, Oct 02, 2008 at 04:08:38PM +0300, Georgi Kodinov wrote: > #At file:///home/kgeorge/mysql/bzr/B34773-5.1-bugteam/ > > 2662 Georgi Kodinov 2008-10-02 > Bug#34773: query with explain extended and derived table / other table > crashes server > > When creating temporary table that contains aggregate functions a > non-reversible source transformation was performed to redirect aggregate > function arguments towards temporary table columns. > This caused EXPLAIN EXTENDED to fail because it was trying to resolve > references to the (freed) temporary table. > Fixed by preserving the original aggregate function arguments and > using them (instead of the transformed ones) for EXPLAIN EXTENDED. ... > @@ -535,6 +538,22 @@ void Item_sum::update_used_tables () > } > > > +Item *Item_sum::set_arg(int i, THD *thd, Item *new_val) > +{ > + if (!orig_args) > + { > + Query_arena *arena, backup; > + arena= thd->activate_stmt_arena_if_needed(&backup); > + orig_args= (Item **) sql_alloc (sizeof (Item *) * arg_count); > + memcpy (orig_args, args, sizeof (Item *) * arg_count); What's with the sapce above and the coding style? > + if (arena) > + thd->restore_active_arena(arena, &backup); > + } > + thd->change_item_tree(args + i, new_val); > + return new_val; > +} What about this scenario: mysql> PREPARE stmt1 AS 'EXPLAIN SELECT 1 FROM (SELECT COUNT( x_func( ...'; mysql> EXECUTE stmt1; * Some code substitutes the item object that corresponds to x_func(..) with $transient_item. $transient_item is allocated on the per-statement mem_root. The change is recorded with change_item_tree(). * Execution enters Item_sum::set_arg, the "if (!orig_args)" branch is taken. * memcpy() call copies the pointer to $transient_item to item_sum->orig_args. * Statement's mem_root and $transient_item are destroyed. The above mentioned change_item_tree() call is undone, however the item_sum->orig_args still keeps the pointer to $transient_item which is now invalid. mysql> EXECUTE stmt1; * At some point the code tries to access item_sum->orig_args[N] and follows the pointer to $transient_item and crashes. Can you explain why it cannot happen? > String * > Item_sum_num::val_str(String *str) > { > BR Sergey -- Sergey Petrunia, Lead Software Engineer MySQL AB, www.mysql.com Office: N/A Blog: http://s.petrunia.net/blog