]> git.ipfire.org Git - thirdparty/postgresql.git/log
thirdparty/postgresql.git
10 days agoAdd fast path for foreign key constraint checks
Amit Langote [Tue, 31 Mar 2026 04:49:21 +0000 (13:49 +0900)] 
Add fast path for foreign key constraint checks

Add a fast-path optimization for foreign key checks that bypasses SPI
by directly probing the unique index on the referenced table.
Benchmarking shows ~1.8x speedup for bulk FK inserts (int PK/int FK,
1M rows, where PK table and index are cached).

The fast path applies when the referenced table is not partitioned and
the constraint does not involve temporal semantics.  Otherwise, the
existing SPI path is used.

This optimization covers only the referential check trigger
(RI_FKey_check).  The action triggers (CASCADE, SET NULL, SET DEFAULT,
RESTRICT, NO ACTION) must find rows on the FK side to modify, which
requires a table scan with no guaranteed index available, and then
execute DML against those rows through the full executor path including
any triggered actions.  Replicating that without substantial code
duplication is not feasible, so those triggers remain on the SPI path.
Extending the fast path to action triggers remains possible as future
work if the necessary infrastructure is built.

The new ri_FastPathCheck() function extracts the FK values, builds scan
keys, performs an index scan, and locks the matching tuple with
LockTupleKeyShare via ri_LockPKTuple(), which handles the RI-specific
subset of table_tuple_lock() results.

If the locked tuple was reached by chasing an update chain
(tmfd.traversed), recheck_matched_pk_tuple() verifies that the key
is still the same, emulating EvalPlanQual.

The scan uses GetTransactionSnapshot(), matching what the SPI path
uses (via _SPI_execute_plan pushing GetTransactionSnapshot() as the
active snapshot).  Under READ COMMITTED this is a fresh snapshot;
under REPEATABLE READ / SERIALIZABLE it is the frozen transaction-
start snapshot, so PK rows committed after the transaction started
are not visible.

The ri_CheckPermissions() function performs schema USAGE and table
SELECT checks, matching what the SPI path gets implicitly through
the executor's permission checks.  The fast path also switches to
the PK table owner's security context (with SECURITY_NOFORCE_RLS)
before the index probe, matching the SPI path where the query runs
as the table owner.

ri_HashCompareOp() is adjusted to handle cross-type equality operators
(e.g. int48eq for int4 PK / int8 FK) which can appear in conpfeqop.
The existing code asserted same-type operators only, which was correct
for its existing callers (ri_KeysEqual compares same-type FK column
values via ff_eq_oprs), but the fast path is the first caller to pass
pf_eq_oprs, which can be cross-type.

Per-key metadata (compare entries, operator procedures, strategy
numbers) is cached in RI_ConstraintInfo via
ri_populate_fastpath_metadata() on first use, eliminating repeated
calls to ri_HashCompareOp() and get_op_opfamily_properties().
conindid and pk_is_partitioned are also cached at constraint load
time, avoiding per-invocation syscache lookups and the need to open
pk_rel before deciding whether the fast path applies.

New regression tests cover RLS bypass and ACL enforcement for the
fast-path permission checks.  New isolation tests exercise concurrent
PK updates under both READ COMMITTED and REPEATABLE READ.

Author: Junwang Zhao <zhjwpku@gmail.com>
Co-authored-by: Amit Langote <amitlangote09@gmail.com>
Reviewed-by: Haibo Yan <tristan.yim@gmail.com>
Tested-by: Tomas Vondra <tomas@vondra.me>
Discussion: https://postgr.es/m/CA+HiwqF4C0ws3cO+z5cLkPuvwnAwkSp7sfvgGj3yQ=Li6KNMqA@mail.gmail.com

10 days agoChange syntax of EXCEPT TABLE clause in publication commands.
Amit Kapila [Tue, 31 Mar 2026 04:10:51 +0000 (09:40 +0530)] 
Change syntax of EXCEPT TABLE clause in publication commands.

Adjust the syntax of the EXCEPT clause in CREATE/ALTER PUBLICATION
added in commits fd366065e0 and 493f8c6439 to move the TABLE keyword
inside the relation list.

Old syntax:
CREATE PUBLICATION ... FOR ALL TABLES EXCEPT TABLE (t1, ...);
ALTER PUBLICATION  ... SET ALL TABLES EXCEPT TABLE (t1, ...);

New syntax:
CREATE PUBLICATION ... FOR ALL TABLES EXCEPT (TABLE t1, ...);
ALTER PUBLICATION  ... SET ALL TABLES EXCEPT (TABLE t1, ...);

This is to ensure that inclusion and exclusion list can be specified in
a same way. Previously, the exclusion table list can be specified as
TABLE (t1, t2, t3) and inclusion list can be specified as TABLE t1, t2,
t3, or TABLE t1, TABLE t2, TABLE t3.

This change is purely syntactic and does not alter behavior.

Reported-by: Masahiko Sawada <sawada.mshk@gmail.com>
Author: vignesh C <vignesh21@gmail.com>
Author: Shlok Kyal <shlok.kyal.oss@gmail.com>
Reviewed-by: shveta malik <shveta.malik@gmail.com>
Reviewed-by: Peter Smith <smithpb2250@gmail.com>
Reviewed-by: Zhijie Hou <houzj.fnst@fujitsu.com>
Reviewed-by: Dilip Kumar <dilipbalaut@gmail.com>
Reviewed-by: SATYANARAYANA NARLAPURAM <satyanarlapuram@gmail.com>
Reviewed-by: Amit Kapila <amit.kapila16@gmail.com>
Discussion: https://postgr.es/m/CAD21AoCC8XuwfX62qKBSfHUAoww_XB3_84HjswgL9jxQy696yw@mail.gmail.com
Discussion: https://postgr.es/m/CALDaNm3=JrucjhiiwsYQw5-PGtBHFONa6F7hhWCXMsGvh=tamA@mail.gmail.com

10 days agoDoc: update ddl.sgml's description of cmin and cmax.
Tom Lane [Mon, 30 Mar 2026 22:25:17 +0000 (18:25 -0400)] 
Doc: update ddl.sgml's description of cmin and cmax.

We long ago folded these two tuple header fields into one field
to save space.  However, nothing was done to the user-facing
documentation about them, perhaps with the idea that we'd add
code to emit something approximating the original definitions.
That never happened and presumably never will, so update the
text to reflect current reality.

Author: Paul A Jungwirth <pj@illuminatedcomputing.com>
Co-authored-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/CA+renyVYYboiTayRRE0j1oKpeB+NjEBSUXfwgEu6O0JESSmauQ@mail.gmail.com

10 days agoAdd warning option -Wold-style-declaration
Peter Eisentraut [Mon, 30 Mar 2026 21:12:38 +0000 (23:12 +0200)] 
Add warning option -Wold-style-declaration

This warning has been triggered a few times via the buildfarm (see
commits 8212625e53f2b7259f8557afe86a9e73b), so we might as well
add it so that everyone sees it.

(This is completely separate from the recently added
-Wold-style-definition.)

Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Reviewed-by: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Discussion: https://www.postgresql.org/message-id/flat/aa73q1aT0A3/vke/%40ip-10-97-1-34.eu-west-3.compute.internal

10 days agolibpq: Add oauth_ca_file option to change CAs without debugging
Jacob Champion [Mon, 30 Mar 2026 21:14:45 +0000 (14:14 -0700)] 
libpq: Add oauth_ca_file option to change CAs without debugging

PG18 hid the PGOAUTHCAFILE envvar behind PGOAUTHDEBUG=UNSAFE, because I
thought that any "real" production usage of private CA certificates
would have them added to the Curl system trust store. But there are use
cases, such as containerized environments, that prefer to manage custom
CA settings more granularly; some of them consider envvar configuration
of certificates to be standard practice.

Move PGOAUTHCAFILE out from under the debug flag, and add an
oauth_ca_file option to libpq to configure trusted CAs per connection.

Patch by Jonathan Gonzalez V., with some additional wordsmithing and
test organization by me.

Author: Jonathan Gonzalez V. <jonathan.abdiel@gmail.com>
Co-authored-by: Jacob Champion <jacob.champion@enterprisedb.com>
Reviewed-by: Zsolt Parragi <zsolt.parragi@percona.com>
Discussion: https://postgr.es/m/16a91d02795cb991963326a902afa764e4d721db.camel%40gmail.com

10 days agoRemove bits* typedefs.
Nathan Bossart [Mon, 30 Mar 2026 21:12:08 +0000 (16:12 -0500)] 
Remove bits* typedefs.

In addition to removing the bits8, bits16, and bits32 typedefs,
this commit replaces all uses with uint8, uint16, or uint32.  bits*
provided little benefit beyond establishing the intent of the
variable, and they were inconsistently used for that purpose.
Third-party code should instead use the corresponding uint*
typedef.

Suggested-by: Andres Freund <andres@anarazel.de>
Reviewed-by: Álvaro Herrera <alvherre@kurilemu.de>
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Reviewed-by: Robert Haas <robertmhaas@gmail.com>
Reviewed-by: Michael Paquier <michael@paquier.xyz>
Reviewed-by: Peter Eisentraut <peter@eisentraut.org>
Reviewed-by: Melanie Plageman <melanieplageman@gmail.com>
Reviewed-by: Dagfinn Ilmari Mannsåker <ilmari@ilmari.org>
Discussion: https://postgr.es/m/absbX33E4eaA0Ity%40nathan

10 days agoUse ShmemInitStruct to allocate shmem for semaphores
Heikki Linnakangas [Mon, 30 Mar 2026 20:39:35 +0000 (23:39 +0300)] 
Use ShmemInitStruct to allocate shmem for semaphores

This makes them visible in pg_shmem_allocations

Reviewed-by: Tomas Vondra <tomas@vondra.me>
Discussion: https://www.postgresql.org/message-id/01ab1d41-3eda-4705-8bbd-af898f5007f1@iki.fi

10 days agoSet pd_prune_xid on insert
Melanie Plageman [Mon, 30 Mar 2026 20:07:11 +0000 (16:07 -0400)] 
Set pd_prune_xid on insert

Now that on-access pruning can update the visibility map (VM) during
read-only queries, set the page’s pd_prune_xid hint during INSERT and on
the new page during UPDATE.

This allows heap_page_prune_and_freeze() to set the VM the first time a
page is read after being filled with tuples. This may avoid I/O
amplification by setting the page all-visible when it is still in shared
buffers and allowing later vacuums to skip scanning the page. It also
enables index-only scans of newly inserted data much sooner.

As a side benefit, this addresses a long-standing note in heap_insert()
and heap_multi_insert(): aborted inserts can now be pruned on-access
rather than lingering until the next VACUUM.

Author: Melanie Plageman <melanieplageman@gmail.com>
Reviewed-by: Andres Freund <andres@anarazel.de>
Reviewed-by: Chao Li <li.evan.chao@gmail.com>
Discussion: https://postgr.es/m/flat/CAAKRu_ZMw6Npd_qm2KM%2BFwQ3cMOMx1Dh3VMhp8-V7SOLxdK9-g%40mail.gmail.com

10 days agoAllow on-access pruning to set pages all-visible
Melanie Plageman [Mon, 30 Mar 2026 19:47:07 +0000 (15:47 -0400)] 
Allow on-access pruning to set pages all-visible

Many queries do not modify the underlying relation. For such queries, if
on-access pruning occurs during the scan, we can check whether the page
has become all-visible and update the visibility map accordingly.
Previously, only vacuum and COPY FREEZE marked pages as all-visible or
all-frozen.

This commit implements on-access VM setting for sequential scans, tid
range scans, sample scans, bitmap heap scans, and the underlying heap
relation in index scans.

Setting the visibility map on-access can avoid write amplification
caused by vacuum later needing to set the page all-visible, which could
trigger a write and potentially an FPI. It also allows more frequent
index-only scans, since they require pages to be marked all-visible in
the VM.

