Commit graph

28764 commits

Author SHA1 Message Date
Tom Lane
2d7808e6fc Fix LIKE/regex optimization for indexscan with exact-match pattern.
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
2026-07-06 13:06:24 -04:00
Robert Haas
e8914ec22f Prevent satisfies_hash_partition from crashing with VARIADIC NULL.
Commit f3b0897a12 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>
2026-07-06 12:51:29 -04:00
Peter Eisentraut
e994f956e4 Forbid generated columns in FOR PORTION OF
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
2026-07-06 09:32:09 +02:00
Richard Guo
44fb59fc60 Fix qual pushdown past grouping with mismatched equivalence
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
2026-07-06 16:13:14 +09:00
Michael Paquier
9d1188f298 Emit a warning when io_min_workers exceeds io_max_workers
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 7905416eef.

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
2026-07-06 11:37:36 +09:00
Michael Paquier
a924407ce0 Improve checks and error messages of pgstat_register_kind()
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
2026-07-06 10:49:28 +09:00
Peter Eisentraut
0e4f0827f6 Fix properties orphaned by dropping a label
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
2026-07-05 13:51:32 +02:00
Tom Lane
a8c2547eaa Disallow renaming a rule to "_RETURN".
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
2026-07-04 11:34:26 -04:00
Peter Eisentraut
e0ff7fd9aa Make property graph object descriptions better translatable
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
2026-07-03 23:46:19 +02:00
Álvaro Herrera
5ee9d7c299
REPACK CONCURRENTLY: Initialize the range table more honestly
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
2026-07-03 20:04:48 +02:00
Peter Eisentraut
efd7d8d7d4 Resolve unknown-type literals in GRAPH_TABLE COLUMNS
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
2026-07-03 17:10:42 +02:00
Alexander Korotkov
c40819ebf9 Prevent access to other sessions' empty temp tables
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 31966b151e, 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
2026-07-03 18:02:14 +03:00
Peter Eisentraut
96418a6da9 Fix handling of dropping a property not associated with the given label
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
2026-07-03 16:29:42 +02:00
Álvaro Herrera
3be823486f
Fix REPACK CONCURRENTLY for stored generated columns
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
2026-07-03 12:22:37 +02:00
Peter Eisentraut
7afa11feca Prevent dropping the last label from a property graph element
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
2026-07-03 12:10:31 +02:00
Michael Paquier
71fa15af59 Fix typo in pg_stat_us_to_ms()
The function converts microseconds to milliseconds, but the parameter
name used "ms".

Thinko in ac8d53dae5.

Author: Tatsuya Kawata <kawatatatsuya0913@gmail.com>
Discussion: https://postgr.es/m/CAHza6qfek15rehnA0GXMCpF2z=Gy6C+3vmcWCMVkU4JiRD8k7g@mail.gmail.com
2026-07-03 12:22:14 +09:00
Fujii Masao
084734ff5a Remove replication slot advice from MultiXact wraparound hints
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
2026-07-03 11:16:34 +09:00
Fujii Masao
c8bd8387c2 Add log_statement_max_length GUC to limit logged statement text
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
2026-07-03 08:47:18 +09:00
John Naylor
51cd5d6f05 Use ssup_datum_*_cmp in more places
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
2026-07-02 15:55:11 +07:00
John Naylor
3eca140531 Fix loss of precision in pg_stat_us_to_ms()
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
2026-07-02 13:26:56 +07:00
Amit Kapila
6b41bd1a45 Expand comment on the slot recheck in drop_local_obsolete_slots().
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
2026-07-02 09:34:17 +05:30
Michael Paquier
7b12ae729e Fix jsonpath .decimal() to honor silent mode
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 66ea94e8e6.

