]> git.ipfire.org Git - thirdparty/postgresql.git/log
thirdparty/postgresql.git
10 days agoHandle nodes that may appear in GraphPattern expression trees
Peter Eisentraut [Mon, 4 May 2026 15:30:56 +0000 (17:30 +0200)] 
Handle nodes that may appear in GraphPattern expression trees

expression_tree_mutator_impl() did not handle T_GraphPattern,
T_GraphElementPattern, and T_GraphPropertyRef.  The corresponding
expression_tree_walker_impl() already handles all three node types.
This causes an "unrecognized node type" error whenever a GRAPH_TABLE
appeared in an expression tree.

While at it, also update raw_expression_tree_walker() and
expression_tree_walker() to handle missing nodes that may appear in
GraphPattern expression trees.  When raw_expression_tree_walker() is
called, GraphElementPattern::labelexpr contains ColumnRefs instead of
GraphLabelRefs.  Hence those are not handled in
raw_expression_tree_walker().

Author: Satyanarayana Narlapuram <satyanarlapuram@gmail.com>
Author: Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
Reviewed-by: Robert Haas <robertmhaas@gmail.com>
Discussion: https://www.postgresql.org/message-id/flat/CAHg%2BQDc97WFTSkXg%3Dg_ZAH8GnY2gJrvq72cs%2BYjqEAuZgXnkAQ%40mail.gmail.com

10 days agoDo not define type for a property graph
Peter Eisentraut [Mon, 4 May 2026 13:45:56 +0000 (15:45 +0200)] 
Do not define type for a property graph

Even though a property graph is defined in pg_class it does not
contain any rows by itself and need not have a type defined. Avoid
creating a type for it.

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

10 days agoFix options listing of pg_restore --no-globals
Peter Eisentraut [Mon, 4 May 2026 10:00:22 +0000 (12:00 +0200)] 
Fix options listing of pg_restore --no-globals

The new pg_restore option --no-globals (commit 3c19983cc08) appeared
out of order in the documentation and help output.  Fix that.

10 days agoAdd missing serial commas
Peter Eisentraut [Mon, 4 May 2026 09:53:04 +0000 (11:53 +0200)] 
Add missing serial commas

10 days agodoc: Fix up spacing around verbatim DocBook elements
Peter Eisentraut [Mon, 4 May 2026 07:45:21 +0000 (09:45 +0200)] 
doc: Fix up spacing around verbatim DocBook elements

10 days agoSimplify translatable messages for tuple value details in conflict.c.
Amit Kapila [Mon, 4 May 2026 06:36:41 +0000 (12:06 +0530)] 
Simplify translatable messages for tuple value details in conflict.c.

append_tuple_value_detail() constructed user-visible messages using
separately translated fragments such as ": ", ", ", and ".",. This
makes correct translation difficult or impossible in some languages.

Refactor append_tuple_value_detail() to move all punctuation and
sentence construction to the callers, which now use a single
translatable string with a %s placeholder for the tuple data.

Reported-by: David Rowley <dgrowleyml@gmail.com>
Author: vignesh C <vignesh21@gmail.com>
Reviewed-by: Hayato Kuroda <kuroda.hayato@fujitsu.com>
Reviewed-by: Amit Kapila <amit.kapila16@gmail.com>
Reviewed-by: Zhijie Hou <houzj.fnst@fujitsu.com>
Reviewed-by: Peter Smith <smithpb2250@gmail.com>
Discussion: https://postgr.es/m/227279.1775956328%40sss.pgh.pa.us#8f3a5f50543556c60cc5a13270cb7ba4
Discussion: https://postgr.es/m/CAApHDvohYOdrvhVxXzCJNX_GYMSWBfjTTtB6hgDauEtZ8Nar2A@mail.gmail.com

11 days agoMark modified the FSM buffer as dirty during recovery
Alexander Korotkov [Sun, 3 May 2026 17:23:50 +0000 (20:23 +0300)] 
Mark modified the FSM buffer as dirty during recovery

The XLogRecordPageWithFreeSpace function updates the freespace map (FSM) data
while replaying data-level WAL records during the recovery. If the FSM block
is updated, it needs to be marked as modified. Currently, this is done with
the MarkBufferDirtyHint call (as in all other cases for modifying FSM data).
However, in the recovery context, this function will actually do nothing if
checksums are enabled. It's assumed that the page should not be dirtied
during recovery while modifying hints to protect against torn pages, since no
new WAL data can be generated at this point to store FPI.

Such logic does not seem fully aligned with the FSM case, as its blocks could
be simply zeroed if a checksum mismatch is detected. Currently, changes to an
FSM block could be lost if each change to that block occurs infrequently
enough to allow it to be evicted from the cache. To persist the change, the
modification needs to be performed while the FSM block is still kept in
buffers and marked as dirty after receiving its FPI. If the block has already
been cleaned, the change won't be persisted, so stored FSM blocks may remain
in an obsolete state.

If a large number of discrepancies between the data in leaf FSM blocks and the
actual data blocks accumulate on the replica server, this could cause
significant delays in insert operations after switchover. Such an insert
operation may need to visit many data blocks marked as having sufficient
space in the FSM, only to discover that the information is incorrect and the
FSM records need to be corrected. In a heavily trafficked insert-only table
with many concurrent clients performing inserts, this has been observed to
cause several-second stalls, causing visible application malfunction. The
desire to avoid such cases was the reason behind the commit ab7dbd681, which
introduced an update of FSM data during the heap_xlog_visible invocation.
However, an update to the FSM data on the standby side could be lost due to a
missing 'dirty' flag, so there is still a possibility that a large number of
FSM records will contain incorrect data. Note that having a zeroed FSM page
in such a case (due to a checksum mismatch) is preferable, as a zero value
will be interpreted as an indication of full data blocks, and the inserter
will be routed to the next FSM block or to the end of the table.

Given that FSM is ready to handle torn page writes and
XLogRecordPageWithFreeSpace is called only during the recovery, there seems
to be no reason to use MarkBufferDirtyHint here instead of a regular
MarkBufferDirty call.

Discussion: https://postgr.es/m/596c4f1c-f966-4512-b9c9-dd8fbcaf0928%40postgrespro.ru
Author: Alexey Makhmutov <a.makhmutov@postgrespro.ru>
Reviewed-by: Andrey Borodin <x4mmm@yandex-team.ru>
Reviewed-by: Melanie Plageman <melanieplageman@gmail.com>
Reviewed-by: Alexander Korotkov <aekorotkov@gmail.com>
11 days agoDocument that WAIT FOR LSN is timeline-blind
Alexander Korotkov [Sun, 3 May 2026 13:20:41 +0000 (16:20 +0300)] 
Document that WAIT FOR LSN is timeline-blind

WAIT FOR LSN compares only the numeric LSN and has no notion of which
timeline a WAL record belongs to.  There are many possible scenarios when
timeline-switching can break read-your-writes consistency.  The proper
analysis and timeline support is possible in the next major release.  Yet
just document the current behaviour.

Reported-by: Xuneng Zhou <xunengzhou@gmail.com>
Author: Alexander Korotkov <aekorotkov@gmail.com>

11 days agoImprove WAIT FOR LSN test coverage
Alexander Korotkov [Sun, 3 May 2026 13:20:16 +0000 (16:20 +0300)] 
Improve WAIT FOR LSN test coverage

Add regression coverage for several WAIT FOR LSN edge cases.

First, cover fresh walreceiver shared-memory initialization after a
standby restart.  Restart the standby while its upstream is down, so
RequestXLogStreaming() seeds writtenUpto/flushedUpto to the
segment-aligned receiveStart and the walreceiver cannot immediately
advance them.  Verify that the seeded flush position is segment-aligned,
that replay can be ahead of it, and that standby_write/standby_flush
still succeed for an already-replayed LSN via the replay-position floor
in GetCurrentLSNForWaitType().

Second, add fencepost checks for the target <= currentLSN predicate.
With replay paused and walreceiver stopped, verify exact boundaries for
standby_replay using pg_last_wal_replay_lsn(), and for standby_flush
using pg_last_wal_receive_lsn().  Also verify that a waiter for
current + 1 sleeps while replay is paused and wakes with success once
new WAL is delivered and replay advances.

Finally, add a cascading-standby timeline-switch test.  Start a waiter
on the downstream standby, promote its upstream, generate WAL on the new
timeline, and verify that the cascade follows the new timeline and the
wait completes successfully once replay reaches the target LSN.

Reported-by: Andres Freund <andres@anarazel.de>
Discussion: https://postgr.es/m/1957514.1775526774%40sss.pgh.pa.us
Author: Alexander Korotkov <aekorotkov@gmail.com>
Author: Xuneng Zhou <xunengzhou@gmail.com>

11 days agoWake standby_write/standby_flush waiters from the WAL replay loop
Alexander Korotkov [Sun, 3 May 2026 13:19:00 +0000 (16:19 +0300)] 
Wake standby_write/standby_flush waiters from the WAL replay loop

The startup process only woke STANDBY_REPLAY waiters after replaying
each WAL record. STANDBY_WRITE and STANDBY_FLUSH waiters depended only
on walreceiver write/flush callbacks. As a result, replay progress alone
did not wake those waiters, and in pure archive recovery (where no
walreceiver exists) they could sleep until timeout.

Fix by also calling WaitLSNWakeup() for STANDBY_WRITE and
STANDBY_FLUSH after each replay. For the replay-floor semantics used by
GetCurrentLSNForWaitType(), replay progress is a valid lower bound for
both modes: WAL cannot be replayed unless it has already been written
and flushed locally.

This works together with the replay-position floor in
GetCurrentLSNForWaitType(). The getter ensures that a waiter woken by
replay can recheck successfully; the replay-side wakeups ensure that a
waiter already asleep is notified when replay reaches its target.

Reported-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/1957514.1775526774%40sss.pgh.pa.us
Author: Xuneng Zhou <xunengzhou@gmail.com>
Reviewed-by: Andres Freund <andres@anarazel.de>
Reviewed-by: Alexander Korotkov <aekorotkov@gmail.com>
11 days agoUse replay position as floor for WAIT FOR LSN standby_(write|flush)
Alexander Korotkov [Sun, 3 May 2026 13:18:30 +0000 (16:18 +0300)] 
Use replay position as floor for WAIT FOR LSN standby_(write|flush)

GetCurrentLSNForWaitType() for standby_write and standby_flush modes
returned only the walreceiver position, which may lag behind WAL
already present on the standby from a base backup, archive restore,
or prior streaming.  This could cause unnecessary blocking if the
target LSN falls between the walreceiver's tracked position and the
replay position.

Fix by returning the maximum of the walreceiver position and the
replay position.  WAL up to the replay point is physically on disk
regardless of its origin, so there is no reason to wait for the
walreceiver to re-receive it.

This complements 29e7dbf5e4d, which seeded writtenUpto to
receiveStart in RequestXLogStreaming() to fix the most common
hang scenario.  The getter-level floor handles the remaining edge
cases: targets between receiveStart and the replay position, and
standbys running with archive recovery only (no walreceiver).

Reported-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/1957514.1775526774%40sss.pgh.pa.us
Author: Xuneng Zhou <xunengzhou@gmail.com>
Reviewed-by: Andres Freund <andres@anarazel.de>
Reviewed-by: Alexander Korotkov <aekorotkov@gmail.com>
11 days agoRemove redundant WAIT FOR LSN caller-side pre-checks
Alexander Korotkov [Sun, 3 May 2026 13:17:32 +0000 (16:17 +0300)] 
Remove redundant WAIT FOR LSN caller-side pre-checks

All five wakeup call sites duplicate WaitLSNWakeup()'s internal
fast-path minWaitedLSN check and add an unnecessary NULL check
on waitLSNState.

Remove the inline pre-checks and call WaitLSNWakeup() directly.
The fast-path check inside WaitLSNWakeup() already returns early
when no waiter's target has been reached, so there is no
performance difference.

The waitLSNState NULL checks are also unnecessary: shared memory
is fully initialized before any backend or auxiliary process
starts, so waitLSNState is always non-NULL at these call sites.

