List:Commits« Previous MessageNext Message »
From:Roy Lyseng Date:June 1 2011 3:07pm
Subject:Re: bzr commit into mysql-trunk branch (roy.lyseng:3379) Bug#12603183
View as plain text  
Just a heads up to reviewers: I have tried to think about how to create a query 
that crashes this solution, by using save_read_first_record both from 
materialize-scan and from subqueries that toggle between ref access and full 
table scan.

Something like
SELECT ... FROM ot...
WHERE ocol NOT IN (SELECT ... FROM mt...
                               WHERE mcol IN (SELECT ... FROM it ...))

Where the inner-most subquery is transformed into a semi-join and 
materialize-scan strategy is selected, and the NOT IN alternates betwen a ref 
access and a full table scan on its inner table. However, the ref access would 
have to be against table mt, but table being materialized in this case is it.

Hence, I think this scenario is not possible.

Thanks,
Roy

  On 01.06.11 12.27, Roy Lyseng wrote:
> #At file:///home/rl136806/mysql/repo/mysql-review/ based on
> revid:tor.didriksen@stripped
>
>   3379 Roy Lyseng	2011-06-01
>        Bug#12603183: Segfault in hp_movelink
>
>          The bug manifests itself sometimes as a segmentation fault,
>          sometimes as a Valgrind warning. Consistent faulting has been
>          difficult to achieve.
>
>          The problem is with the Materialization scan semi-join strategy.
>          When materialization is done, the read_first_record function
>          pointer is replaced with a function to read from the materialized
>          table instead. This strategy works when the materialization is
>          performed once per query, even when the materialized table is
>          read multiple times. However, if the materialization is performed
>          multiple times, such as when called from within another subquery,
>          the original function pointer is never restored, and the wrong
>          function is used to read from the subquery tables when materializing.
>
>          The solution for the problem is to save the original function pointer
>          in the save_read_first_record field of the join_tab and restore
>          it for every new materialization.
>
>          Notice that there are still some result differences, which would
>          not be seen with the original "LIMIT 1" specification.
>          It seems that Materialization scan is still slightly broken when
>          used together with an outer join. This problem will be looked at
>          in the context of WL#5561. Notice also that when semi-join
>          transformation for outer joins is enabled, both subqueries of this
>          query will be converted, and the materialization will be performed
>          only once, avoiding the entire problem. Hence, to reproduce this
>          problem in context of WL#5561, make sure that the outer subquery
>          is not transformed.
>
>
>
> === modified file 'sql/sql_select.cc'
> --- a/sql/sql_select.cc	2011-05-26 06:03:02 +0000
> +++ b/sql/sql_select.cc	2011-06-01 10:27:29 +0000
> @@ -17315,6 +17315,20 @@ sub_select_sjm(JOIN *join, JOIN_TAB *joi
>       Next_select_func next_func= join_tab[sjm->table_count - 1].next_select;
>       join_tab[sjm->table_count - 1].next_select= end_sj_materialize;
>
> +    if (sjm->is_scan)
> +    {
> +      JOIN_TAB *last_tab= join_tab + (sjm->table_count - 1);
> +      if (last_tab->save_read_first_record == NULL)
> +      {
> +        /* Save a copy of the read first function before substituting it */
> +        last_tab->save_read_first_record= last_tab->read_first_record;
> +      }
> +      else
> +      {
> +        /* Restore read function saved in previous materialization round */
> +        last_tab->read_first_record= last_tab->save_read_first_record;
> +      }
> +    }
>       /*
>         Now run the join for the inner tables. The first call is to run the
>         join, the second one is to signal EOF (this is essential for some
> @@ -17331,7 +17345,6 @@ sub_select_sjm(JOIN *join, JOIN_TAB *joi
>       /*
>         Ok, materialization finished. Initialize the access to the temptable
>       */
> -    sjm->materialized= TRUE;
>       join_tab->read_record.read_record= join_no_more_records;
>       if (sjm->is_scan)
>       {
> @@ -17340,7 +17353,6 @@ sub_select_sjm(JOIN *join, JOIN_TAB *joi
>         init_read_record(&last_tab->read_record, join->thd,
>                          sjm->table, NULL, TRUE, TRUE, FALSE);
>
> -      DBUG_ASSERT(last_tab->read_record.read_record == rr_sequential);
>         last_tab->read_first_record= join_read_record_no_init;
>         last_tab->read_record.copy_field= sjm->copy_field;
>         last_tab->read_record.copy_field_end= sjm->copy_field +
> @@ -17350,6 +17362,8 @@ sub_select_sjm(JOIN *join, JOIN_TAB *joi
>         // Clear possible outer join information from earlier use of this join tab
>         last_tab->last_inner= NULL;
>       }
> +
> +    sjm->materialized= true;
>     }
>     else
>     {
>
> === modified file 'sql/sql_select.h'
> --- a/sql/sql_select.h	2011-05-26 06:03:02 +0000
> +++ b/sql/sql_select.h	2011-06-01 10:27:29 +0000
> @@ -308,9 +308,10 @@ public:
>     Next_select_func next_select;
>     READ_RECORD	read_record;
>     /*
> -    Currently the following two fields are used only for a [NOT] IN subquery
> -    if it is executed by an alternative full table scan when the left operand of
> +    The following two fields are used for a [NOT] IN subquery if it is
> +    executed by an alternative full table scan when the left operand of
>       the subquery predicate is evaluated to NULL.
> +    save_read_first_record is also used by semi-join materialization strategy.
>     */
>     READ_RECORD::Setup_func save_read_first_record;/* to save read_first_record */
>     READ_RECORD::Read_func save_read_record;/* to save read_record.read_record */
>
>
>
>


Thread
bzr commit into mysql-trunk branch (roy.lyseng:3379) Bug#12603183Roy Lyseng1 Jun
  • Re: bzr commit into mysql-trunk branch (roy.lyseng:3379) Bug#12603183Roy Lyseng1 Jun
  • Re: bzr commit into mysql-trunk branch (roy.lyseng:3379) Bug#12603183Øystein Grøvlen7 Jun
    • Re: bzr commit into mysql-trunk branch (roy.lyseng:3379) Bug#12603183Roy Lyseng25 Jun