PostgreSQL 20.0 (upcoming) commit log

Introduce bms_offset_members() function

commit   : bb7ded1eebed708865d9bb0a3513c7ed3afe7065    
  
author   : David Rowley <drowley@postgresql.org>    
date     : Thu, 9 Jul 2026 01:11:42 +1200    
  
committer: David Rowley <drowley@postgresql.org>    
date     : Thu, 9 Jul 2026 01:11:42 +1200    

Click here for diff

Effectively, a function to bitshift members by the specified number of  
bits.  We have various fragments of code doing this manually with a  
bms_next_member() -> bms_add_member() loop.  We can do this more  
efficiently in terms of CPU and memory allocation by making a new  
Bitmapset and bitshifting in the words of the old set to populate it.  
  
Author: David Rowley <dgrowleyml@gmail.com>  
Reviewed-by: Chao Li <li.evan.chao@gmail.com>  
Reviewed-by: Greg Burd <greg@burd.me>  
Discussion: https://postgr.es/m/CAApHDvq=eEdw2Qp+aSzSOtTSe+h0fnVQ55CcTNqBkLDYiRZmxw@mail.gmail.com  

M src/backend/nodes/bitmapset.c
M src/backend/optimizer/plan/setrefs.c
M src/backend/optimizer/prep/prepjointree.c
M src/backend/rewrite/rewriteManip.c
M src/backend/statistics/extended_stats.c
M src/include/nodes/bitmapset.h
M src/test/modules/test_bitmapset/expected/test_bitmapset.out
M src/test/modules/test_bitmapset/sql/test_bitmapset.sql
M src/test/modules/test_bitmapset/test_bitmapset–1.0.sql
M src/test/modules/test_bitmapset/test_bitmapset.c

Add hints for sequence synchronization permission warnings

commit   : 3601f976c2e99123203413fd157f117632b3db78    
  
author   : Fujii Masao <fujii@postgresql.org>    
date     : Wed, 8 Jul 2026 18:16:38 +0900    
  
committer: Fujii Masao <fujii@postgresql.org>    
date     : Wed, 8 Jul 2026 18:16:38 +0900    

Click here for diff

Sequence synchronization reports insufficient privileges on publisher  
and subscriber sequences, but the warnings do not indicate which role  
needs which privilege. This makes common configuration mistakes harder  
to diagnose.  
  
Add HINT messages for these warnings. Publisher-side warnings suggest  
granting SELECT to the role used for the replication connection.  
Subscriber-side warnings suggest granting UPDATE to the subscription  
owner when run_as_owner is enabled. Otherwise, the worker runs as the  
sequence owner, so no useful GRANT hint can be provided.  
  
Suggested-by : Amit Kapila <amit.kapila16@gmail.com>  
Author: Fujii Masao <masao.fujii@gmail.com>  
Reviewed-by: Amit Kapila <amit.kapila16@gmail.com>  
Reviewed-by: Bharath Rupireddy <bharath.rupireddyforpostgres@gmail.com>  
Discussion: https://postgr.es/m/CAA4eK1JOo0aJRhFHNWpj3hMwaTtNOopY34f1Lh_QD=z=+DrzWQ@mail.gmail.com  
Backpatch-through: 19  

M doc/src/sgml/logical-replication.sgml
M src/backend/replication/logical/sequencesync.c

doc: Clarify pg_get_sequence_data() NULL-return cases

commit   : 5412abc22d068ff52e13c60309e9d54eb08e6403    
  
author   : Fujii Masao <fujii@postgresql.org>    
date     : Wed, 8 Jul 2026 18:15:33 +0900    
  
committer: Fujii Masao <fujii@postgresql.org>    
date     : Wed, 8 Jul 2026 18:15:33 +0900    

Click here for diff

The documentation previously said that pg_get_sequence_data() returns  
a row of NULL values if the sequence does not exist or if the current  
user lacks privileges on it. This was incomplete and could be misleading.  
A nonexistent relation name is rejected during regclass input conversion,  
while the function returns NULLs for a nonexistent relation OID and  
several other cases.  
  
This commit clarifies that the function returns NULLs when the specified  
relation OID does not exist, the relation is not a sequence, the current  
user lacks SELECT privilege on the sequence, the sequence belongs to  
another session's temporary schema, or it is an unlogged sequence on  
a standby server.  
  
Author: Amit Kapila <amit.kapila16@gmail.com>  
Reviewed-by: Fujii Masao <masao.fujii@gmail.com>  
Discussion: https://postgr.es/m/CAA4eK1JOo0aJRhFHNWpj3hMwaTtNOopY34f1Lh_QD=z=+DrzWQ@mail.gmail.com  
Backpatch-through: 19  

M doc/src/sgml/func/func-sequence.sgml

Resolve unknown-type literals in property expressions

commit   : 57f93af36f02a2559b005491d9fb0da660e32850    
  
author   : Peter Eisentraut <peter@eisentraut.org>    
date     : Wed, 8 Jul 2026 10:11:11 +0200    
  
committer: Peter Eisentraut <peter@eisentraut.org>    
date     : Wed, 8 Jul 2026 10:11:11 +0200    

Click here for diff

When a string literal is provided as a property expression, the data  
type of the property was set to "unknown", which may lead to various  
failures when the property is used in GRAPH_TABLE or when its data  
type is compared against other properties with the same name.  To fix  
this, call resolveTargetListUnknowns() on the targetlist of new  
properties being added to resolve unknown type literals.  
  
Reported-by: Noah Misch <noah@leadboat.com>  
Author: Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>  
Discussion: https://www.postgresql.org/message-id/flat/20260630173053.51.noahmisch%40microsoft.com  

M src/backend/commands/propgraphcmds.c
M src/test/regress/expected/create_property_graph.out
M src/test/regress/sql/create_property_graph.sql

Fix replace_property_refs() ignoring the root of expression tree

commit   : 16a4b3ef8eebd2f3da44c17523fef23d2de80679    
  
author   : Peter Eisentraut <peter@eisentraut.org>    
date     : Wed, 8 Jul 2026 09:40:46 +0200    
  
committer: Peter Eisentraut <peter@eisentraut.org>    
date     : Wed, 8 Jul 2026 09:40:46 +0200    

Click here for diff

replace_property_refs() called expression_tree_mutator() with the root  
of the expression tree as the input node.  But  
expression_tree_mutator() does not call the mutator function on the  
root node, so the root node remains unchanged.  If the root node is a  
property reference or a lateral reference -- the two node kinds that  
replace_property_refs_mutator() rewrites -- it is returned unchanged.  
Modules after the rewriter do not know about property reference nodes,  
resulting in "ERROR: unrecognized node type: 63".  Since varlevelsup  
of lateral references is not incremented, they are not resolved  
correctly in the planner, leading to many different symptoms.  Fix  
this by calling replace_property_refs_mutator() directly from  
replace_property_refs(), similar to how other mutator functions do.  
  
The only case when a property reference or a lateral reference can be  
the root of a GRAPH_TABLE expression tree is when it is a bare  
property reference or a bare lateral reference in the WHERE clause.  
The COLUMNS clause is passed to replace_property_refs() as a  
targetlist.  Every other expression has at least one expression node  
covering the property reference or a lateral reference in the  
expression tree.  That explains why this bug was not seen so far.  
  
Author: Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>  
Reported-by: Noah Misch <noah@leadboat.com>  
Discussion: https://www.postgresql.org/message-id/flat/20260630173053.51.noahmisch%40microsoft.com  

M src/backend/rewrite/rewriteGraphTable.c
M src/test/regress/expected/graph_table.out
M src/test/regress/sql/graph_table.sql

Fix misspelling in docs

commit   : 4b587f666a73a5f8e2f8a47a1be010ffcb084955    
  
author   : Heikki Linnakangas <heikki.linnakangas@iki.fi>    
date     : Wed, 8 Jul 2026 10:20:34 +0300    
  
committer: Heikki Linnakangas <heikki.linnakangas@iki.fi>    
date     : Wed, 8 Jul 2026 10:20:34 +0300    

Click here for diff

Reported-by: Erik Rijkers <er@xs4all.nl>  
Discussion: https://www.postgresql.org/message-id/6223b7dc-bfee-fcff-88d9-13f99b8d4897@xs4all.nl  
Backpatch-through: 19  

M doc/src/sgml/xfunc.sgml

injection_points: Switch wait/wakeup to rely on atomics

commit   : 8daeaa9b642c3c23cbc516da80d50aade6f4dc07    
  
author   : Michael Paquier <michael@paquier.xyz>    
date     : Wed, 8 Jul 2026 14:34:09 +0900    
  
committer: Michael Paquier <michael@paquier.xyz>    
date     : Wed, 8 Jul 2026 14:34:09 +0900    

Click here for diff

This change switches the implementation of wait and wakeups in the  
module injection_points to not rely anymore on condition variables,  
using a more primitive implementation based on atomics.  The former  
implementation required a PGPROC, making it impossible to inject waits  
in the postmaster or during authentication.  A couple of use cases have  
popped up for these in the past, where this would have become handy.  
  
The loop in the wait callback that relied on a condition variable is  
replaced by an atomic counter, whose check increases over time in an  
exponential manner (starts at 10us for quick responsiveness, up to  
100ms).  
  
This change may be backpatched at some point depending on how much  
testing coverage is wanted.  Let's limit ourselves to HEAD for now,  
checking things first with the buildfarm.  
  
Creating a wait still requires the SQL interface.  We are looking at  
expanding that with an alternative implementation, so as early startup  
or authentication waits would become possible.  This refactoring piece  
is mandatory to achieve this goal.  
  
Reviewed-by: Andrey Borodin <x4mmm@yandex-team.ru>  
Discussion: https://postgr.es/m/aher0VsjJ8xeNgLq@paquier.xyz  

M src/test/modules/injection_points/injection_points.c

Fix more Datum conversion inconsistencies

commit   : d92e98340fcb4c3ef728b3e8204573bdc86098f7    
  
author   : Michael Paquier <michael@paquier.xyz>    
date     : Wed, 8 Jul 2026 13:22:50 +0900    
  
committer: Michael Paquier <michael@paquier.xyz>    
date     : Wed, 8 Jul 2026 13:22:50 +0900    

Click here for diff

This is a continuation of the work done in ac59a90bef45.  The  
*GetDatum() macros for output should match with what the SQL functions  
use as DatumGet*() in input.  
  
Aleksander has spotted some of the areas patched here, for pageinspect.  
I have spotted the rest while digging into the state of the tree.  
  
There is no behavior change after this commit, since all the affected  
values are small enough that the signed bit is never used.  
  
Author: Aleksander Alekseev <aleksander@tigerdata.com>  
Author: Michael Paquier <michael@paquier.xyz>  
Discussion: https://postgr.es/m/afLsqRjVqKK8hhKk@paquier.xyz  

M contrib/pageinspect/brinfuncs.c
M contrib/pageinspect/btreefuncs.c
M contrib/pageinspect/ginfuncs.c
M contrib/pageinspect/gistfuncs.c
M contrib/pageinspect/heapfuncs.c
M contrib/pageinspect/rawpage.c
M contrib/pg_logicalinspect/pg_logicalinspect.c
M contrib/pg_walinspect/pg_walinspect.c
M contrib/pgstattuple/pgstatindex.c
M src/backend/access/gin/ginlogic.c
M src/backend/access/transam/xlogfuncs.c
M src/backend/catalog/pg_proc.c
M src/backend/utils/adt/lockfuncs.c

doc: Clarify COPY FROM WHERE expression restrictions

commit   : d35e8babc4602c73ec4f66f93a5004a2ead62438    
  
author   : Fujii Masao <fujii@postgresql.org>    
date     : Wed, 8 Jul 2026 12:44:06 +0900    
  
committer: Fujii Masao <fujii@postgresql.org>    
date     : Wed, 8 Jul 2026 12:44:06 +0900    

Click here for diff

Commit aa606b9316a disallowed generated columns in COPY FROM WHERE  
expressions, and commit 21c69dc73f9 disallowed system columns.  
However, the COPY reference page still mentions only the restriction  
on subqueries.  
  
Update the documentation to also list generated columns and system  
columns as unsupported in COPY FROM WHERE expressions.  
  
Backpatch the generated-column documentation change to all supported  
versions. Backpatch the system-column documentation change to v19,  
where that restriction was introduced.  
  
Author: Fujii Masao <masao.fujii@gmail.com>  
Reviewed-by: Ayush Tiwari <ayushtiwari.slg01@gmail.com>  
Discussion: https://postgr.es/m/CAHGQGwEgxErc54yVOAVWCsr1O=8pgw4oKRPuEQ9mfhkoYGR_XA@mail.gmail.com  
Backpatch-through: 14  

M doc/src/sgml/ref/copy.sgml

pg_recvlogical: send final feedback on SIGINT/SIGTERM shutdown

commit   : b5a8018116c422f39de94f69f0108ff0c9224f0a    
  
author   : Fujii Masao <fujii@postgresql.org>    
date     : Wed, 8 Jul 2026 12:16:34 +0900    
  
committer: Fujii Masao <fujii@postgresql.org>    
date     : Wed, 8 Jul 2026 12:16:34 +0900    

Click here for diff

Previously, when pg_recvlogical exited due to SIGINT or SIGTERM,  
it could terminate without sending final feedback for the last decoded  
changes it had already written locally. So, if pg_recvlogical was  
restarted afterwards, the server-side logical replication slot could  
still point behind those changes, causing them to be sent again.  
  
Make pg_recvlogical send final feedback once more during SIGINT/SIGTERM  
shutdown, before sending CopyDone. This gives the server one more chance  
to advance the slot far enough to avoid resending already-written data,  
so users are less likely to see duplicate decoded output after stopping  
and restarting pg_recvlogical.  
  
This remains a best-effort improvement rather than a guarantee. Depending  
on when the signal arrives, pg_recvlogical can already have written  
decoded output that the server cannot yet safely treat as confirmed, so a  
later restart can still receive duplicate data.  
  
Author: Fujii Masao <masao.fujii@gmail.com>  
Reviewed-by: Ayush Tiwari <ayushtiwari.slg01@gmail.com>  
Discussion: https://postgr.es/m/CAHGQGwE83z9O=X7ADMsSa3e1EuP3_GgqHjFt5SmPDNxZo_wgJA@mail.gmail.com  

M src/bin/pg_basebackup/pg_recvlogical.c
M src/bin/pg_basebackup/t/030_pg_recvlogical.pl

Tighten nullingrels checks for outer joins

commit   : 4721430f199ffaf0936dc19bd473f34e8b1ee791    
  
author   : Richard Guo <rguo@postgresql.org>    
date     : Wed, 8 Jul 2026 12:02:21 +0900    
  
committer: Richard Guo <rguo@postgresql.org>    
date     : Wed, 8 Jul 2026 12:02:21 +0900    

Click here for diff

When fixing up the targetlist and qpqual of an outer join, we must  
account for the effects of the outer join.  Vars and PHVs appearing  
there are logically above the join, so they should have nullingrels  
equal to the input Vars/PHVs' nullingrels plus the bit added by the  
outer join.  
  
Determining the effects of the outer join can be tricky when the join  
has been commuted with another one per outer join identity 3.  In this  
case, the Vars/PHVs in the join's targetlist and qpqual should have  
the same nullingrels that they would if the two joins had been done in  
syntactic order.  Unfortunately, in setrefs.c, we don't have enough  
information to identify what that should be, so we have to use  
superset nullingrels matches instead of exact ones.  
  
However, we can tighten the check somewhat.  Currently, we check  
whether the jointype is JOIN_INNER and use NRM_SUPERSET if it is not.  
We can improve this by checking whether the Join node has non-empty  
ojrelids and using NRM_SUPERSET only in that case.  This allows us to  
perform exact matches in more situations.  
  
To support this, we record the outer-join relids in Join plan nodes.  
This information can also improve EXPLAIN (RANGE_TABLE) output by  
showing which outer-join relids are completed by each Join plan node.  
We may discover additional uses for this information in the future.  
  
Author: Richard Guo <guofenglinux@gmail.com>  
Discussion: https://postgr.es/m/CAMbWs482_DFHzQ079ZPp6c8UvmFdz3Jj+4K8tVRu9g2Bw34NPA@mail.gmail.com  

M contrib/pg_overexplain/expected/pg_overexplain.out
M contrib/pg_overexplain/pg_overexplain.c
M contrib/pg_overexplain/sql/pg_overexplain.sql
M src/backend/optimizer/plan/createplan.c
M src/backend/optimizer/plan/setrefs.c
M src/include/nodes/plannodes.h

Remove nrm_match parameter from fix_upper_expr

commit   : 3b0991059f33305118d850bb94fc9dca590c4ed6    
  
author   : Richard Guo <rguo@postgresql.org>    
date     : Wed, 8 Jul 2026 12:01:44 +0900    
  
committer: Richard Guo <rguo@postgresql.org>    
date     : Wed, 8 Jul 2026 12:01:44 +0900    

Click here for diff

With the changes in the previous commit, we can now use exact  
nullingrels matches in all cases when fixing up expressions of  
upper-level plan nodes that are not joins.  Therefore, we can remove  
the nrm_match parameter from fix_upper_expr(), along with the  
corresponding field in fix_upper_expr_context.  
  
Author: Richard Guo <guofenglinux@gmail.com>  
Discussion: https://postgr.es/m/CAMbWs482_DFHzQ079ZPp6c8UvmFdz3Jj+4K8tVRu9g2Bw34NPA@mail.gmail.com  

M src/backend/optimizer/plan/setrefs.c

Use exact nullingrels matches for NestLoopParams

commit   : 9dce6b5a42bbf97721bd0aeef28688745e77e82f    
  
author   : Richard Guo <rguo@postgresql.org>    
date     : Wed, 8 Jul 2026 12:00:36 +0900    
  
committer: Richard Guo <rguo@postgresql.org>    
date     : Wed, 8 Jul 2026 12:00:36 +0900    

Click here for diff

We have been using NRM_SUBSET to process NestLoopParams in setrefs.c,  
because Vars or PHVs in NestLoopParam expressions may previously have  
had nullingrels that were just subsets of those in the Vars or PHVs  
actually available from the outer side.  
  
Since 66e9df9f6, identify_current_nestloop_params ensures that any  
Vars or PHVs seen in a NestLoopParam expression have nullingrels that  
include exactly the outer-join relids that appear in the outer side's  
output and can null the respective Var or PHV.  As noted in that  
commit's message, we can now safely use NRM_EQUAL to process  
NestLoopParams in setrefs.c.  
  
This patch makes that change and removes the definition of NRM_SUBSET,  
along with all remaining checks for it, since it is no longer used.  
  
Author: Richard Guo <guofenglinux@gmail.com>  
Discussion: https://postgr.es/m/CAMbWs482_DFHzQ079ZPp6c8UvmFdz3Jj+4K8tVRu9g2Bw34NPA@mail.gmail.com  

M src/backend/optimizer/plan/setrefs.c

pg_locale_libc.c: add missing casts to unsigned char.

commit   : e6e08dc5543485c7f4851551e67a99b0cf8027eb    
  
author   : Jeff Davis <jdavis@postgresql.org>    
date     : Tue, 7 Jul 2026 18:20:15 -0700    
  
committer: Jeff Davis <jdavis@postgresql.org>    
date     : Tue, 7 Jul 2026 18:20:15 -0700    

Click here for diff

Discussion: https://postgr.es/m/20260630012919.78@rfd.leadboat.com  
Backpatch-through: 19  

M src/backend/utils/adt/pg_locale_libc.c

pg_locale_libc.c: add guards to ctype methods.

commit   : dbbeafe61ad049c8881aa82575ecf3e89d707ce3    
  
author   : Jeff Davis <jdavis@postgresql.org>    
date     : Tue, 7 Jul 2026 18:20:06 -0700    
  
committer: Jeff Davis <jdavis@postgresql.org>    
date     : Tue, 7 Jul 2026 18:20:06 -0700    

Click here for diff

Necessary for 16-bit wchar_t platforms (Windows).  
  
Other guards are just defensive. Also correct style issue with  
branches.  
  
Reported-by: Noah Misch <noah@leadboat.com>  
Discussion: https://postgr.es/m/20260630012919.78@rfd.leadboat.com  
Backpatch-through: 19  

M src/backend/utils/adt/pg_locale_libc.c

Fix obsolete comment.

commit   : 3ab2abc9494dde30dbdfe9eeb7c96a63128941ae    
  
author   : Jeff Davis <jdavis@postgresql.org>    
date     : Tue, 7 Jul 2026 18:19:59 -0700    
  
committer: Jeff Davis <jdavis@postgresql.org>    
date     : Tue, 7 Jul 2026 18:19:59 -0700    

Click here for diff

Reported-by: Noah Misch <noah@leadboat.com>  
Discussion: https://postgr.es/m/20260630012919.78@rfd.leadboat.com  
Backpatch-through: 19  

M src/backend/utils/adt/pg_locale_libc.c