Reported-by: Andres Freund <andres@anarazel.de>
Discussion: https://postgr.es/m/jzq5shdewncpxc35r3s2mcfsmo4bjovkza5mnqf5bdfumhfi3g%40bglckf7dxmw5
Author: Xuneng Zhou <xunengzhou@gmail.com>
Reviewed-by: Andres Freund <andres@anarazel.de>
Reviewed-by: Alexander Korotkov <aekorotkov@gmail.com>
11 days agoFix memory ordering in WAIT FOR LSN wakeup mechanism
Alexander Korotkov [Sun, 3 May 2026 13:16:30 +0000 (16:16 +0300)] 
Fix memory ordering in WAIT FOR LSN wakeup mechanism

WAIT FOR LSN uses a Dekker-style handshake: the waker stores an LSN
position then reads minWaitedLSN; the waiter stores its target into
minWaitedLSN then reads the position.  Without a barrier between each
side's store and load, a CPU may satisfy the load before the store
becomes globally visible, causing either side to miss a concurrent
update.  The result is a missed wakeup: the waiter sleeps indefinitely
until the next unrelated event.

Fix by embedding the required barriers into the atomic operations on
minWaitedLSN:

- In updateMinWaitedLSN(), use pg_atomic_write_membarrier_u64() so the
  waiter's preceding heap update is visible before the new minWaitedLSN
  value is published.

- In WaitLSNWakeup(), use pg_atomic_read_membarrier_u64() in the
  fast-path check so the waker's preceding position store is globally
  visible before minWaitedLSN is read.

The waiter side is also covered by the barrier semantics already present
in GetCurrentLSNForWaitType(): GetWalRcvWriteRecPtr() uses an explicit
read barrier (from patch 0001), while the remaining getters acquire a
spinlock, which implies the same ordering.

Also call ResetLatch() unconditionally after WaitLatch(), following the
standard latch loop pattern.  WaitLatch() does not guarantee that all
simultaneously true wake conditions are reported in one return, so a
timeout can race with SetLatch().  If we skip ResetLatch() on a timeout
return, the code performs further asynchronous-state checks before
consuming the latch, violating the latch API's required wait/reset
pattern.  That can leave the latch set across loop exit and cause a
later unrelated WaitLatch() in the same backend to return immediately.

Reported-by: Andres Freund <andres@anarazel.de>
Discussion: https://postgr.es/m/zqbppucpmkeqecfy4s5kscnru4tbk6khp3ozqz6ad2zijz354k%40w4bdf4z3wqoz
Author: Xuneng Zhou <xunengzhou@gmail.com>
Reviewed-by: Andres Freund <andres@anarazel.de>
Reviewed-by: Alexander Korotkov <aekorotkov@gmail.com>
11 days agoUse barrier semantics when reading/writing writtenUpto
Alexander Korotkov [Sun, 3 May 2026 13:21:25 +0000 (16:21 +0300)] 
Use barrier semantics when reading/writing writtenUpto

The walreceiver publishes its write position lock-free via writtenUpto.
On weakly-ordered architectures (ARM, PowerPC), both sides of this
handshake need explicit barriers so that the lock-less reader sees a
consistent state.

Use pg_atomic_write_membarrier_u64() at both write sites and
pg_atomic_read_membarrier_u64() in GetWalRcvWriteRecPtr().  This matches
the barrier semantics that GetWalRcvFlushRecPtr() and other LSN-position
functions get implicitly from their spinlock acquire/release, and
protects from bugs caused by expectations of similar barrier guarantees
from different LSN-position functions.

Reported-by: Andres Freund <andres@anarazel.de>
Discussion: https://postgr.es/m/zqbppucpmkeqecfy4s5kscnru4tbk6khp3ozqz6ad2zijz354k%40w4bdf4z3wqoz
Author: Xuneng Zhou <xunengzhou@gmail.com>
Reviewed-by: Andres Freund <andres@anarazel.de>
Reviewed-by: Alexander Korotkov <aekorotkov@gmail.com>
13 days agoAdd missing connection validation in ECPG
Andrew Dunstan [Fri, 1 May 2026 19:12:28 +0000 (15:12 -0400)] 
Add missing connection validation in ECPG

ECPGdeallocate_all(), ECPGprepared_statement(), ECPGget_desc(), and
ecpg_freeStmtCacheEntry() could crash with a SIGSEGV when called
without an established connection (for example, when EXEC SQL CONNECT
was forgotten or a non-existent connection name was used), because
they dereferenced the result of ecpg_get_connection() without first
checking it for NULL.

Each site is fixed in the style of the surrounding code.

New tests are added for these conditions.

Author: Shruthi Gowda <gowdashru@gmail.com>
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Reviewed-by: Fujii Masao <masao.fujii@gmail.com>
Reviewed-by: Mahendra Singh Thalor <mahi6run@gmail.com>
Reviewed-by: Nishant Sharma <nishant.sharma@enterprisedb.com>
Discussion: https://postgr.es/m/3007317.1765210195@sss.pgh.pa.us
Backpatch-through: 14

13 days agoOnly show signal-sender PID/UID detail in server log
Andrew Dunstan [Fri, 1 May 2026 15:52:14 +0000 (11:52 -0400)] 
Only show signal-sender PID/UID detail in server log

The errdetail() added in 55890a91945 (and reworked in 3e2a1496bae)
exposed the operating-system PID and UID of whoever sent the
termination signal directly to the affected client.

Discussion suggested this should not be sent to the client, but only
recorded in the server log where the admin can use it for diagnosis.

Author: Chao Li <li.evan.chao@gmail.com>
Reviewed-by: Jakub Wartak <jakub.wartak@enterprisedb.com>
Discussion: https://postgr.es/m/E5CA274C-74BD-4067-8B73-A3AD8C080EFA@gmail.com

13 days agoFix BF failure introduced in commit 2bf6c9ff71.
Amit Kapila [Fri, 1 May 2026 09:05:26 +0000 (14:35 +0530)] 
Fix BF failure introduced in commit 2bf6c9ff71.

The sequence subscription test switches regress_seq_sub to connect to the
publisher as regress_seq_repl (a non-superuser) when checking behavior
with insufficient sequence privileges but forgot to set up pg_hba.conf to
allow connections from it. The special setup is only needed on Windows
machines that don't use UNIX sockets.

As per buildfarm.

Reported-by: Ajin Cherian <itsajin@gmail.com>
Author: Ayush Tiwari <ayushtiwari.slg01@gmail.com>
Reviewed-by: vignesh C <vignesh21@gmail.com>
Discussion: https://postgr.es/m/CAFPTHDad911HUMkHgD1KZk+WOvTopiBcYf4C_8Fqj1-sZk3xgw@mail.gmail.com

13 days agodoc: Mention validation attempt during ALTER INDEX .. ATTACH PARTITION
Michael Paquier [Fri, 1 May 2026 04:10:35 +0000 (13:10 +0900)] 
doc: Mention validation attempt during ALTER INDEX .. ATTACH PARTITION

Since 9d3e094f12, the command tries to validate the parent index of the
named index, if invalid.  The documentation did not mention this
behavior, which could be confusing.

Author: Mohamed ALi <moali.pg@gmail.com>
Discussion: https://postgr.es/m/CAGnOmWpHu25_LpT=zv7KtetQhqV1QEZzFYLd_TDyOLu1Od9fpw@mail.gmail.com
Backpatch-through: 14

13 days agoAvoid blocking indefinitely while finishing walsender shutdown
Fujii Masao [Fri, 1 May 2026 03:12:44 +0000 (12:12 +0900)] 
Avoid blocking indefinitely while finishing walsender shutdown

When walsender finishes streaming during shutdown, it sends a
CommandComplete message to tell the receiver that WAL streaming is done.
Previously, that path used EndCommand() followed by pq_flush().

Those functions can block indefinitely waiting for the socket to become
writeable. As a result, even when wal_sender_shutdown_timeout is set,
walsender could remain stuck while sending the final completion message,
and the shutdown timeout would not be enforced.

Fix this by introducing EndCommandExtended(), which allows
CommandComplete to be queued with pq_putmessage_noblock(), and by
using the walsender nonblocking flush path instead of pq_flush(), so
the shutdown timeout continues to be checked while pending output is
flushed.

Per CI testing on FreeBSD.

Reported-by: Andres Freund <andres@anarazel.de>
Author: Fujii Masao <masao.fujii@gmail.com>
Reviewed-by: Chao Li <li.evan.chao@gmail.com>
Discussion: https://postgr.es/m/vwlugmsogfn36jhm56zwrgd7m6xe6ircltvfh3kzt6kldvbtht@f45dgow5uhnx

13 days agoFix HAVING-to-WHERE pushdown with nondeterministic collations
Richard Guo [Fri, 1 May 2026 02:13:50 +0000 (11:13 +0900)] 
Fix HAVING-to-WHERE pushdown with nondeterministic collations

When GROUP BY uses a nondeterministic collation, the planner's
optimization of moving HAVING clauses to WHERE can produce incorrect
query results.  The HAVING clause may apply a stricter collation that
distinguishes values the GROUP BY considers equal.  Pushing such a
clause to WHERE causes it to filter individual rows before grouping,
potentially eliminating group members and changing aggregate results.

Fix this by detecting collation conflicts before flatten_group_exprs,
while the HAVING clause still contains GROUP Vars (Vars referencing
RTE_GROUP).  At that point, each GROUP Var directly carries the GROUP
BY collation as its varcollid, making it straightforward to compare
against the operator's inputcollid.  A mismatch where the GROUP BY
collation is nondeterministic means the clause is unsafe to push down.
RowCompareExpr is treated specially, since it carries per-column
inputcollids[] rather than a single inputcollid.

The conflicting clause indices are recorded in a Bitmapset and
consulted during the existing HAVING-to-WHERE loop, so that only
affected clauses are kept in HAVING; other safe clauses in the same
query are still pushed.

Back-patch to v18 only.  The fix relies on the RTE_GROUP mechanism
introduced in v18 (commit 247dea89f), which is what lets us identify
grouping expressions and their resolved collations via GROUP Vars on
pre-flatten havingQual.  Pre-v18 branches lack that machinery, so a
back-patch there would need a different approach.  Given the absence
of field reports of this bug on back branches, the risk of carrying a
different fix on stable branches is not justified.

Author: Richard Guo <guofenglinux@gmail.com>
Reviewed-by: wenhui qiu <qiuwenhuifx@gmail.com>
Discussion: https://postgr.es/m/CAMbWs48Dn2wW6XM94GZsoyMiH42=KgMo+WcobPKuWvGYnWaPOQ@mail.gmail.com
Backpatch-through: 18

2 weeks agoUse "concurrent delete" in serialization error for TM_Deleted cases
Amit Langote [Fri, 1 May 2026 00:56:10 +0000 (09:56 +0900)] 
Use "concurrent delete" in serialization error for TM_Deleted cases

In ExecLockRows() and ri_LockPKTuple(), the TM_Deleted code path was
using the same "could not serialize access due to concurrent update"
message as the TM_Updated path.  Use "concurrent delete" instead, since
the tuple was deleted, not updated.  The ExecLockRows() instance was
likely a copy-paste error per Andres; the ri_LockPKTuple() instance
was carried over from the same pattern in commit 2da86c1ef9.

Update affected isolation test expected files accordingly and add
a new test to fk-concurrent-pk-upd.spec with concurrent delete of the
PK row.

The ExecLockRows() change is master-only for lack of user complaints
and to avoid breaking anything that might match on the error text.

Reported-by: Jian He <jian.universality@gmail.com>
Author: Amit Langote <amitlangote09@gmail.com>
Reviewed-by: Junwang Zhao <zhjwpku@gmail.com>
Discussion: https://postgr.es/m/CACJufxEG1JTCq4A1gnNAu-bGAq9Xn=Xkf7kC3TRWFz6iuUOuRA@mail.gmail.com

2 weeks agoFix JSON_ARRAY(query) empty set handling and view deparsing
Richard Guo [Fri, 1 May 2026 00:42:00 +0000 (09:42 +0900)] 
Fix JSON_ARRAY(query) empty set handling and view deparsing

According to the SQL/JSON standard, JSON_ARRAY(query) must return an
empty JSON array ('[]') when the subquery returns zero rows.

Previously, the parser rewrote JSON_ARRAY(query) into a JSON_ARRAYAGG
aggregate function.  Because this aggregate evaluates to NULL over an
empty set without a GROUP BY clause, the constructor erroneously
returned NULL.  Additionally, this premature rewrite baked physical
implementation details into the catalog, preventing ruleutils.c from
deparsing the original syntax for views.