Author: Melanie Plageman <melanieplageman@gmail.com>
Reviewed-by: Andres Freund <andres@anarazel.de>
Reviewed-by: Kirill Reshke <reshkekirill@gmail.com>
Reviewed-by: Chao Li <li.evan.chao@gmail.com>
Discussion: https://postgr.es/m/flat/CAAKRu_ZMw6Npd_qm2KM%2BFwQ3cMOMx1Dh3VMhp8-V7SOLxdK9-g%40mail.gmail.com

11 days agoAdd commit 874da8b1f6 to .git-blame-ignore-revs.
Nathan Bossart [Mon, 30 Mar 2026 19:35:24 +0000 (14:35 -0500)] 
Add commit 874da8b1f6 to .git-blame-ignore-revs.

11 days agoconfigure: Apply -Werror=vla to C++ as well as C
Peter Eisentraut [Mon, 30 Mar 2026 18:55:16 +0000 (20:55 +0200)] 
configure: Apply -Werror=vla to C++ as well as C

The comment part of d9dd406fe281 mentioned that -Wvla is not applicable
for C++. That is not fully correct: it is true that VLAs are not part of the
C++ standard, and g++ with -pedantic will also warn about them as a non-standard
extension.  However, -Wvla itself works fine in C++ and will catch VLA
usage just as in C.

Fix configure.ac to apply -Werror=vla to C++ as well. There is no need to
fix meson.build as it already includes it in common_warning_flags.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Suggested-by: Peter Eisentraut <peter@eisentraut.org>
Discussion: https://postgr.es/m/7bf60ab1-2b5d-4a77-93ce-815072a0a014%40eisentraut.org

11 days agoBe more careful to preserve consistency of a tuplestore.
Tom Lane [Mon, 30 Mar 2026 17:59:54 +0000 (13:59 -0400)] 
Be more careful to preserve consistency of a tuplestore.

Several places in tuplestore.c would leave the tuplestore data
structure effectively corrupt if some subroutine were to throw
an error.  Notably, if WRITETUP() failed after some number of
successful calls within dumptuples(), the tuplestore would
contain some memtuples pointers that were apparently live
entries but in fact pointed to pfree'd chunks.

In most cases this sort of thing is fine because transaction
abort cleanup is not too picky about the contents of memory that
it's going to throw away anyway.  There's at least one exception
though: if a Portal has a holdStore, we're going to call
tuplestore_end() on that, even during transaction abort.
So it's not cool if that tuplestore is corrupt, and that means
tuplestore.c has to be more careful.

This oversight demonstrably leads to crashes in v15 and before,
if a holdable cursor fails to persist its data due to an undersized
temp_file_limit setting.  Very possibly the same thing can happen in
v16 and v17 as well, though the specific test case submitted failed
to fail there (cf. 095555daf).  The failure is accidentally dodged
as of v18 because 590b045c3 got rid of tuplestore_end's retail tuple
deletion loop.  Still, it seems unwise to permit tuplestores to become
internally inconsistent in any branch, so I've applied the same fix
across the board.

Since the known test case for this is rather expensive and doesn't
fail in recent branches, I've omitted it.

Bug: #19438
Reported-by: Dmitriy Kuzmin <kuzmin.db4@gmail.com>
Author: Tom Lane <tgl@sss.pgh.pa.us>
Reviewed-by: David Rowley <dgrowleyml@gmail.com>
Discussion: https://postgr.es/m/19438-9d37b179c56d43aa@postgresql.org
Backpatch-through: 14

11 days agoReplace getopt() with our re-entrant variant in the backend
Heikki Linnakangas [Mon, 30 Mar 2026 17:47:16 +0000 (20:47 +0300)] 
Replace getopt() with our re-entrant variant in the backend

Some of these probably could continue using non-re-entrant getopt()
even if we start using threads in the future, but it seems better to
make them all anyway, so that we have a clear-cut rule of "no plain
getopt() in the postgres binary".

Reviewed-by: Peter Eisentraut <peter@eisentraut.org>
Discussion: https://www.postgresql.org/message-id/d1da5f0e-0d68-47c9-a882-eb22f462752f@iki.fi

11 days agoInvent a variant of getopt(3) that is thread-safe
Heikki Linnakangas [Mon, 30 Mar 2026 17:47:13 +0000 (20:47 +0300)] 
Invent a variant of getopt(3) that is thread-safe

The standard getopt(3) function is not re-entrant nor thread-safe.
That's OK for current usage, but it's one more little thing we need to
change in order to make the server multi-threaded.

There's no standard getopt_r() function on any platform, I presume
because command line arguments are usually parsed early when you start
a program, before launching any threads, so there isn't much need for
it. However, we call it at backend startup to parse options from the
startup packet. Because there's no standard, we're free to define our
own.

The pg_getopt_start/next() implementation is based on the old getopt
implementation, I just gathered all the state variables to a struct.
The non-re-entrant getopt() function is now a wrapper around the
re-entrant variant, on platforms that don't have getopt(3).
getopt_long() is not used in the server, so we don't need to provide a
re-entrant variant of that.

Reviewed-by: Peter Eisentraut <peter@eisentraut.org>
Discussion: https://www.postgresql.org/message-id/d1da5f0e-0d68-47c9-a882-eb22f462752f@iki.fi

11 days agoFix latent bug in get_stats_option_name()
Heikki Linnakangas [Mon, 30 Mar 2026 17:34:48 +0000 (20:34 +0300)] 
Fix latent bug in get_stats_option_name()

The function is supposed to look at the passed in 'arg' argument, but
peeks at the 'optarg' global variable that's part of getopt()
instead. It happened to work anyway, because all callers passed
'optarg' as the argument.

Reviewed-by: Peter Eisentraut <peter@eisentraut.org>
Discussion: https://www.postgresql.org/message-id/d1da5f0e-0d68-47c9-a882-eb22f462752f@iki.fi

11 days agoPass down information on table modification to scan nodes
Melanie Plageman [Mon, 30 Mar 2026 17:27:34 +0000 (13:27 -0400)] 
Pass down information on table modification to scan nodes

Pass down information to sequential scan, index [only] scan, bitmap
table scan, sample scan, and TID range scan nodes on whether or not the
query modifies the relation being scanned. A later commit will use this
information to update the VM during on-access pruning only if the
relation is not modified by the query.

Author: Melanie Plageman <melanieplageman@gmail.com>
Reviewed-by: Andres Freund <andres@anarazel.de>
Reviewed-by: Andrey Borodin <x4mmm@yandex-team.ru>
Reviewed-by: Tomas Vondra <tomas@vondra.me>
Reviewed-by: Chao Li <li.evan.chao@gmail.com>
Discussion: https://postgr.es/m/4379FDA3-9446-4E2C-9C15-32EFE8D4F31B%40yandex-team.ru

11 days agoDon't use bits32 in table AM interface
Álvaro Herrera [Mon, 30 Mar 2026 17:03:28 +0000 (19:03 +0200)] 
Don't use bits32 in table AM interface

Seems there's near-universal dislike for the bitsXX typedefs.
Revert that part of commit 1bd6f22f43ac in favor of using plain uint32.

11 days agoThread flags through begin-scan APIs
Melanie Plageman [Mon, 30 Mar 2026 16:27:24 +0000 (12:27 -0400)] 
Thread flags through begin-scan APIs

Add an AM user-settable flags parameter to several of the table scan
functions, one table AM callback, and index_beginscan(). This allows
users to pass additional context to be used when building the scan
descriptors.

For index scans, a new flags field is added to IndexFetchTableData, and
the heap AM saves the caller-provided flags there.

This introduces an extension point for follow-up work to pass per-scan
information (such as whether the relation is read-only for the current
query) from the executor to the AM layer.

Author: Melanie Plageman <melanieplageman@gmail.com>
Reviewed-by: Andres Freund <andres@anarazel.de>
Reviewed-by: Tomas Vondra <tomas@vondra.me>
Reviewed-by: David Rowley <dgrowleyml@gmail.com>
Reviewed-by: Chao Li <li.evan.chao@gmail.com>
Discussion: https://postgr.es/m/2be31f17-5405-4de9-8d73-90ebc322f7d8%40vondra.me

11 days agoDetect pfree or repalloc of a previously-freed memory chunk.
Tom Lane [Mon, 30 Mar 2026 16:02:08 +0000 (12:02 -0400)] 
Detect pfree or repalloc of a previously-freed memory chunk.

Before the major rewrite in commit c6e0fe1f2, AllocSetFree() would
typically crash when asked to free an already-free chunk.  That was
an ugly but serviceable way of detecting coding errors that led to
double pfrees.  But since that rewrite, double pfrees went through
just fine, because the "hdrmask" of a freed chunk isn't changed at all
when putting it on the freelist.  We'd end with a corrupt freelist
that circularly links back to the doubly-freed chunk, which would
usually result in trouble later, far removed from the actual bug.

This situation is no good at all for debugging purposes.  Fortunately,
we can fix it at low cost in MEMORY_CONTEXT_CHECKING builds by making
AllocSetFree() check for chunk->requested_size == InvalidAllocSize,
relying on the pre-existing code that sets it that way just below.

I investigated the alternative of changing a freed chunk's methodid
field, which would allow detection in non-MEMORY_CONTEXT_CHECKING
builds too.  But that adds measurable overhead.  Seeing that we didn't
notice this oversight for more than three years, it's hard to argue
that detecting this type of bug is worth any extra overhead in
production builds.

Likewise fix AllocSetRealloc() to detect repalloc() on a freed chunk,
and apply similar changes in generation.c and slab.c.  (generation.c
would hit an Assert failure anyway, but it seems best to make it act
like aset.c.)  bump.c doesn't need changes since it doesn't support
pfree in the first place.  Ideally alignedalloc.c would receive
similar changes, but in debugging builds it's impossible to reach
AlignedAllocFree() or AlignedAllocRealloc() on a pfreed chunk, because
the underlying context's pfree would have wiped the chunk header of
the aligned chunk.  But that means we should get an error of some
sort, so let's be content with that.

Per investigation of why the test case for bug #19438 didn't appear to
fail in v16 and up, even though the underlying bug was still present.
(This doesn't fix the underlying double-free bug, just cause it to
get detected.)

Bug: #19438
Reported-by: Dmitriy Kuzmin <kuzmin.db4@gmail.com>
Author: Tom Lane <tgl@sss.pgh.pa.us>
Reviewed-by: David Rowley <dgrowleyml@gmail.com>
Discussion: https://postgr.es/m/19438-9d37b179c56d43aa@postgresql.org
Backpatch-through: 16

11 days agoFix outdated comment on MainLWLockArray
Heikki Linnakangas [Mon, 30 Mar 2026 14:13:11 +0000 (17:13 +0300)] 
Fix outdated comment on MainLWLockArray

It's no longer passed to child processes down via BackendParameters in
EXEC_BACKEND mode.

Reported-by: Sami Imseih <samimseih@gmail.com>
Discussion: https://www.postgresql.org/message-id/CAA5RZ0vPWNMvTBqyH7nqDRrHd6Y4Et5iNqXFuwpbsPOk3cL4rQ@mail.gmail.com

11 days agopg_plan_advice: Avoid assertion failure with partitionwise aggregate.
Robert Haas [Mon, 30 Mar 2026 13:58:25 +0000 (09:58 -0400)] 
pg_plan_advice: Avoid assertion failure with partitionwise aggregate.

An Append node that is part of a partitionwise aggregate has no
apprelids. If such a node was elided, the previous coding would
attempt to call unique_nonjoin_rtekind() on a NULL pointer, which
leads to an assertion failure. Insert a NULL check to prevent that.

Reported-by: Alexander Lakhin <exclusion@gmail.com>
Discussion: http://postgr.es/m/0afba1ce-c946-4131-972d-191d9a1c097c@gmail.com