Author: Ewan Young <kdbase.hack@gmail.com>
Discussion: https://postgr.es/m/CAON2xHMaigKABiyPBBq3Sjd3gp7uWMJXnnMHt=s85V1ij3KP1w@mail.gmail.com
Backpatch-through: 17
2026-07-02 12:44:29 +09:00
Amit Kapila
fdad19e1cf pgindent fix for commit a5918fddf1. 2026-07-02 08:49:37 +05:30
Amit Kapila
a5918fddf1 Allow logical replication conflicts to be logged to a table.
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
2026-07-02 08:26:07 +05:30
Michael Paquier
3b066de6c0 Add system view pg_stat_kind_info
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
2026-07-02 09:34:21 +09:00
Masahiko Sawada
2e606d75c0 Add min() and max() aggregate support for uuid.
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
2026-07-01 11:42:54 -07:00
Tom Lane
181b6185c7 Improve the names generated for indexes on expressions.
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
2026-07-01 11:33:52 -04:00
Fujii Masao
55f0a13e96 Clear base backup progress on backup failure
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
2026-07-01 23:04:18 +09:00
Fujii Masao
f6fdc2a4a7 Warn on password auth with MD5-encrypted passwords
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
2026-07-01 20:57:28 +09:00
Peter Eisentraut
e8f851d617 Don't cast off_t to 32-bit type for output, bug fix
off_t is most likely a 64-bit integer, so casting it to a 32-bit type
for output could lose data.  There are more issues like this in the
tree, but this is an instance where this could actually happen in
practice, since base backups are routinely larger than 4 GB.  So this
is separated out as a bug fix.

Reviewed-by: Heikki Linnakangas <hlinnaka@iki.fi>
Discussion: https://www.postgresql.org/message-id/flat/20ce62fa-47fc-457b-b504-12f3c1651726%40eisentraut.org
2026-07-01 09:39:42 +02:00
Richard Guo
be69a5ff1f Improve UNION's output row count estimate
A UNION (not UNION ALL) removes duplicates, so its output has no more
rows than its input.  The planner did not account for this: it set the
set-op relation's row count to the total size of the appended input,
as though dedup removed nothing.  That inflated estimate then
propagated to every node above the UNION, leading to poor plan choices
such as a hash join with a full table scan where an index nested loop
would have been cheaper.

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

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

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

Author: Richard Guo <guofenglinux@gmail.com>
Reviewed-by: David Rowley <dgrowleyml@gmail.com>
Reviewed-by: Chengpeng Yan <chengpeng_yan@outlook.com>
Discussion: https://postgr.es/m/CAMbWs48Fu1nhGXPa60oc+adj7ge4dn0nHhqngqKvOVVQP61duA@mail.gmail.com
2026-07-01 15:12:43 +09:00
Michael Paquier
b542d55667 Avoid useless calls in pg_get_multixact_stats()
MultiXactOffsetStorageSize() and GetMultiXactInfo() are called to gather
the information reported by the function, but were wasteful for the case
where a role does not have the privileges of pg_read_all_stats, where we
return a set of NULLs.  These calls are moved to the code path where
their results are used.

Author: Ranier Vilela <ranier.vf@gmail.com>
Discussion: https://postgr.es/m/CAEudQAonQh7be=wOR-CJFW=bgMBz5wW_bv4t0OFxbgn-794JCQ@mail.gmail.com
Backpatch-through: 19
2026-07-01 12:17:17 +09:00
John Naylor
8db58ac8ee Document wal_compression=on
Commit 4035cd5d4 added LZ4 compression for full-page writes in WAL, and
retained "on" as a backward-compatible way to specify the builtin PGLZ
method. Document this meaning of "on" and update postgresql.conf.sample
to make the equivalence clear.

Author: Christoph Berg <myon@debian.org>
Reviewed-by: Michael Paquier <michael@paquier.xyz>
Discussion: https://postgr.es/m/akJDHRtXwGLTppsQ@msg.df7cb.de
Backpatch-through: 15
2026-07-01 08:54:36 +07:00
Tom Lane
1de468099d Disallow set-returning functions within window OVER clauses.
We previously allowed this, but it leads to odd behaviors, basically
because putting a SRF there is inconsistent with the principle that a
window function doesn't change the number of rows in the query result.
There doesn't seem to be a strong reason to try to make such cases
behave consistently.  Users should put their SRFs in lateral FROM
clauses instead.

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