This patch resolves both issues by introducing a new
JSCTOR_JSON_ARRAY_QUERY constructor type.  The parser builds the
executable form --- a COALESCE-wrapped JSON_ARRAYAGG subquery --- from
raw parse nodes via transformExprRecurse, and stores it in the func
field.  The original transformed Query is kept in a new orig_query
field so that ruleutils.c can deparse the original syntax for views.
During planning, eval_const_expressions replaces the node with the
pre-built func expression.

The deparsing issue was reported by Tom Lane.

Bump catalog version.

Bug: #19418
Reported-by: Lukas Eder <lukas.eder@gmail.com>
Author: Richard Guo <guofenglinux@gmail.com>
Reviewed-by: Amit Langote <amitlangote09@gmail.com>
Discussion: https://postgr.es/m/19418-591ba1f29862ef5b@postgresql.org

2 weeks agoREPACK CONCURRENTLY: fix processing of toasted tuples
Álvaro Herrera [Tue, 28 Apr 2026 14:02:27 +0000 (16:02 +0200)] 
REPACK CONCURRENTLY: fix processing of toasted tuples

In order to process tuples inserted or updated while REPACK executes, we
write those tuples to disk and later restore them; however, some forms
of toasted tuples were not being processed correctly.  Fix that.

Also expand the tests a bit for better coverage.

Author: Satya Narlapuram <satyanarlapuram@gmail.com>
Author: Antonin Houska <ah@cybertec.at>
Reviewed-by: Chao Li <li.evan.chao@gmail.com>
Discussion: https://postgr.es/m/CAHg+QDeXb9HM2VGKXQedyCp52GzajJK5KOUdNi6oLjsS0nerQw@mail.gmail.com

2 weeks agoRemove working test that was supposed to fail
Álvaro Herrera [Thu, 30 Apr 2026 20:57:24 +0000 (22:57 +0200)] 
Remove working test that was supposed to fail

I evidently failed to review the expected output in commit 832e220d99af
carefully enough.  Per complaint from Tom Lane.

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

2 weeks agoFix attnum remapping in generateClonedExtStatsStmt()
Andrew Dunstan [Thu, 30 Apr 2026 15:04:57 +0000 (11:04 -0400)] 
Fix attnum remapping in generateClonedExtStatsStmt()

When cloning extended statistics via CREATE TABLE ... LIKE ... INCLUDING
STATISTICS, stxkeys holds attribute numbers from the source (parent)
table, but get_attname() was being called with the child relation's
OID.  If the parent has dropped columns, the child's attribute numbers
are renumbered sequentially and no longer match, so the lookup either
returns the wrong column name (silent corruption) or errors out when
the attnum does not exist in the child.

Fix it by remapping the parent attnum through attmap before the lookup,
consistent with how expression statistics are already handled a few
lines below.

Add a regression test covering both manifestations: a 3-column parent
where the stale attnum refers to no child column (cache-lookup error),
and a 4-column parent where the stale attnum silently refers to the
wrong child column.

Author: Julien Tachoires <julmon@gmail.com>
Reviewed-by: Srinath Reddy Sadipiralla <srinath2133@gmail.com>
Discussion: https://postgr.es/m/20260415105718.tomuncfbmlt67oel@poseidon.home.virt
Backpatch-through: 14

2 weeks agoAvoid SIGSEGV in pg_get_database_ddl() on NULL tablespace
Andrew Dunstan [Thu, 30 Apr 2026 14:14:52 +0000 (10:14 -0400)] 
Avoid SIGSEGV in pg_get_database_ddl() on NULL tablespace

There is a narrow race in which a concurrent ALTER DATABASE ... SET
TABLESPACE moves the database off the tablespace and a DROP TABLESPACE
removes it between the syscache lookup and the catalog scan. If that
happens, output an error.

Author: Chao Li <lic@highgo.com>
Reviewed-by: Jack Bonatakis <jack@bonatak.is>
Reviewed-by: Satyanarayana Narlapuram <satyanarlapuram@gmail.com>
Reviewed-by: Japin Li <japinli@hotmail.com>
Discussion: https://postgr.es/m/573E45C1-31A4-4885-A00C-1A2171159A2A@gmail.com

2 weeks agoFix data_checksum GUC show_hook
Daniel Gustafsson [Thu, 30 Apr 2026 11:41:57 +0000 (13:41 +0200)] 
Fix data_checksum GUC show_hook

Commit f19c0eccae erroneously omitted the show_hook for the
data_checksum GUC.

Author: Daniel Gustafsson <daniel@yesql.se>
Reviewed-by: Tomas Vondra <tomas@vondra.me>
Reviewed-by: SATYANARAYANA NARLAPURAM <satyanarlapuram@gmail.com>
Reviewed-by: Ayush Tiwari <ayushtiwari.slg01@gmail.com>
Discussion: https://postgr.es/m/9197F930-DDEB-4CAC-82A2-16FEC715CCE8@yesql.se

2 weeks agoImprove database detection logic in datachecksumsworker
Daniel Gustafsson [Thu, 30 Apr 2026 11:41:55 +0000 (13:41 +0200)] 
Improve database detection logic in datachecksumsworker

The worker need to know whether a database which failed checksum
processing still exists, or has been dropped.  This improves the
detection logic by checking for being partially dropped.

Author: Daniel Gustafsson <daniel@yesql.se>
Reviewed-by: Tomas Vondra <tomas@vondra.me>
Reviewed-by: SATYANARAYANA NARLAPURAM <satyanarlapuram@gmail.com>
Reviewed-by: Ayush Tiwari <ayushtiwari.slg01@gmail.com>
Discussion: https://postgr.es/m/9197F930-DDEB-4CAC-82A2-16FEC715CCE8@yesql.se

2 weeks agoImprove handling of concurrent checksum requests
Daniel Gustafsson [Thu, 30 Apr 2026 11:41:53 +0000 (13:41 +0200)] 
Improve handling of concurrent checksum requests

When pg_{enable|disable}_data_checksums is called while checksums are
being enabled or disabled, the already running launcher is detected
and the new desired state is recorded.  Processing will then pick up
the new state and change its operation to fulfill the new request.
If the same state is requested but with different cost values, the
new cost values will take effect on the next relation processed.

The previous coding had a complex logic of starting a new launcher
for this, which is now avoided with the shared mem structure instead
used to signal current processing.

This makes the logic more robust, and fixes a bug where the launcher
would erroneously revert back to the "off" state.

Access to the shared memory is also protected with LWLocks in all
cases.  Since the shmem structure is used for signalling between
the worker and the launcher, and there can be only one of each,
there were no concurrency issues detected but it's better to stick
to proper locking protocol should this ever be updated to handle
multiple workers.

Author: Daniel Gustafsson <daniel@yesql.se>
Reviewed-by: Tomas Vondra <tomas@vondra.me>
Reviewed-by: SATYANARAYANA NARLAPURAM <satyanarlapuram@gmail.com>
Reviewed-by: Ayush Tiwari <ayushtiwari.slg01@gmail.com>
Discussion: https://postgr.es/m/9197F930-DDEB-4CAC-82A2-16FEC715CCE8@yesql.se

2 weeks agoTypo and spelling fixups for online checksums
Daniel Gustafsson [Thu, 30 Apr 2026 11:41:50 +0000 (13:41 +0200)] 
Typo and spelling fixups for online checksums

A collection of spelling, wording and punctuation fixups for the code
documentation from postcommit review.

Author: Daniel Gustafsson <daniel@yesql.se>
Reviewed-by: Tomas Vondra <tomas@vondra.me>
Reviewed-by: Ayush Tiwari <ayushtiwari.slg01@gmail.com>
Reviewed-by: SATYANARAYANA NARLAPURAM <satyanarlapuram@gmail.com>
Discussion: https://postgr.es/m/9197F930-DDEB-4CAC-82A2-16FEC715CCE8@yesql.se

2 weeks agoFix invalid checksum state transition in checkpoints
Daniel Gustafsson [Thu, 30 Apr 2026 11:41:48 +0000 (13:41 +0200)] 
Fix invalid checksum state transition in checkpoints

Commit 78e950cb8 added checksum state handling to all XLOG_CHECKPOINT
records which caused unnecessary state transitions and emission of
procsignal barriers.  Remove as only the _REDO record need to handle
checksum state.  Barrier emission is also consistently made after
controlfile updates to avoid race conditions.

Additionally, interrupts are held between calling ProcSignalInit and
InitLocalDataChecksumState to remove a window where otherwise invalid
state transitions can happen.

Also remove a pointless assertion on Controlfile which will never hit.

Author: Tomas Vondra <tomas@vondra.me>
Author: Daniel Gustafsson <daniel@yesql.se>
Reviewed-by: Ayush Tiwari <ayushtiwari.slg01@gmail.com>
Reviewed-by: SATYANARAYANA NARLAPURAM <satyanarlapuram@gmail.com>
Discussion: https://postgr.es/m/9197F930-DDEB-4CAC-82A2-16FEC715CCE8@yesql.se

2 weeks agoHandle data_checksum state changes during launcher_exit
Daniel Gustafsson [Thu, 30 Apr 2026 11:41:46 +0000 (13:41 +0200)] 
Handle data_checksum state changes during launcher_exit

When erroring out from the datachecksums launcher during data checksum
enabling, before state has transitioned to "on", we revert back to the
"off" state.  Since checksums weren't enabled, there is no use staying
in an inprogress state since the checksum launcher currently doesn't
support restarting from where it left off.  Should restartability get
added in the future, this would need to be revisited.  This state
transition was however missing from the allowed transitions in the
statemachine causing an error.

Author: Daniel Gustafsson <daniel@yesql.se>
Reviewed-by: Tomas Vondra <tomas@vondra.me>
Reviewed-by: Ayush Tiwari <ayushtiwari.slg01@gmail.com>
Reviewed-by: SATYANARAYANA NARLAPURAM <satyanarlapuram@gmail.com>
Discussion: https://postgr.es/m/9197F930-DDEB-4CAC-82A2-16FEC715CCE8@yesql.se

2 weeks agoTest improvements for online checksums
Daniel Gustafsson [Thu, 30 Apr 2026 11:41:43 +0000 (13:41 +0200)] 
Test improvements for online checksums

This includes a number of smaller fixups to the online checksums test
module which were found during postcommit review and stabilization
work.

 * Fix scope increase for PG_TEST_EXTRA: The online checksums tests
   have two levels of PG_TEST_EXTRA, checksum and checksums_extended
   for extra test runs and test runs with increased randomization.
   The logic for increasing the number of test iterations was however
   backwards.
 * Change stopmode for PITR test: The pitr suite used immediate stop
   mode which caused problems on slower machines where the sigquit
   would interrupt archive commands leaving partial WAL files behind.
   This would then prevent restart.  Fix by using fast mode which is
   the appropriate mode for the test at hand.  Also increase timeouts
   to help slower test systems since an expired timeout will incur
   the same effect as an immediate standby with a partial WAL left
   behind.  This issue was observed when running the test suites on
   a Raspberry Pi 4 machine.
 * Improve logging: The test suite for data checksums use a set of
   helper functions in a Perl module to avoid repeating code, this
   makes sure that the helper functions do a better job of logging
   their test output to make debug easier.
 * Remove unused code: wait_for_cluster_crash was used during the
   development of online checksums but was never used in any test
   which shipped, so remove the function.
 * Standby fixes: Ensure no vacuum on pgbench init on standby with
   -n to avoid bogus error message in the log, and enable
   hot_standby_feedback to prevent queries from getting cancelled
   due to recovery on slower systems.

Author: Daniel Gustafsson <daniel@yesql.se>
Author: Tomas Vondra <tomas@vondra.me>
Reviewed-by: Ayush Tiwari <ayushtiwari.slg01@gmail.com>
Reviewed-by: SATYANARAYANA NARLAPURAM <satyanarlapuram@gmail.com>
Discussion: https://postgr.es/m/9197F930-DDEB-4CAC-82A2-16FEC715CCE8@yesql.se

2 weeks agoPrevent pg_enable/disable_data_checksums() on standby
Daniel Gustafsson [Thu, 30 Apr 2026 11:41:41 +0000 (13:41 +0200)] 
Prevent pg_enable/disable_data_checksums() on standby

These functions missed a RecoveryInProgress() check, allowing them to
be called on a hot standby.  Enabling, or disabling, checksums on the
standby only would cause the cluster to get out of sync and replaying
checksum transitions to fail.