Fix unintentional behavior change from 5a38104b36.

commit   : d34ce773d2d3bd891e2725ec4d4b94f1195e52cf    
  
author   : Jeff Davis <jdavis@postgresql.org>    
date     : Tue, 7 Jul 2026 18:04:33 -0700    
  
committer: Jeff Davis <jdavis@postgresql.org>    
date     : Tue, 7 Jul 2026 18:04:33 -0700    

Click here for diff

Reported-by: Noah Misch <noah@leadboat.com>  
Discussion: https://postgr.es/m/20260630012919.78@rfd.leadboat.com  
Backpatch-through: 19  

M src/backend/utils/adt/like.c
M src/test/regress/expected/collate.utf8.out
M src/test/regress/sql/collate.utf8.sql

Propagate stadistinct through GROUP BY/DISTINCT in subqueries and CTEs

commit   : 906b1e4a19a59612deb144ff6018cb048f7d73f8    
  
author   : Richard Guo <rguo@postgresql.org>    
date     : Wed, 8 Jul 2026 09:38:31 +0900    
  
committer: Richard Guo <rguo@postgresql.org>    
date     : Wed, 8 Jul 2026 09:38:31 +0900    

Click here for diff

Previously, examine_simple_variable() would return early when a  
subquery or CTE used GROUP BY or DISTINCT.  It could detect uniqueness  
for single-column cases, but for multi-column GROUP BY or DISTINCT,  
selectivity estimation fell back on 1/DEFAULT_NUM_DISTINCT (1/200).  
This produced wildly inaccurate estimates for filters and joins on  
such columns, often leading the planner to choose nested loop joins  
where hash joins would be far better.  This was a significant factor  
in poor TPC-DS benchmark performance.  
  