11 days agoRemove PlannedStmt->resultRelations in favor of resultRelationRelids
Melanie Plageman [Mon, 30 Mar 2026 13:51:28 +0000 (09:51 -0400)] 
Remove PlannedStmt->resultRelations in favor of resultRelationRelids

PlannedStmt->resultRelations was an integer list of range table indexes
because at the time it was added (to Query), the Bitmapset data type did
not yet exist in Postgres.

0f4c170cf3b added a Bitmapset of result relations, so remove the integer
list of RTIs and use the more compact resultRelationRelids.

Discussion: https://postgr.es/m/CAApHDvqAOeOwCKh9g0gfxWa040%3DHyc7_oA%3DC59rjod8kXJDWyw%40mail.gmail.com

11 days agoMake it cheap to check if a relation is modified by a query
Melanie Plageman [Mon, 30 Mar 2026 13:38:03 +0000 (09:38 -0400)] 
Make it cheap to check if a relation is modified by a query

Save the range table indexes of result relations and row mark relations
in separate bitmapsets in the PlannedStmt. Precomputing them allows
cheap membership checks during execution. Together, these two groups
approximate all relations that will be modified by a query. This
includes relations targeted by INSERT, UPDATE, DELETE, and MERGE as well
as relations with any row mark (like SELECT FOR UPDATE).

Future work will use information on whether or not a relation is
modified by a query in a heuristic.

PlannedStmt->resultRelations is only used in a membership check, so it
will be removed in a separate commit.

Author: Melanie Plageman <melanieplageman@gmail.com>
Reviewed-by: Andres Freund <andres@anarazel.de>
Reviewed-by: David Rowley <dgrowleyml@gmail.com>
Reviewed-by: Chao Li <li.evan.chao@gmail.com>
Discussion: https://postgr.es/m/F5CDD1B5-628C-44A1-9F85-3958C626F6A9%40gmail.com

11 days agoHave table_insert and siblings use an unsigned type for options
Álvaro Herrera [Mon, 30 Mar 2026 11:27:04 +0000 (13:27 +0200)] 
Have table_insert and siblings use an unsigned type for options

Using signed types can lead to bugs, such as the one fixed by commit
2a2e1b470b9b.

Discussion: https://postgr.es/m/44e6ze3kuunhky63wmfjxrmn72pds2whwf5ok6hpz7c4my7k2h@l65zhpcuasnf

11 days agoheaderscheck: Avoid mutual inclusion of pg_config.h and c.h
Peter Eisentraut [Mon, 30 Mar 2026 07:31:08 +0000 (09:31 +0200)] 
headerscheck: Avoid mutual inclusion of pg_config.h and c.h

Headers that c.h includes early should not have another header
included before them in the headerscheck test file, especially not
c.h.

A particular instance of a problem is that pg_config.h defines some
symbols that c.h later undefines in some cases, such as in the code
added by commit cd083b54bd67, but there were also some before that.
This only works correctly if pg_config.h is included first.

pg_config_manual.h and pg_config_os.h are closely related to
pg_config.h and should be treated the same way.

postgres_ext.h is meant to be usable standalone, so testing it with
c.h included first defeats the point.

c.h also includes port.h, but this commit leaves that alone, since
port.h does need some of c.h to be processed first.  (But because of
header guards, testing port.h separately is probably ineffective.)

Discussion: https://www.postgresql.org/message-id/flat/579116be-5016-4dbc-aed0-c06f8d9f5bbb%40eisentraut.org

11 days agoMake cast functions to type money error safe
Peter Eisentraut [Mon, 30 Mar 2026 08:05:22 +0000 (10:05 +0200)] 
Make cast functions to type money error safe

This converts the cast functions from types integer, bigint, and
numeric to type money to support soft errors.

Note: Casting from type money to type numeric (the other way, function
cash_numeric) is not yet error safe.

Author: jian he <jian.universality@gmail.com>
Discussion: https://www.postgresql.org/message-id/flat/CADkLM%3Dfv1JfY4Ufa-jcwwNbjQixNViskQ8jZu3Tz_p656i_4hQ%40mail.gmail.com

11 days agoRemove extraneous PGDLLIMPORT
John Naylor [Mon, 30 Mar 2026 07:39:13 +0000 (14:39 +0700)] 
Remove extraneous PGDLLIMPORT

Oversight from commit 3c6e8c123896. Should be harmless, so no
backpatch.

Reported-by: Zsolt Parragi <zsolt.parragi@percona.com>
Discussion: https://postgr.es/m/CAN4CZFM8jmh4+1rUR2c++JWK9sV85T8_mqmwHMvM0YWkTm4_dQ@mail.gmail.com

11 days agoFix accidentally casting away const
Peter Eisentraut [Mon, 30 Mar 2026 07:21:49 +0000 (09:21 +0200)] 
Fix accidentally casting away const

Recently introduced in commit b15c1513984.

11 days agoMake cast function from circle to polygon error safe
Peter Eisentraut [Mon, 30 Mar 2026 07:06:27 +0000 (09:06 +0200)] 
Make cast function from circle to polygon error safe

Previously, the function casting type circle to type polygon could not
be made error safe, because it is an SQL language function.

This refactors it as a C/internal function, by sharing code with the
C/internal function that the SQL function previously wrapped, and soft
error support is added.

Author: jian he <jian.universality@gmail.com>
Reviewed-by: Amul Sul <sulamul@gmail.com>
Reviewed-by: Corey Huinker <corey.huinker@gmail.com>
Discussion: Discussion: https://www.postgresql.org/message-id/flat/CADkLM%3Dfv1JfY4Ufa-jcwwNbjQixNViskQ8jZu3Tz_p656i_4hQ%40mail.gmail.com

11 days agoFix FK triggers losing DEFERRABLE/INITIALLY DEFERRED when marked ENFORCED again
Fujii Masao [Mon, 30 Mar 2026 05:37:33 +0000 (14:37 +0900)] 
Fix FK triggers losing DEFERRABLE/INITIALLY DEFERRED when marked ENFORCED again

Previously, a foreign key defined as DEFERRABLE INITIALLY DEFERRED could
behave as NOT DEFERRABLE after being set to NOT ENFORCED and then back
to ENFORCED.

This happened because recreating the FK triggers on re-enabling the constraint
forgot to restore the tgdeferrable and tginitdeferred fields in pg_trigger.

Fix this bug by properly setting those fields when the foreign key constraint
is marked ENFORCED again and its triggers are recreated, so the original
DEFERRABLE and INITIALLY DEFERRED properties are preserved.

Backpatch to v18, where NOT ENFORCED foreign keys were introduced.

Author: Yasuo Honda <yasuo.honda@gmail.com>
Reviewed-by: Fujii Masao <masao.fujii@gmail.com>
Discussion: https://postgr.es/m/CAKmOUTms2nkxEZDdcrsjq5P3b2L_PR266Hv8kW5pANwmVaRJJQ@mail.gmail.com
Backpatch-through: 18

11 days agoFix datum_image_*()'s inability to detect sign-extension variations
David Rowley [Mon, 30 Mar 2026 03:14:34 +0000 (16:14 +1300)] 
Fix datum_image_*()'s inability to detect sign-extension variations

Functions such as hash_numeric() are not careful to use the correct
PG_RETURN_*() macro according to the return type of that function as
defined in pg_proc.  Because that function is meant to return int32,
when the hashed value exceeds 2^31, the 64-bit Datum value won't wrap to
a negative number, which means the Datum won't have the same value as it
would have had it been cast to int32 on a two's complement machine.  This
isn't harmless as both datum_image_eq() and datum_image_hash() may receive
a Datum that's been formed and deformed from a tuple in some cases, and
not in other cases.  When formed into a tuple, the Datum value will be
coerced into an integer according to the attlen as specified by the
TupleDesc.  This can result in two Datums that should be equal being
classed as not equal, which could result in (but not limited to) an error
such as:

ERROR:  could not find memoization table entry

Here we fix this by ensuring we cast the Datum value to a signed integer
according to the typLen specified in the datum_image_eq/datum_image_hash
function call before comparing or hashing.

Author: David Rowley <dgrowleyml@gmail.com>
Reported-by: Tender Wang <tndrwang@gmail.com>
Backpatch-through: 14
Discussion: https://postgr.es/m/CAHewXNmcXVFdB9_WwA8Ez0P+m_TQy_KzYk5Ri5dvg+fuwjD_yw@mail.gmail.com

11 days agopsql: Make \d+ inheritance tables list formatting consistent with other objects
Fujii Masao [Mon, 30 Mar 2026 02:21:22 +0000 (11:21 +0900)] 
psql: Make \d+ inheritance tables list formatting consistent with other objects

This followw up on the previous change (commit 7bff9f106a5) for partitions by
applying the same formatting to inheritance tables lists.

Previously, \d+ <table> displayed inheritance tables differently from other
object lists: the first inheritance table appeared on the same line as the
"Inherits" header. For example:

    Inherits: test_like_5,
              test_like_5x

This commit updates the output so that inheritance tables are listed
consistently with other objects, with each entry on its own line starting
below the header:

    Inherits:
        test_like_5
        test_like_5x

Author: Peter Smith <smithpb2250@gmail.com>
Reviewed-by: Chao Li <li.evan.chao@gmail.com>
Reviewed-by: Neil Chen <carpenter.nail.cz@gmail.com>
Reviewed-by: Greg Sabino Mullane <htamfids@gmail.com>
Reviewed-by: Soumya S Murali <soumyamurali.work@gmail.com>
Reviewed-by: Fujii Masao <masao.fujii@gmail.com>
Discussion: https://postgr.es/m/CAHut+Pu1puO00C-OhgLnAcECzww8MB3Q8DCsvx0cZWHRfs4gBQ@mail.gmail.com

11 days agopsql: Make \d+ partition list formatting consistent with other objects
Fujii Masao [Mon, 30 Mar 2026 02:06:42 +0000 (11:06 +0900)] 
psql: Make \d+ partition list formatting consistent with other objects

Previously, \d+ <table> displayed partitions differently from other object
lists: the first partition appeared on the same line as the "Partitions"
header. For example:

    Partitions: pt12 FOR VALUES IN (1, 2),
                pt34 FOR VALUES IN (3, 4)

This commit updates the output so that partitions are listed consistently
with other objects, with each entry on its own line starting below the header:

    Partitions:
        pt12 FOR VALUES IN (1, 2)
        pt34 FOR VALUES IN (3, 4)

Author: Peter Smith <smithpb2250@gmail.com>
Reviewed-by: Chao Li <li.evan.chao@gmail.com>
Reviewed-by: Neil Chen <carpenter.nail.cz@gmail.com>
Reviewed-by: Greg Sabino Mullane <htamfids@gmail.com>
Reviewed-by: Soumya S Murali <soumyamurali.work@gmail.com>
Reviewed-by: Fujii Masao <masao.fujii@gmail.com>
Discussion: https://postgr.es/m/CAHut+Pu1puO00C-OhgLnAcECzww8MB3Q8DCsvx0cZWHRfs4gBQ@mail.gmail.com

11 days agoDoc: fix stale text about partition locking with cached plans
Amit Langote [Mon, 30 Mar 2026 01:29:21 +0000 (10:29 +0900)] 
Doc: fix stale text about partition locking with cached plans

Commit 121d774caea added text to master describing pruning-aware
locking behavior introduced by 525392d57.  That behavior was
reverted in May 2025, making the text incorrect.  Replace it with
the text used in back branches, which correctly describes current
behavior: pruned partitions are still locked at the beginning of
execution.

Discussion: https://postgr.es/m/CA+HiwqFT0fPPoYBr0iUFWNB-Og7bEXB9hB=6ogk_qD9=OM8Vbw@mail.gmail.com

11 days agoAdd comment explaining fire_triggers=false in ri_PerformCheck()
Amit Langote [Mon, 30 Mar 2026 01:10:17 +0000 (10:10 +0900)] 
Add comment explaining fire_triggers=false in ri_PerformCheck()