Author: Satyanarayana Narlapuram <satyanarlapuram@gmail.com>
Reviewed-by: Ayush Tiwari <ayushtiwari.slg01@gmail.com>
Reviewed-by: Tomas Vondra <tomas@vondra.me>
Reviewed-by: Daniel Gustafsson <daniel@yesql.se>
Discussion: https://postgr.es/m/CAHg+QDfRk4-S7DMmdbXJnQ-xF=sUpMAKuh8b83ObLqYVKx5QLA@mail.gmail.com

2 weeks agoFix double table_close of sequence_rel in copy_sequences().
Amit Kapila [Thu, 30 Apr 2026 10:57:11 +0000 (16:27 +0530)] 
Fix double table_close of sequence_rel in copy_sequences().

sequence_rel was declared at batch scope, so when a row is skipped due to
concurrent drop or insufficient privileges, the end-of-row cleanup closes
the stale pointer from the previous row, tripping the relcache refcount
assertion.

Move sequence_rel inside the per-row loop.

Author: Ayush Tiwari <ayushtiwari.slg01@gmail.com>
Reviewed-by: vignesh C <vignesh21@gmail.com>
Reviewed-by: Hayato Kuroda <kuroda.hayato@fujitsu.com>
Discussion: https://postgr.es/m/CAJTYsWWOuw-yfmzotV4jCJ6LLxEsb=STLcGtDYXOxRcU9Te3Pw@mail.gmail.com

2 weeks agoFix errno check based on EINTR in pg_flush_data()
Michael Paquier [Thu, 30 Apr 2026 09:44:38 +0000 (18:44 +0900)] 
Fix errno check based on EINTR in pg_flush_data()

Upon a failure of sync_file_range(), EINTR was checked based on the
returned result of the routine rather than its errno.  sync_file_range()
returns -1 on failure, making the check a no-op, invalidating the retry
attempt in this case.

Oversight in 0d369ac65004.

Author: DaeMyung Kang <charsyam@gmail.com>
Discussion: https://postgr.es/m/20260429151811.1810874-1-charsyam@gmail.com
Backpatch-through: 16

2 weeks agoAdjust some incorrect *GetDatum() macros
Michael Paquier [Thu, 30 Apr 2026 04:10:19 +0000 (13:10 +0900)] 
Adjust some incorrect *GetDatum() macros

This reverts portions of commit 6dcfac9696cb, which is wrong in trying
to use a *GetDatum() that matches with the C types of the values read.
*GetDatum() should match with the output argument types of the SQL
functions.

The portions of 6dcfac9696cb that are right regarding this rule are:
- gistget.c, where the GiST support functions use DatumGetUInt16() to
retrieve the strategy number.
- The BRIN code for strategynum, used in syscache lookups.

The adjustments done in this commit are for pageinspect, pg_buffercache
and pg_lock_status().

While double-checking the whole state of the tree regarding non-matching
pairs of DatumGet*() and *GetDatum(), I have found much more code paths
that are incorrect, unrelated to 6dcfac9696cb.  These may be adjusted in
the future, in a different patch (perhaps not for v19, as we are already
past feature freeze).

Reported-by: Peter Eisentraut <peter@eisentraut.org>
Discussion: https://postgr.es/m/97f9375a-be61-4272-a44d-408337fe8fa6@eisentraut.org
Discussion: https://postgr.es/m/CAJ7c6TMcGu8qmRe1gZfJ-gOzVnZq-t=fwn-UuyStx1w6ZyydMw@mail.gmail.com

2 weeks agoFix error of pg_stat_reset_shared()
Michael Paquier [Thu, 30 Apr 2026 02:12:56 +0000 (11:12 +0900)] 
Fix error of pg_stat_reset_shared()

"lock" a values is supported since 4019f725f5d4, but the error message
of the function used when specifying an incorrect value forgot about it.

Author: Maksim Logvinenko <logvinenko-ms@yandex.ru>
Discussion: https://postgr.es/m/433431777389005@mail.yandex.ru

2 weeks agoSuppress "has no symbols" linker warnings on macOS.
Nathan Bossart [Wed, 29 Apr 2026 17:25:09 +0000 (12:25 -0500)] 
Suppress "has no symbols" linker warnings on macOS.

After a recent macOS update, building Postgres produces warnings
that look like this:

    ranlib: warning: 'libpgport_shlib.a(pg_cpu_x86.c.o)' has no symbols
    ranlib: warning: 'libpgport_shlib.a(pg_popcount_x86.c.o)' has no symbols

To fix, add a dummy symbol to files that may otherwise have none.
Per project policy, this is a candidate for back-patching into
out-of-support branches: it suppresses annoying compiler warnings
but changes no behavior.

Reported-by: Zhang Mingli <zmlpostgres@gmail.com>
Reviewed-by: John Naylor <johncnaylorls@gmail.com>
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/229aaaf3-f529-44ed-8e50-00cb6909af21%40Spark
Backpatch-through: 13

2 weeks agotest_tidstore: Stabilize regression tests by sorting offsets.
Masahiko Sawada [Wed, 29 Apr 2026 16:10:04 +0000 (09:10 -0700)] 
test_tidstore: Stabilize regression tests by sorting offsets.

TidStoreSetBlockOffsets() requires its offsets array to be strictly
ascending and asserts this precondition. In test_tidstore, we were
passing random offset numbers deduplicated by a DISTINCT clause in an
array_agg() call directly to the do_set_block_offsets() test
harness. However, DISTINCT without an ORDER BY clause does not
guarantee sorted results according to the SQL standard.

Fix this by sorting the offsets in-place inside do_set_block_offsets()
before calling TidStoreSetBlockOffsets().

While this assertion failure is not observed during regular regression
tests because they use queries simple enough that the optimizer
consistently chooses plans yielding sorted results, it makes sense to
stabilize the test. The failure could theoretically occur depending on
the optimizer's plan choice, and has been reported when experimenting
with certain third-party extensions.

Backpatch to v17, where test_tidstore was introduced, to ensure
extension development on stable branches does not hit this assertion.

Reported-by: Andrei Lepikhov <lepihov@gmail.com>
Author: Andrei Lepikhov <lepihov@gmail.com>
Discussion: https://postgr.es/m/b97f1850-fc7b-43c4-9b04-4e97bb9e7dc0@gmail.com
Backpatch-through: 17

2 weeks agoFix timezone dependence in test_misc/012_ddlutils.pl
Andrew Dunstan [Wed, 29 Apr 2026 15:58:15 +0000 (11:58 -0400)] 
Fix timezone dependence in test_misc/012_ddlutils.pl

The tests introduced in c529ee38b9e are timezone sensitive.

Pin the cluster's timezone to UTC at init time so timestamptz output
is deterministic regardless of the host's local timezone.

2 weeks agoConvert ddlutils regression tests to TAP tests.
Andrew Dunstan [Wed, 29 Apr 2026 15:10:23 +0000 (11:10 -0400)] 
Convert ddlutils regression tests to TAP tests.

The regression tests for pg_get_role_ddl(), pg_get_database_ddl(),
and pg_get_tablespace_ddl() created databases and tablespaces, which
are heavyweight operations.  As noted by Andres Freund, this is
wasteful in the core regression suite which gets run repeatedly.

Convert the three test files (role_ddl.sql, database_ddl.sql,
tablespace_ddl.sql) into a single TAP test that runs once, covering
all the same functionality: basic DDL generation, pretty-printing,
option handling, error cases, permission checks, and edge cases like
quoted names and role memberships.

Discussion: https://postgr.es/m/5c67dc79-909a-4e17-8606-6686667da6c6@dunslane.net

2 weeks agoFix nbtree skip array parallel alloc accounting.
Peter Geoghegan [Wed, 29 Apr 2026 15:22:23 +0000 (11:22 -0400)] 
Fix nbtree skip array parallel alloc accounting.

btestimateparallelscan neglected to add btps_arrElems[] space overhead
for skip array scan keys that were later output by nbtree preprocessing.
Skip arrays don't actually need to use this space, but a scan with a
subsequent SAOP array will need to subscript btps_arrElems[] using a
simple so->arrayKeys[]-wise offset.  so->arrayKeys[] has entries for
both kinds of arrays.

As a result of this oversight, it was possible for an index scan with a
skip array and a lower-order SAOP array to write past the allocated
shared memory boundary when storing the SAOP array's cur_elem.  In
practice the problem seems to be limited to scans with many skipped
index columns, since our general approach to estimating the amount of
shared memory that will be required is fairly conservative.

To fix, have btestimateparallelscan request an extra sizeof(int) space
for key columns that might require a skip array later on.

Oversight in commit 92fe23d9, which added the nbtree skip scan
optimization.

Author: Siddharth Kothari <sidkot@google.com>
Discussion: https://postgr.es/m/CAGCUe0Lwk3C0qdkBa+OLpYc7yXwW=pbaz8Sju4xMXEQAmyp+5g@mail.gmail.com
Backpatch-through: 18

2 weeks agoCosmetic fixes for radix sort
John Naylor [Wed, 29 Apr 2026 09:14:25 +0000 (16:14 +0700)] 
Cosmetic fixes for radix sort

Do minor comment fixes and remove implicit cast to Datum.

While here, let's prefer crashing instead of entering an infinite
loop in case of future programming mistakes when computing next_level,
suggested by ChangAo Chen.

Discussion: https://postgr.es/m/tencent_49E3F11E74D8A584A2144ED532A490CBC40A@qq.com

2 weeks agoRemove unused ByteaSortSupport.abbreviate field
John Naylor [Wed, 29 Apr 2026 06:57:07 +0000 (13:57 +0700)] 
Remove unused ByteaSortSupport.abbreviate field

Oversight in commit 9303d62c6.

Author: Aleksander Alekseev <aleksander@tigerdata.com>
Discussion: https://postgr.es/m/CAJ7c6TOsKmmgyA6EwxKVsNeHFHrWXYdgZivgjo_ujf890BpeeA@mail.gmail.com

2 weeks agoFix xid_advance_interval when max_retention_duration is 0.
Amit Kapila [Tue, 28 Apr 2026 09:21:38 +0000 (14:51 +0530)] 
Fix xid_advance_interval when max_retention_duration is 0.

When a subscription has retain_dead_tuples enabled and maxretention is
zero (unlimited), adjust_xid_advance_interval() mistakenly caps
xid_advance_interval to zero.

This zero interval forces get_candidate_xid() to evaluate
TimestampDifferenceExceeds() as always true, causing the apply worker to
call GetOldestActiveTransactionId() for every WAL message. This
leads to unnecessary ProcArrayLock acquisitions.

Fix this by only capping the interval when maxretention > 0, allowing
the exponential back-off to function properly.

Author: SATYANARAYANA NARLAPURAM <satyanarlapuram@gmail.com>
Reviewed-by: shveta malik <shveta.malik@gmail.com>
Reviewed-by: Nisha Moond <nisha.moond412@gmail.com>
Discussion: https://postgr.es/m/CAHg+QDdKVnCLHot=AcoPpEiSyDzGz7wGYjAFHVOw57oDtmUDWQ@mail.gmail.com

2 weeks agoFix wrong datum conversion for subretentionactive in CreateSubscription.
Amit Kapila [Tue, 28 Apr 2026 07:21:25 +0000 (12:51 +0530)] 
Fix wrong datum conversion for subretentionactive in CreateSubscription.

Use BoolGetDatum() instead of Int32GetDatum() when storing the boolean
subretentionactive column in pg_subscription. This was an oversight in
a850be2fe6.

Author: Lakshmi N <lakshmin.jhs@gmail.com>
Reviewed-by: Nisha Moond <nisha.moond412@gmail.com>
Discussion: https://postgr.es/m/CA+3i_M98-XjE-_fw0p+8xOnw64y2_YLtJfcwvCfsVMn-z2ZjGg@mail.gmail.com

2 weeks agoREPACK CONCURRENTLY: Don't use deferrable primary keys
Álvaro Herrera [Mon, 27 Apr 2026 16:22:03 +0000 (18:22 +0200)] 
REPACK CONCURRENTLY: Don't use deferrable primary keys

Similarly to logical replication, REPACK CONCURRENTLY needs to ability
to reliably locate a tuple based on an identity.  A replica identity
index is okay.  Primary keys normally also are, except when they are
deferrable, because a tuple being modified might not yet be indexed,
causing REPACK to fail.

Change the REPACK CONCURRENTLY code to use GetRelationIdentityOrPK(),
similar to what the logical replication code does.  (Though we don't yet
support locating tuples based on arbitrary indexes for replica identity
FULL.)

