]> git.ipfire.org Git - thirdparty/postgresql.git/log
thirdparty/postgresql.git
2 weeks agoDon't cast off_t to 32-bit type for output, bug fix
Peter Eisentraut [Wed, 1 Jul 2026 07:39:42 +0000 (09:39 +0200)] 
Don't cast off_t to 32-bit type for output, bug fix

off_t is most likely a 64-bit integer, so casting it to a 32-bit type
for output could lose data.  There are more issues like this in the
tree, but this is an instance where this could actually happen in
practice, since base backups are routinely larger than 4 GB.  So this
is separated out as a bug fix.

Reviewed-by: Heikki Linnakangas <hlinnaka@iki.fi>
Discussion: https://www.postgresql.org/message-id/flat/20ce62fa-47fc-457b-b504-12f3c1651726%40eisentraut.org

2 weeks agoUse C11 alignas instead of pg_attribute_aligned
Peter Eisentraut [Mon, 29 Jun 2026 08:46:51 +0000 (10:46 +0200)] 
Use C11 alignas instead of pg_attribute_aligned

Replace pg_attribute_aligned with C11 alignas, for consistency with
current conventions.

(These new uses were added by commit fbc57f2bc2e, which was developed
concurrently with the switch from pg_attribute_aligned to C11 standard
alignas, and it ended up being committed with the "old" style.)

Reviewed-by: John Naylor <johncnaylorls@gmail.com>
Discussion: https://postgr.es/m/CANWCAZaKhE+RD5KKouUFoxx1EbUNrNhcduM1VQ=DkSDadNEFng@mail.gmail.com

2 weeks agoImprove UNION's output row count estimate
Richard Guo [Wed, 1 Jul 2026 06:12:43 +0000 (15:12 +0900)] 
Improve UNION's output row count estimate

A UNION (not UNION ALL) removes duplicates, so its output has no more
rows than its input.  The planner did not account for this: it set the
set-op relation's row count to the total size of the appended input,
as though dedup removed nothing.  That inflated estimate then
propagated to every node above the UNION, leading to poor plan choices
such as a hash join with a full table scan where an index nested loop
would have been cheaper.

This patch estimates the number of distinct output rows as the sum of
the per-child distinct-group estimates instead.  This relies on the
fact that:

  distinct(A union B) <= distinct(A) + distinct(B)

that is, the union cannot have more distinct rows than its children do
in total.  And because each child's distinct-group estimate never
exceeds that child's row-count estimate, this sum is never larger than
the old estimate, so it only tightens the previous over-estimate.

Author: Richard Guo <guofenglinux@gmail.com>
Reviewed-by: David Rowley <dgrowleyml@gmail.com>
Reviewed-by: Chengpeng Yan <chengpeng_yan@outlook.com>
Discussion: https://postgr.es/m/CAMbWs48Fu1nhGXPa60oc+adj7ge4dn0nHhqngqKvOVVQP61duA@mail.gmail.com

2 weeks agoAvoid useless calls in pg_get_multixact_stats()
Michael Paquier [Wed, 1 Jul 2026 03:17:17 +0000 (12:17 +0900)] 
Avoid useless calls in pg_get_multixact_stats()

MultiXactOffsetStorageSize() and GetMultiXactInfo() are called to gather
the information reported by the function, but were wasteful for the case
where a role does not have the privileges of pg_read_all_stats, where we
return a set of NULLs.  These calls are moved to the code path where
their results are used.

Author: Ranier Vilela <ranier.vf@gmail.com>
Discussion: https://postgr.es/m/CAEudQAonQh7be=wOR-CJFW=bgMBz5wW_bv4t0OFxbgn-794JCQ@mail.gmail.com
Backpatch-through: 19

2 weeks agoDocument wal_compression=on
John Naylor [Wed, 1 Jul 2026 01:50:08 +0000 (08:50 +0700)] 
Document wal_compression=on

Commit 4035cd5d4 added LZ4 compression for full-page writes in WAL, and
retained "on" as a backward-compatible way to specify the builtin PGLZ
method. Document this meaning of "on" and update postgresql.conf.sample
to make the equivalence clear.

Author: Christoph Berg <myon@debian.org>
Reviewed-by: Michael Paquier <michael@paquier.xyz>
Discussion: https://postgr.es/m/akJDHRtXwGLTppsQ@msg.df7cb.de
Backpatch-through: 15

2 weeks agodoc: Add new section describing fast-path locking
Michael Paquier [Wed, 1 Jul 2026 01:08:26 +0000 (10:08 +0900)] 
doc: Add new section describing fast-path locking

Fast-path locking is referenced by pg_stat_lock.fastpath_exceeded, by
pg_locks.fastpath, and in the GUC max_locks_per_transaction.  However,
the documentation has never described in details how this works; one
would need to look at the internals of lock.c, mostly around
EligibleForRelationFastPath().

This commit adds a new subsection called "Fast-Path Locking" to the area
dedicated to locks, with the three places mentioned above linking to it.

Author: Tatsuya Kawata <kawatatatsuya0913@gmail.com>
Reviewed-by: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by: Michael Paquier <michael@paquier.xyz>
Discussion: https://postgr.es/m/CAHza6qdKo9dcPy70QBi88vpqhS2gYWViS8=Uj=-+QQbR=ONgSQ@mail.gmail.com

2 weeks agoRemove radius from initdb authentication methods.
Thomas Munro [Tue, 30 Jun 2026 23:25:37 +0000 (11:25 +1200)] 
Remove radius from initdb authentication methods.

Commit a1643d40b removed RADIUS authentication, but apparently
overlooked initdb's list of accepted authentication methods.  As a
result, initdb still accepted radius for --auth, --auth-host, and
--auth-local, allowing it to create a pg_hba.conf that the server could
not load.

Remove radius from initdb's local and host authentication method lists.

Backpatch-through: 19
Author: Chao Li <lic@highgo.com>
Discussion: https://postgr.es/m/983F946B-A7CE-4C93-B5F0-665616F72254%40gmail.com

2 weeks agoDisallow set-returning functions within window OVER clauses.
Tom Lane [Tue, 30 Jun 2026 21:21:23 +0000 (17:21 -0400)] 
Disallow set-returning functions within window OVER clauses.

We previously allowed this, but it leads to odd behaviors, basically
because putting a SRF there is inconsistent with the principle that a
window function doesn't change the number of rows in the query result.
There doesn't seem to be a strong reason to try to make such cases
behave consistently.  Users should put their SRFs in lateral FROM
clauses instead.

This issue has been sitting on the back burner for multiple years
now, partially because it didn't seem wise to back-patch such a
change.  Let's squeeze it into v19 before it's too late.

Bug: #17502
Bug: #19535
Reported-by: Daniel Farkaš <daniel.farkas@datoris.com>
Reported-by: Qifan Liu <imchifan@163.com>
Author: Tom Lane <tgl@sss.pgh.pa.us>
Reviewed-by: David Rowley <dgrowleyml@gmail.com>
Discussion: https://postgr.es/m/17502-281a7aaacfaa872a@postgresql.org
Discussion: https://postgr.es/m/19535-376081d7cc07c86d@postgresql.org
Backpatch-through: 19

2 weeks agodoc: clarify MERGE PARTITIONS adjacency requirement
Alexander Korotkov [Tue, 30 Jun 2026 19:29:43 +0000 (22:29 +0300)] 
doc: clarify MERGE PARTITIONS adjacency requirement

The existing description says the ranges of merged range-partitions
"must be adjacent" only under the heading "If the DEFAULT partition is
not in the list of merged partitions".  That could be misread as
a restriction tied to the presence of a default partition.  In fact,
merging non-adjacent ranges is rejected regardless of whether
the partitioned table has a default partition; spell that out explicitly.

Also, this commit removes a small redundancy in the documentation sentence
stating that "merged range-partitions" are "to be merged".

Reported-by: Justin Pryzby <pryzby@telsasoft.com>
Discussion: https://postgr.es/m/aj6BPoziSb-F8aJz%40pryzbyj2023
Reported-by: Pavel Borisov <pashkin.elfe@gmail.com>
Backpatch-through: 19

2 weeks agoClean up inconsistencies in CPU-identification macros.
Tom Lane [Tue, 30 Jun 2026 16:21:06 +0000 (12:21 -0400)] 
Clean up inconsistencies in CPU-identification macros.

In various places we depend on compiler-defined macros like __x86_64__
to guard CPU-type-specific code.  However, those macros aren't very
well standardized; in particular, it emerges that MSVC doesn't define
any of the ones gcc does, but has its own.  We were not coping with
that consistently, with the result that we're missing some useful
CPU-dependent optimizations in MSVC builds.  There are also some
places that are checking randomly-different spellings that may
have been the only ones recognized by some old compilers, but we
weren't doing that consistently either.

Let's standardize on using gcc's long-form spellings (with trailing
underscores), after putting a stanza into c.h that ensures that these
spellings are defined even when the compiler provides some other one.

I put an "#else #error" branch into the c.h addition so that we'll
get an error if the compiler provides none of the symbols we're
expecting.  That might be best removed in the end, since it might
annoy people trying to port to some new CPU type.  But for testing
this it seems like a good idea, in case we've missed some common
variant spelling.

In addition to enabling some optimizations we previously missed on
MSVC, this cleans up a thinko.  Several places used "_M_X64" in the
apparent belief that that's MSVC's equivalent to __x86_64__, but
it's not: it will also get defined on some but not all ARM64 builds.

Also, guard the x86_feature_available() stuff in pg_cpu.[hc] with
#if defined(__x86_64__) || defined(__i386__)
which seems like a more natural way of specifying what it applies to.

This builds on some previous work by Thomas Munro, but it requires
much less code churn because it re-uses gcc's names for the CPU-type
macros instead of inventing our own.

Author: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/CA+hUKGL8Hs-phHPugrWM=5dAkcT897rXyazYzLw-Szxnzgx-rA@mail.gmail.com
Discussion: https://postgr.es/m/3035145.1780503430@sss.pgh.pa.us

2 weeks agoRemove pg_spin_delay().
Nathan Bossart [Tue, 30 Jun 2026 15:57:54 +0000 (10:57 -0500)] 
Remove pg_spin_delay().

This code appears to be an artifact from commit b64d92f1a5 that was
never used for anything.

Reviewed-by: Corey Huinker <corey.huinker@gmail.com>
Discussion: https://postgr.es/m/afouZUH_eUkIj4i4%40nathan

2 weeks agoMake SPI_prepare argtypes argument const
Peter Eisentraut [Tue, 30 Jun 2026 13:43:56 +0000 (15:43 +0200)] 
Make SPI_prepare argtypes argument const

This changes the argtypes argument of SPI_prepare(),
SPI_prepare_cursor(), SPI_cursor_open_with_args(), and
SPI_execute_with_args() from Oid *argtypes to const Oid *argtypes.
The underlying functions were already receptive to that, so this
doesn't require any significant changes beyond the function signatures
and some internal variables.

Commit 28972b6fc3dc recently introduced a case where a const had to be
cast away before calling these functions.  This is fixed here.

In passing, make a very similar const addition to SPI_modifytuple().

Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Reviewed-by: Ewan Young <kdbase.hack@gmail.com>
Discussion: https://www.postgresql.org/message-id/flat/86b5162f-c472-40fa-997b-0450dece1dec%40eisentraut.org

2 weeks agoFixes for SPI "const Datum *" use
Peter Eisentraut [Tue, 30 Jun 2026 12:03:10 +0000 (14:03 +0200)] 
Fixes for SPI "const Datum *" use

Fixup for commit 8a27d418f8f, which converted many functions to use
"const Datum *" instead of "Datum *", including some SPI functions.

For SPI_cursor_open(), the code was updated but not the documentation.
For SPI_cursor_open_with_args(), the documentation was updated but not
the code.  (Possibly, these two were confused with each other.)  Also,
SPI_execp() and SPI_modifytuple() were not updated, even though they
are closely related to the functions touched by the previous commit
and now look inconsistent.  Fix all these.

Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://www.postgresql.org/message-id/flat/86b5162f-c472-40fa-997b-0450dece1dec%40eisentraut.org

2 weeks agoAdd backend-level lock statistics
Michael Paquier [Tue, 30 Jun 2026 07:59:20 +0000 (16:59 +0900)] 
Add backend-level lock statistics