The reason for passing fire_triggers=false to SPI_execute_snapshot()
in ri_PerformCheck() was not documented, making it unclear why it was
done that way.  Add a comment explaining that it ensures AFTER triggers
on rows modified by the RI action are queued in the outer query's
after-trigger context and fire only after all RI updates on the same
row are complete.

Author: Yugo Nagata <nagata@sraoss.co.jp>
Reviewed-by: Kirill Reshke <reshkekirill@gmail.com>
Reviewed-by: Surya Poondla <suryapoondla4@gmail.com>
Discussion: https://postgr.es/m/20250331212648.ad4ab804559001d7f0788741@sraoss.co.jp

12 days agoMake geometry cast functions error safe
Peter Eisentraut [Sun, 29 Mar 2026 18:40:50 +0000 (20:40 +0200)] 
Make geometry cast functions error safe

This adjusts cast functions of the geometry types to support soft
errors.  This requires refactoring of various helper functions to
support error contexts.  Also make the float8 to float4 cast error
safe.  It requires some of the same helper functions.

This is in preparation for a future feature where conversion errors in
casts can be caught.

(The function casting type circle to type polygon is not yet made error
safe, because it is an SQL language function.)

Author: jian he <jian.universality@gmail.com>
Reviewed-by: Amul Sul <sulamul@gmail.com>
Reviewed-by: Corey Huinker <corey.huinker@gmail.com>
Discussion: https://www.postgresql.org/message-id/flat/CADkLM%3Dfv1JfY4Ufa-jcwwNbjQixNViskQ8jZu3Tz_p656i_4hQ%40mail.gmail.com

12 days agoDoc: document more incompatible pg_restore option pairs.
Tom Lane [Sun, 29 Mar 2026 18:06:50 +0000 (14:06 -0400)] 
Doc: document more incompatible pg_restore option pairs.

Most of the pairs of incompatible options (such as --file and --dbname)
are pretty obvious and need no explanation.  But it may not be obvious
that --single-transaction cannot be used together with --create or
multiple jobs, so let's mention that in the documentation.

Author: Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
Reviewed-by: Laurenz Albe <laurenz.albe@cybertec.at>
Discussion: https://postgr.es/m/CAExHW5ti5igDwOOde6shgfS7JPtCY9gNrkB3xNr=FuGTYVDSjQ@mail.gmail.com

12 days agoDoc: clarify introductory description of pg_dumpall.
Tom Lane [Sun, 29 Mar 2026 17:53:17 +0000 (13:53 -0400)] 
Doc: clarify introductory description of pg_dumpall.

Add a sentence that describes the parts of a cluster's state that are
*not* included in the output.

Also swap two sentences in the introductory paragraph.  Without that,
it is not clear what the "it" at the beginning of the second sentence
is referring to.  Also add a reference to pg_restore, since not all
output formats are restored with pg_dump.

Also clarify the recently-added text about where different output
formats go, and relocate it above the ancillary text about having
to run as superuser.

Reported-by: Dimitre Radoulov <cichomitiko@gmail.com>
Author: Laurenz Albe <laurenz.albe@cybertec.at>
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/CAGJBphSX2oMPPu=VM4U8NP4+qffFH_483tFQCJ_s-mOcN3DLDw@mail.gmail.com

12 days agoFix multiple bugs in astreamer pipeline code.
Andrew Dunstan [Mon, 23 Mar 2026 20:17:08 +0000 (16:17 -0400)] 
Fix multiple bugs in astreamer pipeline code.

astreamer_tar_parser_content() sent the wrong data pointer when
forwarding MEMBER_TRAILER padding to the next streamer.  After
astreamer_buffer_until() buffers the padding bytes, the 'data'
pointer has been advanced past them, but the code passed 'data'
instead of bbs_buffer.data.  This caused the downstream consumer
to receive bytes from after the padding rather than the padding
itself, and could read past the end of the input buffer.

astreamer_gzip_decompressor_content() only checked for
Z_STREAM_ERROR from inflate(), silently ignoring Z_DATA_ERROR
(corrupted data) and Z_MEM_ERROR (out of memory).  Fix by
treating any return other than Z_OK, Z_STREAM_END, and
Z_BUF_ERROR as fatal.

astreamer_gzip_decompressor_free() missed calling inflateEnd() to
release zlib's internal decompression state.

astreamer_tar_parser_free() neglected to pfree() the streamer
struct itself, leaking it.

astreamer_extractor_content() did not check the return value of
fclose() when closing an extracted file.  A deferred write error
(e.g., disk full on buffered I/O) would be silently lost.

Discussion: https://postgr.es/m/results/98c6b630-acbb-44a7-97fa-1692ce2b827c@dunslane.net

Reviewed-By: Tom Lane <tgl@sss.pgh.pa.us>
Backpatch-through: 15

12 days agoSort InternalBGWorkers list alphabetically
Álvaro Herrera [Sun, 29 Mar 2026 12:15:00 +0000 (14:15 +0200)] 
Sort InternalBGWorkers list alphabetically

This simplifies deciding where to add a new one.

13 days agoMake cast functions from jsonb error safe
Peter Eisentraut [Sat, 28 Mar 2026 14:44:13 +0000 (15:44 +0100)] 
Make cast functions from jsonb error safe

This adjusts cast functions from jsonb to other types to support soft
errors.  This just involves some refactoring of the underlying helper
functions to use ereturn.

This is in preparation for a future feature where conversion errors in
casts can be caught.

Author: jian he <jian.universality@gmail.com>
Reviewed-by: Amul Sul <sulamul@gmail.com>
Reviewed-by: Corey Huinker <corey.huinker@gmail.com>
Discussion: https://www.postgresql.org/message-id/flat/CADkLM%3Dfv1JfY4Ufa-jcwwNbjQixNViskQ8jZu3Tz_p656i_4hQ%40mail.gmail.com

13 days agoaio: Don't wait for already in-progress IO
Andres Freund [Fri, 27 Mar 2026 23:51:53 +0000 (19:51 -0400)] 
aio: Don't wait for already in-progress IO

When a backend attempts to start a read IO and finds the first buffer already
has I/O in progress, previously it waited for that I/O to complete before
initiating reads for any of the subsequent buffers.

Although it must wait for the I/O to finish when acquiring the buffer, there's
no reason for it to wait when setting up the read operation. Waiting at this
point prevents starting I/O on subsequent buffers and can significantly reduce
concurrency.

This matters in two workloads:
1) When multiple backends scan the same relation concurrently.
2) When a single backend requests the same block multiple times within the
   readahead distance.

Waiting each time an in-progress read is encountered effectively degenerates
the access pattern into synchronous I/O.

To fix this, when encountering an already in-progress IO for the head buffer,
the wait reference is now recorded and waiting is deferred until
WaitReadBuffers(), when the buffer actually needs to be acquired.

In rare cases, a backend may still need to wait synchronously at IO
start time: If another backend has set BM_IO_IN_PROGRESS on the buffer
but has not yet set the wait reference. Such windows should be brief and
uncommon.

Author: Melanie Plageman <melanieplageman@gmail.com>
Author: Andres Freund <andres@anarazel.de>
Reviewed-by: Andres Freund <andres@anarazel.de>
Reviewed-by: Melanie Plageman <melanieplageman@gmail.com>
Reviewed-by: Nazir Bilal Yavuz <byavuz81@gmail.com>
Discussion: https://postgr.es/m/flat/zljergweqti7x67lg5ije2rzjusie37nslsnkjkkby4laqqbfw%403p3zu522yykv

13 days agobufmgr: Improve StartBufferIO interface
Andres Freund [Fri, 27 Mar 2026 23:02:23 +0000 (19:02 -0400)] 
bufmgr: Improve StartBufferIO interface

Until now StartBufferIO() had a few weaknesses:

- As it did not submit staged IOs, it was not safe to call StartBufferIO()
  where there was a potential for unsubmitted IO, which required
  AsyncReadBuffers() to use a wrapper (ReadBuffersCanStartIO()) around
  StartBufferIO().

- With nowait = true, the boolean return value did not allow to distinguish
  between no IO being necessary and having to wait, which would lead
  ReadBuffersCanStartIO() to unnecessarily submit staged IO.

- Several callers needed to handle both local and shared buffers, requiring
  the caller to differentiate between StartBufferIO() and StartLocalBufferIO()

- In a future commit some callers of StartBufferIO() want the BufferDesc's
  io_wref to be returned, to asynchronously wait for in-progress IO

- Indicating whether to wait with the nowait parameter was somewhat confusing
  compared to a wait parameter

Address these issues as follows:

- StartBufferIO() is renamed to StartSharedBufferIO()

- A new StartBufferIO() is introduced that supports both shared and local
  buffers

- The boolean return value has been replaced with an enum, indicating whether
  the IO is already done, already in progress or that the buffer has been
  readied for IO

- A new PgAioWaitRef * argument allows the caller to get the wait reference is
  desired.  All current callers pass NULL, a user of this will be introduced
  subsequently

- Instead of the nowait argument there now is wait

  This probably would not have been worthwhile on its own, but since all these
  lines needed to be touched anyway...

Author: Andres Freund <andres@anarazel.de>
Author: Melanie Plageman <melanieplageman@gmail.com>
Discussion: https://postgr.es/m/zljergweqti7x67lg5ije2rzjusie37nslsnkjkkby4laqqbfw@3p3zu522yykv

13 days agoFix RequestNamedLWLockTranche in single-user mode
Heikki Linnakangas [Fri, 27 Mar 2026 23:02:11 +0000 (01:02 +0200)] 
Fix RequestNamedLWLockTranche in single-user mode

PostmasterContext is not available in single-user mode, use
TopMemoryContext instead. Also make sure that we use the correct
memory context in the lappend().

Author: Nathan Bossart <nathandbossart@gmail.com>
Discussion: https://www.postgresql.org/message-id/acb_Eo1XtmCO_9z7@nathan

13 days agotest_aio: Add read_stream test infrastructure & tests
Andres Freund [Fri, 27 Mar 2026 22:47:04 +0000 (18:47 -0400)] 
test_aio: Add read_stream test infrastructure & tests

While we have a lot of indirect coverage of read streams, there are corner
cases that are hard to test when only indirectly controlling and observing the
read stream.  This commit adds an SQL callable SRF interface for a read stream
and uses that in a few tests.

To make some of the tests possible, the injection point infrastructure in
test_aio had to be expanded to allow blocking IO completion.

While at it, fix a wrong debug message in inj_io_short_read_hook().

Author: Andres Freund <andres@anarazel.de>
Reviewed-by: Nazir Bilal Yavuz <byavuz81@gmail.com>
Reviewed-by: Melanie Plageman <melanieplageman@gmail.com>
Discussion: https://postgr.es/m/zljergweqti7x67lg5ije2rzjusie37nslsnkjkkby4laqqbfw@3p3zu522yykv

13 days agotest_aio: Add basic tests for StartReadBuffers()
Andres Freund [Fri, 27 Mar 2026 22:44:35 +0000 (18:44 -0400)] 
test_aio: Add basic tests for StartReadBuffers()

Upcoming commits will change StartReadBuffers() and its building blocks,
making it worthwhile to directly test StartReadBuffers().

Reviewed-by: Melanie Plageman <melanieplageman@gmail.com>
Discussion: https://postgr.es/m/zljergweqti7x67lg5ije2rzjusie37nslsnkjkkby4laqqbfw@3p3zu522yykv

13 days agoDoc: split functions-posix-regexp section into multiple subsections.
Tom Lane [Fri, 27 Mar 2026 21:41:00 +0000 (17:41 -0400)] 
Doc: split functions-posix-regexp section into multiple subsections.

Create a <sect4> section for each function that the previous text
described in one long series of paragraphs.  Also split the functions'
previously in-line syntax summaries into <synopsis> clauses, which is
more readable and allows us to sneak in an explicit mention of the
result data type.

This change gives us an opportunity to make cross-reference links
more specific, too, so do that.