While at it, add a few more test cases for situations that aren't
supported by REPACK, to improve coverage.

Author: Chao Li <lic@highgo.com>
Reviewed-by: Zhijie Hou <houzj.fnst@fujitsu.com>
Reviewed-by: Antonin Houska <ah@cybertec.at>
Reviewed-by: Yuchen Li <liyuchen_xyz@163.com>
Discussion: https://postgr.es/m/10DD5E13-B45D-44F1-BE08-C63E00ABCAC0@gmail.com

2 weeks agoFix DELETE/UPDATE FOR PORTION OF with rules
Peter Eisentraut [Mon, 27 Apr 2026 08:29:21 +0000 (10:29 +0200)] 
Fix DELETE/UPDATE FOR PORTION OF with rules

Previously, these test cases would give internal errors or crash.  The
fix is to add some missing fields of ForPortionOfExpr to
expression_tree_walker.

Author: jian he <jian.universality@gmail.com>
Reviewed-by: Kirill Reshke <reshkekirill@gmail.com>
Reviewed-by: Paul A Jungwirth <pj@illuminatedcomputing.com>
Discussion: https://postgr.es/m/CACJufxHs1Hs00EqsZ4NbuAjmYzMzjJyP1sAj12Ne=cBsEVmQOA@mail.gmail.com

2 weeks agodoc: Fix grammar in some logical replication pages
Michael Paquier [Mon, 27 Apr 2026 07:17:04 +0000 (16:17 +0900)] 
doc: Fix grammar in some logical replication pages

Author: Peter Smith <smithpb2250@gmail.com>
Discussion: https://postgr.es/m/CAHut+PuvY_wYLPJ4DTs7NE9Lu2ty4d-OgZAOJC-NvCM=2wwcQQ@mail.gmail.com
Backpatch-through: 14

2 weeks agoFix bogus calls in remove_self_join_rel()
Richard Guo [Mon, 27 Apr 2026 01:40:37 +0000 (10:40 +0900)] 
Fix bogus calls in remove_self_join_rel()

remove_self_join_rel() called adjust_relid_set() on all_result_relids
and leaf_result_relids but threw away the return value.  Since
adjust_relid_set() returns a freshly-built Relids and does not modify
the input in place, the calls did nothing.  This has been the case
since the SJE feature went in (commit fc069a3a6).

There has been no observable misbehavior, because the relid being
passed is guaranteed not to be a member of either set.  At the point
remove_self_join_rel() runs, those sets contain only resultRelation;
inheritance children have not been added yet, as that happens later in
query_planner(), in expand_single_inheritance_child() called from
add_other_rels_to_query().  And remove_self_joins_recurse() rejects
parse->resultRelation as an SJE candidate to preserve the EvalPlanQual
mechanism.  Even with the result assigned, the calls would be no-ops
in practice.

Rather than make the calls do the cleanup they pretend to do, replace
them with assertions of the invariant.  Any future loosening of the
SJE candidate filter -- for instance to allow eliminating a result
relation under provable conditions -- will trip the assertion and
force whoever does it to revisit this code.

Additionally, decorate adjust_relid_set() with pg_nodiscard so that
any future accidental discard of its return value is caught at compile
time.

Author: Richard Guo <guofenglinux@gmail.com>
Reviewed-by: David Rowley <dgrowleyml@gmail.com>
Discussion: https://postgr.es/m/CAMbWs49fYQcqJfJ_Gtn8r1GFNoYtb1=2AUab4ieuqY4Zid9ocQ@mail.gmail.com

2 weeks agoFix some memory leaks in the WAL receiver
Michael Paquier [Mon, 27 Apr 2026 01:32:45 +0000 (10:32 +0900)] 
Fix some memory leaks in the WAL receiver

These are old leaks, that can pile up if a WAL receiver stays alive,
waiting for new WAL data after the sender has switched to a new
timeline.

While this is technically a bug, the impact is minimal and would only
become noticeable if the WAL sender handles a lot of timeline switches,
so no backpatch is done.  Note that in most cases, primary_conninfo
would be updated in a standby to point to a new sender, meaning a
restart of the WAL receiver.  Let's be clean on HEAD, though.

Author: DaeMyung Kang <charsyam@gmail.com>
Discussion: https://postgr.es/m/20260426170100.847923-1-charsyam@gmail.com
Discussion: https://postgr.es/m/20260426170219.849330-1-charsyam@gmail.com

2 weeks agoFix new test with comma in build directory.
Noah Misch [Sun, 26 Apr 2026 22:03:51 +0000 (15:03 -0700)] 
Fix new test with comma in build directory.

Quote pg_hosts.conf fields derived from the build directory, since
hba.c:next_token() treats a comma as a token separator.  Commit
4f433025f666fa4a6209f0e847715767fb1c7ace introduced pg_hosts.conf and
this test.  A build directory name containing a comma worked before that
commit.  A build directory name containing a quote character has not
worked, so don't handle that.

Reviewed-by: Daniel Gustafsson <daniel@yesql.se>
Discussion: https://postgr.es/m/20260426213252.7a@rfd.leadboat.com

2 weeks agoDon't use INT64_FORMAT in translatable string
Peter Eisentraut [Sat, 25 Apr 2026 18:23:03 +0000 (20:23 +0200)] 
Don't use INT64_FORMAT in translatable string

Use PRId64 instead.

2 weeks agoUpdate time zone data files to tzdata release 2026b.
Tom Lane [Fri, 24 Apr 2026 16:28:35 +0000 (12:28 -0400)] 
Update time zone data files to tzdata release 2026b.

British Columbia (America/Vancouver) moved to permanent UTC-07 on
2026-03-09, which will affect their clocks beginning on 2026-11-01.
For lack of any clarity on the point, assume their TZ abbreviation
will be MST from that time forward.

Moldova (Europe/Chisinau) has followed EU DST transition times since
2022.

Backpatch-through: 14

2 weeks agomeson: Differentiate top-level and custom targets
Peter Eisentraut [Fri, 24 Apr 2026 07:51:09 +0000 (09:51 +0200)] 
meson: Differentiate top-level and custom targets

We need to create top-level targets to run targets with the ninja
command like `ninja <target_name>`.

Some targets (man, html, ...) have the same target name on both
top-level and custom target.  This creates a confusion for the meson
build:

$ meson compile -C build html

```
ERROR: Can't invoke target `html`: ambiguous name. Add target type
and/or path:
- ./doc/src/sgml/html:custom
- ./doc/src/sgml/html:alias
```

Solve that problem by adding '-custom' suffix to these problematic
targets' custom target names.  Top-level targets can be called with
both meson and ninja now:

$ meson compile -C build html
$ ninja -C build html

Author: Nazir Bilal Yavuz <byavuz81@gmail.com>
Suggested-by: Álvaro Herrera <alvherre@kurilemu.de>
Discussion: https://postgr.es/m/5508e572-79ae-4b20-84d0-010a66d077f2%40eisentraut.org

2 weeks agopg_get_viewdef() and lateral references in COLUMNS of GRAPH_TABLE
Peter Eisentraut [Fri, 24 Apr 2026 07:12:03 +0000 (09:12 +0200)] 
pg_get_viewdef() and lateral references in COLUMNS of GRAPH_TABLE

Expressions in GRAPH_TABLE COLUMNS list may have lateral references.
get_rule_expr() requires lateral namespaces to deparse such
references.  get_from_clause_item() does not pass them when processing
the expressions in COLUMNS list causing ERROR "bogus varlevelsup: 0
offset 0".  Fix get_from_clause_item() to pass input deparse_context
containing lateral namespaces to get_rule_expr() instead of the dummy
context.

Author: Satyanarayana Narlapuram <satyanarlapuram@gmail.com>
Reviewed-by: Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
Discussion: https://www.postgresql.org/message-id/flat/CAHg%2BQDcLVa2iBnggkHxY4itZbXtDMfsYHEjnCUYe9hNbnxDi-w%40mail.gmail.com

2 weeks agoFix collation of expressions in GRAPH_TABLE COLUMNS clause
Peter Eisentraut [Fri, 24 Apr 2026 06:43:26 +0000 (08:43 +0200)] 
Fix collation of expressions in GRAPH_TABLE COLUMNS clause

GRAPH_TABLE clause is converted into a rangetable entry, which is
ignored by assign_query_collations().  Hence we assign collations
while transforming its parts.  But expressions in COLUMNS clause
missed that treatment, so fix that.

While at it, also add comments about collation assignment to the parts
of GRAPH_TABLE clause, and also fix a small grammar issue.

Reported-by: Satyanarayana Narlapuram <satyanarlapuram@gmail.com>
Author: Satyanarayana Narlapuram <satyanarlapuram@gmail.com>
Author: Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
Discussion: https://www.postgresql.org/message-id/CAHg+QDc4aaiufYSgrwMMPMMRTPtQ66SghcrPFbWJFZMqNaG+BA@mail.gmail.com

2 weeks agoFix typos and grammar in graph table rewrite code
Peter Eisentraut [Fri, 24 Apr 2026 06:27:04 +0000 (08:27 +0200)] 
Fix typos and grammar in graph table rewrite code

Reported-by: Lakshmi N <lakshmin.jhs@gmail.com>
Author: Lakshmi N <lakshmin.jhs@gmail.com>
Author: Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
Discussion: https://www.postgresql.org/message-id/CA+3i_M9gpUGjH-BkJk=UFjK16jq9fEQHpmZ1cxpJO+xM4hWC+A@mail.gmail.com

2 weeks agoCheck for stack overflow when rewriting graph queries
Peter Eisentraut [Fri, 24 Apr 2026 06:18:21 +0000 (08:18 +0200)] 
Check for stack overflow when rewriting graph queries

generate_queries_for_path_pattern_recurse() and
generate_setop_from_pathqueries() are recursive functions.  For a
property graph with hundreds of tables, a graph pattern with a handful
element patterns can cause stack overflow.  Fix it by calling
check_stack_depth() at the beginning of these functions.

Author: Satyanarayana Narlapuram <satyanarlapuram@gmail.com>
Reviewed-by: Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
Discussion: https://www.postgresql.org/message-id/CAHg+QDfgK0xddH8f3eAb+UVn7sBDOnv8RvM6OkP4HtHAt6aD7w@mail.gmail.com

2 weeks agopg_test_timing: store timing deltas in int64
Fujii Masao [Fri, 24 Apr 2026 03:11:40 +0000 (12:11 +0900)] 
pg_test_timing: store timing deltas in int64

Commit 0b096e379e6 changed pg_test_timing to measure timing
differences in nanoseconds instead of microseconds, but the resulting
deltas continued to be stored in int32.

That can overflow for large gaps (for example, values greater than about
2.14 seconds in nanoseconds), leading to truncation or incorrect output.

This commit fixes the issue by storing measured timing deltas in int64.
This prevents overflow for large values and better matches
nanosecond-resolution measurements.

Author: Chao Li <lic@highgo.com>
Reviewed-by: Lukas Fittl <lukas@fittl.com>
Reviewed-by: Xiaopeng Wang <wxp_728@163.com>
Reviewed-by: Fujii Masao <masao.fujii@gmail.com>
Discussion: https://postgr.es/m/F780CEEB-A237-4302-9F55-60E9D8B6533D@gmail.com

3 weeks agoFix incorrect logic for hashed IN / NOT IN with non-strict operators
David Rowley [Fri, 24 Apr 2026 02:03:12 +0000 (14:03 +1200)] 
Fix incorrect logic for hashed IN / NOT IN with non-strict operators

ExecEvalHashedScalarArrayOp(), when using a strict equality function,
performs a short-circuit when looking up NULL values.  When the function
is non-strict, the code incorrectly looked up the hash table for a
zero-valued Datum, which could have resulted in an accidental true
return if the hash table contained zero valued Datum, or could result
in a crash for non-byval types.

Here we fix this by adding an extra step when we build the hash table to
check what the result of a NULL lookup would be.  This requires looping
over the array and checking what the non-hashed version of the code
would do.  We cache the results of that in the expression so that we can
reuse the result any time we're asked to search for a NULL value.

It's important to note that non-strict equality functions are free to
treat any NULL value as equal to any non-NULL value.  For example,
someone may wish to design a type that treats an empty string and NULL
as equal.

All built-in types have strict equality functions, so this could affect
custom / user-defined types.