This commit adds per-backend lock statistics, providing the same
information as pg_stat_lock.  It is now possible to retrieve those stats
(lock wait counts, wait times, and fast-path exceeded count) on a
per-backend basis.

This data can be retrieved with a new system function called
pg_stat_get_backend_lock(), that returns one tuple per lock type based
on the PID provided in input.  Like pg_stat_get_backend_io(), this is
useful if joined with pg_stat_activity to get a live picture of the
locks behavior for each running backend.

pgstat_flush_backend() gains a new flag value, able to control the flush
of the lock stats.

This commit is straight-forward, relying on the infrastructure provided
by 9aea73fc61d4 (backend-level pgstats).

Bump catalog version.  No need to touch PGSTAT_FILE_FORMAT_ID as backend
statistics are never written to disk.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by: Tatsuya Kawata <kawatatatsuya0913@gmail.com>
Reviewed-by: Michael Paquier <michael@paquier.xyz>
Reviewed-by: Tristan Partin <tristan@partin.io>
Reviewed-by: Rui Zhao <zhaorui126@gmail.com>
Discussion: https://postgr.es/m/aiAzEY+cMQb/W8yu@bdtpg

2 weeks agoRefactor pg_stat_get_lock() to use a helper function
Michael Paquier [Tue, 30 Jun 2026 07:24:34 +0000 (16:24 +0900)] 
Refactor pg_stat_get_lock() to use a helper function

This commit extracts the tuple-building logic from pg_stat_get_lock()
into a new static helper pg_stat_lock_build_tuples().  This is in
preparation for a follow-up patch, to add support for backend-level lock
stats, which will reuse the same helper.

This change follows the pattern established by pg_stat_io_build_tuples()
for IO stats and pg_stat_wal_build_tuple() for WAL stats.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by: Tatsuya Kawata <kawatatatsuya0913@gmail.com>
Reviewed-by: Michael Paquier <michael@paquier.xyz>
Reviewed-by: Tristan Partin <tristan@partin.io>
Reviewed-by: Rui Zhao <zhaorui126@gmail.com>
Discussion: https://postgr.es/m/aiAzEY+cMQb/W8yu@bdtpg

2 weeks agoUse placeholders and not GUC names in error message (autovacuum)
Michael Paquier [Tue, 30 Jun 2026 07:16:56 +0000 (16:16 +0900)] 
Use placeholders and not GUC names in error message (autovacuum)

A placeholder %s is now used instead of the GUC names in the error
string of this routine.  This is going to be useful for a follow-up
patch, where we will be able to reuse the same string, hence reducing
the translation work.

Based on a suggestion by me.

Author: Baji Shaik <baji.pgdev@gmail.com>
Discussion: https://postgr.es/m/ajnhfw84reaXgjfO@paquier.xyz

2 weeks agoChange stat_lock.wait_time to double precision
Michael Paquier [Tue, 30 Jun 2026 03:47:34 +0000 (12:47 +0900)] 
Change stat_lock.wait_time to double precision

Other statistics views (pg_stat_io, pg_stat_database, etc.) use float8
for all measured-time columns, the new pg_stat_lock standing out as an
outlier by using bigint.

This commit aligns pg_stat_lock with the other stats views for
consistency.  Like pg_stat_io, the time is stored in microseconds, and
is displayed in milliseconds with a conversion done when the view is
queried.

While on it, replace a use of "long" by PgStat_Counter, the former could
overflow for large wait times where sizeof(long) is 4 bytes (aka WIN32).

Bump catalog version.

Author: Tatsuya Kawata <kawatatatsuya0913@gmail.com>
Reviewed-by: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by: Michael Paquier <michael@paquier.xyz>
Discussion: https://postgr.es/m/CAHza6qerEiQehrbW5xaXyxvR0qJe3KBX1R4kocDz1+7Ygu8x-g@mail.gmail.com
Backpatch-through: 19

2 weeks agoRestore comment at appendShellString().
Noah Misch [Tue, 30 Jun 2026 02:41:09 +0000 (19:41 -0700)] 
Restore comment at appendShellString().

Commit b380a56a3f9556588a89013b765d67947d54f7d0 removed a paragraph, but
two of the paragraph's three sentences remained relevant.

Backpatch-through: 19

2 weeks agobufmgr: Fix race in LockBufferForCleanup()
Fujii Masao [Tue, 30 Jun 2026 01:30:47 +0000 (10:30 +0900)] 
bufmgr: Fix race in LockBufferForCleanup()

LockBufferForCleanup() acquires the exclusive content lock, checks the
buffer's shared pin count, and, if other pins remain, registers itself
as the BM_PIN_COUNT_WAITER before waiting for an unpin notification.

Since commits 5310fac6e0f and c75ebc657ffc, however, a shared buffer
pin can be released while BM_LOCKED is set, introducing the following
race:

- LockBufferForCleanup() observes a refcount greater than one.
- Before it sets BM_PIN_COUNT_WAITER, another backend releases the
  last conflicting pin.
- Since BM_PIN_COUNT_WAITER is not yet set, no wakeup is sent.
- LockBufferForCleanup() then sets BM_PIN_COUNT_WAITER and goes to
  sleep, even though only its own pin remains.

As a result, LockBufferForCleanup() can sleep indefinitely because
the wakeup corresponding to the last conflicting unpin has already been
missed.

Fix this by setting BM_PIN_COUNT_WAITER while holding the buffer
header lock, then rechecking the refcount before releasing the content
lock. If only our pin remains, clear the waiter state and proceed
without sleeping. Otherwise, wait as before.

This issue was reported by buildfarm member skink, where it manifested
as intermittent timeouts in 048_vacuum_horizon_floor.pl.

Backpatch to v19, where commits 5310fac6e0f and c75ebc657ffc
introduced the race.

Reported-by: Alexander Lakhin <exclusion@gmail.com>
Author: Xuneng Zhou <xunengzhou@gmail.com>
Reviewed-by: Andres Freund <andres@anarazel.de>
Reviewed-by: Fujii Masao <masao.fujii@gmail.com>
Discussion: https://postgr.es/m/7685519a-0bf9-4e17-93ca-7e3aa10fa29c@gmail.com
Backpatch-through: 19

2 weeks agoRemove stray blank line in ParseFuncOrColumn()
Fujii Masao [Tue, 30 Jun 2026 01:28:52 +0000 (10:28 +0900)] 
Remove stray blank line in ParseFuncOrColumn()

Commit 419ce13b701 accidentally left a stray blank line in
ParseFuncOrColumn(). Remove it.

No functional change.

Author: Henson Choi <assam258@gmail.com>
Discussion: https://postgr.es/m/CAAAe_zDLBkZFXXCgR_-NuaeW+aUXUtuDoSgg-2QRz+b2g7G4BA@mail.gmail.com
Backpatch-through: 19

2 weeks agoFix unlogged sequence corruption after standby promotion
Fujii Masao [Mon, 29 Jun 2026 23:48:47 +0000 (08:48 +0900)] 
Fix unlogged sequence corruption after standby promotion

Previously, if an unlogged sequence was created on the primary and
replicated to a standby, reading the sequence after promoting the
standby (for example, with nextval()) could trigger the following
assertion failure:

    TRAP: failed Assert("((const PageHeaderData *) page)->pd_special >= SizeOfPageHeaderData")

In non-assert builds, the same operation could instead fail with an
error such as:

    ERROR:  bad magic number in sequence

The problem was that seq_redo() updated the init fork page in shared
buffers but did not flush it to disk. During promotion,
ResetUnloggedRelations() recreates the main fork of unlogged
relations by copying the init fork from disk, bypassing shared
buffers. As a result, the main fork could be recreated from a stale
init fork instead of the WAL-replayed page.

Fix this by introducing a helper to flush init fork buffers
immediately, and make seq_redo() use it. As a result, the main fork
of an unlogged sequence is recreated from the up-to-date init fork on
disk, allowing the unlogged sequence to be read successfully after
standby promotion.

Backpatch to v15, where unlogged sequences were introduced.

Author: Fujii Masao <masao.fujii@gmail.com>
Reviewed-by: vignesh C <vignesh21@gmail.com>
Discussion: https://postgr.es/m/CAHGQGwH1Ssze3XM6wjoTjSLVOR041c6xP+vsdLP951=w8oG8bA@mail.gmail.com
Backpatch-through: 15

2 weeks agoSimplify some stats restore code with InputFunctionCallSafe()
Michael Paquier [Mon, 29 Jun 2026 23:30:08 +0000 (08:30 +0900)] 
Simplify some stats restore code with InputFunctionCallSafe()

statatt_build_stavalues() and array_in_safe() have been relying on
InitFunctionCallInfoData() with a locally-filled state to call a data
type input function.  InputFunctionCallSafe() can be used to achieve the
same job, simplifying some code.

This fixes an over-allocation of FunctionCallInfoBaseData done in
statatt_build_stavalues(), where there was space for 8 elements but only
3 were needed.  The over-allocation exists since REL_18_STABLE, and was
harmless in practice.

While on it, fix some comments for both routines, where elemtypid was
mentioned.

Backpatch down to v19.  This code has been reworked during the last
development cycle while working on the restore of extended statistics,
so this keeps the code consistent across all branches.

Author: Jian He <jian.universality@gmail.com>
Author: Michael Paquier <michael@paquier.xyz>
Discussion: https://postgr.es/m/CACJufxEGah9PaiTQ=cG14GMMBsUQ3ohGct9tdSwbMQPQ0-nbbQ@mail.gmail.com
Backpatch-through: 19

2 weeks agoStamp HEAD as 20devel.
Joe Conway [Mon, 29 Jun 2026 20:29:11 +0000 (16:29 -0400)] 
Stamp HEAD as 20devel.

Let the hacking begin ...

2 weeks agoAdd previous 2 commits to .git-blame-ignore-revs.
Joe Conway [Mon, 29 Jun 2026 19:33:52 +0000 (15:33 -0400)] 
Add previous 2 commits to .git-blame-ignore-revs.

2 weeks agoRun pgperltidy
Joe Conway [Mon, 29 Jun 2026 19:27:44 +0000 (15:27 -0400)] 
Run pgperltidy

This is required before the creation of a new branch.  pgindent is
clean, as well as is reformat-dat-files.

perltidy version is v20230309, as documented in pgindent's README.

2 weeks agoSync typedefs.list with the buildfarm.
Joe Conway [Mon, 29 Jun 2026 19:16:25 +0000 (15:16 -0400)] 
Sync typedefs.list with the buildfarm.

Replace typedefs.list with the authoritative list from our buildfarm, and
run pgindent using that.

2 weeks agoFix typo
Peter Eisentraut [Mon, 29 Jun 2026 14:15:13 +0000 (16:15 +0200)] 
Fix typo

from commit c1fe2d1a383

2 weeks agoForbid FOR PORTION OF with WHERE CURRENT OF
Peter Eisentraut [Mon, 29 Jun 2026 13:13:45 +0000 (15:13 +0200)] 
Forbid FOR PORTION OF with WHERE CURRENT OF

It is not clear how the implicit condition of FOR PORTION OF should
interact with the use of a cursor.  Normally, we forbid combining
WHERE CURRENT OF with other WHERE conditions.  The SQL standard only
includes FOR PORTION OF with <update statement: searched> and <delete
statement: searched>, not <update statement: positioned> or <delete
statement: positioned>, so it is easy for us to exclude the
functionality, at least for now.

Author: Paul A. Jungwirth <pj@illuminatedcomputing.com>
Discussion: https://www.postgresql.org/message-id/flat/CA%2BrenyUEKPexUYsH4qeU8_o1jqKsUkEWca1keS6n21shgG1g%2BA%40mail.gmail.com

2 weeks agoFix handling of copy_file_range() return value
Peter Eisentraut [Mon, 29 Jun 2026 09:49:11 +0000 (11:49 +0200)] 
Fix handling of copy_file_range() return value

Treat copy_file_range() return value of zero as an error: it indicates
that no bytes could be copied (perhaps the source file is shorter than
expected), and the existing retry loop would otherwise spin forever
since nwritten would never reach BLCKSZ.

The other uses of copy_file_range() in the tree don't have this
problem.

