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