Author: Chengpeng Yan <chengpeng_yan@outlook.com>
Author: David Rowley <dgrowleyml@gmail.com>
Reviewed-by: ChangAo Chen <cca5507@qq.com>
Discussion: https://postgr.es/m/A16187AE-2359-4265-9F5E-71D015EC2B2D@outlook.com
Backpatch-through: 14

3 weeks agopg_test_timing: fix unit in backward-clock warning
Fujii Masao [Thu, 23 Apr 2026 23:59:14 +0000 (08:59 +0900)] 
pg_test_timing: fix unit in backward-clock warning

pg_test_timing reports timing differences in nanoseconds in master, and
in microseconds in v14 through v18, but previously the backward-clock
warning incorrectly labeled the value as milliseconds.

This commit fixes the warning message to use "ns" in master and
"us" in v14 through v18, matching the actual unit being reported.

Backpatch to all supported versions.

Author: Chao Li <lic@highgo.com>
Reviewed-by: Lukas Fittl <lukas@fittl.com>
Reviewed-by: Xiaopeng Wang <wxp_728@163.com>
Reviewed-by: Fujii Masao <masao.fujii@gmail.com>
Discussion: https://postgr.es/m/F780CEEB-A237-4302-9F55-60E9D8B6533D@gmail.com
Backpatch-through: 14

3 weeks agoAdd missing source files to several nls.mk
Peter Eisentraut [Thu, 23 Apr 2026 19:52:02 +0000 (21:52 +0200)] 
Add missing source files to several nls.mk

3 weeks agoDon't call CheckAttributeType() with InvalidOid on dropped cols
Heikki Linnakangas [Thu, 23 Apr 2026 18:05:27 +0000 (21:05 +0300)] 
Don't call CheckAttributeType() with InvalidOid on dropped cols

If CheckAttributeType() is called with InvalidOid, it performs a bunch
of pointless, futile syscache lookups with InvalidOid, but ultimately
tolerates it and has no effect. We were calling it with InvalidOid on
dropped columns, but it seems accidental that it works, so let's stop
doing it.

Reviewed-by: Chao Li <li.evan.chao@gmail.com>
Discussion: https://www.postgresql.org/message-id/93ce56cd-02a6-4db1-8224-c8999372facc@iki.fi
Backpatch-through: 14

3 weeks agoDon't allow composite type to be member of itself via multirange
Heikki Linnakangas [Thu, 23 Apr 2026 18:28:11 +0000 (21:28 +0300)] 
Don't allow composite type to be member of itself via multirange

CheckAttributeType() checks that a composite type is not made a member
of itself with ALTER TABLE ADD COLUMN or ALTER TYPE ADD ATTRIBUTE,
even indirectly via a domain, array, another composite type or a range
type. But it missed checking for multiranges. That was a simple
oversight when multiranges were added.

Reviewed-by: Chao Li <li.evan.chao@gmail.com>
Discussion: https://www.postgresql.org/message-id/93ce56cd-02a6-4db1-8224-c8999372facc@iki.fi
Backpatch-through: 14

3 weeks agoMove REPACK (CONCURRENTLY) test out of stock regression tests
Álvaro Herrera [Thu, 23 Apr 2026 10:34:41 +0000 (12:34 +0200)] 
Move REPACK (CONCURRENTLY) test out of stock regression tests

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

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

3 weeks agopsql: Improve describe footer titles for publications.
Amit Kapila [Thu, 23 Apr 2026 08:40:03 +0000 (14:10 +0530)] 
psql: Improve describe footer titles for publications.

The psql describe (`\d`) footer titles were previously unintuitive when
listing publications that included or excluded specific tables. Even
though the tag for included publications was pre-existing, it is better
to update it to "Included in publications:" to match the phrasing of
the "Excluded from publications:" tag.

Footer titles for sequence and schema descriptions have been updated
similarly to maintain consistency.

Reported-by: Álvaro Herrera <alvherre@kurilemu.de>
Author: Peter Smith <smithpb2250@gmail.com>
Reviewed-by: Amit Kapila <amit.kapila16@gmail.com>
Reviewed-by: vignesh C <vignesh21@gmail.com>
Reviewed-by: Yuchen Li <liyuchen_xyz@163.com>
Discussion: https://postgr.es/m/aeDs7iZUox1bbKAK%40alvherre.pgsql

3 weeks agoAvoid casting void * function arguments
Peter Eisentraut [Thu, 23 Apr 2026 06:08:57 +0000 (08:08 +0200)] 
Avoid casting void * function arguments

Like commit c3c240537f6, but for newly added code.

3 weeks agoFix new-to-v19 -Wshadow warnings
David Rowley [Thu, 23 Apr 2026 04:49:29 +0000 (16:49 +1200)] 
Fix new-to-v19 -Wshadow warnings

There's some talk about upgrading our current -Wshadow=compatible-local
up to -Wshadow.  There's some pending questions as to whether the churn
and extra backpatching pain are worthwhile for doing all of them.  We
can't use the latter argument for ones that are new to v19, providing we
fix them now.  So let's fix those ones so that the problem is not any
worse for if we decide to fix the remainder for v20.

Author: Chao Li <li.evan.chao@gmail.com>
Reviewed-by: Peter Smith <smithpb2250@gmail.com>
Reviewed-by: Yuchen Li <liyuchen_xyz@163.com>
Discussion: https://postgr.es/m/CAApHDvp=rx5GxM=yW8QhFF3noXtYt7LkOxJ7zkaPOzpti4Gm8w@mail.gmail.com

3 weeks agocatcache.c: use C_COLLATION_OID for texteqfast/texthashfast.
Jeff Davis [Wed, 22 Apr 2026 17:22:44 +0000 (10:22 -0700)] 
catcache.c: use C_COLLATION_OID for texteqfast/texthashfast.

The problem report was about setting GUCs in the startup packet for a
physical replication connection. Setting the GUC required an ACL
check, which performed a lookup on pg_parameter_acl.parname. The
catalog cache was hardwired to use DEFAULT_COLLATION_OID for
texteqfast() and texthashfast(), but the database default collation
was uninitialized because it's a physical walsender and never connects
to a database. In versions 18 and later, this resulted in a NULL
pointer dereference, while in version 17 it resulted in an ERROR.

As the comments stated, using DEFAULT_COLLATION_OID was arbitrary
anyway: if the collation actually mattered, it should have used the
column's actual collation. (In the catalog, some text columns are the
default collation and some are "C".)

Fix by using C_COLLATION_OID, which doesn't require any initialization
and is always available. When any deterministic collation will do,
it's best to consistently use the simplest and fastest one, so this is
a good idea anyway.

Another problem was raised in the thread, which this commit doesn't
fix (see second discussion link).

Reported-by: Andrey Borodin <x4mmm@yandex-team.ru>
Discussion: https://postgr.es/m/D18AD72A-5004-4EF8-AF80-10732AF677FA@yandex-team.ru
Discussion: https://postgr.es/m/4524ed61a015d3496fc008644dcb999bb31916a7.camel%40j-davis.com
Backpatch-through: 17

3 weeks agopg_upgrade: Fix detection of invalid logical replication slots.
Masahiko Sawada [Wed, 22 Apr 2026 16:59:46 +0000 (09:59 -0700)] 
pg_upgrade: Fix detection of invalid logical replication slots.

Commit 7a1f0f8747a optimized the slot verification query but
overlooked cases where all logical replication slots are already
invalidated. In this scenario, the CTE returns no rows, causing the
main query (which used a cross join) to return an empty result even
when invalid slots exist.

This commit fixes this by using a LEFT JOIN with the CTE, ensuring
that slots are properly reported even if the CTE returns no rows.

Author: Lakshmi N <lakshmin.jhs@gmail.com>
Reviewed-by: Shveta Malik <shveta.malik@gmail.com>
Reviewed-by: Chao Li <li.evan.chao@gmail.com>
Discussion: https://postgr.es/m/CA+3i_M8eT6j8_cBHkYykV-SXCxbmAxpVSKptjDVq+MFtpT-Paw@mail.gmail.com

3 weeks agoHarmonize function parameter names for Postgres 19.
Peter Geoghegan [Wed, 22 Apr 2026 16:47:19 +0000 (12:47 -0400)] 
Harmonize function parameter names for Postgres 19.

Make sure that function declarations use names that exactly match the
corresponding names from function definitions in a few places.  Most of
these inconsistencies were introduced during Postgres 19 development.

This commit was written with help from clang-tidy, by mechanically
applying the same rules as similar clean-up commits (the earliest such
commit was commit 035ce1fe).

3 weeks agoGuard against overly-long numeric formatting symbols from locale.
Tom Lane [Wed, 22 Apr 2026 16:41:00 +0000 (12:41 -0400)] 
Guard against overly-long numeric formatting symbols from locale.

to_char() allocates its output buffer with 8 bytes per formatting
code in the pattern.  If the locale's currency symbol, thousands
separator, or decimal or sign symbol is more than 8 bytes long,
in principle we could overrun the output buffer.  No such locales
exist in the real world, so it seems sufficient to truncate the
symbol if we do see it's too long.

Reported-by: Xint Code
Author: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/638232.1776790821@sss.pgh.pa.us
Backpatch-through: 14

3 weeks agoPrevent some buffer overruns in spell.c's parsing of affix files.
Tom Lane [Wed, 22 Apr 2026 16:02:15 +0000 (12:02 -0400)] 
Prevent some buffer overruns in spell.c's parsing of affix files.

parse_affentry() and addCompoundAffixFlagValue() each collect fields
from an affix file into working buffers of size BUFSIZ.  They failed
to defend against overlength fields, so that a malicious affix file
could cause a stack smash.  BUFSIZ (typically 8K) is certainly way
longer than any reasonable affix field, but let's fix this while
we're closing holes in this area.

I chose to do this by silently truncating the input before it can
overrun the buffer, using logic comparable to the existing logic in
get_nextfield().  Certainly there's at least as good an argument for
raising an error, but for now let's follow the existing precedent.

Reported-by: Igor Stepansky <igor.stepansky@orca.security>
Author: Tom Lane <tgl@sss.pgh.pa.us>
Reviewed-by: Andrey Borodin <x4mmm@yandex-team.ru>
Discussion: https://postgr.es/m/864123.1776810909@sss.pgh.pa.us
Backpatch-through: 14

3 weeks agoPrevent buffer overrun in spell.c's CheckAffix().
Tom Lane [Wed, 22 Apr 2026 14:47:56 +0000 (10:47 -0400)] 
Prevent buffer overrun in spell.c's CheckAffix().

This function writes into a caller-supplied buffer of length
2 * MAXNORMLEN, which should be plenty in real-world cases.
However a malicious affix file could supply an affix long
enough to overrun that.  Defend by just rejecting the match
if it would overrun the buffer.  I also inserted a check of
the input word length against Affix->replen, just to be sure
we won't index off the buffer, though it would be caller error
for that not to be true.

Also make the actual copying steps a bit more readable, and remove
an unnecessary requirement for the whole input word to fit into the
output buffer (even though it always will with the current caller).

The lack of documentation in this code makes my head hurt, so
I also reverse-engineered a basic header comment for CheckAffix.

Reported-by: Xint Code
Author: Tom Lane <tgl@sss.pgh.pa.us>
Reviewed-by: Andrey Borodin <x4mmm@yandex-team.ru>
Discussion: https://postgr.es/m/641711.1776792744@sss.pgh.pa.us
Backpatch-through: 14

3 weeks agoPreserve extension dependencies on indexes during partition merge/split
Alexander Korotkov [Wed, 22 Apr 2026 11:32:57 +0000 (14:32 +0300)] 
Preserve extension dependencies on indexes during partition merge/split

When using ALTER TABLE ... MERGE PARTITIONS or ALTER TABLE ... SPLIT
PARTITION, extension dependencies on partition indexes were being lost.
This happened because the new partition indexes are created fresh from
the parent partitioned table's indexes, while the old partition indexes
(with their extension dependencies) are dropped.

Fix this by collecting extension dependencies from source partition
indexes before detaching them, then applying those dependencies to the
corresponding new partition indexes after they're created.  The mapping
between old and new indexes is done via their common parent partitioned
index.

For MERGE operations, all source partition indexes sharing a parent
partitioned index must have the same extension dependencies; if they
differ, an error naming both conflicting partition indexes is raised.
The check is implemented by collecting one entry per partition index,
sorting by parent index OID, and comparing adjacent entries in a single
pass.  This is order-independent: the same set of partitions produces
the same decision regardless of the order they are listed in the MERGE
command, and subset mismatches are caught in both directions.

