Обсуждение: pgsql: Fix planner's use of Result Cache with unique joins

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

pgsql: Fix planner's use of Result Cache with unique joins

От
David Rowley
Дата:
Fix planner's use of Result Cache with unique joins

When the planner considered using a Result Cache node to cache results
from the inner side of a Nested Loop Join, it failed to consider that the
inner path's parameterization may not be the entire join condition.  If
the join was marked as inner_unique then we may accidentally put the cache
in singlerow mode.  This meant that entries would be marked as complete
after caching the first row.  That was wrong as if only part of the join
condition was parameterized then the uniqueness of the unique join was not
guaranteed at the Result Cache's level.  The uniqueness is only guaranteed
after Nested Loop applies the join filter.  If subsequent rows were found,
this would lead to:

ERROR: cache entry already complete

This could have been fixed by only putting the cache in singlerow mode if
the entire join condition was parameterized.  However, Nested Loop will
only read its inner side so far as the first matching row when the join is
unique, so that might mean we never get an opportunity to mark cache
entries as complete.  Since non-complete cache entries are useless for
subsequent lookups, we just don't bother considering a Result Cache path
in this case.

In passing, remove the XXX comment that claimed the above ERROR might be
better suited to be an Assert.  After there being an actual case which
triggered it, it seems better to keep it an ERROR.

Reported-by: David Christensen
Discussion: https://postgr.es/m/CAOxo6X+dy-V58iEPFgst8ahPKEU+38NZzUuc+a7wDBZd4TrHMQ@mail.gmail.com

Branch
------
master

Details
-------
https://git.postgresql.org/pg/commitdiff/9e215378d7fbb7d4615be917917c52f246cc6c61

Modified Files
--------------
src/backend/executor/nodeResultCache.c |  2 +-
src/backend/optimizer/path/joinpath.c  | 31 +++++++++++++++++++++++++++++++
2 files changed, 32 insertions(+), 1 deletion(-)


Re: pgsql: Fix planner's use of Result Cache with unique joins

От
Tom Lane
Дата:
David Rowley <drowley@postgresql.org> writes:
> Fix planner's use of Result Cache with unique joins

Coverity is not happy with this:

/srv/coverity/git/pgsql-git/postgresql/src/backend/optimizer/path/joinpath.c: 532 in get_resultcache_path()
526          * determining if the join is unique.
527          *
528          * XXX this could be enabled if the remaining join quals were made part of
529          * the inner scan's filter instead of the join filter.  Maybe it's worth
530          * considering doing that?
531          */
>>>     CID 1484914:  Null pointer dereferences  (FORWARD_NULL)
>>>     Dereferencing null pointer "inner_path->param_info".
532         if (extra->inner_unique &&
533             list_length(inner_path->param_info->ppi_clauses) <
534             list_length(extra->restrictlist))
535             return NULL;
536

This complaint is triggered because elsewhere in the same function,
you're careful to check for inner_path->param_info being null before
trying to dereference it:

    if ((inner_path->param_info == NULL ||
         inner_path->param_info->ppi_clauses == NIL) &&
        innerrel->lateral_vars == NIL)
        return NULL;

Coverity reasons that it's probably a bug that you didn't do the same
here; and I think it's right.

            regards, tom lane



Re: pgsql: Fix planner's use of Result Cache with unique joins

От
David Rowley
Дата:
On Mon, 24 May 2021 at 02:14, Tom Lane <tgl@sss.pgh.pa.us> wrote:
> Coverity is not happy with this:

> This complaint is triggered because elsewhere in the same function,
> you're careful to check for inner_path->param_info being null before
> trying to dereference it:
>
>     if ((inner_path->param_info == NULL ||
>          inner_path->param_info->ppi_clauses == NIL) &&
>         innerrel->lateral_vars == NIL)
>         return NULL;
>
> Coverity reasons that it's probably a bug that you didn't do the same
> here; and I think it's right.

Yeah, I think that should be fixed. Thanks for reporting.

I propose the attached.  I think if the restrictlist is empty then we
needn't bother trying Result Cache.

David

Вложения