For DISTINCT or GROUP BY key columns that are simple Vars, we now  
recurse into the subquery to obtain the base table's stadistinct,  
which remains valid after grouping (the set of distinct values is  
preserved).  However, MCV frequencies, histograms, and correlation  
data are not valid because GROUP BY and DISTINCT change the frequency  
distribution of key columns.  So we strip all stats slots from the  
copied stats tuple, causing callers like var_eq_const() to use the  
1/ndistinct estimate instead.  If stadistinct is stored as a negative  
value (a fraction of the base table's row count), we convert it to an  
absolute count so it is not misinterpreted relative to the subquery's  
output row count.  
  
stanullfrac is adjusted too, since grouping collapses NULLs.  For a  
single grouping key, at most one NULL group survives, so the null  
fraction is 1/(ndistinct+1).  For multiple grouping keys the null  
fraction depends on the joint distribution of the keys, which we don't  
have, so we approximate it as zero; NULLs collapse far more  
aggressively than non-NULLs, so the real fraction is well below the  
base table's, and erring low keeps estimates on the hash-join-favoring  
side.  
  
Non-key columns (e.g., aggregate outputs) continue to get no stats,  
same as before.  
  
Author: Richard Guo <guofenglinux@gmail.com>  
Reviewed-by: wenhui qiu <qiuwenhuifx@gmail.com>  
Discussion: https://postgr.es/m/CAMbWs49rWYrecgreDhKsfx3VSDW=qo35s+iAmgGu=wpARrM8_g@mail.gmail.com  

M src/backend/utils/adt/selfuncs.c
M src/test/regress/expected/with.out
M src/test/regress/sql/with.sql

doc: Fix typo in rule-system view example

commit   : 0237f1480a0d618f60d8dd4eca097e99aa7256d9    
  
author   : Fujii Masao <fujii@postgresql.org>    
date     : Wed, 8 Jul 2026 09:04:31 +0900    
  
committer: Fujii Masao <fujii@postgresql.org>    
date     : Wed, 8 Jul 2026 09:04:31 +0900    

Click here for diff

Commit dcb00495236 accidentally changed the final expanded query's  
condition to > 2 while rewriting the example into SQL operator notation.  
  
The original query and the preceding rewritten forms all use >= 2,  
and view expansion should preserve that qualification. This commit  
changes the final condition from > 2 to >= 2.  
  
Backpatch to all supported versions.  
  
Reported-by: Yaroslav Saburov <y.saburov@gmail.com>  
Author: Fujii Masao <masao.fujii@gmail.com>  
Reviewed-by: Daniel Gustafsson <daniel@yesql.se>  
Discussion: https://postgr.es/m/178248467618.108999.9966122434342474006@wrigleys.postgresql.org  
Backpatch-through: 14  

M doc/src/sgml/rules.sgml

Fix EXPLAIN failure when deparsing SQL/JSON aggregates

commit   : 96ab9a990eed2265c6b073646d1566a1dd2bd3f7    
  
author   : Richard Guo <rguo@postgresql.org>    
date     : Wed, 8 Jul 2026 08:46:43 +0900    
  
committer: Richard Guo <rguo@postgresql.org>    
date     : Wed, 8 Jul 2026 08:46:43 +0900    

Click here for diff

If an expression containing an aggregate is evaluated above the plan  
node that computes the aggregate, as happens with window functions or  
with expressions postponed to above the final sort, setrefs.c replaces  
the Aggref or WindowFunc with a Var referencing the lower node's  
output.  For SQL/JSON aggregates such as JSON_ARRAYAGG and  
JSON_OBJECTAGG, deparsing the containing JsonConstructorExpr then  
failed with "invalid JsonConstructorExpr underlying node type", since  
get_json_agg_constructor() did not expect a Var there.  
  
Fix by resolving the Var back to the underlying Aggref or WindowFunc  
and deparsing the constructor as if the aggregate were computed at the  
current node.  The JsonConstructorExpr retains the RETURNING clause  
and the ABSENT/NULL ON NULL and WITH UNIQUE options, and the arguments  
come from the resolved aggregate, so the original JSON aggregate  
syntax is reproduced in full.  This mirrors how get_agg_expr() already  
looks through such a Var when deparsing a combining aggregate.  
  
Reported-by: Thom Brown <thom@linux.com>  
Author: Richard Guo <guofenglinux@gmail.com>  
Discussion: https://postgr.es/m/CAA-aLv5QYTaMOk=Qhv6cgwceeHETZV8YJvWZ_rH+yVZCuchATA@mail.gmail.com  
Backpatch-through: 16  

M src/backend/utils/adt/ruleutils.c
M src/test/regress/expected/sqljson.out
M src/test/regress/sql/sqljson.sql

unicode_case.c: change API to signal UTF8 decoding error.

commit   : 07211f64ace0150c92a00769a1cfe8b9305b9e78    
  
author   : Jeff Davis <jdavis@postgresql.org>    
date     : Tue, 7 Jul 2026 15:23:54 -0700    
  
committer: Jeff Davis <jdavis@postgresql.org>    
date     : Tue, 7 Jul 2026 15:23:54 -0700    

Click here for diff

Errors at this point are not expected, but if encountered, signal to  
the caller so it can raise the appropriate error.  
  
Reviewed-by: Chao Li <li.evan.chao@gmail.com>  
Reviewed-by: Ayush Tiwari <ayushtiwari.slg01@gmail.com>  
Discussion: https://postgr.es/m/c355354e6c3f4a7aafb047361b73db247260fca0.camel@j-davis.com  

M src/backend/utils/adt/pg_locale_builtin.c
M src/common/unicode/case_test.c
M src/common/unicode_case.c
M src/include/common/unicode_case.h

Remove unused tuple fetch in speculative completion

commit   : 7258c891d4cabd366e4529484f2ad6e99234db48    
  
author   : Heikki Linnakangas <heikki.linnakangas@iki.fi>    
date     : Wed, 8 Jul 2026 01:16:24 +0300    
  
committer: Heikki Linnakangas <heikki.linnakangas@iki.fi>    
date     : Wed, 8 Jul 2026 01:16:24 +0300    

Click here for diff

heapam_tuple_complete_speculative() fetched a tuple from the slot only  
to free it immediately afterwards, without ever using it.  
  
The function only needs slot->tts_tid to complete or abort the  
speculative insertion, so remove the unnecessary fetch and pfree().  
  
Author: Chao Li <li.evan.chao@gmail.com>  
Reviewed-by: Japin Li <japinli@hotmail.com>  
Reviewed-by: Xuneng Zhou <xunengzhou@gmail.com>  
Reviewed-by: Surya Poondla <suryapoondla4@gmail.com>  
Discussion: https://www.postgresql.org/message-id/FCB61654-575D-4F08-AA7E-ED462EDE48A7@gmail.com  

M src/backend/access/heap/heapam_handler.c

pg_unicode_fast: fix final sigma logic.

commit   : 36869368989ce37d85c08c33258eb01ae96e2375    
  
author   : Jeff Davis <jdavis@postgresql.org>    
date     : Tue, 7 Jul 2026 14:29:15 -0700    
  
committer: Jeff Davis <jdavis@postgresql.org>    
date     : Tue, 7 Jul 2026 14:29:15 -0700    

Click here for diff

If the string is preceded only by Case Ignorable characters, don't  
consider it to be a final sigma.  
  
In the process, refactor so that the preceding and following  
characters are found first, and then the rule is applied, to improve  
clarity.  
  
Discussion: https://postgr.es/m/c355354e6c3f4a7aafb047361b73db247260fca0.camel@j-davis.com  
Backpatch-through: 18  

M src/common/unicode_case.c
M src/test/regress/expected/collate.utf8.out
M src/test/regress/sql/collate.utf8.sql

Deduplicate metapage sanity checks in _bt_gettrueroot()

commit   : 99319edb8f5e9c4363ac79088e58a70570d728bb    
  
author   : Heikki Linnakangas <heikki.linnakangas@iki.fi>    
date     : Wed, 8 Jul 2026 00:25:24 +0300    
  
committer: Heikki Linnakangas <heikki.linnakangas@iki.fi>    
date     : Wed, 8 Jul 2026 00:25:24 +0300    

Click here for diff

Replace the metapage sanity checks in _bt_gettrueroot() with a call to  
_bt_getmeta(), which does exactly the same checks.  
  
Author: Chao Li <li.evan.chao@gmail.com>  
Reviewed-by: Neil Chen <carpenter.nail.cz@gmail.com>  
Discussion: https://www.postgresql.org/message-id/CAEoWx2nisjqs4iC9o4Hu7-Ab767=cMZZzmhBGb8SaQtMMmVqPQ@mail.gmail.com  

M src/backend/access/nbtree/nbtpage.c

unicode_case.c: defend against truncated UTF8.

commit   : 21ffc271d475a31dbc67706fc1f2a2c5bfc83e14    
  
author   : Jeff Davis <jdavis@postgresql.org>    
date     : Tue, 7 Jul 2026 13:34:55 -0700    
  
committer: Jeff Davis <jdavis@postgresql.org>    
date     : Tue, 7 Jul 2026 13:34:55 -0700    

Click here for diff

Reviewed-by: Chao Li <li.evan.chao@gmail.com>  
Discussion: https://postgr.es/m/c355354e6c3f4a7aafb047361b73db247260fca0.camel@j-davis.com  
Backpatch-through: 17  

M src/backend/utils/adt/pg_locale_builtin.c
M src/common/unicode/case_test.c
M src/common/unicode_case.c

Cleanup comments/docs around the new shmem request callbacks

commit   : 6f7199a1245cab986a13c7b57812255fe77679d1    
  
author   : Heikki Linnakangas <heikki.linnakangas@iki.fi>    
date     : Tue, 7 Jul 2026 22:32:36 +0300    
  
committer: Heikki Linnakangas <heikki.linnakangas@iki.fi>    
date     : Tue, 7 Jul 2026 22:32:36 +0300    

Click here for diff

Make it explicit in the docs that the shmem initialization callbacks  
are called while holding ShmemIndexLock.  
  
Reviewed-by: Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>  
Discussion: https://www.postgresql.org/message-id/CAExHW5sHs+eSiTDOd14buayc6JbBX=Hm5ssFMBK0Ki9sTGEOuA@mail.gmail.com  
Backpatch-through: 19  

M doc/src/sgml/xfunc.sgml
M src/backend/storage/ipc/shmem.c

Fix gistkillitems for GiST root page

commit   : 9c9ddf109bd8d73660ff3fef317f95bc1d7d6cc5    
  
author   : Heikki Linnakangas <heikki.linnakangas@iki.fi>    
date     : Tue, 7 Jul 2026 21:21:16 +0300    
  
committer: Heikki Linnakangas <heikki.linnakangas@iki.fi>    
date     : Tue, 7 Jul 2026 21:21:16 +0300    

Click here for diff

GiST index killitems feature misbehaves for single-page GiST index,  
i.e. one that has only a root page. This is caused by the GiST scan's  
curBlkno variable not being initialized for the first-to-scan page,  
which is the root page.  Fix this by moving the initializing of  
curBlkno into gistScanPage(), where we also set the related curPageLSN  
variable.  
  
Commit 377b7ab145 actually added a regression test for this already,  
but it merely noted that it's not working and memorized the result  
where the items were not killed. Now they are, as the test shows.  
  
This has been broken all along, but since it's just a very minor  
performance issue on tiny tables, I didn't bother backpatching it.  
  
Author: Kirill Reshke <reshkekirill@gmail.com>  
Reviewed-by: Andrey Borodin <x4mmm@yandex-team.ru>  
Reviewed-by: Soumya S Murali <soumyamurali.work@gmail.com>  
Discussion: https://postgr.es/m/CALdSSPgZWX_D8%2BFx4YQqRN5eW5iSx_rJdqQhCfdWTvqKXVfJ4w%40mail.gmail.com  
Discussion: https://postgr.es/m/lxzj26ga6ippdeunz6kuncectr5gfuugmm2ry22qu6hcx6oid6@lzx3sjsqhmt6  

M src/backend/access/gist/gistget.c
M src/test/modules/index/expected/killtuples.out
M src/test/modules/index/specs/killtuples.spec

commit   : 650bb73c137ccdea3a502775e08482731cc799ba    
  
author   : Heikki Linnakangas <heikki.linnakangas@iki.fi>    
date     : Tue, 7 Jul 2026 20:05:56 +0300    
  
committer: Heikki Linnakangas <heikki.linnakangas@iki.fi>    
date     : Tue, 7 Jul 2026 20:05:56 +0300    

Click here for diff

Only "tombstone" files (first segment of main fork) are unlinked after  
checkpoints, so rename the function and remove the extra arguments to  
make that more clear.  
  
Additionally, add an assertion in mdunlinkfiletag() that the FileTag  
only contains expected values.  
  
Author: Matthias van de Meent <boekewurm+postgres@gmail.com>  
Reviewed-by: Thomas Munro <thomas.munro@gmail.com>  
Discussion: https://www.postgresql.org/message-id/CAEze2WjfP95SL_Hsu7GzYXLnQyEsT49zOnNvbY_mBLCFiQra1g@mail.gmail.com  

M src/backend/storage/smgr/md.c

Fix pg_dump ACL minimization for PROPERTY GRAPH.

commit   : 592de8bd21e177229eeef51cb474ccfc2070c65d    
  
author   : Noah Misch <noah@leadboat.com>    
date     : Tue, 7 Jul 2026 09:51:04 -0700    
  
committer: Noah Misch <noah@leadboat.com>    
date     : Tue, 7 Jul 2026 09:51:04 -0700    

Click here for diff

Adding a GRANT caused pg_dump to emit a useless REVOKE + GRANT of owner  
privileges, as seen in a dump of the regression database:  
  
  REVOKE ALL ON PROPERTY GRAPH graph_rls_schema.cabinet FROM nm;  
  GRANT ALL ON PROPERTY GRAPH graph_rls_schema.cabinet TO nm;  
  GRANT ALL ON PROPERTY GRAPH graph_rls_schema.cabinet TO PUBLIC;  
  
For normal dumps, this has no functional consequences.  For --no-owner  
restores, the extra statements may fail or locate unrelated users of the  
destination cluster.  
  
The problem was pg_dump assuming NULL relacl implies acldefault('r'),  
the default for TABLE.  Fix by teaching acldefault() to retrieve the  
PROPERTY GRAPH default ACL.  So pg_dump can still dump from 19beta1, use  
acldefault('g') for v20+ only.  For v19, use a hard-coded snapshot of  
the v19 default.  
  
information_schema.pg_property_graph_privileges also misused  
acldefault('r'), but its "c.prtype IN ('SELECT')" predicate compensated  
for it.  Switch to the new acldefault('g') for clarity.  Bump catversion  
since a new view won't work with old binaries.  Back-patch to v19, which  
introduced PROPERTY GRAPH.  
  
Reviewed-by: Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>  
Reviewed-by: Robert Haas <robertmhaas@gmail.com>  
Discussion: https://postgr.es/m/20260630023308.c7.noahmisch@microsoft.com  
Backpatch-through: 19  

M src/backend/catalog/information_schema.sql
M src/backend/utils/adt/acl.c
M src/bin/pg_dump/pg_dump.c
M src/include/catalog/catversion.h

Remove unnecessary volatile qualifiers.

commit   : b34fd845e03aea7401d3bf403c87e171d10f7709    
  
author   : Nathan Bossart <nathan@postgresql.org>    
date     : Tue, 7 Jul 2026 10:57:48 -0500    
  
committer: Nathan Bossart <nathan@postgresql.org>    
date     : Tue, 7 Jul 2026 10:57:48 -0500    

Click here for diff

This commit cleans up volatile qualifiers that fit the below  
criteria:  
  
* Accesses to shared memory protected by a spinlock or LWLock.  
Before commit 0709b7ee72, callers had to use volatile when  
accessing spinlock-protected shared memory.  Since spinlock  
acquire/release became compiler barriers, and because LWLocks  
provide the same guarantee, that is no longer necessary.  These  
either predate that change or were cargo-culted from code that did.  
  
* Pointers used only to find the address of a member.  The volatile  
qualifier only affects accesses made by dereferencing the pointer,  
so it is unnecessary there.  
  
* Accesses to struct members that are marked volatile in the struct  
definition.  There's no need to mark these pointers volatile,  
either.  
  
* Leftovers from removed PG_TRY blocks.  These were marked volatile  
to protect a value that is modified inside a PG_TRY block, but the  
PG_TRY has since been removed.  
  
Reviewed-by: Heikki Linnakangas <hlinnaka@iki.fi>  
Discussion: https://postgr.es/m/akQ5eJR1tCCXme8e%40nathan  

M src/backend/access/transam/clog.c
M src/backend/catalog/index.c
M src/backend/commands/async.c
M src/backend/replication/syncrep.c
M src/backend/storage/ipc/procsignal.c
M src/backend/storage/ipc/shm_toc.c
M src/backend/storage/lmgr/lock.c
M src/backend/storage/lmgr/proc.c
M src/test/modules/test_shm_mq/setup.c
M src/test/modules/test_shm_mq/worker.c

libpq: Drain all pending bytes from SSL/GSS during pqReadData()

commit   : 343594a26d37522efdbae5fe5de13e19ccf2fa72    
  
author   : Heikki Linnakangas <heikki.linnakangas@iki.fi>    
date     : Tue, 7 Jul 2026 18:45:37 +0300    
  
committer: Heikki Linnakangas <heikki.linnakangas@iki.fi>    
date     : Tue, 7 Jul 2026 18:45:37 +0300    

Click here for diff

The previous commit strengthened a workaround for a hang when large  
messages are split across TLS records/GSS tokens. Because that  
workaround is implemented in libpq internals, it can only help us when  
libpq itself is polling on the socket. In nonblocking situations,  
where the client above libpq is expected to poll, the same bugs can  
show up.  
  
As a contrived example, consider a large protocol-2.0 error coming  
back from a server during PQconnectPoll(), split in an odd way across  
two records:  
  
    -- TLS record (8192-byte payload) --  
    EEEE[...repeated a total of 8192 times]  
    -- TLS record (8193-byte payload) --  
    EEEE[...repeated a total of 8192 times]\0  
  
The first record will fill the first half of the libpq receive buffer,  
which is 16k long by default. The second record completely fills the  
last half with its first 8192 bytes, leaving the terminating NULL in  
the OpenSSL buffer. Since we still haven't seen the terminator at our  
level, PQconnectPoll() will return PGRES_POLLING_READING, expecting to  
come back when the server has sent "the rest" of the data.  But there  
is nothing left to read from the socket; OpenSSL had to pull all of  
the data in the 8193-byte record off of the wire to decrypt it.  
  
A real server would probably not split up the records this way, nor  
keep the connection open after sending a fatal connection error. But  
servers that regularly use larger TLS records can get the libpq  
receive buffer into the same state if DataRows are big enough, as  
reported on the list. While the PostgreSQL server doesn't use larger  
TLS records like that, other non-PostgreSQL servers that implement the  
wire protocol are known to do that, as well as proxies that sit  
between the server and the client  
  
This is a layering violation. libpq makes decisions based on data in  
the application buffer, above the transport buffer (whether SSL or  
GSS), but clients are polling the socket below the transport buffer.  
One way to fix this in a backportable way, without changing APIs too  
much, is to ensure data never stays in the transport buffer. Then  
pqReadData's postconditions will look similar for both raw sockets and  
SSL/GSS: any available data is either in the application buffer, or  
still on the socket.  
  
Building on the prior commit, make pqReadData() to drain all pending  
data from the transport layer into conn->inBuffer, expanding the  
buffer as necessary. This is not particularly efficient from an  
architectural perspective (the pqsecure_read() implementations take  
care to fit their packets into the current buffer, and that effort is  
now completely discarded), but it's hopefully easier to reason about  
than a full rewrite would be for the back branches.  
  
Author: Jacob Champion <jacob.champion@enterprisedb.com>  
Reviewed-by: Mark Dilger <mark.dilger@enterprisedb.com>  
Reviewed-by: solai v <solai.cdac@gmail.com>  
Reported-by: Lars Kanis <lars@greiz-reinsdorf.de>  
Discussion: https://postgr.es/m/2039ac58-d3e0-434b-ac1a-2a987f3b4cb1%40greiz-reinsdorf.de  
Backpatch-through: 14  

M src/interfaces/libpq/fe-misc.c
M src/interfaces/libpq/fe-secure-openssl.c
M src/interfaces/libpq/fe-secure.c

libpq: Extend "read pending" check from SSL to GSS

commit   : ffd080d94fe7154940a1bdac005390d0aee034bc    
  
author   : Heikki Linnakangas <heikki.linnakangas@iki.fi>    
date     : Tue, 7 Jul 2026 18:45:34 +0300    
  
committer: Heikki Linnakangas <heikki.linnakangas@iki.fi>    
date     : Tue, 7 Jul 2026 18:45:34 +0300    

Click here for diff

An extra check for pending bytes in the SSL layer has been part of  
pqReadReady() for a very long time (79ff2e96d). But when GSS transport  
encryption was added, it didn't receive the same treatment. (As  
79ff2e96d notes, "The bug that I fixed in this patch is exceptionally  
hard to reproduce reliably.")  
  
Without that check, it's possible to hit a hang in gssencmode, if the  
server splits a large libpq message such that the final message in a  
streamed response is part of the same wrapped token as the split  
message:  
  
    DataRowDataRowDataRowDataRowDataRowData  
    -- token boundary --  
    RowDataRowCommandCompleteReadyForQuery  
  
If the split message takes up enough memory to nearly fill libpq's  
receive buffer, libpq may return from pqReadData() before the later  
messages are pulled out of the PqGSSRecvBuffer. Without additional  
socket activity from the server, pqReadReady() (via pqSocketCheck())  
will never again return true, hanging the connection.  
  
Pull the pending-bytes check into the pqsecure API layer, where both  
SSL and GSS now implement it.  
  
Note that this does not fix the root problem! Third party clients of  
libpq have no way to call pqsecure_read_is_pending() in their own  
polling. This just brings the GSS implementation up to par with the  
existing SSL workaround; a broader fix is left to a subsequent commit.  
  
In preparation for the broader fix, this patch already changes the  
*_read_pending() functions to return the number of bytes in the buffer  
rather than just a boolean. The current callers don't need that, but  
the subsequent fix will.  
  
Author: Jacob Champion <jacob.champion@enterprisedb.com>  
Discussion: https://postgr.es/m/CAOYmi%2BmpymrgZ76Jre2dx_PwRniS9YZojwH0rZnTuiGHCsj0rA%40mail.gmail.com  
Backpatch-through: 14  

M src/interfaces/libpq/fe-misc.c
M src/interfaces/libpq/fe-secure-gssapi.c
M src/interfaces/libpq/fe-secure-openssl.c
M src/interfaces/libpq/fe-secure.c
M src/interfaces/libpq/libpq-int.h

Replace hardcoded mentions of pg_hosts.conf with GUC

commit   : b9df8d5b8e4f58ef81e6b592278207889863c367    
  
author   : Daniel Gustafsson <dgustafsson@postgresql.org>    
date     : Tue, 7 Jul 2026 17:34:58 +0200    
  
committer: Daniel Gustafsson <dgustafsson@postgresql.org>    
date     : Tue, 7 Jul 2026 17:34:58 +0200    

Click here for diff

Three error messages were using the default file name pg_hosts.conf  
and not the variable backing the GUC, which would make logging be  
confusing for users who have renamed the file using the GUC.  Fix  
by consistently using the HostsFileName variable.  
  
Backpatch down to v19 where serverside SNI was introduced.  
  
Author: Zsolt Parragi <zsolt.parragi@percona.com>  
Reviewed-by: Surya Poondla <suryapoondla4@gmail.com>  
Reviewed-by: Michael Paquier <michael@paquier.xyz>  
Discussion: https://postgr.es/m/CAN4CZFMARYjQfgyRaCKOXDO=Q91kuKn=pSC02DAOOr23ojhEGQ@mail.gmail.com  
Backpatch-through: 19  

M src/backend/libpq/be-secure-openssl.c

pg_dump: check for _beginthreadex() failure in parallel dump

commit   : 75e201bf95d8825f1c025792eed0f13d65657c5d    
  
author   : Heikki Linnakangas <heikki.linnakangas@iki.fi>    
date     : Tue, 7 Jul 2026 18:11:28 +0300    
  
committer: Heikki Linnakangas <heikki.linnakangas@iki.fi>    
date     : Tue, 7 Jul 2026 18:11:28 +0300    

Click here for diff

ParallelBackupStart() stored _beginthreadex()'s return value as the  
worker's thread handle without checking it.  On failure that value is 0,  
which would later reach WaitForMultipleObjects() as a null handle, caught  
only by an Assert.  The fork() path already calls pg_fatal() when it  
fails; do the same for _beginthreadex(), as pgbench does.  
  
Author: Bryan Green <dbryan.green@gmail.com>  
Discussion: https://www.postgresql.org/message-id/8c712d76-ecf7-4749-a6d8-dddc01f298ec@gmail.com  
Backpatch-through: 14  

M src/bin/pg_dump/parallel.c

doc: Add reference to CREATE PROCEDURE on CREATE FUNCTION

commit   : 9762809448b42d841ec09bf17db72ff769ac8b79    
  
author   : Daniel Gustafsson <dgustafsson@postgresql.org>    
date     : Tue, 7 Jul 2026 15:55:24 +0200    
  
committer: Daniel Gustafsson <dgustafsson@postgresql.org>    
date     : Tue, 7 Jul 2026 15:55:24 +0200    

Click here for diff

The reference page for CREATE PROCEDURE had a See Also reference to  
CREATE FUNCTION, but the inverse was missing.  
  
Author: Jian He <jian.universality@gmail.com>  
Reviewed-by: Laurenz Albe <laurenz.albe@cybertec.at>  
Discussion: https://postgr.es/m/CACJufxFTi3ceVRJqWRr3L8GR5q+ZhPCZw=1aDTaBGS1AugweFw@mail.gmail.com  

M doc/src/sgml/ref/create_function.sgml

Fix COUNT's logic for window run condition support

commit   : d007800f02a7b9fe3ca984a1b870405657d990ed    
  
author   : David Rowley <drowley@postgresql.org>    
date     : Tue, 7 Jul 2026 23:57:45 +1200    
  
committer: David Rowley <drowley@postgresql.org>    
date     : Tue, 7 Jul 2026 23:57:45 +1200    

Click here for diff

9d9c02ccd added code to allow the executor to stop early when processing  
WindowAgg nodes where a monotonic window function starts producing  
values that result in a pushed-down qual no longer matching, and will  
never match again due to the window function's monotonic properties.  
  
That commit requires a SupportRequestWFuncMonotonic to exist on the  
window function and for it to detect when the function is monotonic.  For  
COUNT(ANY) and COUNT(*), the support function failed to consider some  
cases where the WindowClause used EXCLUDE to exclude certain rows from  
being aggregated.  Some WindowClause definitions mean we aggregate rows  
that come after the current row, and when processing those rows later,  
if we EXCLUDE certain rows, the monotonic property can be broken.  
Wrongly treating the COUNT(*) or COUNT(ANY) aggregate as monotonic could  
lead to rows being filtered that should not be filtered from the result  
set.  
  
Another issue was that the support function for the COUNT aggregate  
mistakenly thought that a WindowClause without an ORDER BY meant that  
the results would be both monotonically increasing and decreasing, but  
that's only true when in RANGE mode, where all rows are peers.  
  
It is possible to support various cases that do have an EXCLUDE clause,  
but getting the logic correct for the exact set of cases that are valid  
is quite complex and would likely better be left for a future project.  
  
Here, we mostly disable run condition pushdown when there is an EXCLUDE  
clause unless the clause is for EXCLUDE CURRENT ROW, uses COUNT(*)  
(rather than COUNT(ANY)), and the window aggregate has no FILTER clause.  
  
Bug: #19533  
Reported-by: Qifan Liu <imchifan@163.com>  
Author: Chengpeng Yan <chengpeng_yan@outlook.com>  
Author: David Rowley <dgrowleyml@gmail.com>  
Reviewed-by: Richard Guo <guofenglinux@gmail.com>  
Reviewed-by: John Naylor <johncnaylorls@gmail.com>  
Discussion: https://postgr.es/m/19533-413a1014e5d0e766@postgresql.org  
Backpatch-through: 15  

M src/backend/utils/adt/int8.c
M src/test/regress/expected/window.out
M src/test/regress/sql/window.sql

Print off_t/pgoff_t consistently as %lld

commit   : c22d2f7fd46c692c83152773387be6b731c1a4b9    
  
author   : Peter Eisentraut <peter@eisentraut.org>    
date     : Tue, 7 Jul 2026 11:50:22 +0200    
  
committer: Peter Eisentraut <peter@eisentraut.org>    
date     : Tue, 7 Jul 2026 11:50:22 +0200    

Click here for diff

This was the dominant style already, but some places used %llu  
instead.  Since off_t/pgoff_t are signed types, using %lld seems a  
better match, and it might handle obscure error conditions with  
negative values better.  
  
Reviewed-by: Heikki Linnakangas <hlinnaka@iki.fi>  
Reviewed-by: Chao Li <li.evan.chao@gmail.com>  
Discussion: https://www.postgresql.org/message-id/flat/20ce62fa-47fc-457b-b504-12f3c1651726%40eisentraut.org  

M src/bin/pg_combinebackup/reconstruct.c
M src/bin/pg_dump/pg_backup_tar.c
M src/bin/pg_rewind/libpq_source.c
M src/bin/pg_verifybackup/astreamer_verify.c
M src/bin/pg_verifybackup/pg_verifybackup.c

Don't cast pgoff_t to possibly 32-bit types for output

commit   : 04fc2564fbbabe97cadbf782e8d40b8e3f7b22a5    
  
author   : Peter Eisentraut <peter@eisentraut.org>    
date     : Tue, 7 Jul 2026 11:45:09 +0200    
  
committer: Peter Eisentraut <peter@eisentraut.org>    
date     : Tue, 7 Jul 2026 11:45:09 +0200    

Click here for diff

pgoff_t is most likely a 64-bit integer, so casting it to a 32-bit  
type for output could lose data.  In the cases addressed here, the  
files cannot actually get that large, so this is only cosmetic and to  
set better examples for the future.  (Similar issues that could have  
actual practical impact were addressed separately in commit  
e8f851d6172.)  
  
In one case, the 32-bit size is baked into the protocol, so here we  
add an elog and document this discrepancy.  
  
Reviewed-by: Heikki Linnakangas <hlinnaka@iki.fi>  
Reviewed-by: Chao Li <li.evan.chao@gmail.com>  
Discussion: https://www.postgresql.org/message-id/flat/20ce62fa-47fc-457b-b504-12f3c1651726%40eisentraut.org  

M src/backend/access/heap/rewriteheap.c
M src/backend/backup/walsummary.c
M src/backend/replication/walsender.c
M src/backend/storage/file/fd.c
M src/bin/pg_upgrade/slru_io.c

postgres_fdw: Report ANALYZE to pgstats after importing statistics.

commit   : bb4142fb68cfab35b7c5f8db7645196c50662631    
  
author   : Etsuro Fujita <efujita@postgresql.org>    
date     : Tue, 7 Jul 2026 18:40:00 +0900    
  
committer: Etsuro Fujita <efujita@postgresql.org>    
date     : Tue, 7 Jul 2026 18:40:00 +0900    

Click here for diff

Commit 28972b6fc should have done this, but didn't.  
  
While at it, remove an extra blank line in fetch_remote_statistics()  
introduced by that commit.  
  
Reported-by: Chao Li <lic@highgo.com>  
Co-authored-by: Chao Li <lic@highgo.com>  
Co-authored-by: Etsuro Fujita <etsuro.fujita@gmail.com>  
Discussion: https://postgr.es/m/6ED81190-B398-44C9-A1E9-8EFE4ED183AF%40gmail.com  
Backpatch-through: 19  

M contrib/postgres_fdw/expected/postgres_fdw.out
M contrib/postgres_fdw/postgres_fdw.c
M contrib/postgres_fdw/sql/postgres_fdw.sql

Update GROUP BY ALL comments about window functions

commit   : 2ce74583652fb4cd29299a220ff31043adf5c96e    
  
author   : Peter Eisentraut <peter@eisentraut.org>    
date     : Tue, 7 Jul 2026 08:37:15 +0200    
  
committer: Peter Eisentraut <peter@eisentraut.org>    
date     : Tue, 7 Jul 2026 08:37:15 +0200    

Click here for diff

When GROUP BY ALL was added in commit ef38a4d9756, the SQL standard  
working draft was silent on what to do with window functions.  This  
has now been fixed in the SQL standard working draft.  Update the  
documentation and code comments about that.  
  
Also make the documentation more specific that we are only talking  
about aggregate functions referring to the same query level, which is  
another thing that has been made more precise in the SQL standard  
working draft since.  
  
The PostgreSQL implementation was already doing the right thing for  
both aspects, so no functionality changes.  
  
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>  
Discussion: https://www.postgresql.org/message-id/flat/CAHM0NXjz0kDwtzoe-fnHAqPB1qA8_VJN0XAmCgUZ%2BiPnvP5LbA%40mail.gmail.com  

M doc/src/sgml/queries.sgml
M doc/src/sgml/ref/select.sgml
M src/backend/parser/parse_clause.c

Enforce RETURNING typmod on SQL/JSON DEFAULT behavior expressions

commit   : 4c75cc786301886145bc1a450977cbd024814ef5    
  
author   : Amit Langote <amitlan@postgresql.org>    
date     : Tue, 7 Jul 2026 08:14:04 +0900    
  
committer: Amit Langote <amitlan@postgresql.org>    
date     : Tue, 7 Jul 2026 08:14:04 +0900    

Click here for diff

transformJsonBehavior() coerced an ON EMPTY / ON ERROR DEFAULT  
expression only when its type differed from the RETURNING type's OID.  
When the base type matched but the RETURNING type carried a type  
modifier (e.g. numeric(4,1) or varchar(3)), the coercion that enforces  
the typmod was skipped, so the DEFAULT value could violate the  
declared type:  
  
    SELECT JSON_VALUE(jsonb '{}', '$.a'  
                      RETURNING numeric(4,1) DEFAULT 99999.999 ON EMPTY);  
  
returned 99999.999, which 99999.999::numeric(4,1) would reject; the  
value could even be stored into a numeric(4,1) column, as later  
coercions trust its already-correct type label.  
  
Fix by also coercing when the RETURNING type has a typmod, except for  
a NULL constant.  coerce_to_target_type() is a no-op when the typmod  
already matches.  The matching-OID short-circuit dates to 74c96699be3.  
  
Reported-by: Ewan Young <kdbase.hack@gmail.com>  
Author: Ewan Young <kdbase.hack@gmail.com>  
Discussion: https://postgr.es/m/CAON2xHPO9f4cAmyGn1mQ=VqoS7wN5rz4yOiqudxX78zninZpCw@mail.gmail.com  
Backpatch-through: 17  

M src/backend/parser/parse_expr.c
M src/test/regress/expected/sqljson_jsontable.out
M src/test/regress/expected/sqljson_queryfuncs.out
M src/test/regress/sql/sqljson_jsontable.sql
M src/test/regress/sql/sqljson_queryfuncs.sql

Use PG_MODULE_MAGIC_EXT in newly introduced modules

commit   : 4c84545067822bcc8697b7d8f3082c5cf1937d1b    
  
author   : Robert Haas <rhaas@postgresql.org>    
date     : Mon, 6 Jul 2026 15:34:12 -0400    
  
committer: Robert Haas <rhaas@postgresql.org>    
date     : Mon, 6 Jul 2026 15:34:12 -0400    

Click here for diff

We forgot to use the PG_MODULE_MAGIC_EXT in some newly added modules:  
pg_plan_advice, pg_stash_advice and the pgrepack output plugin and  
instead used the older PG_MODULE_MAGIC macro.  
  
Author: Andreas Karlsson <andreas@proxel.se>  
Discussion: http://postgr.es/m/ad7b910c-d145-4120-994d-2e55c456aa75@proxel.se  
Backpatch-through: 19  

M contrib/pg_plan_advice/pg_plan_advice.c
M contrib/pg_stash_advice/pg_stash_advice.c
M src/backend/replication/pgrepack/pgrepack.c

Fix mishandling of leading '\' in nondeterministic LIKE.

commit   : 42b7ff3aaefa5f63b4890679a283f83f1a4acb00    
  
author   : Tom Lane <tgl@sss.pgh.pa.us>    
date     : Mon, 6 Jul 2026 14:47:58 -0400    
  
committer: Tom Lane <tgl@sss.pgh.pa.us>    
date     : Mon, 6 Jul 2026 14:47:58 -0400    

Click here for diff

The loop in MatchText() processed a leading '\' without regard to  
nondeterministic locales, which is problematic if what the '\'  
precedes is an ordinary character that should be subject to  
nondeterministic matching.  We'd insist on a literal match for it,  
which is not right and is not like what happens with a '\' that  
follows some ordinary characters.  Worse, we'd then advance the text  
and pattern pointers by one byte, so that if the escaped character  
is multibyte the next loop iteration would take the nondeterministic  
code path starting at a point within the character.  That could very  
possibly cause pg_strncoll() to misbehave.  
  
The fix is quite simple: move the stanza that handles '\' down past  
the one that handles nondeterminism.  The stanzas for '%' and '_'  
are fine where they are, but the '\' stanza is only correct for  
deterministic matching.  The logic for nondeterministic cases is  
already prepared to do the right things with a '\'.  
  
While here, I replaced tests of "locale && !locale->deterministic"  
with a boolean local variable, reasoning that those are in the hot  
loop paths so saving a branch and indirect fetch is worth the  
trouble.  I also improved a number of related comments.  
  
Author: Tom Lane <tgl@sss.pgh.pa.us>  
Discussion: https://postgr.es/m/391592.1783187986@sss.pgh.pa.us  
Backpatch-through: 18  

M src/backend/utils/adt/like_match.c
M src/test/regress/expected/collate.icu.utf8.out
M src/test/regress/sql/collate.icu.utf8.sql

Fix LIKE matching with nondeterministic collations and backslashes.

commit   : d6ffcae32a10bd9b53fcfe7be507ba00c6083acc    
  
author   : Tom Lane <tgl@sss.pgh.pa.us>    
date     : Mon, 6 Jul 2026 14:35:21 -0400    
  
committer: Tom Lane <tgl@sss.pgh.pa.us>    
date     : Mon, 6 Jul 2026 14:35:21 -0400    

Click here for diff

Commit 85b7efa1c added support for LIKE with nondeterministic  
collations, but it included a bug in the de-escaping logic for  
literal pattern substrings.  That unconditionally skipped all  
backslashes, but when it encounters '\\' it should emit the second  
backslash as a de-escaped character.  That led to acting as though  
the escaped backslash was not there.  
  
Bug: #19474  
Reported-by: Bowen Shi <zxwsbg12138@gmail.com>  
Author: Nitin Motiani <nitinmotiani@google.com>  
Reviewed-by: Zsolt Parragi <zsolt.parragi@percona.com>  
Reviewed-by: Ewan Young <kdbase.hack@gmail.com>  
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>  
Discussion: https://postgr.es/m/19474-5b86a95f3d9a7ecb@postgresql.org  
Discussion: https://postgr.es/m/CAH5HC94yU+K8Gcdy12M5BS8gwD_SXLSHzc9k5tNk7JDnpBiFMA@mail.gmail.com  
Backpatch-through: 18  

M src/backend/utils/adt/like_match.c
M src/test/regress/expected/collate.icu.utf8.out
M src/test/regress/sql/collate.icu.utf8.sql

Make PLy_elog() use pg_integer_constant_p().

commit   : 431896a84eb127b4fe1b609a56c67e28105136c7    
  
author   : Tom Lane <tgl@sss.pgh.pa.us>    
date     : Mon, 6 Jul 2026 13:48:42 -0400    
  
committer: Tom Lane <tgl@sss.pgh.pa.us>    
date     : Mon, 6 Jul 2026 13:48:42 -0400    

Click here for diff

This macro is supposed to work like ereport().  But when  
59c2f03d1 adjusted ereport() to be more MSVC-friendly,  
it missed updating this copy of the logic.  
  
Discussion: https://postgr.es/m/754534.1783264708@sss.pgh.pa.us  
Backpatch-through: 19  

M src/pl/plpython/plpy_elog.h

Fix LIKE/regex optimization for indexscan with exact-match pattern.

commit   : 2d7808e6fc2cb5d7a964e7a24801a6fa133a3261    
  
author   : Tom Lane <tgl@sss.pgh.pa.us>    
date     : Mon, 6 Jul 2026 13:06:21 -0400    
  
committer: Tom Lane <tgl@sss.pgh.pa.us>    
date     : Mon, 6 Jul 2026 13:06:21 -0400    

Click here for diff

Commit 85b7efa1c introduced support for LIKE with non-deterministic  
collations.  By moving some conditionals around, it accidentally broke  
the optimization for converting a LIKE or regex exact-match pattern  
to an equality indexqual when the index collation doesn't match the  
expression collation.  That should be allowed if the expression  
collation is deterministic.  This patch re-introduces the optimization  
for that common case.  
  
One important beneficiary of this optimization is the "\d tablename"  
command in psql.  Without this fix that will do a seqscan on pg_class  
instead of an index point lookup.  
  
Reported-by: Andres Freund <andres@anarazel.de>  
Author: Jelte Fennema-Nio <postgres@jeltef.nl>  
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>  
Discussion: https://postgr.es/m/DHBQIZX8SZVI.ZX614ZMFL645@jeltef.nl  
Backpatch-through: 18  

M src/backend/utils/adt/like_support.c
M src/test/regress/expected/collate.icu.utf8.out
M src/test/regress/expected/collate.out
M src/test/regress/sql/collate.icu.utf8.sql
M src/test/regress/sql/collate.sql

Prevent satisfies_hash_partition from crashing with VARIADIC NULL.

commit   : e8914ec22f8f254b84523d671afb60125d35c9b1    
  
author   : Robert Haas <rhaas@postgresql.org>    
date     : Mon, 6 Jul 2026 12:12:41 -0400    
  
committer: Robert Haas <rhaas@postgresql.org>    
date     : Mon, 6 Jul 2026 12:12:41 -0400    

Click here for diff

Commit f3b0897a1213f46b4d3a99a7f8ef3a4b32e03572 fixed some  
related problems, but overlooked this one. That commit first  
appeared in PostgreSQL 11, so back-patch to all supported branches.  
  
Backpatch-through: 14  
Discussion: http://postgr.es/m/CA+TgmobsvQw3F+KRYT83=N3teh8D2t-oPR=U06QDZJE3viCJRg@mail.gmail.com  
Reviewed-by: Tender Wang <tndrwang@gmail.com>  
Reviewed-by: Ewan Young <kdbase.hack@gmail.com>  

M src/backend/partitioning/partbounds.c
M src/test/regress/expected/hash_part.out
M src/test/regress/sql/hash_part.sql

Remove switch statements in vector8_shift_{left,right}.

commit   : 763ee7ea00b02592b5fb9572d77b82a1f6f052b9    
  
author   : Nathan Bossart <nathan@postgresql.org>    
date     : Mon, 6 Jul 2026 11:40:02 -0500    
  
committer: Nathan Bossart <nathan@postgresql.org>    
date     : Mon, 6 Jul 2026 11:40:02 -0500    

Click here for diff

In commit ec8719ccbf, I added switch statements with all expected  
shift counts to vector8_shift_{left,right} because vshlq_n_u32()  
and vshrq_n_u32() require integer literals.  But we can use  
vshlq_u32() instead for both cases, which does not require an  
integer literal, thereby avoiding the need for the switch  
statements.  This compiles to the same machine code on newer  
versions of popular compilers.  
  
Reviewed-by: John Naylor <johncnaylorls@gmail.com>  
Discussion: https://postgr.es/m/akWxkA-mszMm57cV%40nathan  

M src/include/port/simd.h

Add comment to describe the various frontend cancel methods

commit   : cde6ede7137e3f2399e3f60d3b7af975cfa7ddac    
  
author   : Heikki Linnakangas <heikki.linnakangas@iki.fi>    
date     : Mon, 6 Jul 2026 19:11:04 +0300    
  
committer: Heikki Linnakangas <heikki.linnakangas@iki.fi>    
date     : Mon, 6 Jul 2026 19:11:04 +0300    

Click here for diff

Author: Jelte Fennema-Nio <postgres@jeltef.nl>  
Discussion: https://www.postgresql.org/message-id/DJPAH0WPJV3K.1PYZ8P0QXZVMX@jeltef.nl  

M src/fe_utils/cancel.c

Remove apparent support for SECURITY LABEL ON PROPERTY GRAPH

commit   : 73dfe79fd6034b1e7e41e83d9c82c166dba8eb67    
  
author   : Peter Eisentraut <peter@eisentraut.org>    
date     : Mon, 6 Jul 2026 11:44:55 +0200    
  
committer: Peter Eisentraut <peter@eisentraut.org>    
date     : Mon, 6 Jul 2026 11:44:55 +0200    

Click here for diff

Commit 2f094e7ac69 added a mention of SECURITY LABEL ON PROPERTY GRAPH  
to the SECURITY LABEL reference page, and it added support to psql tab  
completion.  However, security labels on property graphs are not  
actually supported (per SecLabelSupportsObjectType()).  The syntax  
does work, but that is just a result of how gram.y is factored.  We  
don't document or tab-complete the syntax of SECURITY LABEL for other  
object types that are not actually supported, so it was inconsistent  
to do this for property graphs.  Thus, remove this.  
  
Reported-by: Noah Misch <noah@leadboat.com>  
Discussion: https://www.postgresql.org/message-id/flat/20260704221210.08.noahmisch%40microsoft.com  

M doc/src/sgml/ref/security_label.sgml
M src/bin/psql/tab-complete.in.c

Forbid generated columns in FOR PORTION OF

commit   : e994f956e4864f424320f5243b9af11e173ad398    
  
author   : Peter Eisentraut <peter@eisentraut.org>    
date     : Mon, 6 Jul 2026 09:19:02 +0200    
  
committer: Peter Eisentraut <peter@eisentraut.org>    
date     : Mon, 6 Jul 2026 09:19:02 +0200    

Click here for diff

With virtual generated columns there is no column to assign to, and we  
shouldn't assign directly to stored generated columns either.  (Once  
we have PERIODs, we will allow a stored generated column here, but we  
will assign to its start/end inputs.)  
  