Author: jian he <jian.universality@gmail.com>
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/CACJufxFuk9P=P4=BZ=qCkgvo6im8aL8NnCkjxx2S2MQDWNdouw@mail.gmail.com

13 days agobufmgr: Make UnlockReleaseBuffer() more efficient
Andres Freund [Fri, 27 Mar 2026 19:27:04 +0000 (15:27 -0400)] 
bufmgr: Make UnlockReleaseBuffer() more efficient

Now that the buffer content lock is implemented as part of BufferDesc.state,
releasing the lock and unpinning the buffer can be implemented as a single
atomic operation.

This improves workloads that have heavy contention on a small number of
buffers substantially, I e.g., see a ~20% improvement for pipelined readonly
pgbench on an older two socket machine.

Reviewed-by: Melanie Plageman <melanieplageman@gmail.com>
Discussion: https://postgr.es/m/5ubipyssiju5twkb7zgqwdr7q2vhpkpmuelxfpanetlk6ofnop@hvxb4g2amb2d

13 days agoUse UnlockReleaseBuffer() in more places
Andres Freund [Fri, 27 Mar 2026 19:27:04 +0000 (15:27 -0400)] 
Use UnlockReleaseBuffer() in more places

An upcoming commit will make UnlockReleaseBuffer() considerably faster and
more scalable than doing LockBuffer(BUFFER_LOCK_UNLOCK); ReleaseBuffer();. But
it's a small performance benefit even as-is.

Most of the callsites changed in this patch are not performance sensitive,
however some, like the nbtree ones, are in critical paths.

This patch changes all the easily convertible places over to
UnlockReleaseBuffer() mainly because I needed to check all of them anyway, and
reducing cases where the operations are done separately makes the checking
easier.

Reviewed-by: Melanie Plageman <melanieplageman@gmail.com>
Discussion: https://postgr.es/m/5ubipyssiju5twkb7zgqwdr7q2vhpkpmuelxfpanetlk6ofnop@hvxb4g2amb2d

13 days agobufmgr: Don't copy pages while writing out
Andres Freund [Fri, 27 Mar 2026 19:27:04 +0000 (15:27 -0400)] 
bufmgr: Don't copy pages while writing out

After the series of preceding commits introducing and using
BufferBeginSetHintBits()/BufferSetHintBits16(), hint bits are not set anymore
while IO is going on. Therefore we do not need to copy pages while they are
being written out anymore.

For the same reason XLogSaveBufferForHint() now does not need to operate on a
copy of the page anymore, but can instead use the normal XLogRegisterBuffer()
mechanism. For that the assertions and comments to XLogRegisterBuffer() had to
be updated to allow share-exclusive locked buffers to be registered.

Reviewed-by: Melanie Plageman <melanieplageman@gmail.com>
Discussion: https://postgr.es/m/5ubipyssiju5twkb7zgqwdr7q2vhpkpmuelxfpanetlk6ofnop@hvxb4g2amb2d

2 weeks agopgindent: ensure all C files end with a newline.
Tom Lane [Fri, 27 Mar 2026 19:38:48 +0000 (15:38 -0400)] 
pgindent: ensure all C files end with a newline.

Not only is this good style, but it dodges some obscure bugs within
pg_bsd_indent.  We could try to fix said bugs, but the amount of
effort required seems far out of proportion to the benefit.

Reported-by: Akshay Joshi <akshay.joshi@enterprisedb.com>
Author: Tom Lane <tgl@sss.pgh.pa.us>
Reviewed-by: Andrew Dunstan <andrew@dunslane.net>
Discussion: https://postgr.es/m/CANxoLDfca8O5SkeDxB_j6SVNXd+pNKaDmVmEW+2yyicdU8fy0w@mail.gmail.com

2 weeks agodoc: Clarify collation requirements for base32hex sortability.
Masahiko Sawada [Fri, 27 Mar 2026 19:13:29 +0000 (12:13 -0700)] 
doc: Clarify collation requirements for base32hex sortability.

While fixing the base32hex UUID sortability test in commit
89210037a0a, it turned out that the expected lexicographical order is
only maintained under the C collation (or an equivalent byte-wise
collation). Natural language collations may employ different rules,
breaking the sortability.

This commit updates the documentation to explicitly state that
base32hex is "byte-wise sortable", ensuring users do not fall into the
trap of using natural language collations when querying their encoded
data.

Co-Authored-by: Andrey Borodin <x4mmm@yandex-team.ru>
Discussion: https://postgr.es/m/CAD21AoAwX1D6baSGuQXm0mzPXPWB07kgaoaaahjNHHenbdY24A@mail.gmail.com

2 weeks agoAdd rudimentary table prioritization to autovacuum.
Nathan Bossart [Fri, 27 Mar 2026 15:17:05 +0000 (10:17 -0500)] 
Add rudimentary table prioritization to autovacuum.

Autovacuum workers scan pg_class twice to collect the set of tables
to process.  The first pass is for plain relations and materialized
views, and the second is for TOAST tables.  When the worker finds a
table to process, it adds it to the end of a list.  Later on, it
processes the tables in the same order as the list.  This simple
strategy has worked surprisingly well for a long time, but there
have been many discussions over the years about trying to improve
it.

This commit introduces a scoring system that is used to sort the
aforementioned list of tables to process.  The idea is to have
autovacuum workers prioritize tables that are furthest beyond their
thresholds (e.g., a table nearing transaction ID wraparound should
be vacuumed first).  This prioritization scheme is certainly far
from perfect; there are simply too many possibilities for any
scoring technique to work across all workloads, and the situation
might change significantly between the time we calculate the score
and the time that autovacuum processes it.  However, we have
attemped to develop something that is expected to work for a large
portion of workloads with reasonable parameter settings.

The score is calculated as the maximum of the ratios of each of the
table's relevant values to its threshold.  For example, if the
number of inserted tuples is 100, and the insert threshold for the
table is 80, the insert score is 1.25.  If all other scores are
below that value, the table's score will be 1.25.  The other
criteria considered for the score are the table ages (both
relfrozenxid and relminmxid) compared to the corresponding
freeze-max-age setting, the number of update/deleted tuples
compared to the vacuum threshold, and the number of
inserted/updated/deleted tuples compared to the analyze threshold.

Once exception to the previous paragraph is for tables nearing
wraparound, i.e., those that have surpassed the effective failsafe
ages.  In that case, the relfrozenxid/relminmxid-based score is
scaled aggressively so that the table has a decent chance of
sorting to the front of the list.

To adjust how strongly each component contributes to the score, the
following parameters can be adjusted from their default of 1.0 to
anywhere between 0.0 and 10.0 (inclusive).  Setting all of these to
0.0 restores pre-v19 prioritization behavior:

autovacuum_freeze_score_weight
autovacuum_multixact_freeze_score_weight
autovacuum_vacuum_score_weight
autovacuum_vacuum_insert_score_weight
autovacuum_analyze_score_weight

This is intended to be a baby step towards smarter autovacuum
workers.  Possible future improvements include, but are not limited
to, periodic reprioritization, automatic cost limit adjustments,
and better observability (e.g., a system view that shows current
scores).  While we do not expect this commit to produce any
earth-shattering improvements, it is arguably a prerequisite for
the aforementioned follow-up changes.

Reviewed-by: Sami Imseih <samimseih@gmail.com>
Reviewed-by: David Rowley <dgrowleyml@gmail.com>
Reviewed-by: Robert Haas <robertmhaas@gmail.com>
Reviewed-by: wenhui qiu <qiuwenhuifx@gmail.com>
Reviewed-by: Greg Burd <greg@burd.me>
Reviewed-by: Bharath Rupireddy <bharath.rupireddyforpostgres@gmail.com>
Discussion: https://postgr.es/m/aOaAuXREwnPZVISO%40nathan

2 weeks agoAlign tests for stored and virtual generated columns
Peter Eisentraut [Fri, 27 Mar 2026 14:49:34 +0000 (15:49 +0100)] 
Align tests for stored and virtual generated columns

These tests were intended to be aligned with each other, but
additional tests for virtual generated columns disrupted that
alignment.  The test confirming that user-defined types are not
allowed in virtual generated columns has also been moved to the
generated_virtual.sql-specific section.

Author: Yugo Nagata <nagata@sraoss.co.jp>
Reviewed-by: Paul A Jungwirth <pj@illuminatedcomputing.com>
Reviewed-by: Mutaamba Maasha <maasha@gmail.com>
Reviewed-by: Surya Poondla <s_poondla@apple.com>
Discussion: https://www.postgresql.org/message-id/flat/20250808115142.e9ccb81f35466a9a131a4c55@sraoss.co.jp

2 weeks agopgindent: Always clean up .BAK files from pg_bsd_indent
Peter Eisentraut [Fri, 27 Mar 2026 13:24:52 +0000 (14:24 +0100)] 
pgindent: Always clean up .BAK files from pg_bsd_indent

The previous commit let pgindent clean up File::Temp files on SIGINT.
This extends that to also cleaning up the .BAK files, created by
pg_bsd_indent.

Author: Jelte Fennema-Nio <postgres@jeltef.nl>
Discussion: https://www.postgresql.org/message-id/flat/DFCDD5H4J7VX.3GJKRBBDCKQ86@jeltef.nl

2 weeks agopgindent: Clean up temp files created by File::Temp on SIGINT
Peter Eisentraut [Fri, 27 Mar 2026 13:24:13 +0000 (14:24 +0100)] 
pgindent: Clean up temp files created by File::Temp on SIGINT

When pressing Ctrl+C while running pgindent, it would often leave around
files like pgtypedefAXUEEA. This slightly changes SIGINT handling so
those files are cleaned up.

Author: Jelte Fennema-Nio <postgres@jeltef.nl>
Discussion: https://www.postgresql.org/message-id/flat/DFCDD5H4J7VX.3GJKRBBDCKQ86@jeltef.nl

2 weeks agoRefactor PredicateLockShmemInit to not reuse var for different things
Heikki Linnakangas [Fri, 27 Mar 2026 11:24:34 +0000 (13:24 +0200)] 
Refactor PredicateLockShmemInit to not reuse var for different things

The PredicateLockShmemInit function is pretty complicated, and one
source of confusion is that it reuses the same local variable for
sizes of things. Replace the different uses with separate variables
for clarity.

Reviewed-by: Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
Discussion: https://www.postgresql.org/message-id/113724ab-0028-493f-9605-6e8570f0939f@iki.fi

2 weeks agoAvoid memory leak on error while parsing pg_stat_statements dump file
Heikki Linnakangas [Fri, 27 Mar 2026 10:20:38 +0000 (12:20 +0200)] 
Avoid memory leak on error while parsing pg_stat_statements dump file

By using palloc() instead of raw malloc().

Reported-by: Gaurav Singh <gaurav.singh@yugabyte.com>
Reviewed-by: Lukas Fittl <lukas@fittl.com>
Reviewed-by: Daniel Gustafsson <daniel@yesql.se>
Discussion: https://www.postgresql.org/message-id/CAEcQ1bYR9s4eQLFDjzzJHU8fj-MTbmRpW-9J-r2gsCn+HEsynw@mail.gmail.com
Backpatch-through: 14

2 weeks agoAdd a graph pattern variable only once
Peter Eisentraut [Fri, 27 Mar 2026 09:49:49 +0000 (10:49 +0100)] 
Add a graph pattern variable only once

An element pattern variable may be repeated in the path pattern.
GraphTableParseState maintains a list of all variable names used in
the graph pattern.  Add a new variable name to that list only when it
is not present already.  This isn't a problem right now, but it could
be in the future.

Author: Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
Discussion: https://www.postgresql.org/message-id/CAExHW5tR4O0vjeqTCPr2VB5pYjNYbJgbCBEQf63NtU5Pz1MiOQ%40mail.gmail.com