Reviewed-by: Nazir Bilal Yavuz <byavuz81@gmail.com>
Reviewed-by: Kyotaro Horiguchi <horikyota.ntt@gmail.com>
Reviewed-by: Yingying Chen <cyy9255@gmail.com>
Discussion: https://www.postgresql.org/message-id/flat/3208cf7a-c7f3-41eb-92f6-33cbeff4df40%40eisentraut.org

2 weeks agodoc: Reorder table for Object DDL Functions
Michael Paquier [Mon, 29 Jun 2026 04:15:07 +0000 (13:15 +0900)] 
doc: Reorder table for Object DDL Functions

While on it, let's add links pointing to the set of SQL commands
generated by these functions.  The descriptions of the functions are
exactly the same, just moved around.

Author: Peter Smith <smithpb2250@gmail.com>
Reviewed-by: Ian Lawrence Barwick <barwick@gmail.com>
Discussion: https://postgr.es/m/CAHut+Pun9Z8qZFJTa9fLgdhM=Cip9d-cnx2YXDW6eFrSwbQj1g@mail.gmail.com

2 weeks agoplpython: Fix NULL pointer dereferences for broken sequence and mapping objects
Richard Guo [Mon, 29 Jun 2026 02:38:39 +0000 (11:38 +0900)] 
plpython: Fix NULL pointer dereferences for broken sequence and mapping objects

PL/Python and its hstore and jsonb transforms build SQL values from
Python containers by calling Python C API functions that can return
NULL, and in several places the result was used without first checking
it.

On the sequence side, PySequence_GetItem() is used when converting a
returned sequence into a SQL array or composite value, when reading
the argument list passed to plpy.execute() or plpy.cursor(), and when
reading the list of type names given to plpy.prepare().  On the
mapping side, the hstore and jsonb transforms call PyMapping_Size()
and PyMapping_Items() and then index the result with PyList_GetItem()
and PyTuple_GetItem().

All of these return NULL (or -1), with a Python exception set, for a
broken object: for example one whose __getitem__() or items() raises,
or which reports a length that disagrees with what it actually yields.
The unchecked result was then dereferenced, crashing the backend.

Fix this by checking the result of each call and reporting a regular
error if it failed, so that the underlying Python exception is
surfaced instead of taking down the session.

Author: Richard Guo <guofenglinux@gmail.com>
Reviewed-by: Ayush Tiwari <ayushtiwari.slg01@gmail.com>
Discussion: https://postgr.es/m/CAMbWs49BKM9wP6m8bCXEpHwQKp7usvOGV6Jf=J7FYr_BCpxLqg@mail.gmail.com
Backpatch-through: 14

2 weeks agoHardwire RI fast-path end-of-xact cleanup into xact.c
Amit Langote [Mon, 29 Jun 2026 01:24:28 +0000 (10:24 +0900)] 
Hardwire RI fast-path end-of-xact cleanup into xact.c

Commit b7b27eb41a5, which added foreign-key fast-path batching to
ri_triggers.c, registered ri_FastPathXactCallback() via
RegisterXactCallback() to clear the fast-path batching state at end of
transaction.  RegisterXactCallback() is documented as intended for
dynamically loaded modules; built-in code is supposed to hardwire its
end-of-xact hooks into xact.c, mainly so callback ordering can be
controlled where it matters (see the header comment on
RegisterXactCallback()).

Convert the callback into a plain AtEOXact_RI() function and call it
directly from CommitTransaction(), PrepareTransaction() and
AbortTransaction(), alongside the other AtEOXact_* cleanup steps, and
drop the RegisterXactCallback() registration.

Like the other AtEOXact_* routines, AtEOXact_RI() takes an isCommit
argument and treats the two paths differently.  On commit or prepare
the fast-path cache must already have been flushed and torn down by
the after-trigger batch callback, so a surviving cache indicates a
trigger batch was never flushed -- which would have silently skipped
FK checks -- and draws an Assert plus a WARNING.  On abort a surviving
cache is expected (a flush may have errored out partway) and is simply
reset.

There is no ordering dependency here: AtEOXact_RI() only resets
backend-local static state (the cache pointer, the
callback-registered flag, and the in-flush guard).  It touches no
relations, locks, buffers or catalogs, so its position relative to
ResourceOwnerRelease() and the surrounding AtEOXact_* calls does not
matter.  On a normal commit the fast-path cache has already been
flushed and torn down by ri_FastPathEndBatch() (an
AfterTriggerBatchCallback fired from AfterTriggerFireDeferred(), well
before any end-of-xact callback), so the reset is a no-op; its real
job is the abort path, where teardown may not have run and the static
pointers would otherwise dangle into the next transaction.  The cache
memory itself lives in TopTransactionContext and is freed by the
end-of-transaction memory-context reset on both paths.

The companion RegisterSubXactCallback() use from b7b27eb41a5 was
already removed by commit 4113873a, which confined fast-path batching
to the top transaction level, so only the RegisterXactCallback() use
remained.

Reported-by: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Discussion: https://postgr.es/m/ajypPeEWceXRGAEW@bdtpg

2 weeks agodoc: Improve consistency in varlistentry attributes
Daniel Gustafsson [Sun, 28 Jun 2026 21:43:19 +0000 (23:43 +0200)] 
doc: Improve consistency in varlistentry attributes

Use underscores consistent across the varlistentry attributes in
config.sgml. Inconsistencies found using Claude, verified by the
reporter.

Reported-by: Bill Kim <billkimjh@gmail.com>
Reviewed-by: Peter Smith <smithpb2250@gmail.com>
Discussion: https://postgr.es/m/CAMQXxchB0ZfMHyk+Ji-=s3hkqh0_XyuKiaNLRgvatvndSt3KNw@mail.gmail.com

2 weeks agoAvoid collation lookup failure when considering a "char" column.
Tom Lane [Sun, 28 Jun 2026 16:31:29 +0000 (12:31 -0400)] 
Avoid collation lookup failure when considering a "char" column.

If a "char" column has a statistics histogram, scalarineqsel()
would fail with "cache lookup failed for collation 0".  Avoid
the failing lookup by acting as though the collation is "C".

Prior to commit 06421b084, this code didn't fail because
lc_collate_is_c() intentionally didn't spit up on InvalidOid.
It did act differently though: it would take the non-C-collation
code path and hence apply strxfrm using libc's prevailing locale.
But that seems like the wrong thing for a non-collatable comparison,
so let's not resurrect that aspect.

Author: Feng Wu <wufengwufengwufeng@gmail.com>
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/CACK3muq6s-O1Wc3w4dRL1Fe8YQ-Fz1zJbezeQwhuLgNxGNEFiA@mail.gmail.com
Backpatch-through: 18

2 weeks agoUse named boolean parameters for pg_get_*_ddl option arguments
Andrew Dunstan [Fri, 26 Jun 2026 12:00:39 +0000 (08:00 -0400)] 
Use named boolean parameters for pg_get_*_ddl option arguments

Replace the VARIADIC text[] alternating key/value option interface with
typed named boolean parameters for pg_get_role_ddl(), pg_get_tablespace_ddl(),
and pg_get_database_ddl(), as added by commit 4881981f920 and friends.
The new signatures are:

  pg_get_role_ddl(role regrole,
                  pretty boolean DEFAULT false,
                  memberships boolean DEFAULT true)

  pg_get_tablespace_ddl(tablespace oid/name,
                        pretty boolean DEFAULT false,
                        owner boolean DEFAULT true)

  pg_get_database_ddl(db regdatabase,
                      pretty boolean DEFAULT false,
                      owner boolean DEFAULT true,
                      tablespace boolean DEFAULT true)

This provides type safety at the SQL level, allows named-argument calling
syntax (pretty => true), removes the runtime string-parsing machinery
(DdlOption, parse_ddl_options) in favour of direct PG_GETARG_BOOL() calls,
and allows the functions to be marked STRICT.

While we're here, I added an extra TAP test for pg_get_database(owner =>
false, ...)

Catalog version bumped.

Author: Jelte Fennema-Nio <postgres@jeltef.nl>
Discussion: https://postgr.es/m/DHM6C7SLS4BN.1WW9Z4PRPN0VJ@jeltef.nl
(and on Discord)

2 weeks agopgindent fix for commit effb923d9de
Andrew Dunstan [Sat, 27 Jun 2026 23:57:41 +0000 (19:57 -0400)] 
pgindent fix for commit effb923d9de

2 weeks agodoc: Clarify ALTER CONSTRAINT enforceability behavior
Andrew Dunstan [Sat, 27 Jun 2026 21:43:02 +0000 (17:43 -0400)] 
doc: Clarify ALTER CONSTRAINT enforceability behavior

The ALTER TABLE documentation said that FOREIGN KEY and CHECK
constraints may be altered, but did not distinguish between
deferrability and enforceability attributes.

Clarify that deferrability attributes can currently be altered only for
FOREIGN KEY constraints, while enforceability can be altered for both
FOREIGN KEY and CHECK constraints.  Also document that setting a
constraint to ENFORCED verifies existing rows and resumes checking new
or updated rows.

Author: Chao Li <lic@highgo.com>
Reviewed-by: Zsolt Parragi <zsolt.parragi@percona.com>
Discussion: https://postgr.es/m/E74C57FA-1DD0-4C8E-8FB1-538034752592@gmail.com
Discussion: https://postgr.es/m/711B1ED3-1781-4B6C-A573-B58AF20770E5@gmail.com

2 weeks agodoc: Clarify inherited constraint behavior
Andrew Dunstan [Sat, 27 Jun 2026 21:43:02 +0000 (17:43 -0400)] 
doc: Clarify inherited constraint behavior

Update the table inheritance documentation to mention not-null constraints
alongside check constraints where inherited constraints are discussed.

Also clarify that some properties of inherited constraints can now be altered
directly on child tables, while the resulting constraint must remain compatible
with its inherited parent constraints.  For multiple inheritance, say explicitly
that when a column or constraint is inherited from more than one parent, the
stricter definition applies.

Author: Chao Li <lic@highgo.com>
Reviewed-by: Zsolt Parragi <zsolt.parragi@percona.com>
Discussion: https://postgr.es/m/E74C57FA-1DD0-4C8E-8FB1-538034752592@gmail.com

2 weeks agoPrevent inherited CHECK constraints from being weakened
Andrew Dunstan [Sat, 27 Jun 2026 21:42:51 +0000 (17:42 -0400)] 
Prevent inherited CHECK constraints from being weakened

Disallow marking an inherited CHECK constraint as NOT ENFORCED when an
equivalent parent constraint remains ENFORCED. This prevents ALTER
CONSTRAINT from producing a child constraint that is weaker than one of
its inherited parent definitions.

When recursively altering a CHECK constraint to NOT ENFORCED, collect the
corresponding constraints in the affected inheritance subtree and ignore
those parent constraints while checking descendants. If a descendant also
inherits an equivalent ENFORCED constraint from a parent outside the
current ALTER, keep the descendant ENFORCED by merging to the stricter
state.

This was missed in commit 342051d73b3, which introduced the ability to
alter CHECK constraint enforceability.

Add regression coverage for direct child ALTER, ONLY ALTER, mixed-parent
inheritance, and a common-ancestor diamond where all equivalent inherited
constraints can be changed together.

Author: Chao Li <lic@highgo.com>
Reviewed-by: Jian He <jian.universality@gmail.com>
Reviewed-by: Zsolt Parragi <zsolt.parragi@percona.com>
Reviewed-by: Álvaro Herrera <alvherre@kurilemu.de>
Discussion: https://postgr.es/m/E74C57FA-1DD0-4C8E-8FB1-538034752592@gmail.com

2 weeks agoCOPY TO FORMAT JSON: respect column list order
Andrew Dunstan [Sat, 27 Jun 2026 20:48:35 +0000 (16:48 -0400)] 
COPY TO FORMAT JSON: respect column list order

When COPY TO with FORMAT json is given an explicit column list that
names all columns in a different order, the JSON output incorrectly
used the table's physical column order instead of the requested order.

This happened because BeginCopyTo() only built a restricted TupleDesc
when list_length(attnumlist) < tupDesc->natts.  When all columns are
listed (just reordered), this condition was false and no projected
TupleDesc was built, causing CopyToJsonOneRow() to emit columns in
physical order.