Bug: #17502
Bug: #19535
Reported-by: Daniel Farkaš <daniel.farkas@datoris.com>
Reported-by: Qifan Liu <imchifan@163.com>
Author: Tom Lane <tgl@sss.pgh.pa.us>
Reviewed-by: David Rowley <dgrowleyml@gmail.com>
Discussion: https://postgr.es/m/17502-281a7aaacfaa872a@postgresql.org
Discussion: https://postgr.es/m/19535-376081d7cc07c86d@postgresql.org
Backpatch-through: 19
2026-06-30 17:21:23 -04:00
Peter Eisentraut
b1c41398e4 Make SPI_prepare argtypes argument const
This changes the argtypes argument of SPI_prepare(),
SPI_prepare_cursor(), SPI_cursor_open_with_args(), and
SPI_execute_with_args() from Oid *argtypes to const Oid *argtypes.
The underlying functions were already receptive to that, so this
doesn't require any significant changes beyond the function signatures
and some internal variables.

Commit 28972b6fc3 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
2026-06-30 15:43:56 +02:00
Peter Eisentraut
cd3ad3bc03 Fixes for SPI "const Datum *" use
Fixup for commit 8a27d418f8, 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
2026-06-30 14:46:15 +02:00
Michael Paquier
8c579bdc36 Add backend-level lock statistics
This commit adds per-backend lock statistics, providing the same
information as pg_stat_lock.  It is now possible to retrieve those stats
(lock wait counts, wait times, and fast-path exceeded count) on a
per-backend basis.

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

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