2 weeks agoMinor comment fixes to yesterday's LWLock tranche refactoring
Heikki Linnakangas [Fri, 27 Mar 2026 09:44:10 +0000 (11:44 +0200)] 
Minor comment fixes to yesterday's LWLock tranche refactoring

Author: Sami Imseih <samimseih@gmail.com>
Discussion: https://www.postgresql.org/message-id/CAA5RZ0sLENRM+BicUjQFs_rP38oPx3gm0SsGrD0-jMhhM+HZ_w@mail.gmail.com

2 weeks agoReject consecutive element patterns of same kind
Peter Eisentraut [Fri, 27 Mar 2026 09:30:01 +0000 (10:30 +0100)] 
Reject consecutive element patterns of same kind

Adding an implicit empty vertex pattern when a path pattern starts or
ends with an edge pattern or when two consecutive edge patterns appear
in the pattern is not supported right now.  Prohibit such path
patterns.

Author: Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
Reported-by: Alexander Lakhin <exclusion@gmail.com>
Reviewed-by: Henson Choi <assam258@gmail.com>
Discussion: https://www.postgresql.org/message-id/flat/72a23702-6d96-4103-a54b-057c2352e885%2540eisentraut.org

2 weeks agoEnable warning like -Wstrict-prototypes on MSVC as well
Peter Eisentraut [Wed, 25 Mar 2026 14:03:30 +0000 (15:03 +0100)] 
Enable warning like -Wstrict-prototypes on MSVC as well

This adds an MSVC warning option equivalent to those added in commit
29bf4ee7496 for GCC/Clang.

Note that this requires commit bccfc73acde (Disable warnings in system
headers in MSVC).

Reviewed-by: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Discussion: https://www.postgresql.org/message-id/flat/aa73q1aT0A3/vke/%40ip-10-97-1-34.eu-west-3.compute.internal

2 weeks agopg_plan_advice: pgindent
Robert Haas [Fri, 27 Mar 2026 00:10:13 +0000 (20:10 -0400)] 
pg_plan_advice: pgindent

Reported-by: Lukas Fittl <lukas@fittl.com>
2 weeks agoUse ShmemInitStruct to allocate lwlock.c's shared memory
Heikki Linnakangas [Thu, 26 Mar 2026 21:47:37 +0000 (23:47 +0200)] 
Use ShmemInitStruct to allocate lwlock.c's shared memory

It's nice to have them show up in pg_shmem_allocations like all other
shmem areas. ShmemInitStruct() depends on ShmemIndexLock, but only
after postmaster startup.

Reviewed-by: Nathan Bossart <nathandbossart@gmail.com>
Discussion: https://www.postgresql.org/message-id/47aaf57e-1b7b-4e12-bda2-0316081ff50e@iki.fi

2 weeks agoMove ShmemIndexLock into ShmemAllocator
Heikki Linnakangas [Thu, 26 Mar 2026 21:47:33 +0000 (23:47 +0200)] 
Move ShmemIndexLock into ShmemAllocator

This makes shmem.c independent of the main LWLock array. That makes it
possible to stop passing MainLWLockArray through BackendParameters in
the next commit.

Reviewed-by: Nathan Bossart <nathandbossart@gmail.com>
Discussion: https://www.postgresql.org/message-id/47aaf57e-1b7b-4e12-bda2-0316081ff50e@iki.fi

2 weeks agoUse a separate spinlock to protect LWLockTranches
Heikki Linnakangas [Thu, 26 Mar 2026 21:47:29 +0000 (23:47 +0200)] 
Use a separate spinlock to protect LWLockTranches

Previously we reused the shmem allocator's ShmemLock to also protect
lwlock.c's shared memory structures. Introduce a separate spinlock for
lwlock.c for the sake of modularity. Now that lwlock.c has its own
shared memory struct (LWLockTranches), this is easy to do.

Reviewed-by: Nathan Bossart <nathandbossart@gmail.com>
Discussion: https://www.postgresql.org/message-id/47aaf57e-1b7b-4e12-bda2-0316081ff50e@iki.fi

2 weeks agoRefactor how user-defined LWLock tranches are stored in shmem
Heikki Linnakangas [Thu, 26 Mar 2026 21:47:22 +0000 (23:47 +0200)] 
Refactor how user-defined LWLock tranches are stored in shmem

Merge the LWLockTranches and NamedLWLockTrancheRequest data structures
in shared memory into one array of user-defined tranches. The
NamedLWLockTrancheRequest list is now only used in postmaster, to hold
the requests until shared memory is initialized.

Introduce a C struct, LWLockTranches, to hold all the different fields
kept in shared memory. This gives an easier overview of what are all
the things kept in shared memory. Previously, we had separate pointers
for LWLockTrancheNames, LWLockCounter and the (shared memory copy of)
NamedLWLockTrancheRequestArray.

Reviewed-by: Nathan Bossart <nathandbossart@gmail.com>
Discussion: https://www.postgresql.org/message-id/47aaf57e-1b7b-4e12-bda2-0316081ff50e@iki.fi

2 weeks agoRename MAX_NAMED_TRANCHES to MAX_USER_DEFINED_TRANCHES
Heikki Linnakangas [Thu, 26 Mar 2026 21:46:04 +0000 (23:46 +0200)] 
Rename MAX_NAMED_TRANCHES to MAX_USER_DEFINED_TRANCHES

The "named tranches" term is a little confusing. In most places it
refers to tranches requested with RequestNamedLWLockTranche(), even
though all built-in tranches and tranches allocated with
LWLockNewTrancheId() also have a name. But in MAX_NAMED_TRANCHES, it
refers to tranches requested with either RequestNamedLWLockTranche()
or LWLockNewTrancheId(), as it's the maximum of all of those in total.

The "user defined" term is already used in
LWTRANCHE_FIRST_USER_DEFINED, so let's standardize on that to mean
tranches allocated with either RequestNamedLWLockTranche() or
LWLockNewTrancheId().

Reviewed-by: Nathan Bossart <nathandbossart@gmail.com>
Reviewed-by: Sami Imseih <samimseih@gmail.com>
Discussion: https://www.postgresql.org/message-id/47aaf57e-1b7b-4e12-bda2-0316081ff50e@iki.fi

2 weeks agoDoc: declutter CREATE TABLE synopsis.
Tom Lane [Thu, 26 Mar 2026 21:27:32 +0000 (17:27 -0400)] 
Doc: declutter CREATE TABLE synopsis.

Factor out the "persistence mode" and storage/compression parts
of the syntax synopsis to reduce line lengths and increase
readability.  Also add an introductory para about the persistence
modes so that the Description section still lines up with the
synopsis.

Author: David G. Johnston <david.g.johnston@gmail.com>
Reviewed-by: Laurenz Albe <laurenz.albe@cybertec.at>
Reviewed-by: Jian He <jian.universality@gmail.com>
Discussion: https://postgr.es/m/CAKFQuwYfMV-2SdrP-umr5SVNSqTn378BUvHsebetp5=DhT494w@mail.gmail.com

2 weeks agopg_plan_advice: Invent DO_NOT_SCAN(relation_identifier).
Robert Haas [Thu, 26 Mar 2026 21:09:57 +0000 (17:09 -0400)] 
pg_plan_advice: Invent DO_NOT_SCAN(relation_identifier).

The premise of src/test/modules/test_plan_advice is that if we plan
a query once, generate plan advice, and then replan it using that
same advice, all of that advice should apply cleanly, since the
settings and everything else are the same. Unfortunately, that's
not the case: the test suite is the main regression tests, and
concurrent activity can change the statistics on tables involved
in the query, especially system catalogs. That's OK as long as it
only affects costing, but in a few cases, it affects which relations
appear in the final plan at all.

In the buildfarm failures observed to date, this happens because
we consider alternative subplans for the same portion of the query;
in theory, MinMaxAggPath is vulnerable to a similar hazard. In both
cases, the planner clones an entire subquery, and the clone has a
different plan name, and therefore different range table identifiers,
than the original. If a cost change results in flipping between one
of these plans and the other, the test_plan_advice tests will fail,
because the range table identifiers to which advice was applied won't
even be present in the output of the second planning cycle.

To fix, invent a new DO_NOT_SCAN advice tag. When generating advice,
emit it for relations that should not appear in the final plan at
all, because some alternative version of that relation was used
instead. When DO_NOT_SCAN is supplied, disable all scan methods for
that relation.

To make this work, we reuse a bunch of the machinery that previously
existed for the purpose of ensuring that we build the same set of
relation identifiers during planning as we do from the final
PlannedStmt. In the process, this commit slightly weakens the
cross-check mechanism: before this commit, it would fire whenever
the pg_plan_advice module was loaded, even if pg_plan_advice wasn't
actually doing anything; now, it will only engage when we have some
other reason to create a pgpa_planner_state. The old way was complex
and didn't add much useful test coverage, so this seems like an
acceptable sacrifice.

Discussion: http://postgr.es/m/CA+TgmoYuWmN-00Ec5pY7zAcpSFQUQLbgAdVWGR9kOR-HM-fHrA@mail.gmail.com
Reviewed-by: Lukas Fittl <lukas@fittl.com>
2 weeks agoAdd an alternative_plan_name field to PlannerInfo.
Robert Haas [Thu, 26 Mar 2026 20:45:17 +0000 (16:45 -0400)] 
Add an alternative_plan_name field to PlannerInfo.

Typically, we have only one PlannerInfo for any given subquery, but
when we are considering a MinMaxAggPath or a hashed subplan, we end
up creating a second PlannerInfo for the same portion of the query,
with a clone of the original range table. In fact, in the MinMaxAggPath
case, we might end up creating several clones, one per aggregate.

At present, there's no easy way for a plugin, such as pg_plan_advice,
to understand the relationships between the original range table and
the copies of it that are created in these cases.  To fix, add an
alternative_plan_name field to PlannerInfo. For a hashed subplan, this
is the plan name for the non-hashed alternative; for minmax aggregates,
this is the plan_name from the parent PlannerInfo; otherwise, it's the
same as plan_name.

Discussion: http://postgr.es/m/CA+TgmoYuWmN-00Ec5pY7zAcpSFQUQLbgAdVWGR9kOR-HM-fHrA@mail.gmail.com
Reviewed-by: Lukas Fittl <lukas@fittl.com>
2 weeks agoDoc: commit performs rollback of aborted transactions.
Tom Lane [Thu, 26 Mar 2026 19:14:21 +0000 (15:14 -0400)] 
Doc: commit performs rollback of aborted transactions.

The COMMIT command handles an aborted transaction in the same
manner as the ROLLBACK command, but this wasn't explained in
its official reference page.  Also mention that behavior in
the tutorial's material on transactions.

Also add a comment mentioning that we don't raise an exception
for COMMIT within an aborted transaction, as the SQL standard
would have us do.

Hyperlink a couple of cross-references while we're at it.

Author: David G. Johnston <david.g.johnston@gmail.com>
Reviewed-by: Gurjeet Singh <gurjeet@singh.im>
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/CAKFQuwYgYR3rWt6vFXw=ZWZ__bv7PqvdOnHujG+UyqE11f+3sg@mail.gmail.com

2 weeks agoAddress perlcritic complaint in response to 906a0469728
Andres Freund [Thu, 26 Mar 2026 19:03:47 +0000 (15:03 -0400)] 
Address perlcritic complaint in response to 906a0469728

2 weeks agobufmgr: Restructure AsyncReadBuffers()
Andres Freund [Thu, 26 Mar 2026 14:51:52 +0000 (10:51 -0400)] 
bufmgr: Restructure AsyncReadBuffers()

Restructure AsyncReadBuffers() to use early return when the head buffer is
already valid, instead of using a did_start_io flag and if/else branches. Also
move around a bit of the code to be located closer to where it is used. This
is a refactor only.

Author: Melanie Plageman <melanieplageman@gmail.com>
Reviewed-by: Andres Freund <andres@anarazel.de>
Discussion: https://postgr.es/m/zljergweqti7x67lg5ije2rzjusie37nslsnkjkkby4laqqbfw@3p3zu522yykv