For SPLIT operations, the new partition indexes simply inherit all
extension dependencies from the source partition's index.

The regression tests exercising this feature live under
src/test/modules/test_extensions, where the test_ext3 and test_ext5
extensions are available; core regression tests cannot assume any
particular extension is installed.

Author: Matheus Alcantara <matheusssilv97@gmail.com>
Co-authored-by: Alexander Korotkov <aekorotkov@gmail.com>
Reported-by: Kirill Reshke <reshkekirill@gmail.com>
Reviewed-by: Dmitry Koval <d.koval@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/CALdSSPjXtzGM7Uk4fWRwRMXcCczge5uNirPQcYCHKPAWPkp9iQ%40mail.gmail.com

3 weeks agoFix UPDATE/DELETE ... WHERE CURRENT OF on a table with virtual columns.
Dean Rasheed [Wed, 22 Apr 2026 10:50:17 +0000 (11:50 +0100)] 
Fix UPDATE/DELETE ... WHERE CURRENT OF on a table with virtual columns.

Formerly, attempting to use WHERE CURRENT OF to update or delete from
a table with virtual generated columns would fail with the error
"WHERE CURRENT OF on a view is not implemented".

The reason was that the check preventing WHERE CURRENT OF from being
used on a view was in replace_rte_variables_mutator(), which presumed
that the only way it could get there was as part of rewriting a query
on a view. That is no longer the case, since replace_rte_variables()
is now also used to expand the virtual generated columns of a table.

Fix by doing the check for WHERE CURRENT OF on a view at parse time.
This is safe, since it is no longer possible for the relkind to change
after the query is parsed (as of b23cd185f).

Reported-by: Satyanarayana Narlapuram <satyanarlapuram@gmail.com>
Author: Satyanarayana Narlapuram <satyanarlapuram@gmail.com>
Author: Dean Rasheed <dean.a.rasheed@gmail.com>
Discussion: https://postgr.es/m/CAHg+QDc_TwzSgb=B_QgNLt3mvZdmRK23rLb+RkanSQkDF40GjA@mail.gmail.com
Backpatch-through: 18

3 weeks agoFix expansion of EXCLUDED virtual generated columns.
Dean Rasheed [Wed, 22 Apr 2026 08:03:44 +0000 (09:03 +0100)] 
Fix expansion of EXCLUDED virtual generated columns.

If the SET or WHERE clause of an INSERT ... ON CONFLICT command
references EXCLUDED.col, where col is a virtual generated column, the
column was not properly expanded, leading to an "unexpected virtual
generated column reference" error, or incorrect results.

The problem was that expand_virtual_generated_columns() would expand
virtual generated columns in both the SET and WHERE clauses and in the
targetlist of the EXCLUDED pseudo-relation (exclRelTlist). Then
fix_join_expr() from set_plan_refs() would turn the expanded
expressions in the SET and WHERE clauses back into Vars, because they
would be found to match the expression entries in the indexed tlist
produced from exclRelTlist.

To fix this, arrange for expand_virtual_generated_columns() to not
expand virtual generated columns in exclRelTlist. This forces
set_plan_refs() to resolve generation expressions in the query using
non-virtual columns, as required by the executor.

In addition, exclRelTlist now always contains only Vars. That was
something already claimed in a couple of existing comments in the
planner, which relied on that fact to skip some processing, though
those did not appear to constitute active bugs.

Reported-by: Satyanarayana Narlapuram <satyanarlapuram@gmail.com>
Author: Satyanarayana Narlapuram <satyanarlapuram@gmail.com>
Author: Dean Rasheed <dean.a.rasheed@gmail.com>
Discussion: https://postgr.es/m/CAHg+QDf7wTLz_vqb1wi1EJ_4Uh+Vxm75+b4c-Ky=6P+yOAHjbQ@mail.gmail.com
Backpatch-through: 18

3 weeks agoFix some const qualifier use in ri_triggers.c
Amit Langote [Wed, 22 Apr 2026 00:33:10 +0000 (09:33 +0900)] 
Fix some const qualifier use in ri_triggers.c

The ri_FetchConstraintInfo() and ri_LoadConstraintInfo() functions
were declared to return const RI_ConstraintInfo *, but callers
sometimes need to modify the struct, requiring casts to drop the
const.  Remove the misapplied const qualifiers and the casts that
worked around them.

Reported-by: Peter Eisentraut <peter@eisentraut.org>
Author: Peter Eisentraut <peter@eisentraut.org>
Discussion: https://postgr.es/m/548600ed-8bbb-4e50-8fc3-65091b122276@eisentraut.org

3 weeks agoAllow ALTER INDEX .. ATTACH PARTITION to validate a parent index
Michael Paquier [Wed, 22 Apr 2026 01:32:10 +0000 (10:32 +0900)] 
Allow ALTER INDEX .. ATTACH PARTITION to validate a parent index

This commit tweaks ALTER INDEX .. ATTACH PARTITION to attempt a
validation of a parent index in the case where an index is already
attached but the parent is not yet valid.  This occurs in cases where a
parent index was created invalid such as with CREATE INDEX ONLY, but was
left invalid after an invalid child index was attached (partitioned
indexes set indisvalid to false if at least one partition is
!indisvalid, indisvalid is true in a partitioned table iff all
partitions are indisvalid).  This could leave a partition tree in a
situation where a user could not bring the parent index back to valid
after fixing the child index, as there is no built-in mechanism to do
so.  This commit relies on the fact that repeated ATTACH PARTITION
commands on the same index silently succeed.

An invalid parent index is more than just a passive issue.  It causes
for example ON CONFLICT on a partitioned table if the invalid parent
index is used to enforce a unique constraint.

Some test cases are added to track some of problematic patterns, using a
set of partition trees with combinations of invalid indexes and ATTACH
PARTITION.

Reported-by: Mohamed Ali <moali.pg@gmail.com>
Author: Sami Imseih <sanmimseih@gmail.com>
Reviewed-by: Michael Paquier <michael@paquier.xyz>
Reviewed-by: Haibo Yan <tristan.yim@gmail.com>
Discussion: http://postgr.es/m/CAGnOmWqi1D9ycBgUeOGf6mOCd2Dcf=6sKhbf4sHLs5xAcKVCMQ@mail.gmail.com
Backpatch-through: 14

3 weeks agoFix not-quite-right Makefile for src/test/modules/test_checksums.
Tom Lane [Tue, 21 Apr 2026 22:29:24 +0000 (18:29 -0400)] 
Fix not-quite-right Makefile for src/test/modules/test_checksums.

This neglected to set TAP_TESTS = 1, and partially compensated
for that by writing duplicative hand-made rules for check and
installcheck.  That's not really sufficient though.  The way
I noticed the error was that "make distclean" didn't clean out
the tmp_check subdirectory, and there might be other consequences.
Do it the standard way instead.

3 weeks agobufmgr: use I/O stats arguments in FlushUnlockedBuffer()
Melanie Plageman [Tue, 21 Apr 2026 21:47:22 +0000 (17:47 -0400)] 
bufmgr: use I/O stats arguments in FlushUnlockedBuffer()

FlushUnlockedBuffer() accepted io_object and io_context arguments but
hardcoded IOOBJECT_RELATION and IOCONTEXT_NORMAL when calling
FlushBuffer(). Pass them through instead. Also fix FlushBuffer() to use
its io_object parameter for I/O timing stats rather than hardcoding
IOOBJECT_RELATION.

Not actively broken since all current callers pass IOOBJECT_RELATION and
IOCONTEXT_NORMAL, so not backpatched.

Author: Chao Li <lic@highgo.com>
Reviewed-by: Melanie Plageman <melanieplageman@gmail.com>
Discussion: https://postgr.es/m/BC97546F-5C15-42F2-AD57-CFACDB9657D0@gmail.com

3 weeks agoStabilize btree_gist test against on-access VM setting
Melanie Plageman [Tue, 21 Apr 2026 21:32:45 +0000 (17:32 -0400)] 
Stabilize btree_gist test against on-access VM setting

The btree_gist enum test expects a bitmap heap scan. Since b46e1e54d07
enabled setting the VM during on-access pruning and 378a21618 set
pd_prune_xid on INSERT, scans of enumtmp may set pages all-visible.
If autovacuum or autoanalyze then updates pg_class.relallvisible, the
planner could choose an index-only scan instead.

Make the enumtmp a temp table to exclude it from autovacuum/autoanalyze.

Reported-by: Alexander Lakhin <exclusion@gmail.com>
Author: Melanie Plageman <melanieplageman@gmail.com>
Discussion: https://postgr.es/m/46733d68-aec0-4d09-8120-4c66b87047a4%40gmail.com

3 weeks agoStabilize plancache test against on-access VM setting
Melanie Plageman [Tue, 21 Apr 2026 18:36:59 +0000 (14:36 -0400)] 
Stabilize plancache test against on-access VM setting

Since b46e1e54d07 allowed setting the VM on-access and 378a21618 set
pd_prune_xid on INSERT, the testing of generic/custom plans in
src/test/regress/sql/plancache.sql was destabilized.

One of the queries of test_mode could have set the pages all-visible and
if autovacuum/autoanalyze ran and updated pg_class.relallvisible, it
would affect whether we got an index-only or sequential scan.

Preclude this by disabling autovacuum and autoanalyze for test_mode and
carefully sequencing when ANALYZE is run.

Reported-by: Alexander Lakhin <exclusion@gmail.com>
Author: Melanie Plageman <melanieplageman@gmail.com>
Discussion: https://postgr.es/m/71277259-264e-4983-a201-938b404049d7%40gmail.com

3 weeks agoMake local buffers pin limit more conservative
Melanie Plageman [Tue, 21 Apr 2026 15:01:57 +0000 (11:01 -0400)] 
Make local buffers pin limit more conservative

GetLocalPinLimit() and GetAdditionalLocalPinLimit(), currently in use
only by the read stream, previously allowed a backend to pin all
num_temp_buffers local buffers. This meant that the read stream could
use every available local buffer for read-ahead, leaving none for other
concurrent pin-holders like other read streams and related buffers like
the visibility map buffer needed during on-access pruning.

This became more noticeable since b46e1e54d07, which allows on-access
pruning to set the visibility map, which meant that some scans also
needed to pin a page of the VM. It caused a test in
src/test/regress/sql/temp.sql to fail in some cases.

Cap the local pin limit to num_temp_buffers / 4, providing some
headroom. This doesn't guarantee that all needed pins will be available
— for example, a backend can still open more cursors than there are
buffers — but it makes it less likely that read-ahead will exhaust the
pool.

Note that these functions are not limited by definition to use in the
read stream; however, this cap should be appropriate in other contexts.

Reported-by: Alexander Lakhin <exclusion@gmail.com>
Author: Melanie Plageman <melanieplageman@gmail.com>
Reviewed-by: Andres Freund <andres@anarazel.de>
Discussion: https://postgr.es/m/97529f5a-ec10-46b1-ab50-4653126c6889%40gmail.com

3 weeks agoRemove gen_node_support.pl's ad-hoc ABI stability check.
Tom Lane [Tue, 21 Apr 2026 14:58:00 +0000 (10:58 -0400)] 
Remove gen_node_support.pl's ad-hoc ABI stability check.

We installed this in commit eea9fa9b2 to protect against foreseeable
mistakes that would break ABI in stable branches by renumbering
NodeTag enum entries.  However, we now have much more thorough
ABI stability checks thanks to buildfarm members using libabigail
(see the .abi-compliance-history mechanism).  So this incomplete,
single-purpose check seems like an anachronism.  I wouldn't object
to keeping it were it not that it requires an additional manual step
when making a new stable git branch.  That seems like something easy
to screw up, so let's get rid of it.

This patch just removes the logic that checks for changes in the last
auto-assigned NodeTag value.  We still need eea9fa9b2's cross-check
on the supplied list of header files, to prevent divergence between
the makefile and meson build systems.  We'll also sometimes need the
nodetag_number() infrastructure for hand-assigning new NodeTags in
stable branches.

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

3 weeks agoMake plpgsql_trap test more robust and less resource-intensive.
Tom Lane [Tue, 21 Apr 2026 14:54:39 +0000 (10:54 -0400)] 
Make plpgsql_trap test more robust and less resource-intensive.