Fix by also building the projected TupleDesc when an explicit column
list was provided (attnamelist != NIL), even if it names all columns.

Author: Baji Shaik <baji.pgdev@gmail.com>
Reviewed-by: Andrew Dunstan <andrew@dunslane.net>
Discussion: https://postgr.es/m/CA+fm-ROd4cNKM524n6EdgtZ9xOzOHJDNv8J_9Mvr2+2t1qWSDw@mail.gmail.com

2 weeks agoReject child partition FDWs in FOR PORTION OF
Peter Eisentraut [Sat, 27 Jun 2026 17:34:40 +0000 (19:34 +0200)] 
Reject child partition FDWs in FOR PORTION OF

We should defer validating FDW usage until after analysis.  We have to
guard against not just the topmost table, but also individual child
partitions.  Added the check to CheckValidResultRel, because it is
called after looking up child partitions (accounting for pruning), but
before the FDW can run a DirectModify update, which would bypass
per-tuple executor work.

Author: jian he <jian.universality@gmail.com>
Reported-by: Tom Lane <tgl@sss.pgh.pa.us>
Reviewed-by: Paul A. Jungwirth <pj@illuminatedcomputing.com>
Discussion: https://www.postgresql.org/message-id/flat/CA%2BrenyUte0_UJsJiDJQi82oaBsMJn%3Dcct0Wn%3DvOqXtuDn%3DYYJA%40mail.gmail.com

2 weeks agoMove FOR PORTION OF volatile check into planner
Peter Eisentraut [Sat, 27 Jun 2026 07:07:07 +0000 (09:07 +0200)] 
Move FOR PORTION OF volatile check into planner

This needs to be wary of the function volatility changing after we
check it.  We cannot enforce this when checking at parse time, so move
it later, into the planner.

Author: Paul A. Jungwirth <pj@illuminatedcomputing.com>
Reported-by: Tom Lane <tgl@sss.pgh.pa.us>
Reviewed-by: jian he <jian.universality@gmail.com>
Discussion: https://www.postgresql.org/message-id/flat/CA%2BrenyUte0_UJsJiDJQi82oaBsMJn%3Dcct0Wn%3DvOqXtuDn%3DYYJA%40mail.gmail.com

2 weeks agoSwitch maximum of GUC huge_page_size to MAX_KILOBYTES
Michael Paquier [Sat, 27 Jun 2026 02:45:56 +0000 (11:45 +0900)] 
Switch maximum of GUC huge_page_size to MAX_KILOBYTES

As documented in guc.h, MAX_KILOBYTES is used to cap GUC parameters that
are measured in kilobytes of memory.  This way, size_t values can fit in
builds where sizeof(size_t) is 4 bytes.

Unfortunately, huge_page_size has missed this aspect, causing
calculation failures when setting this GUC to a value higher than
MAX_KILOBYTES, up to INT_MAX.

Oversight in d2bddc2500fb.  No backpatch is done, based on the lack of
complaints.

Reported-by: Daria Shanina <vilensipkdm@gmail.com>
Reviewed-by: Kyotaro Horiguchi <horikyota.ntt@gmail.com>
Discussion: https://postgr.es/m/20260626.132415.904994526137946499.horikyota.ntt@gmail.com

2 weeks agoMake crosstabview honor boolean/null display settings
Álvaro Herrera [Fri, 26 Jun 2026 18:03:42 +0000 (20:03 +0200)] 
Make crosstabview honor boolean/null display settings

psql's \pset display_true/false settings, added by commit 645cb44c5490,
affect normal query output, but not \crosstabview.  As a result, boolean
values used anywhere in crosstab output were always shown as "t" or "f",
which is inconsistent.  Change \crosstabview so that the configured
values are displayed instead.

While at it, make \crosstabview print the \pset null string, if any, in
cells for which the query produces a NULL value.  Cells for which the
query produces no value continue to have the empty string.  This is an
oversight in the aboriginal \crosstabview commit, c09b18f21c52.

Add a regression test covering all of this.

Author: Chao Li <lic@highgo.com>
Reported-by: Chao Li <lic@highgo.com>
Reviewed-by: David G. Johnston <david.g.johnston@gmail.com>
Reviewed-by: Álvaro Herrera <alvherre@kurilemu.de>
Backpatch: none needed
Discussion: https://postgr.es/m/B5E6F0A5-4B48-46D0-B5EB-CF8F8CC7D07D@gmail.com

2 weeks agoFix out-of-bounds access in autoprewarm worker
Tomas Vondra [Fri, 26 Jun 2026 17:34:14 +0000 (19:34 +0200)] 
Fix out-of-bounds access in autoprewarm worker

The read stream callback apw_read_stream_next_block() advances p->pos
through the block_info array. When processing the last block, it
increments p->pos to prewarm_stop_idx before returning. The callback
itself is safe because it checks bounds before accessing the array.

However, the caller assigned blk from block_info[i] at the end of the
loop body, before the loop condition was re-evaluated. When i equaled
prewarm_stop_idx, this accessed memory beyond the allocated DSM segment,
causing a segfault.

Restructure the loop to check bounds at the top and assign blk at the
beginning of the loop body, where it is always safe. This avoids the
need for an explicit bounds check at the end.

Backpatch to 18, where the bug was introduced by commit 6acab8bdbcda.

Author: Matheus Alcantara <mths.dev@pm.me>
Reported-by: Glauber Batista <glauberrbatista@gmail.com>
Reviewed-by: Melanie Plageman <melanieplageman@gmail.com>
Reviewed-by: Tomas Vondra <tomas@vondra.me>
Backpatch-through: 18
Discussion: https://www.postgresql.org/message-id/CAO%2B_mTQgQyTYwDh%3DU8iTnsDmOGyWsZJjUV31SmEYwmw6_xY6Bw%40mail.gmail.com

2 weeks agoImprove docs for EXPLAIN (IO)
Tomas Vondra [Fri, 26 Jun 2026 15:57:26 +0000 (17:57 +0200)] 
Improve docs for EXPLAIN (IO)

Commit 681daed931 introduced a new EXPLAIN option "IO", but the docs
did not explain what information was added to the output. Expand the
description a little bit, similarly to the other EXPLAIN options.

While at it, fix a typo in the first sentence.

Author: Tomas Vondra <tomas@vondra.me>

2 weeks agoTake into account default_tablespace during MERGE/SPLIT PARTITION(S)
Alexander Korotkov [Fri, 26 Jun 2026 12:25:13 +0000 (15:25 +0300)] 
Take into account default_tablespace during MERGE/SPLIT PARTITION(S)

createPartitionTable() passed the partitioned parent's reltablespace straight
to heap_create_with_catalog(), bypassing the default_tablespace GUC fallback
that DefineRelation() applies for CREATE TABLE ... PARTITION OF.  When the
parent had no explicit tablespace (reltablespace = 0), the new partition
unconditionally landed in the database default, even if default_tablespace
was set to something else; merging or splitting a set of partitions that all
lived in a non-default tablespace produced a new partition in the database
default.

Mirror DefineRelation()'s logic: take parent's reltablespace if set,
otherwise check GetDefaultTablespace() (which reads default_tablespace
and normalises pg_default / MyDatabaseTableSpace to InvalidOid).  Also
add the CREATE ACL check on the resolved tablespace and the pg_global
rejection, matching DefineRelation()'s behavior.

Update the documentation for MERGE/SPLIT PARTITION to spell out the
tablespace-selection rule explicitly.

Reported-by: Justin Pryzby <pryzby@telsasoft.com>
Reviewed-by: Pavel Borisov <pashkin.elfe@gmail.com>
Discussion: https://postgr.es/m/ajQTklv8QArzTp3h%40pryzbyj2023

2 weeks agodoc: Improve description of pg_get_multixact_stats()
Michael Paquier [Fri, 26 Jun 2026 01:47:32 +0000 (10:47 +0900)] 
doc: Improve description of pg_get_multixact_stats()

This addresses two gaps in the documentation:
- The function uses an xid, and was not mentioned as an exception in a
section of the docs related to xid8.
- The function returns NULL if a role does not have the privileges of
pg_read_all_stats.  The execution is not denied.

Author: Chao Li <li.evan.chao@gmail.com>
Author: Yingying Chen <cyy9255@gmail.com>
Discussion: https://postgr.es/m/CAGGTb65Qmtor2nJP-ATgfWpMpD2qhKrdyO7fmRbbS++nQ=vtMw@mail.gmail.com

2 weeks agoMark uuid-to-bytea cast as leakproof.
Masahiko Sawada [Thu, 25 Jun 2026 21:25:57 +0000 (14:25 -0700)] 
Mark uuid-to-bytea cast as leakproof.

The uuid-to-bytea cast just serializes a valid uuid datum into its
fixed 16-byte representation. It does not have an input-dependent
error path so mark its pg_proc entry as leakproof.

Oversight in commit ba21f5bf8a.

Bump catalog version.

Author: Chao Li <lic@highgo.com>
Discussion: https://postgr.es/m/1FAAF426-9205-4F53-8D3B-F2003D96EC37@gmail.com

2 weeks agoFix null-pointer crash in ECPG compiler.
Tom Lane [Thu, 25 Jun 2026 20:58:29 +0000 (16:58 -0400)] 
Fix null-pointer crash in ECPG compiler.

When compiling a DECLARE section containing a union nested
inside a struct, ecpg passes a null value for struct_sizeof to
ECPGmake_struct_type.  I (tgl) didn't foresee that case in
commit 0e6060790, and wrote an unprotected mm_strdup() call.

Reported-by: iMSA (via Jehan-Guillaume de Rorthais <jgdr@dalibo.com>)
Author: Jehan-Guillaume de Rorthais <jgdr@dalibo.com>
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/20260625114849.34b2148e@karst
Backpatch-through: 18

2 weeks agoMessage and comment wording fixes
Peter Eisentraut [Thu, 25 Jun 2026 08:51:22 +0000 (10:51 +0200)] 
Message and comment wording fixes

Some parts of pg_upgrade referred to "on the old cluster" etc.  Change
that to "in the old cluster", matching existing style.

2 weeks agodoc: Some spell checking
Peter Eisentraut [Thu, 25 Jun 2026 06:36:00 +0000 (08:36 +0200)] 
doc: Some spell checking

2 weeks agoFix options listing of pg_test_timing --cutoff
Peter Eisentraut [Thu, 25 Jun 2026 05:39:59 +0000 (07:39 +0200)] 
Fix options listing of pg_test_timing --cutoff

The new pg_test_timing --cutoff option (commit 0b096e379e6) appeared
out of order in the documentation and the code.  Fix that.

3 weeks agopg_stat_io: Don't flag extends by autovacuum launcher
Melanie Plageman [Wed, 24 Jun 2026 18:51:31 +0000 (14:51 -0400)] 
pg_stat_io: Don't flag extends by autovacuum launcher

pg_stat_io asserts on unexpected combinations of backend type and IOOp.
These combinations were meant to help detect bugs given our current
understanding of the system -- not serve as a set of rules for what is
allowed. The autovacuum launcher scans catalog tables and may on-access
prune them. This previously wouldn't have led to any extends of the
relation, but now that on-access pruning may pin a page of the
visibility map (4f7ecca84ddacbce27), scanning tables may lead to
extending the visibility map. This would cause the launcher to trip an
assert. Since there is no reason to forbid the launcher from doing
extends, remove it from the list of backend type pgstat_tracks_io_op
flags for doing IOOP_EXTEND.

Read-only catalog scans still don't let pruning set the VM; doing so
needs table AM API changes and is left for the future.

Reported-by: Ewan Young <kdbase.hack@gmail.com>
Discussion: https://postgr.es/m/CAON2xHNOyaN9MCZohhD_NL6as3QVhGA0SOn2Hyi9w6+Y-_1bFA@mail.gmail.com

3 weeks agopsql: Add tab completion for subscription wal_receiver_timeout
Fujii Masao [Wed, 24 Jun 2026 13:57:50 +0000 (22:57 +0900)] 
psql: Add tab completion for subscription wal_receiver_timeout

Commit fb80f388f added wal_receiver_timeout as a CREATE/ALTER
SUBSCRIPTION option, but psql tab completion did not include it in the
subscription option lists.

