Commit graph

64524 commits

Author SHA1 Message Date
Jeff Davis
702e9dfd6c 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
2026-06-18 09:20:06 -07:00
Bruce Momjian
9228275b04 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
2026-06-18 12:19:35 -04:00
Nathan Bossart
1f2297b548 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
2026-06-18 10:18:25 -05:00
Nathan Bossart
f0a5c4fbfc 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
2026-06-18 09:31:27 -05:00
Andrew Dunstan
7ca548f23a Revert non-text output formats for pg_dumpall
This reverts the non-text (custom/directory/tar) output format support
for pg_dumpall added by 763aaa06f0 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):

  763aaa06f0  Add non-text output formats to pg_dumpall
  d6d9b96b40  Clean up nodes that are no longer of use in 007_pgdumpall.pl
  01c729e0c7  Fix casting away const-ness in pg_restore.c
  c7572cd48d  Improve writing map.dat preamble
  3c19983cc0  pg_restore: add --no-globals option to skip globals
  abff4492d0  Fix options listing of pg_restore --no-globals
  bb53b8d359  Fix small memory leak in get_dbname_oid_list_from_mfile()
  a793677e57  pg_restore: Remove dead code in restore_all_databases()
  a198c26ded  pg_dumpall: simplify coding of dropDBs()
  ec80215c03  pg_restore: Remove unnecessary strlen() calls in options parsing

Preserved (independent of the feature):

  b2898baaf7  the check_mut_excl_opts() helper in src/fe_utils/option_utils.c
               and its use in pg_dump
  7c8280eeb5  pg_dump's conflicting-option refactor (and tests 002/005)
  be0d0b457c  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)
  74b4438a70  the dangling-grantor-OID GRANT fix (back-patched through 16)
  273d26b75e, d4cb9c3776  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
2026-06-18 09:39:21 -04:00
Alexander Korotkov
ff8bec8c46 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>
2026-06-18 10:30:14 +03:00
Michael Paquier
29fb598b9c 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
2026-06-18 14:05:27 +09:00
Amit Kapila
bdae2c20e8 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
2026-06-18 09:50:33 +05:30
Michael Paquier
850b9218c8 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
2026-06-18 11:49:30 +09:00
Amit Kapila
77b6dd9092 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
2026-06-18 08:02:33 +05:30
Bruce Momjian
34b198b2d7 doc PG 19 relnotes: update to current 2026-06-17 21:44:25 -04:00
Bruce Momjian
2dab2ce3d7 doc PG 19 relnotes: remove VALIDATE CONSTRAINT lock item
Reported-by: Fujii Masao

Discussion: https://postgr.es/m/CAHGQGwGjfu5n5H-jsMp6fAsf-zMJzYWDcJGti6pmr7SHf9BcpA@mail.gmail.com
2026-06-17 21:34:42 -04:00
Fujii Masao
64797ad97d Fix ALTER DOMAIN VALIDATE CONSTRAINT locking
Commit 16a0039dc0 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 16a0039dc0 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
2026-06-18 10:19:15 +09:00
Bruce Momjian
62c09cdc16 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
2026-06-17 19:33:35 -04:00
Jeff Davis
e5c40584a7 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
2026-06-17 15:34:07 -07:00
Jacob Champion
fd5ea2e9e3 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
2026-06-17 09:57:59 -07:00
Jacob Champion
4bd477dcc6 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
2026-06-17 09:57:20 -07:00
Jacob Champion
6222233159 oauth_validator: Print captured stderr after call-count failure
If the call count test fails, you'll reasonably want to know what the
network trace looked like, but that information is currently swallowed.
Print it out instead.

Backpatch-through: 18
2026-06-17 09:57:15 -07:00
Tom Lane
da82fbb8f9 jsonb_plperl, jsonb_plpython: Fix unguarded recursion and loops.
Add check_stack_depth() to Jsonb_to_SV, SV_to_JsonbValue,
PLyObject_FromJsonbContainer, and PLyObject_ToJsonbValue.  Without
this, deeply nested JSONB values can crash the backend with SIGSEGV
instead of raising a proper error.