2 weeks agobufmgr: Make buffer hit helper
Andres Freund [Thu, 26 Mar 2026 14:51:25 +0000 (10:51 -0400)] 
bufmgr: Make buffer hit helper

Already two places count buffer hits, requiring quite a few lines of
code since we do accounting in so many places. Future commits will add
more locations, so refactor into a helper.

Author: Melanie Plageman <melanieplageman@gmail.com>
Reviewed-by: Nazir Bilal Yavuz <byavuz81@gmail.com>
Discussion: https://postgr.es/m/zljergweqti7x67lg5ije2rzjusie37nslsnkjkkby4laqqbfw@3p3zu522yykv

2 weeks agobufmgr: Pass io_object and io_context through to PinBufferForBlock()
Andres Freund [Thu, 26 Mar 2026 14:50:44 +0000 (10:50 -0400)] 
bufmgr: Pass io_object and io_context through to PinBufferForBlock()

PinBufferForBlock() is always_inline and called in a loop in
StartReadBuffersImpl(). Previously it computed io_context and io_object
internally, which required calling IOContextForStrategy() -- a non-inline
function the compiler cannot prove is side-effect-free. This could potential
cause unneeded redundant function calls.

Compute io_context and io_object in the callers instead, allowing
StartReadBuffersImpl() to do so once before entering the loop.

Author: Melanie Plageman <melanieplageman@gmail.com>
Suggested-by: Andres Freund <andres@anarazel.de>
Discussion: https://postgr.es/m/zljergweqti7x67lg5ije2rzjusie37nslsnkjkkby4laqqbfw@3p3zu522yykv

2 weeks agopg_plan_advice: Refactor to invent pgpa_planner_info
Robert Haas [Thu, 26 Mar 2026 15:57:33 +0000 (11:57 -0400)] 
pg_plan_advice: Refactor to invent pgpa_planner_info

pg_plan_advice tracks two pieces of per-PlannerInfo data: (1) for each
RTI, the corresponding relation identifier, for purposes of
cross-checking those calculations against the final plan; and (2) the
set of semijoins seen during planning for which the strategy of making
one side unique was considered. The former is tracked using a hash
table that uses <plan_name, RTI> as the key, and the latter is
tracked using a List of <plan_name, relids>.

It seems better to track both of these things in the same way and
to try to reuse some code instead of having everything be completely
separate, so invent pgpa_planner_info; we'll create one every time we
see a new PlannerInfo and need to associate some data with it, and
we'll use the plan_name field to distinguish between PlannerInfo
objects, as it should always be unique. Then, refactor the two
systems mentioned above to use this new infrastructure.

(Note that the adjustment in pgpa_plan_walker is necessary in order
to avoid spuriously triggering the sanity check in that function,
in the case where a pgpa_planner_info is created for a purpose not
related to sj_unique_rels.)

Discussion: https://postgr.es/m/CA+TgmoaK=4w7-qknUo3QhUJ53pXZq=c=KgZmRyD+k7ytqfmgSg@mail.gmail.com
Reviewed-by: Lukas Fittl <lukas@fittl.com>
2 weeks agoAdd labels to help make psql's hidden queries more understandable.
Tom Lane [Thu, 26 Mar 2026 15:36:38 +0000 (11:36 -0400)] 
Add labels to help make psql's hidden queries more understandable.

We recommend looking at psql's "-E" output to help understand the
system catalogs, but in some cases (particularly table displays)
there's a bunch of rather impenetrable SQL there.  As a small
improvement, label each query issued by describe.c with a short
description of its purpose.  The code is arranged so that the
labels also appear as SQL comments in the server log, if the
server is logging these commands.

We could expand this policy to every use of PSQLexec(), but most of
the ones outside describe.c are issuing simple commands like "BEGIN"
or "COMMIT", which don't seem to need such glosses.  I did add
labels to the commands issued by \sf, \sv and friends.

Also, make the -E and log output for hidden queries say
"INTERNAL QUERY" not just "QUERY", to distinguish them from
user-written queries.

Author: Greg Sabino Mullane <htamfids@gmail.com>
Co-authored-by: David Christensen <david+pg@pgguru.net>
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/CAKAnmmJz8Hh=8Ru8jgzySPWmLBhnv4=oc_0KRiz-UORJ0Dex+w@mail.gmail.com

2 weeks agoFix off-by-one error in read IO tracing
Andres Freund [Thu, 26 Mar 2026 14:07:59 +0000 (10:07 -0400)] 
Fix off-by-one error in read IO tracing

AsyncReadBuffer()'s no-IO needed path passed
TRACE_POSTGRESQL_BUFFER_READ_DONE the wrong block number because it had
already incremented operation->nblocks_done. Fix by folding the
nblocks_done offset into the blocknum local variable at initialization.

Author: Melanie Plageman <melanieplageman@gmail.com>
Reviewed-by: Andres Freund <andres@anarazel.de>
Discussion: https://postgr.es/m/u73un3xeljr4fiidzwi4ikcr6vm7oqugn4fo5vqpstjio6anl2%40hph6fvdiiria
Backpatch-through: 18

2 weeks agoaio: Refactor tests in preparation for more tests
Andres Freund [Thu, 26 Mar 2026 14:07:59 +0000 (10:07 -0400)] 
aio: Refactor tests in preparation for more tests

In a future commit more AIO related tests are due to be introduced. However
001_aio.pl already is fairly large.

This commit introduces a new TestAio package with helpers for writing AIO
related tests. Then it uses the new helpers to simplify the existing
001_aio.pl by iterating over all supported io_methods. This will be
particularly helpful because additional methods already have been submitted.

Additionally this commit splits out testing of initdb using a non-default
method into its own test. While that test is somewhat important, it's fairly
slow and doesn't break that often. For development velocity it's helpful for
001_aio.pl to be faster.

While particularly the latter could benefit from being its own commit, it
seems to introduce more back-and-forth than it's worth.

Author: Andres Freund <andres@anarazel.de>
Reviewed-by: Nazir Bilal Yavuz <byavuz81@gmail.com>
Reviewed-by: Melanie Plageman <melanieplageman@gmail.com>
Discussion: https://postgr.es/m/zljergweqti7x67lg5ije2rzjusie37nslsnkjkkby4laqqbfw@3p3zu522yykv

2 weeks agoRespect disabled_nodes in fix_alternative_subplan.
Robert Haas [Fri, 20 Mar 2026 18:04:41 +0000 (14:04 -0400)] 
Respect disabled_nodes in fix_alternative_subplan.

When my commit e22253467942fdb100087787c3e1e3a8620c54b2 added the
concept of disabled_nodes, it failed to add a disabled_nodes field
to SubPlan. This is a regression: before that commit, when
fix_alternative_subplan compared the costs of two plans, the number
of disabled nodes affected the result, because it was just a
component of the total cost. After that commit, it no longer did,
making it possible for a disabled path to win on cost over one that
is not disabled. Fix that.

As usual for planner fixes that might destabilize plan choices,
no back-patch.

Discussion: https://postgr.es/m/CA+TgmoaK=4w7-qknUo3QhUJ53pXZq=c=KgZmRyD+k7ytqfmgSg@mail.gmail.com
Reviewed-by: Lukas Fittl <lukas@fittl.com>
2 weeks agoFix -Wcast-qual warning
Peter Eisentraut [Thu, 26 Mar 2026 14:00:24 +0000 (15:00 +0100)] 
Fix -Wcast-qual warning

This dials back a couple of the qualifiers added by commit
7724cb9935a.  Specifically, in match_boolean_partition_clause() the
call to negate_clause() casts away the const, so we shouldn't make the
input argument const.

2 weeks agoAvoid sending duplicate WAL locations in standby status replies
Fujii Masao [Thu, 26 Mar 2026 11:54:32 +0000 (20:54 +0900)] 
Avoid sending duplicate WAL locations in standby status replies

Previously, when the startup process applied WAL and requested walreceiver
to send an apply notification to the primary, walreceiver sent a status reply
unconditionally, even if the WAL locations had not advanced since
the previous update.

As a result, the standby could send two consecutive status reply messages
with identical WAL locations even though wal_receiver_status_interval had
not yet elapsed. This could unexpectedly reset the reported replication lag,
making it difficult for users to monitor lag. The second message was also
unnecessary because it reported no progress.

This commit updates walreceiver to send a reply only when the apply location
has advanced since the last status update, even when the startup process
requests a notification.

Author: Fujii Masao <masao.fujii@gmail.com>
Reviewed-by: Shinya Kato <shinya11.kato@gmail.com>
Reviewed-by: Chao Li <li.evan.chao@gmail.com>
Discussion: https://postgr.es/m/CAOzEurTzcUrEzrH97DD7+Yz=HGPU81kzWQonKZvqBwYhx2G9_A@mail.gmail.com

2 weeks agoFix premature NULL lag reporting in pg_stat_replication
Fujii Masao [Thu, 26 Mar 2026 11:49:31 +0000 (20:49 +0900)] 
Fix premature NULL lag reporting in pg_stat_replication

pg_stat_replication is documented to keep the last measured lag values for
a short time after the standby catches up, and then set them to NULL when
there is no WAL activity. However, previously lag values could become NULL
prematurely even while WAL activity was ongoing, especially in logical
replication.

This happened because the code cleared lag when two consecutive reply messages
indicated that the apply location had caught up with the send location.
It did not verify that the reported positions were unchanged, so lag could be
cleared even when positions had advanced between messages. In logical
replication, where the apply location often quickly catches up, this issue was
more likely to occur.

This commit fixes the issue by clearing lag only when the standby reports that
it has fully replayed WAL (i.e., both flush and apply locations have caught up
with the send location) and the write/flush/apply positions remain unchanged
across two consecutive reply messages.

The second message with unchanged positions typically results from
wal_receiver_status_interval, so lag values are cleared after that interval
when there is no activity. This avoids showing stale lag data while preventing
premature NULL values.

Even with this fix, lag may rarely become NULL during activity if identical
position reports are sent repeatedly. Eliminating such duplicate messages
would address this fully, but that change is considered too invasive for stable
branches and will be handled in master only later.

Backpatch to all supported branches.

Author: Shinya Kato <shinya11.kato@gmail.com>
Reviewed-by: Chao Li <li.evan.chao@gmail.com>
Reviewed-by: Fujii Masao <masao.fujii@gmail.com>
Discussion: https://postgr.es/m/CAOzEurTzcUrEzrH97DD7+Yz=HGPU81kzWQonKZvqBwYhx2G9_A@mail.gmail.com
Backpatch-through: 14

2 weeks agoRefactor ShmemIndex initialization
Heikki Linnakangas [Thu, 26 Mar 2026 09:35:55 +0000 (11:35 +0200)] 
Refactor ShmemIndex initialization

Initialize the ShmemIndex hash table in InitShmemAllocator() already,
removing the need for the separate InitShmemIndex() step.

Reviewed-by: Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
Discussion: https://www.postgresql.org/message-id/CAExHW5vM1bneLYfg0wGeAa=52UiJ3z4vKd3AJ72X8Fw6k3KKrg@mail.gmail.com

2 weeks agoMSVC: Remove unnecessary warning option
Peter Eisentraut [Thu, 26 Mar 2026 08:10:42 +0000 (09:10 +0100)] 
MSVC: Remove unnecessary warning option

The MSVC warning option /w24777 added by commit 2307cfe3162 was a
typo, it should have been /w24477.  But this option is already enabled
by default in level 1, so we don't need to add it explicitly.  So just
remove it.

2 weeks agoMake fixed-length list building macros work in C++
Peter Eisentraut [Thu, 26 Mar 2026 07:40:18 +0000 (08:40 +0100)] 
Make fixed-length list building macros work in C++

Compound literals, as used in pg_list.h for list_makeN(), are not a
C++ feature.  MSVC doesn't accept these.  (GCC and Clang accept them,
but they would warn in -pedantic mode.)  Replace with equivalent
inline functions.  (These are the only instances of compound literals
used in PostgreSQL header files.)