Add wal_receiver_timeout to completion for CREATE SUBSCRIPTION ... WITH
and ALTER SUBSCRIPTION ... SET.

Author: Chao Li <lic@highgo.com>
Reviewed-by: Bharath Rupireddy <bharath.rupireddyforpostgres@gmail.com>
Reviewed-by: Xuneng Zhou <xunengzhou@gmail.com>
Reviewed-by: Fujii Masao <masao.fujii@gmail.com>
Discussion: https://postgr.es/m/BBC5628A-63C0-4436-B8F3-90AF59BBEB73@gmail.com

3 weeks agoRemove extraneous newlines from guc_parameters.dat
Peter Eisentraut [Wed, 24 Jun 2026 12:58:54 +0000 (14:58 +0200)] 
Remove extraneous newlines from guc_parameters.dat

In commit fce7c73fb, two unnecessary newlines were kept: before
archive_command and seq_page_cost.  Remove them here just to be
tidier.

Author: Anton Voloshin <a.voloshin@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/270ae9e7-85c6-487d-b02b-a994af56710b%40postgrespro.ru

3 weeks agoDistinguish datacheckums worker invocations more reliably
Heikki Linnakangas [Wed, 24 Jun 2026 12:07:33 +0000 (15:07 +0300)] 
Distinguish datacheckums worker invocations more reliably

In some corner cases, a new datachecksums worker could be launched
while an old one was still running.  If you're really unlucky, the old
worker could set the worker_result in shared memory and mislead the
launcher to think that a newer worker invocation completed
successfully, even though it failed for some reason.  That's highly
unlikely to happen in practice as it requires several race conditions
with workers and launchers starting, failing and succeeding and at the
right moments.  Nevertheless, better to tighten it up.

To distinguish different worker invocations, assign a unique
'worker_invocation' number every time a new worker is launched.  In
the worker, check that the invocation number matches before setting
the worker result.  This ensures that the result always belongs to the
latest invocation.

Reviewed-by: Daniel Gustafsson <daniel@yesql.se>
Discussion: https://www.postgresql.org/message-id/b283fbb9-298e-4953-9120-eefaf24fae20@iki.fi

3 weeks agoMinor cleanup around checking datachecksum worker result
Heikki Linnakangas [Wed, 24 Jun 2026 12:07:30 +0000 (15:07 +0300)] 
Minor cleanup around checking datachecksum worker result

Rename the 'success' field in DataChecksumState to 'worker_result'.
That's more appropriate when it's not a simple boolean.

Don't access the field after releasing the lock in ProcessDatabase().
No other process should be modifying it, but if we bother to do any
locking in the first place, let's do it right.

Reviewed-by: Daniel Gustafsson <daniel@yesql.se>
Discussion: https://www.postgresql.org/message-id/b283fbb9-298e-4953-9120-eefaf24fae20@iki.fi

3 weeks agoAvoid leaving DataChecksumState->worker_pid to an old value
Heikki Linnakangas [Wed, 24 Jun 2026 12:07:27 +0000 (15:07 +0300)] 
Avoid leaving DataChecksumState->worker_pid to an old value

It might be left to an old value if the launcher was terminated while
a worker was running.  launcher_exit() sends SIGTERM to the worker,
but did not clear 'worker_pid'.  Clear it, to be tidy.

Also clear it in ProcessDatabase() before starting a new datachecksums
worker, to be sure we start from a clean slate.  The codepath where
WaitForBackgroundWorkerStartup() returns BGWH_STOPPED but
worker_result != DATACHECKSUMSWORKER_SUCCESSFUL didn't clear it, while
all other codepaths did clear or set it.

Reviewed-by: Daniel Gustafsson <daniel@yesql.se>
Discussion: https://www.postgresql.org/message-id/b283fbb9-298e-4953-9120-eefaf24fae20@iki.fi

3 weeks agoMisc cleanup in datachecksums_state.[ch]
Heikki Linnakangas [Wed, 24 Jun 2026 12:07:24 +0000 (15:07 +0300)] 
Misc cleanup in datachecksums_state.[ch]

Move DataChecksumsWorkerResult struct to the .c file.  It's not used
anywhere else since commit 07009121c2 removed the injection point test
code that the comment referred to.

Mark StartDataChecksumsWorkerLauncher() as static, since it's not
called from outside the .c file.  The DataChecksumsWorkerOperation
struct can then be moved into the .c file too.

Clarify the comment on StartDataChecksumsWorkerLauncher().  It said
"Main entry point for datachecksumsworker launcher process", but I
found that misleading.  That description would be a better fit for
DataChecksumsWorkerLauncherMain(), which is the process's "main"
function, rather than StartDataChecksumsWorkerLauncher().

Fix comment on WaitForAllTransactionsToFinish() on postmaster death.
The comment claimed that it sets "the abort flag" on postmaster death,
but it actually just errors outs.  Improve the comment to explain why
it doesn't just use WL_EXIT_ON_PM_DEATH.

Reviewed-by: Daniel Gustafsson <daniel@yesql.se>
Discussion: https://www.postgresql.org/message-id/b283fbb9-298e-4953-9120-eefaf24fae20@iki.fi

3 weeks agoFix set of typos and grammar mistakes
Michael Paquier [Wed, 24 Jun 2026 07:00:28 +0000 (16:00 +0900)] 
Fix set of typos and grammar mistakes

This is similar to d3bba0415435, batching all the reports of this type
received since the last batch.  This covers typos and inconsistencies
for the most part.

The user-visible documentation change impacts only HEAD.

3 weeks agoRefine error reporting for null treatment on non-window functions
Fujii Masao [Wed, 24 Jun 2026 02:42:36 +0000 (11:42 +0900)] 
Refine error reporting for null treatment on non-window functions

Commit 4e5920e6de8 disallowed RESPECT NULLS/IGNORE NULLS on
non-window functions, but it also caused the parser to check for
that clause too early in some cases. As a result, calls such as a
nonexistent function with IGNORE NULLS no longer reported the more
helpful "function ... does not exist" error, and aggregate functions
used as window functions reported "only window functions accept ..."
instead of the more accurate aggregate-specific error.

This commit moves the RESPECT NULLS/IGNORE NULLS checks so that
helpful existing errors are preserved where appropriate. This restores
"function ... does not exist" for nonexistent functions, while still
reporting that plain functions are not window functions and that
aggregates do not accept null treatment.

Author: Fujii Masao <masao.fujii@gmail.com>
Reviewed-by: Tatsuo Ishii <ishii@postgresql.org>
Reviewed-by: Chao Li <li.evan.chao@gmail.com>
Reviewed-by: Álvaro Herrera <alvherre@kurilemu.de>
Discussion: https://postgr.es/m/CAHGQGwH7VY_0GkhycyYZ4czkPGL0uGzDyOxk3uuFOSRR7wFY3g@mail.gmail.com

3 weeks agoplperl: Fix NULL pointer dereference for forged array object
Richard Guo [Wed, 24 Jun 2026 00:09:48 +0000 (09:09 +0900)] 
plperl: Fix NULL pointer dereference for forged array object

In get_perl_array_ref(), for a PostgreSQL::InServer::ARRAY object, we
look up its "array" key with hv_fetch_string() and then inspect the
returned SV.  However, hv_fetch_string() returns a NULL pointer when
the key is absent, and the code dereferenced that result without first
checking whether the pointer itself was NULL.  As a result, a plperl
function returning a forged PostgreSQL::InServer::ARRAY object that
lacks the "array" key would crash the backend with a segmentation
fault.

Fix this by checking the pointer returned by hv_fetch_string() before
dereferencing it, matching how other callers in this file already
guard the result.  With the check in place, such an object falls
through to the existing error report instead of crashing.

Author: Xing Guo <higuoxing@gmail.com>
Reviewed-by: Richard Guo <guofenglinux@gmail.com>
Discussion: https://postgr.es/m/CACpMh+DYgcnqZwQLXXuxQcehJTd7T8UmKWSLsK4mFBEp9G2ajA@mail.gmail.com
Backpatch-through: 14

3 weeks agoRe-index ModifyTable FDW arrays when pruning result relations
Amit Langote [Tue, 23 Jun 2026 12:07:13 +0000 (21:07 +0900)] 
Re-index ModifyTable FDW arrays when pruning result relations

ExecInitModifyTable() rebuilds the per-result-relation lists after
dropping result relations removed by initial runtime pruning.  The
re-indexing was done for withCheckOptionLists, returningLists,
updateColnosLists, mergeActionLists and mergeJoinConditions, but
fdwPrivLists and fdwDirectModifyPlans were missed.  As a result, a
kept foreign result relation could be handed the wrong fdw_private,
or ri_usesFdwDirectModify could be set from the wrong plan index,
leading to wrong behavior or a crash in BeginForeignModify() and in
the direct-modify path.

show_modifytable_info() had the same problem: it indexed the
plan-ordered node->fdwPrivLists with the post-pruning executor
position, so once initial pruning removed a result relation it
could read a different relation's fdw_private (often a NIL entry),
producing wrong EXPLAIN output or a crash.

Fix by re-indexing fdwPrivLists and fdwDirectModifyPlans alongside
the other lists, saving the re-indexed private lists in
ModifyTableState.mt_fdwPrivLists and reading from there in both
nodeModifyTable.c and explain.c.

Reported-by: Chi Zhang <798604270@qq.com>
Author: Ayush Tiwari <ayushtiwari.slg01@gmail.com>
Author: Rafia Sabih <rafia.pghackers@gmail.com>
Reviewed-by: Matheus Alcantara <matheusssilv97@gmail.com>
Reviewed-by: Etsuro Fujita <etsuro.fujita@gmail.com>
Discussion: https://postgr.es/m/19484-a3cb82c8cde3c8fa%40postgresql.org
Backpatch-through: 18

3 weeks agoNail pg_parameter_acl in relcache.
Jeff Davis [Tue, 23 Jun 2026 19:06:33 +0000 (12:06 -0700)] 
Nail pg_parameter_acl in relcache.

Previously, a parameter specified in the startup packet for a physical
replication connection could encounter an error trying to perform an
ACL check for the setting.

Problem was introduced in a0ffa885e4, but no reasonable back-patchable
solution was found, so fixing only in master.

Bumps catversion.

Discussion: https://postgr.es/m/d8f8e11f06d692fff89e6be0f22732d30cf695a0.camel%40j-davis.com
Reviewed-by: John Naylor <johncnaylorls@gmail.com>
Reviewed-by: Mark Dilger <mark.dilger@enterprisedb.com>
3 weeks agoFix incorrect declarations of variadic pg_get_*_ddl() functions.
Tom Lane [Tue, 23 Jun 2026 19:06:34 +0000 (15:06 -0400)] 
Fix incorrect declarations of variadic pg_get_*_ddl() functions.

The final parameter of an ordinary variadic function should be an
array type.  CREATE FUNCTION won't accept a declaration that isn't
like that, but it's possible to put an incorrect combination into a
pg_proc.dat entry.  Sadly, the opr_sanity test that was supposed to
check that is broken and does not report functions with non-array
final parameters.  This allowed exactly such a thinko to sneak into
the recently-added pg_get_*_ddl() functions: their last argument
should be declared text[] but was declared text.  (We'd probably
have noticed eventually, when somebody tried to actually pass a
variadic array to one of those functions.  But their regression
tests do not do that.)

Fix those functions, and fix the opr_sanity test so we'll notice
next time.  Bump catversion for new pg_proc contents.

Author: Chao Li <li.evan.chao@gmail.com>
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/D41A334E-ED9E-42EE-830D-28D4D36E9317@gmail.com

3 weeks agopsql: Tighten heuristics for BEGIN/END within CREATE SCHEMA.
Tom Lane [Tue, 23 Jun 2026 18:12:03 +0000 (14:12 -0400)] 
psql: Tighten heuristics for BEGIN/END within CREATE SCHEMA.

Since d51697484, psql's scanner treats CREATE SCHEMA as a command that
may contain SQL-standard routine bodies, so that semicolons inside
BEGIN ATOMIC ... END blocks do not terminate the command too early.
However, the code counted BEGIN/END throughout CREATE SCHEMA, so that
it could be fooled by valid (and previously accepted) code such as

    CREATE SCHEMA s CREATE VIEW begin AS SELECT 1;