Also add CHECK_FOR_INTERRUPTS() to the while loop in SV_to_JsonbValue
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.)

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
2026-06-17 11:04:41 -04:00
Nathan Bossart
d2cea63065 vacuumdb: Fix --missing-stats-only for partitioned indexes.
The current form of the catalog query picks up partitioned tables
with expression indexes that lack statistics.  However, since such
indexes never have statistics, there's no point in analyzing them.
To fix, adjust the relevant part of the query to skip partitioned
tables with expression indexes.  While at it, remove the nearby
stainherit check; entries for index expressions always have
stainherit = false.

Author: Baji Shaik <baji.pgdev@gmail.com>
Reviewed-by: Corey Huinker <corey.huinker@gmail.com>
Discussion: https://postgr.es/m/CA%2Bfm-RPE1tEc6CUUPDyRbYTz9tF5Kw47nnk-Zq%3DyYvanbsxyCQ%40mail.gmail.com
Backpatch-through: 18
2026-06-17 09:18:39 -05:00
Michael Paquier
3048e81308 Fix pgstat_count_io_op_time() calls passing incorrect information
Several calls of pgstat_count_io_op_time() have been used as data to
count negative values returned by pg_pread() or pg_pwrite(), leading to
an incorrect count reported, casting them back to uint64.

Most of the problematic calls updated here are adjusted so as we do not
report buggy negative numbers anymore.  In xlogrecovery.c, the spot
updated still counts short reads.  In xlog.c, after a WAL segment
initialization, I/O numbers are aggregated only after checking that the
operation has succeeded.

issues introduced by a051e71e28.

Reported-by: Peter Eisentraut <peter@eisentraut.org>
Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by: Michael Paquier <michael@paquier.xyz>
Reviewed-by: Ayush Tiwari <ayushtiwari.slg01@gmail.com>
Discussion: https://postgr.es/m/0db864e6-4477-4eba-b2be-d3523cc86564@eisentraut.org
Backpatch-through: 18
2026-06-17 16:05:11 +09:00
Heikki Linnakangas
f29299c42b Silence uninitialized variable warning with some compiler versions
The first "if (difffile)" block initializes the startpos variable, and
the second "if (difffile)" block reads it. The second if-condition can
only be true when the first one was true, so the startpos variable is
always initialized when it's used. However, the compiler might not be
able to deduce that, and warn about startpos being used uninitialized.

To silence the warning, rearrange the if-checks. Also, bail out if the
diff file cannot be opened, instead of ignoring it silently.

Author: Mikhail Litsarev <m.litsarev@postgrespro.ru>
Reviewed-by; Ewan Young <kdbase.hack@gmail.com>
Discussion: https://www.postgresql.org/message-id/ee06f058c626cd37babd8c81579ffb1e@postgrespro.ru
2026-06-17 09:00:49 +03:00
David Rowley
1f7dfe8c8e Add tuple deformation test for virtual generated columns
Add coverage for a virtual generated NOT NULL column followed by a
physically stored NOT NULL column.  This exercises the tuple deformation
case fixed by 89eafad297, where TupleDescFinalize() could incorrectly
treat a virtual generated column as part of the guaranteed physical column
prefix and compute cached offsets past it.

Without that fix, deforming the following column could read from the wrong
tuple offset.

Author: Chao Li <li.evan.chao@gmail.com>
Discussion: https://postgr.es/m/A4BC563C-0CA3-4EF3-952A-EA41F9E5BF1E%40gmail.com
2026-06-17 16:57:16 +12:00
Tatsuo Ishii
ab3023ad1e Fix error message typo.
4e5920e6de added an ereport call with the primary error message
starting with upper case, which is prohibited by our error message
style guide. This commit fixes it.

Author: Chao Li <li.evan.chao@gmail.com>
Reviewed-by: Tatsuo Ishii <ishii@postgresql.org>
Discussion: https://postgr.es/m/8BACA715-B9B6-479D-9153-C05F05482664%40gmail.com
2026-06-17 12:43:07 +09:00
Amit Langote
68ace967c1 Fix RI fast-path for domain-typed FK columns
The RI fast path is the first caller to pass a cross-type pf_eq_oprs
operator to ri_HashCompareOp().  Its test for whether a cast can be
skipped, "typeid == righttype", failed when the FK column was a domain,
since typeid is then the domain OID rather than its base type.  The code
concluded no usable conversion existed and threw "no conversion function
from <domain> to <type>" for every valid row.

