Обсуждение: Check volatile functions in ppi_clauses for memoize node

Поиск
Список
Период
Сортировка

Check volatile functions in ppi_clauses for memoize node

От
Richard Guo
Дата:
In get_memoize_path() we have a theory about avoiding memoize node if
there are volatile functions in the inner rel's target/restrict list.

 /*
  * We can't use a memoize node if there are volatile functions in the
  * inner rel's target list or restrict list.  A cache hit could reduce the
  * number of calls to these functions.
  */
 if (contain_volatile_functions((Node *) innerrel->reltarget))
     return NULL;

 foreach(lc, innerrel->baserestrictinfo)
 {
     RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc);

     if (contain_volatile_functions((Node *) rinfo))
         return NULL;
 }

It seems that the check for restrict list is not thorough, because for a
parameterized scan we are supposed to also consider all the join clauses
available from the outer rels, ie, ppi_clauses.  For instance,

create table t (a float);
insert into t values (1.0), (1.0), (1.0), (1.0);
analyze t;

explain (costs off)
select * from t t1 left join lateral
    (select t1.a as t1a, t2.a as t2a from t t2) s
on t1.a = s.t2a + random();
                  QUERY PLAN
-----------------------------------------------
 Nested Loop Left Join
   ->  Seq Scan on t t1
   ->  Memoize
         Cache Key: t1.a
         Cache Mode: binary
         ->  Seq Scan on t t2
               Filter: (t1.a = (a + random()))
(7 rows)

According to the theory we should not use memoize node for this query
because of the volatile function in the inner side.  So propose a patch
to fix that.

Thanks
Richard
Вложения

Re: Check volatile functions in ppi_clauses for memoize node

От
David Rowley
Дата:
On Fri, 4 Aug 2023 at 22:26, Richard Guo <guofenglinux@gmail.com> wrote:
> explain (costs off)
> select * from t t1 left join lateral
>     (select t1.a as t1a, t2.a as t2a from t t2) s
> on t1.a = s.t2a + random();
>                   QUERY PLAN
> -----------------------------------------------
>  Nested Loop Left Join
>    ->  Seq Scan on t t1
>    ->  Memoize
>          Cache Key: t1.a
>          Cache Mode: binary
>          ->  Seq Scan on t t2
>                Filter: (t1.a = (a + random()))
> (7 rows)
>
> According to the theory we should not use memoize node for this query
> because of the volatile function in the inner side.  So propose a patch
> to fix that.

Thanks for the patch.  I've pushed a variation of it.

I didn't really see the need to make a single list with all the
RestrictInfos. It seems fine just to write code and loop over the
ppi_clauses checking for volatility.

David



Re: Check volatile functions in ppi_clauses for memoize node

От
Richard Guo
Дата:

On Mon, Aug 7, 2023 at 6:19 PM David Rowley <dgrowleyml@gmail.com> wrote:
On Fri, 4 Aug 2023 at 22:26, Richard Guo <guofenglinux@gmail.com> wrote:
> explain (costs off)
> select * from t t1 left join lateral
>     (select t1.a as t1a, t2.a as t2a from t t2) s
> on t1.a = s.t2a + random();
>                   QUERY PLAN
> -----------------------------------------------
>  Nested Loop Left Join
>    ->  Seq Scan on t t1
>    ->  Memoize
>          Cache Key: t1.a
>          Cache Mode: binary
>          ->  Seq Scan on t t2
>                Filter: (t1.a = (a + random()))
> (7 rows)
>
> According to the theory we should not use memoize node for this query
> because of the volatile function in the inner side.  So propose a patch
> to fix that.

Thanks for the patch.  I've pushed a variation of it.

I didn't really see the need to make a single list with all the
RestrictInfos. It seems fine just to write code and loop over the
ppi_clauses checking for volatility.

That looks good.  Thanks for pushing it!

Thanks
Richard