Improve this by explicitly checking whether each CREATE sub-clause is
CREATE [OR REPLACE] {FUNCTION|PROCEDURE}, and only counting BEGIN/END
within those clauses.  Since CREATE FUNCTION/PROCEDURE wasn't allowed
in CREATE SCHEMA before d51697484, this will not risk failure on any
cases that worked before v19.

There remain cases that fool the top-level CREATE FUNCTION/PROCEDURE
heuristic and thus also the CREATE SCHEMA case, for example

    CREATE FUNCTION begin () ...

But that's been true all along with no field complaints, so we'll
leave that issue for another day.

In the name of keeping things readable, move the logic supporting
this out of the {identifier} flex rule and into some small new
subroutines.  Also rename existing related PsqlScanState fields
to help distinguish them from the added fields.

This patch also fixes what seems to me (tgl) a small bug: \;
would reset BEGIN/END detection even when inside parens or BEGIN.
That's unlike what a plain semicolon would do, and no such effect
is suggested by the documentation.

Author: Chao Li <li.evan.chao@gmail.com>
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/8E03BB8D-003D-4850-9772-5F8015A5A0C7@gmail.com

3 weeks agodoc: Describe better handling of indexes in ALTER TABLE ATTACH PARTITION
Michael Paquier [Tue, 23 Jun 2026 07:49:34 +0000 (16:49 +0900)] 
doc: Describe better handling of indexes in ALTER TABLE ATTACH PARTITION

When ALTER TABLE ... ATTACH PARTITION matches partition indexes to the
parent table's indexes, invalid indexes are skipped.  This commit
improves the documentation to describe what e90e9275f56 has changed:
invalid indexes are skipped, and only valid indexes are considered for a
match.

Author: Mohamed Ali <moali.pg@gmail.com>
Reviewed-by: Sami Imseih <samimseih@gmail.com>
Discussion: https://postgr.es/m/CAGnOmWpAMaE-BOkpwM6mJnHcpS2QZ8yLSSaqmz+vryEsbCWWWA@mail.gmail.com
Backpatch-through: 14

3 weeks agoReadable identity strings for property graph objects
Peter Eisentraut [Tue, 23 Jun 2026 06:58:16 +0000 (08:58 +0200)] 
Readable identity strings for property graph objects

The "identity" column of pg_identify_object() for property graph
objects can be long string of names connected by "of", e.g. "a of l of
e of g".  The type of the first named object is given by column
"type".  But the types of intermediate objects are not easy to find
from the identity string especially when some of them share the same
name.  Some objects, like user mappings or authorization identifier
members, add types of objects other than the first one in the identity
string.  Do the same for property graph objects.

Author: Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
Reviewed-by: Michael Paquier <michael@paquier.xyz>
Discussion: https://www.postgresql.org/message-id/flat/aej1DkLwhyZWmtxJ%40bdtpg

3 weeks agodoc: Update pg_dump/dumpall/upgrade about handling of external statistics
Michael Paquier [Mon, 22 Jun 2026 23:20:11 +0000 (08:20 +0900)] 
doc: Update pg_dump/dumpall/upgrade about handling of external statistics

The pages of pg_dump, pg_dumpall and pg_upgrade mentioned that their
--no-statistics and --statistics options did not include the handling of
statistics created by CREATE STATISTICS, which was wrong.

Oversight in c32fb29e979d.

Reported-by: Igi Izumi <igi@sraoss.co.jp>
Discussion: https://postgr.es/m/19529-c7eb1e7a0b07eae6@postgresql.org

3 weeks agoFix unsafe order of operations in ResourceOwnerReleaseAll().
Tom Lane [Mon, 22 Jun 2026 22:03:23 +0000 (18:03 -0400)] 
Fix unsafe order of operations in ResourceOwnerReleaseAll().

This function called the resource-kind-specific ReleaseResource()
method for each item before deleting that item from the resowner.
That's backwards from the ordering in ResourceOwnerReleaseAllOfKind,
and it's not very safe.  If ReleaseResource throws an error then the
subsequent abort cleanup will come back here and try to release that
item again, possibly leading to a double-free or similar crash,
and in any case risking an infinite error cleanup loop.  This mistake
explains why the pgcrypto bug just fixed in 80bb0ebcc led to a crash
rather than something more benign.

Remove the item from the resowner, then call ReleaseResource,
matching the way things were done before b8bff07da.  If there
is a problem of this sort, we'd prefer to leak the item than
suffer the other likely consequences.

Per further analysis of bug #19527.

Author: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/646741.1782157515@sss.pgh.pa.us
Backpatch-through: 17

3 weeks agopgcrypto: avoid recursive ResourceOwnerForget().
Tom Lane [Mon, 22 Jun 2026 16:59:16 +0000 (12:59 -0400)] 
pgcrypto: avoid recursive ResourceOwnerForget().

Raising an error within a function using an OSSLCipher object led
to a complaint from ResourceOwnerForget and then a double-free crash,
because ResOwnerReleaseOSSLCipher forgot to unhook the OSSLCipher
object from its owner.  (The sibling logic for OSSLDigest objects got
this right, as did every other ReleaseResource function AFAICS.)

Oversight in cd694f60d.

Bug: #19527
Reported-by: Yuelin Wang <3020001251@tju.edu.cn>
Author: Yuelin Wang <3020001251@tju.edu.cn>
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/19527-6e7686960c6dce78@postgresql.org
Backpatch-through: 17

3 weeks agoStrip removed-relation references from PlaceHolderVars at join removal
Richard Guo [Mon, 22 Jun 2026 01:40:40 +0000 (10:40 +0900)] 
Strip removed-relation references from PlaceHolderVars at join removal

When left-join removal deletes a relation, remove_rel_from_query()
updates the relid sets attached to RestrictInfos and
EquivalenceMembers, and the canonical PlaceHolderVar held in each
PlaceHolderInfo, but it does not rewrite the PlaceHolderVars embedded
in clause and EquivalenceClass member expressions.  That has been
fine, because later processing consults those relid sets rather than
the embedded PlaceHolderVars.

However, such an expression may afterwards be translated for an
appendrel child and have its relids recomputed from scratch by
pull_varnos().  If the embedded PlaceHolderVar's phrels still mentions
the removed relation, pull_varnos() folds it back in, so the rebuilt
clause's relids reference a no-longer-existent relation.  That yields
a parameterized path keyed on the removed relation, tripping the
Assert on root->outer_join_rels in get_eclass_indexes_for_relids().

Fix by stripping the removed relids from the PlaceHolderVars in
surviving rels' baserestrictinfo and in EquivalenceClass member
expressions, keeping them consistent with the canonical
PlaceHolderVars.

This is only reachable on v18 and later, where
match_index_to_operand() began ignoring PlaceHolderVars; before that,
the wrapping PlaceHolderVar prevented the index match that exposes the
stale relids.

Reported-by: Alexander Kuzmenkov <akuzmenkov@tigerdata.com>
Author: Richard Guo <guofenglinux@gmail.com>
Reviewed-by: Tender Wang <tndrwang@gmail.com>
Discussion: https://postgr.es/m/CALzhyqwryL2QywgO03VQr_237Sq3MEVgTTT2_A9G3nGT5-SRZg@mail.gmail.com
Backpatch-through: 18

3 weeks agoplpython: Use funccache.c infrastructure for procedure caching.
Tom Lane [Sun, 21 Jun 2026 19:08:27 +0000 (15:08 -0400)] 
plpython: Use funccache.c infrastructure for procedure caching.

PL/Python set-returning functions can crash with a use-after-free when
CREATE OR REPLACE FUNCTION is executed while the SRF is mid-iteration.
The crash occurs because srfstate->savedargs is allocated in proc->mcxt,
which gets deleted when the procedure is invalidated, leaving a dangling
pointer that PLy_function_restore_args() then dereferences.

The best fix is to use reference counting to prevent destroying the
function state while it's still in use, similar to what PL/pgSQL has
done.  Rather than inventing a new wheel, this commit converts
PL/Python to use the funccache.c infrastructure.

The main challenge is that PL/Python uses SFRM_ValuePerCall for SRFs,
where the handler is called multiple times.  A naive implementation
would allow the refcount to return to zero between calls, but we need
to hang onto the original state and function body.  SQL-language
functions face the same challenge, so this commit follows the same
approach used in functions.c: maintain a per-call-site cache struct
(PLyProcedureCache) in fn_extra that holds both the pointer to the
long-lived PLyProcedure and the SRF execution state.

The use_count is incremented when we first obtain the procedure and is
decremented via a MemoryContextCallback registered on fn_mcxt, which runs
even during error aborts. Cleaning up the per-call SRF state needs more
care: an ExprContextCallback handles the in-query cases, since the
iterator is not guaranteed to run to completion (for example a LIMIT or a
rescan can abandon it early). But unlike SQL functions, whose resources
are released by transaction abort, PL/Python holds Python reference counts
on the iterator and saved arguments that abort will not release, and
ExprContextCallbacks are not invoked during an error abort. The
MemoryContextCallback on fn_mcxt therefore doubles as the backstop that
releases those references when a query errors out mid-iteration.

Since fn_extra is now used for PLyProcedureCache, this commit removes
use of the funcapi.h SRF infrastructure (SRF_IS_FIRSTCALL,
SRF_RETURN_NEXT, etc.) and switches to direct isDone signaling via
ReturnSetInfo, matching how SQL functions handle ValuePerCall mode.

This fixes a longstanding bug, so ideally we'd back-patch it.  But
it'd be impractical to back-patch further than v18 where funccache.c
came in.  The patch is somewhat invasive, and the bug only arises in
very uncommon usages (which is why it evaded detection for so long).
On the whole, the risk/reward ratio for putting this into v18 doesn't
seem good, so commit to master only.

Bug: #19480
Reported-by: Andrzej Doros <adoros@starfishstorage.com>
Author: Matheus Alcantara <matheusssilv97@gmail.com>
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/19480-f1f9fdce30462fc4@postgresql.org

3 weeks agodoc: Clarify pg_get_sequence_data() privileges and NULL results
Fujii Masao [Sat, 20 Jun 2026 09:20:58 +0000 (18:20 +0900)] 
doc: Clarify pg_get_sequence_data() privileges and NULL results

The documentation for pg_get_sequence_data() did not match the
function's behavior. It stated that either USAGE or SELECT privilege
was sufficient, but the function returns sequence data only when the
caller has SELECT privilege.

The documentation also did not explain that the function returns a row
containing all NULL values when sequence data cannot be returned, such
as when the sequence does not exist or the caller lacks the required
privilege.

Update the documentation to reflect the actual behavior, including the
required privilege and the result returned when sequence data is
unavailable.

Author: Fujii Masao <masao.fujii@gmail.com>
Reviewed-by: Tristan Partin <tristan@partin.io>
Discussion: https://postgr.es/m/CAHGQGwGNTaXnBKUV510_P1KwhdbHT+kgZ4zU5njBHy7nCqdhzg@mail.gmail.com

3 weeks agoFix misreporting of publisher sequence permissions during sync
Fujii Masao [Sat, 20 Jun 2026 09:19:23 +0000 (18:19 +0900)] 
Fix misreporting of publisher sequence permissions during sync

When synchronizing sequences for logical replication, a
publisher-side permission failure could be reported as if the sequence
were missing on the publisher, making the real cause harder to
identify.

This happened because pg_get_sequence_data() returns a row of NULL
values when the replication connection lacks permission to read a
sequence. Sequence synchronization treated that the same as a missing
sequence, causing it to emit a misleading "missing sequence on
publisher" warning.

Fix this by distinguishing permission failures from genuinely missing
sequences. The synchronization query now checks whether the
replication connection has the required privilege for each published
sequence, allowing the worker to report permission failures
separately.

Author: Fujii Masao <masao.fujii@gmail.com>
Reviewed-by: Tristan Partin <tristan@partin.io>
Discussion: https://postgr.es/m/CAHGQGwGNTaXnBKUV510_P1KwhdbHT+kgZ4zU5njBHy7nCqdhzg@mail.gmail.com

3 weeks agoMake type cache initialization more resilient on re-entry after OOM
Michael Paquier [Sat, 20 Jun 2026 07:29:28 +0000 (16:29 +0900)] 
Make type cache initialization more resilient on re-entry after OOM