We can't do this in parse analysis, because views haven't yet been  
rewritten, so they mask generated columns.  
  
Author: Paul A. Jungwirth <pj@illuminatedcomputing.com>  
Discussion: https://www.postgresql.org/message-id/agOOykf2HV26yVfU%40nathan  

M doc/src/sgml/ddl.sgml
M src/backend/optimizer/plan/planner.c
M src/test/regress/expected/for_portion_of.out
M src/test/regress/sql/for_portion_of.sql

Fix qual pushdown past grouping with mismatched equivalence

commit   : 44fb59fc605ea0eabd58029bb8dc2c2416c42c3c    
  
author   : Richard Guo <rguo@postgresql.org>    
date     : Mon, 6 Jul 2026 16:13:14 +0900    
  
committer: Richard Guo <rguo@postgresql.org>    
date     : Mon, 6 Jul 2026 16:13:14 +0900    

Click here for diff

The planner has two optimizations that move a qual clause across a  
grouping boundary: subquery_planner transfers HAVING clauses to WHERE  
so they can be evaluated before aggregation, and qual_is_pushdown_safe  
pushes outer restriction clauses into a subquery past its DISTINCT,  
DISTINCT ON, window PARTITION BY, or set-operation grouping layer.  
Both produce wrong results when the moved clause's equivalence  
relation disagrees with the grouping's, since the clause then filters  
rows the grouping would have merged.  
  
The disagreement has two forms.  A type may belong to multiple btree  
opfamilies whose equality operators disagree (e.g. record_ops vs  
record_image_ops); or the grouping may use a nondeterministic  
collation, where comparing the column under a different collation, or  
wrapping it in a function or operator, can distinguish values the  
collation considers equal.  Because we cannot prove an arbitrary  
expression preserves that equality, a grouping column with a  
nondeterministic collation is safe to push only as a direct operand of  
a comparison under its own collation.  
  
Fix both call sites through a shared walker parameterized by a  
callback that maps each Var to the grouping equality operator for its  
column (or InvalidOid for non-grouping Vars).  For HAVING, the  
callback recovers the SortGroupClause's eqop via the GROUP Var's  
varattno, which requires running before flatten_group_exprs while  
havingQual still contains GROUP Vars.  For subquery pushdown, the  
callback recovers the eqop from subquery->distinctClause, a window's  
partitionClause, or any grouping node in the SetOperationStmt tree.  
The walker fires only when there is an equivalence boundary to cross,  
gated by either the existing UNSAFE_NOTIN_DISTINCTON_CLAUSE and  
UNSAFE_NOTIN_PARTITIONBY_CLAUSE flags or by a recursive check for any  
grouping node in the set-op tree.  
  
Back-patch to v18 only.  The HAVING half relies on the RTE_GROUP  
mechanism introduced in v18 (commit 247dea89f), which is what lets us  
identify grouping expressions via GROUP Vars on pre-flatten  
havingQual.  Pre-v18 branches lack that machinery, so a back-patch  
there would need a different approach.  Given the absence of field  
reports of these bugs on back branches, the risk of carrying a  
different fix on stable branches is not justified.  
  
Author: Richard Guo <guofenglinux@gmail.com>  
Reviewed-by: Thom Brown <thom@linux.com>  
Reviewed-by: Florin Irion <irionr@gmail.com>  
Reviewed-by: Zsolt Parragi <zsolt.parragi@percona.com>  
Reviewed-by: Tender Wang <tndrwang@gmail.com>  
Reviewed-by: Chengpeng Yan <chengpeng_yan@outlook.com>  
Discussion: https://postgr.es/m/CAMbWs4-QLZpn3UVOpeG2fOxxhdnkDNMZ_3Zcm3dqJwRAphz68g@mail.gmail.com  
Backpatch-through: 18  

M src/backend/optimizer/path/allpaths.c
M src/backend/optimizer/plan/planner.c
M src/backend/optimizer/util/clauses.c
M src/backend/utils/cache/lsyscache.c
M src/include/optimizer/clauses.h
M src/test/regress/expected/aggregates.out
M src/test/regress/expected/collate.icu.utf8.out
M src/test/regress/expected/subselect.out
M src/test/regress/sql/aggregates.sql
M src/test/regress/sql/collate.icu.utf8.sql
M src/test/regress/sql/subselect.sql
M src/tools/pgindent/typedefs.list

Emit a warning when io_min_workers exceeds io_max_workers

commit   : 9d1188f29865e66c4196578501e74e8c815fba8d    
  
author   : Michael Paquier <michael@paquier.xyz>    
date     : Mon, 6 Jul 2026 11:37:36 +0900    
  
committer: Michael Paquier <michael@paquier.xyz>    
date     : Mon, 6 Jul 2026 11:37:36 +0900    

Click here for diff

When io_min_workers is set strictly higher than io_max_workers, the  
minimum has no effect since the pool will never grow past  
io_max_workers.  Previously this was silently accepted, which could  
be confusing for users expecting at least io_min_workers workers to  
always be running.  
  
In order to avoid noise in the server logs, the following restrictions  
are in place:  
- The only process printing the WARNING is the IO worker with ID 0, on  
startup and reload, which is we know the only process always running  
when using IO workers.  
- At reload, the message shows only if one of the bounds has changed.  
  
Note that this commit reuses a log message updated by 7905416eef9b.  
  
Author: Baji Shaik <baji.pgdev@gmail.com>  
Reviewed-by: Tristan Partin <tristan@partin.io>  
Reviewed-by: Kyotaro Horiguchi <horikyota.ntt@gmail.com>  
Discussion: https://postgr.es/m/CA+fm-RO_O7-XThg2qjj=ir35x9nOFbZYu07gttqAbM5T88QB4Q@mail.gmail.com  

M src/backend/storage/aio/method_worker.c

Improve checks and error messages of pgstat_register_kind()

commit   : a924407ce0264ccb8fcea0de9c6f0573d24b57a7    
  
author   : Michael Paquier <michael@paquier.xyz>    
date     : Mon, 6 Jul 2026 10:49:28 +0900    
  
committer: Michael Paquier <michael@paquier.xyz>    
date     : Mon, 6 Jul 2026 10:49:28 +0900    

Click here for diff

pgstat_register_kind() did not validate that required callbacks are  
set, which could lead to NULL pointer dereferences when trying to  
register a stats kind.  This adds a couple of checks:  
- Fox fixed-sized kinds, init_shmem_cb, reset_all_cb, and snapshot_cb  
are required.  
- For variable-sized kinds, flush_pending_cb is called when there is  
pending data, pending_size being required.  
  
These issues should be easy to notice for someone developing an  
extension that relies on the custom pgstats APIs.  No backpatch is done  
as it is mainly a life improvement.  
  
Author: Sami Imseih <samimseih@gmail.com>  
Discussion: https://postgr.es/m/CAA5RZ0uNoe=xT7QsU1K0mMRg-QAwPtupPWZ2J3weM2PjVL2tiA@mail.gmail.com  

M src/backend/utils/activity/pgstat.c

amcheck: Fix memory leak with gin_index_check()

commit   : e939332c6b1c7750f161424d8fbf8989b11cb5f6    
  
author   : Michael Paquier <michael@paquier.xyz>    
date     : Mon, 6 Jul 2026 09:32:25 +0900    
  
committer: Michael Paquier <michael@paquier.xyz>    
date     : Mon, 6 Jul 2026 09:32:25 +0900    

Click here for diff

"prev_tuple" was overwritten with a new tuple coming from  
CopyIndexTuple() on each loop, leaking memory for every tuple processed  
on entry tree pages.  The function uses a dedicated memory context, but  
this could leave unused large areas of memory while processing a large  
GIN index, the larger the worse.  
  
Oversight in 14ffaece0fb5.  
  
Author: Kirill Reshke <reshkekirill@gmail.com>  
Reviewed-by: Ewan Young <kdbase.hack@gmail.com>  
Discussion: https://postgr.es/m/CALdSSPjTS6TYe5=5NfMUBYZyQu5cn=ABL6K5_OZjzGWqnwXeBw@mail.gmail.com  
Backpatch-through: 18  

M contrib/amcheck/verify_gin.c

Fix psql's pager selection for wrapped expanded output.

commit   : 07abbc93ba5ba41b60927221db92bc73f75fd1ba    
  
author   : Tom Lane <tgl@sss.pgh.pa.us>    
date     : Sun, 5 Jul 2026 18:11:40 -0400    
  
committer: Tom Lane <tgl@sss.pgh.pa.us>    
date     : Sun, 5 Jul 2026 18:11:40 -0400    

Click here for diff

psql decided whether to use the pager in expanded output without  
accounting for possible wrapping of column values.  This could  
allow it to not use the pager in cases where it should do so.  
  
To fix, move the IsPagerNeeded decision in print_aligned_vertical()  
down until after the wrapped data width is known.  Then, if we're in  
wrapped mode, prepare a width_wrap array specifying that width (which,  
in vertical mode, is the same for all columns).  
  
This is fixing an omission in 27da1a796, so back-patch to v19  
where that came in.  
  
Author: Chao Li <li.evan.chao@gmail.com>  
Reviewed-by: Erik Wienhold <ewie@ewie.name>  
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>  
Discussion: https://postgr.es/m/A44110E7-6A03-4C67-95AD-527192A6C768@gmail.com  
Backpatch-through: 19  

M src/bin/psql/t/030_pager.pl
M src/fe_utils/print.c

Simplify dxsyn_lexize().

commit   : 9f03dab4574bd2820eec6902c2ef12b28c706733    
  
author   : Tom Lane <tgl@sss.pgh.pa.us>    
date     : Sun, 5 Jul 2026 16:22:40 -0400    
  
committer: Tom Lane <tgl@sss.pgh.pa.us>    
date     : Sun, 5 Jul 2026 16:22:40 -0400    

Click here for diff

There's no need to create and free a temporary copy of the input,  
since str_tolower() is already able to cope with not-certainly-  
nul-terminated input.  (Before v18, copying was needed because  
this code used lowerstr(), but now we can do without.)  
  
Author: Ayush Tiwari <ayushtiwari.slg01@gmail.com>  
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>  
Discussion: https://postgr.es/m/19525-b0be8e4eb7dbaf07@postgresql.org  

M contrib/dict_xsyn/dict_xsyn.c

Fix properties orphaned by dropping a label

commit   : 0e4f0827f63900374ce7352f1f9e4c39363218d0    
  
author   : Peter Eisentraut <peter@eisentraut.org>    
date     : Sun, 5 Jul 2026 13:47:18 +0200    
  
committer: Peter Eisentraut <peter@eisentraut.org>    
date     : Sun, 5 Jul 2026 13:47:18 +0200    

Click here for diff

AlterPropGraph() cleans up pg_propgraph_property entries that are  
orphaned by dropping an element or by dropping properties associated  
with an element.  But it did not clean up pg_propgraph_property  
entries that are orphaned by dropping labels associated with an  
element.  Fix this missing case.  
  
Author: Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>  
Author: zengman <zengman@halodbtech.com>  
Discussion: https://www.postgresql.org/message-id/flat/tencent_76F6ACA2364EAA1E5DBD7A47%40qq.com  

M src/backend/commands/propgraphcmds.c
M src/test/regress/expected/create_property_graph.out
M src/test/regress/sql/create_property_graph.sql

Disallow renaming a rule to "_RETURN".

commit   : a8c2547eaac73cd6d499a4ab151f0401bf647f56    
  
author   : Tom Lane <tgl@sss.pgh.pa.us>    
date     : Sat, 4 Jul 2026 11:34:26 -0400    
  
committer: Tom Lane <tgl@sss.pgh.pa.us>    
date     : Sat, 4 Jul 2026 11:34:26 -0400    

Click here for diff

ON SELECT rules must be named "_RETURN", while other kinds of rules  
must not be; this ancient restriction is depended on by various client  
code.  We successfully enforced this convention in most places, but  
ALTER RULE allowed renaming a non-SELECT rule to "_RETURN".  Notably,  
that would break dump/restore, since the eventual CREATE RULE command  
would reject the name.  
  
While at it, remove DefineQueryRewrite's hack to substitute "_RETURN"  
for the convention that was used before 7.3.  We dropped other  
server-side code that supported restoring pre-7.3 dumps some time ago  
(notably in e58a59975 and nearby commits), but this bit was missed.  
  
Bug: #19543  
Reported-by: Adam Pickering <adamkpickering@gmail.com>  
Author: Tom Lane <tgl@sss.pgh.pa.us>  
Discussion: https://postgr.es/m/19543-461228e77f3b32fc@postgresql.org  
Backpatch-through: 14  

M src/backend/rewrite/rewriteDefine.c
M src/test/regress/expected/rules.out
M src/test/regress/sql/rules.sql

Make property graph object descriptions better translatable

commit   : e0ff7fd9aa2e6f77c38825e71200ced742220d55    
  
author   : Peter Eisentraut <peter@eisentraut.org>    
date     : Fri, 3 Jul 2026 23:32:20 +0200    
  
committer: Peter Eisentraut <peter@eisentraut.org>    
date     : Fri, 3 Jul 2026 23:32:20 +0200    

Click here for diff

getObjectDescription() currently constructs property graph-related  
object descriptions incrementally with appendStringInfo().  This  
effectively fixes the word order in English, which makes the messages  
difficult to translate naturally into languages such as Japanese.  
  
Author: Kyotaro Horiguchi <horikyota.ntt@gmail.com>  
Reviewed-by: Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>  
Discussion: https://www.postgresql.org/message-id/flat/20260528.121622.1662808269492494574.horikyota.ntt%40gmail.com  

M src/backend/catalog/objectaddress.c

Remove btree_gist's useless logic for encoding-aware truncation.

commit   : b82d69abf64fc0c2fc6fdd491d7cecb8244680c2    
  
author   : Tom Lane <tgl@sss.pgh.pa.us>    
date     : Fri, 3 Jul 2026 15:31:58 -0400    
  
committer: Tom Lane <tgl@sss.pgh.pa.us>    
date     : Fri, 3 Jul 2026 15:31:58 -0400    

Click here for diff

gbt_var_node_cp_len() contained logic to ensure that its choice of  
a common prefix length didn't truncate away part of a multibyte  
character.  However, that was really dead code, because we have not  
allowed truncation of text-string data types since ef770cbb6, and  
it seems unlikely that that behavior could ever get resurrected.  
The code is still reachable via gbt_var_penalty, but for that  
usage it hardly matters if we break in the middle of a multibyte  
character: we're just calculating a small correction factor that  
is arguably bunkum anyway in non-C locales.  
  
