Re: Partial hash index is not used for implied qual. - Mailing list pgsql-hackers

From David Rowley
Subject Re: Partial hash index is not used for implied qual.
Date
Msg-id CAApHDvpVazvK7jAjpMWW5FYR4RQZ2NT8HidS03un8T+Ha8ZQDw@mail.gmail.com
Whole thread Raw
In response to Partial hash index is not used for implied qual.  (Sergei Glukhov <s.glukhov@postgrespro.ru>)
Responses Re: Partial hash index is not used for implied qual.
List pgsql-hackers
On Mon, 24 Nov 2025 at 20:33, Sergei Glukhov <s.glukhov@postgrespro.ru> wrote:
> Partial hash index is not used if qual is an implied qual
> since this qual is not added to indrestrictinfo and we cannot
> get the keys needed to make hash index scan possible.
> Suggested fix is to add implied qual for the indexes
> which requires the presence of a key to scan the index.
>
> How to repeat:

That's not very good. I see we abort building the index path at:

/*
 * If no clauses match the first index column, check for amoptionalkey
 * restriction.  We can't generate a scan over an index with
 * amoptionalkey = false unless there's at least one index clause.
 * (When working on columns after the first, this test cannot fail. It
 * is always okay for columns after the first to not have any
 * clauses.)
 */
if (index_clauses == NIL && !index->amoptionalkey)
    return NIL;

and that's there due to the fact that Hash doesn't support full
clauseless scans. Without the above, you'd get:

SELECT x FROM hash_partial WHERE x = 1;
ERROR:  hash indexes do not support whole-index scans

so, that leads me to believe the location you're adjusting is probably
the best place to fix this issue.

As for the patch, you didn't update the comment to include the reason
you're keeping the restrictinfo clause. That's not great. I think you
should break that new test out into a new "if" test, maybe like:

/*
 * Keep the restrictinfo for non-amoptionalkey index types as
 * dropping the clause could result in having no clauses to use to
 * scan the index.  That's unsupported by non-amoptionalkey
 * indexes, so if we dropped this qual, we'd fail to build a Path
 * for this index later in planning.
 */
if (!index->amoptionalkey)
    index->indrestrictinfo = lappend(index->indrestrictinfo, rinfo);

/* predicate_implied_by() assumes first arg is immutable */
else if (contain_mutable_functions((Node *) rinfo->clause) ||
           !predicate_implied_by(list_make1(rinfo->clause),
                                               index->indpred, false))
    index->indrestrictinfo = lappend(index->indrestrictinfo, rinfo);

David



pgsql-hackers by date:

Previous
From: Sami Imseih
Date:
Subject: Re: [Proposal] Adding callback support for custom statistics kinds
Next
From: Rishu Bagga
Date:
Subject: Re: [PATCH] Write Notifications Through WAL