An out-of-memory failure while initializing the type cache hash tables
would issue an ERROR and leave a backend in a partially inconsistent
state.  Without assertions, the server would crash with a NULL pointer
dereference on initialization re-entry when doing a type lookup due to
one or both hash tables missing.  An assertion would trigger if these
are enabled in the build.

This commit changes the ordering of the type cache initialization to
become more robust on re-entry after an in-flight allocation failure:
- The two hash tables are initialized first, and can only be initialized
once.
- The initialization is considered as done once the in-progress list is
allocated in the CacheMemoryContext.  This is now the last allocation
step.
- Last, the callbacks are registered.  These can only fail with a FATAL
error, taking down the process so leaving the process in a non-complete
state is fine.

This is in the same spirit as b85f9c00fb88 and 29fb598b9cad, where
random allocation failures can make the backend go crazy in the code
paths fixed due to the static states becoming inconsistent.  Like the
other fixes, this is unlikely going to show up in practice, so no
backpatch is done.

Reported-by: Alexander Lakhin <exclusion@gmail.com>
Author: Michael Paquier <michael@paquier.xyz>
Reviewed-by: Matthias van de Meent <boekewurm+postgres@gmail.com>
Discussion: https://postgr.es/m/e77acaac-a1b3-40b3-99ee-5769b4e453e4@gmail.com

3 weeks agoMake StandbyAcquireAccessExclusiveLock() more resilent with OOMs
Michael Paquier [Sat, 20 Jun 2026 06:00:40 +0000 (15:00 +0900)] 
Make StandbyAcquireAccessExclusiveLock() more resilent with OOMs

In StandbyReleaseXidEntryLocks, a failure in acquiring a lock with
LockAcquire() due to an out-of-memory problem would lead to an
inconsistency with the lock state cached in the startup process,
impacting the list of RecoveryLockXidEntrys.  The code is updated here
so as the cached state is updated once the lock is acquired.

This problem is unlikely going to happen in practice.  Even if it were
to show up, it would translate to a LOG message for non-assert builds
(assertion failure otherwise), so no backpatch is done.  This commit is
in the same spirit as 29fb598b9cad, with a problem emulated by injecting
random failures for allocations.

Reported-by: Alexander Lakhin <exclusion@gmail.com>
Author: Matthias van de Meent <boekewurm+postgres@gmail.com>
Discussion: https://postgr.es/m/e77acaac-a1b3-40b3-99ee-5769b4e453e4@gmail.com

3 weeks agoMake pg_mkdir_p() tolerant of a concurrent directory creation.
Tom Lane [Fri, 19 Jun 2026 16:52:00 +0000 (12:52 -0400)] 
Make pg_mkdir_p() tolerant of a concurrent directory creation.

pg_mkdir_p creates each missing path component with a stat() followed
by mkdir().  If the stat() reports the component as absent but another
process creates it in the window before this process's mkdir(), mkdir()
fails with EEXIST and pg_mkdir_p treated that as a hard error -- unlike
"mkdir -p", which is meant to be idempotent and race-tolerant.

This shows up when several processes concurrently create paths that
share an ancestor directory: for example, parallel initdb runs whose
data directories live under a common temporary directory.  One process
wins the race to create the shared ancestor and the others fail with
    could not create directory "...": File exists

Fix this race condition by first trying mkdir() and only attempting
stat() if it fails with EEXIST.

On Windows, there's an additional problem: stat() opens a file handle
and participates in share-mode locking, which means it can transiently
fail on a directory another process is concurrently creating.  Use
GetFileAttributes() instead: it requests only FILE_READ_ATTRIBUTES
and is exempt from share-mode denial, so it reliably sees a
concurrently-created directory.

I (tgl) also chose to back-patch 039f7ee0f's effects on this function,
so that pgmkdirp.c remains identical in all live branches.

Author: Andrew Dunstan <andrew@dunslane.net>
Co-authored-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/3ca004de-e49b-4471-b8aa-fd656e70f68c@dunslane.net
Backpatch-through: 14

3 weeks agoUpdate JIT tuple deforming code for virtual generated columns
David Rowley [Fri, 19 Jun 2026 03:26:18 +0000 (15:26 +1200)] 
Update JIT tuple deforming code for virtual generated columns

The JIT deforming code contains an optimization that determines which
columns are guaranteed to exist in the tuple.  That's used to allow
skipping of reading the tuple's natts when the code only needs to deform
attributes that are guaranteed to always exist in all tuples.  83ea6c540
missed updating this code to account for VIRTUAL generated columns.
These are stored as NULLs in the tuple, but may be defined as NOT NULL.
This could result in the code thinking more columns are guaranteed to
exist than actually do.

Author: David Rowley <dgrowleyml@gmail.com>
Reviewed-by: Chao Li <li.evan.chao@gmail.com>
Backpatch-through: 18
Discussion: https://postgr.es/m/1151393.1781734980@sss.pgh.pa.us

3 weeks agoFix comments on data checksum cost settings
Daniel Gustafsson [Thu, 18 Jun 2026 21:16:35 +0000 (23:16 +0200)] 
Fix comments on data checksum cost settings

The cost parameters for the data checksums worker can be updated by the
user issuing a repeated enable checksum command, but the comments on the
struct members hadn't been updated to reflect this and were out of date.
Another part of the same comment needed better wording to be readable.

Also wrap the reading of the parameters in a lock, there is no live
bug due to not using a lock but it's still the right thing to do.

Author: Daniel Gustafsson <daniel@yesql.se>
Reviewed-by: Heikki Linnakangas <hlinnaka@iki.fi>
Reported-by: Heikki Linnakangas <hlinnaka@iki.fi>
Discussion: https://postgr.es/m/2176020b-ecbc-438b-9fc3-9c3593d9e6fc@iki.fi

3 weeks agoSilence "may be used uninitialized" compiler warning.
Nathan Bossart [Thu, 18 Jun 2026 16:29:49 +0000 (11:29 -0500)] 
Silence "may be used uninitialized" compiler warning.

Newer gcc warns that this "actual_arg_types" variable may be used
uninitialized, but visual inspection indicates there's no bug.  To
silence the warning, initialize the variable to zeros.

Bug: #19485
Reported-by: Hans Buschmann <buschmann@nidsa.net>
Tested-by: Erik Rijkers <er@xs4all.nl>
Tested-by: Hans Buschmann <buschmann@nidsa.net>
Reviewed-by: Tristan Partin <tristan@partin.io>
Reviewed-by: Álvaro Herrera <alvherre@kurilemu.de>
Discussion: https://postgr.es/m/19485-2b03231a775756f1%40postgresql.org
Discussion: https://postgr.es/m/6c52a1a6612948519468d46cb224a8c4%40nidsa.net

3 weeks agohstore_plperl: Add CHECK_FOR_INTERRUPTS() in reference-unwinding loop.
Tom Lane [Thu, 18 Jun 2026 16:22:55 +0000 (12:22 -0400)] 
hstore_plperl: Add CHECK_FOR_INTERRUPTS() in reference-unwinding loop.

