Re: Reduce build times of pg_trgm GIN indexes
Heikki Linnakangas <hlinnaka@iki.fi>
From: Heikki Linnakangas <hlinnaka@iki.fi>
To: David Geier <geidav.pg@gmail.com>, Tom Lane <tgl@sss.pgh.pa.us>,
Peter Eisentraut <peter@eisentraut.org>
Cc: Matthias van de Meent <boekewurm+postgres@gmail.com>,
pgsql-hackers <pgsql-hackers@postgresql.org>
Date: 2026-04-15T11:06:14Z
Lists: pgsql-hackers
On 14/04/2026 10:02, David Geier wrote:
>> I didn't do it for performance, but because I find the function easier
>> to read that way. We could change it back.
>>
>> It's a pretty scary thought that a compiler might misoptimize that
>> though. In the same function we have 'nullFlags', too, as a local
>> variable, even before this commit. Not sure why Coverity doesn't
>> complain about that.
>>
>>> /*
>>> * PointerGetDatum
>>> * Returns datum representation for a pointer.
>>> */
>>> static inline Datum
>>> PointerGetDatum(const void *X)
>>> {
>>> return (Datum) (uintptr_t) X;
>>> }
>>
>> Hmm, is that 'const' incorrect? This function doesn't modify *X, but the
>> resulting address will be used to modify it. Maybe changing it to non-
>> const "void *X" would give Coverity a hint.
This was briefly discussed when PointerGetDatum() was changed from a
macro to a static inline function [1]. On that email, Peter pointed out
that the compiler was doing the same deduction that Coverity did now,
i.e. that if you pass the Datum returned by PointerGetDatum(&foo) to a
function, it cannot change *foo. I'm surprised we dismissed that worry
so quickly. If the compiler optimizes based on that assumption, you can
get incorrect code.
Three alternative fixes were discussed on that thread. Here's a fourth
one that I think is better;
#define PointerGetDatum(X) \
((Datum) (uintptr_t) (true ? (X) : NULL))
I found this trick with the dummy conditional expression at [2]. It
always evaluates to just (X), but it has the effect that you get a
compiler error if (X) is not a pointer.
[1]
https://www.postgresql.org/message-id/812568f2-ff1d-ebd9-aee6-e00d8f2e0fb6%40enterprisedb.com
[2] See "TO_VOID_PTR_EXPR()" at
https://medium.com/@pauljlucas/generic-in-c-d7ab47e3b5ab
> Ah, that could be it.
> Is there a way for me to run Coverity on a patch to test that out?
Not really I'm afraid. I can commit a fix and we'll see if it helps the
next time that Coverity runs (= Sunday).
> Which Coverity CI do we actually use? Is it this one here [1]?
>
> [1] https://scan.coverity.com/projects/209?
Yeah, that's the one, but only the security team has access.
- Heikki
Commits
Same data as JSON:
GET /api/v1/messages/:b64id/commits
the thread's linked commits as JSON, with link sources.
API reference →
-
Change PointerGetDatum() back to a macro
- d65995cbc6e1 19 (unreleased) landed
-
Replace deprecated StaticAssertStmt() with StaticAssertDecl()
- 66ad764c8d51 19 (unreleased) landed
-
Optimize sorting and deduplicating trigrams
- 9f3755ea07aa 19 (unreleased) landed
-
Optimize sort and deduplication in ginExtractEntries()
- 6f5ad00ab763 19 (unreleased) landed
-
Inline ginCompareAttEntries for speed
- bba81f9d3d4f 19 (unreleased) landed