We were using "select count(*) into x from generate_series(1,
1_000_000_000_000)" to waste one second waiting for a statement
timeout trap.  Aside from consuming CPU to little purpose, this could
easily eat several hundred MB of temporary file space, which has been
observed to cause out-of-disk-space errors in the buildfarm.
Let's just use "pg_sleep(10)", which is far less resource-intensive.

Also update the "when others" exception handler so that if it does
ever again trap an error, it will tell us what error.  The cause of
these intermittent buildfarm failures had been obscure for awhile.

Discussion: https://postgr.es/m/557992.1776779694@sss.pgh.pa.us
Backpatch-through: 14

3 weeks agoFix a set of typos and grammar issues across the tree
Michael Paquier [Tue, 21 Apr 2026 05:46:22 +0000 (14:46 +0900)] 
Fix a set of typos and grammar issues across the tree

This batch is similar to 462fe0ff6215 and addresses a variety of code
style issues, including grammar mistakes, typos, inconsistent variable
names in function declarations, and incorrect function names in comments
and documentation.  These fixes have accumulated on the community
mailing lists since the commit mentioned above.

Notably, Alexander Lakhin previously submitted a patch identifying many
of the trivial typos and grammar issues that had been reported on
pgsql-hackers.  His patch covered a somewhat large portion of the issues
addressed here, though not all of them.

The documentation changes only affect HEAD.

3 weeks agoFix incorrect NEW references to generated columns in rule rewriting
Richard Guo [Tue, 21 Apr 2026 05:28:26 +0000 (14:28 +0900)] 
Fix incorrect NEW references to generated columns in rule rewriting

When a rule action or rule qualification references NEW.col where col
is a generated column (stored or virtual), the rewriter produces
incorrect results.

rewriteTargetListIU removes generated columns from the query's target
list, since stored generated columns are recomputed by the executor
and virtual ones store nothing.  However, ReplaceVarsFromTargetList
then cannot find these columns when resolving NEW references during
rule rewriting.  For UPDATE, the REPLACEVARS_CHANGE_VARNO fallback
redirects NEW.col to the original target relation, making it read the
pre-update value (same as OLD.col).  For INSERT,
REPLACEVARS_SUBSTITUTE_NULL replaces it with NULL.  Both are wrong
when the generated column depends on columns being modified.

Fix by building target list entries for generated columns from their
generation expressions, pre-resolving the NEW.attribute references
within those expressions against the query's targetlist, and passing
them together with the query's targetlist to ReplaceVarsFromTargetList.

Back-patch to all supported branches.  Virtual generated columns were
added in v18, so the back-patches in pre-v18 branches only handle
stored generated columns.

Reported-by: SATYANARAYANA NARLAPURAM <satyanarlapuram@gmail.com>
Author: Richard Guo <guofenglinux@gmail.com>
Author: Dean Rasheed <dean.a.rasheed@gmail.com>
Reviewed-by: Chao Li <li.evan.chao@gmail.com>
Discussion: https://postgr.es/m/CAHg+QDexGTmCZzx=73gXkY2ZADS6LRhpnU+-8Y_QmrdTS6yUhA@mail.gmail.com
Backpatch-through: 14

3 weeks agoFix orphaned processes when startup process fails during PM_STARTUP
Michael Paquier [Tue, 21 Apr 2026 00:39:59 +0000 (09:39 +0900)] 
Fix orphaned processes when startup process fails during PM_STARTUP

When the startup process exists with a FATAL error during PM_STARTUP,
the postmaster called ExitPostmaster() directly, assuming that no other
processes are running at this stage.  Since 7ff23c6d277d, this
assumption is not true, as the checkpointer, the background writer, the
IO workers and bgworkers kicking in early would be around.

This commit removes the startup-specific shortcut happening in
process_pm_child_exit() for a failing startup process during PM_STARTUP,
falling down to the existing exit() flow to signal all the started
children with SIGQUIT, so as we have no risk of creating orphaned
processes.

This required an extra change in HandleFatalError() for v18 and newer
versions, as an assertion could be triggered for PM_STARTUP.  It is now
incorrect.  In v17 and older versions, HandleChildCrash() needs to be
changed to handle PM_STARTUP so as children can be waited on.

While on it, fix a comment at the top of postmaster.c.  It was claiming
that the checkpointer and the background writer were started after
PM_RECOVERY.  That is not the case.

Author: Ayush Tiwari <ayushtiwari.slg01@gmail.com>
Discussion: https://postgr.es/m/CAJTYsWVoD3V9yhhqSae1_wqcnTdpFY-hDT7dPm5005ZFsL_bpA@mail.gmail.com
Backpatch-through: 15

3 weeks agodoc: Use "integer" for some I/O worker GUC type descriptions
Fujii Masao [Mon, 20 Apr 2026 23:50:10 +0000 (08:50 +0900)] 
doc: Use "integer" for some I/O worker GUC type descriptions

The documentation previously described the io_max_workers,
io_worker_idle_timeout, and io_worker_launch_interval GUCs as
type "int". However, the documentation consistently uses "integer"
for parameters of this type.

This commit updates these parameter descriptions to use "integer"
for consistency.

Author: Fujii Masao <masao.fujii@gmail.com>
Reviewed-by: Daniel Gustafsson <daniel@yesql.se>
Discussion: https://postgr.es/m/CAHGQGwEpMDpB-K8SSUVRRHg6L6z3pLAkekd9aviOS=ns0EC=+Q@mail.gmail.com

3 weeks agodoc: Correct context description for some JIT support GUCs
Fujii Masao [Mon, 20 Apr 2026 23:44:19 +0000 (08:44 +0900)] 
doc: Correct context description for some JIT support GUCs

The documentation for jit_debugging_support and jit_profiling_support
previously stated that these parameters can only be set at server start.

However, both parameters use the PGC_SU_BACKEND context, meaning they
can be set at session start by superusers or users granted the appropriate
SET privilege, but cannot be changed within an active session.

This commit updates the documentation to reflect the actual behavior.

Backpatch to all supported versions.

Author: Fujii Masao <masao.fujii@gmail.com>
Reviewed-by: Daniel Gustafsson <daniel@yesql.se>
Discussion: https://postgr.es/m/CAHGQGwEpMDpB-K8SSUVRRHg6L6z3pLAkekd9aviOS=ns0EC=+Q@mail.gmail.com
Backpatch-through: 14

3 weeks agoplsample: Use TextDatumGetCString() for text-to-CString conversion
Fujii Masao [Mon, 20 Apr 2026 23:37:17 +0000 (08:37 +0900)] 
plsample: Use TextDatumGetCString() for text-to-CString conversion

Replace the outdated DatumGetCString(DirectFunctionCall1(textout, ...))
pattern with TextDatumGetCString(). The macro is the modern, more
efficient way to convert a text Datum to a C string as it avoids
unnecessary function call machinery and handles detoasting internally.

Since plsample serves as reference code for extension authors, it
should follow current idiomatic practices.

Author: Amul Sul <sulamul@gmail.com>
Discussion: https://postgr.es/m/CAAJ_b95-xMvUN1PEqxv8y6g-A-8k+fSgyv20kSZc9eF1wZAUPg@mail.gmail.com

3 weeks agoFix relid-set clobber during join removal.
Tom Lane [Mon, 20 Apr 2026 23:24:46 +0000 (19:24 -0400)] 
Fix relid-set clobber during join removal.

Commit cfcd57111 et al fell over under Valgrind testing.
(It seems to be enough to #define USE_VALGRIND, you don't actually
need to run it under Valgrind to see failures.)  The cause is that
remove_rel_from_eclass updates each EquivalenceMember's em_relids,
and those can be aliases of the left_relids or right_relids of some
RestrictInfo in ec_sources.  If the update made em_relids empty then
bms_del_member will have pfree'd the relid set, so that the subsequent
attempt to clean up ec_sources accesses already-freed memory.

We missed seeing ill effects before cfcd57111 because (a) if the
pfree happens then we will remove the EquivalenceMember altogether,
making the source RestrictInfo no longer of use, and (b) the
cleanup of ec_sources didn't touch left/right_relids before that.

I'm unclear though on how cfcd57111 managed to pass non-USE_VALGRIND
testing.  Apparently we managed to store another Bitmapset into the
freed space before trying to access it, but you'd not think that would
happen 100% of the time.  I think what USE_VALGRIND changes is that it
makes list.c much more memory-hungry, so that the freed space gets
claimed by some List node before a Bitmapset can be put there.

This failure can be seen in v16, v17, and master, but oddly enough not
v18.  That's because the SJE patch replaced the simple bms_del_members
calls used here with adjust_relid_set, which is careful not to
scribble on its input.  But commit 20efbdffe just recently put back
the old coding and thus resurrected the problem.

Discussion: https://postgr.es/m/458729.1776724816@sss.pgh.pa.us
Backpatch-through: 16, 17, master

3 weeks agoFix callers of unicode_strtitle() using srclen == -1.
Jeff Davis [Mon, 20 Apr 2026 21:44:08 +0000 (14:44 -0700)] 
Fix callers of unicode_strtitle() using srclen == -1.

Currently, only called that way in tests, which failed to fail.

Discussion: https://postgr.es/m/581a72ff452bb045ba83bbe3c6cf4467702d4f0f.camel@j-davis.com
Backpatch-through: 18

3 weeks agostyle: define parameterless functions as foo(void).
Jeff Davis [Mon, 20 Apr 2026 21:42:54 +0000 (14:42 -0700)] 
style: define parameterless functions as foo(void).

Avoids warning in 'update-unicode' build target. Similar to
11171fe1fc.

Discussion: https://postgr.es/m/581a72ff452bb045ba83bbe3c6cf4467702d4f0f.camel@j-davis.com

3 weeks agodoc: Fix missing role attribute in pg_get_tablespace_ddl() description.
Masahiko Sawada [Mon, 20 Apr 2026 20:31:13 +0000 (13:31 -0700)] 
doc: Fix missing role attribute in pg_get_tablespace_ddl() description.

The second function signature entry for pg_get_tablespace_ddl() was
missing the role="func_signature" attribute. This commit adds the
missing attribute to ensure consistent formatting with other function
entries.

Author: Tatsuya Kawata <kawatatatsuya0913@gmail.com>
Discussion: https://postgr.es/m/CAHza6qcSgwdh+f41zEm6NSaGHvs5_cwjVu22+KTic=TfnonrFA@mail.gmail.com

3 weeks agoClean up all relid fields of RestrictInfos during join removal.
Tom Lane [Mon, 20 Apr 2026 18:48:23 +0000 (14:48 -0400)] 
Clean up all relid fields of RestrictInfos during join removal.

The original implementation of remove_rel_from_restrictinfo()
thought it could skate by with removing no-longer-valid relid
bits from only the clause_relids and required_relids fields.
This is quite bogus, although somehow we had not run across a
counterexample before now.  At minimum, the left_relids and
right_relids fields need to be fixed because they will be
examined later by clause_sides_match_join().  But it seems
pretty foolish not to fix all the relid fields, so do that.

This needs to be back-patched as far as v16, because the
bug report shows a planner failure that does not occur
before v16.  I'm a little nervous about back-patching,
because this could cause unexpected plan changes due to
opening up join possibilities that were rejected before.
But it's hard to argue that this isn't a regression.  Also,
the fact that this changes no existing regression test results
suggests that the scope of changes may be fairly narrow.
I'll refrain from back-patching further though, since no
adverse effects have been demonstrated in older branches.

Bug: #19460
Reported-by: François Jehl <francois.jehl@pigment.com>
Author: Tom Lane <tgl@sss.pgh.pa.us>
Reviewed-by: Richard Guo <guofenglinux@gmail.com>
Discussion: https://postgr.es/m/19460-5625143cef66012f@postgresql.org
Backpatch-through: 16

3 weeks agoMake ExecForPortionOfLeftovers() obey SRF protocol.
Tom Lane [Mon, 20 Apr 2026 14:21:52 +0000 (10:21 -0400)] 
Make ExecForPortionOfLeftovers() obey SRF protocol.

Before each call to the SRF, initialize isnull and isDone, as per the
comments for struct ReturnSetInfo.  This fixes a Coverity warning
about rsi.isDone not being initialized.  The built-in
{multi,}range_minus_multi functions don't return without setting it,
but a user-supplied function might not be as accommodating.

We also add statistics tracking around the function call, which
will be expected once user-defined withoutPortionProcs functions
are supported, and a cross-check on rsi.returnMode just for
paranoia's sake.

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