Add CHECK_FOR_INTERRUPTS() to the while loop in plperl_to_hstore()
that dereferences chains of Perl references, so that a circular
reference (e.g. $x = \$x) can be cancelled by the user instead of
spinning indefinitely.  (We looked at detecting such circular
references, but it seems more trouble than it's worth.)

This is a follow-up to da82fbb8f, which fixed the same issue in
SV_to_JsonbValue() in jsonb_plperl.

Author: Aleksander Alekseev <aleksander@tigerdata.com>
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/CAJ7c6TPbjkzUk4qJ5dHvDNEz0hBuFue3A-XWz_=897z+BC+z8A@mail.gmail.com
Backpatch-through: 14

3 weeks agoAvoid errors during DROP SUBSCRIPTION when slot_name is NONE.
Jeff Davis [Thu, 18 Jun 2026 16:00:32 +0000 (09:00 -0700)] 
Avoid errors during DROP SUBSCRIPTION when slot_name is NONE.

Previously, if the subscription used a server,
ForeignServerConnectionString() could raise an error (e.g. missing
user mapping) during DROP SUBSCRIPTION even if the conninfo wasn't
needed at all.

Construct conninfo after the early return, so that if slot_name is
NONE and rstates is NIL, the DROP SUBSCRIPTION will succeed even if
ForeignServerConnectionString() raises an error (e.g. missing user
mapping).

If slot_name is NONE and rstates is not NIL, DROP SUBSCRIPTION may
still encounter an error from ForeignServerConnectionString().

Reported-by: Hayato Kuroda (Fujitsu) <kuroda.hayato@fujitsu.com>
Reviewed-by: Chao Li <li.evan.chao@gmail.com>
Discussion: https://postgr.es/m/OS9PR01MB12149B54DEA148108C6FA5667F52D2@OS9PR01MB12149.jpnprd01.prod.outlook.com

3 weeks agodoc PG 19 relnotes: fix "standard_conforming_strings = off text
Bruce Momjian [Thu, 18 Jun 2026 16:19:16 +0000 (12:19 -0400)] 
doc PG 19 relnotes:  fix "standard_conforming_strings = off text

Reported-by: Tom Lane
Discussion: https://postgr.es/m/1242905.1781796886@sss.pgh.pa.us

3 weeks agoAvoid division-by-zero when calculating autovacuum MXID score.
Nathan Bossart [Thu, 18 Jun 2026 15:18:25 +0000 (10:18 -0500)] 
Avoid division-by-zero when calculating autovacuum MXID score.

In some cases, effective_multixact_freeze_max_age can be 0, which
presents a division-by-zero hazard for the multixact ID age score
calculation.  To fix, bump it to 1 in that case so that we use the
multixact ID age as the score.  While at it, also document that
this component score scales due to high multixact member space
usage.

Reported-by: Masahiko Sawada <sawada.mshk@gmail.com>
Author: Sami Imseih <samimseih@gmail.com>
Reviewed-by: Bharath Rupireddy <bharath.rupireddyforpostgres@gmail.com>
Discussion: https://postgr.es/m/CAD21AoC6nKeYAjTvJ9dmBea03GZK9222h_O%3DONmcVuxfyO88Bg%40mail.gmail.com

3 weeks agodoc: Fix "Prev" link, take 2.
Nathan Bossart [Thu, 18 Jun 2026 14:31:27 +0000 (09:31 -0500)] 
doc: Fix "Prev" link, take 2.

Commit 6678b58d78 fixed a wrong "Prev" link by changing the link
generation code to use [position()=last()] instead of [last()] in
the predicate on the union of reverse axes.  Unfortunately, that
caused documentation builds to take much longer.  To fix, combine
the "preceding" and "ancestor" steps into one "preceding" step and
one "ancestor" step, and revert the predicate back to [last()].
The smaller union evades the libxml2 bug while avoiding the build
time regression.

Reported-by: Tom Lane <tgl@sss.pgh.pa.us>
Tested-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/1132496.1781718007%40sss.pgh.pa.us
Backpatch-through: 14

3 weeks agoRevert non-text output formats for pg_dumpall
Andrew Dunstan [Mon, 15 Jun 2026 19:58:04 +0000 (15:58 -0400)] 
Revert non-text output formats for pg_dumpall

This reverts the non-text (custom/directory/tar) output format support
for pg_dumpall added by 763aaa06f03 and its feature-specific follow-ups,
in line with Noah Misch's post-commit review which recommends reverting
and finishing the work through the commitfest.

Scope is deliberately minimal: only the feature itself is removed.
Independent improvements that merely touched the same files, or that were
committed alongside the feature but do not depend on its design, are
preserved.

Reverted (the feature):

  763aaa06f03  Add non-text output formats to pg_dumpall
  d6d9b96b404  Clean up nodes that are no longer of use in 007_pgdumpall.pl
  01c729e0c7a  Fix casting away const-ness in pg_restore.c
  c7572cd48d3  Improve writing map.dat preamble
  3c19983cc08  pg_restore: add --no-globals option to skip globals
  abff4492d02  Fix options listing of pg_restore --no-globals
  bb53b8d359d  Fix small memory leak in get_dbname_oid_list_from_mfile()
  a793677e57b  pg_restore: Remove dead code in restore_all_databases()
  a198c26dede  pg_dumpall: simplify coding of dropDBs()
  ec80215c033  pg_restore: Remove unnecessary strlen() calls in options parsing

Preserved (independent of the feature):

  b2898baaf7e  the check_mut_excl_opts() helper in src/fe_utils/option_utils.c
               and its use in pg_dump
  7c8280eeb58  pg_dump's conflicting-option refactor (and tests 002/005)
  be0d0b457cb  pg_dumpall's rejection of --clean together with --data-only
               (re-expressed directly, since pg_dumpall.c is otherwise
               returned to its pre-feature state)
  74b4438a70b  the dangling-grantor-OID GRANT fix (back-patched through 16)
  273d26b75e7d4cb9c37765  independent pg_restore.sgml clarifications

Because the feature restructured pg_dumpall.c and pg_restore.c (pg_restore's
main() was split into restore_one_database() plus a dispatcher) and
interleaved its option checks with the conflicting-option refactor in the
same regions, the cosmetic check_mut_excl_opts() reflow of those two files'
option blocks is inseparable from the feature and comes out with it; the
behavior is unchanged.  The reusable helper and pg_dump's use of it are
unaffected.

Discussion: https://postgr.es/m/20260607000218.96.noahmisch@microsoft.com

3 weeks agoCreate TOAST table for partitions made by MERGE/SPLIT PARTITION
Alexander Korotkov [Thu, 18 Jun 2026 07:30:14 +0000 (10:30 +0300)] 
Create TOAST table for partitions made by MERGE/SPLIT PARTITION

ALTER TABLE ... MERGE PARTITIONS / SPLIT PARTITION builds a new
partition via createPartitionTable(), but never gives it a TOAST table.
When the source rows carried out-of-line varlena values, the move
into the new partition entered heap_toast_insert_or_update() with
reltoastrelid = InvalidOid: the externalization step is skipped, the
value falls back to inline storage and heap_insert() fails with
"row is too big" error.  Also, TOAST table is needed if the new partition
receives out-of-line varlena values after the DDL operation is complete.

Call NewRelationCreateToastTable() right after the new partition is
created in createPartitionTable(), mirroring what DefineRelation()
does for regular CREATE TABLE.  NewRelationCreateToastTable() decides
on its own whether a TOAST table is actually required, so partitions
with no toast-eligible columns are unaffected.

Reported-by: Justin Pryzby <pryzby@telsasoft.com>
Discussion: https://postgr.es/m/ai_c4-v8iLA2kXFV%40pryzbyj2023
Reviewed-by: Pavel Borisov <pashkin.elfe@gmail.com>
Reviewed-by: Jian He <jian.universality@gmail.com>
3 weeks agoMake GetSnapshotData() more resilient on out-of-memory errors
Michael Paquier [Thu, 18 Jun 2026 05:05:27 +0000 (14:05 +0900)] 
Make GetSnapshotData() more resilient on out-of-memory errors

If the allocation of Snapshot->subxip fails, a follow-up call of
GetSnapshotData() would see a partially-initialized snapshot, causing a
NULL dereference on reentry when using "subxip" because only "xip" would
be allocated.  In the event of an out-of-memory error when allocating
"subxip", "xip" is now reset before throwing an ERROR, so as Snapshots
can be allocated and handled gracefully on retry.

This problem is unlikely going to show up in practice, so no backpatch.

Reported-by: Alexander Lakhin <exclusion@gmail.com>
Author: Matthias van de Meent <boekewurm+postgres@gmail.com>
Discussion: https://postgr.es/m/e77acaac-a1b3-40b3-99ee-5769b4e453e4@gmail.com

3 weeks agoAvoid stale slot access after dropping obsolete synced slots.
Amit Kapila [Thu, 18 Jun 2026 04:20:33 +0000 (09:50 +0530)] 
Avoid stale slot access after dropping obsolete synced slots.

drop_local_obsolete_slots() continued to dereference local_slot after
calling ReplicationSlotDropAcquired().  Once the slot is dropped, its
entry in the slot array can be reused by another backend, so later reads
of local_slot->data could observe a different slot's name or database
OID, leading to an incorrect unlock and log message.

Save the slot name and database OID before performing the drop, and use
the saved values for the subsequent UnlockSharedObject() call and the log
message.  While at it, emit the "dropped replication slot" message only
when a slot was actually dropped, rather than unconditionally.

Author: Xuneng Zhou <xunengzhou@gmail.com>
Reviewed-by: Zhijie Hou <houzj.fnst@fujitsu.com>
Reviewed-by: Amit Kapila <amit.kapila16@gmail.com>
Reviewed-by: Fujii Masao <masao.fujii@gmail.com>
Backpatch-through: 17, where it was introduced
Discussion: https://postgr.es/m/TY4PR01MB177184FF9EE916F577E1F554194082@TY4PR01MB17718.jpnprd01.prod.outlook.com

3 weeks agoFix PANIC with track_functions due to concurrent drop of pgstats entries
Michael Paquier [Thu, 18 Jun 2026 02:49:30 +0000 (11:49 +0900)] 
Fix PANIC with track_functions due to concurrent drop of pgstats entries

pgstat_drop_entry_internal() generates an ERROR if facing a pgstats
entry already marked as dropped.  With a workload doing a lot of
concurrent CALL and DROP/CREATE PROCEDURE, it could be possible for
AtEOXact_PgStat_DroppedStats(), that wants to do transactional drops, to
find entries that are already dropped, after a commit record has been
written.  In this case, ERRORs are upgraded to PANIC, taking down the
server.

This issue is fixed by making pgstat_drop_entry() optionally more
tolerant to concurrent drops, adding to the routine a missing_ok option
to make some of its callers more tolerant (spoiler: some of the callers
want a strict behavior, like replication slots and backend stats).
pgstat_drop_entry_internal() cannot be called anymore for an entry
marked as dropped, hence its error is replaced by an assertion.
Functions are handled as a special case in core; this problem could also
apply to custom stats kinds depending on what an extension does.
track_functions is costly when enabled (disabled by default), which is
perhaps the main reason why this has not be found yet.

A similar version of this patch has been proposed by Sami Imseih on a
different thread for a feature in development.  This version has tweaked
here by me for the sake of fixing this issue.

Reported-by: zhanglihui <zlh21343@163.com>
Author: Sami Imseih <samimseih@gmail.com>
Author: Michael Paquier <michael@paquier.xyz>
Reviewed-by: Ayush Tiwari <ayushtiwari.slg01@gmail.com>
Discussion: https://postgr.es/m/19520-73873648d44793cf@postgresql.org
Backpatch-through: 15

3 weeks agoDoc: Clarify that publication exclusions track table identity.
Amit Kapila [Thu, 18 Jun 2026 02:32:33 +0000 (08:02 +0530)] 
Doc: Clarify that publication exclusions track table identity.

The EXCEPT clause of a FOR ALL TABLES publication tracks each excluded
table by its identity rather than by name. As a result, renaming a table
or moving it to another schema with ALTER TABLE ... SET SCHEMA leaves the
exclusion in place, and the table stays excluded from the publication.

This behavior was not previously documented and could surprise users who
might reasonably expect a schema-qualified exclusion to apply only while
the table remains in that schema. Add a note to CREATE PUBLICATION to make
the behavior explicit.

Author: Peter Smith <smithpb2250@gmail.com>
Reviewed-by: Amit Kapila <amit.kapila16@gmail.com>
Discussion: https://postgr.es/m/CAHut+PvQ5BqnawCQd6r1tqqd+iAJC-CuRY8wscuXSrpHGUzofA@mail.gmail.com

3 weeks agodoc PG 19 relnotes: update to current
Bruce Momjian [Thu, 18 Jun 2026 01:44:25 +0000 (21:44 -0400)] 
doc PG 19 relnotes:  update to current

3 weeks agodoc PG 19 relnotes: remove VALIDATE CONSTRAINT lock item
Bruce Momjian [Thu, 18 Jun 2026 01:34:23 +0000 (21:34 -0400)] 
doc PG 19 relnotes:  remove VALIDATE CONSTRAINT lock item

Reported-by: Fujii Masao
Discussion: https://postgr.es/m/CAHGQGwGjfu5n5H-jsMp6fAsf-zMJzYWDcJGti6pmr7SHf9BcpA@mail.gmail.com

3 weeks agoFix ALTER DOMAIN VALIDATE CONSTRAINT locking
Fujii Masao [Thu, 18 Jun 2026 01:19:15 +0000 (10:19 +0900)] 
Fix ALTER DOMAIN VALIDATE CONSTRAINT locking

Commit 16a0039dc0d1 reduced the lock level for ALTER DOMAIN ...
VALIDATE CONSTRAINT from ShareLock to ShareUpdateExclusiveLock.
However, that change was unsafe. If DML on tables using the domain had
already started and initialized domain constraint checks before a NOT
VALID constraint was added, it could still insert or update rows that
violated the new constraint.

This commit reverts commit 16a0039dc0d1 so that ALTER DOMAIN ...
VALIDATE CONSTRAINT once again acquires ShareLock on relations using
the domain. Also add an isolation test covering this case.

Author: Chao Li <lic@highgo.com>
Reviewed-by: Fujii Masao <masao.fujii@gmail.com>
Reviewed-by: Álvaro Herrera <alvherre@kurilemu.de>
Discussion: https://postgr.es/m/463C0E1A-4A40-4BCA-839C-9236B80D65EE@gmail.com

3 weeks agodoc PG 19 relnotes: mention pg_dump{all} & standard_conforming_strings
Bruce Momjian [Wed, 17 Jun 2026 23:33:35 +0000 (19:33 -0400)] 
doc PG 19 relnotes: mention pg_dump{all} & standard_conforming_strings

Dumps will fail if standard_conforming_strings = off.

Reported-by: Tom Lane
Backpatch-through: 1131492.1781717349@sss.pgh.pa.us

3 weeks agoAvoid errors during ALTER SUBSCRIPTION.
Jeff Davis [Wed, 17 Jun 2026 22:34:07 +0000 (15:34 -0700)] 
Avoid errors during ALTER SUBSCRIPTION.

Previously, when retrieving the old Subscription object, constructing
the conninfo could encounter an error during
ForeignServerConnectionString(). ACL errors were handled properly, but
other errors could interfere with a user fixing the problem with ALTER
SUBSCRIPTION.

Reported-by: Chao Li <li.evan.chao@gmail.com>
Reviewed-by: Chao Li <li.evan.chao@gmail.com>
Discussion: https://postgr.es/m/D908370F-2695-4231-851D-17179A6A6F2A@gmail.com

4 weeks agooauth: Skip call-count test for libcurl 8.20.0
Jacob Champion [Wed, 17 Jun 2026 16:57:59 +0000 (09:57 -0700)] 
oauth: Skip call-count test for libcurl 8.20.0

The call-count test in 001_server.pl runs into a recent upstream
regression in Curl:

    https://github.com/curl/curl/issues/21547

The symptom is high CPU usage on some platforms during OAuth HTTP
requests. But it looks like the fix is on track for a June 2026 release,
as part of Curl 8.21.0, so just skip the test if we happen to be using
the broken version.

Reported-by: Andrew Dunstan <andrew@dunslane.net>
Reported-by: Tom Lane <tgl@sss.pgh.pa.us>
Tested-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/CAOYmi%2B%3DyrwMSsHuNJ1V14isA4iSix5Xb3P3VEp1X0BS61MdV4A%40mail.gmail.com
Backpatch-through: 18

4 weeks agolibpq-oauth: Print libcurl version with OAUTHDEBUG_UNSAFE_TRACE
Jacob Champion [Wed, 17 Jun 2026 16:57:20 +0000 (09:57 -0700)] 
libpq-oauth: Print libcurl version with OAUTHDEBUG_UNSAFE_TRACE

When debugging an OAuth trace, it's helpful to know what version of Curl
is in use. The SSL library that Curl is using (which may not be the one
in use by libpq) is also relevant, and it's just as easy to get, so
print that too.

This is being added post-feature-freeze, with RMT approval, in order to
fix some tests in the face of an upstream Curl regression. A subsequent
commit will make use of it in oauth_validator. Backpatch to 18 as well.

Tested-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/CAOYmi%2B%3DkP86t%2BZFFXNQ9G6K4ht7utdmB%3DCzhP%3DZ2wvuBymOTtQ%40mail.gmail.com
Backpatch-through: 18