Look through the domain to its base type.  When pfeqop comes directly
from the index opfamily its right-hand input is getBaseType(fktype), so
getBaseType(typeid) == righttype is the correct test; the PK = PK
fallback (right-hand input opcintype) still fails that test and falls
through to the existing cast lookup unchanged.

Oversight in commit 2da86c1.

Reported-by: Ewan Young <kdbase.hack@gmail.com>
Author: Ewan Young <kdbase.hack@gmail.com>
Reviewed-by: Amit Langote <amitlangote09@gmail.com>
Discussion: https://postgr.es/m/CAON2xHNDFC4cX2atvTpMuC=cK9y7q4J+n3+15w4148AohXEc1w@mail.gmail.com
2026-06-17 11:15:53 +09:00
Tatsuo Ishii
4e5920e6de Fix to not allow null treatment to non window functions.
The null treatment clause (RESPECT NULLS/IGNORE NULLS) are only
allowed to window functions per spec. Previously the check was only
applied to aggregates in window clause. Other types of functions were
allowed to use the clause, which was plain wrong.

To fix this, ParseFuncOrColumn() now checks whether other than window
functions are used with the null treatment clause. If so, error out.

Also remove the unnecessary test for "aggregate functions do not
accept RESPECT/IGNORE NULLS" because it is now checked in the
early-stage new check. The window regression test expected file is
changed accordingly.

Reported-by: jian he <jian.universality@gmail.com>
Reviewed-by: jian he <jian.universality@gmail.com>
Author: Tatsuo Ishii <ishii@postgresql.org>
Discussion: https://postgr.es/m/CACJufxFnm%2BAj2Jyhyd58PtW8e1vTZDKimkZE%2BMashCPSDKw56Q%40mail.gmail.com
2026-06-17 10:12:07 +09:00
Michael Paquier
9285737ac3 Fix another instability in recovery TAP test 004_timeline_switch
The test did not wait for the standby to be connected to the primary.
This breaks one assumption at the beginning of the test, where the
primary is stopped to ensure that all its records are flushed to both
standbys before moving on with its next steps.

If standby_1 finishes ahead of standby_2, the test would be able work
fine as the former waits for the latter.  The opposite is not true,
standby_2 getting ahead of standby_1 would cause the test to fail on
timeout when standby_1 attempts to connect to standby_2.

This commit adds an additional polling query after the two standbys are
started, checking that both standbys are connected to the primary before
processing with the initial steps of the test.

Like 7185eddf05, backpatch down to v14.