Hence, delete said code.  That actually removes all need for  
gbtree_vinfo.eml, which allows const-ification of the gbtree_vinfo  
structs in which we were changing it, which removes one headache  
for future attempts to thread-ify the backend.  
  
(Curiously, all this infrastructure was itself added by ef770cbb6.  
Not sure why Teodor didn't see the contradiction.)  
  
Author: Tom Lane <tgl@sss.pgh.pa.us>  
Reviewed-by: Ayush Tiwari <ayushtiwari.slg01@gmail.com>  
Discussion: https://postgr.es/m/AH*AvQCYKhQGVvPWi1GiU4oY.8.1781609375063.Hmail.3020001251@tju.edu.cn  

M contrib/btree_gist/btree_bit.c
M contrib/btree_gist/btree_bytea.c
M contrib/btree_gist/btree_numeric.c
M contrib/btree_gist/btree_text.c
M contrib/btree_gist/btree_utils_var.c
M contrib/btree_gist/btree_utils_var.h

Tighten up btree_gist's handling of truncated bounds.

commit   : fea9c1884b2009a94287989e961d6493e22bf656    
  
author   : Tom Lane <tgl@sss.pgh.pa.us>    
date     : Fri, 3 Jul 2026 15:25:19 -0400    
  
committer: Tom Lane <tgl@sss.pgh.pa.us>    
date     : Fri, 3 Jul 2026 15:25:19 -0400    

Click here for diff

Truncating an internal node's upper bound can cause it to compare  
less than some values that in fact are included in the represented  
leaf page.  So we need a hack to make sure it looks large enough  
to include all values that could be on the page.  But there's no  
equivalent issue for the lower bound.  The fact that the code did  
fuzzy comparisons for the lower bound too seems to be the result of  
fuzzy thinking.  Or maybe there was a desire to not assume too much  
about what the datatype's comparison rule is; but we've already  
fully bought into the premise that internal keys compare like bytea.  
  
Hence, remove the useless check against the key's lower bound in  
gbt_var_node_pf_match.  The comparable check in gbt_var_penalty may  
also be useless, but I'm not quite sure.  In any case that seems  
negligible from a performance standpoint, so I left it alone.  
  
Also, in the strategy cases in gbt_var_consistent that only  
require comparisons to the lower bound, there's no need to call  
gbt_var_node_pf_match at all.  Refactor that logic by inventing  
macros lower_is_below_query and upper_is_above_query to directly  
express what we need to test.  I also took this opportunity to flip  
all the tests around to be "indexkey OP query" rather than mostly  
being the reverse: IMO this makes the code less confusing since the  
tests now match the names of the strategies.  
  
Also, in the name of consistency, make gbt_num_consistent look  
like that too.  There's no functional change there, but this  
should be more readable going forward.  
  
Author: Tom Lane <tgl@sss.pgh.pa.us>  
Reviewed-by: Ayush Tiwari <ayushtiwari.slg01@gmail.com>  
Discussion: https://postgr.es/m/AH*AvQCYKhQGVvPWi1GiU4oY.8.1781609375063.Hmail.3020001251@tju.edu.cn  

M contrib/btree_gist/btree_utils_num.c
M contrib/btree_gist/btree_utils_var.c

Sync signatures of gbt_var_consistent() and gbt_num_consistent().

commit   : 4b808ed77cd95dd1d6bf7acdb8ee4f8eb027422c    
  
author   : Tom Lane <tgl@sss.pgh.pa.us>    
date     : Fri, 3 Jul 2026 14:23:22 -0400    
  
committer: Tom Lane <tgl@sss.pgh.pa.us>    
date     : Fri, 3 Jul 2026 14:23:22 -0400    

Click here for diff

For some odd reason we pass the strategy number to gbt_num_consistent  
as "const StrategyNumber *strategy".  There's no reason for that:  
it almost certainly costs more at both callers and callee to pass a  
pointer than to pass a small integer value.  And it's inconsistent  
with gbt_var_consistent(), so fix it.  
  
gbt_var_consistent() had its own infelicity, which was not marking  
the input "key" value const.  Fix that too while we're here.  
  
This is primarily cosmetic, so I see no need to backpatch.  
  
Author: Tom Lane <tgl@sss.pgh.pa.us>  
Discussion: https://postgr.es/m/AH*AvQCYKhQGVvPWi1GiU4oY.8.1781609375063.Hmail.3020001251@tju.edu.cn  

M contrib/btree_gist/btree_bool.c
M contrib/btree_gist/btree_cash.c
M contrib/btree_gist/btree_date.c
M contrib/btree_gist/btree_enum.c
M contrib/btree_gist/btree_float4.c
M contrib/btree_gist/btree_float8.c
M contrib/btree_gist/btree_inet.c
M contrib/btree_gist/btree_int2.c
M contrib/btree_gist/btree_int4.c
M contrib/btree_gist/btree_int8.c
M contrib/btree_gist/btree_interval.c
M contrib/btree_gist/btree_macaddr.c
M contrib/btree_gist/btree_macaddr8.c
M contrib/btree_gist/btree_oid.c
M contrib/btree_gist/btree_time.c
M contrib/btree_gist/btree_ts.c
M contrib/btree_gist/btree_utils_num.c
M contrib/btree_gist/btree_utils_num.h
M contrib/btree_gist/btree_utils_var.c
M contrib/btree_gist/btree_utils_var.h
M contrib/btree_gist/btree_uuid.c

REPACK CONCURRENTLY: Initialize the range table more honestly

commit   : 5ee9d7c299f2fe2f29db18c6448f798950efe22e    
  
author   : Álvaro Herrera <alvherre@kurilemu.de>    
date     : Fri, 3 Jul 2026 20:04:48 +0200    
  
committer: Álvaro Herrera <alvherre@kurilemu.de>    
date     : Fri, 3 Jul 2026 20:04:48 +0200    

Click here for diff

We were skipping a bunch of things that are mostly unnecessary for  
REPACK.  However, one thing that seems would be better to pass closer to  
truth, is the updatedCols bitmapset in the range table entry for the  
repacked table.  Cons up an RTE and install it into the EState.  
  
This only has an effect on btree indexes, because certain operations are  
optimized in the case of unchanged columns; and even then, correctnesss  
is not being compromised.  
  
The values we pass after this commit are not fully trustworthy either,  
because we simply say "all columns were updated" for all insert/updates,  
regardless of whether their values were actually modified or not.  
However, this way we err to the side of caution rather than to the  
opposite direction as we were originally doing.  This could be refined  
in the future, but there's a trade-off: determining whether the column  
was in fact updated could be expensive.  
  
Author: Antonin Houska <ah@cybertec.at>  
Reviewed-by: Ewan Young <kdbase.hack@gmail.com>  
Backpatch-through: 19  
Discussion: https://postgr.es/m/18222.1782126731@localhost  

M src/backend/commands/repack.c

Fix btree_gist's NotEqual strategy on internal index pages.

commit   : eef644e57c38a79eb29bf9f3f05efbcee8fbdfce    
  
author   : Tom Lane <tgl@sss.pgh.pa.us>    
date     : Fri, 3 Jul 2026 13:50:14 -0400    
  
committer: Tom Lane <tgl@sss.pgh.pa.us>    
date     : Fri, 3 Jul 2026 13:50:14 -0400    

Click here for diff

gbt_var_consistent() handled the <> (BtreeGistNotEqual) strategy without  
distinguishing leaf from internal pages, unlike every other strategy.  
In particular, it tried to apply the datatype-specific f_eq method,  
which is completely wrong since internal keys might not have the same  
representation as leaf keys.  This led to OOB reads and potentially  
crashes, and most likely to wrong query results as well.  
  
On leaf pages we can apply the inverse of what the Equal strategy does.  
On internal pages, use a correct implementation of what the previous  
code intended: we can descend if the query value equals both bounds,  
*so long as the bounds aren't truncated*.  With truncated bounds we  
don't quite know the range of what's below, so we must always descend.  
  
Adjust the code in gbt_num_consistent() to look similar, too.  This  
fixes a performance buglet in that there's no need to do two comparisons  
on a leaf entry, but the main point is just to keep code consistency.  
  
Reported-by: 王跃林 <violin0613@tju.edu.cn>  
Author: Ayush Tiwari <ayushtiwari.slg01@gmail.com>  
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>  
Discussion: https://postgr.es/m/AH*AvQCYKhQGVvPWi1GiU4oY.8.1781609375063.Hmail.3020001251@tju.edu.cn  
Backpatch-through: 14  

M contrib/btree_gist/btree_utils_num.c
M contrib/btree_gist/btree_utils_var.c

Reverse-engineer some documentation for btree_gist's varlena modules.

commit   : d6284bbd152c1ea9e73bc77d6cb26bbf636d569b    
  
author   : Tom Lane <tgl@sss.pgh.pa.us>    
date     : Fri, 3 Jul 2026 13:18:13 -0400    
  
committer: Tom Lane <tgl@sss.pgh.pa.us>    
date     : Fri, 3 Jul 2026 13:18:13 -0400    

Click here for diff

There are a number of rather subtle points about the behavior of  
this code, which its original authors did not deign to document.  
Try to improve that.  In particular, explain how internal and leaf  
keys can differ and what the restrictions are on that.  
  
This work arose from trying to fix some bugs, and in the process  
I believe I've identified some more, but this patch does not attempt  
to fix anything, only document it.  I did make a few purely cosmetic  
code changes, such as removing dead (and confusing!) initializations  
of variables and choosing more appropriate types for some pointers.  
  
Author: Tom Lane <tgl@sss.pgh.pa.us>  
Reviewed-by: Ayush Tiwari <ayushtiwari.slg01@gmail.com>  
Discussion: https://postgr.es/m/AH*AvQCYKhQGVvPWi1GiU4oY.8.1781609375063.Hmail.3020001251@tju.edu.cn  

M contrib/btree_gist/btree_bit.c
M contrib/btree_gist/btree_bytea.c
M contrib/btree_gist/btree_numeric.c
M contrib/btree_gist/btree_text.c
M contrib/btree_gist/btree_utils_var.c
M contrib/btree_gist/btree_utils_var.h

Use the proper comparator in gbt_bit_ssup_cmp.

commit   : a9fa6c69e3f5405866a0ebed27597e80760abc77    
  
author   : Tom Lane <tgl@sss.pgh.pa.us>    
date     : Fri, 3 Jul 2026 13:11:14 -0400    
  
committer: Tom Lane <tgl@sss.pgh.pa.us>    
date     : Fri, 3 Jul 2026 13:11:14 -0400    

Click here for diff

If we're dealing with leaf entries, the function to call is bitcmp  
not byteacmp.  Using byteacmp didn't lead to any obvious failure,  
but it did result in sorting the entries in a way not matching the  
datatype's actual sort order.  Hence the constructed index would be  
less efficient than one would expect, and in particular worse than  
what you got before this code was added in v18 (by commit e4309f73f).  
  
We might want to recommend that users reindex btree_gist indexes  
on bit/varbit columns.  
  
Author: Tom Lane <tgl@sss.pgh.pa.us>  
Reviewed-by: Ayush Tiwari <ayushtiwari.slg01@gmail.com>  
Discussion: https://postgr.es/m/AH*AvQCYKhQGVvPWi1GiU4oY.8.1781609375063.Hmail.3020001251@tju.edu.cn  
Backpatch-through: 18  

M contrib/btree_gist/btree_bit.c

Resolve unknown-type literals in GRAPH_TABLE COLUMNS

commit   : efd7d8d7d495472b2e5091af325474f05853214b    
  
author   : Peter Eisentraut <peter@eisentraut.org>    
date     : Fri, 3 Jul 2026 16:58:31 +0200    
  
committer: Peter Eisentraut <peter@eisentraut.org>    
date     : Fri, 3 Jul 2026 16:58:31 +0200    

Click here for diff

The unknown-type literals in the COLUMNS clause of a GRAPH_TABLE are  
now resolved to the appropriate types.  Without that, this could cause  
various failures.  
  
Author: Satya Narlapuram <satyanarlapuram@gmail.com>  
Author: Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>  
Reviewed-by: Junwang Zhao <zhjwpku@gmail.com>  
Discussion: https://www.postgresql.org/message-id/flat/CAHg%2BQDcyKNWyzDoKMxiZNjv7C-wAxs8y0ZoNkOV137Y%2Bnk3UXg%40mail.gmail.com  

M src/backend/parser/parse_clause.c
M src/test/regress/expected/graph_table.out
M src/test/regress/sql/graph_table.sql

Prevent access to other sessions' empty temp tables

commit   : c40819ebf954eefe8ec35c210b8a3d7a7a7aaea0    
  
author   : Alexander Korotkov <akorotkov@postgresql.org>    
date     : Fri, 3 Jul 2026 15:53:03 +0300    
  
committer: Alexander Korotkov <akorotkov@postgresql.org>    
date     : Fri, 3 Jul 2026 15:53:03 +0300    

Click here for diff

Commit ce146621 ensures that ERROR is raised if a session tries to read  
pages of another session's temp table.  But there is a corner case where  
the other session's temp table is empty -- in this case the INSERT  
command bypasses our checks and executes without any errors.  
  
Such behavior is inconsistent and erroneous: it leaves an invalid buffer  
in the temp buffers pool.  Since the buffer was created for another  
session's temp table, we get an error "no such file or directory" when  
trying to flush it.  
  
This commit fixes it by adding a RELATION_IS_OTHER_TEMP check in the  
relation-extension path.  
  
Backpatch to 16, because it is the first release after 31966b151e6, which  
introduced a separate local relation extension function  
ExtendBufferedRelLocal(), which lacks of RELATION_IS_OTHER_TEMP() check.  
As this fix introduces more checks to 013_temp_obj_multisession.pl, backpatch  
the whole test script to 16.  
  
Discussion: https://postgr.es/m/CAJDiXgiX2XZBHDNo%2BzBbvku%2BtchrUurvPRaN1_40mEQ1_sG90g%40mail.gmail.com  
Author: Daniil Davydov <3danissimo@gmail.com>  
Reviewed-by: Jim Jones <jim.jones@uni-muenster.de>  
Reviewed-by: Imran Zaheer <imran.zhir@gmail.com>  
Reviewed-by: ZizhuanLiu X-MAN <44973863@qq.com>  
Backpatch-through: 16  

M src/backend/storage/buffer/bufmgr.c
M src/include/utils/rel.h
M src/test/modules/test_misc/t/013_temp_obj_multisession.pl

Fix handling of dropping a property not associated with the given label

commit   : 96418a6da9d0e120c30f9b6c2c2bd8bbb0a98d00    
  
author   : Peter Eisentraut <peter@eisentraut.org>    
date     : Fri, 3 Jul 2026 16:06:29 +0200    
  
committer: Peter Eisentraut <peter@eisentraut.org>    
date     : Fri, 3 Jul 2026 16:06:29 +0200    

Click here for diff

When dropping a property by name from a label, the code checked only  
whether the property existed in the graph's property catalog.  It did  
not verify that the property was actually associated with the given  
label, resulting in passing InvalidOid to performDeletion().  Fix it  
by explicilty checking the label property association.  
  
While at it also rearrange the code so as to avoid multiple ereport  
calls for the same error in the same block.  
  
Author: Chao Li <lic@highgo.com>  
Reviewed-by: Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>  
Discussion: https://www.postgresql.org/message-id/flat/1DA5D52A-4AFA-426E-83F7-42ED974D682B%40gmail.com  

M src/backend/commands/propgraphcmds.c
M src/test/regress/expected/create_property_graph.out
M src/test/regress/sql/create_property_graph.sql

Fix tracing of BackendKeyData and CancelRequest

commit   : b22b619056e8dc6f5f9966f8b9781bdc7cbec897    
  
author   : Heikki Linnakangas <heikki.linnakangas@iki.fi>    
date     : Fri, 3 Jul 2026 14:57:35 +0300    
  
committer: Heikki Linnakangas <heikki.linnakangas@iki.fi>    
date     : Fri, 3 Jul 2026 14:57:35 +0300    

Click here for diff

BackendKeyData length was increased from 4 bytes to a variable-length  
length (up to 256 bytes) in a460251f0a. However, pqTrace still traces  
it as a 4 bytes key, leading to a "mismatched message length" warning  
message. The same issue impacts the tracing of CancelRequest.  
  
This patch fixes the issue by using pqTraceOutputNchar instead of  
pqTraceOutputInt32 in both cases.  
  
Author: Anthonin Bonnefoy <anthonin.bonnefoy@datadoghq.com>  
Discussion: https://www.postgresql.org/message-id/CAO6_Xqo6gTv9=76H=k2qDRFU+KHuBiY2S=bQynEr6J8gS7L6xA@mail.gmail.com  
Backpatch-through: 18  

M src/interfaces/libpq/fe-trace.c

Fix REPACK CONCURRENTLY for stored generated columns

commit   : 3be823486f2c9f405fc754ac0ece3ce412aee105    
  
author   : Álvaro Herrera <alvherre@kurilemu.de>    
date     : Fri, 3 Jul 2026 12:22:37 +0200    
  
committer: Álvaro Herrera <alvherre@kurilemu.de>    
date     : Fri, 3 Jul 2026 12:22:37 +0200    

Click here for diff

In order to replay concurrent changes, REPACK CONCURRENTLY needs the  
pg_attrdef tuples for the transient table to be there, in case a tuple  
is modified concurrently with REPACK and requires to store the value  
from the generated column (which, with the current arrangements, means  
all tuples concurrently updated or inserted).  Fix by creating a copy of  
them from the original table.  Add a test that tickles the bug.  
  
Author: Antonin Houska <ah@cybertec.at>  
Reported-by: Ewan Young <kdbase.hack@gmail.com>  
Diagnosed-by: Ewan Young <kdbase.hack@gmail.com>  
Reviewed-by: Ewan Young <kdbase.hack@gmail.com>  
Backpatch-through: 19  
Discussion: https://postgr.es/m/CAON2xHMrELwx9vKg6niSf8fMBA=-MGXmG=MPQU6+vMVhGjF8kQ@mail.gmail.com  

M src/backend/commands/repack.c
M src/test/modules/injection_points/specs/repack.spec

Prevent dropping the last label from a property graph element

commit   : 7afa11feca6c4e48d01890580564d55cf226fe02    
  
author   : Peter Eisentraut <peter@eisentraut.org>    
date     : Fri, 3 Jul 2026 11:52:42 +0200    
  
committer: Peter Eisentraut <peter@eisentraut.org>    
date     : Fri, 3 Jul 2026 11:52:42 +0200    

Click here for diff

Per SQL/PGQ standard, every graph element must have at least one  
label.  When dropping a label from a graph element, ensure that there  
exists at least one other label on the element.  If the label being  
dropped is the only label on the element, raise an error.  
  
We hold a ShareRowExclusiveLock when modifying a property graph.  
Hence the label will not be dropped even when multiple labels are  
being dropped concurrently.  
  
Author: Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>  
Author: Satyanarayana Narlapuram <satyanarlapuram@gmail.com>  
Reported-by: Satyanarayana Narlapuram <satyanarlapuram@gmail.com>  
Discussion: https://www.postgresql.org/message-id/CAHg+QDeP=mTHTV48R23zKMy1SBmCKZ_L7-z5zKnYyw+K0x-gCg@mail.gmail.com  

M doc/src/sgml/ref/alter_property_graph.sgml
M src/backend/commands/propgraphcmds.c
M src/test/regress/expected/create_property_graph.out
M src/test/regress/sql/create_property_graph.sql

Add commit fdad19e1cf to .git-blame-ignore-revs.

commit   : 617c7574055009fc6678a0f17bc9160d94e58607    
  
author   : Amit Kapila <akapila@postgresql.org>    
date     : Fri, 3 Jul 2026 14:05:21 +0530    
  
committer: Amit Kapila <akapila@postgresql.org>    
date     : Fri, 3 Jul 2026 14:05:21 +0530    

Click here for diff

M .git-blame-ignore-revs

Fix log_statement_max_length test with verbose logs

commit   : 9bfbf5bf61901b57d86fab20559b7973b5a83298    
  
author   : Fujii Masao <fujii@postgresql.org>    
date     : Fri, 3 Jul 2026 14:41:44 +0900    
  
committer: Fujii Masao <fujii@postgresql.org>    
date     : Fri, 3 Jul 2026 14:41:44 +0900    

Click here for diff

Buildfarm member prion reported a failure in the test added by commit  
c8bd8387c27 to verify that the server logs an empty statement body  
when log_statement_max_length = 0.  
  
The test assumed that "statement:" would appear immediately after  
"LOG:" in the logged statement message. However, prion runs with  
log_error_verbosity = verbose, which inserts the SQLSTATE between  
"LOG:" and the message text. As a result, the test failed even though  
the server behaved correctly.  
  
Per buildfarm member prion.  
  
Discussion: https://postgr.es/m/CAHGQGwFiQKwvLVG+U0WWNo2kgkQ88FVGhYH_MBZu9Y0SJ8BjDw@mail.gmail.com  

M src/test/modules/test_misc/t/014_log_statement_max_length.pl

psql: Fix \df tab completion for procedures

commit   : 6d4ca6de97770cdaee18517dd2f8fe8f4ecee187    
  
author   : Fujii Masao <fujii@postgresql.org>    
date     : Fri, 3 Jul 2026 13:46:35 +0900    
  
committer: Fujii Masao <fujii@postgresql.org>    
date     : Fri, 3 Jul 2026 13:46:35 +0900    

Click here for diff

Commit fb421231daa extended \df to include procedures, but its tab  
completion continued not to show procedures.  
  
Update \df tab completion to include procedures as well.  
  
Backpatch to all supported versions.  
  
Author: Erik Wienhold <ewie@ewie.name>  
Reviewed-by: Surya Poondla <suryapoondla4@gmail.com>  
Reviewed-by: Fujii Masao <masao.fujii@gmail.com>  
Discussion: https://postgr.es/m/10fbfdfe-80f6-4ef9-b8b3-f7be0eb53a50@ewie.name  
Backpatch-through: 14  

M src/bin/psql/tab-complete.in.c

pgindent fix for commit 53e6f51ee

commit   : a5422fe3bd7ecd9c64cf4a8acf5f510b8da676c5    
  
author   : Richard Guo <rguo@postgresql.org>    
date     : Fri, 3 Jul 2026 12:31:15 +0900    
  
committer: Richard Guo <rguo@postgresql.org>    
date     : Fri, 3 Jul 2026 12:31:15 +0900    

Click here for diff

M contrib/pg_plan_advice/pgpa_scan.c

Fix typo in pg_stat_us_to_ms()

commit   : 71fa15af591a3ec61a6bf57fee3a44a7824fba19    
  
author   : Michael Paquier <michael@paquier.xyz>    
date     : Fri, 3 Jul 2026 12:22:14 +0900    
  
committer: Michael Paquier <michael@paquier.xyz>    
date     : Fri, 3 Jul 2026 12:22:14 +0900    

Click here for diff

The function converts microseconds to milliseconds, but the parameter  
name used "ms".  
  
Thinko in ac8d53dae5ae.  
  
Author: Tatsuya Kawata <kawatatatsuya0913@gmail.com>  
Discussion: https://postgr.es/m/CAHza6qfek15rehnA0GXMCpF2z=Gy6C+3vmcWCMVkU4JiRD8k7g@mail.gmail.com  

M src/backend/utils/adt/pgstatfuncs.c

Switch Get[Local]BufferDescriptor() to use a signed value in input

commit   : ba4134075a822e119e2ca6c2718ff08ae9464a37    
  
author   : Michael Paquier <michael@paquier.xyz>    
date     : Fri, 3 Jul 2026 12:07:30 +0900    
  
committer: Michael Paquier <michael@paquier.xyz>    
date     : Fri, 3 Jul 2026 12:07:30 +0900    

Click here for diff

GetBufferDescriptor() and GetLocalBufferDescriptor() took a uint32  
buffer index, but every real caller derives the index from a Buffer:  
- Unsigned value for shared buffers.  
- Signed value for local buffers.  
  
Both routines now take in input a signed number, GetBufferDescriptor()  
gaining an assertion checking that the input value is in the range  
allowed by the GUC shared_buffers.  This work is a follow-up of  
e18b0cb7344c, where we found that passing down a value for a local  
buffer was undetected and finished outside the range of NBuffers.  
  
While monitoring all the existing callers of *BufferDescriptor(), the  
only consumer that passes does an unsigned value is ClockSweepTick(),  
whose result is always a module of NBuffers.  
  
Suggested-by: Andres Freund <andres@anarazel.de>  
Author: Ayush Tiwari <ayushtiwari.slg01@gmail.com>  
Reviewed-by: Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>  
Reviewed-by: Michael Paquier <michael@paquier.xyz>  
Discussion: https://postgr.es/m/CAExHW5uzRMYVZsXXS3HXXT0fG_sNrpUhUqwP4NorhaCqH9JDhA@mail.gmail.com  

M src/include/storage/buf_internals.h

Remove replication slot advice from MultiXact wraparound hints

commit   : 084734ff5a4249f0095771ee1addedbd41a88a18    
  
author   : Fujii Masao <fujii@postgresql.org>    
date     : Fri, 3 Jul 2026 11:16:34 +0900    
  
committer: Fujii Masao <fujii@postgresql.org>    
date     : Fri, 3 Jul 2026 11:16:34 +0900    

Click here for diff

Previously, MultiXactId wraparound hints suggested dropping stale  
replication slots. While that advice is appropriate for transaction ID  
wraparound, where replication slots can hold back XID horizons,  
it was misleading for MultiXactId wraparound. Following it could lead  
users to drop replication slots unnecessarily without helping resolve  
the MultiXactId wraparound condition.  
  
MultiXact cleanup is not directly delayed by replication slots.  
Instead, it depends on whether old MultiXactIds can still be seen  
as live by running transactions.  
  
This commit removes the replication slot advice from MultiXactId  
wraparound hints, and documents that stale replication slots are  
normally not relevant to resolving MultiXactId wraparound problems.  
  
Backpatch to all supported branches.  
  
BUG #18876  
Reported-by: Haruka Takatsuka <harukat@sraoss.co.jp>  
Author: Fujii Masao <masao.fujii@gmail.com>  
Discussion: https://postgr.es/m/18876-0d0b53bad5a1f4c1@postgresql.org  
Backpatch-through: 14  

M doc/src/sgml/maintenance.sgml
M src/backend/access/transam/multixact.c
M src/backend/commands/vacuum.c

Add log_statement_max_length GUC to limit logged statement text

commit   : c8bd8387c27ab0e60a7864d231f06e8c3fdbfa8d    
  
author   : Fujii Masao <fujii@postgresql.org>    
date     : Fri, 3 Jul 2026 08:47:18 +0900    
  
committer: Fujii Masao <fujii@postgresql.org>    
date     : Fri, 3 Jul 2026 08:47:18 +0900    

Click here for diff

Very large statements can make server logs grow unexpectedly. This is  
particularly painful when applications accidentally or intentionally  
send huge literal values and statement logging is enabled: the full  
statement text may be written to the log even when DBA sees only  
its leading part is useful for normal operations.  
  
This commit adds log_statement_max_length GUC that limits the number  
of bytes of statement text emitted by statement logging. The setting  
applies to statements logged by log_statement, log_min_duration_statement,  
log_min_duration_sample, and log_transaction_sample_rate. A positive  
value truncates the logged statement body to at most that many bytes,  
zero  logs an empty statement body, and the default value -1 preserves  
the existing behavior of logging statements in full.  
  
Truncation is byte-based, matching the GUC unit, but it clips only  
at multibyte character boundaries so that the log output remains valid.  
This setting does not affect statements logged because of  
log_min_error_statement; handling error-statement logging can be  
considered separately.  
  
Author: Jim Jones <jim.jones@uni-muenster.de>  
Author: Kirill Gavrilov <diphantxm@gmail.com>  
Reviewed-by: Kirill Reshke <reshkekirill@gmail.com>  
Reviewed-by: Álvaro Herrera <alvherre@kurilemu.de>  
Reviewed-by: Maxym Kharchenko <maxymkharchenko@gmail.com>  
Reviewed-by: Fujii Masao <masao.fujii@gmail.com>  
Discussion: https://postgr.es/m/CA+E0NR4S+NC6+QHyY_vUuQZMzLhKqczMx-jJVqtjAxF6+=JwAA@mail.gmail.com  

M doc/src/sgml/config.sgml
M src/backend/tcop/postgres.c
M src/backend/utils/misc/guc_parameters.dat
M src/backend/utils/misc/guc_tables.c
M src/backend/utils/misc/postgresql.conf.sample
M src/include/utils/guc.h
M src/test/modules/test_misc/meson.build
A src/test/modules/test_misc/t/014_log_statement_max_length.pl

pg_plan_advice: Don't generate FOREIGN_JOIN advice for a single relation.

commit   : 53e6f51eef55e8e4520901e40b4d143d944358c0    
  
author   : Robert Haas <rhaas@postgresql.org>    
date     : Thu, 2 Jul 2026 15:45:22 -0400    
  
committer: Robert Haas <rhaas@postgresql.org>    
date     : Thu, 2 Jul 2026 15:45:22 -0400    

Click here for diff

A foreign scan can target a single relation while still reaching the  
fs_relids branch of pgpa_build_scan() -- for example, when postgres_fdw  
pushes an aggregate down over one foreign table. In that case, no  
advice should be emitted.  
  
Author: Mahendra Singh Thalor <mahi6run@gmail.com>  
Co-authored-by: Robert Haas <rhaas@postgresql.org>  
Discussion: http://postgr.es/m/CAKYtNAofuAJBz6++SeikpCb=Y=MO1QgEuZNJ+KZOP2johF1r4Q@mail.gmail.com  

M contrib/pg_plan_advice/Makefile
M contrib/pg_plan_advice/meson.build
M contrib/pg_plan_advice/pgpa_scan.c
A contrib/pg_plan_advice/t/001_foreign_scan.pl

Add commit d69fdf79b8 to .git-blame-ignore-revs.

commit   : 9ef89fdb61046d0687e92ecea8035caef8a753c0    
  
author   : Nathan Bossart <nathan@postgresql.org>    
date     : Thu, 2 Jul 2026 13:05:50 -0500    
  
committer: Nathan Bossart <nathan@postgresql.org>    
date     : Thu, 2 Jul 2026 13:05:50 -0500    

Click here for diff

M .git-blame-ignore-revs

Run pgindent and pgperltidy for previous 3 commits.

commit   : d69fdf79b8ba7549a9c449e255aab0734cc67a4f    
  
author   : Nathan Bossart <nathan@postgresql.org>    
date     : Thu, 2 Jul 2026 13:05:50 -0500    
  
committer: Nathan Bossart <nathan@postgresql.org>    
date     : Thu, 2 Jul 2026 13:05:50 -0500    

Click here for diff

For ease of review, and to be able to put the indentation changes  
in .git-blame-ignore-revs, I did not fix the indentation of the  
last 3 commits.  Do that now.  
  
Discussion: https://postgr.es/m/adZ4j88Dq9r8y9_9%40nathan  

M src/bin/pg_dump/pg_dump.c
M src/bin/pg_dump/pg_dumpall.c
M src/bin/pg_upgrade/check.c
M src/bin/pg_upgrade/controldata.c
M src/bin/pg_upgrade/exec.c
M src/bin/pg_upgrade/multixact_rewrite.c
M src/bin/pg_upgrade/pg_upgrade.c
M src/bin/pg_upgrade/relfilenumber.c
M src/bin/pg_upgrade/t/006_transfer_modes.pl
M src/bin/psql/command.c
M src/bin/psql/describe.c

Remove psql support for pre-v10 servers.

commit   : 831bec45924a80cccf20cec7cf4c941874eb96c8    
  
author   : Nathan Bossart <nathan@postgresql.org>    
date     : Thu, 2 Jul 2026 13:05:50 -0500    
  
committer: Nathan Bossart <nathan@postgresql.org>    
date     : Thu, 2 Jul 2026 13:05:50 -0500    

Click here for diff

Per discussion, it seems like a good time to bump the minimum  
supported version for various applications.  Our current policy is  
to support at least 10 previous major versions, so this bumps the  
minimum to v10 for the v20 release.  For reference, the minimum was  
last bumped to v9.2 in 2021 for v15 (see commits 30e7c175b8,  
e469f0aaf3, cf0cab868a, and 492046fa9e).  
  
For ease of review, and to be able to put the indentation changes  
in .git-blame-ignore-revs, I did not fix the indentation in this  
patch.  I'll push a separate pgindent commit after these changes  
are applied.  
  
Reviewed-by: Fujii Masao <masao.fujii@gmail.com>  
Discussion: https://postgr.es/m/adZ4j88Dq9r8y9_9%40nathan  

M doc/src/sgml/ref/psql-ref.sgml
M src/bin/psql/command.c
M src/bin/psql/describe.c
M src/bin/psql/tab-complete.in.c

Remove pg_upgrade support for upgrading from pre-v10 servers.

commit   : 14d84180830768fee1d88e87e837567b89795736    
  
author   : Nathan Bossart <nathan@postgresql.org>    
date     : Thu, 2 Jul 2026 13:05:50 -0500    
  
committer: Nathan Bossart <nathan@postgresql.org>    
date     : Thu, 2 Jul 2026 13:05:50 -0500    

Click here for diff

Per discussion, it seems like a good time to bump the minimum  
supported version for various applications.  Our current policy is  
to support at least 10 previous major versions, so this bumps the  
minimum to v10 for the v20 release.  For reference, the minimum was  
last bumped to v9.2 in 2021 for v15 (see commits 30e7c175b8,  
e469f0aaf3, cf0cab868a, and 492046fa9e).  
  
For ease of review, and to be able to put the indentation changes  
in .git-blame-ignore-revs, I did not fix the indentation in this  
patch.  I'll push a separate pgindent commit after these changes  
are applied.  
  
Reviewed-by: Fujii Masao <masao.fujii@gmail.com>  
Discussion: https://postgr.es/m/adZ4j88Dq9r8y9_9%40nathan  

M doc/src/sgml/ref/pgupgrade.sgml
M src/bin/pg_upgrade/check.c
M src/bin/pg_upgrade/controldata.c
M src/bin/pg_upgrade/exec.c
M src/bin/pg_upgrade/file.c
M src/bin/pg_upgrade/multixact_rewrite.c
M src/bin/pg_upgrade/pg_upgrade.c
M src/bin/pg_upgrade/pg_upgrade.h
M src/bin/pg_upgrade/relfilenumber.c
M src/bin/pg_upgrade/server.c
M src/bin/pg_upgrade/t/006_transfer_modes.pl
M src/bin/pg_upgrade/version.c

Remove pg_dump/pg_dumpall support for dumping from pre-v10 servers.

commit   : 3a0a30884fd08301f211f064c1433f8148e67c3a    
  
author   : Nathan Bossart <nathan@postgresql.org>    
date     : Thu, 2 Jul 2026 13:05:50 -0500    
  
committer: Nathan Bossart <nathan@postgresql.org>    
date     : Thu, 2 Jul 2026 13:05:50 -0500    

Click here for diff

Per discussion, it seems like a good time to bump the minimum  
supported version for various applications.  Our current policy is  
to support at least 10 previous major versions, so this bumps the  
minimum to v10 for the v20 release.  For reference, the minimum was  
last bumped to v9.2 in 2021 for v15 (see commits 30e7c175b8,  
e469f0aaf3, cf0cab868a, and 492046fa9e).  As in previous changes of  
this sort, we aren't removing pg_restore's ability to read older  
archive files, though it's fair to wonder how that might be tested  
nowadays.  
  
For ease of review, and to be able to put the indentation changes  
in .git-blame-ignore-revs, I did not fix the indentation in this  
patch.  I'll push a separate pgindent commit after these changes  
are applied.  
  
Reviewed-by: Fujii Masao <masao.fujii@gmail.com>  
Discussion: https://postgr.es/m/adZ4j88Dq9r8y9_9%40nathan  

M doc/src/sgml/ref/pg_dump.sgml
M doc/src/sgml/runtime.sgml
M src/bin/pg_dump/connectdb.c
M src/bin/pg_dump/pg_dump.c
M src/bin/pg_dump/pg_dumpall.c

Use ssup_datum_*_cmp in more places

commit   : 51cd5d6f052306e9288ff8c162ca9596432a5d2e    
  
author   : John Naylor <john.naylor@postgresql.org>    
date     : Thu, 2 Jul 2026 15:53:44 +0700    
  
committer: John Naylor <john.naylor@postgresql.org>    
date     : Thu, 2 Jul 2026 15:53:44 +0700    

Click here for diff

The int2, oid, and oid8 "fastcmp" comparators are functionally  
equivalent to the ssup_datum_int32_cmp (for int2) and  
ssup_datum_unsigned_cmp (for oid, oid8) functions added by commit  
697492434, so simplify by using the latter instead. This has the  
added benefit of making these types eligible for radix sort.  
  
Author: Baji Shaik <baji.pgdev@gmail.com>  
Reviewed-by: Michael Paquier <michael@paquier.xyz>  
Discussion: https://postgr.es/m/CA+fm-RMyLC94NfrxCh273+dKs44U0ZJjRczznvzvgw=KtpPNVw@mail.gmail.com  

M src/backend/access/nbtree/nbtcompare.c

test_custom_stats: Fail if loading module outside shared_preload_libraries

commit   : 5045d9ff3b5a8b09742d8bf70221c7d708305219    
  
author   : Michael Paquier <michael@paquier.xyz>    
date     : Thu, 2 Jul 2026 15:52:46 +0900    
  
committer: Michael Paquier <michael@paquier.xyz>    
date     : Thu, 2 Jul 2026 15:52:46 +0900    

Click here for diff

Previously, test_custom_var_stats and test_custom_fixed_stats silently  
skipped pgstat_register_kind() when not loaded via  
shared_preload_libraries, behavior inherited from injection_points.  
This left the SQL functions callable without the kind registered,  
leading to various issues on the backend side.  
  
This code is not designed to work without the pgstats kinds registered.  
pgstat_register_kind() gets now called when these libraries are loaded,  
with or without shared_preload_libraries, letting the registration fail  
if loading the modules at a later step than startup.  test_custom_rmgrs  
does the same thing.  
  
Oversight in 31280d96a648.  
  
Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>  
Reviewed-by: Ewan Young <kdbase.hack@gmail.com>  
Discussion: https://postgr.es/m/akS/ldidWeqG1FWk@bdtpg  
Backpatch-through: 19  

M src/test/modules/test_custom_stats/test_custom_fixed_stats.c
M src/test/modules/test_custom_stats/test_custom_var_stats.c

Fix loss of precision in pg_stat_us_to_ms()

commit   : 3eca140531f1c8e58e9a59af827488616699a052    
  
author   : John Naylor <john.naylor@postgresql.org>    
date     : Thu, 2 Jul 2026 13:26:56 +0700    
  
committer: John Naylor <john.naylor@postgresql.org>    
date     : Thu, 2 Jul 2026 13:26:56 +0700    

Click here for diff

Multiplying by the constant 0.001 can produce trailing-digit noise in  
displayed values (for example 0.009000000000000001 instead of 0.009,  
with default extra_float_digits) because 0.001 cannot be represented  
exactly in binary floating point. Use division by 1000.0 instead,  
matching code elsewhere in the tree.  
  
Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>  
Discussion: https://postgr.es/m/akIYkMK4bHe9qX/N@bdtpg  

M src/backend/utils/adt/pgstatfuncs.c

Remove stale comment

commit   : 11b33bd3c19c5f28310dd97a3d785b773a789da4    
  
author   : John Naylor <john.naylor@postgresql.org>    
date     : Thu, 2 Jul 2026 13:15:35 +0700    
  
committer: John Naylor <john.naylor@postgresql.org>    
date     : Thu, 2 Jul 2026 13:15:35 +0700    

Click here for diff

Commit 732e6677a added a member to TimeoutType, invalidating the  
comment on EnableTimeoutParams.type. Rather than documenting the list,  
as is done for vars that should only take a subset of enum values,  
just remove the comment.  
  
Author: Xuneng Zhou <xunengzhou@gmail.com>  
Discussion: https://postgr.es/m/CABPTF7XuFqwOcBJ1x0rTKvEvvQ+zfZVidmjTybJPmu9_zTL6Ug@mail.gmail.com  

M src/include/utils/timeout.h

Expand comment on the slot recheck in drop_local_obsolete_slots().

commit   : 6b41bd1a459cb457cbb51d021b70004646d78db0    
  
author   : Amit Kapila <akapila@postgresql.org>    
date     : Thu, 2 Jul 2026 09:34:17 +0530    
  
committer: Amit Kapila <akapila@postgresql.org>    
date     : Thu, 2 Jul 2026 09:34:17 +0530    

Click here for diff

The existing comment explained that a user-created slot could reuse the  
same shared memory as 'local_slot' during the window between selecting a  
slot to drop and locking its database, and that we therefore recheck  
before dropping.  It did not, however, spell out the fuller consequence:  
because local_slot points to a reusable slot-array entry, its fields may  
already describe a replacement slot, so the earlier drop decision and the  
slot_database used for locking could relate to an unrelated slot/database.  
  
Expand the comment to describe this, and note that the recheck prevents  
us from dropping a user-created replacement slot while the residual risk  
(such as briefly locking an unrelated database) is confined to the cycle  
and is acceptable given the race is rare and non-fatal.  
  
No functional change.  
  
Author: Fujii Masao <masao.fujii@gmail.com>  
Author: Xuneng Zhou <xunengzhou@gmail.com>  
Author: Amit Kapila <amit.kapila16@gmail.com>  
Discussion: https://postgr.es/m/CAHGQGwGGyEDL3dh7uJ6qPsGvnq4QK_R8+U=12CaprnzwrwaLGA@mail.gmail.com  
Discussion: https://postgr.es/m/CAHGQGwHqQ1PPVFfYKVxLfRyC-byRdwSN0NeaHj9SLYV97oO5cw@mail.gmail.com  

M src/backend/replication/logical/slotsync.c

Fix jsonpath .decimal() to honor silent mode

commit   : 7b12ae729e6a838c269e133cd740ad39a686ec9f    
  
author   : Michael Paquier <michael@paquier.xyz>    
date     : Thu, 2 Jul 2026 12:44:29 +0900    
  
committer: Michael Paquier <michael@paquier.xyz>    
date     : Thu, 2 Jul 2026 12:44:29 +0900    

Click here for diff

The jsonpath .decimal(precision[, scale]) method built its numeric  
typmod by calling numerictypmodin() through DirectFunctionCall1(), which  
can throw a hard error for an incorrect set of precision and/or scale  
vaulues.  This breaks the silent mode supported by this function, that  
should not fail.  
  
Most of the jsonpath code uses the soft error reporting to bypass  
errors, which is what this fix does by avoiding a direct use of  
numerictypmodin().  Its code is refactored to use a new routine called  
make_numeric_typmod_safe(), able to take an error context in input.  
numerictypmodin() sets no context, mapping to its previous behavior.  
The jsonpath code sets or not a context depending on the use of the  
silent mode.  This result leads to some nice simplifications:  
numerictypmodin() feeds on an array, we can now pass directly values for  
the scale and precision.  
  
Oversight in 66ea94e8e606.  
  
Author: Ewan Young <kdbase.hack@gmail.com>  
Discussion: https://postgr.es/m/CAON2xHMaigKABiyPBBq3Sjd3gp7uWMJXnnMHt=s85V1ij3KP1w@mail.gmail.com  
Backpatch-through: 17  

M src/backend/utils/adt/jsonpath_exec.c
M src/backend/utils/adt/numeric.c
M src/include/utils/numeric.h
M src/test/regress/expected/jsonb_jsonpath.out
M src/test/regress/sql/jsonb_jsonpath.sql

pgindent fix for commit a5918fddf1.

commit   : fdad19e1cfe4564230092e034c0b2185e4a04909    
  
author   : Amit Kapila <akapila@postgresql.org>    
date     : Thu, 2 Jul 2026 08:49:37 +0530    
  
committer: Amit Kapila <akapila@postgresql.org>    
date     : Thu, 2 Jul 2026 08:49:37 +0530    

Click here for diff

M src/backend/replication/logical/conflict.c

Allow logical replication conflicts to be logged to a table.

commit   : a5918fddf10d297c70f7ec9067e9177e0be6d520    
  
author   : Amit Kapila <akapila@postgresql.org>    
date     : Thu, 2 Jul 2026 07:44:27 +0530    
  
committer: Amit Kapila <akapila@postgresql.org>    
date     : Thu, 2 Jul 2026 07:44:27 +0530    

Click here for diff

Until now, logical replication conflicts were only written as plain text  
to the server log, which is hard to query, analyze, or feed into external  
monitoring and automation.  
  
This commit adds a conflict_log_destination option to CREATE SUBSCRIPTION  
and ALTER SUBSCRIPTION that controls where conflicts are recorded. It  
accepts 'log' (the existing behavior), 'table', or 'all'.  
  
When table logging is enabled ('table' or 'all'), an internal log table  
named pg_conflict_log_<subid> is created automatically in a dedicated,  
system-managed pg_conflict namespace. Using a separate namespace avoids  
collisions with user table names and lets the table be shielded from  
direct modification. The table is tied to the subscription through an  
internal dependency, so it is dropped automatically when the subscription  
is removed.  
  
The conflict details, including the local and remote tuples, are stored in  
JSON columns, so a single table layout can accommodate rows from tables  
with different schemas. The table also records the local and remote  
transaction IDs, LSNs, commit timestamps, and the conflict type, providing  
a complete record for post-mortem analysis.  
  
A per-subscription table was chosen over a single global log because it  
aligns table ownership with the subscription lifecycle. This keeps  
permission management simple: the subscription owner can perform the  
permitted maintenance operations without the security concerns or  
Row-Level Security that a shared table would require.  
  
Because the table is system-managed, it is protected from direct  
manipulation: DDL (such as ALTER, DROP, CREATE INDEX, and adding a  
trigger, rule, policy, or extended statistics), use as an inheritance  
parent or a foreign-key target, and manual INSERT, UPDATE, MERGE, or row  
locking are all rejected.  Only DELETE and TRUNCATE are permitted, so that  
users can prune old conflict rows.  
  
Conflict log tables are also excluded from publications, even those  
defined with FOR ALL TABLES or FOR TABLES IN SCHEMA.  
  
This commit only establishes the conflict log table along with its  
creation, cleanup, and protection; recording the conflicts detected  
during apply into the table will be handled in a follow-up commit.  
  
Author: Dilip Kumar <dilipbalaut@gmail.com>  
Author: Nisha Moond <nisha.moond412@gmail.com>  
Author: Amit Kapila <akapila@postgresql.org>  
Reviewed-by: Shveta Malik <shveta.malik@gmail.com>  
Reviewed-by: Vignesh C <vignesh21@gmail.com>  
Reviewed-by: Peter Smith <smithpb2250@gmail.com>  
Reviewed-by: Shlok Kyal <shlok.kyal.oss@gmail.com>  
Reviewed-by: Masahiko Sawada <sawada.mshk@gmail.com>  
Discussion: https://postgr.es/m/CAFiTN-u5D5o_AGNbHRZHaOqAMWkxLf%2BhSk_r9X3gv6HbLOB5%2Bg%40mail.gmail.com  

M doc/src/sgml/ddl.sgml
M doc/src/sgml/glossary.sgml
M doc/src/sgml/logical-replication.sgml
M doc/src/sgml/ref/alter_subscription.sgml
M doc/src/sgml/ref/create_subscription.sgml
M doc/src/sgml/ref/drop_subscription.sgml
M src/backend/catalog/aclchk.c
M src/backend/catalog/catalog.c
M src/backend/catalog/pg_publication.c
M src/backend/catalog/pg_subscription.c
M src/backend/catalog/system_views.sql
M src/backend/commands/lockcmds.c
M src/backend/commands/policy.c
M src/backend/commands/statscmds.c
M src/backend/commands/subscriptioncmds.c
M src/backend/commands/tablecmds.c
M src/backend/commands/trigger.c
M src/backend/executor/execMain.c
M src/backend/replication/logical/conflict.c
M src/backend/rewrite/rewriteDefine.c
M src/bin/initdb/initdb.c
M src/bin/psql/tab-complete.in.c
M src/include/catalog/catalog.h
M src/include/catalog/catversion.h
M src/include/catalog/pg_namespace.dat
M src/include/catalog/pg_subscription.h
M src/include/replication/conflict.h
M src/test/regress/expected/subscription.out
M src/test/regress/sql/subscription.sql
M src/test/subscription/t/035_conflicts.pl
M src/tools/pgindent/typedefs.list

Add system view pg_stat_kind_info

commit   : 3b066de6c0a1dadbd8bed107e55cae659af0598f    
  
author   : Michael Paquier <michael@paquier.xyz>    
date     : Thu, 2 Jul 2026 09:34:21 +0900    
  
committer: Michael Paquier <michael@paquier.xyz>    
date     : Thu, 2 Jul 2026 09:34:21 +0900    

Click here for diff

This commit adds support for pg_stat_kind_info, that exposes at SQL  
level data about the statistics kinds registered into a backend:  
- Meta-data of a stats kind (built-in or custom, some properties).  
- Number of entries, if tracking is enabled.  
  
We have discussed the possibility of more fields (like shared memory  
size for a single entry); this adds the minimum agreed on.  
  
This is in spirit similar to pg_get_loaded_modules() for custom stats  
kinds, this view providing detailed information about the stats kinds  
when registered through shared_preload_libraries.  
  
Bump catalog version.  
  
Author: Tristan Partin <tristan@partin.io>  
Reviewed-by: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>  
Reviewed-by: Sami Imseih <samimseih@gmail.com>  
Reviewed-by: Michael Paquier <michael@paquier.xyz>  
Discussion: https://postgr.es/m/DI6OFGHJ1B69.25YVDEP3BABRH@partin.io  

M doc/src/sgml/monitoring.sgml
M src/backend/catalog/system_views.sql
M src/backend/utils/activity/Makefile
M src/backend/utils/activity/meson.build
A src/backend/utils/activity/pgstat_kind.c
M src/include/catalog/catversion.h
M src/include/catalog/pg_proc.dat
M src/test/modules/test_custom_stats/t/001_custom_stats.pl
M src/test/regress/expected/rules.out
M src/test/regress/expected/stats.out
M src/test/regress/sql/stats.sql

Add min() and max() aggregate support for uuid.

commit   : 2e606d75c0bf9c867b51ad228eae384a9d1de21a    
  
author   : Masahiko Sawada <msawada@postgresql.org>    
date     : Wed, 1 Jul 2026 11:42:54 -0700    
  
committer: Masahiko Sawada <msawada@postgresql.org>    
date     : Wed, 1 Jul 2026 11:42:54 -0700    

Click here for diff

The uuid type already has a full set of comparison operators and a  
btree operator class, so it is totally ordered.  min() and max() were  
the only common aggregates missing for it. Add the uuid_larger() and  
uuid_smaller() support functions and register the min(uuid) and  
max(uuid) aggregates that use them.  
  
uuid values are compared lexicographically over their 128 bits.  For  
UUIDv7, whose most significant bits encode a Unix timestamp, this  
coincides with chronological order, so min() and max() return the  
oldest and newest values.  
  
Bump catalog version.  
  
Author: Tristan Partin <tristan@partin.io>  
Reviewed-by: Bharath Rupireddy <bharath.rupireddyforpostgres@gmail.com>  
Reviewed-by: Zsolt Parragi <zsolt.parragi@percona.com>  
Reviewed-by: Masahiko Sawada <sawada.mshk@gmail.com>  
Discussion: https://postgr.es/m/DJGML0T9FCDV.3VA29JLODXEHZ@partin.io  

M doc/src/sgml/datatype.sgml
M doc/src/sgml/func/func-aggregate.sgml
M src/backend/utils/adt/uuid.c
M src/include/catalog/catversion.h
M src/include/catalog/pg_aggregate.dat
M src/include/catalog/pg_proc.dat
M src/test/regress/expected/opr_sanity.out
M src/test/regress/expected/uuid.out
M src/test/regress/sql/uuid.sql

Fix macro-redefinition warning introduced by aeb07c55f.

commit   : 85656c1bef4af031f8e9801d927cdaeaaae95566    
  
author   : Tom Lane <tgl@sss.pgh.pa.us>    
date     : Wed, 1 Jul 2026 13:44:45 -0400    
  
committer: Tom Lane <tgl@sss.pgh.pa.us>    
date     : Wed, 1 Jul 2026 13:44:45 -0400    

Click here for diff

Some platforms provide a definition of unreachable() in standard C  
headers, leading to a conflict with unreachable() in the new  
timezone code.  It seems best for our purposes to conform to what  
pg_unreachable() does, so #undef away the platform version.  
  
Reported-by: Tristan Partin <tristan@partin.io>  
Discussion: https://postgr.es/m/DJNDN9UQS9GP.11L4NJ1HHE1ZJ@partin.io  

M src/timezone/private.h

btree_gist: fix NaN handling in float4/float8 opclasses.

commit   : 7d3448961da3f8cb5c78b9d58c5e03b6bff53364    
  
author   : Tom Lane <tgl@sss.pgh.pa.us>    
date     : Wed, 1 Jul 2026 13:27:22 -0400    
  
committer: Tom Lane <tgl@sss.pgh.pa.us>    
date     : Wed, 1 Jul 2026 13:27:22 -0400    

Click here for diff

The float4 and float8 btree_gist opclasses compared keys with raw C  
operators (==, <, >).  IEEE 754 makes every comparison involving NaN  
false, so GiST disagreed with the regular float comparison operators  
and with the btree opclass, which uses float[4|8]_cmp_internal()  
(so that all NaNs are equal and NaN sorts after every non-NaN value).  
  
In addition, the penalty and distance functions were not careful  
about NaNs, and the penalty functions could also misbehave for IEEE  
infinities.  Wrong answers from the penalty functions would probably  
do no more than make the index non-optimal, but the distance mistakes  
were visible from SQL.  
  
To fix, make the comparison functions rely on the same NaN-aware  
comparison functions the core code uses, and rewrite the penalty  
and distance functions to follow the rules that NaNs are equal  
but maximally far away from non-NaNs.  The penalty_num() code was  
formerly shared between integral and float cases, but I chose to make  
two copies so that the integral cases are not saddled with the extra  
logic for NaNs and infinities/overflows.  I also rewrote it as static  
inline functions instead of an unreadable and uncommented macro.  
  
The float penalty functions were previously unreached by the  
regression tests, so add new test cases to exercise them.  
  
There's no on-disk format change, but users who have NaN entries  
in a btree_gist index would be well advised to reindex it.  
  
Bug: #19501  
Bug: #19524  
Reported-by: Man Zeng <zengman@halodbtech.com>  
Reported-by: Yuelin Wang <3020001251@tju.edu.cn>  
Author: Bill Kim <billkimjh@gmail.com>  
Co-authored-by: Tom Lane <tgl@sss.pgh.pa.us>  
Discussion: https://postgr.es/m/19501-3bff3bbc97f1e7c9@postgresql.org  
Discussion: https://postgr.es/m/19524-9559d302c8455664@postgresql.org  
Discussion: https://postgr.es/m/CAMQXxcgbtD2LXfX0tpgvOizxP-XxrCHV2ZDy4By_TZnJMsxXWQ@mail.gmail.com  
Backpatch-through: 14  

M contrib/btree_gist/btree_float4.c
M contrib/btree_gist/btree_float8.c
M contrib/btree_gist/btree_utils_num.h
M contrib/btree_gist/data/float4.data
M contrib/btree_gist/data/float8.data
M contrib/btree_gist/expected/float4.out
M contrib/btree_gist/expected/float8.out
M contrib/btree_gist/expected/numeric.out
M contrib/btree_gist/sql/float4.sql
M contrib/btree_gist/sql/float8.sql

doc: Fix pg_stat_autovacuum_scores descriptions.

commit   : 6440265606241277d9d99241116b14d7cc2783ca    
  
author   : Nathan Bossart <nathan@postgresql.org>    
date     : Wed, 1 Jul 2026 10:47:53 -0500    
  
committer: Nathan Bossart <nathan@postgresql.org>    
date     : Wed, 1 Jul 2026 10:47:53 -0500    

Click here for diff

The descriptions of the component scores state that values greater  
than or equal to the corresponding weight parameter mean autovacuum  
will process the table.  However, since the code that determines  
whether to vacuum or analyze a table actually checks whether the  
threshold is exceeded, it's more accurate to say "greater than"  
there.  
  
Author: Chao Li <li.evan.chao@gmail.com>  
Reviewed-by: Sami Imseih <samimseih@gmail.com>  
Discussion: https://postgr.es/m/E3ABDC6B-80CA-4C37-BA0B-A519D49F4C66%40gmail.com  
Backpatch-through: 19  

M doc/src/sgml/monitoring.sgml

Improve the names generated for indexes on expressions.

commit   : 181b6185c79e09e6ac94428189d9afac807244ac    
  
author   : Tom Lane <tgl@sss.pgh.pa.us>    
date     : Wed, 1 Jul 2026 11:33:52 -0400    
  
committer: Tom Lane <tgl@sss.pgh.pa.us>    
date     : Wed, 1 Jul 2026 11:33:52 -0400    

Click here for diff

If the user doesn't specify a name for an index, it's generated  
based on the names chosen for the index columns (which the user  
has no direct control over).  For index columns that are just  
columns of the base relation, the index column name is the same as  
the base column name; but for index columns that are expressions,  
it's less clear what to do.  Up to now, what we have done is  
equivalent to the heuristics used to choose SELECT output column  
names, except that we fall back to "expr" not "?column?" in the  
numerous cases that FigureColname doesn't know what to do with.  
This is not tremendously helpful.  More, it frequently leads to  
collisions of generated index names, which we can handle but  
only at the cost of user confusion; also there's some risk of  
concurrent index creations trying to use the same name.  
Let's try to do better.  
  
Messing with the FigureColname heuristics would have a very  
large blast radius, since that affects the column headings  
that applications see.  That doesn't seem wise, but fortunately  
SQL queries are seldom directly concerned with index names.  
So we should be able to change the index-name generation rules  
as long as we decouple them from FigureColname.  
  
The method used in this patch is to dig through the expression,  
extract the names of Vars, the string representations of Consts,  
and the names of functions, and run those together with underscores  
between.  Other expression node types are ignored but descended  
through.  We could work harder by handling more node types, but  
it seems like this is likely to be sufficient to arrive at unique  
index names in many cases.  
  
Notably, this rule ignores the names of operators, for example  
both "a + b" and "a * b" will be rendered as "a_b".  This choice  
was made to reduce the probability of having to double-quote  
the index name.  
  
I've also chosen to strip Const representations down to only  
alphanumeric characters (plus non-ASCII characters, which our  
parser treats as alphabetic anyway).  So for example "x + 1.0"  
would be represented as "x_10".  This likewise avoids possible  
quoting problems.  I also considered limiting how many characters  
we'd take from each Const, but didn't do that here.  
  
We might tweak these rules some more after we get some experience  
with this patch.  It's being committed at the start of a  
development cycle to provide as much time as possible to gather  
feedback.  
  
Author: Tom Lane <tgl@sss.pgh.pa.us>  
Reviewed-by: Robert Haas <robertmhaas@gmail.com>  
Discussion: https://postgr.es/m/876799.1757987810@sss.pgh.pa.us  
Discussion: https://postgr.es/m/18959-f63b53b864bb1417@postgresql.org  

M contrib/seg/expected/partition.out
M src/backend/commands/indexcmds.c
M src/backend/parser/parse_target.c
M src/backend/parser/parse_utilcmd.c
M src/include/nodes/parsenodes.h
M src/include/parser/parse_target.h
M src/test/regress/expected/alter_table.out
M src/test/regress/expected/create_index.out
M src/test/regress/expected/create_table.out
M src/test/regress/expected/create_table_like.out
M src/test/regress/expected/indexing.out
M src/test/regress/expected/inherit.out
M src/test/regress/expected/rangetypes.out
M src/test/regress/expected/stats_import.out
M src/test/regress/sql/create_index.sql
M src/test/regress/sql/indexing.sql
M src/tools/pgindent/typedefs.list

Sync our copy of the timezone library with IANA release tzcode2026b.

commit   : aeb07c55fab5c17a600b77ffcdc3b71425d6a8e7    
  
author   : Tom Lane <tgl@sss.pgh.pa.us>    
date     : Wed, 1 Jul 2026 10:56:46 -0400    
  
committer: Tom Lane <tgl@sss.pgh.pa.us>    
date     : Wed, 1 Jul 2026 10:56:46 -0400    

Click here for diff

This was moderately tedious, because upstream has been busy  
since we last did this in 2020.  
  
Notably, they changed the signatures of both tzload() and tzparse(),  
which we'd unwisely exposed as API for callers to use.  I concluded  
that the best answer was to change them both back to "static" and  
instead expose a new API function of our own choosing, pg_tzload().  
  
That change may be a sufficient reason not to back-patch this update,  
as I'd normally want to do.  There's probably not a good reason for  
extensions to be calling those functions, but on the other hand  
there are few pressing reasons for a back-patch.  The one bug we have  
run into (a Valgrind uninitialized-data complaint about zic) appears  
to have no field-visible consequences.  
  
A few of the files generated by this version of zic are not  
byte-for-byte the same as before, but "zdump -v" avers that  
they represent the same sets of transitions.  
  
Discussion: https://postgr.es/m/2294297.1780270682@sss.pgh.pa.us  

M src/bin/initdb/findtimezone.c
M src/timezone/README
M src/timezone/localtime.c
M src/timezone/pgtz.c
M src/timezone/pgtz.h
M src/timezone/private.h
M src/timezone/strftime.c
M src/timezone/tzfile.h
M src/timezone/zic.c
M src/tools/pgindent/typedefs.list

Fix CPU-identification macros for RISC-V.

commit   : d3223485546e8579a1703731ef4e39a08a712860    
  
author   : Tom Lane <tgl@sss.pgh.pa.us>    
date     : Wed, 1 Jul 2026 10:10:21 -0400    
  
committer: Tom Lane <tgl@sss.pgh.pa.us>    
date     : Wed, 1 Jul 2026 10:10:21 -0400    

Click here for diff

Turns out that RISC-V intentionally doesn't follow the common  
naming pattern for CPU-identification macros.  But the point of  
2ef57e636 is to have a common pattern, so we're going to override  
their opinion.  
  
Discussion: https://postgr.es/m/CA+hUKGL8Hs-phHPugrWM=5dAkcT897rXyazYzLw-Szxnzgx-rA@mail.gmail.com  

M src/include/c.h

Clear base backup progress on backup failure

commit   : 55f0a13e96be6c1b81425a3353c08df8b8ec3a6c    
  
author   : Fujii Masao <fujii@postgresql.org>    
date     : Wed, 1 Jul 2026 23:03:08 +0900    
  
committer: Fujii Masao <fujii@postgresql.org>    
date     : Wed, 1 Jul 2026 23:03:08 +0900    

Click here for diff

Previously, if a base backup failed after it had started streaming  
files, pg_stat_progress_basebackup could continue to show a stale  
progress entry even though the backup was no longer running. This could  
be observed when the client kept the replication connection open after  
the error. It is normally not observable when using pg_basebackup,  
because the client disconnects after the error.  
  
The problem was that progress reporting was cleared only after  
successful completion.  
  
This commit moves the progress reporting cleanup into the progress  
sink's cleanup callback so that it is cleared after both successful  
and failed backups.  
  
Backpatch to v15. v14 has the same issue, but the fix does not apply  
cleanly because it lacks the base backup sink infrastructure. Since  
the bug does not affect the backup itself and is normally not  
observable when using pg_basebackup, skip the v14 backpatch.  
  
Author: Chao Li <lic@highgo.com>  
Reviewed-by: Fujii Masao <masao.fujii@gmail.com>  
Discussion: https://postgr.es/m/EA1A6CD2-EFA6-462B-9A02-03003555AB4A@gmail.com  
Backpatch-through: 15  

M src/backend/backup/basebackup.c
M src/backend/backup/basebackup_progress.c
M src/include/backup/basebackup_sink.h

Warn on password auth with MD5-encrypted passwords

commit   : f6fdc2a4a737b62323b786aea59ab7a38cd7f835    
  
author   : Fujii Masao <fujii@postgresql.org>    
date     : Wed, 1 Jul 2026 20:57:28 +0900    
  
committer: Fujii Masao <fujii@postgresql.org>    
date     : Wed, 1 Jul 2026 20:57:28 +0900    

Click here for diff

Commit bc60ee860 added a connection warning after successful MD5  
authentication, but only for the md5 authentication method. A role with  
an MD5-encrypted password can also authenticate via the password method,  
which left that path without the same deprecation warning.  
  
Emit the MD5 deprecation connection warning after successful  
password authentication as well, when the stored password is  
MD5-encrypted.  
  
Backpatch to v19, where the MD5 connection warning was introduced.  
  
Author: Fujii Masao <masao.fujii@gmail.com>  
Reviewed-by: Chao Li <li.evan.chao@gmail.com>  
Reviewed-by: Japin Li <japinli@hotmail.com>  
Discussion: https://postgr.es/m/CAHGQGwGkWfn5rtHzvdRbVk+PCefQU3gun3hc7QnaMXHFa5Bu3w@mail.gmail.com  
Backpatch-through: 19  

M doc/src/sgml/config.sgml
M src/backend/libpq/auth.c
M src/backend/libpq/crypt.c
M src/test/authentication/t/001_password.pl

Fix mismatched deallocation functions

commit   : 30652b356d20c1d3772137370a6a8d29575e04d1    
  
author   : Peter Eisentraut <peter@eisentraut.org>    
date     : Wed, 1 Jul 2026 13:48:45 +0200    
  
committer: Peter Eisentraut <peter@eisentraut.org>    
date     : Wed, 1 Jul 2026 13:48:45 +0200    

Click here for diff

In fe_memutils.h, we have various allocation functions beginning with  
either pg_ or p.  The pg_ functions have a matching pg_free() for  
freeing memory, while the p functions use pfree().  In some cases, we  
were allocating memory with one set of functions while using the wrong  
deallocation functions.  This creates a tiny bit of mental overhead  
when reading code.  Matching up allocation and deallocation functions  
makes it easier to analyze memory handling in a code path.  
  
Author: Tristan Partin <tristan@partin.io>  
Reviewed-by: Zsolt Parragi <zsolt.parragi@percona.com>  
Discussion: https://www.postgresql.org/message-id/flat/DIBZE2B6SVF2.28R3EQTYJSWIG@partin.io  

M contrib/oid2name/oid2name.c
M src/bin/initdb/initdb.c
M src/bin/pg_basebackup/pg_basebackup.c
M src/bin/pg_basebackup/pg_createsubscriber.c
M src/bin/pg_basebackup/streamutil.c
M src/bin/pg_combinebackup/load_manifest.c
M src/bin/pg_combinebackup/pg_combinebackup.c
M src/bin/pg_combinebackup/reconstruct.c
M src/bin/pg_ctl/pg_ctl.c
M src/bin/pg_dump/compress_gzip.c
M src/bin/pg_dump/compress_lz4.c
M src/bin/pg_dump/compress_none.c
M src/bin/pg_dump/connectdb.c
M src/bin/pg_dump/dumputils.c
M src/bin/pg_dump/parallel.c
M src/bin/pg_dump/pg_backup_archiver.c
M src/bin/pg_dump/pg_backup_custom.c
M src/bin/pg_dump/pg_backup_db.c
M src/bin/pg_dump/pg_backup_directory.c
M src/bin/pg_dump/pg_backup_tar.c
M src/bin/pg_dump/pg_dump.c
M src/bin/pg_dump/pg_dump_sort.c
M src/bin/pg_dump/pg_dumpall.c
M src/bin/pg_upgrade/check.c
M src/bin/pg_upgrade/function.c
M src/bin/pg_verifybackup/pg_verifybackup.c
M src/bin/pgbench/pgbench.c
M src/bin/psql/command.c
M src/bin/psql/common.c
M src/bin/psql/describe.c
M src/bin/psql/help.c
M src/bin/psql/input.c
M src/bin/psql/large_obj.c
M src/bin/psql/mainloop.c
M src/bin/psql/prompt.c
M src/bin/psql/startup.c
M src/bin/psql/stringutils.c
M src/bin/psql/tab-complete.in.c
M src/bin/scripts/vacuuming.c
M src/common/logging.c
M src/fe_utils/print.c
M src/interfaces/ecpg/test/pg_regress_ecpg.c
M src/test/isolation/isolation_main.c
M src/test/isolation/isolationtester.c
M src/test/modules/libpq_pipeline/libpq_pipeline.c
M src/test/regress/pg_regress.c
M src/test/regress/pg_regress_main.c

Split dry-run messages into primary and detail

commit   : e3b5817c8b89790f7f4bf96a1fef98aed88d2fdb    
  
author   : Peter Eisentraut <peter@eisentraut.org>    
date     : Wed, 1 Jul 2026 10:12:33 +0200    
  
committer: Peter Eisentraut <peter@eisentraut.org>    
date     : Wed, 1 Jul 2026 10:12:33 +0200    

Click here for diff

Fixup for commit c05dee19112.  It fits better with the style and APIs  
to print separate primary and a detail messages instead of one  
multiline message.  
  
Reviewed-by: Euler Taveira <euler@eulerto.com>  
Reviewed-by: Peter Smith <smithpb2250@gmail.com>  
Reviewed-by: Álvaro Herrera <alvherre@kurilemu.de>  
Discussion: https://postgr.es/m/CAHut+PsvQJQnQO0KT0S2oegenkvJ8FUuY-QS5syyqmT24R2xFQ@mail.gmail.com  

M src/bin/pg_archivecleanup/pg_archivecleanup.c
M src/bin/pg_basebackup/pg_createsubscriber.c
M src/bin/pg_combinebackup/pg_combinebackup.c
M src/bin/pg_rewind/pg_rewind.c
M src/bin/scripts/vacuumdb.c

Don't cast off_t to 32-bit type for output, bug fix

commit   : e8f851d61727babe2ce162292b21e6afc89ca65f    
  
author   : Peter Eisentraut <peter@eisentraut.org>    
date     : Wed, 1 Jul 2026 09:39:42 +0200    
  
committer: Peter Eisentraut <peter@eisentraut.org>    
date     : Wed, 1 Jul 2026 09:39:42 +0200    

Click here for diff

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  

M src/backend/backup/basebackup_server.c

Use C11 alignas instead of pg_attribute_aligned

commit   : 8061bfd15abe4d6943ac1563617c19fc069aad70    
  
author   : Peter Eisentraut <peter@eisentraut.org>    
date     : Mon, 29 Jun 2026 10:46:51 +0200    
  
committer: Peter Eisentraut <peter@eisentraut.org>    
date     : Mon, 29 Jun 2026 10:46:51 +0200    

Click here for diff

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  

M src/port/pg_crc32c_armv8.c

Improve UNION's output row count estimate

commit   : be69a5ff1fd96cdbfe917ac4739142e52aab126e    
  
author   : Richard Guo <rguo@postgresql.org>    
date     : Wed, 1 Jul 2026 15:12:43 +0900    
  
committer: Richard Guo <rguo@postgresql.org>    
date     : Wed, 1 Jul 2026 15:12:43 +0900    

Click here for diff

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  

M src/backend/optimizer/prep/prepunion.c
M src/test/regress/expected/union.out
M src/test/regress/sql/union.sql

Avoid useless calls in pg_get_multixact_stats()

commit   : b542d556670586ebadf380102f6ead920609e592    
  
author   : Michael Paquier <michael@paquier.xyz>    
date     : Wed, 1 Jul 2026 12:17:17 +0900    
  
committer: Michael Paquier <michael@paquier.xyz>    
date     : Wed, 1 Jul 2026 12:17:17 +0900    

Click here for diff

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  

M src/backend/utils/adt/multixactfuncs.c

Document wal_compression=on

commit   : 8db58ac8eec7402af1a746621fb2910f1673db0a    
  
author   : John Naylor <john.naylor@postgresql.org>    
date     : Wed, 1 Jul 2026 08:50:08 +0700    
  
committer: John Naylor <john.naylor@postgresql.org>    
date     : Wed, 1 Jul 2026 08:50:08 +0700    

Click here for diff

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  

M doc/src/sgml/config.sgml
M src/backend/utils/misc/postgresql.conf.sample

doc: Add new section describing fast-path locking

commit   : 2d31da527169fb54916d7435629c04a7b7bbda1d    
  
author   : Michael Paquier <michael@paquier.xyz>    
date     : Wed, 1 Jul 2026 10:08:26 +0900    
  
committer: Michael Paquier <michael@paquier.xyz>    
date     : Wed, 1 Jul 2026 10:08:26 +0900    

Click here for diff

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  

M doc/src/sgml/config.sgml
M doc/src/sgml/monitoring.sgml
M doc/src/sgml/mvcc.sgml
M doc/src/sgml/system-views.sgml

Remove radius from initdb authentication methods.

commit   : a78f7390bf19868cc313482b307d5148ad00aae2    
  
author   : Thomas Munro <tmunro@postgresql.org>    
date     : Wed, 1 Jul 2026 11:25:37 +1200    
  
committer: Thomas Munro <tmunro@postgresql.org>    
date     : Wed, 1 Jul 2026 11:25:37 +1200    

Click here for diff

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  

M src/bin/initdb/initdb.c

Disallow set-returning functions within window OVER clauses.

commit   : 1de468099d27f44c1998c9c2251cd2aefcfab524    
  
author   : Tom Lane <tgl@sss.pgh.pa.us>    
date     : Tue, 30 Jun 2026 17:21:23 -0400    
  
committer: Tom Lane <tgl@sss.pgh.pa.us>    
date     : Tue, 30 Jun 2026 17:21:23 -0400    

Click here for diff

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  

M src/backend/parser/parse_func.c
M src/test/regress/expected/tsrf.out
M src/test/regress/sql/tsrf.sql

doc: clarify MERGE PARTITIONS adjacency requirement

commit   : 57f19774d6c88f501c835a7772a71ca5ba2bc163    
  
author   : Alexander Korotkov <akorotkov@postgresql.org>    
date     : Tue, 30 Jun 2026 22:29:43 +0300    
  
committer: Alexander Korotkov <akorotkov@postgresql.org>    
date     : Tue, 30 Jun 2026 22:29:43 +0300    

Click here for diff

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  

M doc/src/sgml/ref/alter_table.sgml

Clean up inconsistencies in CPU-identification macros.

commit   : 2ef57e636fc97528a37515673f5f56a1fcf97186    
  
author   : Tom Lane <tgl@sss.pgh.pa.us>    
date     : Tue, 30 Jun 2026 12:21:06 -0400    
  
committer: Tom Lane <tgl@sss.pgh.pa.us>    
date     : Tue, 30 Jun 2026 12:21:06 -0400    

Click here for diff

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  

M src/common/d2s.c
M src/include/c.h
M src/include/port/atomics.h
M src/include/port/atomics/arch-x86.h
M src/include/port/pg_bitutils.h
M src/include/port/pg_cpu.h
M src/include/portability/instr_time.h
M src/include/storage/s_lock.h
M src/port/pg_cpu_x86.c

Remove pg_spin_delay().

commit   : ae27a41e0c7f1d1c451aff230cac32fc7cdb1fee    
  
author   : Nathan Bossart <nathan@postgresql.org>    
date     : Tue, 30 Jun 2026 10:57:54 -0500    
  
committer: Nathan Bossart <nathan@postgresql.org>    
date     : Tue, 30 Jun 2026 10:57:54 -0500    

Click here for diff

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  

M src/include/port/atomics.h
M src/include/port/atomics/arch-x86.h
M src/include/port/atomics/generic.h

Make SPI_prepare argtypes argument const

commit   : b1c41398e48ca7d38a46c901dc93872c968b227c    
  
author   : Peter Eisentraut <peter@eisentraut.org>    
date     : Tue, 30 Jun 2026 15:43:56 +0200    
  
committer: Peter Eisentraut <peter@eisentraut.org>    
date     : Tue, 30 Jun 2026 15:43:56 +0200    

Click here for diff

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  

M contrib/postgres_fdw/postgres_fdw.c
M doc/src/sgml/spi.sgml
M src/backend/executor/spi.c
M src/backend/utils/adt/ri_triggers.c
M src/backend/utils/cache/plancache.c
M src/include/executor/spi.h
M src/include/executor/spi_priv.h
M src/include/utils/plancache.h

Fixes for SPI "const Datum *" use

commit   : cd3ad3bc03567ee120a638c840112b8865e055a8    
  
author   : Peter Eisentraut <peter@eisentraut.org>    
date     : Tue, 30 Jun 2026 14:03:10 +0200    
  
committer: Peter Eisentraut <peter@eisentraut.org>    
date     : Tue, 30 Jun 2026 14:03:10 +0200    

Click here for diff

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  

M doc/src/sgml/spi.sgml
M src/backend/executor/spi.c
M src/include/executor/spi.h

Add backend-level lock statistics

commit   : 8c579bdc366dbca4fe9432a01408216133628c52    
  
author   : Michael Paquier <michael@paquier.xyz>    
date     : Tue, 30 Jun 2026 16:59:20 +0900    
  
committer: Michael Paquier <michael@paquier.xyz>    
date     : Tue, 30 Jun 2026 16:59:20 +0900    

Click here for diff

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  

M doc/src/sgml/monitoring.sgml
M src/backend/utils/activity/pgstat_backend.c
M src/backend/utils/activity/pgstat_lock.c
M src/backend/utils/adt/pgstatfuncs.c
M src/include/catalog/catversion.h
M src/include/catalog/pg_proc.dat
M src/include/pgstat.h
M src/include/utils/pgstat_internal.h
M src/test/regress/expected/stats.out
M src/test/regress/sql/stats.sql

Refactor pg_stat_get_lock() to use a helper function

commit   : dfe7d17e00665875639e905fa385231dacc57c4e    
  
author   : Michael Paquier <michael@paquier.xyz>    
date     : Tue, 30 Jun 2026 16:24:34 +0900    
  
committer: Michael Paquier <michael@paquier.xyz>    
date     : Tue, 30 Jun 2026 16:24:34 +0900    

Click here for diff

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  

M src/backend/utils/adt/pgstatfuncs.c

Use placeholders and not GUC names in error message (autovacuum)

commit   : 7905416eef9b2ad2ff8783330d830ef2c28bef2a    
  
author   : Michael Paquier <michael@paquier.xyz>    
date     : Tue, 30 Jun 2026 16:16:56 +0900    
  
committer: Michael Paquier <michael@paquier.xyz>    
date     : Tue, 30 Jun 2026 16:16:56 +0900    

Click here for diff

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  

M src/backend/postmaster/autovacuum.c

Change stat_lock.wait_time to double precision

commit   : c776550e4662385b0ebeac653ae86755008d29f3    
  
author   : Michael Paquier <michael@paquier.xyz>    
date     : Tue, 30 Jun 2026 12:47:34 +0900    
  
committer: Michael Paquier <michael@paquier.xyz>    
date     : Tue, 30 Jun 2026 12:47:34 +0900    

Click here for diff

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  

M doc/src/sgml/monitoring.sgml
M src/backend/storage/lmgr/proc.c
M src/backend/utils/activity/pgstat_lock.c
M src/backend/utils/adt/pgstatfuncs.c
M src/include/catalog/catversion.h
M src/include/catalog/pg_proc.dat
M src/include/pgstat.h

Restore comment at appendShellString().

commit   : cfa573cf8cbdcbf7cbcae34911bd1ee292abdd2f    
  
author   : Noah Misch <noah@leadboat.com>    
date     : Mon, 29 Jun 2026 19:41:09 -0700    
  
committer: Noah Misch <noah@leadboat.com>    
date     : Mon, 29 Jun 2026 19:41:09 -0700    

Click here for diff

Commit b380a56a3f9556588a89013b765d67947d54f7d0 removed a paragraph, but  
two of the paragraph's three sentences remained relevant.  
  
Backpatch-through: 19  

M src/fe_utils/string_utils.c

bufmgr: Fix race in LockBufferForCleanup()

commit   : 8d85cb889a395f08d58e59c31a67f199f0fc25c3    
  
author   : Fujii Masao <fujii@postgresql.org>    
date     : Tue, 30 Jun 2026 10:30:47 +0900    
  
committer: Fujii Masao <fujii@postgresql.org>    
date     : Tue, 30 Jun 2026 10:30:47 +0900    

Click here for diff

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  

M src/backend/storage/buffer/bufmgr.c

Remove stray blank line in ParseFuncOrColumn()

commit   : d8113095c488ad588a0890833f67d01df46374e7    
  
author   : Fujii Masao <fujii@postgresql.org>    
date     : Tue, 30 Jun 2026 10:28:52 +0900    
  
committer: Fujii Masao <fujii@postgresql.org>    
date     : Tue, 30 Jun 2026 10:28:52 +0900    

Click here for diff

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  

M src/backend/parser/parse_func.c

Fix unlogged sequence corruption after standby promotion

commit   : 8e684ce11ddaac2604375b8efcae97f6b36af4e7    
  
author   : Fujii Masao <fujii@postgresql.org>    
date     : Tue, 30 Jun 2026 08:48:47 +0900    
  
committer: Fujii Masao <fujii@postgresql.org>    
date     : Tue, 30 Jun 2026 08:48:47 +0900    

Click here for diff

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  

M src/backend/access/hash/hash_xlog.c
M src/backend/access/transam/xlogutils.c
M src/backend/commands/sequence_xlog.c
M src/include/access/xlogutils.h
M src/test/recovery/meson.build
A src/test/recovery/t/054_unlogged_sequence_promotion.pl

Simplify some stats restore code with InputFunctionCallSafe()

commit   : efa59a500457f310abbc38dc472f03e959ccd5b8    
  
author   : Michael Paquier <michael@paquier.xyz>    
date     : Tue, 30 Jun 2026 08:30:08 +0900    
  
committer: Michael Paquier <michael@paquier.xyz>    
date     : Tue, 30 Jun 2026 08:30:08 +0900    

Click here for diff

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  

M src/backend/statistics/extended_stats_funcs.c
M src/backend/statistics/stat_utils.c

Stamp HEAD as 20devel.

commit   : a281a3e6dbb45d5cca41ea5f7b746724eb3ca70d    
  
author   : Joe Conway <mail@joeconway.com>    
date     : Mon, 29 Jun 2026 16:29:11 -0400    
  
committer: Joe Conway <mail@joeconway.com>    
date     : Mon, 29 Jun 2026 16:29:11 -0400    

Click here for diff

Let the hacking begin ...  

M configure
M configure.ac
M doc/src/sgml/filelist.sgml
D doc/src/sgml/release-19.sgml
A doc/src/sgml/release-20.sgml
M doc/src/sgml/release.sgml
M meson.build
M src/tools/git_changelog
M src/tools/version_stamp.pl