This commit is straight-forward, relying on the infrastructure provided
by 9aea73fc61 (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
2026-06-30 16:59:20 +09:00
Michael Paquier
dfe7d17e00 Refactor pg_stat_get_lock() to use a helper function
This commit extracts the tuple-building logic from pg_stat_get_lock()
into a new static helper pg_stat_lock_build_tuples().  This is in
preparation for a follow-up patch, to add support for backend-level lock
stats, which will reuse the same helper.

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

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by: Tatsuya Kawata <kawatatatsuya0913@gmail.com>
Reviewed-by: Michael Paquier <michael@paquier.xyz>
Reviewed-by: Tristan Partin <tristan@partin.io>
Reviewed-by: Rui Zhao <zhaorui126@gmail.com>
Discussion: https://postgr.es/m/aiAzEY+cMQb/W8yu@bdtpg
2026-06-30 16:24:34 +09:00
Michael Paquier
7905416eef Use placeholders and not GUC names in error message (autovacuum)
A placeholder %s is now used instead of the GUC names in the error
string of this routine.  This is going to be useful for a follow-up
patch, where we will be able to reuse the same string, hence reducing
the translation work.

Based on a suggestion by me.

Author: Baji Shaik <baji.pgdev@gmail.com>
Discussion: https://postgr.es/m/ajnhfw84reaXgjfO@paquier.xyz
2026-06-30 16:16:56 +09:00
Michael Paquier
c776550e46 Change stat_lock.wait_time to double precision
Other statistics views (pg_stat_io, pg_stat_database, etc.) use float8
for all measured-time columns, the new pg_stat_lock standing out as an
outlier by using bigint.

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

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

Bump catalog version.

Author: Tatsuya Kawata <kawatatatsuya0913@gmail.com>
Reviewed-by: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by: Michael Paquier <michael@paquier.xyz>
Discussion: https://postgr.es/m/CAHza6qerEiQehrbW5xaXyxvR0qJe3KBX1R4kocDz1+7Ygu8x-g@mail.gmail.com
Backpatch-through: 19
2026-06-30 12:47:34 +09:00
Fujii Masao
8d85cb889a bufmgr: Fix race in LockBufferForCleanup()
LockBufferForCleanup() acquires the exclusive content lock, checks the
buffer's shared pin count, and, if other pins remain, registers itself
as the BM_PIN_COUNT_WAITER before waiting for an unpin notification.

Since commits 5310fac6e0 and c75ebc657f, 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 5310fac6e0 and c75ebc657f
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
2026-06-30 10:36:41 +09:00
Fujii Masao
d8113095c4 Remove stray blank line in ParseFuncOrColumn()
Commit 419ce13b70 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
2026-06-30 10:28:52 +09:00
Fujii Masao
8e684ce11d Fix unlogged sequence corruption after standby promotion
Previously, if an unlogged sequence was created on the primary and
replicated to a standby, reading the sequence after promoting the
standby (for example, with nextval()) could trigger the following
assertion failure:

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

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

    ERROR:  bad magic number in sequence

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

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

Backpatch to v15, where unlogged sequences were introduced.

Author: Fujii Masao <masao.fujii@gmail.com>
Reviewed-by: vignesh C <vignesh21@gmail.com>
Discussion: https://postgr.es/m/CAHGQGwH1Ssze3XM6wjoTjSLVOR041c6xP+vsdLP951=w8oG8bA@mail.gmail.com
Backpatch-through: 15
2026-06-30 08:48:47 +09:00
Michael Paquier
efa59a5004 Simplify some stats restore code with InputFunctionCallSafe()
statatt_build_stavalues() and array_in_safe() have been relying on
InitFunctionCallInfoData() with a locally-filled state to call a data
type input function.  InputFunctionCallSafe() can be used to achieve the
same job, simplifying some code.

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

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

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

Author: Jian He <jian.universality@gmail.com>
Author: Michael Paquier <michael@paquier.xyz>
Discussion: https://postgr.es/m/CACJufxEGah9PaiTQ=cG14GMMBsUQ3ohGct9tdSwbMQPQ0-nbbQ@mail.gmail.com
Backpatch-through: 19
2026-06-30 08:30:08 +09:00
Peter Eisentraut
bc3ae886a7 Forbid FOR PORTION OF with WHERE CURRENT OF
It is not clear how the implicit condition of FOR PORTION OF should
interact with the use of a cursor.  Normally, we forbid combining
WHERE CURRENT OF with other WHERE conditions.  The SQL standard only
includes FOR PORTION OF with <update statement: searched> and <delete
statement: searched>, not <update statement: positioned> or <delete
statement: positioned>, so it is easy for us to exclude the
functionality, at least for now.

Author: Paul A. Jungwirth <pj@illuminatedcomputing.com>
Discussion: https://www.postgresql.org/message-id/flat/CA%2BrenyUEKPexUYsH4qeU8_o1jqKsUkEWca1keS6n21shgG1g%2BA%40mail.gmail.com
2026-06-29 15:17:10 +02:00
Amit Langote
6f4bac854f Hardwire RI fast-path end-of-xact cleanup into xact.c
Commit b7b27eb41a, which added foreign-key fast-path batching to
ri_triggers.c, registered ri_FastPathXactCallback() via
RegisterXactCallback() to clear the fast-path batching state at end of
transaction.  RegisterXactCallback() is documented as intended for
dynamically loaded modules; built-in code is supposed to hardwire its
end-of-xact hooks into xact.c, mainly so callback ordering can be
controlled where it matters (see the header comment on
RegisterXactCallback()).

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

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

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

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

Reported-by: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Discussion: https://postgr.es/m/ajypPeEWceXRGAEW@bdtpg
2026-06-29 10:24:28 +09:00
Tom Lane
b574fec00f Avoid collation lookup failure when considering a "char" column.
If a "char" column has a statistics histogram, scalarineqsel()
would fail with "cache lookup failed for collation 0".  Avoid
the failing lookup by acting as though the collation is "C".

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

Author: Feng Wu <wufengwufengwufeng@gmail.com>
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/CACK3muq6s-O1Wc3w4dRL1Fe8YQ-Fz1zJbezeQwhuLgNxGNEFiA@mail.gmail.com
Backpatch-through: 18
2026-06-28 12:31:29 -04:00
Andrew Dunstan
d6ed87d198 Use named boolean parameters for pg_get_*_ddl option arguments
Replace the VARIADIC text[] alternating key/value option interface with
typed named boolean parameters for pg_get_role_ddl(), pg_get_tablespace_ddl(),
and pg_get_database_ddl(), as added by commit 4881981f92 and friends.
The new signatures are:

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

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

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

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

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

Catalog version bumped.

Author: Jelte Fennema-Nio <postgres@jeltef.nl>
Discussion: https://postgr.es/m/DHM6C7SLS4BN.1WW9Z4PRPN0VJ@jeltef.nl
(and on Discord)
2026-06-28 10:45:26 -04:00
Andrew Dunstan
02f699c141 pgindent fix for commit effb923d9d 2026-06-27 20:05:06 -04:00
Andrew Dunstan
0cd17fdd3c Prevent inherited CHECK constraints from being weakened
Disallow marking an inherited CHECK constraint as NOT ENFORCED when an
equivalent parent constraint remains ENFORCED. This prevents ALTER
CONSTRAINT from producing a child constraint that is weaker than one of
its inherited parent definitions.

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

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

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

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