Author: Jelte Fennema-Nio <postgres@jeltef.nl>
Discussion: https://www.postgresql.org/message-id/flat/CAGECzQR21OnnKiZO_1rLWO0-16kg1JBxnVq-wymYW0-_1cUNtg%40mail.gmail.com

2 weeks agoRefactor replorigin_session_setup() for better readability.
Amit Kapila [Thu, 26 Mar 2026 03:45:25 +0000 (09:15 +0530)] 
Refactor replorigin_session_setup() for better readability.

Reorder the validation checks in replorigin_session_setup() to provide a
more logical flow. This makes the function easier to follow and ensures
that basic state checks are performed consistently.

Additionally, update an error message to align its phrasing with similar
diagnostics in the replication origin subsystem, improving overall
consistency.

Author: Heikki Linnakangas <hlinnaka@iki.fi>
Reviewed-by: shveta malik <shveta.malik@gmail.com>
Reviewed-by: Amit Kapila <amit.kapila16@gmail.com>
Discussion: https://postgr.es/m/e0508305-bc6a-417c-b969-36564d632f9e@iki.fi

2 weeks agoFix UUID sortability tests in base32hex encoding.
Masahiko Sawada [Thu, 26 Mar 2026 03:12:26 +0000 (20:12 -0700)] 
Fix UUID sortability tests in base32hex encoding.

Commit 497c1170cb1 added base32hex encoding support, but its
regression test for UUIDs failed on buildfarm members hippopotamus and
jay using natural language locales (such as cs_CZ). This happened
because those collations may sort characters differently, which breaks
the strict byte-wise lexicographical ordering expected by base32hex
encoding.

This commit fixes the regression tests by explicitly using the C
collation.

Per buildfarm members hippopotamus and jay.

Analyzed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/682417.1774482047@sss.pgh.pa.us

2 weeks agoImprove timeout handling of pg_promote()
Michael Paquier [Thu, 26 Mar 2026 01:39:40 +0000 (10:39 +0900)] 
Improve timeout handling of pg_promote()

Previously, pg_promote() looped a fixed number of times, calculated from
the specified timeout, and waited 100ms on a latch, once per iteration,
for the promotion of a standby to complete.  However, unrelated signals
to the backend could set the latch and wake up the backend early,
resulting in a faster consumption of the loops and an execution time of
the function that does not match with the timeout input given in input.
This could be confusing for the function caller, especially if some
backend-side timeout is aggressive, because the function would return
much earlier than expected and report that the promote request has not
completed within the time requested.

This commit refines the logic to track the time actually elapsed, by
looping until the requested duration has truly passed.  The code
calculates the end time we expect, then uses it when looping.

Author: Robert Pang <robertpang@google.com>
Reviewed-by: Tiancheng Ge <getiancheng_2012@163.com>
Discussion: https://postgr.es/m/CAJhEC07OK8J7tLUbyiccnuOXRE7UKxBNqD2-pLfeFXa=tBoWtw@mail.gmail.com

2 weeks agoRemove a low-value, high-risk optimization in pg_waldump.
Tom Lane [Wed, 25 Mar 2026 23:15:52 +0000 (19:15 -0400)] 
Remove a low-value, high-risk optimization in pg_waldump.

The code removed here deleted already-used data from a partially-read
WAL segment's hashtable entry.  The intent was evidently to try to
keep the entry's memory consumption below the WAL segment's total
size, but we don't use WAL segments that are so large as to make that
a big win.  The important memory-space optimization is to remove
hashtable entries altogether when done with them, and that's handled
elsewhere.  To buy that, we must accept a substantially more complex
(and under-documented) logical invariant about what is in entry->buf,
as well as complex and under-documented interactions with the entry
spilling logic, various re-checking code paths in xlogreader.c,
and pg_waldump's overall data processing order.  Any of those aspects
could have bugs lurking still, and are quite likely to be prone to
new bugs after future code changes.

Given the number of bugs we've already found in commit b15c15139,
I judge that simplifying anything we possibly can is a good decision.

While here, revise and extend some related comments.

Discussion: https://postgr.es/m/374225.1774459521@sss.pgh.pa.us

2 weeks agoFix misuse of simplehash.h hash operations in pg_waldump.
Tom Lane [Wed, 25 Mar 2026 22:37:28 +0000 (18:37 -0400)] 
Fix misuse of simplehash.h hash operations in pg_waldump.

Both ArchivedWAL_insert() and ArchivedWAL_delete_item() can cause
existing hashtable entries to move.  The code didn't account for this
and could leave privateInfo->cur_file pointing at a dead or incorrect
entry, with hilarity ensuing.  Likewise, read_archive_wal_page calls
read_archive_file which could result in movement of the hashtable
entry it is working with.

I believe these bugs explain some odd buildfarm failures, although
the amount of data we use in pg_waldump's TAP tests isn't enough to
trigger them reliably.

This code's all new as of commit b15c15139, so no need for back-patch.

Discussion: https://postgr.es/m/374225.1774459521@sss.pgh.pa.us

2 weeks agoFix file descriptor leakages in pg_waldump.
Tom Lane [Wed, 25 Mar 2026 22:28:42 +0000 (18:28 -0400)] 
Fix file descriptor leakages in pg_waldump.

TarWALDumpCloseSegment was of the opinion that it didn't need to
do anything.  It was mistaken: it has to close the open file if
any, because nothing else will, leading to a descriptor leak.

In addition, we failed to ensure that any file being read by the
XLogReader machinery gets closed before the atexit callback tries to
cleanup the temporary directory holding spilled WAL files.  While the
file would have been closed already in case of a success exit, this
doesn't happen in case of pg_fatal() exits.  The least messy way
to fix that is to move the atexit function into pg_waldump.c,
where it has easier access to the XLogReaderState pointer and to
WALDumpCloseSegment.

These FD leakages are pretty insignificant on Unix-ish platforms,
but they're a bug on Windows, because they prevent successful cleanup
of the temporary directory for extracted WAL files.  (Windows can't
delete a directory that holds a deleted-but-still-open file.)
This is visible in occasional buildfarm failures.

This code's all new as of commit b15c15139, so no need for back-patch.

Discussion: https://postgr.es/m/374225.1774459521@sss.pgh.pa.us

2 weeks agoAdd base32hex support to encode() and decode() functions.
Masahiko Sawada [Wed, 25 Mar 2026 18:35:19 +0000 (11:35 -0700)] 
Add base32hex support to encode() and decode() functions.

This adds support for base32hex encoding and decoding, as defined in
RFC 4648 Section 7. Unlike standard base32, base32hex uses the
extended hex alphabet (0-9, A-V) which preserves the lexicographical
order of the encoded data.

This is particularly useful for representing UUIDv7 values in a
compact string format while maintaining their time-ordered sort
property.

The encode() function produces output padded with '=', while decode()
accepts both padded and unpadded input. Following the behavior of
other encoding types, decoding is case-insensitive.

Suggested-by: Sergey Prokhorenko <sergeyprokhorenko@yahoo.com.au>
Author: Andrey Borodin <x4mmm@yandex-team.ru>
Co-authored-by: Aleksander Alekseev <aleksander@tigerdata.com>
Reviewed-by: Masahiko Sawada <sawada.mshk@gmail.com>
Reviewed-by: Илья Чердаков <i.cherdakov.pg@gmail.com>
Reviewed-by: Chengxi Sun <chengxisun92@gmail.com>
Reviewed-by: Chao Li <li.evan.chao@gmail.com>
Discussion: https://postgr.es/m/CAJ7c6TOramr1UTLcyB128LWMqita1Y7%3Darq3KHaU%3Dqikf5yKOQ%40mail.gmail.com

2 weeks agoRemove unused autovac_table.at_sharedrel
Álvaro Herrera [Wed, 25 Mar 2026 13:04:33 +0000 (14:04 +0100)] 
Remove unused autovac_table.at_sharedrel

The last use was removed by commit 38f7831d703b.  After that, we compute
MyWorkerInfo->wi_sharedrel directly from the pg_class tuple of the table
being vacuumed rather than passing it around.

Author: Yugo Nagata <nagata@sraoss.co.jp>
Discussion: https://postgr.es/m/20260325165734.7ab8e4e55fe4c2f1e55031d9@sraoss.co.jp

2 weeks agopsql: Fix tab completion for FOREIGN DATA WRAPPER and SUBSCRIPTION.
Masahiko Sawada [Wed, 25 Mar 2026 16:30:26 +0000 (09:30 -0700)] 
psql: Fix tab completion for FOREIGN DATA WRAPPER and SUBSCRIPTION.

Commit 8185bb5347 extended the CREATE/ALTER SUBSCRIPTION and
CREATE/ALTER FOREIGN DATA WRAPPER commands, but missed the
corresponding tab-completion logic. This commit fixes that oversight
by adding completion support for:

- The CONNECTION keyword in CREATE/ALTER FOREIGN DATA WRAPPER.
- The list of foreign servers in CREATE/ALTER SUBSCRIPTION.

Author: Yamaguchi Atsuo <acrobatcoder@gmail.com>
Discussion: https://postgr.es/m/CAKSyusJWdWcUKVd3qJXcEaQxJewGymQWV_r3-mc=Knrqo0AZ_g@mail.gmail.com

2 weeks agoRemove compiler warning option -Wendif-labels
Peter Eisentraut [Wed, 25 Mar 2026 14:03:30 +0000 (15:03 +0100)] 
Remove compiler warning option -Wendif-labels

This warning has always been on by default in GCC (and in Clang at
least going back to 3.1), so we don't need the option explicitly.

Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Reviewed-by: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Discussion: https://www.postgresql.org/message-id/flat/aa73q1aT0A3/vke/%40ip-10-97-1-34.eu-west-3.compute.internal

2 weeks agoDisable warnings in system headers in MSVC
Peter Eisentraut [Wed, 25 Mar 2026 14:03:30 +0000 (15:03 +0100)] 
Disable warnings in system headers in MSVC

This is similar to the standard behavior in GCC.  For MSVC, we set all
headers in angle brackets to be considered system headers.  (GCC goes
by path, not include style.)

The required option is available since VS 2017.  (Before VS 2019
version 16.10, the additional option /experimental:external is
required, but per discussion in [0], we effectively require 16.11, so
this shouldn't be a problem.)

[0]: https://www.postgresql.org/message-id/04ab76a3-186c-4a37-8076-e6882ebf9d43%40eisentraut.org

Then, we can remove one workaround for avoiding a warning from a
system header.  (And some warnings to be enabled in the future could
benefit from this.)

Reviewed-by: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Discussion: https://www.postgresql.org/message-id/flat/aa73q1aT0A3/vke/%40ip-10-97-1-34.eu-west-3.compute.internal

2 weeks agoFix some typos and make small stylistic improvements
Peter Eisentraut [Wed, 25 Mar 2026 08:17:40 +0000 (09:17 +0100)] 
Fix some typos and make small stylistic improvements

for commit 2f094e7ac69

Author: zengman <zengman@halodbtech.com>
Reviewed-by: Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
Discussion: https://www.postgresql.org/message-id/flat/a855795d-e697-4fa5-8698-d20122126567@eisentraut.org

2 weeks agoFix typo
Peter Eisentraut [Wed, 25 Mar 2026 06:09:44 +0000 (07:09 +0100)] 
Fix typo

Mistake in commit e2f289e5b9b: SOFT_ERROR_OCCURRED was called with the
wrong fcinfo field.

Reported-by: Jianghua Yang <yjhjstz@gmail.com>
Reviewed-by: Nathan Bossart <nathandbossart@gmail.com>
Discussion: https://www.postgresql.org/message-id/flat/CAAZLFmSGti716gWeY%3DDCZ9TTVOixnHZ4_4V4tDzoeE86D64vOA%40mail.gmail.com