postgres-github.git / summary / log / commit / refs

commit    ffeda04259bb0b78e901c61e4b9d0ad86e786f4f
Author:   Richard Guo <rguo@postgresql.org>
Date:     Wed Jun 03 01:12:40 2026 +0000

    Fix eager aggregation for semi/antijoin inner rels
    
    Eager aggregation pushes a partial aggregate down to a base or join
    relation, to be finalized after that relation is joined with the rest
    of the query.  eager_aggregation_possible_for_relation() already
    refuses to do this for a relation on the nullable side of an outer
    join, but it failed to also refuse it for a relation on the inner side
    of a semijoin or antijoin.
    
    Such a join does not emit its inner rows, so a partial aggregate
    computed on the inner side does not survive the join and cannot be
    combined by the final aggregation.  This can happen only for an
    aggregate that references no table column, such as count(*): it is
    considered computable on any relation, including the inner one,
    whereas an aggregate that references a column is anchored to the outer
    side and never reaches the inner relation.
    
    The existing outer-join check did not catch this because it consults
    nulling_relids, which only tracks joins that null-extend their inner
    side.  Semijoins and antijoins formed from EXISTS, IN, NOT EXISTS, or
    NOT IN sublinks do not null-extend and carry no ojrelid, so they are
    invisible to that check.
    
    Fix by additionally rejecting any relation that includes inner-side
    relations of a semijoin or antijoin but not the join's outer side.
    Pushing a partial aggregate to the outer side of such a join, grouped
    by the join key, remains valid and is still allowed.
    
    Reported-by: Radim Marek <radim@boringsql.com>
    Author: Richard Guo <guofenglinux@gmail.com>
    Reviewed-by: Tender Wang <tndrwang@gmail.com>
    Discussion: https://postgr.es/m/CAJgoLk+d_P5sKrx-SZt01Acm_j0QnWn6aKJzFJ=waRu_3C8AoQ@mail.gmail.com