Author: Sergey Tatarintsev <s.tatarintsev@postgrespro.ru>
Reviewed-by: Ewan Young <kdbase.hack@gmail.com>
Discussion: https://postgr.es/m/fea4190e-f8b5-4432-a52d-bcbee5f34366@postgrespro.ru
Backpatch-through: 14
2026-06-17 08:42:04 +09:00
Bruce Momjian
9e28c0bd13 doc PG 19 relnotes: update to current
Reported-by: Chao Li
2026-06-16 13:28:48 -04:00
Álvaro Herrera
f50c329f53
logical decoding: Correctly free speculative insertion
The error path in ReorderBufferProcessTXN was not freeing
(reorderbuffer.c's representation of) a speculative insertion record
correctly.  In assert-enabled builds, this leads to an assertion
failure.  In production builds, I see no effect; there may be a small
transient leak, but in an improbable code path such as this, such a leak
is not of any significance.  For users running with assertions enabled,
the crash is annoying.

Fix by having ReorderBufferProcessTXN() free the speculative insert
ahead of freeing the rest of the transaction, and no longer try to
handle that insert as a separate argument to ReorderBufferResetTXN().

This code came in with commit 7259736a6e (14-era).  Backpatch all the
way back.

In branches 14-16, also backpatch the assertion that originally fails in
the problem scenario, which was added by dbed2e3662 (originally
backpatched to 17), that at the end of ReorderBufferReturnTXN() the
in-memory size of the transaction is zero.

Author: Vishal Prasanna <vishal.g@zohocorp.com>
Reviewed-by: Hayato Kuroda <kuroda.hayato@fujitsu.com>
Backpatch-through: 14
Discussion: https://postgr.es/m/19c7623e882.4080fd5426212.311756747309556767@zohocorp.com
2026-06-16 18:13:15 +02:00
Álvaro Herrera
e2a8cabc47
concurrent repack: check there are no leftover toast attribs
Upon reading attributes from the file of concurrent changes, verify that
none are left over unprocessed after we read all columns for the tuple.
This should never happen, so add an elog(ERROR) for it.

While at it, downgrade a nearby message from ereport() to elog().  These
things should never happen.

Author: Aleksander Alekseev <aleksander@tigerdata.com>
Discussion: https://postgr.es/m/CAJ7c6TMSF7cANU8nEJ9E28EvU74tE4H7AzT292Rt3ZuHqqxq8w@mail.gmail.com
2026-06-16 14:26:31 +02:00
Michael Paquier
ae39bd23c6 pg_restore: Use dependency-based matching for STATISTICS DATA
The previous approach introduced by 0dd93de69e was weak in terms of
name matching, as an --index=foo could match with a table with the same
name but from a different schema, pulling in more data than necessary.

For example, imagine the following case:
CREATE SCHEMA s1;
CREATE SCHEMA s2;
CREATE TABLE s1.foo (id int);
INSERT INTO s1.foo SELECT generate_series(1,100);
ANALYZE s1.foo;
CREATE TABLE s2.bar (id int);
CREATE INDEX foo ON s2.bar(id);
INSERT INTO s2.bar SELECT generate_series(1,100);
ANALYZE s2.bar;

A targetted pg_restore --index=foo would grab the relation and attribute
stats of s1.foo on top of the index s2.foo, which is incorrect.  This
commit fixes this scenario by relying on a lookup of the dependencies of
a STATISTICS DATA TOC entry, checking if a TOC entry depends on an index
or another relkind before matching with the names of the objects wanted
for the restore.

Discussion: https://postgr.es/m/ajDBwpxs-otl585H@paquier.xyz
Backpatch-through: 18
2026-06-16 15:58:12 +09:00
Heikki Linnakangas
3f32804918 Fix int32 overflow in ltree_compare()
The expression (len_diff * 10 * (an + 1)) used as the return value of
ltree_compare() is computed at int32 width.  With LTREE_MAX_LEVELS =
65535, the product can exceed INT32_MAX once an ltree has more than
~14,653 levels, which causes the result to wrap and invert its sign.
That corrupts btree ordering as well as the "magnitude" consumed by
ltree_penalty() for GiST page splits.

To fix, split ltree_compare() into two functions.  The new
ltree_compare_distance() function returns a float, which won't
overflow.  It's used by the ltree_penalty() caller.  All the other
callers only care about the sign of the return value, i.e. which of
the arguments is greater, so change ltree_compare() to not multiply
the result with (10 * (an + 1)), which avoids the overflow for those
callers.

Existing btree or GiST indexes on ltree columns containing values with
more than ~14,653 levels may be corrupt and should be REINDEXed.

Add a regression test based on the reporter's PoC.

Author: Ayush Tiwari <ayushtiwari.slg01@gmail.com>
Reported-by: 王跃林 <violin0613@tju.edu.cn>
Discussion: https://www.postgresql.org/message-id/AI6AnABgKW93Qbx1jVzi84r9.8.1781322625756.Hmail.3020001251%40tju.edu.cn
Backpatch-through: 14
2026-06-16 09:29:47 +03:00
Michael Paquier
f6e4ec0a70 Reject oversized MCV lists in pg_restore_extended_stats()
import_mcv(), called by pg_restore_extended_stats(), allowed a list of
MCV items to be larger than the maximum supported when the stats are
loaded back in statext_mcv_deserialize() (STATS_MCVLIST_MAX_ITEMS or 10k
items).  A follow-up attempt at loading them would cause a failure,
statext_mcv_deserialize() blocking any attempts.

Attempts at restoring MCV lists too long are now rejected, generating a
WARNING like other inconsistent inputs.

Author: Ewan Young <kdbase.hack@gmail.com>
Discussion: https://postgr.es/m/CAON2xHORd2ESXm1KcVeeZ0Kd_aJk4dL4M2WLtzVDM4puaZ-20w@mail.gmail.com
2026-06-16 15:14:58 +09:00
David Rowley
e5f94c4808 Fix various query jumble comments
Some comments for struct WindowFunc were trying to detail which fields
were irrelevant for query jumble but the list had not been kept
up-to-date.  Here we fix that by removing the comment to allow the
"query_jumble_ignore" attribute to self-document.  This involved
removing similar comments from other structs.

While we're on the topic, improve comments around why Consts only jumble
the "consttype" and also add some rationale about why various other fields
are ignored.

Reported-by: jian he <jian.universality@gmail.com>
Author: David Rowley <dgrowleyml@gmail.com>
Author: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/CACJufxEWeP2SLVMsbFNynd0pQnwbxh6U-v1nq5ccf9mSvBZntw%40mail.gmail.com
2026-06-16 13:42:21 +12:00
Michael Paquier
d3b345eef3 pg_dump: Remove dead code in TAP tests
The schema_only_with_statistics test scenario was referenced in
002_pg_dump.pl, but was associated to no command sequence since
0ed92cf50c.

Issue discovered while investigating a different bug.  Perhaps this
cleanup is not worth backpatching, but there is also an argument in
favor of reducing noise when touching this area of the code in stable
branches.

Reviewed-by: Ewan Young <kdbase.hack@gmail.com>
Reviewed-by: Ayush Tiwari <ayushtiwari.slg01@gmail.com>
Discussion: https://postgr.es/m/ai-y0S7Z25NlrG_n@paquier.xyz
Backpatch-through: 18
2026-06-16 08:31:39 +09:00
Michael Paquier
0dd93de69e Fix inconsistencies with pg_restore --statistics[-only]
Attempting to restore a schema, a table or an index with
--only-statistics skipped all the statistics of the objects wanted.
Like for pg_dump, statistics should be included, so this created an
assymetry between dump and restore.

A second set of problems existed for --table and --index, where the
presence of --statistics skipped the restore of the stats of the
object(s) targetted.

This issue has been reported originally as related to an inconsistency
with the way extended stats restore is handled in Postgres v19, but the
issue is related to the restore of relation and attribute statistics in
v18.  Some TAP tests are added to cover all these cases.

Reported-by: Chao Li <li.evan.chao@gmail.com>
Author: Chao Li <li.evan.chao@gmail.com>
Author: Michael Paquier <michael@paquier.xyz>
Reviewed-by: Corey Huinker <corey.huinker@gmail.com>
Discussion: https://postgr.es/m/66E80CAB-527C-42B1-BB65-3F82CF4AD998@gmail.com
Backpatch-through: 18
2026-06-16 08:21:08 +09:00
Tom Lane
a75bd485b5 Clean up quoting of variable strings within replication commands.
Our handling of quoting within replication commands was pretty
sloppy, typically looking like
        appendStringInfo(&cmd, " SLOT \"%s\"", options->slotname);
This is fine as long as options->slotname doesn't contain a double
quote mark, but what if it does?  In principle this'd allow injection
of harmful options into replication commands, in the probably-unlikely
case that a slot name comes from untrustworthy input.  We ought to
clean that up.

Moreover, even the places that were trying to be more careful
generally got it wrong, because they used quoting subroutines
intended for SQL commands rather than something that will work
with the replication-command scanner repl_scanner.l.  For example,
several places naively use PQescapeLiteral() to quote option values
for replication commands.  If the string contains a backslash,
PQescapeLiteral() will produce E'...' literal syntax, which
repl_scanner.l doesn't recognize.  Another near miss was to use
quote_identifier() to quote identifiers.  That function won't quote
valid lowercase identifiers unless they match SQL keywords ... but in
this context, replication keywords are what matter.  Neither of these
errors seem to risk string injection, but they definitely can cause
syntax errors in replication commands that ought to be valid.

We can clean all this up by using simple quoting logic that just
doubles single or double quotes respectively.

Or at least, we could if repl_scanner.l handled doubled double quotes
in identifiers, but for some reason it doesn't!  So the first step in
this fix has to be to fix that.  (The fact that we'll later reject
slot names containing double quotes is very far short of justifying
this omission.)

Having done that, this patch runs around and applies correct
quoting in all places that generate replication commands containing
strings coming from outside the immediate context.  Probably some
of these places are safe because of restrictions elsewhere, but it
seems best to just quote all the time.

This was originally reported as a security bug, which it could be
if replication slot names or parameters were to originate from
untrustworthy sources.  But the security team concluded that that
was a very improbable situation, so we're just going to fix this
as a regular bug.

Reported-by: Team Dhiutsa
Author: Tom Lane <tgl@sss.pgh.pa.us>
Reviewed-by: Ayush Tiwari <ayushtiwari.slg01@gmail.com>
Discussion: https://postgr.es/m/1648659.1781287310@sss.pgh.pa.us
Backpatch-through: 14
2026-06-15 15:35:37 -04:00
Nathan Bossart
6678b58d78 doc: Fix "Prev" link.
Presently, the "Prev" link on the page for background workers sends
you to the middle of the previous chapter instead of the actual
previous page.  This appears to be caused by a libxml2 bug, but
regardless, a minimal fix is to change the link generation code to
use [position()=last()] instead of [last()] in the predicate on the
union of reverse axes.

Reviewed-by: Ayush Tiwari <ayushtiwari.slg01@gmail.com>
Discussion: https://postgr.es/m/aim4AZorFKaC7Wrf%40nathan
Backpatch-through: 14
2026-06-15 12:16:38 -05:00
Tom Lane
8ebbf79a83 Doc: reword discussion of asterisk after table names in FROM.
The syntax "tablename *" has been obsolete for years, but we want to
retain it and its documentation for backward compatibility reasons.
However, the documentation wording was confusing and could be
understood to mean that "tablename *" is the same as "ONLY tablename".

Reported-by: Jochen Bandhauer <jochen.bandhauer@gmx.net>
Author: Laurenz Albe <laurenz.albe@cybertec.at>
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/178125831604.1285960.8250607197280951685@wrigleys.postgresql.org
2026-06-15 13:07:57 -04:00
Tom Lane
ca6969629d Modernize pg_bsd_indent's error/warning reporting code.
Late-model clang complains that these functions should be labeled
with "format(printf, 2, 3)", and it's right.  But let's go a bit
further and also make use of varargs, to remove duplication and
allow these functions to be used with non-integer input values.

Since no good deed goes unpunished, I had to also adjust a couple
of call sites.  They weren't wrong as-is, since the size_t-sized
arguments were coerced to int on the way into diag3().  But
without that, we have to adjust the format strings.

The point of this is to suppress compiler warnings, so back-patch
into branches containing pg_bsd_indent, even though there's no
functional change.

Author: Tom Lane <tgl@sss.pgh.pa.us>
Reviewed-by: Ayush Tiwari <ayushtiwari.slg01@gmail.com>
Discussion: https://postgr.es/m/1645041.1781283554@sss.pgh.pa.us
Backpatch-through: 16
2026-06-15 12:22:55 -04:00
Heikki Linnakangas
e0511883ca Fix PQdescribePrepared with more than 7498 params
If a query has more than 7498 params, the ParameterDescription message
exceeds the 30000 byte limit on messages that are not specifically
marked as possibly being longer than that (VALID_LONG_MESSAGE_TYPE).
To fix, add ParameterDescription to the list.

Author: Ning Sun <classicning@gmail.com>
Discussion: https://www.postgresql.org/message-id/dbfb4b65-0aa8-470a-8b87-b6496160b28a@gmail.com
Backpatch-through: 14
2026-06-15 11:28:45 +03:00
Michael Paquier
b78cd2bda5 Trim regression test expected output for xml
This commit reduces the number of expected output files for the "xml"
test from three to two (well, mostly one, see below for details).

xml_2.out existed to handle some differences in output due to libxml2
2.9.3, due to some error context missing (085423e3e3).  This file is
removed, by tweaking the XML inputs to trigger the same error patterns
for the problematic 2.9.3 and other libxml2 versions.  This part is
authored by Tom Lane.

xml_1.out (no libxml2 support) is reduced in size by adding an \if query
that exits the test early.  This still checks NO_XML_SUPPORT() through
xmlin().  The rest of the test is skipped if XML input cannot be
handled by the backend.  This part has been written by me.

Author: Tom Lane <tgl@sss.pgh.pa.us>
Author: Michael Paquier <michael@paquier.xyz>
Reviewed-by: Daniel Gustafsson <daniel@yesql.se>
Discussion: https://postgr.es/m/aiu6CXO67q-s70n5@paquier.xyz
Backpatch-through: 14
2026-06-15 11:37:52 +09:00
Tom Lane
2963ddeef2 Doc: remove stale entry for removed aclitem[] ~ aclitem operator.
Commit 2f70fdb06 removed the deprecated containment operator
~(aclitem[],aclitem) from the catalogs, but missed removing its entry
from the documentation.  (Arguably the blame should fall on c62dd80cd,
which added this entry in contravention of the longstanding policy
that we don't document deprecated aliases in the first place.)

Author: Shinya Kato <shinya11.kato@gmail.com>
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/CAOzEurQSyR5psWukyhUz1LtxyO55C2Vfp0Fmt8w2jGKxhszQmQ@mail.gmail.com
Backpatch-through: 14
2026-06-14 11:01:48 -04:00
Etsuro Fujita
0131e8fc50 Fix oversight in commit aa1f93a33.
Since the remote column names of a foreign table could be longer than
NAMEDATALEN, remattrmap_cmp(), which compares such column names, should
have used strcmp(), not strncmp() with n=NAMEDATALEN.

Author: Chao Li <li.evan.chao@gmail.com>
Reviewed-by: Etsuro Fujita <etsuro.fujita@gmail.com>
Discussion: https://postgr.es/m/81D981EB-ECC1-495D-8EAC-5CFB67B2CF77%40gmail.com
2026-06-14 16:00:00 +09:00
Alexander Korotkov
da1eff08a5 amcheck: Use correct varlena size accessor in bt_normalize_tuple()
bt_normalize_tuple() uses VARSIZE() to get the size of varlena, even though
it's not yet known, that it has a 4-byte header.  Fix this by replacing a
accessor with a universal VARSIZE_ANY().

Backpatch to all supported versions.

Reported-by: Andres Freund <andres@anarazel.de>
Discussion: https://postgr.es/m/7ckc7oka4bvafkf5bwlqs6ygrhlsbhz25ppozfch7zbuxcx3rf%40e4pr4oqenalc
Author: Andrey Borodin <x4mmm@yandex-team.ru>
Reviewed-by: Alexander Korotkov <aekorotkov@gmail.com>
Backpatch-through: 14
2026-06-14 04:04:48 +03:00
Andrew Dunstan
3e3d7875e9 Adjust cross-version upgrade tests for seg_out() fix
Commit 0e1f1ed157 taught seg_out() to print the certainty indicator
on an interval's upper boundary, but it was back-patched only as far
as v14.  When upgrading from an older release, the old server prints
the one test_seg row exercising that case ('4.6 .. ~7.0') without the
indicator, so the pre- and post-upgrade dumps do not match.  Make
AdjustUpgrade.pm delete just that row; seg's comparison function does
distinguish the certainty indicators, so the otherwise identical row
'4.6 .. 7.0' is unaffected.

Back-patch to all supported branches.

Per buildfarm members crake and fairywren.

Discussion: https://postgr.es/m/5ccbdbde-6467-4a10-bf4d-0be73a05ce8d@dunslane.net
2026-06-12 18:05:25 -04:00
Álvaro Herrera
5459223edb
Fix translatable string construction in psql
Similar to commit 3692a622d3, for a slightly different code pattern in
psql.

No backpatch to avoid disrupting translation in stable branches.

Author: Álvaro Herrera <alvherre@kurilemu.de>
Reviewed-by: Peter Smith <smithpb2250@gmail.com>
Discussion: https://postgr.es/m/airjxKXx7aTG8kfE@alvherre.pgsql
2026-06-12 14:24:41 +02:00
Michael Paquier
0b74df66f0 Update expected regression test output for xml_2.out
This one has been forgotten in 8bf257aeba.  Per report from buildfarm
member massasauga.

Backpatch-through: 14
2026-06-12 12:37:21 +09:00
Michael Paquier
a8ee70bd5e Fix second race with timeline selection during promotion
read_local_xlog_page_guts has the same race as logical_read_xlog_page:
RecoveryInProgress() can return true during promotion, impacting the
availability of the operations doing WAL page reads with this callback.

This problem is similar to eb4e7224a1 that has addressed the issue for
logical replication, impacting more areas of the code where this WAL
page callback can be used (same narrow window during promotion, same
availability issue):
- pg_walinspect.
- Slot advance (SQL function).
- Slot creation.

Repack workers (v19~) and 2PC files (since forever) can also use this
callback, but they are irrelevant as far as I know.  A test is added
with the SQL lookup functions.  This part relies on injection points,
and is backpatched down to v18, like the test added for eb4e7224a1.

This issue could probably be fixed as well in v14 and v15 for
pg_walinspect.  However, I also feel that there is a conservative
argument about consistency here due to the support of logical decoding
on standbys, so let's limit ourselves to v16 for now.  pg_walinspect is
used less in the field compared to the two other operations, making
addressing this problem less attractive in these two older branches.

Reported-by: Xuneng Zhou <xunengzhou@gmail.com>
Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by: Xuneng Zhou <xunengzhou@gmail.com>
Reviewed-by: Hayato Kuroda <kuroda.hayato@fujitsu.com>
Discussion: https://postgr.es/m/7daef094-abf3-4672-bc23-3df4763b16a3%40gmail.com
Backpatch-through: 16
2026-06-12 11:44:11 +09:00
Amit Langote
4113873a5a Confine RI fast-path batching to the top transaction level
The FK fast-path batching added in b7b27eb41a buffers rows in a
transaction-lived cache (ri_fastpath_cache) keyed by constraint OID.
Running user-defined cast and equality functions during a batch flush,
together with the cache's lifetime and iteration, exposed two defects
reachable by an unprivileged table owner.

First, on subtransaction abort ri_FastPathSubXactCallback discarded the
entire cache.  An entry's batch holds rows buffered by the enclosing
transaction, not just the aborting subxact -- the cache is keyed by
constraint, so a single entry can mix rows from multiple subxact levels.
An internal subxact abort during after-trigger firing (e.g. a PL/pgSQL
BEGIN ... EXCEPTION block) therefore dropped buffered rows of the outer
transaction without running their FK checks, letting orphan rows commit
behind a constraint that still reported itself valid.  The discard also
left relations opened by the batch unclosed, producing "resource was not
closed" warnings.

Second, ri_FastPathEndBatch flushes by iterating the cache with
hash_seq_search.  If flush-time user code inserts into a different
fast-path FK table, a new entry is added to the cache mid-scan; it may
land in a bucket the scan has already passed and never be reached, and
ri_FastPathTeardown then destroys the cache without flushing it,
silently dropping that check.

Cleanly unwinding the cache on subxact abort would require tracking the
originating subxact of each buffered row, since rows from different
levels share an entry (the cache is keyed by constraint) and deferred
constraints cannot be flushed early at a subxact boundary.  Rather than
add that bookkeeping, confine batching to the top transaction level: in
RI_FKey_check, when GetCurrentTransactionNestLevel() > 1, use the
per-row fast path (ri_FastPathCheck) instead of buffering.  Rows checked
inside a subtransaction are then verified immediately and roll back
cleanly with their subtransaction, and the cache only ever holds
top-level rows.  With the cache confined to the top level, a
subtransaction abort has nothing of its own to discard, so
ri_FastPathSubXactCallback is removed along with its registration.

For the second defect, add a cache-wide flag (ri_fastpath_flushing) set
while ri_FastPathEndBatch iterates the cache.  A re-entrant FK check
arriving while the flag is set takes the per-row path rather than adding
an entry to the cache being scanned, so no entry can be missed and torn
down unflushed.  The flag is cleared in a PG_FINALLY so a flush that
throws (a reported violation or an error from user code) does not leave
it stuck.  As defensive insurance it is also cleared in
ri_FastPathXactCallback() at transaction end.

The per-row fast path still bypasses SPI and stays well ahead of the
pre-19 SPI-based check.  A fuller fix that preserves batching across
subtransactions -- whether by tracking the originating subxact of each
buffered row or by per-subxact cache stacks merged into the parent on
commit -- is left for a future release.

The subtransaction-abort case is covered by a new regression test.  The
mid-scan cross-table case depends on hash bucket placement and so is not
reliably reproducible in a portable test, but the flag prevents it by
construction.

Reported-by: Nikolay Samokhvalov <nik@postgres.ai>
Reviewed-by: Nikolay Samokhvalov <nik@postgres.ai>
Reviewed-by: Ayush Tiwari <ayushtiwari.slg01@gmail.com>
Reviewed-by: Junwang Zhao <zhjwpku@gmail.com>
Discussion: https://postgr.es/m/CAM527d9exRCdWrhJOnAxk_vACg7sr_yPoaJp_+uCFY0qP8v=aw@mail.gmail.com
2026-06-12 11:30:38 +09:00