Compare commits

...

368 Commits

Author SHA1 Message Date
Tom Lane
6304632eaa Stamp 17.2. 2024-11-18 15:32:12 -05:00
Tom Lane
9ac1003320 Release notes for 17.2, 16.6, 15.10, 14.15, 13.18, 12.22. 2024-11-16 17:09:53 -05:00
Tom Lane
6bfacd368b Undo unintentional ABI break in struct ResultRelInfo.
Commits aac2c9b4f et al. added a bool field to struct ResultRelInfo.
That's no problem in the master branch, but in released branches
care must be taken when modifying publicly-visible structs to avoid
an ABI break for extensions.  Frequently we solve that by adding the
new field at the end of the struct, and that's what was done here.
But ResultRelInfo has stricter constraints than just about any other
node type in Postgres.  Some executor APIs require extensions to index
into arrays of ResultRelInfo, which means that any change whatever in
sizeof(ResultRelInfo) causes a fatal ABI break.

Fortunately, this is easy to fix, because the new field can be
squeezed into available padding space instead --- indeed, that's where
it was put in master, so this fix also removes a cross-branch coding
variation.

Per report from Pavan Deolasee.  Patch v14-v17 only; earlier versions
did not gain the extra field, nor is there any problem in master.

Discussion: https://postgr.es/m/CABOikdNmVBC1LL6pY26dyxAS2f+gLZvTsNt=2XbcyG7WxXVBBQ@mail.gmail.com
2024-11-16 12:58:26 -05:00
Noah Misch
1c05004a89 Fix per-session activation of ALTER {ROLE|DATABASE} SET role.
After commit 5a2fed911a85ed6d8a015a6bafe3a0d9a69334ae, the catalog state
resulting from these commands ceased to affect sessions.  Restore the
longstanding behavior, which is like beginning the session with a SET
ROLE command.  If cherry-picking the CVE-2024-10978 fixes, default to
including this, too.  (This fixes an unintended side effect of fixing
CVE-2024-10978.)  Back-patch to v12, like that commit.  The release team
decided to include v12, despite the original intent to halt v12 commits
earlier this week.

Tom Lane and Noah Misch.  Reported by Etienne LAFARGE.

Discussion: https://postgr.es/m/CADOZwSb0UsEr4_UTFXC5k7=fyyK8uKXekucd+-uuGjJsGBfxgw@mail.gmail.com
2024-11-15 20:39:59 -08:00
Masahiko Sawada
568e78a653 Fix a possibility of logical replication slot's restart_lsn going backwards.
Previously LogicalIncreaseRestartDecodingForSlot() accidentally
accepted any LSN as the candidate_lsn and candidate_valid after the
restart_lsn of the replication slot was updated, so it potentially
caused the restart_lsn to move backwards.

A scenario where this could happen in logical replication is: after a
logical replication restart, based on previous candidate_lsn and
candidate_valid values in memory, the restart_lsn advances upon
receiving a subscriber acknowledgment. Then, logical decoding restarts
from an older point, setting candidate_lsn and candidate_valid based
on an old RUNNING_XACTS record. Subsequent subscriber acknowledgments
then update the restart_lsn to an LSN older than the current value.

In the reported case, after WAL files were removed by a checkpoint,
the retreated restart_lsn prevented logical replication from
restarting due to missing WAL segments.

This change essentially modifies the 'if' condition to 'else if'
condition within the function. The previous code had an asymmetry in
this regard compared to LogicalIncreaseXminForSlot(), which does
almost the same thing for different fields.

The WAL removal issue was reported by Hubert Depesz Lubaczewski.

Backpatch to all supported versions, since the bug exists since 9.4
where logical decoding was introduced.

Reviewed-by: Tomas Vondra, Ashutosh Bapat, Amit Kapila
Discussion: https://postgr.es/m/Yz2hivgyjS1RfMKs%40depesz.com
Discussion: https://postgr.es/m/85fff40e-148b-4e86-b921-b4b846289132%40vondra.me
Backpatch-through: 13
2024-11-15 17:06:08 -08:00
Tom Lane
5f28e6ba7f Avoid assertion due to disconnected NFA sub-graphs in regex parsing.
In commit 08c0d6ad6 which introduced "rainbow" arcs in regex NFAs,
I didn't think terribly hard about what to do when creating the color
complement of a rainbow arc.  Clearly, the complement cannot match any
characters, and I took the easy way out by just not building any arcs
at all in the complement arc set.  That mostly works, but Nikolay
Shaplov found a case where it doesn't: if we decide to delete that
sub-NFA later because it's inside a "{0}" quantifier, delsub()
suffered an assertion failure.  That's because delsub() relies on
the target sub-NFA being fully connected.  That was always true
before, and the best fix seems to be to restore that property.
Hence, invent a new arc type CANTMATCH that can be generated in
place of an empty color complement, and drop it again later when we
start NFA optimization.  (At that point we don't need to do delsub()
any more, and besides there are other cases where NFA optimization can
lead to disconnected subgraphs.)

It appears that this bug has no consequences in a non-assert-enabled
build: there will be some transiently leaked NFA states/arcs, but
they'll get cleaned up eventually.  Still, we don't like assertion
failures, so back-patch to v14 where rainbow arcs were introduced.

Per bug #18708 from Nikolay Shaplov.

Discussion: https://postgr.es/m/18708-f94f2599c9d2c005@postgresql.org
2024-11-15 18:23:38 -05:00
Álvaro Herrera
cb844d66b5
Avoid deleting critical WAL segments during pg_rewind
Previously, in unlucky cases, it was possible for pg_rewind to remove
certain WAL segments from the rewound demoted primary.  In particular
this happens if those files have been marked for archival (i.e., their
.ready files were created) but not yet archived; the newly promoted node
no longer has such files because of them having been recycled, but they
are likely critical for recovery in the demoted node.  If pg_rewind
removes them, recovery is not possible anymore.

Fix this by maintaining a hash table of files in this situation in the
scan that looks for a checkpoint, which the decide_file_actions phase
can consult so that it knows to preserve them.

Backpatch to 14.  The problem also exists in 13, but that branch was not
blessed with commit eb00f1d4bf96, so this patch is difficult to apply
there.  Users of older releases will just have to continue to be extra
careful when rewinding.

Co-authored-by: Полина Бунгина (Polina Bungina) <bungina@gmail.com>
Co-authored-by: Alexander Kukushkin <cyberdemn@gmail.com>
Reviewed-by: Kyotaro Horiguchi <horikyota.ntt@gmail.com>
Reviewed-by: Atsushi Torikoshi <torikoshia@oss.nttdata.com>
Discussion: https://postgr.es/m/CAAtGL4AhzmBRsEsaDdz7065T+k+BscNadfTqP1NcPmsqwA5HBw@mail.gmail.com
2024-11-15 12:53:12 +01:00
Michael Paquier
1d6a03ea41 Fix race conditions with drop of reused pgstats entries
This fixes a set of race conditions with cumulative statistics where a
shared stats entry could be dropped while it should still be valid in
the event when it is reused: an entry may refer to a different object
but requires the same hash key.  This can happen with various stats
kinds, like:
- Replication slots that compute internally an index number, for
different slot names.
- Stats kinds that use an OID in the object key, where a wraparound
causes the same key to be used if an OID is used for the same object.
- As of PostgreSQL 18, custom pgstats kinds could also be an issue,
depending on their implementation.

This issue is fixed by introducing a counter called "generation" in the
shared entries via PgStatShared_HashEntry, initialized at 0 when an
entry is created and incremented when the same entry is reused, to avoid
concurrent issues on drop because of other backends still holding a
reference to it.  This "generation" is copied to the local copy that a
backend holds when looking at an object, then cross-checked with the
shared entry to make sure that the entry is not dropped even if its
"refcount" justifies that if it has been reused.

This problem could show up when a backend shuts down and needs to
discard any entries it still holds, causing statistics to be removed
when they should not, or even an assertion failure.  Another report
involved a failure in a standby after an OID wraparound, where the
startup process would FATAL on a "can only drop stats once", stopping
recovery abruptly.  The buildfarm has been sporadically complaining
about the problem, as well, but the window is hard to reach with the
in-core tests.

Note that the issue can be reproduced easily by adding a sleep before
dshash_find() in pgstat_release_entry_ref() to enlarge the problematic
window while repeating test_decoding's isolation test oldest_xmin a
couple of times, for example, as pointed out by Alexander Lakhin.

Reported-by: Alexander Lakhin, Peter Smith
Author: Kyotaro Horiguchi, Michael Paquier
Reviewed-by: Bertrand Drouvot
Discussion: https://postgr.es/m/CAA4eK1KxuMVyAryz_Vk5yq3ejgKYcL6F45Hj9ZnMNBS-g+PuZg@mail.gmail.com
Discussion: https://postgr.es/m/17947-b9554521ad963c9c@postgresql.org
Backpatch-through: 15
2024-11-15 11:32:13 +09:00
Michael Paquier
73731b2432 Fix comment in injection_point.c
InjectionPointEntry->name was described as a hash key, which was fine
when introduced in d86d20f0ba79, but it is not now.

Oversight in 86db52a5062a, that has changed the way injection points are
stored in shared memory from a hash table to an array.

Backpatch-through: 17
2024-11-13 13:58:19 +09:00
Peter Geoghegan
7af6d13061 Count contrib/bloom index scans in pgstat view.
Maintain the pg_stat_user_indexes.idx_scan pgstat counter during
contrib/Bloom index scans.

Oversight in commit 9ee014fc, which added the Bloom index contrib
module.

Author: Masahiro Ikeda <ikedamsh@oss.nttdata.com>
Reviewed-By: Peter Geoghegan <pg@bowt.ie>
Discussion: https://postgr.es/m/c48839d881388ee401a01807c686004d@oss.nttdata.com
Backpatch: 13- (all supported branches).
2024-11-12 20:57:43 -05:00
Alexander Korotkov
a6fa869cfa Fix arrays comparison in CompareOpclassOptions()
The current code calls array_eq() and does not provide FmgrInfo.  This commit
provides initialization of FmgrInfo and uses C collation as the safe option
for text comparison because we don't know anything about the semantics of
opclass options.

Backpatch to 13, where opclass options were introduced.

Reported-by: Nicolas Maus
Discussion: https://postgr.es/m/18692-72ea398df3ec6712%40postgresql.org
Backpatch-through: 13
2024-11-12 01:51:20 +02:00
Tom Lane
91f20bc2f7 Stamp 17.1. 2024-11-11 17:42:37 -05:00
Tom Lane
052aa02971 Last-minute updates for release notes.
Security: CVE-2024-10976, CVE-2024-10977, CVE-2024-10978, CVE-2024-10979
2024-11-11 17:40:13 -05:00
Tom Lane
f4f5d27d87 Parallel workers use AuthenticatedUserId for connection privilege checks.
Commit 5a2fed911 had an unexpected side-effect: the parallel worker
launched for the new test case would fail if it couldn't use a
superuser-reserved connection slot.  The reason that test failed
while all our pre-existing ones worked is that the connection
privilege tests in InitPostgres had been based on the superuserness
of the leader's AuthenticatedUserId, but after the rearrangements
of 5a2fed911 we were testing the superuserness of CurrentUserId,
which the new test case deliberately made to be a non-superuser.

This all seems very accidental and probably not the behavior we really
want, but a security patch is no time to be redesigning things.
Pending some discussion about desirable semantics, hack it so that
InitPostgres continues to pay attention to the superuserness of
AuthenticatedUserId when starting a parallel worker.

Nathan Bossart and Tom Lane, per buildfarm member sawshark.

Security: CVE-2024-10978
2024-11-11 17:05:53 -05:00
Tom Lane
8d19f3fea0 Fix cross-version upgrade tests.
TestUpgradeXversion knows how to make the main regression database's
references to pg_regress.so be version-independent.  But it doesn't
do that for plperl's database, so that the C function added by
commit b7e3a52a8 is causing cross-version upgrade test failures.
Path of least resistance is to just drop the function at the end
of the new test.

In <= v14, also take the opportunity to clean up the generated
test files.

Security: CVE-2024-10979
2024-11-11 13:57:21 -05:00
Tom Lane
4cd4f3b974 Avoid bizarre meson behavior with backslashes in command arguments.
meson makes the backslashes in text2macro.pl's --strip argument
into forward slashes, effectively disabling comment stripping.
That hasn't caused us issues before, but it breaks the test case
for b7e3a52a8.  We don't really need the pattern to be adjustable,
so just hard-wire it into the script instead.

Context: https://github.com/mesonbuild/meson/issues/1564
Security: CVE-2024-10979
2024-11-11 12:20:08 -05:00
Tom Lane
cd82afdda5 Fix improper interactions between session_authorization and role.
The SQL spec mandates that SET SESSION AUTHORIZATION implies
SET ROLE NONE.  We tried to implement that within the lowest-level
functions that manipulate these settings, but that was a bad idea.
In particular, guc.c assumes that it doesn't matter in what order
it applies GUC variable updates, but that was not the case for these
two variables.  This problem, compounded by some hackish attempts to
work around it, led to some security-grade issues:

* Rolling back a transaction that had done SET SESSION AUTHORIZATION
would revert to SET ROLE NONE, even if that had not been the previous
state, so that the effective user ID might now be different from what
it had been.

* The same for SET SESSION AUTHORIZATION in a function SET clause.

* If a parallel worker inspected current_setting('role'), it saw
"none" even when it should see something else.

Also, although the parallel worker startup code intended to cope
with the current role's pg_authid row having disappeared, its
implementation of that was incomplete so it would still fail.

Fix by fully separating the miscinit.c functions that assign
session_authorization from those that assign role.  To implement the
spec's requirement, teach set_config_option itself to perform "SET
ROLE NONE" when it sets session_authorization.  (This is undoubtedly
ugly, but the alternatives seem worse.  In particular, there's no way
to do it within assign_session_authorization without incompatible
changes in the API for GUC assign hooks.)  Also, improve
ParallelWorkerMain to directly set all the relevant user-ID variables
instead of relying on some of them to get set indirectly.  That
allows us to survive not finding the pg_authid row during worker
startup.

In v16 and earlier, this includes back-patching 9987a7bf3 which
fixed a violation of GUC coding rules: SetSessionAuthorization
is not an appropriate place to be throwing errors from.

Security: CVE-2024-10978
2024-11-11 10:29:54 -05:00
Nathan Bossart
edcda9bb4c Ensure cached plans are correctly marked as dependent on role.
If a CTE, subquery, sublink, security invoker view, or coercion
projection references a table with row-level security policies, we
neglected to mark the plan as potentially dependent on which role
is executing it.  This could lead to later executions in the same
session returning or hiding rows that should have been hidden or
returned instead.

Reported-by: Wolfgang Walther
Reviewed-by: Noah Misch
Security: CVE-2024-10976
Backpatch-through: 12
2024-11-11 09:00:00 -06:00
Noah Misch
3ebcfa54db Block environment variable mutations from trusted PL/Perl.
Many process environment variables (e.g. PATH), bypass the containment
expected of a trusted PL.  Hence, trusted PLs must not offer features
that achieve setenv().  Otherwise, an attacker having USAGE privilege on
the language often can achieve arbitrary code execution, even if the
attacker lacks a database server operating system user.

To fix PL/Perl, replace trusted PL/Perl %ENV with a tied hash that just
replaces each modification attempt with a warning.  Sites that reach
these warnings should evaluate the application-specific implications of
proceeding without the environment modification:

  Can the application reasonably proceed without the modification?

    If no, switch to plperlu or another approach.

    If yes, the application should change the code to stop attempting
    environment modifications.  If that's too difficult, add "untie
    %main::ENV" in any code executed before the warning.  For example,
    one might add it to the start of the affected function or even to
    the plperl.on_plperl_init setting.

In passing, link to Perl's guidance about the Perl features behind the
security posture of PL/Perl.

Back-patch to v12 (all supported versions).

Andrew Dunstan and Noah Misch

Security: CVE-2024-10979
2024-11-11 06:23:46 -08:00
Peter Eisentraut
6bf5bf11c3 Translation updates
Source-Git-URL: https://git.postgresql.org/git/pgtranslation/messages.git
Source-Git-Hash: 2592030f456910263c8972668576f954fce10595
2024-11-11 13:52:24 +01:00
Michael Paquier
a5cc4c6671 libpq: Bail out during SSL/GSS negotiation errors
This commit changes libpq so that errors reported by the backend during
the protocol negotiation for SSL and GSS are discarded by the client, as
these may include bytes that could be consumed by the client and write
arbitrary bytes to a client's terminal.

A failure with the SSL negotiation now leads to an error immediately
reported, without a retry on any other methods allowed, like a fallback
to a plaintext connection.

A failure with GSS discards the error message received, and we allow a
fallback as it may be possible that the error is caused by a connection
attempt with a pre-11 server, GSS encryption having been introduced in
v12.  This was a problem only with v17 and newer versions; older
versions discard the error message already in this case, assuming a
failure caused by a lack of support for GSS encryption.

Author: Jacob Champion
Reviewed-by: Peter Eisentraut, Heikki Linnakangas, Michael Paquier
Security: CVE-2024-10977
Backpatch-through: 12
2024-11-11 10:19:56 +09:00
Tom Lane
ca19f881b0 Release notes for 17.1, 16.5, 15.9, 14.14, 13.17, 12.21. 2024-11-10 13:40:41 -05:00
Nathan Bossart
0a883a067b Fix sign-compare warnings in pg_iovec.h.
The code in question (pg_preadv() and pg_pwritev()) has been around
for a while, but commit 15c9ac3629 moved it to a header file.  If
third-party code that includes this header file is built with
-Wsign-compare on a system without preadv() or pwritev(), warnings
ensue.  This commit fixes said warnings by casting the result of
pg_pread()/pg_pwrite() to size_t, which should be safe because we
will have already checked for a negative value.

Author: Wolfgang Walther
Discussion: https://postgr.es/m/16989737-1aa8-48fd-8dfe-b7ada06509ab%40technowledgy.de
Backpatch-through: 17
2024-11-08 16:11:08 -06:00
Tom Lane
4145ea0910 First-draft release notes for 17.1.
(We lack a query for identifying broken foreign keys in the first
changelog item, but the rest of this is in reviewable shape.)

As usual, the release notes for other branches will be made by cutting
these down, but put them up for community review first.

Also as usual for a .1 release, there are some entries here that
are not really relevant for v17 because they already appeared in 17.0.
Those'll be removed later.
2024-11-08 16:39:34 -05:00
Tom Lane
943b65358e Improve fix for not entering parallel mode when holding interrupts.
Commit ac04aa84a put the shutoff for this into the planner, which is
not ideal because it doesn't prevent us from re-using a previously
made parallel plan.  Revert the planner change and instead put the
shutoff into InitializeParallelDSM, modeling it on the existing code
there for recovering from failure to allocate a DSM segment.

However, that code path is mostly untested, and testing a bit harder
showed there's at least one bug: ExecHashJoinReInitializeDSM is not
prepared for us to have skipped doing parallel DSM setup.  I also
thought the Assert in ReinitializeParallelWorkers is pretty
ill-advised, and replaced it with a silent Min() operation.

The existing test case added by ac04aa84a serves fine to test this
version of the fix, so no change needed there.

Patch by me, but thanks to Noah Misch for the core idea that we
could shut off worker creation when !INTERRUPTS_CAN_BE_PROCESSED.
Back-patch to v12, as ac04aa84a was.

Discussion: https://postgr.es/m/CAC-SaSzHUKT=vZJ8MPxYdC_URPfax+yoA1hKTcF4ROz_Q6z0_Q@mail.gmail.com
2024-11-08 13:42:01 -05:00
Amit Langote
a0cdfc8893 Disallow partitionwise join when collations don't match
If the collation of any join key column doesn’t match the collation of
the corresponding partition key, partitionwise joins can yield incorrect
results. For example, rows that would match under the join key collation
might be located in different partitions due to the partitioning
collation. In such cases, a partitionwise join would yield different
results from a non-partitionwise join, so disallow it in such cases.

Reported-by: Tender Wang <tndrwang@gmail.com>
Author: Jian He <jian.universality@gmail.com>
Reviewed-by: Tender Wang <tndrwang@gmail.com>
Reviewed-by: Junwang Zhao <zhjwpku@gmail.com>
Discussion: https://postgr.es/m/CAHewXNno_HKiQ6PqyLYfuqDtwp7KKHZiH1J7Pqyz0nr+PS2Dwg@mail.gmail.com
Backpatch-through: 12
2024-11-08 17:19:35 +09:00
Amit Langote
b6484ca953 Disallow partitionwise grouping when collations don't match
If the collation of any grouping column doesn’t match the collation of
the corresponding partition key, partitionwise grouping can yield
incorrect results. For example, rows that would be grouped under the
grouping collation may end up in different partitions under the
partitioning collation. In such cases, full partitionwise grouping
would produce results that differ from those without partitionwise
grouping, so disallowed that.

Partial partitionwise aggregation is still allowed, as the Finalize
step reconciles partition-level aggregates with grouping requirements
across all partitions, ensuring that the final output remains
consistent.

This commit also fixes group_by_has_partkey() by ensuring the
RelabelType node is stripped from grouping expressions when matching
them to partition key expressions to avoid false mismatches.

Bug: #18568
Reported-by: Webbo Han <1105066510@qq.com>
Author: Webbo Han <1105066510@qq.com>
Reviewed-by: Tender Wang <tndrwang@gmail.com>
Reviewed-by: Aleksander Alekseev <aleksander@timescale.com>
Reviewed-by: Jian He <jian.universality@gmail.com>
Discussion: https://postgr.es/m/18568-2a9afb6b9f7e6ed3@postgresql.org
Discussion: https://postgr.es/m/tencent_9D9103CDA420C07768349CC1DFF88465F90A@qq.com
Discussion: https://postgr.es/m/CAHewXNno_HKiQ6PqyLYfuqDtwp7KKHZiH1J7Pqyz0nr+PS2Dwg@mail.gmail.com
Backpatch-through: 12
2024-11-08 16:07:13 +09:00
Richard Guo
78b1c553bb Fix inconsistent RestrictInfo serial numbers
When we generate multiple clones of the same qual condition to cope
with outer join identity 3, we need to ensure that all the clones get
the same serial number.  To achieve this, we reset the
root->last_rinfo_serial counter each time we produce RestrictInfo(s)
from the qual list (see deconstruct_distribute_oj_quals).  This
approach works only if we ensure that we are not changing the qual
list in any way that'd affect the number of RestrictInfos built from
it.

However, with b262ad440, an IS NULL qual on a NOT NULL column might
result in an additional constant-FALSE RestrictInfo.  And different
versions of the same qual clause can lead to different conclusions
about whether it can be reduced to constant-FALSE.  This would affect
the number of RestrictInfos built from the qual list for different
versions, causing inconsistent RestrictInfo serial numbers across
multiple clones of the same qual.  This inconsistency can confuse
users of these serial numbers, such as rebuild_joinclause_attr_needed,
and lead to planner errors such as "ERROR:  variable not found in
subplan target lists".

To fix, reset the root->last_rinfo_serial counter after generating the
additional constant-FALSE RestrictInfo.

Back-patch to v17 where the issue crept in.  In v17, I failed to make
a test case that would expose this bug, so no test case for v17.

Author: Richard Guo
Discussion: https://postgr.es/m/CAMbWs4-B6kafn+LmPuh-TYFwFyEm-vVj3Qqv7Yo-69CEv14rRg@mail.gmail.com
2024-11-08 11:24:26 +09:00
Álvaro Herrera
e2b5693c6c
doc: Reword ALTER TABLE ATTACH restriction on NO INHERIT constraints
The previous wording is easy to read incorrectly; this change makes it
simpler, less ambiguous, and less prominent.

Backpatch to all live branches.

Reviewed-by: Amit Langote <amitlangote09@gmail.com>
Discussion: https://postgr.es/m/202411051201.zody6mld7vkw@alvherre.pgsql
2024-11-07 14:06:24 +01:00
Jeff Davis
8148e7124d Fix lc_collate_is_c() when LC_COLLATE != LC_CTYPE.
An unfortunate typo in commit 2d819a08a1 can cause wrong results when
the default collation provider is libc, LC_CTYPE=C, and LC_COLLATE is
a real locale. Users with this combination of settings must REINDEX
all affected indexes.

The same typo can also cause performance degradation when LC_COLLATE=C
and LC_CTYPE is a real locale.

Problem does not exist in master (due to refactoring), so fix only in
version 17.

Reported-by: Drew Callahan
Discussion: https://postgr.es/m/d5081a7f4f6d425c28dd69d1e09b2e78f149e726.camel@j-davis.com
2024-11-06 14:44:35 -08:00
Thomas Munro
b7467ab71c Monkey-patch LLVM code to fix ARM relocation bug.
Supply a new memory manager for RuntimeDyld, to avoid crashes in
generated code caused by memory placement that can overflow a 32 bit
data type.  This is a drop-in replacement for the
llvm::SectionMemoryManager class in the LLVM library, with Michael
Smith's proposed fix from
https://www.github.com/llvm/llvm-project/pull/71968.

We hereby slurp it into our own source tree, after moving into a new
namespace llvm::backport and making some minor adjustments so that it
can be compiled with older LLVM versions as far back as 12.  It's harder
to make it work on even older LLVM versions, but it doesn't seem likely
that people are really using them so that is not investigated for now.

The problem could also be addressed by switching to JITLink instead of
RuntimeDyld, and that is the LLVM project's recommended solution as
the latter is about to be deprecated.  We'll have to do that soon enough
anyway, and then when the LLVM version support window advances far
enough in a few years we'll be able to delete this code.  Unfortunately
that wouldn't be enough for PostgreSQL today: in most relevant versions
of LLVM, JITLink is missing or incomplete.

Several other projects have already back-ported this fix into their fork
of LLVM, which is a vote of confidence despite the lack of commit into
LLVM as of today.  We don't have our own copy of LLVM so we can't do
exactly what they've done; instead we have a copy of the whole patched
class so we can pass an instance of it to RuntimeDyld.

The LLVM project hasn't chosen to commit the fix yet, and even if it
did, it wouldn't be back-ported into the releases of LLVM that most of
our users care about, so there is not much point in waiting any longer
for that.  If they make further changes and commit it to LLVM 19 or 20,
we'll still need this for older versions, but we may want to
resynchronize our copy and update some comments.

The changes that we've had to make to our copy can be seen by diffing
our SectionMemoryManager.{h,cpp} files against the ones in the tree of
the pull request.  Per the LLVM project's license requirements, a copy
is in SectionMemoryManager.LICENSE.

This should fix the spate of crash reports we've been receiving lately
from users on large memory ARM systems.

Back-patch to all supported releases.

Co-authored-by: Thomas Munro <thomas.munro@gmail.com>
Co-authored-by: Anthonin Bonnefoy <anthonin.bonnefoy@datadoghq.com>
Reviewed-by: Anthonin Bonnefoy <anthonin.bonnefoy@datadoghq.com>
Reviewed-by: Daniel Gustafsson <daniel@yesql.se> (license aspects)
Reported-by: Anthonin Bonnefoy <anthonin.bonnefoy@datadoghq.com>
Discussion: https://postgr.es/m/CAO6_Xqr63qj%3DSx7HY6ZiiQ6R_JbX%2B-p6sTPwDYwTWZjUmjsYBg%40mail.gmail.com
2024-11-06 23:07:34 +13:00
Michael Paquier
7f3b41ce48 Clear padding of PgStat_HashKey when handling pgstats entries
PgStat_HashKey is currently initialized in a way that could result in
random data if the structure has any padding bytes.  The structure
has no padding bytes currently, fortunately, but it could become a
problem should the structure change at some point in the future.

The code is changed to use some memset(0) so as any padding would be
handled properly, as it would be surprising to see random failures in
the pgstats entry lookups.  PgStat_HashKey is a structure internal to
pgstats, and an ABI change could be possible in the scope of a bug fix,
so backpatch down to 15 where this has been introduced.

Author: Bertrand Drouvot
Reviewed-by: Jelte Fennema-Nio, Michael Paquier
Discussion: https://postgr.es/m/Zyb7RW1y9dVfO0UH@ip-10-97-1-34.eu-west-3.compute.internal
Backpatch-through: 15
2024-11-05 09:40:55 +09:00
Tom Lane
811f8d3f10 Use portable diff options in pg_bsd_indent's regression test.
We had been using "diff -upd", which evidently works for most people,
but Solaris's diff doesn't like it.  (We'd not noticed because the
Solaris buildfarm animals weren't running this test until they were
upgraded to the latest buildfarm client script.)  Change to "diff -U3"
which is what pg_regress has used for ages.

Per buildfarm (and off-list discussion with Noah Misch).

Back-patch to v16 where this test was added.  In v16,
also back-patch the relevant part of 628c1d1f2 so that
the test script looks about the same in all branches.
2024-11-04 18:08:48 -05:00
Tom Lane
e2a9129093 pg_basebackup, pg_receivewal: fix failure to find password in ~/.pgpass.
Sloppy refactoring in commit cca97ce6a caused these programs
to pass dbname = NULL to libpq if there was no "--dbname" switch
on the command line, where before "replication" would be passed.
This didn't break things completely, because the source server doesn't
care about the dbname specified for a physical replication connection.
However, it did cause libpq to fail to match a ~/.pgpass entry that
has "replication" in the dbname field.  Restore the previous behavior
of passing "replication".

Also, closer inspection shows that if you do specify a dbname
in the connection string, that is what will be matched to ~/.pgpass,
not "replication".  This was the pre-existing behavior so we should
not change it, but the SGML docs were pretty misleading about it.
Improve that.

Per bug #18685 from Toshi Harada.  Back-patch to v17 where the
error crept in.

Discussion: https://postgr.es/m/18685-fee2dd142b9688f1@postgresql.org
Discussion: https://postgr.es/m/2702546.1730740456@sss.pgh.pa.us
2024-11-04 14:36:04 -05:00
Robert Haas
e367114429 pg_combinebackup: Error if incremental file exists in full backup.
Suppose that you run a command like "pg_combinebackup b1 b2 -o output",
but both b1 and b2 contain an INCREMENTAL.$something file in a directory
that is expected to contain relation files. This is an error, but the
previous code would not detect the problem and instead write a garbage
full file named $something to the output directory. This commit adds
code to detect the error and a test case to verify the behavior.

It's difficult to imagine that this will ever happen unless someone
is intentionally trying to break incremental backup, but per discussion,
let's consider that the lack of adequate sanity checking in this area is
a bug and back-patch to v17, where incremental backup was introduced.

Patch by me, reviewed by Bertrand Drouvot and Amul Sul.

Discussion: http://postgr.es/m/CA+TgmoaD7dBYPqe7kMtO0dyto7rd0rUh7joh=JPUSaFszKY6Pg@mail.gmail.com
2024-11-04 10:19:37 -05:00
Robert Haas
0d635b615d pg_combinebackup: When reconstructing, avoid double slash in filename.
This function is always called with a relative_path that ends in a
slash, so there's no need to insert a second one. So, don't. Instead,
add an assertion to verify that nothing gets broken in the future, and
adjust the comments.

While this is not a critical bug, the duplicate slash is visible in
error messages, which could create confusion, so back-patch to v17.
This is also better in that it keeps the code consistent across
branches.

Patch by me, reviewed by Bertrand Drouvot and Amul Sul.

Discussion: http://postgr.es/m/CA+TgmoaD7dBYPqe7kMtO0dyto7rd0rUh7joh=JPUSaFszKY6Pg@mail.gmail.com
2024-11-04 10:04:26 -05:00
Noah Misch
54bc22fbf6 Suppress new "may be used uninitialized" warning.
Buildfarm member mamba fails to deduce that the function never uses this
variable without initializing it.  Back-patch to v12, like commit
b412f402d1e020c5dac94f3bf4a005db69519b99.
2024-11-02 19:42:55 -07:00
Noah Misch
0bcb9d0794 Move I/O before the index_update_stats() buffer lock region.
Commit a07e03fd8fa7daf4d1356f7cb501ffe784ea6257 enlarged the work done
here under the pg_class heap buffer lock.  Two preexisting actions are
best done before holding that lock.  Both RelationGetNumberOfBlocks()
and visibilitymap_count() do I/O, and the latter might exclusive-lock a
visibility map buffer.  Moving these reduces contention and risk of
undetected LWLock deadlock.  Back-patch to v12, like that commit.

Discussion: https://postgr.es/m/20241031200139.b4@rfd.leadboat.com
2024-11-02 09:05:00 -07:00
Noah Misch
c1099dd745 Revert "For inplace update, send nontransactional invalidations."
This reverts commit 95c5acb3fc261067ab65ddc0b2dca8e162f09442 (v17) and
counterparts in each other non-master branch.  If released, that commit
would have caused a worst-in-years minor release regression, via
undetected LWLock self-deadlock.  This commit and its self-deadlock fix
warrant more bake time in the master branch.

Reported by Alexander Lakhin.

Discussion: https://postgr.es/m/10ec0bc3-5933-1189-6bb8-5dec4114558e@gmail.com
2024-11-02 09:05:00 -07:00
Noah Misch
bc6bad8857 Revert "WAL-log inplace update before revealing it to other sessions."
This reverts commit bfd5c6e279c8e1702eea882439dc7ebdf4d4b3a5 (v17) and
counterparts in each other non-master branch.  This unblocks reverting a
commit on which it depends.

Discussion: https://postgr.es/m/10ec0bc3-5933-1189-6bb8-5dec4114558e@gmail.com
2024-11-02 09:04:59 -07:00
Bruce Momjian
0a0a0f2c59 doc: fix ALTER DOMAIN domain_constraint to spell out options
It used to refer to CREATE DOMAIN, but CREATE DOMAIN allows NULL, while
ALTER DOMAIN does not.

Reported-by: elionescu@yahoo.com

Discussion: https://postgr.es/m/172225092461.915373.6103973717483380183@wrigleys.postgresql.org

Backpatch-through: 12
2024-11-01 13:54:28 -04:00
Bruce Momjian
787bd3dde2 doc: remove mention of ActiveState for Perl and Tcl on Windows
Replace with Strawberry Perl and Magicsplat Tcl.

Reported-by: Yasir Hussain

Discussion: https://postgr.es/m/CAA9OW9fAAM_WDYYpAquqF6j1hmfRMzHPsFkRfP5E6oSfkF=dMA@mail.gmail.com

Backpatch-through: 12
2024-11-01 11:30:54 -04:00
Tom Lane
a358019159 Stabilize jsonb_path_query test case.
An operation like '12:34:56'::time_tz takes the UTC offset from
the prevailing time zone, which means that the results change
across DST transitions.  One of the test cases added in ed055d249
failed to consider this.

Per report from Bernhard Wiedemann.  Back-patch to v17, as the
test case was.

Discussion: https://postgr.es/m/ba8e1bc0-8a99-45b7-8397-3f2e94415e03@suse.de
2024-10-30 11:42:34 -04:00
Peter Geoghegan
c177726ae4 Fix bug in nbtree array primitive scan scheduling.
A bug in nbtree's handling of primitive index scan scheduling could lead
to wrong answers when a scrollable cursor was used with an index scan
that had a SAOP index qual.  Wrong answers were only possible when the
scan direction changed after a primitive scan was scheduled, but before
_bt_next was asked to fetch the next tuple in line (i.e. for things to
break, _bt_next had to be denied the opportunity to step off the page in
the same direction as the one used when the primscan was scheduled).
Furthermore, the issue only occurred when the page in question happened
to be the first page to be visited by the entire top-level scan; the
issue hinged upon the cursor backing up to the absolute beginning of the
key space that it returns tuples from (fetching in the opposite scan
direction across a "primitive scan boundary" always worked correctly).

To fix, make _bt_next unset the "needs primitive index scan" flag when
it detects that the current scan direction is not the one that was used
by _bt_readpage back when the primitive scan in question was scheduled.
This fixes the cases that are known to be faulty, and also seems like a
good idea on general robustness grounds.

Affected scrollable cursor cases now avoid a spurious primitive index
scan when they fetch backwards to the absolute start of the key space to
be visited by their cursor.  Fetching backwards now only returns those
tuples at the start of the scan, as expected.  It'll also be okay to
once again fetch forwards from the start at that point, since the scan
will be left in a state that's exactly consistent with the state it was
in before any tuples were ever fetched, as expected.

Oversight in commit 5bf748b8, which enhanced nbtree ScalarArrayOp
execution.

Author: Peter Geoghegan <pg@bowt.ie>
Discussion: https://postgr.es/m/CAH2-Wznv49bFsE2jkt4GuZ0tU2C91dEST=50egzjY2FeOcHL4Q@mail.gmail.com
Backpatch: 17-, where commit 5bf748b8 first appears.
2024-10-30 10:57:17 -04:00
Álvaro Herrera
936ab6de95
Fix some more bugs in foreign keys connecting partitioned tables
* In DetachPartitionFinalize() we were applying a tuple conversion map
  to tuples that didn't need one, which can lead to erratic behavior if
  a partitioned table has a partition with a different column order, as
  reported by Alexander Lakhin. This was introduced by 53af9491a043.
  Don't do that.  Also, modify a recently added test case to exercise
  this.

* The same function as well as CloneFkReferenced() were acquiring
  AccessShareLock on a partition, only to have CreateTrigger() later
  acquire ShareRowExclusiveLock on it.  This can lead to deadlock by
  lock escalation, unnecessarily.  Avoid that by acquiring the stronger
  lock to begin with.  This probably dates back to branch 12, but I have
  never seen a report of this being a problem in the field.

* Innocuous but wasteful: also introduced by 53af9491a043, we were
  reading a pg_constraint tuple from syscache that we don't need, as
  reported by Tender Wang.  Don't.

Backpatch to 15.

Discussion: https://postgr.es/m/461e9c26-2076-8224-e119-84998b6a784e@gmail.com
2024-10-30 10:54:03 +01:00
Noah Misch
9aef6f19ac Unpin buffer before inplace update waits for an XID to end.
Commit a07e03fd8fa7daf4d1356f7cb501ffe784ea6257 changed inplace updates
to wait for heap_update() commands like GRANT TABLE and GRANT DATABASE.
By keeping the pin during that wait, a sequence of autovacuum workers
and an uncommitted GRANT starved one foreground LockBufferForCleanup()
for six minutes, on buildfarm member sarus.  Prevent, at the cost of a
bit of complexity.  Back-patch to v12, like the earlier commit.  That
commit and heap_inplace_lock() have not yet appeared in any release.

Discussion: https://postgr.es/m/20241026184936.ae.nmisch@google.com
2024-10-29 09:39:58 -07:00
Tom Lane
cad65907ee Update time zone data files to tzdata release 2024b.
Historical corrections for Mexico, Mongolia, and Portugal.
Notably, Asia/Choibalsan is now an alias for Asia/Ulaanbaatar
rather than being a separate zone, mainly because the differences
between those zones were found to be based on untrustworthy data.
2024-10-29 11:49:50 -04:00
Michael Paquier
709ce29b16 doc: Add better description for rewrite functions in event triggers
There are two functions that can be used in event triggers to get more
details about a rewrite happening on a relation.  Both had a limited
documentation:
- pg_event_trigger_table_rewrite_reason() and
pg_event_trigger_table_rewrite_oid() were not mentioned in the main
event trigger section in the paragraph dedicated to the event
table_rewrite.
- pg_event_trigger_table_rewrite_reason() returns an integer which is a
bitmap of the reasons why a rewrite happens.  There was no explanation
about the meaning of these values, forcing the reader to look at the
code to find out that these are defined in event_trigger.h.

While on it, let's add a comment in event_trigger.h where the
AT_REWRITE_* are defined, telling to update the documentation when
these values are changed.

Backpatch down to 13 as a consequence of 1ad23335f36b, where this area
of the documentation has been heavily reworked.

Author: Greg Sabino Mullane
Discussion: https://postgr.es/m/CAKAnmmL+Z6j-C8dAx1tVrnBmZJu+BSoc68WSg3sR+CVNjBCqbw@mail.gmail.com
Backpatch-through: 13
2024-10-29 15:35:14 +09:00
David Rowley
e5086b3ff4 Doc: clarify enable_indexscan=off also disabled Index Only Scans
Disabling enable_indexscan has always also disabled Index Only Scans.
Here we make that more clear in the documentation in an attempt to
prevent future complaints complaining about this expected behavior.

Reported-by: Melanie Plageman
Author: David G. Johnston, David Rowley
Backpatch-through: 12, oldest supported version
Discussion: https://postgr.es/m/CAAKRu_atV=kovgpaLREyG68PB5+ncKvJ2UNoeRetEgyC3Yb5Sw@mail.gmail.com
2024-10-29 16:24:47 +13:00
Michael Paquier
bb584e8312 Fix dependency of partitioned table and table AM with CREATE TABLE .. USING
A pg_depend entry between a partitioned table and its table access
method was missing when using CREATE TABLE .. USING with an unpinned
access method.  DROP ACCESS METHOD could be used, while it should be
blocked if CASCADE is not specified, even if there was a partitioned
table that depends on the table access method.  pg_class.relam would
then hold an orphaned OID value still pointing to the AM dropped.

The problem is fixed by adding a dependency between the partitioned
table and its table access method if set when the relation is created.
A test checking the contents of pg_depend in this case is added.

Issue introduced in 374c7a229042, that has added support for CREATE
TABLE .. USING for partitioned tables.

Reviewed-by: Alexander Lakhin
Discussion: https://postgr.es/m/18674-1ef01eceec278fab@postgresql.org
Backpatch-through: 17
2024-10-29 08:41:53 +09:00
Tom Lane
e631ed89c2 Guard against enormously long input in pg_saslprep().
Coverity complained that pg_saslprep() could suffer integer overflow,
leading to under-allocation of the output buffer, if the input string
exceeds SIZE_MAX/4.  This hazard seems largely hypothetical, but it's
easy enough to defend against, so let's do so.

This patch creates a third place in src/common/ where we are locally
defining MaxAllocSize so that we can test against that in the same way
in backend and frontend compiles.  That seems like about two places
too many, so the next patch will move that into common/fe_memutils.h.
I'm hesitant to do that in back branches however.

Back-patch to v14.  The code looks similar in older branches, but
before commit 67a472d71 there was a separate test on the input string
length that prevented this hazard.

Per Coverity report.
2024-10-28 14:33:55 -04:00
Heikki Linnakangas
22b914121a Fix overflow in bsearch_arg() with more than INT_MAX elements
This was introduced in commit bfa2cee784, which replaced the old
bsearch_cmp() function we had in extended_stats.c with the current
implementation. The original discussion or commit message of
bfa2cee784 didn't mention where the new implementation came from, but
based on some googling, I'm guessing *BSD or libiberty, all of which
share this same code, with or without this fix.

Author: Ranier Vilela
Reviewed-by: Nathan Bossart
Backpatch-through: 14
Discussion: https://www.postgresql.org/message-id/CAEudQAp34o_8u6sGSVraLwuMv9F7T9hyHpePXHmRaxR2Aboi%2Bw%40mail.gmail.com
2024-10-28 14:07:57 +02:00
Noah Misch
bfd5c6e279 WAL-log inplace update before revealing it to other sessions.
A buffer lock won't stop a reader having already checked tuple
visibility.  If a vac_update_datfrozenid() and then a crash happened
during inplace update of a relfrozenxid value, datfrozenxid could
overtake relfrozenxid.  That could lead to "could not access status of
transaction" errors.  Back-patch to v12 (all supported versions).  In
v14 and earlier, this also back-patches the assertion removal from
commit 7fcf2faf9c7dd473208fd6d5565f88d7f733782b.

Discussion: https://postgr.es/m/20240620012908.92.nmisch@google.com
2024-10-25 06:51:06 -07:00
Noah Misch
95c5acb3fc For inplace update, send nontransactional invalidations.
The inplace update survives ROLLBACK.  The inval didn't, so another
backend's DDL could then update the row without incorporating the
inplace update.  In the test this fixes, a mix of CREATE INDEX and ALTER
TABLE resulted in a table with an index, yet relhasindex=f.  That is a
source of index corruption.  Back-patch to v12 (all supported versions).
The back branch versions don't change WAL, because those branches just
added end-of-recovery SIResetAll().  All branches change the ABI of
extern function PrepareToInvalidateCacheTuple().  No PGXN extension
calls that, and there's no apparent use case in extensions.

Reviewed by Nitin Motiani and (in earlier versions) Andres Freund.

Discussion: https://postgr.es/m/20240523000548.58.nmisch@google.com
2024-10-25 06:51:06 -07:00
Noah Misch
a4668c99f0 At end of recovery, reset all sinval-managed caches.
An inplace update's invalidation messages are part of its transaction's
commit record.  However, the update survives even if its transaction
aborts or we stop recovery before replaying its transaction commit.
After recovery, a backend that started in recovery could update the row
without incorporating the inplace update.  That could result in a table
with an index, yet relhasindex=f.  That is a source of index corruption.

This bulk invalidation avoids the functional consequences.  A future
change can fix the !RecoveryInProgress() scenario without changing the
WAL format.  Back-patch to v17 - v12 (all supported versions).  v18 will
instead add invalidations to WAL.

Discussion: https://postgr.es/m/20240618152349.7f.nmisch@google.com
2024-10-25 06:51:06 -07:00
Noah Misch
e119076828 Stop reading uninitialized memory in heap_inplace_lock().
Stop computing a never-used value.  This removes the read; the read had
no functional implications.  Back-patch to v12, like commit
a07e03fd8fa7daf4d1356f7cb501ffe784ea6257.

Reported by Alexander Lakhin.

Discussion: https://postgr.es/m/6c92f59b-f5bc-e58c-9bdd-d1f21c17c786@gmail.com
2024-10-24 09:16:17 -07:00
Daniel Gustafsson
0a059206fc doc: Fix INSERT statement syntax for identity columns
The INSERT statements in the examples were erroneously using
VALUE instead of VALUES. Backpatch to v17 where the examples
were added through a37bb7c1399.

Reported-by: shixiong327926@gmail.com
Discussion: https://postgr.es/m/172958472112.696.6075270400394560263@wrigleys.postgresql.org
Backpatch-through: 17
2024-10-23 14:58:17 +02:00
Amit Langote
f92f6b3db4 Remove unnecessary word in a comment
Relations opened by the executor are only closed once in
ExecCloseRangeTableRelations(), so the word "again" in the comment
for ExecGetRangeTableRelation() is misleading and unnecessary.

Discussion: https://postgr.es/m/CA+HiwqHnw-zR+u060i3jp4ky5UR0CjByRFQz50oZ05de7wUg=Q@mail.gmail.com
Backpatch-through: 12
2024-10-23 17:55:12 +09:00
Michael Paquier
2c37cb26f8 ecpg: Fix out-of-bound read in DecodeDateTime()
It was possible for the code to read out-of-bound data from the
"day_tab" table with some crafted input data.  Let's treat these as
invalid input as the month number is incorrect.

A test is added to test this case with a check on the errno returned by
the decoding routine.  A test close to the new one added in this commit
was testing for a failure, but did not look at the errno generated, so
let's use this commit to also change it, adding a check on the errno
returned by DecodeDateTime().

Like the other test scripts, dt_test should likely be expanded to
include more checks based on the errnos generated in these code paths.
This is left as future work.

This issue exists since 2e6f97560a83, so backpatch all the way down.

Reported-by: Pavel Nekrasov
Author: Bruce Momjian, Pavel Nekrasov
Discussion: https://postgr.es/m/18614-6bbe00117352309e@postgresql.org
Backpatch-through: 12
2024-10-23 08:35:00 +09:00
Álvaro Herrera
5914a22f6e
Restructure foreign key handling code for ATTACH/DETACH
... to fix bugs when the referenced table is partitioned.

The catalog representation we chose for foreign keys connecting
partitioned tables (in commit f56f8f8da6af) is inconvenient, in the
sense that a standalone table has a different way to represent the
constraint when referencing a partitioned table, than when the same
table becomes a partition (and vice versa).  Because of this, we need to
create additional catalog rows on detach (pg_constraint and pg_trigger),
and remove them on attach.  We were doing some of those things, but not
all of them, leading to missing catalog rows in certain cases.

The worst problem seems to be that we are missing action triggers after
detaching a partition, which means that you could update/delete rows
from the referenced partitioned table that still had referencing rows on
that table, the server failing to throw the required errors.

!!!
Note that this means existing databases with FKs that reference
partitioned tables might have rows that break relational integrity, on
tables that were once partitions on the referencing side of the FK.

Another possible problem is that trying to reattach a table
that had been detached would fail indicating that internal triggers
cannot be found, which from the user's point of view is nonsensical.

In branches 15 and above, we fix this by creating a new helper function
addFkConstraint() which is in charge of creating a standalone
pg_constraint row, and repurposing addFkRecurseReferencing() and
addFkRecurseReferenced() so that they're only the recursive routine for
each side of the FK, and they call addFkConstraint() to create
pg_constraint at each partitioning level and add the necessary triggers.
These new routines can be used during partition creation, partition
attach and detach, and foreign key creation.  This reduces redundant
code and simplifies the flow.

In branches 14 and 13, we have a much simpler fix that consists on
simply removing the constraint on detach.  The reason is that those
branches are missing commit f4566345cf40, which reworked the way this
works in a way that we didn't consider back-patchable at the time.

We opted to leave branch 12 alone, because it's different from branch 13
enough that the fix doesn't apply; and because it is going in EOL mode
very soon, patching it now might be worse since there's no way to undo
the damage if it goes wrong.

Existing databases might need to be repaired.

In the future we might want to rethink the catalog representation to
avoid this problem, but for now the code seems to do what's required to
make the constraints operate correctly.

Co-authored-by: Jehan-Guillaume de Rorthais <jgdr@dalibo.com>
Co-authored-by: Tender Wang <tndrwang@gmail.com>
Co-authored-by: Alvaro Herrera <alvherre@alvh.no-ip.org>
Reported-by: Guillaume Lelarge <guillaume@lelarge.info>
Reported-by: Jehan-Guillaume de Rorthais <jgdr@dalibo.com>
Reported-by: Thomas Baehler (SBB CFF FFS) <thomas.baehler2@sbb.ch>
Discussion: https://postgr.es/m/20230420144344.40744130@karst
Discussion: https://postgr.es/m/20230705233028.2f554f73@karst
Discussion: https://postgr.es/m/GVAP278MB02787E7134FD691861635A8BC9032@GVAP278MB0278.CHEP278.PROD.OUTLOOK.COM
Discussion: https://postgr.es/m/18541-628a61bc267cd2d3@postgresql.org
2024-10-22 16:01:18 +02:00
Tom Lane
3685ad6188 Fix wrong assertion and poor error messages in "COPY (query) TO".
If the query is rewritten into a NOTIFY command by a DO INSTEAD
rule, we'd get an assertion failure, or in non-assert builds
issue a rather confusing error message.  Improve that.

Also fix a longstanding grammar mistake in a nearby error message.

Per bug #18664 from Alexander Lakhin.  Back-patch to all supported
branches.

Tender Wang and Tom Lane

Discussion: https://postgr.es/m/18664-ffd0ebc2386598df@postgresql.org
2024-10-21 15:08:22 -04:00
Heikki Linnakangas
234f6d09e5 Fix race condition in committing a serializable transaction
The finished transaction list can contain XIDs that are older than the
serializable global xmin. It's a short-lived state;
ClearOldPredicateLocks() removes any such transactions from the list,
and it's called whenever the global xmin advances. But if another
backend calls SummarizeOldestCommittedSxact() in that window, it will
call SerialAdd() on an XID that's older than the global xmin, or if
there are no more transactions running, when global xmin is
invalid. That trips the assertion in SerialAdd().

Fixes bug #18658 reported by Andrew Bille. Thanks to Alexander Lakhin
for analysis. Backpatch to all versions.

Discussion: https://www.postgresql.org/message-id/18658-7dab125ec688c70b%40postgresql.org
2024-10-21 09:49:29 +03:00
Álvaro Herrera
e9959ff71c
Note that index_name in ALTER INDEX ATTACH PARTITION can be schema-qualified
Missed in 8b08f7d4820f; backpatch to all supported branches.

Reported-by: alvaro@datadoghq.com
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/172924785099.698.15236991344616673753@wrigleys.postgresql.org
2024-10-20 15:36:20 +02:00
Amit Langote
7148cb3e30 SQL/JSON: Fix some oversights in commit b6e1157e7
The decision in b6e1157e7 to ignore raw_expr when evaluating a
JsonValueExpr was incorrect.  While its value is not ultimately
used (since formatted_expr's value is), failing to initialize it
can lead to problems, for instance,  when the expression tree in
raw_expr contains Aggref nodes, which must be initialized to
ensure the parent Agg node works correctly.

Also, optimize eval_const_expressions_mutator()'s handling of
JsonValueExpr a bit.  Currently, when formatted_expr cannot be folded
into a constant, we end up processing it twice -- once directly in
eval_const_expressions_mutator() and again recursively via
ece_generic_processing().  This recursive processing is required to
handle raw_expr. To avoid the redundant processing of formatted_expr,
we now  process raw_expr directly in eval_const_expressions_mutator().

Finally, update the comment of JsonValueExpr to describe the roles of
raw_expr and formatted_expr more clearly.

Bug: #18657
Reported-by: Alexander Lakhin <exclusion@gmail.com>
Diagnosed-by: Fabio R. Sluzala <fabio3rs@gmail.com>
Diagnosed-by: Tender Wang <tndrwang@gmail.com>
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/18657-1b90ccce2b16bdb8@postgresql.org
Backpatch-through: 16
2024-10-20 12:21:12 +09:00
Nathan Bossart
053b6daeb9 Adjust documentation for configuring Linux huge pages.
The present wording about viewing shared_memory_size_in_huge_pages
seems to suggest that the parameter cannot be viewed after startup
at all, whereas the intent is to make it clear that you can't use
"postgres -C" to view this parameter while the server is running.
This commit rephrases this section to remove the ambiguity.

Author: Seino Yuki
Reviewed-by: Michael Paquier, David G. Johnston, Fujii Masao
Discussion: https://postgr.es/m/420584fd274f9ec4f337da55ffb3b790%40oss.nttdata.com
Backpatch-through: 15
2024-10-18 10:20:15 -05:00
Michael Paquier
b8d08aafc0 Fix description of PostgreSQL::Test::Cluster::wait_for_event()
The arguments of the function were listed in an incorrect order in the
description of the routine.  This information can be seen with perldoc.

Issue spotted while working on this area of the code.

Backpatch-through: 17
2024-10-18 13:50:07 +09:00
Thomas Munro
4ac5d33a8b Fix extreme skew detection in Parallel Hash Join.
After repartitioning the inner side of a hash join that would have
exceeded the allowed size, we check if all the tuples from a parent
partition moved to one child partition.  That is evidence that it
contains duplicate keys and later attempts to repartition will also
fail, so we should give up trying to limit memory (for lack of a better
fallback strategy).

A thinko prevented the check from working correctly in partition 0 (the
one that is partially loaded into memory already).  After
repartitioning, we should check for extreme skew if the *parent*
partition's space_exhausted flag was set, not the child partition's.
The consequence was repeated futile repartitioning until per-partition
data exceeded various limits including "ERROR: invalid DSA memory alloc
request size 1811939328", OS allocation failure, or temporary disk space
errors.  (We could also do something about some of those symptoms, but
that's material for separate patches.)

This problem only became likely when PostgreSQL 16 introduced support
for Parallel Hash Right/Full Join, allowing NULL keys into the hash
table.  Repartitioning always leaves NULL in partition 0, no matter how
many times you do it, because the hash value is all zero bits.  That's
unlikely for other hashed values, but they might still have caused
wasted extra effort before giving up.

Back-patch to all supported releases.

Reported-by: Craig Milhiser <craig@milhiser.com>
Reviewed-by: Andrei Lepikhov <lepihov@gmail.com>
Discussion: https://postgr.es/m/CA%2BwnhO1OfgXbmXgC4fv_uu%3DOxcDQuHvfoQ4k0DFeB0Qqd-X-rQ%40mail.gmail.com
2024-10-17 22:10:29 +13:00
Peter Eisentraut
e90d108823 Fix whitespace 2024-10-17 08:42:58 +02:00
Michael Paquier
c06a4746b1 Fix validation of COPY FORCE_NOT_NULL/FORCE_NULL for the all-column cases
This commit adds missing checks for COPY FORCE_NOT_NULL and FORCE_NULL
when applied to all columns via "*".  These options now correctly
require CSV mode and are disallowed in COPY TO, making their behavior
consistent with FORCE_QUOTE.

Some regression tests are added to verify the correct behavior for the
all-columns case, including FORCE_QUOTE, which was not tested.

Backpatch down to 17, where support for the all-column grammar with
FORCE_NOT_NULL and FORCE_NULL has been added.

Author: Joel Jacobson
Reviewed-by: Zhang Mingli
Discussion: https://postgr.es/m/65030d1d-5f90-4fa4-92eb-f5f50389858e@app.fastmail.com
Backpatch-through: 17
2024-10-17 08:45:56 +09:00
Michael Paquier
a30c1ca21c Rewrite some regression queries for option checks with COPY
Some queries in copy2 are there to check various option combinations,
and used "stdin" or "stdout" incompatible with the COPY TO or FROM
clauses combined with them, which was confusing.  This commit rewrites
these queries to use a compatible grammar.

The coverage of the tests is unchanged.  Like the original commit
451d1164b9d0, backpatch down to 16 where these have been introduced.  A
follow-up commit will rely on this area of the tests for a bug fix.

Author: Joel Jacobson
Reviewed-by: Zhang Mingli
Discussion: https://postgr.es/m/65030d1d-5f90-4fa4-92eb-f5f50389858e@app.fastmail.com
Backpatch-through: 16
2024-10-17 07:21:40 +09:00
Tom Lane
b5eef75391 Further refine _SPI_execute_plan's rule for atomic execution.
Commit 2dc1deaea turns out to have been still a brick shy of a load,
because CALL statements executing within a plpgsql exception block
could still pass the wrong snapshot to stable functions within the
CALL's argument list.  That happened because standard_ProcessUtility
forces isAtomicContext to true if IsTransactionBlock is true, which
it always will be inside a subtransaction.  Then ExecuteCallStmt
would think it does not need to push a new snapshot --- but
_SPI_execute_plan didn't do so either, since it thought it was in
nonatomic mode.

The best fix for this seems to be for _SPI_execute_plan to operate
in atomic execution mode if IsSubTransaction() is true, even when the
SPI context as a whole is non-atomic.  This makes _SPI_execute_plan
have the same rules about when non-atomic execution is allowed as
_SPI_commit/_SPI_rollback have about when COMMIT/ROLLBACK are allowed,
which seems appropriately symmetric.  (If anyone ever tries to allow
COMMIT/ROLLBACK inside a subtransaction, this would all need to be
rethought ... but I'm unconvinced that such a thing could be logically
consistent at all.)

For further consistency, also check IsSubTransaction() in
SPI_inside_nonatomic_context.  That does not matter for its
one present-day caller StartTransaction, which can't be reached
inside a subtransaction.  But if any other callers ever arise,
they'd presumably want this definition.

Per bug #18656 from Alexander Alehin.  Back-patch to all
supported branches, like previous fixes in this area.

Discussion: https://postgr.es/m/18656-cade1780866ef66c@postgresql.org
2024-10-16 17:36:29 -04:00
Masahiko Sawada
eef9cc4dc2 Reduce memory block size for decoded tuple storage to 8kB.
Commit a4ccc1cef introduced the Generation Context and modified the
logical decoding process to use a Generation Context with a fixed
block size of 8MB for storing tuple data decoded during logical
decoding (i.e., rb->tup_context). Several reports have indicated that
the logical decoding process can be terminated due to
out-of-memory (OOM) situations caused by excessive memory usage in
rb->tup_context.

This issue can occur when decoding a workload involving several
concurrent transactions, including a long-running transaction that
modifies tuples. By design, the Generation Context does not free a
memory block until all chunks within that block are
released. Consequently, if tuples modified by the long-running
transaction are stored across multiple memory blocks, these blocks
remain allocated until the long-running transaction completes, leading
to substantial memory fragmentation. The memory usage during logical
decoding, tracked by rb->size, does not account for memory
fragmentation, resulting in potentially much higher memory consumption
than the value of the logical_decoding_work_mem parameter.

Various improvement strategies were discussed in the relevant
thread. This change reduces the block size of the Generation Context
used in rb->tup_context from 8MB to 8kB. This modification
significantly decreases the likelihood of substantial memory
fragmentation occurring and is relatively straightforward to
backport. Performance testing across multiple platforms has confirmed
that this change will not introduce any performance degradation that
would impact actual operation.

Backport to all supported branches.

Reported-by: Alex Richman, Michael Guissine, Avi Weinberg
Reviewed-by: Amit Kapila, Fujii Masao, David Rowley
Tested-by: Hayato Kuroda, Shlok Kyal
Discussion: https://postgr.es/m/CAD21AoBTY1LATZUmvSXEssvq07qDZufV4AF-OHh9VD2pC0VY2A%40mail.gmail.com
Backpatch-through: 12
2024-10-16 12:08:02 -07:00
Amit Langote
064e040085 Fix typo in comment of transformJsonAggConstructor()
An oversight of 3a8a1f3254b.

Reported-by: Tender Wang <tndrwang@gmail.com>
Author: Tender Wang <tndrwang@gmail.com>
Backpatch-through: 16
2024-10-16 20:36:46 +09:00
Nathan Bossart
8aaca07851 Add type cast to foreach_internal's loop variable.
C++ requires explicitly casting void pointers to the appropriate
pointer type, which means the foreach_ptr macro cannot be used in
C++ code without this change.

Author: Jelte Fennema-Nio
Reviewed-by: Bruce Momjian
Discussion: https://postgr.es/m/CAGECzQSYG3QfHrc-rOk2KbnB9iJOd7Qu-Xii1s-GTA%3D3JFt49Q%40mail.gmail.com
Backpatch-through: 17
2024-10-15 16:20:49 -05:00
Michael Paquier
8a6170860c psql: Fix \watch when using interval values less than 1ms
Attempting to use an interval of time less than 1ms would cause \watch
to hang.  This was confusing, so let's change the logic so as an
interval lower than 1ms behaves the same as 0.

Comments are added to mention that the internals of do_watch() had
better rely on "sleep_ms", the interval value in milliseconds.  While on
it, this commit adds a test to check the behavior of interval values
less than 1ms.

\watch hanging for interval values less than 1ms existed before
6f9ee74d45aa, that has changed the code to support an interval value of
0.

Reported-by: Heikki Linnakangas
Author: Andrey M. Borodin, Michael Paquier
Discussion: https://postgr.es/m/88445e0e-3156-4b9d-afae-9a1a7b1631f6@iki.fi
Backpatch-through: 16
2024-10-14 12:27:57 +09:00
Tom Lane
54889ea64b Correctly identify which EC members are computable at a plan node.
find_computable_ec_member() had the wrong mental model of what
its primary caller prepare_sort_from_pathkeys() would do with
the selected EquivalenceClass member expression.  We will not
compute the EC expression in a plan node atop the one returning
the passed-in targetlist; rather, the EC expression will be
computed as an additional column of that targetlist.  So any
Var or quasi-Var used in the given tlist is also available to the
EC expression.  In simple cases this makes no difference because
the given tlist is just a list of Vars or quasi-Vars --- but if
we are considering an appendrel member produced by flattening
a UNION ALL, the tlist may contain expressions, resulting in
failure to match and a "could not find pathkey item to sort"
error.

To fix, we can flatten both the tlist and the EC members with
pull_var_clause(), and then just check for subset-ness, so
that the code is actually shorter than before.

While this bug is quite old, the present patch only works back to
v13.  We could possibly make it work in v12 by back-patching parts
of 375398244.  On the whole though I don't like the risk/reward
ratio of that idea.  v12's final release is next month, meaning
there would be no chance to correct matters if the patch causes a
regression.  Since this failure has escaped notice for 14 years,
it's likely nobody will hit it in the field with v12.

Per bug #18652 from Alexander Lakhin.

Andrei Lepikhov and Tom Lane

Discussion: https://postgr.es/m/18652-deaa782ebcca85d1@postgresql.org
2024-10-12 14:56:08 -04:00
Jeff Davis
ff33df26c2 Fix missed case for builtin collation provider.
A missed check for the builtin collation provider could result in
falling through to call isalpha().

This does not appear to have practical consequences because it only
happens for characters in the ASCII range. Regardless, the builtin
provider should not be calling libc functions, so backpatch.

Discussion: https://postgr.es/m/1bd5a0a5192f82c22ee7527e825b18ab0028b2c7.camel@j-davis.com
Backpatch-through: 17
2024-10-11 16:59:10 -07:00
Bruce Momjian
912d15cba5 doc PG 17 relnotes: clarify pg_upgrade and logical slot preserv.
Reported-by: Amit Kapila

Discussion: https://postgr.es/m/CAA4eK1+bChgccySmcm0LbvkmBDJ3ufsLneF4iNa_aZ7t2P6=8w@mail.gmail.com

Backpatch-through: 17 only
2024-10-09 23:05:50 -04:00
Bruce Momjian
7e059fb6c0 doc PG 17 relnotes: add missing commands for safe search path
Reported-by: Yugo NAGATA

Discussion: https://postgr.es/m/20240926141921.57d0b430fa53ac4389344847@sraoss.co.jp

Backpatch-through: 17 only
2024-10-09 22:58:03 -04:00
Tom Lane
a3c4a91f1e Avoid crash in estimate_array_length with null root pointer.
Commit 9391f7152 added a "PlannerInfo *root" parameter to
estimate_array_length, but failed to consider the possibility that
NULL would be passed for that, leading to a null pointer dereference.

We could rectify the particular case shown in the bug report by fixing
simplify_function/inline_function to pass through the root pointer.
However, as long as eval_const_expressions is documented to accept
NULL for root, similar hazards would remain.  For now, let's just do
the narrow fix of hardening estimate_array_length to not crash.
Its behavior with NULL root will be the same as it was before
9391f7152, so this is not too awful.

Per report from Fredrik Widlert (via Paul Ramsey).  Back-patch to v17
where 9391f7152 came in.

Discussion: https://postgr.es/m/518339E7-173E-45EC-A0FF-9A4A62AA4F40@cleverelephant.ca
2024-10-09 17:07:53 -04:00
Daniel Gustafsson
647e76c0ff doc: Fix mention of AT LOCAL in release notes
The release notes accidentally spelled AT LOCAL as AS LOCAL.

Reported-by: Takatsuka Haruka <harukat@sraoss.co.jp>
Discussion: https://postgr.es/m/18649-4d146d83086d4e7c@postgresql.org
2024-10-09 10:13:20 +02:00
Daniel Gustafsson
c5b9097255 Remove incorrect function import from pgindent
Commit 149ac7d4559 which re-implemented pgindent in Perl explicitly
imported the devnull function from File::Spec, but the module does
not export anything.  In recent versions of Perl calling a missing
import function cause a warning, which combined with warnings being
fatal cause pgindent to error out.

Backpatch to all supported versions.

Author: Erik Wienhold <ewie@ewie.name>
Reviewed-by: Andrew Dunstan <andrew@dunslane.net>
Reviewed-by: Daniel Gustafsson <daniel@yesql.se>
Discusson: https://postgr.es/m/2372cd74-11b0-46f9-b28e-8f9627215d19@ewie.name
Backpatch-through: v12
2024-10-09 09:34:34 +02:00
Amit Kapila
c4b8a916f8 Stabilize the test added by commit 022564f60c.
The test was unstable in branches 14 and 15 as we were relying on the
number of changes in the table having a toast column to start streaming.
On branches >= 16, we have a GUC debug_logical_replication_streaming which
can stream each change, so the test was stable in those branches.

Change the test to use PREPARE TRANSACTION as that should make the result
consistent and test the code changed in 022564f60c.

Reported-by: Daniel Gustafsson as per buildfarm
Author: Hou Zhijie, Amit Kapila
Backpatch-through: 14
Discussion: https://postgr.es/m/8C2F86AA-981E-4803-B14D-E264C0255330@yesql.se
2024-10-08 12:13:28 +05:30
Jeff Davis
2fe4167bc6 Fix search_path cache initialization.
The cache needs to be available very early, so don't rely on
InitializeSearchPath() to initialize the it.

Reported-by: Murat Efendioğlu
Discussion: https://postgr.es/m/CACbCzujQ4zS8MM1bx-==+tr+D3Hk5G1cjN4XkUQ+Q=cEpwhzqg@mail.gmail.com
Backpatch-through: 17
2024-10-07 17:54:19 -07:00
Bruce Momjian
a8b2402041 doc PG 17 relnotes: move adminpack item to incompatibilities
Reported-by: Laurenz Albe

Discussion: https://postgr.es/m/1e1aa41dd5b0851b5c0d328a50b1ab598bd59419.camel@cybertec.at

Backpatch-through: 17 only
2024-10-07 20:11:25 -04:00
Nathan Bossart
5bd26e6527 vacuumdb: Schema-qualify operator in catalog query's WHERE clause.
Commit 1ab67c9dfa, which modified this catalog query so that it
doesn't return temporary relations, forgot to schema-qualify the
operator.  A comment earlier in the function implores us to fully
qualify everything in the query:

	 * Since we execute the constructed query with the default search_path
	 * (which could be unsafe), everything in this query MUST be fully
	 * qualified.

This commit fixes that.  While at it, add a newline for consistency
with surrounding code.

Reviewed-by: Noah Misch
Discussion: https://postgr.es/m/ZwQJYcuPPUsF0reU%40nathan
Backpatch-through: 12
2024-10-07 16:49:20 -05:00
Nathan Bossart
a356d23fd3 Fix Y2038 issues with MyStartTime.
Several places treat MyStartTime as a "long", which is only 32 bits
wide on some platforms.  In reality, MyStartTime is a pg_time_t,
i.e., a signed 64-bit integer.  This will lead to interesting bugs
on the aforementioned systems in 2038 when signed 32-bit integers
are no longer sufficient to store Unix time (e.g., "pg_ctl start"
hanging).  To fix, ensure that MyStartTime is handled as a 64-bit
value everywhere.  (Of course, users will need to ensure that
time_t is 64 bits wide on their system, too.)

Co-authored-by: Max Johnson
Discussion: https://postgr.es/m/CO1PR07MB905262E8AC270FAAACED66008D682%40CO1PR07MB9052.namprd07.prod.outlook.com
Backpatch-through: 12
2024-10-07 13:51:03 -05:00
Amit Kapila
9181077590 Fix fetching default toast value during decoding of in-progress transactions.
During logical decoding of in-progress transactions, we perform the toast
table scan while fetching the default toast value for an attribute. We
forgot to initialize the flag during this scan to indicate that the system
table scan is in progress. We need this flag to ensure that during logical
decoding we never directly access the tableam or heap APIs because we check
for concurrent aborts only in systable_* APIs.

Reported-by: Alexander Lakhin
Author: Takeshi Ideriha, Hou Zhijie
Reviewed-by: Amit Kapila, Hou Zhijie
Backpatch-through: 14
Discussion: https://postgr.es/m/18641-6687273b7f15269d@postgresql.org
2024-10-07 15:15:05 +05:30
Tom Lane
3daeb539a6 Ignore not-yet-defined Portals in pg_cursors view.
pg_cursor() supposed that any Portal it finds in the hash table must
have sourceText set up, but there's an edge case where that is not so.
A newly-created Portal has sourceText = NULL, and that doesn't change
until PortalDefineQuery is called.  In SPI_cursor_open_internal,
we perform GetCachedPlan between CreatePortal and PortalDefineQuery,
and it's possible for user-defined code to execute during that
planning and cause a fetch from the pg_cursors view, resulting in a
null-pointer-dereference crash.  (It looks like the same could happen
in exec_bind_message, but I've not tried to provoke a failure there.)

I considered trying to fix this by setting sourceText sooner, but
there may be instances of this same calling pattern in extensions,
and we couldn't be sure they'd get the memo promptly.  It seems
better to redefine pg_cursor as not showing Portals that have
not yet had PortalDefineQuery called on them, which we can do by
just skipping them if sourceText is still NULL.

(Before a1c692358, pg_cursor would instead return a row with NULL
in the statement column.  We could revert to that behavior but it
doesn't really seem like a better definition, especially since our
documentation doesn't suggest that the column could be NULL.)

Per report from PetSerAl.  Back-patch to all supported branches.

Discussion: https://postgr.es/m/CAKygsHTBXLXjwV43kpZa+Cs+XTiaeeJiZdL4cPBm9f4MTdw7wg@mail.gmail.com
2024-10-06 16:03:48 -04:00
Tom Lane
fee8cb9473 Use generateClonedIndexStmt to propagate CREATE INDEX to partitions.
When instantiating an existing partitioned index for a new child
partition, we use generateClonedIndexStmt to build a suitable
IndexStmt to pass to DefineIndex.  However, when DefineIndex needs
to recurse to instantiate a newly created partitioned index on an
existing child partition, it was doing copyObject on the given
IndexStmt and then applying a bunch of ad-hoc fixups.  This has
a number of problems, primarily that it implies fresh lookups of
referenced objects such as opclasses and collations.  Since commit
2af07e2f7 caused DefineIndex to restrict search_path internally, those
lookups could fail or deliver different results than the original one.
We can avoid those problems and save a few dozen lines of code by
using generateClonedIndexStmt in this code path too.

Another thing this fixes is incorrect propagation of parent-index
comments to child indexes (because the copyObject approach copies
the idxcomment field while generateClonedIndexStmt doesn't).  I had
noticed this in connection with commit c01eb619a, but not run the
problem to ground.

I'm tempted to back-patch this further than v17, but the only thing
it's known to fix in older branches is the comment issue, which is
pretty minor and doesn't seem worth the risk of introducing new
issues in stable branches.  (If anyone does care about that,
clearing idxcomment in the copied IndexStmt would be a safer fix.)

Per bug #18637 from usamoi.  Back-patch to v17 where the search_path
change came in.

Discussion: https://postgr.es/m/18637-f51e314546e3ba2a@postgresql.org
2024-10-05 14:46:44 -04:00
Thomas Munro
9c7acc3330 Reject non-ASCII locale names.
Commit bf03cfd1 started scanning all available BCP 47 locale names on
Windows.  This caused an abort/crash in the Windows runtime library if
the default locale name contained non-ASCII characters, because of our
use of the setlocale() save/restore pattern with "char" strings.  After
switching to another locale with a different encoding, the saved name
could no longer be understood, and setlocale() would abort.

"Turkish_Türkiye.1254" is the example from recent reports, but there are
other examples of countries and languages with non-ASCII characters in
their names, and they appear in Windows' (old style) locale names.

To defend against this:

1.  In initdb, reject non-ASCII locale names given explicity on the
command line, or returned by the operating system environment with
setlocale(..., ""), or "canonicalized" by the operating system when we
set it.

2.  In initdb only, perform the save-and-restore with Windows'
non-standard wchar_t variant of setlocale(), so that it is not subject
to round trip failures stemming from char string encoding confusion.

3.  In the backend, we don't have to worry about the save-and-restore
problem because we have already vetted the defaults, so we just have to
make sure that CREATE DATABASE also rejects non-ASCII names in any new
databases.  SET lc_XXX doesn't suffer from the problem, but the ban
applies to it too because it uses check_locale().  CREATE COLLATION
doesn't suffer from the problem either, but it doesn't use
check_locale() so it is not included in the new ban for now, to minimize
the change.

Anyone who encounters the new error message should either create a new
duplicated locale with an ASCII-only name using Windows Locale Builder,
or consider using BCP 47 names like "tr-TR".  Users already couldn't
initialize a cluster with "Turkish_Türkiye.1254" on PostgreSQL 16+, but
the new failure mode is an error message that explains why, instead of a
crash.

Back-patch to 16, where bf03cfd1 landed.  Older versions are affected
in theory too, but only 16 and later are causing crash reports.

Reviewed-by: Andrew Dunstan <andrew@dunslane.net> (the idea, not the patch)
Reported-by: Haifang Wang (Centific Technologies Inc) <v-haiwang@microsoft.com>
Discussion: https://postgr.es/m/PH8PR21MB3902F334A3174C54058F792CE5182%40PH8PR21MB3902.namprd21.prod.outlook.com
2024-10-05 13:54:35 +13:00
Dean Rasheed
34ae54af92 Fix wrong varnullingrels error for MERGE WHEN NOT MATCHED BY SOURCE.
If a MERGE command contains WHEN NOT MATCHED BY SOURCE actions, the
source relation appears on the outer side of the join. Thus, any Vars
referring to the source in the merge join condition, actions, and
RETURNING list should be marked as nullable by the join, since they
are used in the ModifyTable node above the join. Note that this only
applies to the copy of join condition used in the executor to
distinguish MATCHED from NOT MATCHED BY SOURCE cases. Vars in the
original join condition, inside the join node itself, should not be
marked.

Failure to correctly mark these Vars led to a "wrong varnullingrels"
error in the final stage of query planning, in some circumstances. We
happened to get away without this in all previous tests, since they
all involved a ModifyTable node directly on top of the join node, so
that the top plan targetlist coincided with the output of the join,
and the varnullingrels check was more lax. However, if another plan
node, such as a one-time filter Result node, gets inserted between the
ModifyTable node and the join node, then a stricter check is applied,
which fails.

Per bug #18634 from Alexander Lakhin. Thanks to Tom Lane and Richard
Guo for review and analysis.

Back-patch to v17, where WHEN NOT MATCHED BY SOURCE support was added
to MERGE.

Discussion: https://postgr.es/m/18634-db5299c937877f2b%40postgresql.org
2024-10-03 13:45:37 +01:00
Dean Rasheed
d7d297f844 Fix incorrect non-strict join recheck in MERGE WHEN NOT MATCHED BY SOURCE.
If a MERGE command contains WHEN NOT MATCHED BY SOURCE actions, the
merge join condition is used by the executor to distinguish MATCHED
from NOT MATCHED BY SOURCE cases. However, this qual is executed using
the output from the join subplan node, which nulls the output from the
source relation in the not matched case, and so the result may be
incorrect if the join condition is "non-strict" -- for example,
something like "src.col IS NOT DISTINCT FROM tgt.col".

Fix this by enhancing the join recheck condition with an additional
"src IS NOT NULL" check, so that it does the right thing when
evaluated using the output from the join subplan.

Noted by Tom Lane while investigating bug #18634 from Alexander
Lakhin.

Back-patch to v17, where WHEN NOT MATCHED BY SOURCE support was added
to MERGE.

Discussion: https://postgr.es/m/18634-db5299c937877f2b%40postgresql.org
2024-10-03 12:50:38 +01:00
Tom Lane
c7a201053e Parse libpq's "keepalives" option more like other integer options.
Use pqParseIntParam (nee parse_int_param) instead of using strtol
directly.  This allows trailing whitespace, which the previous coding
didn't, and makes the spelling of the error message consistent with
other similar cases.

This seems to be an oversight in commit e7a221797, which introduced
parse_int_param.  That fixed places that were using atoi(), but missed
this place which was randomly using strtol() instead.

Ordinarily I'd consider this minor cleanup not worth back-patching.
However, it seems that ecpg assumes it can add trailing whitespace
to URL parameters, so that use of the keepalives option fails in
that context.  Perhaps that's worth improving as a separate matter.
In the meantime, back-patch this to all supported branches.

Yuto Sasaki (some further cleanup by me)

Discussion: https://postgr.es/m/TY2PR01MB36286A7B97B9A15793335D18C1772@TY2PR01MB3628.jpnprd01.prod.outlook.com
2024-10-02 17:30:36 -04:00
Michael Paquier
97dccefc36 doc: Clarify name of files generated by pg_waldump --save-fullpage
The fork name is always separated with the block number by an underscore
in the names of the files generated, but the docs stuck them together
without a separator, which was confusing.

Author: Christoph Berg
Discussion: https://postgr.es/m/ZvxtSLiix9eceMRM@msg.df7cb.de
Backpatch-through: 16
2024-10-02 11:12:45 +09:00
Tatsuo Ishii
a94d5b3728 Doc: replace unnecessary non-breaking space with ordinal space.
There were unnecessary non-breaking spaces (nbsp, U+00A0, 0xc2a0 in
UTF-8) in the docs.  This commit replaces them with ASCII spaces
(0x20).

config.sgml is backpatched through 17.
ref/drop_extension.sgml is backpatched through 13.

Discussion: https://postgr.es/m/20240930.153404.202479334310259810.ishii%40postgresql.org
Reviewed-by: Yugo Nagata, Daniel Gustafsson
Backpatch-through: 17, 13
2024-10-01 16:26:35 +09:00
Michael Paquier
f250cb29d9 Fix race condition in COMMIT PREPARED causing orphaned 2PC files
COMMIT PREPARED removes on-disk 2PC files near its end, but the state
checked if a file is on-disk or not gets read from shared memory while
not holding the two-phase state lock.

Because of that, there was a small window where a second backend doing a
PREPARE TRANSACTION could reuse the GlobalTransaction put back into the
2PC free list by the COMMIT PREPARED, overwriting the "ondisk" flag read
afterwards by the COMMIT PREPARED to decide if its on-disk two-phase
state file should be removed, preventing the file deletion.

This commit fixes this issue so as the "ondisk" flag in the
GlobalTransaction is read while holding the two-phase state lock, not
from shared memory after its entry has been added to the free list.

Orphaned two-phase state files flushed to disk after a checkpoint are
discarded at the beginning of recovery.  However, a truncation of
pg_xact/ would make the startup process issue a FATAL when it cannot
read the SLRU page holding the state of the transaction whose 2PC file
was orphaned, which is a necessary step to decide if the 2PC file should
be removed or not.  Removing manually the file would be necessary in
this case.

Issue introduced by effe7d9552dd, so backpatch all the way down.

Mea culpa.

Author: wuchengwen
Discussion: https://postgr.es/m/tencent_A7F059B5136A359625C7B2E4A386B3C3F007@qq.com
Backpatch-through: 12
2024-10-01 15:44:07 +09:00
Tom Lane
6596a8c860 Remove incorrect entries in pg_walsummary's getopt_long call.
For some reason this listed "-f" and "-w" as valid switches, though
the code doesn't implement any such thing nor do the docs mention
them.  The effect of this was that if you tried to use one of these
switches, you'd get an unhelpful error message.

Yusuke Sugie

Discussion: https://postgr.es/m/68e72a2a70f4d84c1c7847b13bcdaef8@oss.nttdata.com
2024-09-30 12:07:03 -04:00
Fujii Masao
77f1546819 reindexdb: Skip reindexing temporary tables and indexes.
Reindexing temp tables or indexes of other sessions is not allowed.
However, reindexdb in parallel mode previously listed them as
the objects to process, leading to failures.

This commit ensures reindexdb in parallel mode skips temporary tables
and indexes by adding a condition based on the relpersistence column
in pg_class to the object listing queries, preventing these issues.

Note that this commit does not affect reindexdb when temporary tables
or indexes are explicitly specified using the -t or -j options;
reindexdb in that case still does not skip them and can cause an error.

Back-patch to v13 where parallel mode was introduced in reindexdb.

Author: Fujii Masao
Reviewed-by: Michael Paquier
Discussion: https://postgr.es/m/5f37ee56-14fb-44fe-9150-9eb97e10538b@oss.nttdata.com
2024-09-30 11:15:56 +09:00
Noah Misch
da99df15c2 Remove NULL dereference from RenameRelationInternal().
Defect in last week's commit aac2c9b4fde889d13f859c233c2523345e72d32b,
per Coverity.  Reaching this would need catalog corruption.  Back-patch
to v12, like that commit.
2024-09-29 15:54:28 -07:00
Noah Misch
4aad471688 Avoid 037_invalid_database.pl hang under debug_discard_caches.
Back-patch to v12 (all supported versions).
2024-09-27 15:29:00 -07:00
Nathan Bossart
18cea252ac doc: Note that CREATE MATERIALIZED VIEW restricts search_path.
Since v17, CREATE MATERIALIZED VIEW has set search_path to
"pg_catalog, pg_temp" while running the query.  The docs for the
other commands that restrict search_path mention it, but the page
for CREATE MATERIALIZED VIEW does not.  Fix that.

Oversight in commit 4b74ebf726.

Author: Yugo Nagata
Reviewed-by: Jeff Davis
Discussion: https://postgr.es/m/20240805160502.d2a4975802a832b1e04afb80%40sraoss.co.jp
Backpatch-through: 17
2024-09-27 16:21:21 -05:00
Michael Paquier
1532599a85 Fix incorrect memory access in VACUUM FULL with invalid toast indexes
An invalid toast index is skipped in reindex_relation().  These would be
remnants of a failed REINDEX CONCURRENTLY and they should never been
rebuilt as there can only be one valid toast index at a time.

REINDEX_REL_SUPPRESS_INDEX_USE, used by CLUSTER and VACUUM FULL, needs
to maintain a list of the indexes being processed.  The list of indexes
is retrieved from the relation cache, and includes invalid indexes.  The
code has missed that invalid toast indexes are ignored in
reindex_relation() as this leads to a hard failure in reindex_index(),
and they were left in the reindex pending list, making the list
inconsistent when rechecked.  The incorrect memory access was happening
when scanning pg_class for the refresh of pg_database.datfrozenxid, when
doing a scan of pg_class.

This issue exists since REINDEX CONCURRENTLY exists, where invalid toast
indexes can exist, so backpatch all the way down.

Reported-by: Alexander Lakhin
Author: Tender Wang
Discussion: https://postgr.es/m/18630-9aed99c38830657d@postgresql.org
Backpatch-through: 12
2024-09-27 09:40:14 +09:00
Tom Lane
3e8c92c956 Doc: InitPlans aren't parallel-restricted any more.
Commit e08d74ca1 removed that restriction, but missed updating
the documentation about it.  Noted by Egor Rogov.

Discussion: https://postgr.es/m/cdc8f87b-a378-4e22-6d29-40ae32dd97d1@postgrespro.ru
2024-09-26 10:37:51 -04:00
Nathan Bossart
4e0864af16 Remove extra whitespace in pg_upgrade status message.
There's no need to add another level of indentation to this status
message.  pg_log() will put it in the right place.

Oversight in commit 347758b120.

Reviewed-by: Daniel Gustafsson
Discussion: https://postgr.es/m/ZunW7XHLd2uTts4f%40nathan
Backpatch-through: 17
2024-09-25 11:18:56 -05:00
Michael Paquier
85cb21df67 vacuumdb: Skip temporary tables in query to build list of relations
Running vacuumdb with a non-superuser while another user has created a
temporary table would lead to a mid-flight permission failure,
interrupting the operation.  vacuum_rel() skips temporary relations of
other backends, and it makes no sense for vacuumdb to know about these
relations, so let's switch it to ignore temporary relations entirely.

Adding a qual in the query based on relpersistence simplifies the
generation of its WHERE clause in vacuum_one_database(), per se the
removal of "has_where".

Author: VaibhaveS, Michael Paquier
Reviewed-by: Fujii Masao
Discussion: https://postgr.es/m/CAM_eQjwfAR=y3G1fGyS1U9FTmc+FyJm9amNfY2QCZBnDDbNPZg@mail.gmail.com
Backpatch-through: 12
2024-09-25 14:44:50 +09:00
Noah Misch
3b7a689e1a For inplace update durability, make heap_update() callers wait.
The previous commit fixed some ways of losing an inplace update.  It
remained possible to lose one when a backend working toward a
heap_update() copied a tuple into memory just before inplace update of
that tuple.  In catalogs eligible for inplace update, use LOCKTAG_TUPLE
to govern admission to the steps of copying an old tuple, modifying it,
and issuing heap_update().  This includes MERGE commands.  To avoid
changing most of the pg_class DDL, don't require LOCKTAG_TUPLE when
holding a relation lock sufficient to exclude inplace updaters.
Back-patch to v12 (all supported versions).  In v13 and v12, "UPDATE
pg_class" or "UPDATE pg_database" can still lose an inplace update.  The
v14+ UPDATE fix needs commit 86dc90056dfdbd9d1b891718d2e5614e3e432f35,
and it wasn't worth reimplementing that fix without such infrastructure.

Reviewed by Nitin Motiani and (in earlier versions) Heikki Linnakangas.

Discussion: https://postgr.es/m/20231027214946.79.nmisch@google.com
2024-09-24 15:25:22 -07:00
Noah Misch
fd27b878c2 Fix data loss at inplace update after heap_update().
As previously-added tests demonstrated, heap_inplace_update() could
instead update an unrelated tuple of the same catalog.  It could lose
the update.  Losing relhasindex=t was a source of index corruption.
Inplace-updating commands like VACUUM will now wait for heap_update()
commands like GRANT TABLE and GRANT DATABASE.  That isn't ideal, but a
long-running GRANT already hurts VACUUM progress more just by keeping an
XID running.  The VACUUM will behave like a DELETE or UPDATE waiting for
the uncommitted change.

For implementation details, start at the systable_inplace_update_begin()
header comment and README.tuplock.  Back-patch to v12 (all supported
versions).  In back branches, retain a deprecated heap_inplace_update(),
for extensions.

Reported by Smolkin Grigory.  Reviewed by Nitin Motiani, (in earlier
versions) Heikki Linnakangas, and (in earlier versions) Alexander
Lakhin.

Discussion: https://postgr.es/m/CAMp+ueZQz3yDk7qg42hk6-9gxniYbp-=bG2mgqecErqR5gGGOA@mail.gmail.com
2024-09-24 15:25:21 -07:00
Noah Misch
f33bf1c7d5 Warn if LOCKTAG_TUPLE is held at commit, under debug_assertions.
The current use always releases this locktag.  A planned use will
continue that intent.  It will involve more areas of code, making unlock
omissions easier.  Warn under debug_assertions, like we do for various
resource leaks.  Back-patch to v12 (all supported versions), the plan
for the commit of the new use.

Reviewed by Heikki Linnakangas.

Discussion: https://postgr.es/m/20240512232923.aa.nmisch@google.com
2024-09-24 15:25:21 -07:00
Tom Lane
923a71584f Fix psql describe commands' handling of ACL columns for old servers.
Commit d1379ebf4 carelessly broke printACLColumn for pre-9.4 servers,
by using the cardinality() function which we introduced in 9.4.
We expect psql's describe-related commands to work back to 9.2, so
this is bad.  Use the longstanding array_length() function instead.

Per report from Christoph Berg.  Back-patch to v17.

Discussion: https://postgr.es/m/ZvLXYglRS6hMMhtr@msg.df7cb.de
2024-09-24 17:21:38 -04:00
Tom Lane
d7ec59a63d Stamp 17.0. 2024-09-23 16:02:53 -04:00
Peter Eisentraut
29d483fb33 Translation updates
Source-Git-URL: https://git.postgresql.org/git/pgtranslation/messages.git
Source-Git-Hash: 4b069f67b5be4227eb620a74c9900f079f2e59f4
2024-09-23 12:06:47 +02:00
Tom Lane
64b61fa5d7 Doc: update 17.0 release date.
Also some trivial copy-editing.
2024-09-20 16:19:34 -04:00
Bruce Momjian
1d7cef2b60 doc PG 17 relnotes: add major features list
Reported-by: Tom Lane

Discussion: https://postgr.es/m/d1748552-31f5-4f80-937b-767b5f7d8324@postgresql.org

Author: Jonathan Katz

Backpatch-through: 17 only
2024-09-20 16:01:34 -04:00
Tom Lane
a47ad3a42d Doc: explain how to test ADMIN privilege with pg_has_role().
This has always been possible, but the syntax is a bit obscure,
and our user-facing docs were not very helpful.  Spell it out
more clearly.

Per complaint from Dominique Devienne.  Back-patch to
all supported branches.

Discussion: https://postgr.es/m/CAFCRh-8JNEy+dV4SXFOrWca50u+d=--TO4cq=+ac1oBtfJy4AA@mail.gmail.com
2024-09-20 15:56:34 -04:00
Peter Geoghegan
fb4f5e58af Fix nbtree pgstats accounting with parallel scans.
Commit 5bf748b8, which enhanced nbtree ScalarArrayOp execution, made
parallel index scans work with the new design for arrays via explicit
scheduling of primitive index scans.  Under this scheme a parallel index
scan with array keys will perform the same number of index descents as
an equivalent serial index scan (barring corner cases where an
individual parallel worker discovers that it can advance the scan's
array keys without anybody needing to perform another descent of the
index to get to the relevant page on the leaf level).

Despite all this, the pgstats accounting wasn't updated; it continued to
increment the total number of index scans for the rel once per _bt_first
call, no matter the details.  As a result, the number of (primitive)
index scans could be over-counted during parallel scans.

To fix, delay incrementing the count of index scans until after we've
established that another descent of the index (using either _bt_search
or _bt_endpoint) is required.  That way pg_stat_user_tables.idx_scan
always advances in the same way, regardless of whether or not the scan
makes use of parallelism.

Oversight in commit 5bf748b8, which enhanced nbtree ScalarArrayOp
execution.

Author: Peter Geoghegan <pg@bowt.ie>
Reviewed-By: Tomas Vondra <tomas@vondra.me>
Discussion: https://postgr.es/m/CAH2-Wz=E7XrkvscBN0U6V81NK3Q-dQOmivvbEsjG-zwEfDdFpg@mail.gmail.com
Discussion: https://postgr.es/m/CAH2-WzkRqvaqR2CTNqTZP0z6FuL4-3ED6eQB0yx38XBNj1v-4Q@mail.gmail.com
Backpatch: 17-, where nbtree SAOP execution was enhanced.
2024-09-20 14:06:30 -04:00
Bruce Momjian
a24cd4bf5d doc PG relnotes: remove warning about commit links in PDF build
Make paragraph empty instead of removing it.

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

Backpatch-through: 12
2024-09-19 18:05:22 -04:00
Bruce Momjian
ff25193e56 doc PG relnotes: document "Unresolved ID reference found" cause
Backpatch-through: 12
2024-09-19 12:01:59 -04:00
Bruce Momjian
95fba23317 doc PG relnotes: rename commit link paragraph for clarity
FYI, during PDF builds, this link type generates a "Unresolved ID
reference found" warning because it is suppressed from the PDF output.

Backpatch-through: 12
2024-09-19 09:47:22 -04:00
Bruce Momjian
681bbd07cc Improve Perl script which adds commit links to release notes
Reported-by: Andrew Dunstan

Discussion: https://postgr.es/m/b2465837-56df-4794-a0b5-5e6ed44ed870@dunslane.net

Author: Andrew Dunstan

Backpatch-through: 12
2024-09-19 08:45:32 -04:00
Michael Paquier
b0ae6db208 psql: Fix memory leak with repeated calls of \bind
Calling \bind repeatedly would cause the memory allocated for the list
of bind parameters to be leaked after each call, as the list is reset
when beginning a single call.

This issue is fixed by making the cleanup of the bind parameter list
more aggressive, refactoring it into a single routine called after
processing a query and before running an individual \bind.

HEAD required more surgery and has been fixed by 87eeadaea143.  Issue
introduced by 5b66de3433e2.

Reported-by: Anthonin Bonnefoy
Discussion: https://postgr.es/m/2e5b89af-a351-ff0a-000c-037ac28314ab@gmail.com
Backpatch-through: 16
2024-09-19 16:25:07 +09:00
Bruce Momjian
19b389c608 doc PG relnotes: add paragraph explaining the section symbol
And suppress the symbol in print mode, where the section symbol does not
appear.

Discussion: https://postgr.es/m/ZuobILbmGGetxEg5@momjian.us

Backpatch-through: 12
2024-09-18 17:13:19 -04:00
Bruce Momjian
120f883d79 doc PG relnotes: no relnote footnotes for commit links in PDF
In print output, there are too many commit links for footnotes in the
release notes to be useful.

Reported-by: Tom Lane

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

Backpatch-through: 12
2024-09-18 16:34:52 -04:00
Fujii Masao
fa3a022136 docs: Improve the description of num_timed column in pg_stat_checkpointer.
The previous documentation stated that num_timed reflects the number of
scheduled checkpoints performed. However, checkpoints may be skipped
if the server has been idle, and num_timed counts both skipped and completed
checkpoints. This commit clarifies the description to make it clear that
the counter includes both skipped and completed checkpoints.

Back-patch to v17 where pg_stat_checkpointer was added.

Author: Fujii Masao
Reviewed-by: Alexander Korotkov
Discussion: https://postgr.es/m/9ea77f40-818d-4841-9dee-158ac8f6e690@oss.nttdata.com
2024-09-19 02:16:00 +09:00
Peter Eisentraut
633b609e1c Update list of acknowledgments in release notes
current through 2370582ab14
2024-09-18 09:08:31 +02:00
Noah Misch
2370582ab1 Don't enter parallel mode when holding interrupts.
Doing so caused the leader to hang in wait_event=ParallelFinish, which
required an immediate shutdown to resolve.  Back-patch to v12 (all
supported versions).

Francesco Degrassi

Discussion: https://postgr.es/m/CAC-SaSzHUKT=vZJ8MPxYdC_URPfax+yoA1hKTcF4ROz_Q6z0_Q@mail.gmail.com
2024-09-17 19:54:25 -07:00
Michael Paquier
7db9bfc1f7 Add missing query ID reporting in extended query protocol
This commit adds query ID reports for two code paths when processing
extended query protocol messages:
- When receiving a bind message, setting it to the first Query retrieved
from a cached cache.
- When receiving an execute message, setting it to the first PlannedStmt
stored in a portal.

An advantage of this method is that this is able to cover all the types
of portals handled in the extended query protocol, particularly these
two when the report done in ExecutorStart() is not enough (neither is an
addition in ExecutorRun(), actually, for the second point):
- Multiple execute messages, with multiple ExecutorRun().
- Portal with execute/fetch messages, like a query with a RETURNING
clause and a fetch size that stores the tuples in a first execute
message going though ExecutorStart() and ExecuteRun(), followed by one
or more execute messages doing only fetches from the tuplestore created
in the first message.  This corresponds to the case where
execute_is_fetch is set, for example.

Note that the query ID reporting done in ExecutorStart() is still
necessary, as an EXECUTE requires it.  Query ID reporting is optimistic
and more calls to pgstat_report_query_id() don't matter as the first
report takes priority except if the report is forced.  The comment in
ExecutorStart() is adjusted to reflect better the reality with the
extended query protocol.

The test added in pg_stat_statements is a courtesy of Robert Haas.  This
uses psql's \bind metacommand, hence this part is backpatched down to
v16.

Reported-by:  Kaido Vaikla, Erik Wienhold
Author: Sami Imseih
Reviewed-by: Jian He, Andrei Lepikhov, Michael Paquier
Discussion: https://postgr.es/m/CA+427g8DiW3aZ6pOpVgkPbqK97ouBdf18VLiHFesea2jUk3XoQ@mail.gmail.com
Discussion: https://postgr.es/m/CA+TgmoZxtnf_jZ=VqBSyaU8hfUkkwoJCJ6ufy4LGpXaunKrjrg@mail.gmail.com
Discussion: https://postgr.es/m/1391613709.939460.1684777418070@office.mailbox.org
Backpatch-through: 14
2024-09-18 09:59:14 +09:00
Thomas Munro
ec1d545c8f Allow ReadStream to be consumed as raw block numbers.
Commits 041b9680 and 6377e12a changed the interface of
scan_analyze_next_block() to take a ReadStream instead of a BlockNumber
and a BufferAccessStrategy, and to return a value to indicate when the
stream has run out of blocks.

This caused integration problems for at least one known extension that
uses specially encoded BlockNumber values that map to different
underlying storage, because acquire_sample_rows() sets up the stream so
that read_stream_next_buffer() reads blocks from the main fork of the
relation's SMgrRelation.

Provide read_stream_next_block(), as a way for such an extension to
access the stream of raw BlockNumbers directly and forward them to its
own ReadBuffer() calls after decoding, as it could in earlier releases.
The new function returns the BlockNumber and BufferAccessStrategy that
were previously passed directly to scan_analyze_next_block().
Alternatively, an extension could wrap the stream of BlockNumbers in
another ReadStream with a callback that performs any decoding required
to arrive at real storage manager BlockNumber values, so that it could
benefit from the I/O combining and concurrency provided by
read_stream.c.

Another class of table access method that does nothing in
scan_analyze_next_block() because it is not block-oriented could use
this function to control the number of block sampling loops.  It could
match the previous behavior with "return read_stream_next_block(stream,
&bas) != InvalidBlockNumber".

Ongoing work is expected to provide better ANALYZE support for table
access methods that don't behave like heapam with respect to storage
blocks, but that will be for future releases.

Back-patch to 17.

Reported-by: Mats Kindahl <mats@timescale.com>
Reviewed-by: Mats Kindahl <mats@timescale.com>
Discussion: https://postgr.es/m/CA%2B14425%2BCcm07ocG97Fp%2BFrD9xUXqmBKFvecp0p%2BgV2YYR258Q%40mail.gmail.com
2024-09-18 11:29:58 +12:00
Tom Lane
f7567f9e53 Repair pg_upgrade for identity sequences with non-default persistence.
Since we introduced unlogged sequences in v15, identity sequences
have defaulted to having the same persistence as their owning table.
However, it is possible to change that with ALTER SEQUENCE, and
pg_dump tries to preserve the logged-ness of sequences when it doesn't
match (as indeed it wouldn't for an unlogged table from before v15).

The fly in the ointment is that ALTER SEQUENCE SET [UN]LOGGED fails
in binary-upgrade mode, because it needs to assign a new relfilenode
which we cannot permit in that mode.  Thus, trying to pg_upgrade a
database containing a mismatching identity sequence failed.

To fix, add syntax to ADD/ALTER COLUMN GENERATED AS IDENTITY to allow
the sequence's persistence to be set correctly at creation, and use
that instead of ALTER SEQUENCE SET [UN]LOGGED in pg_dump.  (I tried to
make SET [UN]LOGGED work without any pg_dump modifications, but that
seems too fragile to be a desirable answer.  This way should be
markedly faster anyhow.)

In passing, document the previously-undocumented SEQUENCE NAME option
that pg_dump also relies on for identity sequences; I see no value
in trying to pretend it doesn't exist.

Per bug #18618 from Anthony Hsu.
Back-patch to v15 where we invented this stuff.

Discussion: https://postgr.es/m/18618-d4eb26d669ed110a@postgresql.org
2024-09-17 15:53:36 -04:00
Peter Geoghegan
a24bffc021 Avoid parallel nbtree index scan hangs with SAOPs.
Commit 5bf748b8, which enhanced nbtree ScalarArrayOp execution, made
parallel index scans work with the new design for arrays via explicit
scheduling of primitive index scans.  A backend that successfully
scheduled the scan's next primitive index scan saved its backend local
array keys in shared memory.  Any backend could pick up the scheduled
primitive scan within _bt_first.  This scheme decouples scheduling a
primitive scan from starting the scan (by performing another descent of
the index via a _bt_search call from _bt_first) to make things robust.

The scheme had a deadlock hazard, at least when the leader process
participated in the scan.  _bt_parallel_seize had a code path that made
backends that were not in an immediate position to start a scheduled
primitive index scan wait for some other backend to do so instead.
Under the right circumstances, the leader process could wait here
forever: the leader would wait for any other backend to start the
primitive scan, while every worker was busy waiting on the leader to
consume tuples from the scan's tuple queue.

To fix, don't wait for a scheduled primitive index scan to be started by
some other eligible backend from within _bt_parallel_seize (when the
calling backend isn't in a position to do so itself).  Return false
instead, while recording that the scan has a scheduled primitive index
scan in backend local state.  This leaves the backend in the same state
as the existing case where a backend schedules (or tries to schedule)
another primitive index scan from within _bt_advance_array_keys, before
calling _bt_parallel_seize.  _bt_parallel_seize already handles that
case by returning false without waiting, and without unsetting the
backend local state.  Leaving the backend in this state enables it to
start a previously scheduled primitive index scan once it gets back to
_bt_first.

Oversight in commit 5bf748b8, which enhanced nbtree ScalarArrayOp
execution.

Matthias van de Meent, with tweaks by me.

Author: Matthias van de Meent <boekewurm+postgres@gmail.com>
Reported-By: Tomas Vondra <tomas@vondra.me>
Reviewed-By: Peter Geoghegan <pg@bowt.ie>
Discussion: https://postgr.es/m/CAH2-WzmMGaPa32u9x_FvEbPTUkP5e95i=QxR8054nvCRydP-sw@mail.gmail.com
Backpatch: 17-, where nbtree SAOP execution was enhanced.
2024-09-17 11:10:33 -04:00
Bruce Momjian
054a23b674 scripts: add Perl script to add links to release notes
Reported-by: jian he

Discussion: https://postgr.es/m/ZuYsS5XdA7hVcV9l@momjian.us

Backpatch-through: 12
2024-09-16 13:26:37 -04:00
Tom Lane
b9645dca10 Replace usages of xmlXPathCompile() with xmlXPathCtxtCompile().
In existing releases of libxml2, xmlXPathCompile can be driven
to stack overflow because it fails to protect itself against
too-deeply-nested input.  While there is an upstream fix as of
yesterday, it will take years for that to propagate into all
shipping versions.  In the meantime, we can protect our own
usages basically for free by calling xmlXPathCtxtCompile instead.

(The actual bug is that libxml2 keeps its nesting counter in the
xmlXPathContext, and its parsing code was willing to just skip
counting nesting levels if it didn't have a context.  So if we supply
a context, all is well.  It seems odd actually that it works at all
to not supply a context, because this means that XPath parsing does
not have access to XML namespace info.  Apparently libxml2 never
checks namespaces until runtime?  Anyway, this seems like good
future-proofing even if its only immediate effect is to dodge a bug.)

Sadly, this hack only offers protection with libxml2 2.9.11 and newer.
Before that there are multiple similar problems, so if you are
processing untrusted XML it behooves you to get a newer version.
But we have some pretty old libxml2 in the buildfarm, so it seems
impractical to add a regression test to verify this fix.

Per bug #18617 from Jingzhou Fu.  Back-patch to all supported
versions.

Discussion: https://postgr.es/m/18617-1cee4d2ed1f4e7ae@postgresql.org
Discussion: https://gitlab.gnome.org/GNOME/libxml2/-/issues/799
2024-09-15 13:33:09 -04:00
Tom Lane
6283ff2018 Run regression tests with timezone America/Los_Angeles.
Historically we've used timezone "PST8PDT", but the recent release
2024b of tzdb changes the definition of that zone in a way that
breaks many test cases concerned with dates before 1970.  Although
we've not yet adopted 2024b into our own tree, this is already
problematic for people using --with-system-tzdata if their platform
has already adopted 2024b.  To work with both older and newer
versions of tzdb, switch to using "America/Los_Angeles", accepting
the ensuing changes in regression test results.

Back-patch to all supported branches.

Per report and patch from Wolfgang Walther.

Discussion: https://postgr.es/m/0a997455-5aba-4cf2-a354-d26d8bcbfae6@technowledgy.de
2024-09-14 17:55:02 -04:00
Alvaro Herrera
fca91b5c90
Add commit 7229ebe011df to .git-blame-ignore-revs. 2024-09-14 20:17:30 +02:00
Bruce Momjian
77120dd081 doc PG 17 relnotes: adjust SGML format for commit add script
Backpatch-through: 17 only
2024-09-14 13:20:02 -04:00
Bruce Momjian
4a89807569 doc PG 17 relnotes: remove commit link whose comment was removed
Backpatch-through: 17 only
2024-09-14 12:49:47 -04:00
Tom Lane
e3b2c651bc Remove obsolete comment in pg_stat_statements.
Commit 76db9cb63 removed the use of multiple nesting counters,
but missed one comment describing that arrangement.

Back-patch to v17 where 76db9cb63 came in, just to avoid confusion.

Julien Rouhaud

Discussion: https://postgr.es/m/gfcwh3zjxc2vygltapgo7g6yacdor5s4ynr234b6v2ohhuvt7m@gr42joxalenw
2024-09-14 11:42:40 -04:00
Bruce Momjian
54497e0ed8 doc PG 17 relnotes: update to current
Backpatch-through: 17 only
2024-09-14 10:38:34 -04:00
Andrew Dunstan
dc2a660bd9 Improve meson's detection of perl build flags
The current method of detecting perl build flags breaks if the path to
perl contains a space. This change makes two improvements. First,
instead of getting a list of ldflags and ccdlflags and then trying to
filter those out of the reported ldopts, we tell perl to suppress
reporting those in the first instance. Second, it tells perl to parse
those and output them, one per line. Thus any space on the option in a
file name, for example, is preserved.

Issue reported off-list by Muralikrishna Bandaru

Discussion: https://postgr.es/01117f88-f465-bf6c-9362-083bd72ca305@dunslane.net

Backpatch to release 16.
2024-09-14 10:36:57 -04:00
Bruce Momjian
984702d0ee doc PG 17 relnotes: move EXPLAIN items to their own section
Reported-by: Álvaro Herrera

Discussion: https://postgr.es/m/202409111750.xtcbl7ppdoyn@alvherre.pgsql

Backpatch-through: 17 only
2024-09-14 09:27:21 -04:00
Andrew Dunstan
648397b1d4 Only define NO_THREAD_SAFE_LOCALE for MSVC plperl when required
Latest versions of Strawberry Perl define USE_THREAD_SAFE_LOCALE, and we
therefore get a handshake error when building against such instances.
The solution is to perform a test to see if USE_THREAD_SAFE_LOCALE is
defined and only define NO_THREAD_SAFE_LOCALE if it isn't.

Backpatch the meson.build fix back to release 16 and apply the same
logic to Mkvcbuild.pm in releases 12 through 16.

Original report of the issue from Muralikrishna Bandaru.
2024-09-14 08:48:04 -04:00
Bruce Momjian
4e7b9a1adc doc PG 17 relnotes: move partition access method item
Also clarify wording.

Reported-by: Álvaro Herrera

Discussion: https://postgr.es/m/202409111750.xtcbl7ppdoyn@alvherre.pgsql

Backpatch-through: 17 only
2024-09-13 18:21:56 -04:00
Bruce Momjian
26cea9fb82 doc PG 17 relnotes: add dynamic shared memory registry item
Reported-by: Nathan Bossart

Discussion: https://postgr.es/m/Ztcuwbs0FGCPOEu9@nathan

Backpatch-through: 17 only
2024-09-13 16:17:42 -04:00
Tom Lane
418c6a2c72 Allow _h_indexbuild() to be interrupted.
When we are building a hash index that is large enough to need
pre-sorting (larger than either maintenance_work_mem or NBuffers),
the initial sorting phase is interruptible, but the insertion
phase wasn't.  Add the missing CHECK_FOR_INTERRUPTS().

Per bug #18616 from Alexander Lakhin.  Back-patch to all
supported branches.

Pavel Borisov

Discussion: https://postgr.es/m/18616-acbb9e5caf41e964@postgresql.org
2024-09-13 16:17:04 -04:00
Bruce Momjian
b9a65a678b doc PG 17 relnotes: replace commit hashes with section marks
Backpatch-through: 17 only
2024-09-13 12:29:51 -04:00
Nathan Bossart
9b3c3c0fc2 Fix contrib/pageinspect's test for sequences.
I managed to break this test in two different ways in commit
05036a3155.

First, the output of the new call to tuple_data_split() on the test
sequence is dependent on endianness.  This is fixed by setting a
special start value for the test sequence that produces the same
output regardless of the endianness of the machine.

Second, on versions older than v15, the new test case fails under
"force_parallel_mode = regress" with the following error:

	ERROR:  cannot access temporary tables during a parallel operation

This is because pageinspect's disk-accessing functions are
incorrectly marked PARALLEL SAFE on versions older than v15 (see
commit aeaaf520f4 for details).  This one is fixed by changing the
test sequence to be permanent.  The only reason it was previously
marked temporary was to avoid needing a DROP SEQUENCE command at
the end of the test.  Unlike some other tests in this file, the use
of a permanent sequence here shouldn't result in any test
instability like what was fixed by commit e2933a6e11.

Reviewed-by: Tom Lane
Discussion: https://postgr.es/m/ZuOKOut5hhDlf_bP%40nathan
Backpatch-through: 12
2024-09-13 10:16:40 -05:00
Bruce Momjian
9f949c9cb2 doc PG 17 relnotes: add links to commits
Copied from SGML comments.

Discussion: https://postgr.es/m/CACJufxF+9YCDce5vzmZY6ZCEeTJsYFG-kPohT9UjKikJX30mGw@mail.gmail.com

Author: jian he

Backpatch-through: 17 only
2024-09-13 09:42:39 -04:00
Amit Langote
32ccfa0476 SQL/JSON: Update example in JSON_QUERY() documentation
Commit 2c27346ed684 fixed the behavior of JSON_QUERY() when WITH
CONDITIONAL WRAPPER is used, but the documentation example wasn't
updated to reflect this change. This commit updates the example to
show the correct result.

Per off-list report from Andreas Ulbrich.

Backpatch-through: 17
2024-09-13 16:10:01 +09:00
Nathan Bossart
6ea7f04b73 Reintroduce support for sequences in pgstattuple and pageinspect.
Commit 4b82664156 restricted a number of functions provided by
contrib modules to only relations that use the "heap" table access
method.  Sequences always use this table access method, but they do
not advertise as such in the pg_class system catalog, so the
aforementioned commit also (presumably unintentionally) removed
support for sequences from some of these functions.  This commit
reintroduces said support for sequences to these functions and adds
a couple of relevant tests.

Co-authored-by: Ayush Vatsa
Reviewed-by: Robert Haas, Michael Paquier, Matthias van de Meent
Discussion: https://postgr.es/m/CACX%2BKaP3i%2Bi9tdPLjF5JCHVv93xobEdcd_eB%2B638VDvZ3i%3DcQA%40mail.gmail.com
Backpatch-through: 12
2024-09-12 16:31:29 -05:00
Tom Lane
cc4fdfa411 Make jsonpath .string() be immutable for datetimes.
Discussion of commit ed055d249 revealed that we don't actually
want jsonpath's .string() method to depend on DateStyle, nor
TimeZone either, because the non-"_tz" jsonpath functions are
supposed to be immutable.  Potentially we could allow a TimeZone
dependency in the "_tz" variants, but it seems better to just
uniformly define this method as returning the same string that
jsonb text output would do.  That's easier to implement too,
saving a couple dozen lines.

Patch by me, per complaint from Peter Eisentraut.  Back-patch
to v17 where this feature came in (in 66ea94e8e).  Also
back-patch ed055d249 to provide test cases.

Discussion: https://postgr.es/m/5e8879d0-a3c8-4be2-950f-d83aa2af953a@eisentraut.org
2024-09-12 14:30:29 -04:00
David Rowley
2645f6d643 Doc: alphabetize aggregate function table
A few recent JSON aggregates have been added without much consideration
to the existing order.  Put these back in alphabetical order (with the
exception of the JSONB variant of each JSON aggregate).

Author: Wolfgang Walther <walther@technowledgy.de>
Reviewed-by: Marlene Reiterer <marlene.reiterer.03@gmail.com>
Discussion: https://postgr.es/m/6a7b910c-3feb-4006-b817-9b4759cb6bb6%40technowledgy.de
Backpatch-through: 16, where these aggregates were added
2024-09-12 22:37:27 +12:00
Amit Langote
2c27346ed6 SQL/JSON: Fix JSON_QUERY(... WITH CONDITIONAL WRAPPER)
Currently, when WITH CONDITIONAL WRAPPER is specified, array wrappers
are applied even to a single SQL/JSON item if it is a scalar JSON
value, but this behavior does not comply with the standard.

To fix, apply wrappers only when there are multiple SQL/JSON items
in the result.

Reported-by: Peter Eisentraut <peter@eisentraut.org>
Author: Peter Eisentraut <peter@eisentraut.org>
Author: Amit Langote <amitlangote09@gmail.com>
Reviewed-by: Andrew Dunstan <andrew@dunslane.net>
Discussion: https://postgr.es/m/8022e067-818b-45d3-8fab-6e0d94d03626%40eisentraut.org
Backpatch-through: 17
2024-09-12 09:39:42 +09:00
Tom Lane
7f88e50b45 Remove incorrect Assert.
check_agglevels_and_constraints() asserted that if we find an
aggregate function in an EXPR_KIND_FROM_SUBSELECT expression, the
expression must be in a LATERAL subquery.  Alexander Lakhin found a
case where that's not so: because of the odd scoping rules for NEW/OLD
within a rule, a reference to NEW/OLD could cause an aggregate to be
considered top-level even though it's in an unmarked sub-select.
The error message that would be thrown seems sufficiently on-point,
so just remove the Assert.  (Hence, this is not a bug for production
builds.)

This Assert was added by me in commit eaccfded9 (9.3 era).  It looks
like I put it in to cross-check that the new logic for detecting
misplaced aggregates (using agglevelsup) caught the same cases that a
previous check on p_lateral_active did.  So there might have been some
related misbehavior before eaccfded9 ... but that's very ancient
history by now, so I didn't dig any deeper.

Per bug #18608 from Alexander Lakhin.  Back-patch to all supported
branches.

Discussion: https://postgr.es/m/18608-48de0717508ee429@postgresql.org
2024-09-11 11:41:59 -04:00
Magnus Hagander
7748c847c3 pg_createsubscriber: minor documentation fixes 2024-09-11 16:31:30 +02:00
Tomas Vondra
78bc5f7118 Fix unique key checks in JSON object constructors
When building a JSON object, the code builds a hash table of keys, to
allow checking if the keys are unique. The uniqueness check and adding
the new key happens in json_unique_check_key(), but this assumes the
pointer to the key remains valid.

Unfortunately, two places passed pointers to keys in a buffer, while
also appending more data (additional key/value pairs) to the buffer.
With enough data the buffer is resized by enlargeStringInfo(), which
calls repalloc(), invalidating the earlier key pointers.

Due to this the uniqueness check may fail with both false negatives and
false positives, producing JSON objects with duplicate keys or failing
to produce a perfectly valid JSON object.

This affects multiple functions that enforce uniqueness of keys, all
introduced in PG16 with the new SQL/JSON:

- json_object_agg_unique / jsonb_object_agg_unique
- json_object / jsonb_objectagg

Existing regression tests did not detect the issue, simply because the
initial buffer size is 1024 and the objects were small enough not to
require the repalloc.

With a sufficiently large object, AddressSanitizer reported the access
to invalid memory immediately. So would valgrind, of course.

Fixed by copying the key into the hash table memory context, and adding
regression tests with enough data to repalloc the buffer. Backpatch to
16, where the functions were introduced.

Reported by Alexander Lakhin. Investigation and initial fix by Junwang
Zhao, with various improvements and tests by me.

Reported-by: Alexander Lakhin
Author: Junwang Zhao, Tomas Vondra
Backpatch-through: 16
Discussion: https://postgr.es/m/18598-3279ed972a2347c7@postgresql.org
Discussion: https://postgr.es/m/CAEG8a3JjH0ReJF2_O7-8LuEbO69BxPhYeXs95_x7+H9AMWF1gw@mail.gmail.com
2024-09-11 13:21:30 +02:00
Tom Lane
946f150aa1 Fix some whitespace issues in XMLSERIALIZE(... INDENT).
We must drop whitespace while parsing the input, else libxml2
will include "blank" nodes that interfere with the desired
indentation behavior.  The end result is that we didn't indent
nodes separated by whitespace.

Also, it seems that libxml2 may add a trailing newline when working
in DOCUMENT mode.  This is semantically insignificant, so strip it.

This is in the gray area between being a bug fix and a definition
change.  However, the INDENT option is still pretty new (since v16),
so I think we can get away with changing this in stable branches.
Hence, back-patch to v16.

Jim Jones

Discussion: https://postgr.es/m/872865a8-548b-48e1-bfcd-4e38e672c1e4@uni-muenster.de
2024-09-10 16:20:31 -04:00
Amit Langote
77aebe9a8d SQL/JSON: Avoid initializing unnecessary ON ERROR / ON EMPTY steps
When the ON ERROR / ON EMPTY behavior is to return NULL, returning
NULL directly from ExecEvalJsonExprPath() suffices. Therefore, there's
no need to create separate steps to check the error/empty flag or
those to evaluate the the constant NULL expression.  This speeds up
common cases because the default ON ERROR / ON EMPTY behavior for
JSON_QUERY() and JSON_VALUE() is to return NULL.  However, these steps
are necessary if the RETURNING type is a domain, as constraints on the
domain may need to be checked.

Reported-by: Jian He <jian.universality@gmail.com>
Author: Jian He <jian.universality@gmail.com>
Author: Amit Langote <amitlangote09@gmail.com>
Discussion: https://postgr.es/m/CACJufxEo4sUjKCYtda0_qt9tazqqKPmF1cqhW9KBOUeJFqQd2g@mail.gmail.com
Backpatch-through: 17
2024-09-09 15:59:06 +09:00
Michael Paquier
cd6b2ae3e7 Fix waits of REINDEX CONCURRENTLY for indexes with predicates or expressions
As introduced by f9900df5f94, a REINDEX CONCURRENTLY job done for an
index with predicates or expressions would set PROC_IN_SAFE_IC in its
MyProc->statusFlags, causing it to be ignored by other concurrent
operations.

Such concurrent index rebuilds should never be ignored, as a predicate
or an expression could call a user-defined function that accesses a
different table than the table where the index is rebuilt.

A test that uses injection points is added, backpatched down to 17.
Michail has proposed a different test, but I have added something
simpler with more coverage.

Oversight in f9900df5f949.

Author: Michail Nikolaev
Discussion: https://postgr.es/m/CANtu0oj9A3kZVduFTG0vrmGnKB+DCHgEpzOp0qAyOgmks84j0w@mail.gmail.com
Backpatch-through: 14
2024-09-09 13:49:59 +09:00
Tom Lane
e69030cb51 Fix incorrect pg_stat_io output on 32-bit machines.
pg_stat_get_io() applied TimestampTzGetDatum twice to the
stat_reset_timestamp value.  On 64-bit builds that's harmless because
TimestampTzGetDatum is a no-op, but on 32-bit builds it results in
displaying garbage in the stats_reset column of the pg_stat_io view.

Bug dates to commit a9c70b46d which introduced pg_stat_io, so
back-patch to v16 where that came in.

Bertrand Drouvot

Discussion: https://postgr.es/m/Ztrd+XcPTz1zorkg@ip-10-97-1-34.eu-west-3.compute.internal
2024-09-06 11:58:10 -04:00
Amit Langote
446d5ad7ae SQL/JSON: Fix default ON ERROR behavior for JSON_TABLE
Use EMPTY ARRAY instead of EMPTY.

This change does not affect the runtime behavior of JSON_TABLE(),
which continues to return an empty relation ON ERROR. It only alters
whether the default ON ERROR behavior is shown in the deparsed output.

Reported-by: Jian He <jian.universality@gmail.com>
Discussion: https://postgr.es/m/CACJufxEo4sUjKCYtda0_qt9tazqqKPmF1cqhW9KBOUeJFqQd2g@mail.gmail.com
Backpatch-through: 17
2024-09-06 13:30:42 +09:00
Amit Langote
cd680b3921 SQL/JSON: Fix JSON_TABLE() column deparsing
The deparsing code in get_json_expr_options() unnecessarily emitted
the default column-specific ON ERROR / EMPTY behavior when the
top-level ON ERROR behavior in JSON_TABLE was set to ERROR. Fix that
by not overriding the column-specific default, determined based on
the column's JsonExprOp in get_json_table_columns(), with
JSON_BEHAVIOR_ERROR when that is the top-level ON ERROR behavior.

Note that this only removes redundancy; the current deparsing output
is not incorrect, just redundant.

Reviewed-by: Jian He <jian.universality@gmail.com>
Discussion: https://postgr.es/m/CACJufxEo4sUjKCYtda0_qt9tazqqKPmF1cqhW9KBOUeJFqQd2g@mail.gmail.com
Backpatch-through: 17
2024-09-06 13:30:40 +09:00
Amit Langote
eef5195f30 Revert recent SQL/JSON related commits
Reverts c88ce386c4d, 5067c230b8e, and  e4e27976a68, because a few BF
animals didn't like one or all of them.
2024-09-06 12:52:39 +09:00
Amit Langote
e4e27976a6 SQL/JSON: Avoid initializing unnecessary ON ERROR / ON EMPTY steps
When the ON ERROR / ON EMPTY behavior is to return NULL, returning
NULL directly from ExecEvalJsonExprPath() suffices. Therefore, there's
no need to create separate steps to check the error/empty flag or
those to evaluate the the constant NULL expression.  This speeds up
common cases because the default ON ERROR / ON EMPTY behavior for
JSON_QUERY() and JSON_VALUE() is to return NULL.  However, these steps
are necessary if the RETURNING type is a domain, as constraints on the
domain may need to be checked.

Reported-by: Jian He <jian.universality@gmail.com>
Author: Jian He <jian.universality@gmail.com>
Author: Amit Langote <amitlangote09@gmail.com>
Discussion: https://postgr.es/m/CACJufxEo4sUjKCYtda0_qt9tazqqKPmF1cqhW9KBOUeJFqQd2g@mail.gmail.com
Backpatch-through: 17
2024-09-06 12:04:29 +09:00
Amit Langote
5067c230b8 SQL/JSON: Fix default ON ERROR behavior for JSON_TABLE
Use EMPTY ARRAY instead of EMPTY.

This change does not affect the runtime behavior of JSON_TABLE(),
which continues to return an empty relation ON ERROR. It only alters
whether the default ON ERROR behavior is shown in the deparsed output.

Reported-by: Jian He <jian.universality@gmail.com>
Discussion: https://postgr.es/m/CACJufxEo4sUjKCYtda0_qt9tazqqKPmF1cqhW9KBOUeJFqQd2g@mail.gmail.com
Backpatch-through: 17
2024-09-06 12:01:49 +09:00
Amit Langote
c88ce386c4 SQL/JSON: Fix JSON_TABLE() column deparsing
The deparsing code in get_json_expr_options() unnecessarily emitted
the default column-specific ON ERROR / EMPTY behavior when the
top-level ON ERROR behavior in JSON_TABLE was set to ERROR. Fix that
by not overriding the column-specific default, determined based on
the column's JsonExprOp in get_json_table_columns(), with
JSON_BEHAVIOR_ERROR when that is the top-level ON ERROR behavior.

Note that this only removes redundancy; the current deparsing output
is not incorrect, just redundant.

Reviewed-by: Jian He <jian.universality@gmail.com>
Discussion: https://postgr.es/m/CACJufxEo4sUjKCYtda0_qt9tazqqKPmF1cqhW9KBOUeJFqQd2g@mail.gmail.com
Backpatch-through: 17
2024-09-06 12:01:49 +09:00
Amit Langote
fe32343814 Update comment about ExprState.escontext
The updated comment provides more helpful guidance by mentioning that
escontext should be set when soft error handling is needed.

Reported-by: Jian He <jian.universality@gmail.com>
Discussion: https://postgr.es/m/CACJufxEo4sUjKCYtda0_qt9tazqqKPmF1cqhW9KBOUeJFqQd2g@mail.gmail.com
Backpatch-through: 17
2024-09-06 12:01:49 +09:00
Bruce Momjian
35afec71ae doc PG 17 relnotes: remove tab complete for MERGE/SPLIT partit.
commit 60ae37a8b

Backpatch-through: 17 only
2024-09-05 21:49:02 -04:00
Tom Lane
7dcbf0afa2 Prevent mis-encoding of "trailing junk after numeric literal" errors.
Since commit 2549f0661, we reject an identifier immediately following
a numeric literal (without separating whitespace), because that risks
ambiguity with hex/octal/binary integers.  However, that patch used
token patterns like "{integer}{ident_start}", which is problematic
because {ident_start} matches only a single byte.  If the first
character after the integer is a multibyte character, this ends up
with flex reporting an error message that includes a partial multibyte
character.  That can cause assorted bad-encoding problems downstream,
both in the report to the client and in the postmaster log file.

To fix, use {identifier} not {ident_start} in the "junk" token
patterns, so that they will match complete multibyte characters.
This seems generally better user experience quite aside from the
encoding problem: for "123abc" the error message will now say that
the error appeared at or near "123abc" instead of "123a".

While at it, add some commentary about why these patterns exist
and how they work.

Report and patch by Karina Litskevich; review by Pavel Borisov.
Back-patch to v15 where the problem came in.

Discussion: https://postgr.es/m/CACiT8iZ_diop=0zJ7zuY3BXegJpkKK1Av-PU7xh0EDYHsa5+=g@mail.gmail.com
2024-09-05 12:42:33 -04:00
Michael Paquier
07b828e9d4 Fix inconsistent LWLock tranche name "CommitTsSLRU"
This term was using an inconsistent casing between the code and the
documentation, using "CommitTsSLRU" in wait_event_names.txt and
"CommitTSSLRU" in the code.

Let's update the term in the code to reflect what's in the
documentation, "CommitTs" being more commonly used, so as
pg_stat_activity shows the same term as the documentation.

Oversight in 53c2a97a9266.

Author: Alexander Lakhin
Discussion: https://postgr.es/m/f7e514cf-2446-21f1-a5d2-8c089a6e2168@gmail.com
Backpatch-through: 17
2024-09-04 10:22:19 +09:00
Michael Paquier
bab1fd9277 Avoid installcheck failure in TAP tests using injection_points
These tests depend on the test module injection_points to be installed,
but it may not be available as the contents of src/test/modules/ are not
installed by default.

This commit adds a workaround based on a scan of pg_available_extensions
to check if the extension is available, skipping the test if it is not.
This allows installcheck to work transparently.

There are more tests impacted by this problem on HEAD, but for now this
addresses only the tests that exist on HEAD and v17 as the release is
close by.

Reported-by: Maxim Orlov
Discussion: https://postgr.es/m/CACG=ezZkoT-pFz6a9XnyToiuR-Wg8fGELqHLoyBodr+2h-77qA@mail.gmail.com
Backpatch-through: 17
2024-09-04 08:56:28 +09:00
Michael Paquier
ff43b5e70d Simplify makefiles exporting twice enable_injection_points
This is confusing, as it exports twice the same variable.  Oversight in
6782709df81f that has spread in more places afterwards.

Reported-by: Alvaro Herrera, Tom Lane
Discussion: https://postgr.es/m/202408201630.mn6vbohjh7hh@alvherre.pgsql
Backpatch-through: 17
2024-09-04 08:05:56 +09:00
Tom Lane
94f1474e60 Stamp 17rc1. 2024-09-02 16:11:07 -04:00
Peter Eisentraut
c96176c48d Fix warnings from msgfmt
/usr/bin/msgfmt: po/fr.po: warning: PO file header fuzzy
                           warning: older versions of msgfmt will give an error on this

Apparently, not all versions of msgfmt produce this.  Quick fix for
now, more to be researched later.
2024-09-02 18:03:47 +02:00
Peter Eisentraut
e6ec1d6aab Fix rarely-run test for message wording change
fixup for 2e6a8047f0

Reported-by: Nazir Bilal Yavuz <byavuz81@gmail.com>
2024-09-02 17:47:18 +02:00
Peter Eisentraut
986a3ac497 Translation updates
Source-Git-URL: https://git.postgresql.org/git/pgtranslation/messages.git
Source-Git-Hash: d0110df9f34c2d32cb2652d4477c3135dabe84f7
2024-09-02 12:02:42 +02:00
Thomas Munro
3ed3683618 Fix unfairness in all-cached parallel seq scan.
Commit b5a9b18c introduced block streaming infrastructure with a special
fast path for all-cached scans, and commit b7b0f3f2 connected the
infrastructure up to sequential scans.  One of the fast path
micro-optimizations had an unintended consequence: it interfered with
parallel sequential scan's block range allocator (from commit 56788d21),
which has its own ramp-up and ramp-down algorithm when handing out
groups of pages to workers.  A scan of an all-cached table could give
extra blocks to one worker, when others had finished.  In some plans
(probably already very bad plans, such as the one reported by
Alexander), the unfairness could be magnified.

An internal buffer of 16 block numbers is removed, keeping just a single
block buffer for technical reasons.

Back-patch to 17.

Reported-by: Alexander Lakhin <exclusion@gmail.com>
Discussion: https://postgr.es/m/63a63690-dd92-c809-0b47-af05459e95d1%40gmail.com
2024-08-31 17:29:30 +12:00
Thomas Munro
34226d4ad7 Stabilize 039_end_of_wal test.
The first test was sensitive to the insert LSN after setting up the
catalogs, which depended on environmental things like the locales on the
OS and usernames.  Switch to a new WAL file before the first test, as a
simple way to put every computer into the same state.

Back-patch to all supported releases.

Reported-by: Anton Voloshin <a.voloshin@postgrespro.ru>
Reported-by: Nathan Bossart <nathandbossart@gmail.com>
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Reviewed-by: Nathan Bossart <nathandbossart@gmail.com>
Discussion: https://postgr.es/m/b26aeac2-cb6d-4633-a7ea-945baae83dcf%40postgrespro.ru
2024-08-31 15:00:09 +12:00
Masahiko Sawada
0776724050 Clarify restrict_nonsystem_relation_kind description.
This change improves the description of the
restrict_nonsystem_relation_kind parameter in guc_table.c and the
documentation for better clarity.

Backpatch to 12, where this GUC parameter was introduced.

Reviewed-by: Peter Eisentraut
Discussion: https://postgr.es/m/6a96f1af-22b4-4a80-8161-1f26606b9ee2%40eisentraut.org
Backpatch-through: 12
2024-08-30 15:06:07 -07:00
Tom Lane
8749d850f9 Make postgres_fdw's query_cancel test less flaky.
This test occasionally shows

+WARNING:  could not get result of cancel request due to timeout

which appears to be because the cancel request is sometimes unluckily
sent to the remote session between queries, and then it's ignored.

This patch tries to make that less probable in three ways:

1. Use a test query that does not involve remote estimates, so that
no EXPLAINs are sent.
2. Make sure that the remote session is ready-to-go (transaction
started, SET commands sent) before we start the timer.
3. Increase the statement_timeout to 100ms, to give the local
session enough time to plan and issue the query.

We might have to go higher than 100ms to make this adequately
stable in the buildfarm, but let's see how it goes.

Back-patch to v17 where this test was introduced.

Jelte Fennema-Nio and Tom Lane

Discussion: https://postgr.es/m/578934.1725045685@sss.pgh.pa.us
2024-08-30 16:47:39 -04:00
Tom Lane
b43110869f Avoid inserting PlaceHolderVars in cases where pre-v16 PG did not.
Commit 2489d76c4 removed some logic from pullup_replace_vars()
that avoided wrapping a PlaceHolderVar around a pulled-up
subquery output expression if the expression could be proven
to go to NULL anyway (because it contained Vars or PHVs of the
pulled-up relation and did not contain non-strict constructs).
But removing that logic turns out to cause performance regressions
in some cases, because the extra PHV blocks subexpression folding,
and will do so even if outer-join reduction later turns it into a
no-op with no phnullingrels bits.  This can for example prevent
an expression from being matched to an index.

The reason for always adding a PHV was to ensure we had someplace
to put the varnullingrels marker bits of the Var being replaced.
However, it turns out we can optimize in exactly the same cases that
the previous code did, because we can instead attach the needed
varnullingrels bits to the contained Var(s)/PHV(s).

This is not a complete solution --- it would be even better if we
could remove PHVs after reducing them to no-ops.  It doesn't look
practical to back-patch such an improvement, but this change seems
safe and at least gets rid of the performance-regression cases.

Per complaint from Nikhil Raj.  Back-patch to v16 where the
problem appeared.

Discussion: https://postgr.es/m/CAG1ps1xvnTZceKK24OUfMKLPvDP2vjT-d+F2AOCWbw_v3KeEgg@mail.gmail.com
2024-08-30 12:42:13 -04:00
Peter Eisentraut
df51201f34 Update list of acknowledgments in release notes
current through df80b1d6cd
2024-08-30 10:03:48 +02:00
Peter Eisentraut
df80b1d6cd Remove duplicate name from list of acknowledgments
Reported-by: m.zhilin@postgrespro.ru
2024-08-30 08:38:16 +02:00
Peter Eisentraut
47b92f8fc5 Correct name in list of acknowledgments
Reported-by: Etsuro Fujita <etsuro.fujita@gmail.com>
2024-08-30 08:34:39 +02:00
Tom Lane
a7eb633563 Fix mis-deparsing of ORDER BY lists when there is a name conflict.
If an ORDER BY item in SELECT is a bare identifier, the parser
first seeks it as an output column name of the SELECT (for SQL92
compatibility).  However, ruleutils.c is expecting the SQL99
interpretation where such a name is an input column name.  So it's
possible to produce an incorrect display of a view in the (admittedly
pretty ill-advised) case where some other column is renamed in the
SELECT output list to match an ORDER BY column.

This can be fixed by table-qualifying such names in the dumped
view text.  To avoid cluttering less-ill-advised queries, we'd
like to do so only when there's an actual name conflict.
That requires passing the current get_query_def call's resultDesc
parameter down to get_variable, so that it can determine what
the output column names are.  In hopes of reducing rather than
increasing notational clutter in ruleutils.c, I moved that value
into the deparse_context struct and removed it from the parameter
lists of get_query_def's other subroutines.

I made a few other cosmetic changes while at it:
* Likewise move the colNamesVisible parameter into deparse_context.
* Rename deparse_context's windowTList field to targetList,
since it's no longer used only in connection with WINDOW clauses.
* Replace the special_exprkind field with a bool inGroupBy,
since that was all it was being used for, and the apparent
flexibility of storing a ParseExprKind proved to be illusory.
(We need a separate varInOrderBy field to make this patch work.)
* Remove useless save/restore logic in get_select_query_def.

In principle, this bug is quite old.  However, it seems unreachable
before 1b4d280ea, because before that the presence of "new" and "old"
entries in a view's rangetable caused us to always table-qualify every
Var reference in dumped views.  Hence, back-patch to v16 where that
came in.

Per bug #18589 from Quynh Tran.

Discussion: https://postgr.es/m/18589-70091cb81db1a3f1@postgresql.org
2024-08-29 13:24:17 -04:00
Peter Eisentraut
f2353dd717 Message style improvements 2024-08-29 14:33:18 +02:00
Peter Eisentraut
fdbf7e46a4 Disallow USING clause when altering type of generated column
This does not make sense.  It would write the output of the USING
clause into the converted column, which would violate the generation
expression.  This adds a check to error out if this is specified.

There was a test for this, but that test errored out for a different
reason, so it was not effective.

Reported-by: Jian He <jian.universality@gmail.com>
Reviewed-by: Yugo NAGATA <nagata@sraoss.co.jp>
Discussion: https://www.postgresql.org/message-id/flat/c7083982-69f4-4b14-8315-f9ddb20b9834%40eisentraut.org
2024-08-29 08:59:30 +02:00
Amit Kapila
135007a100 Doc: Fix the ambiguity in the description of failover slots.
The failover slots ensure a seamless transition of a subscriber after the
standby is promoted. But the docs for it also explain the behavior of
asynchronous replication which can confuse the readers.

Reported-by: Masahiro Ikeda
Backpatch-through: 17
Discussion: https://postgr.es/m/OS3PR01MB6390B660F4198BB9745E0526B18B2@OS3PR01MB6390.jpnprd01.prod.outlook.com
2024-08-29 08:45:41 +05:30
Peter Eisentraut
0be079ec97 Message style improvements 2024-08-27 17:01:57 +02:00
Peter Eisentraut
203b5ceee8 Fix misplaced translator comments
They did not immediately precede the code they were applying to.
2024-08-27 16:16:16 +02:00
Masahiko Sawada
c739ae9e28 Fix identation. 2024-08-26 16:16:09 -07:00
Masahiko Sawada
dbed2e3662 Fix memory counter update in ReorderBuffer.
Commit 5bec1d6bc5e changed the memory usage updates of the
ReorderBufferTXN to zero all at once by subtracting txn->size, rather
than updating it for each change. However, if TOAST reconstruction
data remained in the transaction when freeing it, there were cases
where it further subtracted the memory counter from zero, resulting in
an assertion failure.

This change calculates the memory size for each change and updates the
memory usage to precisely the amount that has been freed.

Backpatch to v17, where this was introducd.

Reviewed-by: Amit Kapila, Shlok Kyal
Discussion: https://postgr.es/m/CAD21AoAqkNUvicgKPT_dXzNoOwpPkVTg0QPPxEcWmzT0moCJ1g%40mail.gmail.com
Backpatch-through: 17
2024-08-26 11:00:04 -07:00
Peter Geoghegan
6749d4aabe Fix nbtree lookahead overflow bug.
Add bounds checking to nbtree's lookahead/skip-within-a-page mechanism.
Otherwise it's possible for cases with lots of before-array-keys tuples
to overflow an int16 variable, causing the mechanism to generate an out
of bounds page offset number.

Oversight in commit 5bf748b8, which enhanced nbtree ScalarArrayOp
execution.

Reported-By: Alexander Lakhin <exclusion@gmail.com>
Discussion: https://postgr.es/m/6c68ac42-bbb5-8b24-103e-af0e279c536f@gmail.com
Backpatch: 17-, where nbtree SAOP execution was enhanced.
2024-08-26 11:29:13 -04:00
Peter Eisentraut
5e58107b0b pg_upgrade: Message style improvements 2024-08-26 14:38:59 +02:00
Bruce Momjian
74e3db06a0 doc PG 17 relnotes: remove ALTER TABLE SPLIT/MERGE PARTITION
Reverted in commit 84f594da358

Backpatch-through: 17 only
2024-08-25 22:09:18 -04:00
Alexander Korotkov
84f594da35 Revert support for ALTER TABLE ... MERGE/SPLIT PARTITION(S) commands
This commit reverts 1adf16b8fb, 87c21bb941, and subsequent fixes and
improvements including df64c81ca9, c99ef1811a, 9dfcac8e15, 885742b9f8,
842c9b2705, fcf80c5d5f, 96c7381c4c, f4fc7cb54b, 60ae37a8bc, 259c96fa8f,
449cdcd486, 3ca43dbbb6, 2a679ae94e, 3a82c689fd, fbd4321fd5, d53a4286d7,
c086896625, 4e5d6c4091, 04158e7fa3.

The reason for reverting is security issues related to repeatable name lookups
(CVE-2014-0062).  Even though 04158e7fa3 solved part of the problem, there
are still remaining issues, which aren't feasible to even carefully analyze
before the RC deadline.

Reported-by: Noah Misch, Robert Haas
Discussion: https://postgr.es/m/20240808171351.a9.nmisch%40google.com
Backpatch-through: 17
2024-08-24 19:18:24 +03:00
Peter Eisentraut
29e1253198 Add list of acknowledgments to release notes
This contains all individuals mentioned in the commit messages during
PostgreSQL 17 development.

current through REL_17_BETA3
2024-08-24 16:15:13 +02:00
Peter Eisentraut
bf886dfdd4 pg_createsubscriber: Message style improvements 2024-08-24 15:56:50 +02:00
Tom Lane
79c3012dc2 Provide feature-test macros for libpq features added in v17.
As per the policy established in commit 6991e774e, invent macros
that can be tested at compile time to detect presence of new libpq
features.  This should make calling code more readable and less
error-prone than checking the libpq version would be (especially
since we don't expose that at compile time; the server version is
an unreliable substitute).

Discussion: https://postgr.es/m/2042418.1724346970@sss.pgh.pa.us
2024-08-23 10:12:56 -04:00
Noah Misch
6b1f78d90b Fix attach of a previously-detached injection point.
It's normal for the name in a free slot to match the new name.  The
max_inuse mechanism kept simple cases from reaching the problem.  The
problem could appear when index 0 was the previously-detached entry and
index 1 is in use.  Back-patch to v17, where this code first appeared.
2024-08-22 00:07:09 -07:00
Alexander Korotkov
f636ab41ab Avoid repeated table name lookups in createPartitionTable()
Currently, createPartitionTable() opens newly created table using its name.
This approach is prone to privilege escalation attack, because we might end
up opening another table than we just created.

This commit address the issue above by opening newly created table by its
OID.  It appears to be tricky to get a relation OID out of ProcessUtility().
We have to extend TableLikeClause with new newRelationOid field, which is
filled within ProcessUtility() to be further accessed by caller.

Security: CVE-2014-0062
Reported-by: Noah Misch
Discussion: https://postgr.es/m/20240808171351.a9.nmisch%40google.com
Reviewed-by: Pavel Borisov, Dmitry Koval
2024-08-22 09:52:54 +03:00
Tom Lane
2366ab246a Disallow creating binary-coercible casts involving range types.
For a long time we have forbidden binary-coercible casts to or from
composite and array types, because such a cast cannot work correctly:
the type OID embedded in the value would need to change, but it won't
in a binary coercion.  That reasoning applies equally to range types,
but we overlooked installing a similar restriction here when we
invented range types.  Do so now.

Given the lack of field complaints, we won't change this in stable
branches, but it seems not too late for v17.

Per discussion of a problem noted by Peter Eisentraut.

Discussion: https://postgr.es/m/076968e1-0852-40a9-bc0b-117cd3f0e43c@eisentraut.org
2024-08-21 12:00:03 -04:00
Peter Eisentraut
0c7ec3b3a0 doc: remove llvm-config search from configure documentation
As of 4dd29b6833, we no longer attempt to locate any other llvm-config
variant than plain llvm-config in configure-based builds; update the
documentation accordingly. (For Meson-based builds, we still use Meson's
LLVMDependencyConfigTool [0], which runs through a set of possible
suffixes [1], so no need to update the documentation there.)

[0]: 7d28ff2939/mesonbuild/dependencies/dev.py (L184)
[1]: 7d28ff2939/mesonbuild/environment.py (L183)

Author: Ole Peder Brandtzæg <olebra@samfundet.no>
Discussion: https://www.postgresql.org/message-id/20240518224601.gtisttjerylukjr5%40samfundet.no
2024-08-21 15:12:24 +02:00
Amit Kapila
915aafe82a Don't advance origin during apply failure.
We advance origin progress during abort on successful streaming and
application of ROLLBACK in parallel streaming mode. But the origin
shouldn't be advanced during an error or unsuccessful apply due to
shutdown. Otherwise, it will result in a transaction loss as such a
transaction won't be sent again by the server.

Reported-by: Hou Zhijie
Author: Hayato Kuroda and Shveta Malik
Reviewed-by: Amit Kapila
Backpatch-through: 16
Discussion: https://postgr.es/m/TYAPR01MB5692FAC23BE40C69DA8ED4AFF5B92@TYAPR01MB5692.jpnprd01.prod.outlook.com
2024-08-21 09:08:16 +05:30
Alvaro Herrera
5effd59704
Minor wording change in table "JSON Creation Functions"
For readability.  Backpatch to 16.

Author: Erik Wienhold <ewie@ewie.name>
Discussion: https://postgr.es/m/8ddac732-d650-4958-b9c9-ea8e6116251e@ewie.name
2024-08-20 17:53:40 -04:00
Nathan Bossart
effc4c9a66 Fix a couple of wait event descriptions.
The descriptions for ProcArrayGroupUpdate and XactGroupUpdate claim
that these events mean we are waiting for the group leader "at end
of a parallel operation," but neither pertains to parallel
operations.  This commit reverts these descriptions to their
wording before commit 3048898e73, i.e., "end of a parallel
operation" is changed to "transaction end."

Author: Sameer Kumar
Reviewed-by: Amit Kapila
Discussion: https://postgr.es/m/CAGPeHmh6UMrKQHKCmX%2B5vV5TH9P%3DKw9en3k68qEem6J%3DyrZPUA%40mail.gmail.com
Backpatch-through: 13
2024-08-20 13:43:20 -05:00
John Naylor
667401dd40 Document limit on the number of out-of-line values per table
Document the hard limit stemming from the size of an OID, and also
mention the perfomance impact that occurs before the hard limit
is reached.

Jakub Wartak and Robert Haas
Backpatch to all supported versions

Discussion: https://postgr.es/m/CAKZiRmwWhp2yxjqJLwbBjHdfbJBcUmmKMNAZyBjjtpgM9AMatQ%40mail.gmail.com
2024-08-20 13:36:33 +07:00
Bruce Momjian
ef3aa800e8 doc: Improve vague pg_createsubscriber description
Discussion: https://postgr.es/m/ZqX_4J-nFTQtmj6K@momjian.us

Author: Euler Taveira

Backpatch-through: 17
2024-08-19 18:27:21 -04:00
Alvaro Herrera
11f1218ce8
Avoid failure to open dropped detached partition
When a partition is detached and immediately dropped, a prepared
statement could try to compute a new partition descriptor that includes
it.  This leads to this kind of error:
ERROR:  could not open relation with OID 457639

Avoid this by skipping the partition in expand_partitioned_rtentry if it
doesn't exist.

Noted by me while investigating bug #18559.  Kuntal Gosh helped to
identify the exact failure.

Backpatch to 14, where DETACH CONCURRENTLY was introduced.

Author: Álvaro Herrera <alvherre@alvh.no-ip.org>
Reviewed-by: Kuntal Ghosh <kuntalghosh.2007@gmail.com>
Reviewed-by: Junwang Zhao <zhjwpku@gmail.com>
Discussion: https://postgr.es/m/202408122233.bo4adt3vh5bi@alvherre.pgsql
2024-08-19 16:09:10 -04:00
Tomas Vondra
de8770b47f Explain dropdb can't use syscache because of TOAST
Add a comment explaining dropdb() can't rely on syscache. The issue with
flattened rows was fixed by commit 0f92b230f88b, but better to have
a clear explanation why the systable scan is necessary. The other places
doing in-place updates on pg_database have the same comment.

Suggestion and patch by Yugo Nagata. Backpatch to 12, same as the fix.

Author: Yugo Nagata
Backpatch-through: 12
Discussion: https://postgr.es/m/CAJTYsWWNkCt+-UnMhg=BiCD3Mh8c2JdHLofPxsW3m2dkDFw8RA@mail.gmail.com
2024-08-19 13:43:27 +02:00
Daniel Gustafsson
19021d28cd Fix regression in TLS session ticket disabling
Commit 274bbced disabled session tickets for TLSv1.3 on top of the
already disabled TLSv1.2 session tickets, but accidentally caused
a regression where TLSv1.2 session tickets were incorrectly sent.
Fix by unconditionally disabling TLSv1.2 session tickets and only
disable TLSv1.3 tickets when the right version of OpenSSL is used.

Backpatch to all supported branches.

Reported-by: Cameron Vogt <cvogt@automaticcontrols.net>
Reported-by: Fire Emerald <fire.github@gmail.com>
Reviewed-by: Jacob Champion <jacob.champion@enterprisedb.com>
Discussion: https://postgr.es/m/DM6PR16MB3145CF62857226F350C710D1AB852@DM6PR16MB3145.namprd16.prod.outlook.com
Backpatch-through: v12
2024-08-19 12:55:11 +02:00
Thomas Munro
1cc73d15ea Fix harmless LC_COLLATE[_MASK] confusion.
Commit ca051d8b101 called newlocale(LC_COLLATE, ...) instead of
newlocale(LC_COLLATE_MASK, ...), in code reached only on FreeBSD.  They
have the same value on that OS, explaining why it worked.  Fix.

Back-patch to 14, where ca051d8b101 landed.
2024-08-19 22:21:06 +12:00
Michael Paquier
b7935bc10b Fix more holes with SLRU code in need of int64 for segment numbers
This is a continuation of c9e24573905b, containing changes included into
the proposed patch that have been missed in the actual commit.  I have
managed to miss these diffs while doing a rebase of the original patch.

Thanks to Noah Misch, Peter Eisentraut and Alexander Korotkov for the
pokes.

Discussion: https://postgr.es/m/92fe572d-638e-4162-aef6-1c42a2936f25@eisentraut.org
Discussion: https://postgr.es/m/20240810175055.cd.nmisch@google.com
Backpatch-through: 17
2024-08-19 12:34:52 +09:00
Alvaro Herrera
fad0da271e
Search for SLRU page only in its own bank
One of the two slot scans in SlruSelectLRUPage was not walking only the
slots in the specific bank where the buffer could be; change it to do
that.

Oversight in 53c2a97a9266.

Author: Sergey Sargsyan <sergey.sargsyan.2001@gmail.com>
Discussion: https://postgr.es/m/18582-5f301dd30ba91a38@postgresql.org
2024-08-18 21:04:57 -04:00
Thomas Munro
4b6aa0cffc ci: Upgrade MacPorts version to 2.10.1.
MacPorts version 2.9.3 started failing in our ci_macports_packages.sh
script, for reasons not fully determined, but plausibly linked to the
release of 2.10.1.  2.10.1 seems to work, so let's switch to it.

Back-patch to 15, where CI began.

Reported-by: Peter Eisentraut <peter@eisentraut.org>
Discussion: https://postgr.es/m/81f104e8-f0a9-43c0-85bd-2bbbf590a5b8%40eisentraut.org
2024-08-19 11:48:01 +12:00
Tomas Vondra
d1da801150 Fix DROP DATABASE for databases with many ACLs
Commit c66a7d75e652 modified DROP DATABASE so that if interrupted, the
database is known to be in an invalid state and can only be dropped.
This is done by setting a flag using an in-place update, so that it's
not lost in case of rollback.

For databases with many ACLs, this may however fail like this:

  ERROR:  wrong tuple length

This happens because with many ACLs, the pg_database.datacl attribute
gets TOASTed. The dropdb() code reads the tuple from the syscache, which
means it's detoasted. But the in-place update expects the tuple length
to match the on-disk tuple.

Fixed by reading the tuple from the catalog directly, not from syscache.

Report and fix by Ayush Tiwari. Backpatch to 12. The DROP DATABASE fix
was backpatched to 11, but 11 is EOL at this point.

Reported-by: Ayush Tiwari
Author: Ayush Tiwari
Reviewed-by: Tomas Vondra
Backpatch-through: 12
Discussion: https://postgr.es/m/CAJTYsWWNkCt+-UnMhg=BiCD3Mh8c2JdHLofPxsW3m2dkDFw8RA@mail.gmail.com
2024-08-19 00:05:23 +02:00
Bruce Momjian
a95f13cbfb docs: fix incorrect plpgsql error message
Change "$1" to "username".

Reported-by: philipp.salvisberg@gmail.com

Discussion: https://postgr.es/m/172112109590.736590.12219129462878821880@wrigleys.postgresql.org

Backpatch-through: 12
2024-08-16 22:50:54 -04:00
Bruce Momjian
35af4bd951 doc PG 17 relnotes: fix incorrect reference to huge_page_status
Reported-by: Justin Pryzby

Discussion: https://postgr.es/m/ZrTOaaxuG3JRSvwM@pryzbyj2023

Backpatch-through: 17 only
2024-08-16 13:11:23 -04:00
Bruce Momjian
6b84ae65fb doc PG 17 relnotes: improve text for pg_walfile_name*()
Reported-by: Yugo Nagata

Discussion: https://postgr.es/m/20240726132224.3a77e79c4e563125c451e865@sraoss.co.jp

Backpatch-through: 17 only
2024-08-16 13:01:34 -04:00
Bruce Momjian
0ed4a84b7c doc PG 17 relnotes: fix pg_statistic_ext.stxstattarget ref.
Reported-by: Kisoon Kwon

Discussion: https://postgr.es/m/CAGOrKoVhjP_AeKGgzxWjRwdPqKL5Y-3TcVZoaz0bVTPwU8Yz+g@mail.gmail.com

Backpatch-through: 17 only
2024-08-16 12:53:02 -04:00
Peter Eisentraut
47b47a5617 Remove incidental md5() function use from test
To allow test to pass in OpenSSL FIPS mode, similar to 657f5f223e, for
a new test that has been added since.

Reviewed-by: Tomas Vondra <tomas@vondra.me>
Discussion: https://www.postgresql.org/message-id/86763810-70a1-4872-8ba7-1676f788e5a2@eisentraut.org
2024-08-16 17:25:57 +02:00
Heikki Linnakangas
68f199cea3 Relax fsyncing at end of a bulk load that was not WAL-logged
And improve the comments.

Backpatch to v17 where this was introduced.

Reviewed-by: Noah Misch
Discussion: https://www.postgresql.org/message-id/cac7d1b6-8358-40be-af0b-21bc9b27d34c@iki.fi
2024-08-16 14:45:59 +03:00
Jeff Davis
225483238d Fix doc typo: unicode_assigned() return type.
Reported-by: Hironobu SUZUKI
Discussion: https://postgr.es/m/5dd88820-bb00-4b90-904b-738ea2e4ee2e@interdb.jp
Backpatch-through: 17
2024-08-14 19:07:34 -07:00
Peter Eisentraut
253c49e075 Use errmsg_internal for debug messages
Some newer code was applying this inconsistently.
2024-08-13 10:05:56 +02:00
Alvaro Herrera
0820f80622
Fix creation of partition descriptor during concurrent detach+drop
If a partition undergoes DETACH CONCURRENTLY immediately followed by
DROP, this could cause a problem for a concurrent transaction
recomputing the partition descriptor when running a prepared statement,
because it tries to dereference a pointer to a tuple that's not found in
a catalog scan.

The existing retry logic added in commit dbca3469ebf8 is sufficient to
cope with the overall problem, provided we don't try to dereference a
non-existant heap tuple.

Arguably, the code in RelationBuildPartitionDesc() has been wrong all
along, since no check was added in commit 898e5e3290a7 against receiving
a NULL tuple from the catalog scan; that bug has only become
user-visible with DETACH CONCURRENTLY which was added in branch 14.
Therefore, even though there's no known mechanism to cause a crash
because of this, backpatch the addition of such a check to all supported
branches.  In branches prior to 14, this would cause the code to fail
with a "missing relpartbound for relation XYZ" error instead of
crashing; that's okay, because there are no reports of such behavior
anyway.

Author: Kuntal Ghosh <kuntalghosh.2007@gmail.com>
Reviewed-by: Junwang Zhao <zhjwpku@gmail.com>
Reviewed-by: Tender Wang <tndrwang@gmail.com>
Discussion: https://postgr.es/m/18559-b48286d2eacd9a4e@postgresql.org
2024-08-12 18:17:56 -04:00
Tom Lane
e57296ed48 Log more info when wait-for-catchup tests time out.
Cluster.pm's wait_for_catchup and allied subroutines don't provide
enough information to diagnose the problem when a wait times out.
In hopes of debugging some intermittent buildfarm failures, let's
dump the ending state of the relevant system view when that happens.

Add this to v17 too, but not stable branches.

Discussion: https://postgr.es/m/352068.1723422725@sss.pgh.pa.us
2024-08-12 13:18:36 -04:00
Tom Lane
aed881386a Suppress Coverity warnings about Asserts in get_name_for_var_field.
Coverity thinks dpns->plan could be null at these points.  That
shouldn't really be possible, but it's easy enough to modify the
Asserts so they'd not core-dump if it were true.

These are new in b919a97a6.  Back-patch to v13; the v12 version
of the patch didn't have these Asserts.
2024-08-11 12:24:56 -04:00
Tom Lane
2b8d33f66c Allow adjusting session_authorization and role in parallel workers.
The code intends to allow GUCs to be set within parallel workers
via function SET clauses, but not otherwise.  However, doing so fails
for "session_authorization" and "role", because the assign hooks for
those attempt to set the subsidiary "is_superuser" GUC, and that call
falls foul of the "not otherwise" prohibition.  We can't switch to
using GUC_ACTION_SAVE for this, so instead add a new GUC variable
flag GUC_ALLOW_IN_PARALLEL to mark is_superuser as being safe to set
anyway.  (This is okay because is_superuser has context PGC_INTERNAL
and thus only hard-wired calls can change it.  We'd need more thought
before applying the flag to other GUCs; but maybe there are other
use-cases.)  This isn't the prettiest fix perhaps, but other
alternatives we thought of would be much more invasive.

While here, correct a thinko in commit 059de3ca4: when rejecting
a GUC setting within a parallel worker, we should return 0 not -1
if the ereport doesn't longjmp.  (This seems to have no consequences
right now because no caller cares, but it's inconsistent.)  Improve
the comments to try to forestall future confusion of the same kind.

Despite the lack of field complaints, this seems worth back-patching.
Thanks to Nathan Bossart for the idea to invent a new flag,
and for review.

Discussion: https://postgr.es/m/2833457.1723229039@sss.pgh.pa.us
2024-08-10 15:51:28 -04:00
John Naylor
2eda3df9ad Lower minimum maintenance_work_mem to 64kB
Since the introduction of TID store, vacuum uses far less memory in
the common case than in versions 16 and earlier. Invoking multiple
rounds of index vacuuming in turn requires a much larger table. It'd
be a good idea anyway to cover this case in regression testing, and a
lower limit is less painful for slow buildfarm animals. The reason to
do it now is to re-enable coverage of the bugfix in commit 83c39a1f7f.

For consistency, give autovacuum_work_mem the same treatment.

Suggested by Andres Freund
Tested by Melanie Plageman
Backpatch to v17, where TID store was introduced

Discussion: https://postgr.es/m/20240516205458.ohvlzis5b5tvejru@awork3.anarazel.de
Discussion: https://postgr.es/m/20240722164745.fvaoh6g6zprisqgp%40awork3.anarazel.de
2024-08-10 14:59:13 +07:00
Nathan Bossart
6bec76faa4 doc: Fix name of CRC algorithm in "Reliability" section.
This section claims we use CRC-32 for WAL records and two-phase
state files, but we've actually used CRC-32C since v9.5 (commit
5028f22f6e).  Fix that.

Reviewed-by: Robert Haas
Discussion: https://postgr.es/m/ZrUFpLP-w2zTAHqq%40nathan
Backpatch-through: 12
2024-08-09 10:52:37 -05:00
Tom Lane
81a12a4477 Fix "failed to find plan for subquery/CTE" errors in EXPLAIN.
To deparse a reference to a field of a RECORD-type output of a
subquery, EXPLAIN normally digs down into the subquery's plan to try
to discover exactly which anonymous RECORD type is meant.  However,
this can fail if the subquery has been optimized out of the plan
altogether on the grounds that no rows could pass the WHERE quals,
which has been possible at least since 3fc6e2d7f.  There isn't
anything remaining in the plan tree that would help us, so fall back
to printing the field name as "fN" for the N'th column of the record.
(This will actually be the right thing some of the time, since it
matches the column names we assign to RowExprs.)

In passing, fix a comment typo in create_projection_plan, which
I noticed while experimenting with an alternative fix for this.

Per bug #18576 from Vasya B.  Back-patch to all supported branches.

Richard Guo and Tom Lane

Discussion: https://postgr.es/m/18576-9feac34e132fea9e@postgresql.org
2024-08-09 11:21:39 -04:00
Alvaro Herrera
344f9f5e2b
Refuse ATTACH of a table referenced by a foreign key
Trying to attach a table as a partition which is already on the
referenced side of a foreign key on the partitioned table that it is
being attached to, leads to strange behavior: we try to clone the
foreign key from the parent to the partition, but this new FK points to
the partition itself, and the mix of pg_constraint rows and triggers
doesn't behave well.

Rather than trying to untangle the mess (which might be possible given
sufficient time), I opted to forbid the ATTACH.  This doesn't seem a
problematic restriction, given that we already fail to create the
foreign key if you do it the other way around, that is, having the
partition first and the FK second.

Backpatch to all supported branches.

Reported-by: Alexander Lakhin <exclusion@gmail.com>
Reviewed-by: Tender Wang <tndrwang@gmail.com>
Discussion: https://postgr.es/m/18541-628a61bc267cd2d3@postgresql.org
2024-08-08 19:35:13 -04:00
Alvaro Herrera
28b953f263
Refactor error messages to reduce duplication
I also took the liberty of changing

	errmsg("COPY DEFAULT only available using COPY FROM")
to
	errmsg("COPY %s cannot be used with %s", "DEFAULT", "COPY TO")

because the original wording is unlike all other messages that indicate
option incompatibility.  This message was added by commit 9f8377f7a279
(16-era), in whose development thread there was no discussion on this
point.

Backpatch to 17.
2024-08-08 15:17:11 -04:00
Heikki Linnakangas
a7bf3e6685 Fix pg_rewind debug output to print the source timeline history
getTimelineHistory() is called twice, to read the source and the
target timeline history files. However, the loop to print the file
with the --debug option used the wrong variable when dealing with the
source. As a result, the source's history was always printed as empty.

Spotted while debugging bug #18575, but this does not fix that bug,
just the debugging output. Backpatch to all supported versions.

Discussion: https://www.postgresql.org/message-id/092dd515-b7b4-4fd0-8407-ceca2f02f6ec@iki.fi
2024-08-08 10:21:12 +03:00
Peter Eisentraut
e9e05c6550 Revert ECPG's use of pnstrdup()
Commit 0b9466fce added a dependency on fe_memutils' pnstrdup() inside
informix.c.  This adds an exit() path in a library, which we don't
want.  (Unlike libpq, the ecpg libraries don't have an automated check
for that, but it makes sense to keep them to a similar standard.)  The
ecpg code can already handle failure results from the *strdup() call
by itself.

Author: Jacob Champion <jacob.champion@enterprisedb.com>
Discussion: https://www.postgresql.org/message-id/CAOYmi+=pg=W5L1h=3MEP_EB24jaBu2FyATrLXqQHGe7cpuvwyg@mail.gmail.com
2024-08-08 07:41:02 +02:00
Noah Misch
75345f6985 Fix names of "Visual Studio" and Meson in a documentation sentence.
Commit 3cffe7946c268be91a340ec9a27081cb93d67d35 missed this.  Back-patch
to v17, which introduced this.

Discussion: https://postgr.es/m/CAJ7c6TM7ct0EjoCQaLSVYoxxnEw4xCUFebWj77GktWsqEdyCtQ@mail.gmail.com
2024-08-07 11:43:18 -07:00
Tom Lane
0dd33a6fca Fix edge case in plpgsql's make_callstmt_target().
If the plancache entry for the CALL statement is already stale,
it's possible for us to fetch an old procedure OID out of it,
and then fail with "cache lookup failed for function NNN".
In ordinary usage this never happens because make_callstmt_target
is called just once immediately after building the plancache
entry.  It can be forced however by setting up an erroneous CALL
(that causes make_callstmt_target itself to report an error),
then dropping/recreating the target procedure, then repeating
the erroneous CALL.

To fix, use SPI_plan_get_cached_plan() to fetch the plancache's
plan, rather than assuming we can use SPI_plan_get_plan_sources().
This shouldn't add any noticeable overhead in the normal case,
and in the stale-plan case we'd have had to replan anyway a little
further down.

The other callers of SPI_plan_get_plan_sources() seem OK, because
either they don't need up-to-date plans or they know that the
query was just (re) planned.  But add some commentary in hopes
of not falling into this trap again.

Per bug #18574 from Song Hongyu.  Back-patch to v14 where this coding
was introduced.  (Older branches have comparable code, but it's run
after any required replanning, so there's no issue.)

Discussion: https://postgr.es/m/18574-2ce7ba3249221389@postgresql.org
2024-08-07 12:54:39 -04:00
Alvaro Herrera
899f39ea25
Refactor/reword some error messages to avoid duplicates
Also, remove brackets around "EMPTY [ ARRAY ]".  An error message is
not the place to state that a keyword is optional.

Backpatch to 17.
2024-08-07 11:30:36 -04:00
Heikki Linnakangas
ffac8ac48e Make fallback MD5 implementation thread-safe on big-endian systems
Replace a static scratch buffer with a local variable, because a
static buffer makes the function not thread-safe. This function is
used in client-code in libpq, so it needs to be thread-safe. It was
until commit b67b57a966, which replaced the implementation with the
one from pgcrypto.

Backpatch to v14, where we switched to the new implementation.

Reviewed-by: Robert Haas, Michael Paquier
Discussion: https://www.postgresql.org/message-id/dfa2015d-ad21-4802-a4cc-3850fc5fff3f@iki.fi
2024-08-07 10:44:00 +03:00
Tom Lane
b18b3a8150 Stamp 17beta3. 2024-08-05 16:03:01 -04:00
Masahiko Sawada
fdf218f1d5 Restrict accesses to non-system views and foreign tables during pg_dump.
When pg_dump retrieves the list of database objects and performs the
data dump, there was possibility that objects are replaced with others
of the same name, such as views, and access them. This vulnerability
could result in code execution with superuser privileges during the
pg_dump process.

This issue can arise when dumping data of sequences, foreign
tables (only 13 or later), or tables registered with a WHERE clause in
the extension configuration table.

To address this, pg_dump now utilizes the newly introduced
restrict_nonsystem_relation_kind GUC parameter to restrict the
accesses to non-system views and foreign tables during the dump
process. This new GUC parameter is added to back branches too, but
these changes do not require cluster recreation.

Back-patch to all supported branches.

Reviewed-by: Noah Misch
Security: CVE-2024-7348
Backpatch-through: 12
2024-08-05 06:05:30 -07:00
Peter Eisentraut
91099bb287 Translation updates
Source-Git-URL: https://git.postgresql.org/git/pgtranslation/messages.git
Source-Git-Hash: f1fa38f3bf3e0a5d3a95304dcf6a11acf304577c
2024-08-05 12:12:32 +02:00
Noah Misch
c175c9202d Fix name of "Visual Studio" in documentation.
Back-patch to v17, which introduced this.

Aleksander Alekseev

Discussion: https://postgr.es/m/CAJ7c6TM7ct0EjoCQaLSVYoxxnEw4xCUFebWj77GktWsqEdyCtQ@mail.gmail.com
2024-08-02 12:50:11 -07:00
Alvaro Herrera
ca26455348
Fix NLS file reference in pg_createsubscriber
pg_createsubscriber is referring to a non-existent message translation
file, causing NLS to not work correctly. This command should use the
same file as pg_basebackup.

Author: Kyotaro Horiguchi <horikyota.ntt@gmail.com>
Discussion: https://postgr.es/m/20240802.115717.1083441453338151622.horikyota.ntt@gmail.com
2024-08-02 12:05:38 -04:00
Alvaro Herrera
8c6ba6e6a8
pg_createsubscriber: Fix bogus error message
Also some desultory style improvement
2024-08-02 12:01:10 -04:00
Peter Eisentraut
83737ef89c pg_createsubscriber: Rename option --socket-directory to --socketdir
For consistency with the equivalent option in pg_upgrade.

Reviewed-by: Hayato Kuroda <kuroda.hayato@fujitsu.com>
Reviewed-by: Euler Taveira <euler@eulerto.com>
Discussion: https://www.postgresql.org/message-id/flat/1ed82b9b-8e20-497d-a2f8-aebdd793d595%40eisentraut.org
2024-08-01 12:14:08 +02:00
Etsuro Fujita
eb39497eed Update comment in portal.h.
We store tuples into the portal's tuple store for a PORTAL_ONE_MOD_WITH
query as well.

Back-patch to all supported branches.

Reviewed by Andy Fan.

Discussion: https://postgr.es/m/CAPmGK14HVYBZYZtHabjeCd-e31VT%3Dwx6rQNq8QfehywLcpZ2Hw%40mail.gmail.com
2024-08-01 17:45:00 +09:00
Tom Lane
630b81d5cc Revert "Allow parallel workers to cope with a newly-created session user ID."
This reverts commit 5887dd4894db5ac1c6411615160555ac6e57e49b.

Some buildfarm animals are failing with "cannot change
"client_encoding" during a parallel operation".  It looks like
assign_client_encoding is unhappy at being asked to roll back a
client_encoding setting after a parallel worker encounters a
failure.  There must be more to it though: why didn't I see this
during local testing?  In any case, it's clear that moving the
RestoreGUCState() call is not as side-effect-free as I thought.
Given that the bug f5f30c22e intended to fix has gone unreported
for years, it's not something that's urgent to fix; I'm not
willing to risk messing with it further with only days to our
next release wrap.
2024-07-31 20:54:31 -04:00
Tom Lane
5887dd4894 Allow parallel workers to cope with a newly-created session user ID.
Parallel workers failed after a sequence like
	BEGIN;
	CREATE USER foo;
	SET SESSION AUTHORIZATION foo;
because check_session_authorization could not see the uncommitted
pg_authid row for "foo".  This is because we ran RestoreGUCState()
in a separate transaction using an ordinary just-created snapshot.
The same disease afflicts any other GUC that requires catalog lookups
and isn't forgiving about the lookups failing.

To fix, postpone RestoreGUCState() into the worker's main transaction
after we've set up a snapshot duplicating the leader's.  This affects
check_transaction_isolation and check_transaction_deferrable, which
think they should only run during transaction start.  Make them
act like check_transaction_read_only, which already knows it should
silently accept the value when InitializingParallelWorker.

Per bug #18545 from Andrey Rachitskiy.  Back-patch to all
supported branches, because this has been wrong for awhile.

Discussion: https://postgr.es/m/18545-feba138862f19aaa@postgresql.org
2024-07-31 18:54:10 -04:00
David Rowley
3256722d7b Doc: mention executor memory usage for enable_partitionwise* GUCs
Prior to this commit, the docs for enable_partitionwise_aggregate and
enable_partitionwise_join mentioned the additional overheads enabling
these causes for the query planner, but they mentioned nothing about the
possible surge in work_mem-consuming executor nodes that could end up in
the final plan.  Dimitrios reported the OOM killer intervened on his
query as a result of using enable_partitionwise_aggregate=on.

Here we adjust the docs to mention the possible increase in the number of
work_mem-consuming executor nodes that can appear in the final plan as a
result of enabling these GUCs.

Reported-by: Dimitrios Apostolou
Reviewed-by: Ashutosh Bapat
Discussion: https://postgr.es/m/3603c380-d094-136e-e333-610914fb3e80%40gmx.net
Discussion: https://postgr.es/m/CAApHDvoZ0_yqwPFEpb6h261L76BUpmh5GxBQq0LeRzQ5Jh3zzg@mail.gmail.com
Backpatch-through: 12, oldest supported version
2024-08-01 01:26:16 +12:00
Jeff Davis
10fdc67f81 Relax check for return value from second call of pg_strnxfrm().
strxfrm() is not guaranteed to return the exact number of bytes needed
to store the result; it may return a higher value.

Discussion: https://postgr.es/m/32f85d88d1f64395abfe5a10dd97a62a4d3474ce.camel@j-davis.com
Reviewed-by: Heikki Linnakangas
Backpatch-through: 16
2024-07-30 16:25:03 -07:00
Andrew Dunstan
0d57dc2f91 Preserve tz when converting to jsonb timestamptz
This removes an inconsistency in the treatment of different datatypes by
the jsonpath timestamp_tz() function. Conversions from data types that
are not timestamp-aware, such as date and timestamp, are now treated
consistently with conversion from those that are such as timestamptz.

Author: David Wheeler
Reviewed-by: Junwang Zhao and Jeevan Chalke

Discussion: https://postgr.es/m/7DE080CE-6D8C-4794-9BD1-7D9699172FAB%40justatheory.com

Backpatch to release 17.
2024-07-30 07:57:16 -04:00
Peter Eisentraut
71795d1cb4 pg_createsubscriber: Remove obsolete comment
This comment should have been removed by commit b9639138262.  There is
no replication slot check on the primary anymore.

Author: Euler Taveira <euler@eulerto.com>
Discussion: https://www.postgresql.org/message-id/697d692f-f9d3-41f6-9f0e-29a4fb18e544@app.fastmail.com
2024-07-30 12:34:04 +02:00
Andrew Dunstan
787ea8c9d8 Stabilize xid_wraparound tests
The tests had a race condition if autovacuum was set to off. Instead we
create all the tables we are interested in with autovacuum disabled, so
they are only ever touched when in danger of wraparound.

Discussion: https://postgr.es/m/3e2cbd24-f45e-4b2b-ba83-8149214f0a4d@dunslane.net

Masahiko Sawada (slightly tweaked by me)

Backpatch to release 17 where these tests were introduced.
2024-07-30 06:26:36 -04:00
Amit Kapila
e5ba6a5ab6 pg_createsubscriber: Fix an unpredictable recovery wait time.
The problem is that the tool is using the LSN returned by
pg_create_logical_replication_slot() as recovery_target_lsn. This LSN is
ahead of the current WAL position and the recovery waits until the
publisher writes a WAL record to reach the target and ends the recovery.
On idle systems, this wait time is unpredictable and could lead to failure
in promoting the subscriber. To avoid that, insert a harmless WAL record.

Reported-by: Alexander Lakhin and Tom Lane
Diagnosed-by: Hayato Kuroda
Author: Euler Taveira
Reviewed-by: Hayato Kuroda, Amit Kapila
Backpatch-through: 17
Discussion: https://postgr.es/m/2377319.1719766794%40sss.pgh.pa.us
Discussion: https://postgr.es/m/CA+TgmoYcY+Wb67NAwaHT7MvxCSeV86oSc+va9hHKaasE42ukyw@mail.gmail.com
2024-07-30 14:17:30 +05:30
Amit Langote
f95c5090d9 SQL/JSON: Fix casting for integer EXISTS columns in JSON_TABLE
The current method of coercing the boolean result value of
JsonPathExists() to the target type specified for an EXISTS column,
which is to call the type's input function via json_populate_type(),
leads to an error when the target type is integer, because the
integer input function doesn't recognize boolean literal values as
valid.

Instead use the boolean-to-integer cast function for coercion in that
case so that using integer or domains thereof as type for EXISTS
columns works. Note that coercion for ON ERROR values TRUE and FALSE
already works like that because the parser creates a cast expression
including the cast function, but the coercion of the actual result
value is not handled by the parser.

Tests by Jian He.

Reported-by: Jian He <jian.universality@gmail.com>
Author: Jian He <jian.universality@gmail.com>
Author: Amit Langote <amitlangote09@gmail.com>
Discussion: https://postgr.es/m/CACJufxEo4sUjKCYtda0_qt9tazqqKPmF1cqhW9KBOUeJFqQd2g@mail.gmail.com
Backpatch-through: 17
2024-07-30 10:39:28 +09:00
Amit Langote
847ee701bd SQL/JSON: Some fixes to JsonBehavior expression casting
1. Remove the special case handling when casting the JsonBehavior
   expressions to types with typmod, like 86d33987 did for the casting
   of SQL/JSON constructor functions.

2. Fix casting for fixed-length character and bit string types by
   using assignment-level casts.  This is again similar to what
   86d33987 did, but for ON ERROR / EMPTY expressions.

3. Use runtime coercion for the boolean ON ERROR constants so that
   using fixed-length character string types, for example, for an
   EXISTS column doesn't cause a "value too long for type
   character(n)" when the parser tries to coerce the default ON ERROR
   value "false" to that type, that is, even when clause is not
   specified.

4. Simplify the conditions of when to use runtime coercion vs
   creating the cast expression in the parser itself.  jsonb-valued
   expressions are now always coerced at runtime and boolean
   expressions too if the target type is a string type for the
   reasons mentioned above.

New tests are from a patch that Jian He posted.  Outputs of some
existing tests change because the coercion now happens at runtime
instead of at parse time.

Reported-by: Jian He <jian.universality@gmail.com>
Author: Jian He <jian.universality@gmail.com>
Author: Amit Langote <amitlangote09@gmail.com>
Discussion: https://postgr.es/m/CACJufxEo4sUjKCYtda0_qt9tazqqKPmF1cqhW9KBOUeJFqQd2g@mail.gmail.com
Backpatch-through: 17
2024-07-30 10:37:56 +09:00
Heikki Linnakangas
f208a16035 Detach syslogger from shared memory
Commit aafc05de1b removed the calls to detach from shared memory from
syslogger startup. That was not intentional, so put them back.

Author: Rui Zhao
Reviewed-by: Aleksander Alekseev
Backpatch-through: 17
Discussion: https://www.postgresql.org/message-id/11505016-8cf3-4691-b996-7faed99b7877.xiyuan.zr@alibaba-inc.com
2024-07-29 22:42:15 +03:00
Tom Lane
81db073a28 Count individual SQL commands in pg_restore's --transaction-size mode.
The initial implementation in commit 959b38d77 counted one action
per TOC entry (except for some special cases for multi-blob BLOBS
entries).  This assumes that TOC entries are all about equally
complex, but it turns out that that assumption doesn't hold up very
well in binary-upgrade mode.  For example, even after the previous
commit I was able to cause backend bloat with tables having many
inherited constraints.  There may be other cases too.  (Since no
serious problems have been reported with --single-transaction mode,
we can conclude that the backend copes well with psql's regular
restore scripts; but before 959b38d77 we never ran binary-upgrade
restores with multi-command transactions.)

To fix, count multi-command TOC entries as N actions, allowing the
transaction size to be scaled down when we hit a complex TOC entry.
Rather than add a SQL parser to pg_restore, approximate "multi
command" by counting semicolons in the TOC entry's defn string.
This will be fooled by semicolons appearing in string literals ---
but the error is in the conservative direction, so it doesn't seem
worth working harder.  The biggest risk is with function/procedure
TOC entries, but we can just explicitly skip those.

(This is undoubtedly a hack, and maybe someday we'll be able to
revert it after fixing the backend's bloat issues or rethinking
what pg_dump emits in binary upgrade mode.  But that surely isn't
a project for v17.)

Thanks to Alexander Korotkov for the let's-count-semicolons idea.

Per report from Justin Pryzby.  Back-patch to v17 where txn_size mode
was introduced.

Discussion: https://postgr.es/m/ZqEND4ZcTDBmcv31@pryzbyj2023
2024-07-29 12:17:24 -04:00
Tom Lane
2fa989e6a3 Reduce number of commands dumpTableSchema emits for binary upgrade.
Avoid issuing a separate SQL UPDATE command for each column when
directly manipulating pg_attribute contents in binary upgrade mode.
With the separate updates, we triggered a relcache invalidation with
each update.  For a table with N columns, that causes O(N^2) relcache
bloat in txn_size mode because the table's newly-created relcache
entry can't be flushed till end of transaction.  Reducing the number
of commands should make it marginally faster as well as avoiding that
problem.

While at it, likewise avoid issuing a separate UPDATE on pg_constraint
for each inherited constraint.  This is less exciting, first because
inherited (non-partitioned) constraints are relatively rare, and
second because the backend has a good deal of trouble anyway with
restoring tables containing many such constraints, due to
MergeConstraintsIntoExisting being horribly inefficient.  But it seems
more consistent to do it this way here too, and it surely can't hurt.

In passing, fix one place in dumpTableSchema that failed to use ONLY
in ALTER TABLE.  That's not a live bug, but it's inconsistent.
Also avoid silently casting away const from string literals.

Per report from Justin Pryzby.  Back-patch to v17 where txn_size mode
was introduced.

Discussion: https://postgr.es/m/ZqEND4ZcTDBmcv31@pryzbyj2023
2024-07-29 11:53:49 -04:00
David Rowley
1e020258e5 Fix incorrect return value for pg_size_pretty(bigint)
pg_size_pretty(bigint) would return the value in bytes rather than PB
for the smallest-most bigint value.  This happened due to an incorrect
assumption that the absolute value of -9223372036854775808 could be
stored inside a signed 64-bit type.

Here we fix that by instead storing that value in an unsigned 64-bit type.

This bug does exist in versions prior to 15 but the code there is
sufficiently different and the bug seems sufficiently non-critical that
it does not seem worth risking backpatching further.

Author: Joseph Koshakow <koshy44@gmail.com>
Discussion: https://postgr.es/m/CAAvxfHdTsMZPWEHUrZ=h3cky9Ccc3Mtx2whUHygY+ABP-mCmUw@mail.gmail.com
Backpatch-through: 15
2024-07-28 22:23:32 +12:00
Peter Eisentraut
821fbd63ea libpq: Use strerror_r instead of strerror
Commit 453c4687377 introduced a use of strerror() into libpq, but that
is not thread-safe.  Fix by using strerror_r() instead.

In passing, update some of the code comments added by 453c4687377, as
we have learned more about the reason for the change in OpenSSL that
started this.

Reviewed-by: Daniel Gustafsson <daniel@yesql.se>
Discussion: Discussion: https://postgr.es/m/b6fb018b-f05c-4afd-abd3-318c649faf18@highgo.ca
2024-07-28 10:19:57 +02:00
Bruce Momjian
7525e4c62f doc PG 17 relnotes: add "()" to PQsocketPoll mention
Backpatch-through: 17 only
2024-07-28 04:10:11 -04:00
Heikki Linnakangas
ed9d044632 Support falling back to non-preferred readline implementation with meson
To build with -Dreadline=enabled one can use either readline or
libedit. The -Dlibedit_preferred flag is supposed to control the order
of names to lookup.  This works fine when either both libraries are
present or -Dreadline is set to auto. However, explicitly enabling
readline with only libedit present, but not setting libedit_preferred,
or alternatively enabling readline with only readline present, but
setting libedit_preferred, too, are both broken. This is because
cc.find_library will throw an error for a not found dependency as soon
as the first required dependency is checked, thus it's impossible to
fallback to the alternative.

Here we only check the second of the two dependencies for
requiredness, thus we only fail when none of the two can be found.

Author: Wolfgang Walther
Reviewed-by: Nazir Bilal Yavuz, Alvaro Herrera, Peter Eisentraut
Reviewed-by: Tristan Partin
Discussion: https://www.postgresql.org/message-id/ca8f37e1-a2c3-40e2-91f6-59c3d3652ad4@technowledgy.de
Backpatch: 16-, where meson support was added
2024-07-27 13:54:16 +03:00
Heikki Linnakangas
eb6765d57c Support absolute bindir/libdir in regression tests with meson
Passing an absolute bindir/libdir will install the binaries and
libraries to <build>/tmp_install/<bindir> and
<build>/tmp_install/<libdir> respectively.

This path is correctly passed to the regression test suite via
configure/make, but not via meson, yet. This is because the "/"
operator in the following expression throws away the whole left side
when the right side is an absolute path:

    test_install_location / get_option('libdir')

This was already correctly handled for dir_prefix, which is likely
absolute as well. This patch handles both bindir and libdir in the
same way - prefixing absolute paths with the tmp_install path
correctly.

Author: Wolfgang Walther
Reviewed-by: Nazir Bilal Yavuz, Alvaro Herrera, Peter Eisentraut
Reviewed-by: Tristan Partin
Discussion: https://www.postgresql.org/message-id/ca8f37e1-a2c3-40e2-91f6-59c3d3652ad4@technowledgy.de
Backpatch: 16-, where meson support was added
2024-07-27 13:54:12 +03:00
Heikki Linnakangas
a32ffeebfa Fallback to clang in PATH with meson
Some distributions put clang into a different path than the llvm
binary path.

For example, this is the case on NixOS / nixpkgs, which failed to find
clang with meson before this patch.

Author: Wolfgang Walther
Reviewed-by: Nazir Bilal Yavuz, Alvaro Herrera, Peter Eisentraut
Reviewed-by: Tristan Partin
Discussion: https://www.postgresql.org/message-id/ca8f37e1-a2c3-40e2-91f6-59c3d3652ad4@technowledgy.de
Backpatch: 16-, where meson support was added
2024-07-27 13:54:06 +03:00
Heikki Linnakangas
469b97c524 Fallback to uuid for ossp-uuid with meson
The upstream name for the ossp-uuid package / pkg-config file is
"uuid". Many distributions change this to be "ossp-uuid" to not
conflict with e2fsprogs.

This lookup fails on distributions which don't change this name, for
example NixOS / nixpkgs. Both "ossp-uuid" and "uuid" are also checked
in configure.ac.

Author: Wolfgang Walther
Reviewed-by: Nazir Bilal Yavuz, Alvaro Herrera, Peter Eisentraut
Reviewed-by: Tristan Partin
Discussion: https://www.postgresql.org/message-id/ca8f37e1-a2c3-40e2-91f6-59c3d3652ad4@technowledgy.de
Backpatch: 16-, where meson support was added
2024-07-27 13:54:01 +03:00
Michael Paquier
e367a413b0 Fix more holes with SLRU code in need of int64 for segment numbers
This is a continuation of 3937cadfd438, taking care of more areas I have
managed to miss previously.

Reported-by: Noah Misch
Reviewed-by: Noah Misch
Discussion: https://postgr.es/m/20240724130059.1f.nmisch@google.com
Backpatch-through: 17
2024-07-27 07:16:59 +09:00
Robert Haas
53b327f83e Wait for WAL summarization to catch up before creating .partial file.
When a standby is promoted, CleanupAfterArchiveRecovery() may decide
to rename the final WAL file from the old timeline by adding ".partial"
to the name. If WAL summarization is enabled and this file is renamed
before its partial contents are summarized, WAL summarization breaks:
the summarizer gets stuck at that point in the WAL stream and just
errors out.

To fix that, first make the startup process wait for WAL summarization
to catch up before renaming the file. Generally, this should be quick,
and if it's not, the user can shut off summarize_wal and try again.
To make this fix work, also teach the WAL summarizer that after a
promotion has occurred, no more WAL can appear on the previous
timeline: previously, the WAL summarizer wouldn't switch to the new
timeline until we actually started writing WAL there, but that meant
that when the startup process was waiting for the WAL summarizer, it
was waiting for an action that the summarizer wasn't yet prepared to
take.

In the process of fixing these bugs, I realized that the logic to wait
for WAL summarization to catch up was spread out in a way that made
it difficult to reuse properly, so this code refactors things to make
it easier.

Finally, add a test case that would have caught this bug and the
previously-fixed bug that WAL summarization sometimes needs to back up
when the timeline changes.

Discussion: https://postgr.es/m/CA+TgmoZGEsZodXC4f=XZNkAeyuDmWTSkpkjCEOcF19Am0mt_OA@mail.gmail.com
2024-07-26 14:51:10 -04:00
Robert Haas
f2af1f4559 Fix indentation. 2024-07-26 12:00:03 -04:00
Daniel Gustafsson
1272cfb727 Fix macro placement in pg_config.h.in
Commit 274bbced85383e831dde accidentally placed the pg_config.h.in
for SSL_CTX_set_num_tickets on the wrong line wrt where autoheader
places it.  Fix by re-arranging and backpatch to the same level as
the original commit.

Reported-by: Marina Polyakova <m.polyakova@postgrespro.ru>
Discussion: https://postgr.es/m/48cebe8c3eaf308bae253b1dbf4e4a75@postgrespro.ru
Backpatch-through: v12
2024-07-26 16:25:56 +02:00
Robert Haas
c7cfbc5157 Allow WAL summarization to back up when timeline changes.
The old code believed that it was not possible to switch timelines
without first replaying all of the WAL from the old timeline, but
that turns out to be false, as demonstrated by an example from Fujii
Masao. As a result, it assumed that summarization would always
continue from the LSN where summarization previously ended. But in
fact, when a timeline switch occurs without replaying all the WAL
from the previous timeline, we can need to back up to an earlier
LSN. Adjust accordingly.

Discussion: https://postgr.es/m/CA+TgmoZGEsZodXC4f=XZNkAeyuDmWTSkpkjCEOcF19Am0mt_OA@mail.gmail.com
2024-07-26 09:59:39 -04:00
Peter Eisentraut
c0c0050708 pg_createsubscriber: Message style improvements
Refactor some messages, improve quoting.
2024-07-26 14:55:15 +02:00
Heikki Linnakangas
f19beba3e3 Fix using injection points at backend startup in EXEC_BACKEND mode
Commit 86db52a506 changed the locking of injection points to use only
atomic ops and spinlocks, to make it possible to define injection
points in processes that don't have a PGPROC entry (yet). However, it
didn't work in EXEC_BACKEND mode, because the pointer to shared memory
area was not initialized until the process "attaches" to all the
shared memory structs. To fix, pass the pointer to the child process
along with other global variables that need to be set up early.

Backpatch-through: 17
2024-07-26 15:12:12 +03:00
Heikki Linnakangas
f06a632a77 Fix fallback behavior when server sends an ERROR early at startup
With sslmode=prefer, the desired behavior is to completely fail the
connection attempt, *not* fall back to a plaintext connection, if the
server responds to the SSLRequest with an error ('E') response instead
of rejecting SSL with an 'N' response. This was broken in commit
05fd30c0e7.

Reported-by: Jacob Champion
Reviewed-by: Michael Paquier
Discussion: https://www.postgresql.org/message-id/CAOYmi%2Bnwvu21mJ4DYKUa98HdfM_KZJi7B1MhyXtnsyOO-PB6Ww%40mail.gmail.com
Backpatch-through: 17
2024-07-26 15:02:29 +03:00
Daniel Gustafsson
3df7f44a8c Disable all TLS session tickets
OpenSSL supports two types of session tickets for TLSv1.3, stateless
and stateful. The option we've used only turns off stateless tickets
leaving stateful tickets active. Use the new API introduced in 1.1.1
to disable all types of tickets.

Backpatch to all supported versions.

Reviewed-by: Heikki Linnakangas <hlinnaka@iki.fi>
Reported-by: Andres Freund <andres@anarazel.de>
Discussion: https://postgr.es/m/20240617173803.6alnafnxpiqvlh3g@awork3.anarazel.de
Backpatch-through: v12
2024-07-26 11:09:45 +02:00
Amit Langote
8a1a4087bd SQL/JSON: Remove useless code in ExecInitJsonExpr()
The code was for adding an unconditional JUMP to the next step,
which is unnecessary processing.

Reported-by: Jian He <jian.universality@gmail.com>
Discussion: https://postgr.es/m/CACJufxEo4sUjKCYtda0_qt9tazqqKPmF1cqhW9KBOUeJFqQd2g@mail.gmail.com
Backpatch-through: 17
2024-07-26 16:37:59 +09:00
Amit Langote
3c3ccd4ca8 SQL/JSON: Respect OMIT QUOTES when RETURNING domains over jsonb
populate_domain() didn't take into account the omit_quotes flag passed
down to json_populate_type() by ExecEvalJsonCoercion() and that led
to incorrect behavior when the RETURNING type is a domain over
jsonb.  Fix that by passing the flag by adding a new function
parameter to populate_domain().

Reported-by: Jian He <jian.universality@gmail.com>
Discussion: https://postgr.es/m/CACJufxEo4sUjKCYtda0_qt9tazqqKPmF1cqhW9KBOUeJFqQd2g@mail.gmail.com
Backpatch-through: 17
2024-07-26 16:36:10 +09:00
Amit Langote
d1dc4ae560 SQL/JSON: Improve error-handling of JsonBehavior expressions
Instead of returning a NULL when the JsonBehavior expression value
could not be coerced to the RETURNING type, throw the error message
informing the user that it is the JsonBehavior expression that caused
the error with the actual coercion error message shown in its DETAIL
line.

Discussion: https://postgr.es/m/CACJufxEo4sUjKCYtda0_qt9tazqqKPmF1cqhW9KBOUeJFqQd2g@mail.gmail.com
Backpatch-through: 17
2024-07-26 16:36:06 +09:00
Amit Langote
79fa052e78 SQL/JSON: Fix error-handling of some JsonBehavior expressions
To ensure that the errors of executing a JsonBehavior expression that
is coerced in the parser are caught instead of being thrown directly,
pass ErrorSaveContext to ExecInitExprRec() when initializing it.
Also, add a EEOP_JSONEXPR_COERCION_FINISH step to handle the errors
that are caught that way.

Discussion: https://postgr.es/m/CACJufxEo4sUjKCYtda0_qt9tazqqKPmF1cqhW9KBOUeJFqQd2g@mail.gmail.com
Backpatch-through: 17
2024-07-26 16:36:02 +09:00
Tom Lane
facd895871 Doc: fix misleading syntax synopses for targetlists.
In the syntax synopses for SELECT, INSERT, UPDATE, etc,
SELECT ... and RETURNING ... targetlists were missing { ... }
braces around an OR (|) operator.  That allows misinterpretation
which could lead to confusion.

David G. Johnston, per gripe from masondeanm@aol.com.

Discussion: https://postgr.es/m/172193970148.915373.2403176471224676074@wrigleys.postgresql.org
2024-07-25 19:52:08 -04:00
Robert Haas
de8b098ce5 Document restrictions regarding incremental backups and standbys.
If you try to take an incremental backup on a standby and there hasn't
been much system activity, it might fail. Document why this happens.
Also add a hint to the error message you get, to make it more likely
that users will understand what has gone wrong.

Laurenz Albe and Robert Haas

Discussion: https://postgr.es/m/5468641ad821dad7aa3b2d65bf843146443a1b68.camel@cybertec.at
2024-07-25 16:09:24 -04:00
Peter Eisentraut
6622da8d3c pg_createsubscriber: Message improvements
Objects are typically "in" a database, not "on".
2024-07-25 15:29:50 +02:00
Peter Eisentraut
b5006abcdc Remove useless unconstify() call
This should have been part of 67c0ef9752 but was apparently forgotten
there.
2024-07-25 11:39:14 +02:00
Thomas Munro
5f03da8518 ci: Pin MacPorts version to 2.9.3.
Commit d01ce180 invented a new way to find the latest MacPorts version.
By bad luck, a new beta release has just been published, and it seems
to lack some packages we need.  Go back to searching for this specific
version for now.  We still search with a pattern so that we can find the
package for the running version of macOS, but for now we always look for
2.9.3.  The code to do that had been anticipated already in a commented
out line, I just didn't expect to have to use it so soon...

Also include the whole MacPorts installation script in the cache key, so
that changes to the script cause a fresh installation.  This should make
it a bit easier to reason about the effect of changes on cached state in
github accounts using CI, when we make adjustments.

Back-patch to 15, like d01ce180.

Discussion: https://postgr.es/m/CA%2BhUKGLqJdv6RcwyZ_0H7khxtLTNJyuK%2BvDFzv3uwYbn8hKH6A%40mail.gmail.com
2024-07-25 14:48:18 +12:00
Thomas Munro
f8c1bb2bb9 ci: Upgrade macOS version from 13 to 14.
1.  Previously we were using ghcr.io/cirruslabs/macos-XXX-base:latest
images, but Cirrus has started ignoring that and using a particular
image, currently ghcr.io/cirruslabs/macos-runner:sonoma, for github
accounts using free CI resources (as opposed to dedicated runner
machines, as cfbot uses).  Let's just ask for that image anyway, to stay
in sync.

2.  Instead of hard-coding a MacPorts installation URL, deduce it from
the running macOS version and the available releases.  This removes the
need to keep the ci_macports_packages.sh in sync with .cirrus.task.yml,
and to advance the MacPorts version from time to time.

3.  Change the cache key we use to cache the whole macports installation
across builds to include the OS major version, to trigger a fresh
installation when appropriate.

Back-patch to 15 where CI began.

Reviewed-by: Andres Freund <andres@anarazel.de>
Discussion: https://postgr.es/m/CA%2BhUKGLqJdv6RcwyZ_0H7khxtLTNJyuK%2BvDFzv3uwYbn8hKH6A%40mail.gmail.com
2024-07-25 11:31:17 +12:00
Nathan Bossart
73de50e13e pg_upgrade: Retrieve subscription count more efficiently.
Presently, pg_upgrade obtains the number of subscriptions in the
to-be-upgraded cluster by first querying pg_subscription in every
database for the number of subscriptions in only that database.
Then, in count_old_cluster_subscriptions(), it adds all the values
collected in the first step.  This is expensive, especially when
there are many databases.

Fortunately, there is a better way to retrieve the subscription
count.  Since pg_subscription is a shared catalog, we only need to
connect to a single database and query it once.  This commit
modifies pg_upgrade to use that approach, which also allows us to
trim several lines of code.  In passing, move the call to
get_db_subscription_count(), which has been renamed to
get_subscription_count(), from get_db_rel_and_slot_infos() to the
dedicated >= v17 section in check_and_dump_old_cluster().

We may be able to make similar improvements to
get_old_cluster_logical_slot_infos(), but that is left as a future
exercise.

Reviewed-by: Michael Paquier, Amit Kapila
Discussion: https://postgr.es/m/ZprQJv_TxccN3tkr%40nathan
Backpatch-through: 17
2024-07-24 11:30:33 -05:00
Alvaro Herrera
0cc57dca29
Fix a missing article in the documentation
Per complaint from Grant Gryczan.

It's a very old typo; backpatch all the way back.

Author: Laurenz Albe <laurenz.albe@cybertec.at>
Discussion: https://postgr.es/m/172179789219.915368.16590585529628354757@wrigleys.postgresql.org
2024-07-24 14:13:55 +02:00
Alvaro Herrera
2b22543a44
Reset relhassubclass upon attaching table as a partition
We don't allow inheritance parents as partitions, and have checks to
prevent this; but if a table _was_ in the past an inheritance parents
and all their children are removed, the pg_class.relhassubclass flag
may remain set, which confuses the partition pruning code (most
obviously, it results in an assertion failure; in production builds it
may be worse.)

Fix by resetting relhassubclass on attach.

Backpatch to all supported versions.

Reported-by: Alexander Lakhin <exclusion@gmail.com>
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/18550-d5e047e9a897a889@postgresql.org
2024-07-24 12:38:18 +02:00
Amit Kapila
20aaa634f7 Doc: Fix the mistakes in the subscription's failover option.
The documentation incorrectly stated that users could not alter the
subscription's failover option when the two-phase commit is enabled.

The steps to confirm that the standby server is ready for failover were
incorrect.

Author: Shveta Malik, Hou Zhijie
Reviewed-by: Amit Kapila
Discussion: https://postgr.es/m/OS0PR01MB571657B72F8D75BD858DCCE394AD2@OS0PR01MB5716.jpnprd01.prod.outlook.com
Discussion: https://postgr.es/m/CAJpy0uBBk+OZXXqQ00Gai09XR+mDi2=9sMBYY0F+BedoFivaMA@mail.gmail.com
2024-07-24 15:30:58 +05:30
Nathan Bossart
657e54a058 Detect integer overflow in array_set_slice().
When provided an empty initial array, array_set_slice() fails to
check for overflow when computing the new array's dimensions.
While such overflows are ordinarily caught by ArrayGetNItems(),
commands with the following form are accepted:

	INSERT INTO t (i[-2147483648:2147483647]) VALUES ('{}');

To fix, perform the hazardous computations using overflow-detecting
arithmetic routines.  As with commit 18b585155a, the added test
cases generate errors that include a platform-dependent value, so
we again use psql's VERBOSITY parameter to suppress printing the
message text.

Reported-by: Alexander Lakhin
Author: Joseph Koshakow
Reviewed-by: Jian He
Discussion: https://postgr.es/m/31ad2cd1-db94-bdb3-f91a-65ffdb4bef95%40gmail.com
Backpatch-through: 12
2024-07-23 21:59:02 -05:00
Michael Paquier
165ea79a60 Use more consistently int64 for page numbers in SLRU-related code
clog.c, async.c and predicate.c included some SLRU page numbers still
handled as 4-byte integers, while int64 should be used for this purpose.

These holes have been introduced in 4ed8f0913bfd, that has introduced
the use of 8-byte integers for SLRU page numbers, still forgot about the
code paths updated by this commit.

Reported-by: Noah Misch
Author: Aleksander Alekseev, Michael Paquier
Discussion: https://postgr.es/m/20240626002747.dc.nmisch@google.com
Backpatch-through: 17
2024-07-23 17:59:20 +09:00
Michael Paquier
3b279d89cb Improve comments in slru.{c,h} about segment name format
slru.h described incorrectly how SLRU segment names are formatted
depending on the segment number and if long or short segment names are
used.  This commit closes the gap with a better description, fitting
with the reality.

Reported-by: Noah Misch
Author: Aleksander Alekseev
Discussion: https://postgr.es/m/20240626002747.dc.nmisch@google.com
Backpatch-through: 17
2024-07-23 16:55:09 +09:00
Tom Lane
db46016304 Doc: improve description of plpgsql's FETCH and MOVE commands.
We were not being clear about which variants of the "direction"
clause are permitted in MOVE.  Also, the text seemed to be
written with only the FETCH/MOVE NEXT case in mind, so it
didn't apply very well to other variants.

Also, document that "MOVE count IN cursor" only works if count
is a constant.  This is not the whole truth, because some other
cases such as a parenthesized expression will also work, but
we want to push people to use "MOVE FORWARD count" instead.
The constant case is enough to cover what we allow in plain SQL,
and that seems sufficient to claim support for.

Update a comment in pl_gram.y claiming that we don't document
that point.

Per gripe from Philipp Salvisberg.

Discussion: https://postgr.es/m/172155553388.702.7932496598218792085@wrigleys.postgresql.org
2024-07-22 19:43:27 -04:00
Melanie Plageman
1a3e90948b Revert "Test that vacuum removes tuples older than OldestXmin"
This reverts commit 80c34692e8e674e3b2f150f248ef2002ae2ac3a7.

This test proved to be unstable on the buildfarm, timing out before the
standby could catch up on 32-bit machines where more rows were required
and failing to reliably trigger multiple index vacuum rounds on 64-bit
machines where fewer rows should be required.

Because the instability is only known to be present on versions of
Postgres with TIDStore used for dead TID storage by vacuum, this is only
being reverted on master and REL_17_STABLE.

As having this coverage may be valuable, there is a discussion on the
thread of possible ways to stabilize the test. If that happens, a fixed
test can be committed again.

Backpatch-through: 17
Reported-by: Tom Lane

Discussion: https://postgr.es/m/614152.1721580711%40sss.pgh.pa.us
2024-07-22 16:57:44 -04:00
Robert Haas
e7dabbcebd Initialize wal_level in the initial checkpoint record.
As per Coverity and Tom Lane, commit 402b586d0 (back-patched to v17
as 2b5819e2b) forgot to initialize this new structure member in this
code path.
2024-07-22 15:34:54 -04:00
Robert Haas
6c8d2ea7a5 Add missing call to ConditionVariableCancelSleep().
After calling ConditionVariableSleep() or ConditionVariableTimedSleep()
one or more times, code is supposed to call ConditionVariableCancelSleep()
to remove itself from the waitlist. This code neglected to do so.
As far as I know, that had no observable consequences, but let's make
the code correct.

Discussion: http://postgr.es/m/CA+TgmoYW8eR+KN6zhVH0sin7QH6AvENqw_bkN-bB4yLYKAnsew@mail.gmail.com
2024-07-22 10:10:52 -04:00
Alvaro Herrera
d329a515f4
postgres_fdw: Split out the query_cancel test to its own file
This allows us to skip it in Cygwin, where it's reportedly flaky because
of platform bugs or something.

Backpatch to 17, where the test was introduced by commit 2466d6654f85.

Reported-by: Alexander Lakhin <exclusion@gmail.com>
Discussion: https://postgr.es/m/e4d0cb33-6be5-e4d5-ae49-9eac3ff2b005@gmail.com
2024-07-22 12:49:57 +02:00
Andres Freund
9ac6995d6b meson: Add dependency lookups via names used by cmake
Particularly on windows it's useful to look up dependencies via cmake, instead
of pkg-config. Meson supports doing so. Unfortunately the dependency names
used by various projects often differs between their pkg-config and cmake
files.

This would look a lot neater if we could rely on meson >= 0.60.0...

Reviewed-by: Tristan Partin <tristan@partin.io>
Discussion: https://postgr.es/m/20240709065101.xhc74r3mdg2lmn4w@awork3.anarazel.de
Backpatch: 16-, where meson support was added
2024-07-20 13:51:08 -07:00
Andres Freund
1213875b3a meson: Add support for detecting ossp-uuid without pkg-config
This is necessary as ossp-uuid on windows installs neither a pkg-config nor a
cmake dependency information. Nor is there another supported uuid
implementation available on windows.

Reported-by: Dave Page <dpage@pgadmin.org>
Reviewed-by: Tristan Partin <tristan@partin.io>
Discussion: https://postgr.es/m/20240709065101.xhc74r3mdg2lmn4w@awork3.anarazel.de
Backpatch: 16-, where meson support was added
2024-07-20 13:51:08 -07:00
Andres Freund
a850701c7d meson: Add support for detecting gss without pkg-config
This is required as MIT Kerberos does provide neither pkg-config nor cmake
dependency information on windows.

Reported-by: Dave Page <dpage@pgadmin.org>
Reviewed-by: Tristan Partin <tristan@partin.io>
Discussion: https://postgr.es/m/20240709065101.xhc74r3mdg2lmn4w@awork3.anarazel.de
Backpatch: 16-, where meson support was added
2024-07-20 13:51:08 -07:00
Andres Freund
5b707bb507 meson: Add missing argument to gssapi.h check
These were missing since the initial introduction of the meson based build, in
e6927270cd18. As-is this is unlikely to cause an issue, but a future commit
will add support for detecting gssapi without use of dependency(), which could
fail due to this.

Discussion: https://postgr.es/m/20240708225659.gmyqoosi7km6ysgn@awork3.anarazel.de
Backpatch: 16-, where the meson based build was added
2024-07-20 13:51:08 -07:00
Tom Lane
041a00c480 Correctly check updatability of columns targeted by INSERT...DEFAULT.
If a view has some updatable and some non-updatable columns, we failed
to verify updatability of any columns for which an INSERT or UPDATE
on the view explicitly specifies a DEFAULT item (unless the view has
a declared default for that column, which is rare anyway, and one
would almost certainly not write one for a non-updatable column).
This would lead to an unexpected "attribute number N not found in
view targetlist" error rather than the intended error.

Per bug #18546 from Alexander Lakhin.  This bug is old, so back-patch
to all supported branches.

Discussion: https://postgr.es/m/18546-84a292e759a9361d@postgresql.org
2024-07-20 13:40:15 -04:00
Nathan Bossart
3764ee47f7 Add overflow checks to money type.
None of the arithmetic functions for the the money type handle
overflow.  This commit introduces several helper functions with
overflow checking and makes use of them in the money type's
arithmetic functions.

Fixes bug #18240.

Reported-by: Alexander Lakhin
Author: Joseph Koshakow
Discussion: https://postgr.es/m/18240-c5da758d7dc1ecf0%40postgresql.org
Discussion: https://postgr.es/m/CAAvxfHdBPOyEGS7s%2Bxf4iaW0-cgiq25jpYdWBqQqvLtLe_t6tw%40mail.gmail.com
Backpatch-through: 12
2024-07-19 11:52:32 -05:00
Melanie Plageman
80c34692e8 Test that vacuum removes tuples older than OldestXmin
If vacuum fails to prune a tuple killed before OldestXmin, it will
decide to freeze its xmax and later error out in pre-freeze checks.

Add a test reproducing this scenario to the recovery suite which creates
a table on a primary, updates the table to generate dead tuples for
vacuum, and then, during the vacuum, uses a replica to force
GlobalVisState->maybe_needed on the primary to move backwards and
precede the value of OldestXmin set at the beginning of vacuuming the
table.

This commit is separate from the fix in case there are test stability
issues.

Author: Melanie Plageman
Reviewed-by: Peter Geoghegan
Discussion: https://postgr.es/m/CAAKRu_apNU2MPBK96V%2BbXjTq0RiZ-%3DA4ZTaysakpx9jxbq1dbQ%40mail.gmail.com
2024-07-19 12:12:03 -04:00
Melanie Plageman
fd4f12df5e Ensure vacuum removes all visibly dead tuples older than OldestXmin
If vacuum fails to remove a tuple with xmax older than
VacuumCutoffs->OldestXmin and younger than GlobalVisState->maybe_needed,
it may attempt to freeze the tuple's xmax and then ERROR out in
pre-freeze checks with "cannot freeze committed xmax".

Fix this by having vacuum always remove tuples older than OldestXmin.

It is possible for GlobalVisState->maybe_needed to precede OldestXmin if
maybe_needed is forced to go backward while vacuum is running. This can
happen if a disconnected standby with a running transaction older than
VacuumCutoffs->OldestXmin reconnects to the primary after vacuum
initially calculates GlobalVisState and OldestXmin.

In back branches starting with 14, the first version using
GlobalVisState, failing to remove tuples older than OldestXmin during
pruning caused vacuum to infinitely loop in lazy_scan_prune(), as
investigated on this [1] thread. After 1ccc1e05ae removed the retry loop
in lazy_scan_prune() and stopped comparing tuples to OldestXmin, the
hang could no longer happen, but we could still attempt to freeze dead
tuples with xmax older than OldestXmin -- resulting in an ERROR.

Fix this by always removing dead tuples with xmax older than
VacuumCutoffs->OldestXmin. This is okay because the standby won't replay
the tuple removal until the tuple is removable. Thus, the worst that can
happen is a recovery conflict.

[1] https://postgr.es/m/20240415173913.4zyyrwaftujxthf2%40awork3.anarazel.de#1b216b7768b5bd577a3d3d51bd5aadee

Back-patch through 14

Author: Melanie Plageman
Reviewed-by: Peter Geoghegan, Robert Haas, Andres Freund, Heikki Linnakangas, and Noah Misch
Discussion: https://postgr.es/m/CAAKRu_bDD7oq9ZwB2OJqub5BovMG6UjEYsoK2LVttadjEqyRGg%40mail.gmail.com
2024-07-19 12:12:03 -04:00
Heikki Linnakangas
b0a8a7ddd3 Move resowner from common JitContext to LLVM specific
Only the LLVM specific code uses it since resource owners were made
extensible in commit b8bff07daa85c837a2747b4d35cd5a27e73fb7b2. This is
new in v17, so backpatch there to keep the branches from diverging
just yet.

Author: Andreas Karlsson <andreas@proxel.se>
Discussion: https://www.postgresql.org/message-id/fd3a2a00-6605-4e30-a118-48418b478e6e@proxel.se
2024-07-19 10:27:54 +03:00
Etsuro Fujita
935fe79ea1 postgres_fdw: Avoid "cursor can only scan forward" error.
Commit d844cd75a disallowed rewind in a non-scrollable cursor to resolve
anomalies arising from such a cursor operation.  However, this failed to
take into account the assumption in postgres_fdw that when rescanning a
foreign relation, it can rewind the cursor created for scanning the
foreign relation without specifying the SCROLL option, regardless of its
scrollability, causing this error when it tried to do such a rewind in a
non-scrollable cursor.  Fix by modifying postgres_fdw to instead
recreate the cursor, regardless of its scrollability, when rescanning
the foreign relation.  (If we had a way to check its scrollability, we
could improve this by rewinding it if it is scrollable and recreating it
if not, but we do not have it, so this commit modifies it to recreate it
in any case.)

Per bug #17889 from Eric Cyr.  Devrim Gunduz also reported this problem.
Back-patch to v15 where that commit enforced the prohibition.

Reviewed by Tom Lane.

Discussion: https://postgr.es/m/17889-e8c39a251d258dda%40postgresql.org
Discussion: https://postgr.es/m/b415ac3255f8352d1ea921cf3b7ba39e0587768a.camel%40gunduz.org
2024-07-19 13:15:01 +09:00
Michael Paquier
38e271d3c2 Propagate query IDs of utility statements in functions
For utility statements defined within a function, the query tree is
copied to a PlannedStmt as utility commands do not require planning.
However, the query ID was missing from the information passed down.

This leads to plugins relying on the query ID like pg_stat_statements to
not be able to track utility statements within function calls.  Tests
are added to check this behavior, depending on pg_stat_statements.track.

This is an old bug.  Now, query IDs for utilities are compiled using
their parsed trees rather than the query string since v16
(3db72ebcbe20), leading to less bloat with utilities, so backpatch down
only to this version.

Author: Anthonin Bonnefoy
Discussion: https://postgr.es/m/CAO6_XqrGp-uwBqi3vBPLuRULKkddjC7R5QZCgsFren=8E+m2Sg@mail.gmail.com
Backpatch-through: 16
2024-07-19 10:21:21 +09:00
Robert Haas
2b5819e2b4 Do not summarize WAL if generated with wal_level=minimal.
To do this, we must include the wal_level in the first WAL record
covered by each summary file; so add wal_level to struct Checkpoint
and the payload of XLOG_CHECKPOINT_REDO and XLOG_END_OF_RECOVERY.

This, in turn, requires bumping XLOG_PAGE_MAGIC and, since the
Checkpoint is also stored in the control file, also
PG_CONTROL_VERSION. It's not great to do that so late in the release
cycle, but the alternative seems to ship v17 without robust
protections against this scenario, which could result in corrupted
incremental backups.

A side effect of this patch is that, when a server with
wal_level=replica is started with summarize_wal=on for the first time,
summarization will no longer begin with the oldest WAL that still
exists in pg_wal, but rather from the first checkpoint after that.
This change should be harmless, because a WAL summary for a partial
checkpoint cycle can never make an incremental backup possible when
it would otherwise not have been.

Report by Fujii Masao. Patch by me. Review and/or testing by Jakub
Wartak and Fujii Masao.

Discussion: http://postgr.es/m/6e30082e-041b-4e31-9633-95a66de76f5d@oss.nttdata.com
2024-07-18 12:19:29 -04:00
Tom Lane
4cbd8c6022 Doc: fix minor syntax error in example.
The CREATE TABLE option is GENERATED BY DEFAULT *AS* IDENTITY.

Per bug #18543 from Ondřej Navrátil.  Seems to have crept in
in a37bb7c13, so back-patch to v17 where that was added.

Discussion: https://postgr.es/m/18543-93c721689f9928e8@postgresql.org
2024-07-17 15:17:52 -04:00
Nathan Bossart
925479b8d8 Use PqMsg_* macros in more places.
Commit f4b54e1ed9, which introduced macros for protocol characters,
missed updating a few places.  It also did not introduce macros for
messages sent from parallel workers to their leader processes.
This commit adds a new section in protocol.h for those.

Author: Aleksander Alekseev
Discussion: https://postgr.es/m/CAJ7c6TNTd09AZq8tGaHS3LDyH_CCnpv0oOz2wN1dGe8zekxrdQ%40mail.gmail.com
Backpatch-through: 17
2024-07-17 10:51:00 -05:00
Andrew Dunstan
5d797c896f Avoid error in recovery test if history file is not yet present
Error was detected when testing use of libpq sessions instead of psql
for polling queries.

Discussion: https://postgr.es/m/e86b6d2d-20d8-4ac9-9a98-165fff7db886@dunslane.net

Backpatch to all live branches
2024-07-17 10:44:14 -04:00
Amit Langote
2177306a64 SQL/JSON: Rethink c2d93c3802b
This essentially reverts c2d93c3802b except tests. The problem with
c2d93c3802b was that it only changed the casting behavior for types
with typmod, and had coding issues noted in the post-commit review.

This commit changes coerceJsonFuncExpr() to use assignment-level casts
instead of explicit casts to coerce the result of JSON constructor
functions to the specified or the default RETURNING type.  Using
assignment-level casts fixes the problem that using explicit casts was
leading to the wrong typmod / length coercion behavior -- truncating
results longer than the specified length instead of erroring out --
which c2d93c3802b aimed to solve.

That restricts the set of allowed target types to string types, the
same set that's currently allowed.

Discussion: https://postgr.es/m/202406291824.reofujy7xdj3@alvherre.pgsql
2024-07-17 17:13:48 +09:00
Jeff Davis
b4da732fd6 When creating materialized views, use REFRESH to load data.
Previously, CREATE MATERIALIZED VIEW ... WITH DATA populated the MV
the same way as CREATE TABLE ... AS.

Instead, reuse the REFRESH logic, which locks down security-restricted
operations and restricts the search_path. This reduces the chance that
a subsequent refresh will fail.

Reported-by: Noah Misch
Backpatch-through: 17
Discussion: https://postgr.es/m/20240630222344.db.nmisch@google.com
2024-07-16 15:41:22 -07:00
Amit Langote
b6ed3cf4b0 SQL/JSON: Fix a paragraph in JSON_TABLE documentation
Using <replaceable>text</replaceable> inside parantheses is not a
common or good style, so rephrase a sentence to avoid that style.
Also rephrase the text in that paragraph a bit while at it.

Reported-by: Marcos Pegoraro <marcos@f10.com.br>
Author: Jian He <jian.universality@gmail.com>
Reviewed-by: Daniel Gustafsson <daniel@yesql.se>
Reviewed-by: Peter Eisentraut <peter@eisentraut.org>
Discussion: https://postgr.es/m/CAB-JLwZqH3Yec6Kz-4-+pa0ZG9QJBsxjJZwYcMZYzEDR_fXnKw@mail.gmail.com
2024-07-16 14:11:10 +09:00
Andres Freund
ff3cae4875 Fix bad indentation introduced in 43cd30bcd1c
Oops.

Reported-by: Nathan Bossart <nathandbossart@gmail.com>
Discussion: https://postgr.es/m/ZpVZB9rH5tHllO75@nathan
Backpatch: 12-, like 43cd30bcd1c
2024-07-15 15:17:37 -07:00
Jeff Davis
a15b0edb5d Add missing RestrictSearchPath() calls.
Reported-by: Noah Misch
Backpatch-through: 17
Discussion: https://postgr.es/m/20240630222344.db.nmisch@google.com
2024-07-15 12:08:00 -07:00
Andres Freund
bd40ffd8af ci: Upgrade to Debian Bookworm
Bullseye is getting long in the tooth, upgrade to the current stable version.

Backpatch to all versions with CI support, we don't want to generate CI images
for multiple Debian versions.

Author: Nazir Bilal Yavuz <byavuz81@gmail.com>
Discussion: https://postgr.es/m/CAN55FZ0fY5EFHXLKCO_%3Dp4pwFmHRoVom_qSE_7B48gpchfAqzw%40mail.gmail.com
Backpatch: 15-, where CI was added
2024-07-15 09:26:01 -07:00
Andres Freund
9b047cc0b2 Fix type confusion in guc_var_compare()
Before this change guc_var_compare() cast the input arguments to
const struct config_generic *.  That's not quite right however, as the input
on one side is often just a char * on one side.

Instead just use char *, the first field in config_generic.

This fixes a -Warray-bounds warning with some versions of gcc. While the
warning is only known to be triggered for <= 15, the issue the warning points
out seems real, so apply the fix everywhere.

Author: Nazir Bilal Yavuz <byavuz81@gmail.com>
Reported-by: Erik Rijkers <er@xs4all.nl>
Suggested-by: Andres Freund <andres@anarazel.de>
Discussion: https://postgr.es/m/a74a1a0d-0fd2-3649-5224-4f754e8f91aa%40xs4all.nl
2024-07-15 09:26:01 -07:00
Tom Lane
34f457e99a Doc: minor improvements for plpgsql "Transaction Management" section.
Point out that savepoint commands cannot be issued in PL/pgSQL,
and suggest that exception blocks can usually be used instead.

Add a caveat to the discussion of cursor loops vs. transactions,
pointing out that any locks taken by the cursor query will be lost
at COMMIT.  This is implicit in what's already said, but the existing
text leaves the distinct impression that the auto-hold behavior is
transparent, which it's not really.

Per a couple of recent complaints (one unsigned, and one in bug #18531
from Dzmitry Jachnik).  Back-patch to v17, just so this makes it into
current docs in less than a year-and-a-half.

Discussion: https://postgr.es/m/172076354433.736586.14347210271966220018@wrigleys.postgresql.org
Discussion: https://postgr.es/m/18531-c6dddd33b8555fd2@postgresql.org
2024-07-15 11:59:43 -04:00
Heikki Linnakangas
b8bf76cbde Use atomics to avoid locking in InjectionPointRun()
This allows using injection points without having a PGPROC, like early
at backend startup, or in the postmaster.

The injection points facility is new in v17, so backpatch there.

Reviewed-by: Michael Paquier <michael@paquier.xyz>
Disussion: https://www.postgresql.org/message-id/4317a7f7-8d24-435e-9e49-29b72a3dc418@iki.fi
2024-07-15 10:33:09 +03:00
Fujii Masao
6a700da46e Fix unstable tests in partition_merge.sql and partition_split.sql.
The tests added by commit c086896625 were unstable due to
missing schema names when checking pg_tables and pg_indexes.

Backpatch to v17.

Reported by buildfarm.
2024-07-15 14:11:49 +09:00
Fujii Masao
929390e4d8 Fix tablespace handling in MERGE/SPLIT partition commands.
As commit ca4103025d stated, new partitions without a specified tablespace
should inherit the parent relation's tablespace. However, previously,
ALTER TABLE MERGE PARTITIONS and ALTER TABLE SPLIT PARTITION commands
always created new partitions in the default tablespace, ignoring
the parent's tablespace. This commit ensures new partitions inherit
the parent's tablespace.

Backpatch to v17 where these commands were introduced.

Author: Fujii Masao
Reviewed-by: Masahiko Sawada
Discussion: https://postgr.es/m/abaf390b-3320-40a5-8815-ef476db5cfe7@oss.nttdata.com
2024-07-15 13:14:20 +09:00
Tom Lane
cf588e10f6 Avoid unhelpful internal error for incorrect recursive-WITH queries.
checkWellFormedRecursion would issue "missing recursive reference"
if a WITH RECURSIVE query contained a single self-reference but
that self-reference was inside a top-level WITH, ORDER BY, LIMIT,
etc, rather than inside the second arm of the UNION as expected.
We already intended to throw more-on-point errors for such cases,
but those error checks must be done before examining the UNION arm
in order to have the desired results.  So this patch need only
move some code (and improve the comments).

Per bug #18536 from Alexander Lakhin.  Back-patch to all supported
branches.

Discussion: https://postgr.es/m/18536-0a342ec07901203e@postgresql.org
2024-07-14 13:49:46 -04:00
Andrew Dunstan
5ea9f66616 Use correct collate.windows.win1252.out
I inadvertently missed backporting this to Release 17 from commit 291c420747

per offlist reminder from Alexander Lakhin.
2024-07-13 16:24:01 -04:00
Noah Misch
0d3b35c367 Fix new assertion for MERGE view_name ... DO NOTHING.
Such queries don't expand automatically updatable views, and ModifyTable
uses the wholerow attribute unconditionally.  The user-visible behavior
is fine, so change to more-specific assertions.  Commit
d5f788b41dc2cbdde6e7694c70dda54d829a5ed5 added the wrong assertion.
Back-patch to v17, where commit 5f2e179bd31e5f5803005101eb12a8d7bf8db8f3
introduced MERGE view_name.

Reported by Alexander Lakhin.

Discussion: https://postgr.es/m/e4b40a88-c134-6926-3196-bc4501cb87a2@gmail.com
2024-07-13 08:09:36 -07:00
Noah Misch
f5bb46fb2e Don't lose partitioned table reltuples=0 after relhassubclass=f.
ANALYZE sets relhassubclass=f when a partitioned table no longer has
partitions.  An ANALYZE doing that proceeded to apply the inplace update
of pg_class.reltuples to the old pg_class tuple instead of the new
tuple, losing that reltuples=0 change if the ANALYZE committed.
Non-partitioning inheritance trees were unaffected.  Back-patch to v14,
where commit 375aed36ad83f0e021e9bdd3a0034c0c992c66dc introduced
maintenance of partitioned table pg_class.reltuples.

Reported by Alexander Lakhin.

Discussion: https://postgr.es/m/a295b499-dcab-6a99-c06e-01cf60593344@gmail.com
2024-07-13 08:09:36 -07:00
Andrew Dunstan
dd12eb33af Make sure to run pg_isready on correct port
The current code can have pg_isready unexpectedly succeed if there is a
server running on the default port. To avoid this we delay running the
test until after a node has been created but before it starts, and then
use that node's port, so we are fairly sure there is nothing running on
the port.

Backpatch to all live branches.
2024-07-13 08:08:07 -04:00
Thomas Munro
3c1c82d406 Fix lost Windows socket EOF events.
Winsock only signals an FD_CLOSE event once if the other end of the
socket shuts down gracefully.  Because each WaitLatchOrSocket() call
constructs and destroys a new event handle every time, with unlucky
timing we can lose it and hang.  We get away with this only if the other
end disconnects non-gracefully, because FD_CLOSE is repeatedly signaled
in that case.

To fix this design flaw in our Windows socket support fundamentally,
we'd probably need to rearchitect it so that a single event handle
exists for the lifetime of a socket, or switch to completely different
multiplexing or async I/O APIs.  That's going to be a bigger job
and probably wouldn't be back-patchable.

This brute force kludge closes the race by explicitly polling with
MSG_PEEK before sleeping.

Back-patch to all supported releases.  This should hopefully clear up
some random build farm and CI hang failures reported over the years.  It
might also allow us to try using graceful shutdown in more places again
(reverted in commit 29992a6) to fix instability in the transmission of
FATAL error messages, but that isn't done by this commit.

Reported-by: Tom Lane <tgl@sss.pgh.pa.us>
Tested-by: Alexander Lakhin <exclusion@gmail.com>
Discussion: https://postgr.es/m/176008.1715492071%40sss.pgh.pa.us
2024-07-13 15:02:33 +12:00
Alvaro Herrera
0340eefd9b
Add ORDER BY to new test query
Per buildfarm.
2024-07-12 13:44:19 +02:00
Alvaro Herrera
30ca4e1ab1
Fix ALTER TABLE DETACH for inconsistent indexes
When a partitioned table has an index that doesn't support a constraint,
but a partition has an equivalent index that does, then a DETACH
operation would misbehave: a crash in assertion-enabled systems (because
we fail to find the constraint in the parent that we expect to), or a
broken coninhcount value (-1) in production systems (because we blindly
believe that we've successfully detached the parent).

While we should reject an ATTACH of a partition with such an index, we
have failed to do so in existing releases, so adding an error in stable
releases might break the (unlikely) existing applications that rely on
this behavior.  At this point I don't even want to reject them in
master, because it'd break pg_upgrade if such databases exist, and there
would be no easy way to fix existing databases without expensive index
rebuilds.

(Later on we could add ALTER TABLE ... ADD CONSTRAINT USING INDEX to
partitioned tables, which would allow the user to fix such patterns.  At
that point we could add more restrictions to prevent the problem from
its root.)

Also, add a test case that leaves one table in this condition, so that
we can verify that pg_upgrade continues to work if we later decide to
change the policy on the master branch.

Backpatch to all supported branches.

Co-authored-by: Tender Wang <tndrwang@gmail.com>
Reported-by: Alexander Lakhin <exclusion@gmail.com>
Reviewed-by: Tender Wang <tndrwang@gmail.com>
Reviewed-by: Michael Paquier <michael@paquier.xyz>
Discussion: https://postgr.es/m/18500-62948b6fe5522f56@postgresql.org
2024-07-12 12:54:01 +02:00
Amit Kapila
ae4e072bad Fix unstable test in 040_pg_createsubscriber.
The slot synchronization failed because the local slot's (created during
slot synchronization) catalog_xmin on standby is ahead of remote slot.
This happens because the INSERT before slot synchronization results in the
generation of a new xid that could be replicated to the standby. Now
before the xmin of the physical slot on the primary catches up via
hot_standby_feedback, the test has created a logical slot that got some
prior value of catalog_xmin.

To fix this we could try to ensure that the physical slot's catalog_xmin
is caught up to latest value before creating a logical slot but we took a
simpler path to move the INSERT after synchronizing the logical slot.

Reported-by: Alexander Lakhin as per buildfarm
Diagnosed-by: Amit Kapila, Hou Zhijie, Alexander Lakhin
Author: Hou Zhijie
Backpatch-through: 17
Discussion: https://postgr.es/m/bde6ac67-69cc-c104-5ab6-dd4f5deadf24@gmail.com
2024-07-12 09:35:46 +05:30
Masahiko Sawada
068674f4ab Fix possibility of logical decoding partial transaction changes.
When creating and initializing a logical slot, the restart_lsn is set
to the latest WAL insertion point (or the latest replay point on
standbys). Subsequently, WAL records are decoded from that point to
find the start point for extracting changes in the
DecodingContextFindStartpoint() function. Since the initial
restart_lsn could be in the middle of a transaction, the start point
must be a consistent point where we won't see the data for partial
transactions.

Previously, when not building a full snapshot, serialized snapshots
were restored, and the SnapBuild jumps to the consistent state even
while finding the start point. Consequently, the slot's restart_lsn
and confirmed_flush could be set to the middle of a transaction. This
could lead to various unexpected consequences. Specifically, there
were reports of logical decoding decoding partial transactions, and
assertion failures occurred because only subtransactions were decoded
without decoding their top-level transaction until decoding the commit
record.

To resolve this issue, the changes prevent restoring the serialized
snapshot and jumping to the consistent state while finding the start
point.

On v17 and HEAD, a flag indicating whether snapshot restores should be
skipped has been added to the SnapBuild struct, and SNAPBUILD_VERSION
has been bumpded.

On backbranches, the flag is stored in the LogicalDecodingContext
instead, preserving on-disk compatibility.

Backpatch to all supported versions.

Reported-by: Drew Callahan
Reviewed-by: Amit Kapila, Hayato Kuroda
Discussion: https://postgr.es/m/2444AA15-D21B-4CCE-8052-52C7C2DAFE5C%40amazon.com
Backpatch-through: 12
2024-07-11 22:48:21 +09:00
Tom Lane
a9747be272 Make our back branches compatible with libxml2 2.13.x.
This back-patches HEAD commits 066e8ac6e, 6082b3d5d, e7192486d,
and 896cd266f into supported branches.  Changes:

* Use xmlAddChildList not xmlAddChild in XMLSERIALIZE
(affects v16 and up only).  This was a flat-out coding mistake
that we got away with due to lax checking in previous versions
of xmlAddChild.

* Use xmlParseInNodeContext not xmlParseBalancedChunkMemory.
This is to dodge a bug in xmlParseBalancedChunkMemory in libxm2
releases 2.13.0-2.13.2.  While that bug is now fixed upstream and
will probably never be seen in any production-oriented distro, it is
currently a problem on some more-bleeding-edge-friendly platforms.

* Suppress "chunk is not well balanced" errors from libxml2,
unless it is the only error.  This eliminates an error-reporting
discrepancy between 2.13 and older releases.  This error is
almost always redundant with previous errors, if not flat-out
inappropriate, which is why 2.13 changed the behavior and why
nobody's likely to miss it.

Erik Wienhold and Tom Lane, per report from Frank Streitzig.

Discussion: https://postgr.es/m/trinity-b0161630-d230-4598-9ebc-7a23acdb37cb-1720186432160@3c-app-gmx-bap25
Discussion: https://postgr.es/m/trinity-361ba18b-541a-4fe7-bc63-655ae3a7d599-1720259822452@3c-app-gmx-bs01
2024-07-10 20:15:52 -04:00
Andrew Dunstan
4506d18a98 Use diff's --strip-trailing-cr flag where appropriate on Windows
Test result files might be checked out using Unix or Windows style line
endings, depening on git flags, so on Windows we use the
--strip-trailing-cr flag to tell diff to ignore line endings
differences.

The flag is added to the diff invocation for the test_json_parser module
tests and the pg_bsd_indent tests. in pg_regress.c we replace the
current use of the "-w" flag, which ignore all white space differences,
with this one which only ignores line end differences.

Discussion: https://postgr.es/m/20240707052030.r77hbdkid3mwksop@awork3.anarazel.de
2024-07-10 10:05:00 -04:00
Fujii Masao
0248762b2a doc: Update track_io_timing documentation to mention pg_stat_io.
The I/O timing information collected when track_io_timing is
enabled is now documented to appear in the pg_stat_io view,
which was previously not mentioned.

This commit also enhances the description of track_io_timing
to clarify that it monitors not only block read and write
but also block extend and fsync operations. Additionally,
the description of track_wal_io_timing has been improved
to mention both WAL write and WAL fsync monitoring.

Backpatch to v16 where pg_stat_io was added.

Author: Hajime Matsunaga
Reviewed-by: Melanie Plageman, Nazir Bilal Yavuz, Fujii Masao
Discussion: https://postgr.es/m/TYWPR01MB10742EE4A6F34C33061429D38A4D52@TYWPR01MB10742.jpnprd01.prod.outlook.com
2024-07-10 15:58:11 +09:00
Andrew Dunstan
e72f787ea6 Prevent CRLF conversion of inputs in json_parser test module
Do this by opening the file in PG_BINARY_R mode. This prevents us from
getting wrong byte count from stat().

Per complaint from Andres Freund

Discussion: https://postgr.es/m/20240707052030.r77hbdkid3mwksop@awork3.anarazel.de

Backpatch to rlease 17 where this code was introduced
2024-07-09 17:34:47 -04:00
Jeff Davis
d3e076549b Fix missing invalidations for search_path cache.
Reported-by: Noah Misch
Discussion: https://postgr.es/m/20240630223047.1f.nmisch@google.com
Backpatch-through: 17
2024-07-09 11:27:10 -07:00
Amit Langote
ce416fadb4 SQL/JSON: Various improvements to SQL/JSON query function docs
1. Remove the keyword SELECT from the examples to be consistent
with the examples of other JSON-related functions listed on the
same page.

2. Add <synopsis> tags around the functions' syntax definition

3. Capitalize function names in the syntax synopsis and the examples

4. Use <itemizedlist> lists for dividing the descriptions of
   individual functions into bullet points

5. Significantly rewrite the description of wrapper clauses of
   JSON_QUERY

6. Significantly rewrite the descriptions of ON ERROR / EMPTY
   clauses of JSON_QUERY() and JSON_VALUE() functions

7. Add a note about how JSON_VALUE() and JSON_QUERY() differ when
   returning a JSON null result

8. Move the description of the PASSING clause from the descriptions
   of individual functions into the top paragraph

And other miscellaneous text improvements, typo fixes.

Suggested-by: Thom Brown <thom@linux.com>
Suggested-by: David G. Johnston <david.g.johnston@gmail.com>
Reviewed-by: Jian He <jian.universality@gmail.com>
Reviewed-by: Erik Rijkers <er@xs4all.nl>
Discussion: https://postgr.es/m/CAA-aLv7Dfy9BMrhUZ1skcg=OdqysWKzObS7XiDXdotJNF0E44Q@mail.gmail.com
Discussion: https://postgr.es/m/CAKFQuwZNxNHuPk44zDF7z8qZec1Aof10aA9tWvBU5CMhEKEd8A@mail.gmail.com
2024-07-09 16:16:02 +09:00
Fujii Masao
ab4129091c Fix limit block handling in pg_wal_summary_contents().
Previously, pg_wal_summary_contents() had two issues,
causing discrepancies between pg_wal_summary_contents()
and the pg_walsummary command on the same WAL summary file:

(1) It did not emit the limit block when that's the only data for
     a particular relation fork.
(2) It emitted the same limit block multiple times if the list of
     block numbers was long enough.

This commit fixes these issues.

Backpatch to v17 where pg_wal_summary_contents() was added.

Author: Fujii Masao
Reviewed-by: Robert Haas
Discussion: https://postgr.es/m/90980ee6-2da6-42f6-a7b0-b7bae62ae279@oss.nttdata.com
2024-07-09 09:29:11 +09:00
Andrew Dunstan
d3e213ae13 Symlink pg_replslot robustly on Windows in pg_basebackup test
This reverts commit e9f15bc9. Instead of a hacky solution that didn't
work on Windows, we avoid trying to move the directory possibly across
drives, and instead remove it and recreate it in the new location.

Discussion: https://postgr.es/m/20240707070243.sb77kp4ubowauctz@awork3.anarazel.de

Backpatch to release 14 like the previous patch.
2024-07-08 13:52:27 -04:00
Andrew Dunstan
e68cf81bfe Choose ports for test servers less likely to result in conflicts
If we choose ports in the range typically used for ephemeral ports there
is a danger of encountering a port conflict due to a race condition
between the time we choose the port in a range below that typically used
to allocate ephemeral ports, but higher than the range typically used by
well known services.

Author: Jelte Fenema-Nio, with some editing by me.

Discussion: https://postgr.es/m/d6ee8761-39d1-0033-1afb-d5a57ee056f2@gmail.com

Backpatch to all live branches (12 and up)
2024-07-08 11:40:58 -04:00
Andrew Dunstan
e4754f780f Force nodes for SSL tests to start in TCP mode
Currently they are started in unix socket mode in ost cases, and then
converted to run in TCP mode. This can result in port collisions, and
there is no virtue in startng in unix socket mode, so start as we will
be going on.

Discussion: https://postgr.es/m/d6ee8761-39d1-0033-1afb-d5a57ee056f2@gmail.com

Backpatch to all live branches (12 and up).
2024-07-08 11:40:58 -04:00
Dean Rasheed
7a8977d258 Fix scale clamping in numeric round() and trunc().
The numeric round() and trunc() functions clamp the scale argument to
the range between +/- NUMERIC_MAX_RESULT_SCALE (2000), which is much
smaller than the actual allowed range of type numeric. As a result,
they return incorrect results when asked to round/truncate more than
2000 digits before or after the decimal point.

Fix by using the correct upper and lower scale limits based on the
actual allowed (and documented) range of type numeric.

While at it, use the new NUMERIC_WEIGHT_MAX constant instead of
SHRT_MAX in all other overflow checks, and fix a comment thinko in
power_var() introduced by e54a758d24 -- the minimum value of
ln_dweight is -NUMERIC_DSCALE_MAX (-16383), not -SHRT_MAX, though this
doesn't affect the point being made in the comment, that the resulting
local_rscale value may exceed NUMERIC_MAX_DISPLAY_SCALE (1000).

Back-patch to all supported branches.

Dean Rasheed, reviewed by Joel Jacobson.

Discussion: https://postgr.es/m/CAEZATCXB%2BrDTuMjhK5ZxcouufigSc-X4tGJCBTMpZ3n%3DxxQuhg%40mail.gmail.com
2024-07-08 17:51:23 +01:00
Amit Langote
d4f8517b0b Typo fix
Reported-by: Junwang Zhao <zhjwpku@gmail.com>
Discussion: https://postgr.es/m/CAEG8a3KPi=LayiTwJ11ikF7bcqnZUrcj8NgX0V8nO1mQKZ9GfQ@mail.gmail.com
Backpatch-through: 17
2024-07-08 22:12:42 +09:00
Heikki Linnakangas
5afebbe529 Fix outdated comment after removal of direct SSL fallback
The option to fall back from direct SSL to negotiated SSL or a
plaintext connection was removed in commit fb5718f35f.

Discussion: https://www.postgresql.org/message-id/c82ad227-e049-4e18-8898-475a748b5a5a@iki.fi
2024-07-08 12:44:56 +03:00
Richard Guo
cccab85c2b Fix right-anti-joins when the inner relation is proven unique
For an inner_unique join, we always assume that the executor will stop
scanning for matches after the first match.  Therefore, for a mergejoin
that is inner_unique and whose mergeclauses are sufficient to identify a
match, we set the skip_mark_restore flag to true, indicating that the
executor need not do mark/restore calls.  However, merge-right-anti-join
did not get this memo and continues scanning the inner side for matches
after the first match.  If there are duplicates in the outer scan, we
may incorrectly skip matching some inner tuples, which can lead to wrong
results.

Here we fix this issue by ensuring that merge-right-anti-join also
advances to next outer tuple after the first match in inner_unique
cases.  This also saves cycles by avoiding unnecessary scanning of inner
tuples after the first match.

Although hash-right-anti-join does not suffer from this wrong results
issue, we apply the same change to it as well, to help save cycles for
the same reason.

Per bug #18522 from Antti Lampinen, and bug #18526 from Feliphe Pozzer.
Back-patch to v16 where right-anti-join was introduced.

Author: Richard Guo
Discussion: https://postgr.es/m/18522-c7a8956126afdfd0@postgresql.org
2024-07-08 10:17:12 +09:00
Michael Paquier
fa1a63dffc Re-enable autoruns for for cmd.exe on Windows
This acts as a revert of b83747a8a65b and 9886744a361b.  As pointed out
by Noah, HEAD and REL_17_STABLE are in a weird state where the code
paths adding /D would limit the spawn of child processes, but we still
have code paths where the spawn of more than one child process would be
possible.

Let's remove these /D switches for now, to bring back the code into a
state consistent with how autorun is configured on a Windows host.

Reported-by: Noah Misch
Discussion: https://postgr.es/m/20240630021211.f3.nmisch@google.com
Backpatch-through: 17
2024-07-08 09:43:35 +09:00
David Rowley
84a9d38006 Fix incorrect sentinel byte logic in GenerationRealloc()
This only affects MEMORY_CONTEXT_CHECKING builds.

This fixes an off-by-one issue in GenerationRealloc() where the
fast-path code which tries to reuse the existing allocation if the
existing chunk is >= the new requested size.  The code there thought it
was always ok to use the existing chunk, but when oldsize == size there
isn't enough space to store the sentinel byte.  If both sizes matched
exactly set_sentinel() would overwrite the first byte beyond the chunk
and then subsequent GenerationRealloc() calls could then fail the
Assert(chunk->requested_size < oldsize) check which is trying to ensure
the chunk is large enough to store the sentinel.

The same issue does not exist in aset.c as the sentinel checking code
only adds a sentinel byte if there's enough space in the chunk.

Reported-by: Alexander Lakhin <exclusion@gmail.com>
Discussion: https://postgr.es/m/49275921-7b39-41af-5eb8-97b50ce3312e@gmail.com
Backpatch-through: 16, where the problem was introduced by 0e480385e
2024-07-06 14:00:06 +12:00
Thomas Munro
9c273679b3 Cope with <regex.h> name clashes.
macOS 15's SDK pulls in headers related to <regex.h> when we include
<xlocale.h>.  This causes our own regex_t implementation to clash with
the OS's regex_t implementation.  Luckily our function names already had
pg_ prefixes, but the macros and typenames did not.

Include <regex.h> explicitly on all POSIX systems, and fix everything
that breaks.  Then we can prove that we are capable of fully hiding and
replacing the system regex API with our own.

1.  Deal with standard-clobbering macros by undefining them all first.
POSIX says they are "symbolic constants".  If they are macros, this
allows us to redefine them.  If they are enums or variables, our macros
will hide them.

2.  Deal with standard-clobbering types by giving our types pg_
prefixes, and then using macros to redirect xxx_t -> pg_xxx_t.

After including our "regex/regex.h", the system <regex.h> is hidden,
because we've replaced all the standard names.  The PostgreSQL source
tree and extensions can continue to use standard prefix-less type and
macro names, but reach our implementation, if they included our
"regex/regex.h" header.

Back-patch to all supported branches, so that macOS 15's tool chain can
build them.

Reported-by: Stan Hu <stanhu@gmail.com>
Suggested-by: Tom Lane <tgl@sss.pgh.pa.us>
Tested-by: Aleksander Alekseev <aleksander@timescale.com>
Discussion: https://postgr.es/m/CAMBWrQnEwEJtgOv7EUNsXmFw2Ub4p5P%2B5QTBEgYwiyjy7rAsEQ%40mail.gmail.com
2024-07-06 11:23:40 +12:00
Bruce Momjian
8af6958957 doc PG 17 relnotes: fix psql connection cancelation item
Reported-by: Matthias van de Meent

Discussion: https://postgr.es/m/CAEze2WiprrENrFQqeXij2XyLAdoZaFTFLGC8sE=V8c1yrWn+2A@mail.gmail.com

Backpatch-through: 17 only
2024-07-05 16:51:56 -04:00
Tom Lane
7f9c715191 Doc: small improvements in discussion of geometric data types.
State explicitly that the coordinates in our geometric data types are
float8.  Also explain that polygons store their bounding box.

While here, fix the table of geometric data types to show type
"line"'s size correctly: it's 24 bytes not 32.  This has somehow
escaped notice since that table was made in 1998.

Per suggestion from Sebastian Skałacki.  The size error seems
important enough to justify back-patching.

Discussion: https://postgr.es/m/172000045661.706.1822177575291548794@wrigleys.postgresql.org
2024-07-04 13:23:32 -04:00
Alvaro Herrera
e72f841cbe
Fix copy/paste mistake in comment
Backpatch to 17

Author: Yugo NAGATA <nagata@sraoss.co.jp>
Discussion: https://postgr.es/m/20240704134638.355ad44a445fa1e764a220cd@sranhm.sraoss.co.jp
2024-07-04 13:57:47 +02:00
Alvaro Herrera
3a9d0d774d
Remove bogus assertion in pg_atomic_monotonic_advance_u64
This code wanted to ensure that the 'exchange' variable passed to
pg_atomic_compare_exchange_u64 has correct alignment, but apparently
platforms don't actually require anything that doesn't come naturally.

While messing with pg_atomic_monotonic_advance_u64: instead of using
Max() to determine the value to return, just use
pg_atomic_compare_exchange_u64()'s return value to decide; also, use
pg_atomic_compare_exchange_u64 instead of the _impl version; also remove
the unnecessary underscore at the end of variable name "target".

Backpatch to 17, where this code was introduced by commit bf3ff7bf83bc.

Reported-by: Alexander Lakhin <exclusion@gmail.com>
Discussion: https://postgr.es/m/36796438-a718-cf9b-2071-b2c1b947c1b5@gmail.com
2024-07-04 13:25:31 +02:00
Daniel Gustafsson
1c9acb14ae doc: Specify when ssl_prefer_server_ciphers was added
The ssl_prefer_server_ciphers setting is quite important from a
security point of view, so simply stating that older versions
doesn't have it isn't very helpful.  This adds the version when
the GUC was added to help readers.

Backpatch to all supported versions since this setting has been
around since 9.4.

Reviewed-by: Peter Eisentraut <peter@eisentraut.org>
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/5D7E0F5E-E620-4D54-8788-66D421AC76F0@yesql.se
Backpatch-through: v12
2024-07-04 12:10:12 +02:00
Amit Langote
290a6d800d SQL/JSON: Fix some obsolete comments.
JSON_OBJECT(), JSON_OBJETAGG(), JSON_ARRAY(), and JSON_ARRAYAGG()
added in 7081ac46ace are not transformed into direct calls to
user-defined functions as the comments claim. Fix by mentioning
instead that they are transformed into JsonConstructorExpr nodes,
which may call them, for example, for the *AGG() functions.

Reported-by: Alexander Lakhin <exclusion@gmail.com>
Discussion: https://postgr.es/m/058c856a-e090-ac42-ff00-ffe394f52a87%40gmail.com
Backpatch-through: 16
2024-07-04 16:17:21 +09:00
Alexander Korotkov
619f76cce1 Fix typo in GetRunningTransactionData()
e85662df44 made GetRunningTransactionData() calculate the oldest running
transaction id within the current database.  However, because of the typo,
the new code uses oldestRunningXid instead of oldestDatabaseRunningXid
in comparison before updating oldestDatabaseRunningXid.  This commit fixes
that issue.

Reported-by: Noah Misch
Discussion: https://postgr.es/m/20240630231816.bf.nmisch%40google.com
Backpatch-through: 17
2024-07-04 02:08:01 +03:00
Heikki Linnakangas
95219c020c Avoid 0-length memcpy to NULL with EXEC_BACKEND
memcpy(NULL, src, 0) is forbidden by POSIX, even though every
production version of libc allows it. Let's be tidy.

Per report from Thomas Munro, running UBSan with EXEC_BACKEND.
Backpatch to v17, where this code was added.

Discussion: https://www.postgresql.org/message-id/CA%2BhUKG%2Be-dV7YWBzfBZXsgovgRuX5VmvmOT%2Bv0aXiZJ-EKbXcw@mail.gmail.com
2024-07-03 16:20:56 +03:00
Heikki Linnakangas
1906b1e0ad Tighten check for --forkchild argument when spawning child process
Commit aafc05de1b removed all the other --fork* arguments. Altough
this is inconsequential, backpatch to v17 since this is new.

Author: Nathan Bossart
Discussion: https://www.postgresql.org/message-id/ZnCCEN0l3qWv-XpW@nathan
2024-07-03 16:20:56 +03:00
Amit Kapila
14387ab065 Fix the testcase introduced in commit 81d20fbf7a.
The failed test was syncing failover replication slot to standby to test
that we remove such slots after the standby is converted to subscriber by
pg_createsubscriber.

In one of the buildfarm members, the sync of the slot failed because the
LSN on the standby was before the syncslot's LSN. We need to wait for
standby to catch up before trying to sync the slot with
pg_sync_replication_slots().

The other buildfarm failed because autovacuum generated a xid which is
replicated to the standby at some random point making slots at primary
lag behind standby during slot sync.

Both these failures wouldn't have occurred if we had used built-in
slotsync worker as it would have waited for the standby to sync with
primary but for this test, it is sufficient to use
pg_sync_replication_slots().

Reported-by: Alexander Lakhin as per buildfarm
Author: Kuroda Hayato
Reviewed-by: Amit Kapila
Backpatch-through: 17
Discussion: https://postgr.es/m/0dffca12-bf17-4a7a-334d-225569de5e6e@gmail.com
Discussion: https://postgr.es/m/OSBPR01MB25528300C71FDD83EA1DCA12F5DD2@OSBPR01MB2552.jpnprd01.prod.outlook.com
2024-07-03 14:57:07 +05:30
Amit Kapila
622cb84d69 Drop pre-existing subscriptions from the converted subscriber.
We don't need the pre-existing subscriptions on the newly formed
subscriber by using pg_createsubscriber. The apply workers corresponding
to these subscriptions can connect to other publisher nodes and either get
some unwarranted data or can lead to ERRORs in connecting to such nodes.

Author: Kuroda Hayato
Reviewed-by: Amit Kapila, Shlok Kyal, Vignesh C
Backpatch-through: 17
Discussion: https://postgr.es/m/OSBPR01MB25526A30A1FBF863ACCDDA3AF5C92@OSBPR01MB2552.jpnprd01.prod.outlook.com
2024-07-02 11:20:06 +05:30
Amit Kapila
ca522e2a89 Remove unused structure member in pg_createsubscriber.c.
Author: Kuroda Hayato
Backpatch-through: 17
Discussion: https://postgr.es/m/OSBPR01MB25526A30A1FBF863ACCDDA3AF5C92@OSBPR01MB2552.jpnprd01.prod.outlook.com
2024-07-02 10:15:11 +05:30
Amit Kapila
58c5f60eb8 Update release notes to reflect recent commit 0f934b0739.
Author: Hou Zhijie
Discussion: https://postgr.es/m/ZnWeUgdHong93fQN@momjian.us
Discussion: https://postgr.es/m/OS3PR01MB57187B959C1ECC78B0C7C91A94D32@OS3PR01MB5718.jpnprd01.prod.outlook.com
2024-07-02 09:17:41 +05:30
Tom Lane
31f8d620b2 Preserve CurrentMemoryContext across notify and sinval interrupts.
ProcessIncomingNotify is called from the main processing loop that
normally runs in MessageContext.  That outer-loop code assumes that
whatever it allocates will be cleaned up when we're done processing
the current client message --- but if we service a notify interrupt,
then whatever gets allocated before the next switch into
MessageContext will be permanently leaked in TopMemoryContext,
because CommitTransactionCommand sets CurrentMemoryContext to
TopMemoryContext.  There are observable leaks associated with
(at least) encoding conversion of incoming queries and parameters
attached to Bind messages.

sinval catchup interrupts have a similar problem.  There might be
others, but I've not identified any other clear cases.

To fix, take care to save and restore CurrentMemoryContext across
the Start/CommitTransactionCommand calls in these functions.

Per bug #18512 from wizardbrony.  Commit to back branches only;
in HEAD, this was dealt with by the riskier but more thoroughgoing
approach in commit 1afe31f03.

Discussion: https://postgr.es/m/3478884.1718656625@sss.pgh.pa.us
2024-07-01 12:21:07 -04:00
Alvaro Herrera
6d2ac55491
Fix copy-paste mistake in PQcancelCreate
When an OOM occurred, this function was incorrectly setting a status of
CONNECTION_BAD on the passed in PGconn instead of on the newly created
PGcancelConn.

Mistake introduced with 61461a300c1c.  Backpatch to 17.

Author: Jelte Fennema-Nio <postgres@jeltef.nl>
Reported-by: Noah Misch <noah@leadboat.com>
Discussion: https://postgr.es/m/20240630190040.26.nmisch@google.com
2024-07-01 13:58:22 +02:00
Amit Kapila
0f934b0739 Rename standby_slot_names to synchronized_standby_slots.
The standby_slot_names GUC allows the specification of physical standby
slots that must be synchronized before the logical walsenders associated
with logical failover slots. However, for this purpose, the GUC name is
too generic.

Author: Hou Zhijie
Reviewed-by: Bertrand Drouvot, Masahiko Sawada
Backpatch-through: 17
Discussion: https://postgr.es/m/ZnWeUgdHong93fQN@momjian.us
2024-07-01 11:33:55 +05:30
Tom Lane
55c309fc5b Further weaken new pg_createsubscriber test on Windows.
Also omit backslashes (\) in the generated database names on Windows.
As before, perhaps we can revert this after updating affected
buildfarm animals.

Discussion: https://postgr.es/m/2509767.1719773880@sss.pgh.pa.us
2024-06-30 23:21:08 -04:00
Michael Paquier
10ee893d78 Adapt REL_17_STABLE to its new status as a stable branch
Per the checklist in RELEASE_CHANGES for the creation of a new stable
branch, this commit does the following things:
- Arm gen_node_support.pl's nodetag ABI stability, based on the contents
of nodetags.h.
- Update URLs of top-level README and Makefile to point to the new
stable version.

In passing, this fixes an incorrect comment in release-17.sgml.
2024-07-01 08:05:35 +09:00
672 changed files with 112554 additions and 95648 deletions

View File

@ -65,7 +65,7 @@ task:
CPUS: 4 CPUS: 4
BUILD_JOBS: 8 BUILD_JOBS: 8
TEST_JOBS: 8 TEST_JOBS: 8
IMAGE_FAMILY: pg-ci-bullseye IMAGE_FAMILY: pg-ci-bookworm
CCACHE_DIR: ${CIRRUS_WORKING_DIR}/ccache_dir CCACHE_DIR: ${CIRRUS_WORKING_DIR}/ccache_dir
# no options enabled, should be small # no options enabled, should be small
CCACHE_MAXSIZE: "150M" CCACHE_MAXSIZE: "150M"
@ -243,7 +243,7 @@ task:
CPUS: 4 CPUS: 4
BUILD_JOBS: 4 BUILD_JOBS: 4
TEST_JOBS: 8 # experimentally derived to be a decent choice TEST_JOBS: 8 # experimentally derived to be a decent choice
IMAGE_FAMILY: pg-ci-bullseye IMAGE_FAMILY: pg-ci-bookworm
CCACHE_DIR: /tmp/ccache_dir CCACHE_DIR: /tmp/ccache_dir
DEBUGINFOD_URLS: "https://debuginfod.debian.net" DEBUGINFOD_URLS: "https://debuginfod.debian.net"
@ -314,7 +314,7 @@ task:
#DEBIAN_FRONTEND=noninteractive apt-get -y install ... #DEBIAN_FRONTEND=noninteractive apt-get -y install ...
matrix: matrix:
- name: Linux - Debian Bullseye - Autoconf - name: Linux - Debian Bookworm - Autoconf
env: env:
SANITIZER_FLAGS: -fsanitize=address SANITIZER_FLAGS: -fsanitize=address
@ -348,7 +348,7 @@ task:
on_failure: on_failure:
<<: *on_failure_ac <<: *on_failure_ac
- name: Linux - Debian Bullseye - Meson - name: Linux - Debian Bookworm - Meson
env: env:
CCACHE_MAXSIZE: "400M" # tests two different builds CCACHE_MAXSIZE: "400M" # tests two different builds
@ -375,7 +375,7 @@ task:
${LINUX_MESON_FEATURES} \ ${LINUX_MESON_FEATURES} \
-Dllvm=disabled \ -Dllvm=disabled \
--pkg-config-path /usr/lib/i386-linux-gnu/pkgconfig/ \ --pkg-config-path /usr/lib/i386-linux-gnu/pkgconfig/ \
-DPERL=perl5.32-i386-linux-gnu \ -DPERL=perl5.36-i386-linux-gnu \
-DPG_TEST_EXTRA="$PG_TEST_EXTRA" \ -DPG_TEST_EXTRA="$PG_TEST_EXTRA" \
build-32 build-32
EOF EOF
@ -411,7 +411,7 @@ task:
task: task:
name: macOS - Ventura - Meson name: macOS - Sonoma - Meson
env: env:
CPUS: 4 # always get that much for cirrusci macOS instances CPUS: 4 # always get that much for cirrusci macOS instances
@ -420,7 +420,7 @@ task:
# work OK. See # work OK. See
# https://postgr.es/m/20220927040208.l3shfcidovpzqxfh%40awork3.anarazel.de # https://postgr.es/m/20220927040208.l3shfcidovpzqxfh%40awork3.anarazel.de
TEST_JOBS: 8 TEST_JOBS: 8
IMAGE: ghcr.io/cirruslabs/macos-ventura-base:latest IMAGE: ghcr.io/cirruslabs/macos-runner:sonoma
CIRRUS_WORKING_DIR: ${HOME}/pgsql/ CIRRUS_WORKING_DIR: ${HOME}/pgsql/
CCACHE_DIR: ${HOME}/ccache CCACHE_DIR: ${HOME}/ccache
@ -460,6 +460,13 @@ task:
# updates macports every time. # updates macports every time.
macports_cache: macports_cache:
folder: ${MACPORTS_CACHE} folder: ${MACPORTS_CACHE}
fingerprint_script: |
# Include the OS major version in the cache key. If the OS image changes
# to a different major version, we need to reinstall.
sw_vers -productVersion | sed 's/\..*//'
# Also start afresh if we change our MacPorts install script.
md5 src/tools/ci/ci_macports_packages.sh
reupload_on_changes: true
setup_additional_packages_script: | setup_additional_packages_script: |
sh src/tools/ci/ci_macports_packages.sh \ sh src/tools/ci/ci_macports_packages.sh \
ccache \ ccache \
@ -651,7 +658,7 @@ task:
env: env:
CPUS: 4 CPUS: 4
BUILD_JOBS: 4 BUILD_JOBS: 4
IMAGE_FAMILY: pg-ci-bullseye IMAGE_FAMILY: pg-ci-bookworm
# Use larger ccache cache, as this task compiles with multiple compilers / # Use larger ccache cache, as this task compiles with multiple compilers /
# flag combinations # flag combinations

View File

@ -14,6 +14,9 @@
# #
# $ git log --pretty=format:"%H # %cd%n# %s" $PGINDENTGITHASH -1 --date=iso # $ git log --pretty=format:"%H # %cd%n# %s" $PGINDENTGITHASH -1 --date=iso
c739ae9e288c095cfe1b91ce27a2f2c075ed5da4 # 2024-08-26 16:16:09 -0700
# Fix identation.
da256a4a7fdcca35fe7ca808686ad3de6ee22306 # 2024-05-14 16:34:50 -0400 da256a4a7fdcca35fe7ca808686ad3de6ee22306 # 2024-05-14 16:34:50 -0400
# Pre-beta mechanical code beautification. # Pre-beta mechanical code beautification.

View File

@ -20,7 +20,7 @@ all:
all check install installdirs installcheck installcheck-parallel uninstall clean distclean maintainer-clean dist distcheck world check-world install-world installcheck-world: all check install installdirs installcheck installcheck-parallel uninstall clean distclean maintainer-clean dist distcheck world check-world install-world installcheck-world:
@if [ ! -f GNUmakefile ] ; then \ @if [ ! -f GNUmakefile ] ; then \
echo "You need to run the 'configure' program first. Please see"; \ echo "You need to run the 'configure' program first. Please see"; \
echo "<https://www.postgresql.org/docs/devel/installation.html>" ; \ echo "<https://www.postgresql.org/docs/17/installation.html>" ; \
false ; \ false ; \
fi fi
@IFS=':' ; \ @IFS=':' ; \

View File

@ -12,9 +12,9 @@ and functions. This distribution also contains C language bindings.
Copyright and license information can be found in the file COPYRIGHT. Copyright and license information can be found in the file COPYRIGHT.
General documentation about this version of PostgreSQL can be found at General documentation about this version of PostgreSQL can be found at
<https://www.postgresql.org/docs/devel/>. In particular, information <https://www.postgresql.org/docs/17/>. In particular, information
about building PostgreSQL from the source code can be found at about building PostgreSQL from the source code can be found at
<https://www.postgresql.org/docs/devel/installation.html>. <https://www.postgresql.org/docs/17/installation.html>.
The latest version of this software, and related software, may be The latest version of this software, and related software, may be
obtained at <https://www.postgresql.org/download/>. For more information obtained at <https://www.postgresql.org/download/>. For more information

27
configure vendored
View File

@ -1,6 +1,6 @@
#! /bin/sh #! /bin/sh
# Guess values for system-dependent variables and create Makefiles. # Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69 for PostgreSQL 17beta2. # Generated by GNU Autoconf 2.69 for PostgreSQL 17.2.
# #
# Report bugs to <pgsql-bugs@lists.postgresql.org>. # Report bugs to <pgsql-bugs@lists.postgresql.org>.
# #
@ -582,8 +582,8 @@ MAKEFLAGS=
# Identity of this package. # Identity of this package.
PACKAGE_NAME='PostgreSQL' PACKAGE_NAME='PostgreSQL'
PACKAGE_TARNAME='postgresql' PACKAGE_TARNAME='postgresql'
PACKAGE_VERSION='17beta2' PACKAGE_VERSION='17.2'
PACKAGE_STRING='PostgreSQL 17beta2' PACKAGE_STRING='PostgreSQL 17.2'
PACKAGE_BUGREPORT='pgsql-bugs@lists.postgresql.org' PACKAGE_BUGREPORT='pgsql-bugs@lists.postgresql.org'
PACKAGE_URL='https://www.postgresql.org/' PACKAGE_URL='https://www.postgresql.org/'
@ -1450,7 +1450,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing. # Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh. # This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF cat <<_ACEOF
\`configure' configures PostgreSQL 17beta2 to adapt to many kinds of systems. \`configure' configures PostgreSQL 17.2 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]... Usage: $0 [OPTION]... [VAR=VALUE]...
@ -1515,7 +1515,7 @@ fi
if test -n "$ac_init_help"; then if test -n "$ac_init_help"; then
case $ac_init_help in case $ac_init_help in
short | recursive ) echo "Configuration of PostgreSQL 17beta2:";; short | recursive ) echo "Configuration of PostgreSQL 17.2:";;
esac esac
cat <<\_ACEOF cat <<\_ACEOF
@ -1690,7 +1690,7 @@ fi
test -n "$ac_init_help" && exit $ac_status test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then if $ac_init_version; then
cat <<\_ACEOF cat <<\_ACEOF
PostgreSQL configure 17beta2 PostgreSQL configure 17.2
generated by GNU Autoconf 2.69 generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc. Copyright (C) 2012 Free Software Foundation, Inc.
@ -2443,7 +2443,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake. running configure, to aid debugging if configure makes a mistake.
It was created by PostgreSQL $as_me 17beta2, which was It was created by PostgreSQL $as_me 17.2, which was
generated by GNU Autoconf 2.69. Invocation command line was generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@ $ $0 $@
@ -12591,12 +12591,13 @@ fi
done done
# Function introduced in OpenSSL 1.1.1. # Function introduced in OpenSSL 1.1.1.
for ac_func in X509_get_signature_info for ac_func in X509_get_signature_info SSL_CTX_set_num_tickets
do : do :
ac_fn_c_check_func "$LINENO" "X509_get_signature_info" "ac_cv_func_X509_get_signature_info" as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
if test "x$ac_cv_func_X509_get_signature_info" = xyes; then : ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
cat >>confdefs.h <<_ACEOF cat >>confdefs.h <<_ACEOF
#define HAVE_X509_GET_SIGNATURE_INFO 1 #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
_ACEOF _ACEOF
fi fi
@ -19785,7 +19786,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their # report actual input values of CONFIG_FILES etc. instead of their
# values after options handling. # values after options handling.
ac_log=" ac_log="
This file was extended by PostgreSQL $as_me 17beta2, which was This file was extended by PostgreSQL $as_me 17.2, which was
generated by GNU Autoconf 2.69. Invocation command line was generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES CONFIG_FILES = $CONFIG_FILES
@ -19856,7 +19857,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\ ac_cs_version="\\
PostgreSQL config.status 17beta2 PostgreSQL config.status 17.2
configured by $0, generated by GNU Autoconf 2.69, configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\" with options \\"\$ac_cs_config\\"

View File

@ -17,7 +17,7 @@ dnl Read the Autoconf manual for details.
dnl dnl
m4_pattern_forbid(^PGAC_)dnl to catch undefined macros m4_pattern_forbid(^PGAC_)dnl to catch undefined macros
AC_INIT([PostgreSQL], [17beta2], [pgsql-bugs@lists.postgresql.org], [], [https://www.postgresql.org/]) AC_INIT([PostgreSQL], [17.2], [pgsql-bugs@lists.postgresql.org], [], [https://www.postgresql.org/])
m4_if(m4_defn([m4_PACKAGE_VERSION]), [2.69], [], [m4_fatal([Autoconf version 2.69 is required. m4_if(m4_defn([m4_PACKAGE_VERSION]), [2.69], [], [m4_fatal([Autoconf version 2.69 is required.
Untested combinations of 'autoconf' and PostgreSQL versions are not Untested combinations of 'autoconf' and PostgreSQL versions are not
@ -1358,7 +1358,7 @@ if test "$with_ssl" = openssl ; then
# function was removed. # function was removed.
AC_CHECK_FUNCS([CRYPTO_lock]) AC_CHECK_FUNCS([CRYPTO_lock])
# Function introduced in OpenSSL 1.1.1. # Function introduced in OpenSSL 1.1.1.
AC_CHECK_FUNCS([X509_get_signature_info]) AC_CHECK_FUNCS([X509_get_signature_info SSL_CTX_set_num_tickets])
AC_DEFINE([USE_OPENSSL], 1, [Define to 1 to build with OpenSSL support. (--with-ssl=openssl)]) AC_DEFINE([USE_OPENSSL], 1, [Define to 1 to build with OpenSSL support. (--with-ssl=openssl)])
elif test "$with_ssl" != no ; then elif test "$with_ssl" != no ; then
AC_MSG_ERROR([--with-ssl must specify openssl]) AC_MSG_ERROR([--with-ssl must specify openssl])

View File

@ -121,6 +121,7 @@ blgetbitmap(IndexScanDesc scan, TIDBitmap *tbm)
*/ */
bas = GetAccessStrategy(BAS_BULKREAD); bas = GetAccessStrategy(BAS_BULKREAD);
npages = RelationGetNumberOfBlocks(scan->indexRelation); npages = RelationGetNumberOfBlocks(scan->indexRelation);
pgstat_count_index_scan(scan->indexRelation);
for (blkno = BLOOM_HEAD_BLKNO; blkno < npages; blkno++) for (blkno = BLOOM_HEAD_BLKNO; blkno < npages; blkno++)
{ {

View File

@ -114,7 +114,7 @@ CREATE TABLE brin_parallel_test (a int, b text, c bigint) WITH (fillfactor=40);
-- for the different opclasses we build later). -- for the different opclasses we build later).
INSERT INTO brin_parallel_test INSERT INTO brin_parallel_test
SELECT (CASE WHEN (mod(i,231) = 0) OR (i BETWEEN 3500 AND 4000) THEN NULL ELSE i END), SELECT (CASE WHEN (mod(i,231) = 0) OR (i BETWEEN 3500 AND 4000) THEN NULL ELSE i END),
(CASE WHEN (mod(i,233) = 0) OR (i BETWEEN 3750 AND 4250) THEN NULL ELSE md5(i::text) END), (CASE WHEN (mod(i,233) = 0) OR (i BETWEEN 3750 AND 4250) THEN NULL ELSE encode(sha256(i::text::bytea), 'hex') END),
(CASE WHEN (mod(i,233) = 0) OR (i BETWEEN 3850 AND 4500) THEN NULL ELSE (i/100) + mod(i,8) END) (CASE WHEN (mod(i,233) = 0) OR (i BETWEEN 3850 AND 4500) THEN NULL ELSE (i/100) + mod(i,8) END)
FROM generate_series(1,5000) S(i); FROM generate_series(1,5000) S(i);
-- Build an index with different opclasses - minmax, bloom and minmax-multi. -- Build an index with different opclasses - minmax, bloom and minmax-multi.
@ -152,8 +152,8 @@ SELECT relname, relpages
ORDER BY relname; ORDER BY relname;
relname | relpages relname | relpages
------------------------+---------- ------------------------+----------
brin_test_parallel_idx | 3 brin_test_parallel_idx | 4
brin_test_serial_idx | 3 brin_test_serial_idx | 4
(2 rows) (2 rows)
-- Check that (A except B) and (B except A) is empty, which means the indexes -- Check that (A except B) and (B except A) is empty, which means the indexes
@ -186,8 +186,8 @@ SELECT relname, relpages
ORDER BY relname; ORDER BY relname;
relname | relpages relname | relpages
------------------------+---------- ------------------------+----------
brin_test_parallel_idx | 3 brin_test_parallel_idx | 4
brin_test_serial_idx | 3 brin_test_serial_idx | 4
(2 rows) (2 rows)
SELECT * FROM brin_page_items(get_raw_page('brin_test_parallel_idx', 2), 'brin_test_parallel_idx') SELECT * FROM brin_page_items(get_raw_page('brin_test_parallel_idx', 2), 'brin_test_parallel_idx')

View File

@ -239,3 +239,13 @@ SELECT page_checksum(decode(repeat('00', :block_size), 'hex'), 1);
(1 row) (1 row)
-- tests for sequences
create sequence test_sequence start 72057594037927937;
select tuple_data_split('test_sequence'::regclass, t_data, t_infomask, t_infomask2, t_bits)
from heap_page_items(get_raw_page('test_sequence', 0));
tuple_data_split
-------------------------------------------------------
{"\\x0100000000000001","\\x0000000000000000","\\x00"}
(1 row)
drop sequence test_sequence;

View File

@ -320,7 +320,11 @@ tuple_data_split_internal(Oid relid, char *tupdata,
raw_attrs = initArrayResult(BYTEAOID, CurrentMemoryContext, false); raw_attrs = initArrayResult(BYTEAOID, CurrentMemoryContext, false);
nattrs = tupdesc->natts; nattrs = tupdesc->natts;
if (rel->rd_rel->relam != HEAP_TABLE_AM_OID) /*
* Sequences always use heap AM, but they don't show that in the catalogs.
*/
if (rel->rd_rel->relkind != RELKIND_SEQUENCE &&
rel->rd_rel->relam != HEAP_TABLE_AM_OID)
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("only heap AM is supported"))); errmsg("only heap AM is supported")));

View File

@ -62,7 +62,7 @@ CREATE TABLE brin_parallel_test (a int, b text, c bigint) WITH (fillfactor=40);
-- for the different opclasses we build later). -- for the different opclasses we build later).
INSERT INTO brin_parallel_test INSERT INTO brin_parallel_test
SELECT (CASE WHEN (mod(i,231) = 0) OR (i BETWEEN 3500 AND 4000) THEN NULL ELSE i END), SELECT (CASE WHEN (mod(i,231) = 0) OR (i BETWEEN 3500 AND 4000) THEN NULL ELSE i END),
(CASE WHEN (mod(i,233) = 0) OR (i BETWEEN 3750 AND 4250) THEN NULL ELSE md5(i::text) END), (CASE WHEN (mod(i,233) = 0) OR (i BETWEEN 3750 AND 4250) THEN NULL ELSE encode(sha256(i::text::bytea), 'hex') END),
(CASE WHEN (mod(i,233) = 0) OR (i BETWEEN 3850 AND 4500) THEN NULL ELSE (i/100) + mod(i,8) END) (CASE WHEN (mod(i,233) = 0) OR (i BETWEEN 3850 AND 4500) THEN NULL ELSE (i/100) + mod(i,8) END)
FROM generate_series(1,5000) S(i); FROM generate_series(1,5000) S(i);

View File

@ -98,3 +98,9 @@ SHOW block_size \gset
SELECT fsm_page_contents(decode(repeat('00', :block_size), 'hex')); SELECT fsm_page_contents(decode(repeat('00', :block_size), 'hex'));
SELECT page_header(decode(repeat('00', :block_size), 'hex')); SELECT page_header(decode(repeat('00', :block_size), 'hex'));
SELECT page_checksum(decode(repeat('00', :block_size), 'hex'), 1); SELECT page_checksum(decode(repeat('00', :block_size), 'hex'), 1);
-- tests for sequences
create sequence test_sequence start 72057594037927937;
select tuple_data_split('test_sequence'::regclass, t_data, t_infomask, t_infomask2, t_bits)
from heap_page_items(get_raw_page('test_sequence', 0));
drop sequence test_sequence;

View File

@ -19,7 +19,8 @@ LDFLAGS_SL += $(filter -lm, $(LIBS))
REGRESS_OPTS = --temp-config $(top_srcdir)/contrib/pg_stat_statements/pg_stat_statements.conf REGRESS_OPTS = --temp-config $(top_srcdir)/contrib/pg_stat_statements/pg_stat_statements.conf
REGRESS = select dml cursors utility level_tracking planning \ REGRESS = select dml cursors utility level_tracking planning \
user_activity wal entry_timestamp cleanup oldextversions user_activity wal entry_timestamp extended cleanup \
oldextversions
# Disabled because these tests require "shared_preload_libraries=pg_stat_statements", # Disabled because these tests require "shared_preload_libraries=pg_stat_statements",
# which typical installcheck users do not have (e.g. buildfarm clients). # which typical installcheck users do not have (e.g. buildfarm clients).
NO_INSTALLCHECK = 1 NO_INSTALLCHECK = 1

View File

@ -0,0 +1,10 @@
-- Tests with extended query protocol
SET pg_stat_statements.track_utility = FALSE;
-- This test checks that an execute message sets a query ID.
SELECT query_id IS NOT NULL AS query_id_set
FROM pg_stat_activity WHERE pid = pg_backend_pid() \bind \g
query_id_set
--------------
t
(1 row)

View File

@ -67,6 +67,51 @@ SELECT toplevel, calls, query FROM pg_stat_statements
t | 1 | SET pg_stat_statements.track = 'all' t | 1 | SET pg_stat_statements.track = 'all'
(7 rows) (7 rows)
-- Procedure with multiple utility statements.
CREATE OR REPLACE PROCEDURE proc_with_utility_stmt()
LANGUAGE SQL
AS $$
SHOW pg_stat_statements.track;
show pg_stat_statements.track;
SHOW pg_stat_statements.track_utility;
$$;
SET pg_stat_statements.track_utility = TRUE;
-- all-level tracking.
SET pg_stat_statements.track = 'all';
SELECT pg_stat_statements_reset() IS NOT NULL AS t;
t
---
t
(1 row)
CALL proc_with_utility_stmt();
SELECT toplevel, calls, query FROM pg_stat_statements
ORDER BY query COLLATE "C", toplevel;
toplevel | calls | query
----------+-------+----------------------------------------------------
t | 1 | CALL proc_with_utility_stmt()
t | 1 | SELECT pg_stat_statements_reset() IS NOT NULL AS t
f | 2 | SHOW pg_stat_statements.track
f | 1 | SHOW pg_stat_statements.track_utility
(4 rows)
-- top-level tracking.
SET pg_stat_statements.track = 'top';
SELECT pg_stat_statements_reset() IS NOT NULL AS t;
t
---
t
(1 row)
CALL proc_with_utility_stmt();
SELECT toplevel, calls, query FROM pg_stat_statements
ORDER BY query COLLATE "C", toplevel;
toplevel | calls | query
----------+-------+----------------------------------------------------
t | 1 | CALL proc_with_utility_stmt()
t | 1 | SELECT pg_stat_statements_reset() IS NOT NULL AS t
(2 rows)
-- DO block - top-level tracking without utility. -- DO block - top-level tracking without utility.
SET pg_stat_statements.track = 'top'; SET pg_stat_statements.track = 'top';
SET pg_stat_statements.track_utility = FALSE; SET pg_stat_statements.track_utility = FALSE;

View File

@ -50,6 +50,7 @@ tests += {
'user_activity', 'user_activity',
'wal', 'wal',
'entry_timestamp', 'entry_timestamp',
'extended',
'cleanup', 'cleanup',
'oldextversions', 'oldextversions',
], ],

View File

@ -887,13 +887,6 @@ pgss_planner(Query *parse,
* We can't process the query if no query_string is provided, as * We can't process the query if no query_string is provided, as
* pgss_store needs it. We also ignore query without queryid, as it would * pgss_store needs it. We also ignore query without queryid, as it would
* be treated as a utility statement, which may not be the case. * be treated as a utility statement, which may not be the case.
*
* Note that planner_hook can be called from the planner itself, so we
* have a specific nesting level for the planner. However, utility
* commands containing optimizable statements can also call the planner,
* same for regular DML (for instance for underlying foreign key queries).
* So testing the planner nesting level only is not enough to detect real
* top level planner call.
*/ */
if (pgss_enabled(nesting_level) if (pgss_enabled(nesting_level)
&& pgss_track_planning && query_string && pgss_track_planning && query_string

View File

@ -0,0 +1,7 @@
-- Tests with extended query protocol
SET pg_stat_statements.track_utility = FALSE;
-- This test checks that an execute message sets a query ID.
SELECT query_id IS NOT NULL AS query_id_set
FROM pg_stat_activity WHERE pid = pg_backend_pid() \bind \g

View File

@ -33,6 +33,28 @@ END; $$;
SELECT toplevel, calls, query FROM pg_stat_statements SELECT toplevel, calls, query FROM pg_stat_statements
ORDER BY query COLLATE "C", toplevel; ORDER BY query COLLATE "C", toplevel;
-- Procedure with multiple utility statements.
CREATE OR REPLACE PROCEDURE proc_with_utility_stmt()
LANGUAGE SQL
AS $$
SHOW pg_stat_statements.track;
show pg_stat_statements.track;
SHOW pg_stat_statements.track_utility;
$$;
SET pg_stat_statements.track_utility = TRUE;
-- all-level tracking.
SET pg_stat_statements.track = 'all';
SELECT pg_stat_statements_reset() IS NOT NULL AS t;
CALL proc_with_utility_stmt();
SELECT toplevel, calls, query FROM pg_stat_statements
ORDER BY query COLLATE "C", toplevel;
-- top-level tracking.
SET pg_stat_statements.track = 'top';
SELECT pg_stat_statements_reset() IS NOT NULL AS t;
CALL proc_with_utility_stmt();
SELECT toplevel, calls, query FROM pg_stat_statements
ORDER BY query COLLATE "C", toplevel;
-- DO block - top-level tracking without utility. -- DO block - top-level tracking without utility.
SET pg_stat_statements.track = 'top'; SET pg_stat_statements.track = 'top';
SET pg_stat_statements.track_utility = FALSE; SET pg_stat_statements.track_utility = FALSE;

View File

@ -2372,6 +2372,9 @@ ERROR: value 2025 out of bounds for option "siglen"
DETAIL: Valid values are between "1" and "2024". DETAIL: Valid values are between "1" and "2024".
create index trgm_idx on test_trgm using gist (t gist_trgm_ops(siglen=2024)); create index trgm_idx on test_trgm using gist (t gist_trgm_ops(siglen=2024));
set enable_seqscan=off; set enable_seqscan=off;
-- check index compatibility handling when opclass option is specified
alter table test_trgm alter column t type varchar(768);
alter table test_trgm alter column t type text;
select t,similarity(t,'qwertyu0988') as sml from test_trgm where t % 'qwertyu0988' order by sml desc, t; select t,similarity(t,'qwertyu0988') as sml from test_trgm where t % 'qwertyu0988' order by sml desc, t;
t | sml t | sml
-------------+---------- -------------+----------

View File

@ -52,6 +52,10 @@ create index trgm_idx on test_trgm using gist (t gist_trgm_ops(siglen=2025));
create index trgm_idx on test_trgm using gist (t gist_trgm_ops(siglen=2024)); create index trgm_idx on test_trgm using gist (t gist_trgm_ops(siglen=2024));
set enable_seqscan=off; set enable_seqscan=off;
-- check index compatibility handling when opclass option is specified
alter table test_trgm alter column t type varchar(768);
alter table test_trgm alter column t type text;
select t,similarity(t,'qwertyu0988') as sml from test_trgm where t % 'qwertyu0988' order by sml desc, t; select t,similarity(t,'qwertyu0988') as sml from test_trgm where t % 'qwertyu0988' order by sml desc, t;
select t,similarity(t,'gwertyu0988') as sml from test_trgm where t % 'gwertyu0988' order by sml desc, t; select t,similarity(t,'gwertyu0988') as sml from test_trgm where t % 'gwertyu0988' order by sml desc, t;
select t,similarity(t,'gwertyu1988') as sml from test_trgm where t % 'gwertyu1988' order by sml desc, t; select t,similarity(t,'gwertyu1988') as sml from test_trgm where t % 'gwertyu1988' order by sml desc, t;

View File

@ -273,6 +273,31 @@ select pgstathashindex('test_partition_hash_idx');
(4,8,0,1,0,0,0,100) (4,8,0,1,0,0,0,100)
(1 row) (1 row)
-- these should work for sequences
create sequence test_sequence;
select count(*) from pgstattuple('test_sequence');
count
-------
1
(1 row)
select pg_relpages('test_sequence');
pg_relpages
-------------
1
(1 row)
-- these should fail for sequences
select pgstatindex('test_sequence');
ERROR: relation "test_sequence" is not a btree index
select pgstatginindex('test_sequence');
ERROR: relation "test_sequence" is not a GIN index
select pgstathashindex('test_sequence');
ERROR: relation "test_sequence" is not a hash index
select pgstattuple_approx('test_sequence');
ERROR: relation "test_sequence" is of wrong relation kind
DETAIL: This operation is not supported for sequences.
drop sequence test_sequence;
drop table test_partitioned; drop table test_partitioned;
drop view test_view; drop view test_view;
drop foreign table test_foreign_table; drop foreign table test_foreign_table;

View File

@ -323,7 +323,11 @@ pgstat_heap(Relation rel, FunctionCallInfo fcinfo)
pgstattuple_type stat = {0}; pgstattuple_type stat = {0};
SnapshotData SnapshotDirty; SnapshotData SnapshotDirty;
if (rel->rd_rel->relam != HEAP_TABLE_AM_OID) /*
* Sequences always use heap AM, but they don't show that in the catalogs.
*/
if (rel->rd_rel->relkind != RELKIND_SEQUENCE &&
rel->rd_rel->relam != HEAP_TABLE_AM_OID)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED), (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("only heap AM is supported"))); errmsg("only heap AM is supported")));

View File

@ -119,6 +119,18 @@ create index test_partition_hash_idx on test_partition using hash (a);
select pgstatindex('test_partition_idx'); select pgstatindex('test_partition_idx');
select pgstathashindex('test_partition_hash_idx'); select pgstathashindex('test_partition_hash_idx');
-- these should work for sequences
create sequence test_sequence;
select count(*) from pgstattuple('test_sequence');
select pg_relpages('test_sequence');
-- these should fail for sequences
select pgstatindex('test_sequence');
select pgstatginindex('test_sequence');
select pgstathashindex('test_sequence');
select pgstattuple_approx('test_sequence');
drop sequence test_sequence;
drop table test_partitioned; drop table test_partitioned;
drop view test_view; drop view test_view;
drop foreign table test_foreign_table; drop foreign table test_foreign_table;

View File

@ -16,7 +16,7 @@ SHLIB_LINK_INTERNAL = $(libpq)
EXTENSION = postgres_fdw EXTENSION = postgres_fdw
DATA = postgres_fdw--1.0.sql postgres_fdw--1.0--1.1.sql DATA = postgres_fdw--1.0.sql postgres_fdw--1.0--1.1.sql
REGRESS = postgres_fdw REGRESS = postgres_fdw query_cancel
ifdef USE_PGXS ifdef USE_PGXS
PG_CONFIG = pg_config PG_CONFIG = pg_config

View File

@ -637,6 +637,17 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft_empty ORDER BY c1;
Remote SQL: SELECT c1, c2 FROM public.loct_empty ORDER BY c1 ASC NULLS LAST Remote SQL: SELECT c1, c2 FROM public.loct_empty ORDER BY c1 ASC NULLS LAST
(3 rows) (3 rows)
-- test restriction on non-system foreign tables.
SET restrict_nonsystem_relation_kind TO 'foreign-table';
SELECT * from ft1 where c1 < 1; -- ERROR
ERROR: access to non-system foreign table is restricted
INSERT INTO ft1 (c1) VALUES (1); -- ERROR
ERROR: access to non-system foreign table is restricted
DELETE FROM ft1 WHERE c1 = 1; -- ERROR
ERROR: access to non-system foreign table is restricted
TRUNCATE ft1; -- ERROR
ERROR: access to non-system foreign table is restricted
RESET restrict_nonsystem_relation_kind;
-- =================================================================== -- ===================================================================
-- WHERE with remotely-executable conditions -- WHERE with remotely-executable conditions
-- =================================================================== -- ===================================================================
@ -2760,22 +2771,6 @@ SELECT t1.c1, t2.c2 FROM v4 t1 LEFT JOIN ft5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c
(10 rows) (10 rows)
ALTER VIEW v4 OWNER TO regress_view_owner; ALTER VIEW v4 OWNER TO regress_view_owner;
-- Make sure this big CROSS JOIN query is pushed down
EXPLAIN (VERBOSE, COSTS OFF) SELECT count(*) FROM ft1 CROSS JOIN ft2 CROSS JOIN ft4 CROSS JOIN ft5;
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
Foreign Scan
Output: (count(*))
Relations: Aggregate on ((((public.ft1) INNER JOIN (public.ft2)) INNER JOIN (public.ft4)) INNER JOIN (public.ft5))
Remote SQL: SELECT count(*) FROM ((("S 1"."T 1" r1 INNER JOIN "S 1"."T 1" r2 ON (TRUE)) INNER JOIN "S 1"."T 3" r4 ON (TRUE)) INNER JOIN "S 1"."T 4" r6 ON (TRUE))
(4 rows)
-- Make sure query cancellation works
BEGIN;
SET LOCAL statement_timeout = '10ms';
select count(*) from ft1 CROSS JOIN ft2 CROSS JOIN ft4 CROSS JOIN ft5; -- this takes very long
ERROR: canceling statement due to statement timeout
COMMIT;
-- ==================================================================== -- ====================================================================
-- Check that userid to use when querying the remote table is correctly -- Check that userid to use when querying the remote table is correctly
-- propagated into foreign rels present in subqueries under an UNION ALL -- propagated into foreign rels present in subqueries under an UNION ALL
@ -6846,6 +6841,51 @@ SELECT * FROM ft1 ORDER BY c6 ASC NULLS FIRST, c1 OFFSET 15 LIMIT 10;
40 | 42 | 00040_trig_update | Tue Feb 10 00:00:00 1970 PST | Tue Feb 10 00:00:00 1970 | 0 | 0 | foo 40 | 42 | 00040_trig_update | Tue Feb 10 00:00:00 1970 PST | Tue Feb 10 00:00:00 1970 | 0 | 0 | foo
(10 rows) (10 rows)
-- Test ReScan code path that recreates the cursor even when no parameters
-- change (bug #17889)
CREATE TABLE loct1 (c1 int);
CREATE TABLE loct2 (c1 int, c2 text);
INSERT INTO loct1 VALUES (1001);
INSERT INTO loct1 VALUES (1002);
INSERT INTO loct2 SELECT id, to_char(id, 'FM0000') FROM generate_series(1, 1000) id;
INSERT INTO loct2 VALUES (1001, 'foo');
INSERT INTO loct2 VALUES (1002, 'bar');
CREATE FOREIGN TABLE remt2 (c1 int, c2 text) SERVER loopback OPTIONS (table_name 'loct2');
ANALYZE loct1;
ANALYZE remt2;
SET enable_mergejoin TO false;
SET enable_hashjoin TO false;
SET enable_material TO false;
EXPLAIN (VERBOSE, COSTS OFF)
UPDATE remt2 SET c2 = remt2.c2 || remt2.c2 FROM loct1 WHERE loct1.c1 = remt2.c1 RETURNING remt2.*;
QUERY PLAN
--------------------------------------------------------------------------------
Update on public.remt2
Output: remt2.c1, remt2.c2
Remote SQL: UPDATE public.loct2 SET c2 = $2 WHERE ctid = $1 RETURNING c1, c2
-> Nested Loop
Output: (remt2.c2 || remt2.c2), remt2.ctid, remt2.*, loct1.ctid
Join Filter: (remt2.c1 = loct1.c1)
-> Seq Scan on public.loct1
Output: loct1.ctid, loct1.c1
-> Foreign Scan on public.remt2
Output: remt2.c2, remt2.ctid, remt2.*, remt2.c1
Remote SQL: SELECT c1, c2, ctid FROM public.loct2 FOR UPDATE
(11 rows)
UPDATE remt2 SET c2 = remt2.c2 || remt2.c2 FROM loct1 WHERE loct1.c1 = remt2.c1 RETURNING remt2.*;
c1 | c2
------+--------
1001 | foofoo
1002 | barbar
(2 rows)
RESET enable_mergejoin;
RESET enable_hashjoin;
RESET enable_material;
DROP FOREIGN TABLE remt2;
DROP TABLE loct1;
DROP TABLE loct2;
-- =================================================================== -- ===================================================================
-- test check constraints -- test check constraints
-- =================================================================== -- ===================================================================

View File

@ -0,0 +1,32 @@
SELECT version() ~ 'cygwin' AS skip_test \gset
\if :skip_test
\quit
\endif
-- Let's test canceling a remote query. Use a table that does not have
-- remote_estimate enabled, else there will be multiple queries to the
-- remote and we might unluckily send the cancel in between two of them.
-- First let's confirm that the query is actually pushed down.
EXPLAIN (VERBOSE, COSTS OFF)
SELECT count(*) FROM ft1 a CROSS JOIN ft1 b CROSS JOIN ft1 c CROSS JOIN ft1 d;
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
Foreign Scan
Output: (count(*))
Relations: Aggregate on ((((public.ft1 a) INNER JOIN (public.ft1 b)) INNER JOIN (public.ft1 c)) INNER JOIN (public.ft1 d))
Remote SQL: SELECT count(*) FROM ((("S 1"."T 1" r1 INNER JOIN "S 1"."T 1" r2 ON (TRUE)) INNER JOIN "S 1"."T 1" r4 ON (TRUE)) INNER JOIN "S 1"."T 1" r6 ON (TRUE))
(4 rows)
BEGIN;
-- Make sure that connection is open and set up.
SELECT count(*) FROM ft1 a;
count
-------
822
(1 row)
-- Timeout needs to be long enough to be sure that we've sent the slow query.
SET LOCAL statement_timeout = '100ms';
-- This would take very long if not canceled:
SELECT count(*) FROM ft1 a CROSS JOIN ft1 b CROSS JOIN ft1 c CROSS JOIN ft1 d;
ERROR: canceling statement due to statement timeout
COMMIT;

View File

@ -0,0 +1,3 @@
SELECT version() ~ 'cygwin' AS skip_test \gset
\if :skip_test
\quit

View File

@ -36,6 +36,7 @@ tests += {
'regress': { 'regress': {
'sql': [ 'sql': [
'postgres_fdw', 'postgres_fdw',
'query_cancel',
], ],
'regress_args': ['--dlpath', meson.build_root() / 'src/test/regress'], 'regress_args': ['--dlpath', meson.build_root() / 'src/test/regress'],
}, },

View File

@ -522,7 +522,7 @@ process_pgfdw_appname(const char *appname)
appendStringInfoString(&buf, application_name); appendStringInfoString(&buf, application_name);
break; break;
case 'c': case 'c':
appendStringInfo(&buf, "%lx.%x", (long) (MyStartTime), MyProcPid); appendStringInfo(&buf, "%" INT64_MODIFIER "x.%x", MyStartTime, MyProcPid);
break; break;
case 'C': case 'C':
appendStringInfoString(&buf, cluster_name); appendStringInfoString(&buf, cluster_name);

View File

@ -1662,9 +1662,12 @@ postgresReScanForeignScan(ForeignScanState *node)
/* /*
* If any internal parameters affecting this node have changed, we'd * If any internal parameters affecting this node have changed, we'd
* better destroy and recreate the cursor. Otherwise, rewinding it should * better destroy and recreate the cursor. Otherwise, if the remote
* be good enough. If we've only fetched zero or one batch, we needn't * server is v14 or older, rewinding it should be good enough; if not,
* even rewind the cursor, just rescan what we have. * rewind is only allowed for scrollable cursors, but we don't have a way
* to check the scrollability of it, so destroy and recreate it in any
* case. If we've only fetched zero or one batch, we needn't even rewind
* the cursor, just rescan what we have.
*/ */
if (node->ss.ps.chgParam != NULL) if (node->ss.ps.chgParam != NULL)
{ {
@ -1674,8 +1677,15 @@ postgresReScanForeignScan(ForeignScanState *node)
} }
else if (fsstate->fetch_ct_2 > 1) else if (fsstate->fetch_ct_2 > 1)
{ {
snprintf(sql, sizeof(sql), "MOVE BACKWARD ALL IN c%u", if (PQserverVersion(fsstate->conn) < 150000)
fsstate->cursor_number); snprintf(sql, sizeof(sql), "MOVE BACKWARD ALL IN c%u",
fsstate->cursor_number);
else
{
fsstate->cursor_exists = false;
snprintf(sql, sizeof(sql), "CLOSE c%u",
fsstate->cursor_number);
}
} }
else else
{ {

View File

@ -327,6 +327,14 @@ DELETE FROM loct_empty;
ANALYZE ft_empty; ANALYZE ft_empty;
EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft_empty ORDER BY c1; EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft_empty ORDER BY c1;
-- test restriction on non-system foreign tables.
SET restrict_nonsystem_relation_kind TO 'foreign-table';
SELECT * from ft1 where c1 < 1; -- ERROR
INSERT INTO ft1 (c1) VALUES (1); -- ERROR
DELETE FROM ft1 WHERE c1 = 1; -- ERROR
TRUNCATE ft1; -- ERROR
RESET restrict_nonsystem_relation_kind;
-- =================================================================== -- ===================================================================
-- WHERE with remotely-executable conditions -- WHERE with remotely-executable conditions
-- =================================================================== -- ===================================================================
@ -742,14 +750,6 @@ SELECT t1.c1, t2.c2 FROM v4 t1 LEFT JOIN ft5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c
SELECT t1.c1, t2.c2 FROM v4 t1 LEFT JOIN ft5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 10 LIMIT 10; SELECT t1.c1, t2.c2 FROM v4 t1 LEFT JOIN ft5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 10 LIMIT 10;
ALTER VIEW v4 OWNER TO regress_view_owner; ALTER VIEW v4 OWNER TO regress_view_owner;
-- Make sure this big CROSS JOIN query is pushed down
EXPLAIN (VERBOSE, COSTS OFF) SELECT count(*) FROM ft1 CROSS JOIN ft2 CROSS JOIN ft4 CROSS JOIN ft5;
-- Make sure query cancellation works
BEGIN;
SET LOCAL statement_timeout = '10ms';
select count(*) from ft1 CROSS JOIN ft2 CROSS JOIN ft4 CROSS JOIN ft5; -- this takes very long
COMMIT;
-- ==================================================================== -- ====================================================================
-- Check that userid to use when querying the remote table is correctly -- Check that userid to use when querying the remote table is correctly
-- propagated into foreign rels present in subqueries under an UNION ALL -- propagated into foreign rels present in subqueries under an UNION ALL
@ -1647,6 +1647,31 @@ SELECT * FROM ft1 ORDER BY c6 DESC NULLS FIRST, c1 OFFSET 15 LIMIT 10;
EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 ORDER BY c6 ASC NULLS FIRST, c1 OFFSET 15 LIMIT 10; EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 ORDER BY c6 ASC NULLS FIRST, c1 OFFSET 15 LIMIT 10;
SELECT * FROM ft1 ORDER BY c6 ASC NULLS FIRST, c1 OFFSET 15 LIMIT 10; SELECT * FROM ft1 ORDER BY c6 ASC NULLS FIRST, c1 OFFSET 15 LIMIT 10;
-- Test ReScan code path that recreates the cursor even when no parameters
-- change (bug #17889)
CREATE TABLE loct1 (c1 int);
CREATE TABLE loct2 (c1 int, c2 text);
INSERT INTO loct1 VALUES (1001);
INSERT INTO loct1 VALUES (1002);
INSERT INTO loct2 SELECT id, to_char(id, 'FM0000') FROM generate_series(1, 1000) id;
INSERT INTO loct2 VALUES (1001, 'foo');
INSERT INTO loct2 VALUES (1002, 'bar');
CREATE FOREIGN TABLE remt2 (c1 int, c2 text) SERVER loopback OPTIONS (table_name 'loct2');
ANALYZE loct1;
ANALYZE remt2;
SET enable_mergejoin TO false;
SET enable_hashjoin TO false;
SET enable_material TO false;
EXPLAIN (VERBOSE, COSTS OFF)
UPDATE remt2 SET c2 = remt2.c2 || remt2.c2 FROM loct1 WHERE loct1.c1 = remt2.c1 RETURNING remt2.*;
UPDATE remt2 SET c2 = remt2.c2 || remt2.c2 FROM loct1 WHERE loct1.c1 = remt2.c1 RETURNING remt2.*;
RESET enable_mergejoin;
RESET enable_hashjoin;
RESET enable_material;
DROP FOREIGN TABLE remt2;
DROP TABLE loct1;
DROP TABLE loct2;
-- =================================================================== -- ===================================================================
-- test check constraints -- test check constraints
-- =================================================================== -- ===================================================================

View File

@ -0,0 +1,20 @@
SELECT version() ~ 'cygwin' AS skip_test \gset
\if :skip_test
\quit
\endif
-- Let's test canceling a remote query. Use a table that does not have
-- remote_estimate enabled, else there will be multiple queries to the
-- remote and we might unluckily send the cancel in between two of them.
-- First let's confirm that the query is actually pushed down.
EXPLAIN (VERBOSE, COSTS OFF)
SELECT count(*) FROM ft1 a CROSS JOIN ft1 b CROSS JOIN ft1 c CROSS JOIN ft1 d;
BEGIN;
-- Make sure that connection is open and set up.
SELECT count(*) FROM ft1 a;
-- Timeout needs to be long enough to be sure that we've sent the slow query.
SET LOCAL statement_timeout = '100ms';
-- This would take very long if not canceled:
SELECT count(*) FROM ft1 a CROSS JOIN ft1 b CROSS JOIN ft1 c CROSS JOIN ft1 d;
COMMIT;

View File

@ -14,7 +14,7 @@ PGFILEDESC = "seg - line segment data type"
HEADERS = segdata.h HEADERS = segdata.h
REGRESS = security seg REGRESS = security seg partition
EXTRA_CLEAN = segparse.h segparse.c segscan.c EXTRA_CLEAN = segparse.h segparse.c segscan.c

View File

@ -0,0 +1,54 @@
--
-- Test that partitioned-index operations cope with objects that are
-- not in the secure search path. (This has little to do with seg,
-- but we need an opclass that isn't in pg_catalog, and the base system
-- has no such opclass.) Note that we need to test propagation of the
-- partitioned index's properties both to partitions that pre-date it
-- and to partitions created later.
--
create function mydouble(int) returns int strict immutable parallel safe
begin atomic select $1 * 2; end;
create collation mycollation from "POSIX";
create table pt (category int, sdata seg, tdata text)
partition by list (category);
-- pre-existing partition
create table pt12 partition of pt for values in (1,2);
insert into pt values(1, '0 .. 1'::seg, 'zed');
-- expression references object in public schema
create index pti1 on pt ((mydouble(category) + 1));
-- opclass in public schema
create index pti2 on pt (sdata seg_ops);
-- collation in public schema
create index pti3 on pt (tdata collate mycollation);
-- new partition
create table pt34 partition of pt for values in (3,4);
insert into pt values(4, '-1 .. 1'::seg, 'foo');
\d+ pt
Partitioned table "public.pt"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
----------+---------+-----------+----------+---------+----------+--------------+-------------
category | integer | | | | plain | |
sdata | seg | | | | plain | |
tdata | text | | | | extended | |
Partition key: LIST (category)
Indexes:
"pti1" btree ((mydouble(category) + 1))
"pti2" btree (sdata)
"pti3" btree (tdata COLLATE mycollation)
Partitions: pt12 FOR VALUES IN (1, 2),
pt34 FOR VALUES IN (3, 4)
\d+ pt12
Table "public.pt12"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
----------+---------+-----------+----------+---------+----------+--------------+-------------
category | integer | | | | plain | |
sdata | seg | | | | plain | |
tdata | text | | | | extended | |
Partition of: pt FOR VALUES IN (1, 2)
Partition constraint: ((category IS NOT NULL) AND (category = ANY (ARRAY[1, 2])))
Indexes:
"pt12_expr_idx" btree ((mydouble(category) + 1))
"pt12_sdata_idx" btree (sdata)
"pt12_tdata_idx" btree (tdata COLLATE mycollation)

View File

@ -55,6 +55,7 @@ tests += {
'sql': [ 'sql': [
'security', 'security',
'seg', 'seg',
'partition',
], ],
}, },
} }

View File

@ -0,0 +1,36 @@
--
-- Test that partitioned-index operations cope with objects that are
-- not in the secure search path. (This has little to do with seg,
-- but we need an opclass that isn't in pg_catalog, and the base system
-- has no such opclass.) Note that we need to test propagation of the
-- partitioned index's properties both to partitions that pre-date it
-- and to partitions created later.
--
create function mydouble(int) returns int strict immutable parallel safe
begin atomic select $1 * 2; end;
create collation mycollation from "POSIX";
create table pt (category int, sdata seg, tdata text)
partition by list (category);
-- pre-existing partition
create table pt12 partition of pt for values in (1,2);
insert into pt values(1, '0 .. 1'::seg, 'zed');
-- expression references object in public schema
create index pti1 on pt ((mydouble(category) + 1));
-- opclass in public schema
create index pti2 on pt (sdata seg_ops);
-- collation in public schema
create index pti3 on pt (tdata collate mycollation);
-- new partition
create table pt34 partition of pt for values in (3,4);
insert into pt values(4, '-1 .. 1'::seg, 'foo');
\d+ pt
\d+ pt12

View File

@ -8,7 +8,8 @@ REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
spill slot truncate stream stats twophase twophase_stream spill slot truncate stream stats twophase twophase_stream
ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \ ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \ oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
twophase_snapshot slot_creation_error catalog_change_snapshot twophase_snapshot slot_creation_error catalog_change_snapshot \
skip_snapshot_restore
REGRESS_OPTS = --temp-config $(top_srcdir)/contrib/test_decoding/logical.conf REGRESS_OPTS = --temp-config $(top_srcdir)/contrib/test_decoding/logical.conf
ISOLATION_OPTS = --temp-config $(top_srcdir)/contrib/test_decoding/logical.conf ISOLATION_OPTS = --temp-config $(top_srcdir)/contrib/test_decoding/logical.conf

View File

@ -0,0 +1,45 @@
Parsed test spec with 3 sessions
starting permutation: s0_init s0_begin s0_insert1 s1_init s2_checkpoint s2_get_changes_slot0 s0_insert2 s0_commit s1_get_changes_slot0 s1_get_changes_slot1
step s0_init: SELECT 'init' FROM pg_create_logical_replication_slot('slot0', 'test_decoding');
?column?
--------
init
(1 row)
step s0_begin: BEGIN;
step s0_insert1: INSERT INTO tbl VALUES (1);
step s1_init: SELECT 'init' FROM pg_create_logical_replication_slot('slot1', 'test_decoding'); <waiting ...>
step s2_checkpoint: CHECKPOINT;
step s2_get_changes_slot0: SELECT data FROM pg_logical_slot_get_changes('slot0', NULL, NULL, 'skip-empty-xacts', '1', 'include-xids', '0');
data
----
(0 rows)
step s0_insert2: INSERT INTO tbl VALUES (2);
step s0_commit: COMMIT;
step s1_init: <... completed>
?column?
--------
init
(1 row)
step s1_get_changes_slot0: SELECT data FROM pg_logical_slot_get_changes('slot0', NULL, NULL, 'skip-empty-xacts', '1', 'include-xids', '0');
data
-----------------------------------------
BEGIN
table public.tbl: INSERT: val1[integer]:1
table public.tbl: INSERT: val1[integer]:2
COMMIT
(4 rows)
step s1_get_changes_slot1: SELECT data FROM pg_logical_slot_get_changes('slot1', NULL, NULL, 'skip-empty-xacts', '1', 'include-xids', '0');
data
----
(0 rows)
?column?
--------
stop
(1 row)

View File

@ -109,6 +109,25 @@ SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL, 'incl
committing streamed transaction committing streamed transaction
(17 rows) (17 rows)
/*
* Test concurrent abort with toast data. When streaming the second insertion, we
* detect that the subtransaction was aborted, and reset the transaction while having
* the TOAST changes in memory, resulting in deallocating both decoded changes and
* TOAST reconstruction data. Memory usage counters must be updated correctly.
*/
BEGIN;
INSERT INTO stream_test SELECT repeat(string_agg(to_char(g.i, 'FM0000'), ''), 50) FROM generate_series(1, 500) g(i);
ALTER TABLE stream_test ADD COLUMN i INT;
SAVEPOINT s1;
INSERT INTO stream_test(data, i) SELECT repeat(string_agg(to_char(g.i, 'FM0000'), ''), 50), 1 FROM generate_series(1, 500) g(i);
ROLLBACK TO s1;
COMMIT;
SELECT count(*) FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'stream-changes', '1');
count
-------
5
(1 row)
DROP TABLE stream_test; DROP TABLE stream_test;
SELECT pg_drop_replication_slot('regression_slot'); SELECT pg_drop_replication_slot('regression_slot');
pg_drop_replication_slot pg_drop_replication_slot

View File

@ -205,11 +205,34 @@ SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'inc
COMMIT COMMIT
(3 rows) (3 rows)
-- Test that accessing a TOAST table is permitted during the decoding of a
-- prepared transaction.
-- Create a table with a column that uses a TOASTed default value.
-- (temporarily hide query, to avoid the long CREATE TABLE stmt)
\set ECHO none
BEGIN;
INSERT INTO test_tab VALUES('test');
PREPARE TRANSACTION 'test_toast_table_access';
SELECT count(*) FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'stream-changes', '1');
count
-------
3
(1 row)
COMMIT PREPARED 'test_toast_table_access';
-- consume commit prepared
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'stream-changes', '1');
data
-------------------------------------------
COMMIT PREPARED 'test_toast_table_access'
(1 row)
-- Test 8: -- Test 8:
-- cleanup and make sure results are also empty -- cleanup and make sure results are also empty
DROP TABLE test_prepared1; DROP TABLE test_prepared1;
DROP TABLE test_prepared2; DROP TABLE test_prepared2;
DROP TABLE test_prepared_savepoint; DROP TABLE test_prepared_savepoint;
DROP TABLE test_tab;
-- show results. There should be nothing to show -- show results. There should be nothing to show
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
data data

View File

@ -62,6 +62,7 @@ tests += {
'concurrent_stream', 'concurrent_stream',
'twophase_snapshot', 'twophase_snapshot',
'slot_creation_error', 'slot_creation_error',
'skip_snapshot_restore',
], ],
'regress_args': [ 'regress_args': [
'--temp-config', files('logical.conf'), '--temp-config', files('logical.conf'),

View File

@ -0,0 +1,46 @@
# Test that a slot creation skips to restore serialized snapshot to reach
# the consistent state.
setup
{
DROP TABLE IF EXISTS tbl;
CREATE TABLE tbl (val1 integer);
}
teardown
{
DROP TABLE tbl;
SELECT 'stop' FROM pg_drop_replication_slot('slot0');
SELECT 'stop' FROM pg_drop_replication_slot('slot1');
}
session "s0"
setup { SET synchronous_commit = on; }
step "s0_init" { SELECT 'init' FROM pg_create_logical_replication_slot('slot0', 'test_decoding'); }
step "s0_begin" { BEGIN; }
step "s0_insert1" { INSERT INTO tbl VALUES (1); }
step "s0_insert2" { INSERT INTO tbl VALUES (2); }
step "s0_commit" { COMMIT; }
session "s1"
setup { SET synchronous_commit = on; }
step "s1_init" { SELECT 'init' FROM pg_create_logical_replication_slot('slot1', 'test_decoding'); }
step "s1_get_changes_slot0" { SELECT data FROM pg_logical_slot_get_changes('slot0', NULL, NULL, 'skip-empty-xacts', '1', 'include-xids', '0'); }
step "s1_get_changes_slot1" { SELECT data FROM pg_logical_slot_get_changes('slot1', NULL, NULL, 'skip-empty-xacts', '1', 'include-xids', '0'); }
session "s2"
setup { SET synchronous_commit = on ;}
step "s2_checkpoint" { CHECKPOINT; }
step "s2_get_changes_slot0" { SELECT data FROM pg_logical_slot_get_changes('slot0', NULL, NULL, 'skip-empty-xacts', '1', 'include-xids', '0'); }
# While 'slot1' creation by "s1_init" waits for s0-transaction to commit, the
# RUNNING_XACTS record is written by "s2_checkpoint" and "s2_get_changes_slot1"
# serializes consistent snapshots to the disk at LSNs where are before
# s0-transaction's commit. After s0-transaction commits, "s1_init" resumes but
# must not restore any serialized snapshots and will reach the consistent state
# when decoding a RUNNING_XACT record generated after s0-transaction's commit.
# We check if the get_changes on 'slot1' will not return any s0-transaction's
# changes as its confirmed_flush_lsn will be after the s0-transaction's commit
# record.
permutation "s0_init" "s0_begin" "s0_insert1" "s1_init" "s2_checkpoint" "s2_get_changes_slot0" "s0_insert2" "s0_commit" "s1_get_changes_slot0" "s1_get_changes_slot1"

View File

@ -44,5 +44,20 @@ toasted-123456789012345678901234567890123456789012345678901234567890123456789012
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'stream-changes', '1'); SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'stream-changes', '1');
/*
* Test concurrent abort with toast data. When streaming the second insertion, we
* detect that the subtransaction was aborted, and reset the transaction while having
* the TOAST changes in memory, resulting in deallocating both decoded changes and
* TOAST reconstruction data. Memory usage counters must be updated correctly.
*/
BEGIN;
INSERT INTO stream_test SELECT repeat(string_agg(to_char(g.i, 'FM0000'), ''), 50) FROM generate_series(1, 500) g(i);
ALTER TABLE stream_test ADD COLUMN i INT;
SAVEPOINT s1;
INSERT INTO stream_test(data, i) SELECT repeat(string_agg(to_char(g.i, 'FM0000'), ''), 50), 1 FROM generate_series(1, 500) g(i);
ROLLBACK TO s1;
COMMIT;
SELECT count(*) FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'stream-changes', '1');
DROP TABLE stream_test; DROP TABLE stream_test;
SELECT pg_drop_replication_slot('regression_slot'); SELECT pg_drop_replication_slot('regression_slot');

View File

@ -104,11 +104,33 @@ COMMIT PREPARED 'test_prepared_nodecode';
-- should be decoded now -- should be decoded now
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
-- Test that accessing a TOAST table is permitted during the decoding of a
-- prepared transaction.
-- Create a table with a column that uses a TOASTed default value.
-- (temporarily hide query, to avoid the long CREATE TABLE stmt)
\set ECHO none
SELECT 'CREATE TABLE test_tab (a text DEFAULT ''' || string_agg('toast value', '') || ''');' FROM generate_series(1, 4000)
\gexec
\set ECHO all
BEGIN;
INSERT INTO test_tab VALUES('test');
PREPARE TRANSACTION 'test_toast_table_access';
SELECT count(*) FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'stream-changes', '1');
COMMIT PREPARED 'test_toast_table_access';
-- consume commit prepared
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'stream-changes', '1');
-- Test 8: -- Test 8:
-- cleanup and make sure results are also empty -- cleanup and make sure results are also empty
DROP TABLE test_prepared1; DROP TABLE test_prepared1;
DROP TABLE test_prepared2; DROP TABLE test_prepared2;
DROP TABLE test_prepared_savepoint; DROP TABLE test_prepared_savepoint;
DROP TABLE test_tab;
-- show results. There should be nothing to show -- show results. There should be nothing to show
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');

View File

@ -386,7 +386,7 @@ pgxml_xpath(text *document, xmlChar *xpath, xpath_workspace *workspace)
workspace->ctxt->node = xmlDocGetRootElement(workspace->doctree); workspace->ctxt->node = xmlDocGetRootElement(workspace->doctree);
/* compile the path */ /* compile the path */
comppath = xmlXPathCompile(xpath); comppath = xmlXPathCtxtCompile(workspace->ctxt, xpath);
if (comppath == NULL) if (comppath == NULL)
xml_ereport(xmlerrcxt, ERROR, ERRCODE_EXTERNAL_ROUTINE_EXCEPTION, xml_ereport(xmlerrcxt, ERROR, ERRCODE_EXTERNAL_ROUTINE_EXCEPTION,
"XPath Syntax Error"); "XPath Syntax Error");
@ -650,7 +650,7 @@ xpath_table(PG_FUNCTION_ARGS)
ctxt->node = xmlDocGetRootElement(doctree); ctxt->node = xmlDocGetRootElement(doctree);
/* compile the path */ /* compile the path */
comppath = xmlXPathCompile(xpaths[j]); comppath = xmlXPathCtxtCompile(ctxt, xpaths[j]);
if (comppath == NULL) if (comppath == NULL)
xml_ereport(xmlerrcxt, ERROR, xml_ereport(xmlerrcxt, ERROR,
ERRCODE_EXTERNAL_ROUTINE_EXCEPTION, ERRCODE_EXTERNAL_ROUTINE_EXCEPTION,

View File

@ -925,6 +925,17 @@ test ! -f /mnt/server/archivedir/00000001000000A900000065 &amp;&amp; cp pg_wal/0
to manage. For a large database all of which is heavily modified, to manage. For a large database all of which is heavily modified,
incremental backups won't be much smaller than full backups. incremental backups won't be much smaller than full backups.
</para> </para>
<para>
An incremental backup is only possible if replay would begin from a later
checkpoint than for the previous backup upon which it depends. If you
take the incremental backup on the primary, this condition is always
satisfied, because each backup triggers a new checkpoint. On a standby,
replay begins from the most recent restartpoint. Therefore, an
incremental backup of a standby server can fail if there has been very
little activity since the previous backup, since no new restartpoint might
have been created.
</para>
</sect2> </sect2>
<sect2 id="backup-lowlevel-base-backup"> <sect2 id="backup-lowlevel-base-backup">

View File

@ -1443,11 +1443,11 @@ include_dir 'conf.d'
</para> </para>
<para> <para>
Older PostgreSQL versions do not have this setting and always use the <productname>PostgreSQL</productname> versions before 9.4 do not have
client's preferences. This setting is mainly for backward this setting and always use the client's preferences. This setting is
compatibility with those versions. Using the server's preferences is mainly for backward compatibility with those versions. Using the
usually better because it is more likely that the server is appropriately server's preferences is usually better because it is more likely that
configured. the server is appropriately configured.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -4318,11 +4318,17 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows
<listitem> <listitem>
<para> <para>
Enables the WAL summarizer process. Note that WAL summarization can Enables the WAL summarizer process. Note that WAL summarization can
be enabled either on a primary or on a standby. WAL summarization be enabled either on a primary or on a standby. This parameter can only
cannot be enabled when <varname>wal_level</varname> is set to be set in the <filename>postgresql.conf</filename> file or on the server
<literal>minimal</literal>. This parameter can only be set in the command line. The default is <literal>off</literal>.
<filename>postgresql.conf</filename> file or on the server command line. </para>
The default is <literal>off</literal>. <para>
The server cannot be started with <literal>summarize_wal=on</literal>
if <literal>wal_level</literal> is set to <literal>minimal</literal>. If
<literal>summarize_wal=on</literal> is configured after server startup
while <literal>wal_level=minimal</literal>, the summarizer will run
but refuse to generate summary files for any WAL generated with
<literal>wal_level=minimal</literal>.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -4569,10 +4575,10 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry id="guc-standby-slot-names" xreflabel="standby_slot_names"> <varlistentry id="guc-synchronized-standby-slots" xreflabel="synchronized_standby_slots">
<term><varname>standby_slot_names</varname> (<type>string</type>) <term><varname>synchronized_standby_slots</varname> (<type>string</type>)
<indexterm> <indexterm>
<primary><varname>standby_slot_names</varname> configuration parameter</primary> <primary><varname>synchronized_standby_slots</varname> configuration parameter</primary>
</indexterm> </indexterm>
</term> </term>
<listitem> <listitem>
@ -4587,7 +4593,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows
after the standby is promoted, the physical replication slot for the after the standby is promoted, the physical replication slot for the
standby should be listed here. Note that logical replication will not standby should be listed here. Note that logical replication will not
proceed if the slots specified in the proceed if the slots specified in the
<varname>standby_slot_names</varname> do not exist or are invalidated. <varname>synchronized_standby_slots</varname> do not exist or are invalidated.
Additionally, the replication management functions Additionally, the replication management functions
<link linkend="pg-replication-slot-advance"> <link linkend="pg-replication-slot-advance">
<function>pg_replication_slot_advance</function></link>, <function>pg_replication_slot_advance</function></link>,
@ -4596,12 +4602,12 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows
<link linkend="pg-logical-slot-peek-changes"> <link linkend="pg-logical-slot-peek-changes">
<function>pg_logical_slot_peek_changes</function></link>, <function>pg_logical_slot_peek_changes</function></link>,
when used with logical failover slots, will block until all when used with logical failover slots, will block until all
physical slots specified in <varname>standby_slot_names</varname> have physical slots specified in <varname>synchronized_standby_slots</varname> have
confirmed WAL receipt. confirmed WAL receipt.
</para> </para>
<para> <para>
The standbys corresponding to the physical replication slots in The standbys corresponding to the physical replication slots in
<varname>standby_slot_names</varname> must configure <varname>synchronized_standby_slots</varname> must configure
<literal>sync_replication_slots = true</literal> so they can receive <literal>sync_replication_slots = true</literal> so they can receive
logical failover slot changes from the primary. logical failover slot changes from the primary.
</para> </para>
@ -5413,8 +5419,9 @@ ANY <replaceable class="parameter">num_sync</replaceable> ( <replaceable class="
</term> </term>
<listitem> <listitem>
<para> <para>
Enables or disables the query planner's use of index-scan plan Enables or disables the query planner's use of index-scan and
types. The default is <literal>on</literal>. index-only-scan plan types. The default is <literal>on</literal>.
Also see <xref linkend="guc-enable-indexonlyscan"/>.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -5429,7 +5436,9 @@ ANY <replaceable class="parameter">num_sync</replaceable> ( <replaceable class="
<para> <para>
Enables or disables the query planner's use of index-only-scan plan Enables or disables the query planner's use of index-only-scan plan
types (see <xref linkend="indexes-index-only-scans"/>). types (see <xref linkend="indexes-index-only-scans"/>).
The default is <literal>on</literal>. The default is <literal>on</literal>. The
<xref linkend="guc-enable-indexscan"/> setting must also be
enabled to have the query planner consider index-only-scans.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -5561,9 +5570,13 @@ ANY <replaceable class="parameter">num_sync</replaceable> ( <replaceable class="
joining the matching partitions. Partitionwise join currently applies joining the matching partitions. Partitionwise join currently applies
only when the join conditions include all the partition keys, which only when the join conditions include all the partition keys, which
must be of the same data type and have one-to-one matching sets of must be of the same data type and have one-to-one matching sets of
child partitions. Because partitionwise join planning can use child partitions. With this setting enabled, the number of nodes
significantly more CPU time and memory during planning, the default is whose memory usage is restricted by <varname>work_mem</varname>
<literal>off</literal>. appearing in the final plan can increase linearly according to the
number of partitions being scanned. This can result in a large
increase in overall memory consumption during the execution of the
query. Query planning also becomes significantly more expensive in
terms of memory and CPU. The default value is <literal>off</literal>.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -5581,9 +5594,13 @@ ANY <replaceable class="parameter">num_sync</replaceable> ( <replaceable class="
tables to be performed separately for each partition. If the tables to be performed separately for each partition. If the
<literal>GROUP BY</literal> clause does not include the partition <literal>GROUP BY</literal> clause does not include the partition
keys, only partial aggregation can be performed on a per-partition keys, only partial aggregation can be performed on a per-partition
basis, and finalization must be performed later. Because basis, and finalization must be performed later. With this setting
partitionwise grouping or aggregation can use significantly more CPU enabled, the number of nodes whose memory usage is restricted by
time and memory during planning, the default is <varname>work_mem</varname> appearing in the final plan can increase
linearly according to the number of partitions being scanned. This
can result in a large increase in overall memory consumption during
the execution of the query. Query planning also becomes significantly
more expensive in terms of memory and CPU. The default value is
<literal>off</literal>. <literal>off</literal>.
</para> </para>
</listitem> </listitem>
@ -8319,7 +8336,9 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv;
measure the overhead of timing on your system. measure the overhead of timing on your system.
I/O timing information is I/O timing information is
displayed in <link linkend="monitoring-pg-stat-database-view"> displayed in <link linkend="monitoring-pg-stat-database-view">
<structname>pg_stat_database</structname></link>, in the output of <structname>pg_stat_database</structname></link>,
<link linkend="monitoring-pg-stat-io-view">
<structname>pg_stat_io</structname></link>, in the output of
<xref linkend="sql-explain"/> when the <literal>BUFFERS</literal> option <xref linkend="sql-explain"/> when the <literal>BUFFERS</literal> option
is used, in the output of <xref linkend="sql-vacuum"/> when is used, in the output of <xref linkend="sql-vacuum"/> when
the <literal>VERBOSE</literal> option is used, by autovacuum the <literal>VERBOSE</literal> option is used, by autovacuum
@ -9368,7 +9387,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv;
<para> <para>
If <varname>transaction_timeout</varname> is shorter or equal to If <varname>transaction_timeout</varname> is shorter or equal to
<varname>idle_in_transaction_session_timeout</varname> or <varname>statement_timeout</varname> <varname>idle_in_transaction_session_timeout</varname> or <varname>statement_timeout</varname>
then the longer timeout is ignored. then the longer timeout is ignored.
</para> </para>
<para> <para>
@ -9797,6 +9816,23 @@ SET XML OPTION { DOCUMENT | CONTENT };
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry id="guc-restrict-nonsystem-relation-kind" xreflabel="restrict_nonsystem_relation_kind">
<term><varname>restrict_nonsystem_relation_kind</varname> (<type>string</type>)
<indexterm>
<primary><varname>restrict_nonsystem_relation_kind</varname></primary>
<secondary>configuration parameter</secondary>
</indexterm>
</term>
<listitem>
<para>
Set relation kinds for which access to non-system relations is prohibited.
The value takes the form of a comma-separated list of relation kinds.
Currently, the supported relation kinds are <literal>view</literal> and
<literal>foreign-table</literal>.
</para>
</listitem>
</varlistentry>
</variablelist> </variablelist>
</sect2> </sect2>
<sect2 id="runtime-config-client-format"> <sect2 id="runtime-config-client-format">

View File

@ -3369,7 +3369,7 @@ SELECT person.name, holidays.num_weeks FROM person, holidays
</row> </row>
<row> <row>
<entry><type>line</type></entry> <entry><type>line</type></entry>
<entry>32 bytes</entry> <entry>24 bytes</entry>
<entry>Infinite line</entry> <entry>Infinite line</entry>
<entry>{A,B,C}</entry> <entry>{A,B,C}</entry>
</row> </row>
@ -3413,6 +3413,11 @@ SELECT person.name, holidays.num_weeks FROM person, holidays
</tgroup> </tgroup>
</table> </table>
<para>
In all these types, the individual coordinates are stored as
<type>double precision</type> (<type>float8</type>) numbers.
</para>
<para> <para>
A rich set of functions and operators is available to perform various geometric A rich set of functions and operators is available to perform various geometric
operations such as scaling, translation, rotation, and determining operations such as scaling, translation, rotation, and determining
@ -3603,8 +3608,16 @@ SELECT person.name, holidays.num_weeks FROM person, holidays
<para> <para>
Polygons are represented by lists of points (the vertices of the Polygons are represented by lists of points (the vertices of the
polygon). Polygons are very similar to closed paths; the essential polygon). Polygons are very similar to closed paths; the essential
difference is that a polygon is considered to include the area semantic difference is that a polygon is considered to include the
within it, while a path is not. area within it, while a path is not.
</para>
<para>
An important implementation difference between polygons and
paths is that the stored representation of a polygon includes its
smallest bounding box. This speeds up certain search operations,
although computing the bounding box adds overhead while constructing
new polygons.
</para> </para>
<para> <para>

View File

@ -257,7 +257,7 @@ CREATE TABLE people (
or alternatively or alternatively
<programlisting> <programlisting>
CREATE TABLE people ( CREATE TABLE people (
id bigint <emphasis>GENERATED BY DEFAULT IDENTITY</emphasis>, id bigint <emphasis>GENERATED BY DEFAULT AS IDENTITY</emphasis>,
..., ...,
); );
</programlisting> </programlisting>
@ -271,8 +271,8 @@ CREATE TABLE people (
example, with the above definitions and assuming additional appropriate example, with the above definitions and assuming additional appropriate
columns, writing columns, writing
<programlisting> <programlisting>
INSERT INTO people (name, address) VALUE ('A', 'foo'); INSERT INTO people (name, address) VALUES ('A', 'foo');
INSERT INTO people (name, address) VALUE ('B', 'bar'); INSERT INTO people (name, address) VALUES ('B', 'bar');
</programlisting> </programlisting>
would generate values for the <literal>id</literal> column starting at 1 would generate values for the <literal>id</literal> column starting at 1
and result in the following table data: and result in the following table data:
@ -285,7 +285,7 @@ INSERT INTO people (name, address) VALUE ('B', 'bar');
Alternatively, the keyword <literal>DEFAULT</literal> can be specified in Alternatively, the keyword <literal>DEFAULT</literal> can be specified in
place of a value to explicitly request the sequence-generated value, like place of a value to explicitly request the sequence-generated value, like
<programlisting> <programlisting>
INSERT INTO people (id, name, address) VALUE (<emphasis>DEFAULT</emphasis>, 'C', 'baz'); INSERT INTO people (id, name, address) VALUES (<emphasis>DEFAULT</emphasis>, 'C', 'baz');
</programlisting> </programlisting>
Similarly, the keyword <literal>DEFAULT</literal> can be used in Similarly, the keyword <literal>DEFAULT</literal> can be used in
<command>UPDATE</command> commands. <command>UPDATE</command> commands.
@ -4354,44 +4354,6 @@ ALTER INDEX measurement_city_id_logdate_key
... ...
</programlisting> </programlisting>
</para> </para>
<para>
There is also an option for merging multiple table partitions into
a single partition using the
<link linkend="sql-altertable-merge-partitions"><command>ALTER TABLE ... MERGE PARTITIONS</command></link>.
This feature simplifies the management of partitioned tables by allowing
users to combine partitions that are no longer needed as
separate entities. It's important to note that this operation is not
supported for hash-partitioned tables and acquires an
<literal>ACCESS EXCLUSIVE</literal> lock, which could impact high-load
systems due to the lock's restrictive nature. For example, we can
merge three monthly partitions into one quarter partition:
<programlisting>
ALTER TABLE measurement
MERGE PARTITIONS (measurement_y2006m01,
measurement_y2006m02,
measurement_y2006m03) INTO measurement_y2006q1;
</programlisting>
</para>
<para>
Similarly to merging multiple table partitions, there is an option for
splitting a single partition into multiple using the
<link linkend="sql-altertable-split-partition"><command>ALTER TABLE ... SPLIT PARTITION</command></link>.
This feature could come in handy when one partition grows too big
and needs to be split into multiple. It's important to note that
this operation is not supported for hash-partitioned tables and acquires
an <literal>ACCESS EXCLUSIVE</literal> lock, which could impact high-load
systems due to the lock's restrictive nature. For example, we can split
the quarter partition back to monthly partitions:
<programlisting>
ALTER TABLE measurement SPLIT PARTITION measurement_y2006q1 INTO
(PARTITION measurement_y2006m01 FOR VALUES FROM ('2006-01-01') TO ('2006-02-01'),
PARTITION measurement_y2006m02 FOR VALUES FROM ('2006-02-01') TO ('2006-03-01'),
PARTITION measurement_y2006m03 FOR VALUES FROM ('2006-03-01') TO ('2006-04-01'));
</programlisting>
</para>
</sect3> </sect3>
<sect3 id="ddl-partitioning-declarative-limitations"> <sect3 id="ddl-partitioning-declarative-limitations">

View File

@ -99,6 +99,11 @@
control statements are available to rewrite a table, control statements are available to rewrite a table,
like <literal>CLUSTER</literal> and <literal>VACUUM</literal>, like <literal>CLUSTER</literal> and <literal>VACUUM</literal>,
the <literal>table_rewrite</literal> event is not triggered by them. the <literal>table_rewrite</literal> event is not triggered by them.
To find the OID of the table that was rewritten, use the function
<literal>pg_event_trigger_table_rewrite_oid()</literal> (see
<xref linkend="functions-event-triggers"/>). To discover the reason(s)
for the rewrite, use the function
<literal>pg_event_trigger_table_rewrite_reason()</literal>.
</para> </para>
<para> <para>

View File

@ -2910,7 +2910,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in
<primary>unicode_assigned</primary> <primary>unicode_assigned</primary>
</indexterm> </indexterm>
<function>unicode_assigned</function> ( <type>text</type> ) <function>unicode_assigned</function> ( <type>text</type> )
<returnvalue>text</returnvalue> <returnvalue>boolean</returnvalue>
</para> </para>
<para> <para>
Returns <literal>true</literal> if all characters in the string are Returns <literal>true</literal> if all characters in the string are
@ -16005,7 +16005,7 @@ table2-mapping
which specifies the data type returned. It must be one of <type>json</type>, which specifies the data type returned. It must be one of <type>json</type>,
<type>jsonb</type>, <type>bytea</type>, a character string type (<type>text</type>, <type>jsonb</type>, <type>bytea</type>, a character string type (<type>text</type>,
<type>char</type>, or <type>varchar</type>), or a type <type>char</type>, or <type>varchar</type>), or a type
for which there is a cast from <type>json</type> to that type. that can be cast to <type>json</type>.
By default, the <type>json</type> type is returned. By default, the <type>json</type> type is returned.
</para> </para>
@ -17965,15 +17965,16 @@ ERROR: jsonpath member accessor can only be applied to an object
<returnvalue><replaceable>string</replaceable></returnvalue> <returnvalue><replaceable>string</replaceable></returnvalue>
</para> </para>
<para> <para>
String value converted from a JSON boolean, number, string, or datetime String value converted from a JSON boolean, number, string, or
datetime
</para> </para>
<para> <para>
<literal>jsonb_path_query_array('[1.23, "xyz", false]', '$[*].string()')</literal> <literal>jsonb_path_query_array('[1.23, "xyz", false]', '$[*].string()')</literal>
<returnvalue>["1.23", "xyz", "false"]</returnvalue> <returnvalue>["1.23", "xyz", "false"]</returnvalue>
</para> </para>
<para> <para>
<literal>jsonb_path_query('"2023-08-15"', '$.datetime().string()')</literal> <literal>jsonb_path_query('"2023-08-15 12:34:56"', '$.timestamp().string()')</literal>
<returnvalue>"2023-08-15"</returnvalue> <returnvalue>"2023-08-15T12:34:56"</returnvalue>
</para></entry> </para></entry>
</row> </row>
@ -18054,7 +18055,9 @@ ERROR: jsonpath member accessor can only be applied to an object
<returnvalue><replaceable>decimal</replaceable></returnvalue> <returnvalue><replaceable>decimal</replaceable></returnvalue>
</para> </para>
<para> <para>
Rounded decimal value converted from a JSON number or string. <literal>precision</literal> and <literal>scale</literal> must be integer values. Rounded decimal value converted from a JSON number or string
(<literal>precision</literal> and <literal>scale</literal> must be
integer values)
</para> </para>
<para> <para>
<literal>jsonb_path_query('1234.5678', '$.decimal(6, 2)')</literal> <literal>jsonb_path_query('1234.5678', '$.decimal(6, 2)')</literal>
@ -18156,7 +18159,7 @@ ERROR: jsonpath member accessor can only be applied to an object
</para> </para>
<para> <para>
Time without time zone value converted from a string, with fractional Time without time zone value converted from a string, with fractional
seconds adjusted to the given precision. seconds adjusted to the given precision
</para> </para>
<para> <para>
<literal>jsonb_path_query('"12:34:56.789"', '$.time(2)')</literal> <literal>jsonb_path_query('"12:34:56.789"', '$.time(2)')</literal>
@ -18185,7 +18188,7 @@ ERROR: jsonpath member accessor can only be applied to an object
</para> </para>
<para> <para>
Time with time zone value converted from a string, with fractional Time with time zone value converted from a string, with fractional
seconds adjusted to the given precision. seconds adjusted to the given precision
</para> </para>
<para> <para>
<literal>jsonb_path_query('"12:34:56.789 +05:30"', '$.time_tz(2)')</literal> <literal>jsonb_path_query('"12:34:56.789 +05:30"', '$.time_tz(2)')</literal>
@ -18214,7 +18217,7 @@ ERROR: jsonpath member accessor can only be applied to an object
</para> </para>
<para> <para>
Timestamp without time zone value converted from a string, with Timestamp without time zone value converted from a string, with
fractional seconds adjusted to the given precision. fractional seconds adjusted to the given precision
</para> </para>
<para> <para>
<literal>jsonb_path_query('"2023-08-15 12:34:56.789"', '$.timestamp(2)')</literal> <literal>jsonb_path_query('"2023-08-15 12:34:56.789"', '$.timestamp(2)')</literal>
@ -18243,7 +18246,7 @@ ERROR: jsonpath member accessor can only be applied to an object
</para> </para>
<para> <para>
Timestamp with time zone value converted from a string, with fractional Timestamp with time zone value converted from a string, with fractional
seconds adjusted to the given precision. seconds adjusted to the given precision
</para> </para>
<para> <para>
<literal>jsonb_path_query('"2023-08-15 12:34:56.789 +05:30"', '$.timestamp_tz(2)')</literal> <literal>jsonb_path_query('"2023-08-15 12:34:56.789 +05:30"', '$.timestamp_tz(2)')</literal>
@ -18665,10 +18668,15 @@ $.* ? (@ like_regex "^\\d+$")
<literal>JSON_QUERY()</literal>, and <literal>JSON_VALUE()</literal> <literal>JSON_QUERY()</literal>, and <literal>JSON_VALUE()</literal>
described in <xref linkend="functions-sqljson-querying"/> can be used described in <xref linkend="functions-sqljson-querying"/> can be used
to query JSON documents. Each of these functions apply a to query JSON documents. Each of these functions apply a
<replaceable>path_expression</replaceable> (the query) to a <replaceable>path_expression</replaceable> (an SQL/JSON path query) to a
<replaceable>context_item</replaceable> (the document); see <replaceable>context_item</replaceable> (the document). See
<xref linkend="functions-sqljson-path"/> for more details on what <xref linkend="functions-sqljson-path"/> for more details on what
<replaceable>path_expression</replaceable> can contain. the <replaceable>path_expression</replaceable> can contain. The
<replaceable>path_expression</replaceable> can also reference variables,
whose values are specified with their respective names in the
<literal>PASSING</literal> clause that is supported by each function.
<replaceable>context_item</replaceable> can be a <type>jsonb</type> value
or a character string that can be successfully cast to <type>jsonb</type>.
</para> </para>
<table id="functions-sqljson-querying"> <table id="functions-sqljson-querying">
@ -18691,37 +18699,48 @@ $.* ? (@ like_regex "^\\d+$")
<row> <row>
<entry role="func_table_entry"><para role="func_signature"> <entry role="func_table_entry"><para role="func_signature">
<indexterm><primary>json_exists</primary></indexterm> <indexterm><primary>json_exists</primary></indexterm>
<function>json_exists</function> ( <synopsis>
<replaceable>context_item</replaceable>, <replaceable>path_expression</replaceable> <optional> <literal>PASSING</literal> { <replaceable>value</replaceable> <literal>AS</literal> <replaceable>varname</replaceable> } <optional>, ...</optional></optional> <function>JSON_EXISTS</function> (
<optional> { <literal>TRUE</literal> | <literal>FALSE</literal> |<literal> UNKNOWN</literal> | <literal>ERROR</literal> } <literal>ON ERROR</literal> </optional>) <replaceable>context_item</replaceable>, <replaceable>path_expression</replaceable>
<optional> <literal>PASSING</literal> { <replaceable>value</replaceable> <literal>AS</literal> <replaceable>varname</replaceable> } <optional>, ...</optional></optional>
<optional>{ <literal>TRUE</literal> | <literal>FALSE</literal> |<literal> UNKNOWN</literal> | <literal>ERROR</literal> } <literal>ON ERROR</literal> </optional>) <returnvalue>boolean</returnvalue>
</synopsis>
</para> </para>
<itemizedlist>
<listitem>
<para> <para>
Returns true if the SQL/JSON <replaceable>path_expression</replaceable> Returns true if the SQL/JSON <replaceable>path_expression</replaceable>
applied to the <replaceable>context_item</replaceable> using the applied to the <replaceable>context_item</replaceable> yields any
<literal>PASSING</literal> <replaceable>value</replaceable>s yields any items, false otherwise.
items.
</para> </para>
</listitem>
<listitem>
<para> <para>
The <literal>ON ERROR</literal> clause specifies the behavior if The <literal>ON ERROR</literal> clause specifies the behavior if
an error occurs; the default is to return the <type>boolean</type> an error occurs during <replaceable>path_expression</replaceable>
<literal>FALSE</literal> value. Note that if the evaluation. Specifying <literal>ERROR</literal> will cause an error to
<replaceable>path_expression</replaceable> is <literal>strict</literal> be thrown with the appropriate message. Other options include
and <literal>ON ERROR</literal> behavior is <literal>ERROR</literal>, returning <type>boolean</type> values <literal>FALSE</literal> or
an error is generated if it yields no items. <literal>TRUE</literal> or the value <literal>UNKNOWN</literal> which
is actually an SQL NULL. The default when no <literal>ON ERROR</literal>
clause is specified is to return the <type>boolean</type> value
<literal>FALSE</literal>.
</para> </para>
</listitem>
</itemizedlist>
<para> <para>
Examples: Examples:
</para> </para>
<para> <para>
<literal>select json_exists(jsonb '{"key1": [1,2,3]}', 'strict $.key1[*] ? (@ > 2)')</literal> <literal>JSON_EXISTS(jsonb '{"key1": [1,2,3]}', 'strict $.key1[*] ? (@ > $x)' PASSING 2 AS x)</literal>
<returnvalue>t</returnvalue> <returnvalue>t</returnvalue>
</para> </para>
<para> <para>
<literal>select json_exists(jsonb '{"a": [1,2,3]}', 'lax $.a[5]' ERROR ON ERROR)</literal> <literal>JSON_EXISTS(jsonb '{"a": [1,2,3]}', 'lax $.a[5]' ERROR ON ERROR)</literal>
<returnvalue>f</returnvalue> <returnvalue>f</returnvalue>
</para> </para>
<para> <para>
<literal>select json_exists(jsonb '{"a": [1,2,3]}', 'strict $.a[5]' ERROR ON ERROR)</literal> <literal>JSON_EXISTS(jsonb '{"a": [1,2,3]}', 'strict $.a[5]' ERROR ON ERROR)</literal>
<returnvalue></returnvalue> <returnvalue></returnvalue>
<programlisting> <programlisting>
ERROR: jsonpath array subscript is out of bounds ERROR: jsonpath array subscript is out of bounds
@ -18731,72 +18750,96 @@ ERROR: jsonpath array subscript is out of bounds
<row> <row>
<entry role="func_table_entry"><para role="func_signature"> <entry role="func_table_entry"><para role="func_signature">
<indexterm><primary>json_query</primary></indexterm> <indexterm><primary>json_query</primary></indexterm>
<function>json_query</function> ( <synopsis>
<replaceable>context_item</replaceable>, <replaceable>path_expression</replaceable> <optional> <literal>PASSING</literal> { <replaceable>value</replaceable> <literal>AS</literal> <replaceable>varname</replaceable> } <optional>, ...</optional></optional> <function>JSON_QUERY</function> (
<optional> <literal>RETURNING</literal> <replaceable>data_type</replaceable> <optional> <literal>FORMAT JSON</literal> <optional> <literal>ENCODING UTF8</literal> </optional> </optional> </optional> <replaceable>context_item</replaceable>, <replaceable>path_expression</replaceable>
<optional> { <literal>WITHOUT</literal> | <literal>WITH</literal> { <literal>CONDITIONAL</literal> | <optional><literal>UNCONDITIONAL</literal></optional> } } <optional> <literal>ARRAY</literal> </optional> <literal>WRAPPER</literal> </optional> <optional> <literal>PASSING</literal> { <replaceable>value</replaceable> <literal>AS</literal> <replaceable>varname</replaceable> } <optional>, ...</optional></optional>
<optional> { <literal>KEEP</literal> | <literal>OMIT</literal> } <literal>QUOTES</literal> <optional> <literal>ON SCALAR STRING</literal> </optional> </optional> <optional> <literal>RETURNING</literal> <replaceable>data_type</replaceable> <optional> <literal>FORMAT JSON</literal> <optional> <literal>ENCODING UTF8</literal> </optional> </optional> </optional>
<optional> { <literal>ERROR</literal> | <literal>NULL</literal> | <literal>EMPTY</literal> { <optional> <literal>ARRAY</literal> </optional> | <literal>OBJECT</literal> } | <literal>DEFAULT</literal> <replaceable>expression</replaceable> } <literal>ON EMPTY</literal> </optional> <optional> { <literal>WITHOUT</literal> | <literal>WITH</literal> { <literal>CONDITIONAL</literal> | <optional><literal>UNCONDITIONAL</literal></optional> } } <optional> <literal>ARRAY</literal> </optional> <literal>WRAPPER</literal> </optional>
<optional> { <literal>ERROR</literal> | <literal>NULL</literal> | <literal>EMPTY</literal> { <optional> <literal>ARRAY</literal> </optional> | <literal>OBJECT</literal> } | <literal>DEFAULT</literal> <replaceable>expression</replaceable> } <literal>ON ERROR</literal> </optional>) <optional> { <literal>KEEP</literal> | <literal>OMIT</literal> } <literal>QUOTES</literal> <optional> <literal>ON SCALAR STRING</literal> </optional> </optional>
<optional> { <literal>ERROR</literal> | <literal>NULL</literal> | <literal>EMPTY</literal> { <optional> <literal>ARRAY</literal> </optional> | <literal>OBJECT</literal> } | <literal>DEFAULT</literal> <replaceable>expression</replaceable> } <literal>ON EMPTY</literal> </optional>
<optional> { <literal>ERROR</literal> | <literal>NULL</literal> | <literal>EMPTY</literal> { <optional> <literal>ARRAY</literal> </optional> | <literal>OBJECT</literal> } | <literal>DEFAULT</literal> <replaceable>expression</replaceable> } <literal>ON ERROR</literal> </optional>) <returnvalue>jsonb</returnvalue>
</synopsis>
</para> </para>
<itemizedlist>
<listitem>
<para> <para>
Returns the result of applying the SQL/JSON Returns the result of applying the SQL/JSON
<replaceable>path_expression</replaceable> to the <replaceable>path_expression</replaceable> to the
<replaceable>context_item</replaceable> using the <replaceable>context_item</replaceable>.
<literal>PASSING</literal> <replaceable>value</replaceable>s.
</para> </para>
</listitem>
<listitem>
<para> <para>
If the path expression returns multiple SQL/JSON items, it might be By default, the result is returned as a value of type <type>jsonb</type>,
necessary to wrap the result using the <literal>WITH WRAPPER</literal> though the <literal>RETURNING</literal> clause can be used to return
clause to make it a valid JSON string. If the wrapper is as some other type to which it can be successfully coerced.
<literal>UNCONDITIONAL</literal>, an array wrapper will always be
applied, even if the returned value is already a single JSON object
or an array. If it is <literal>CONDITIONAL</literal>, it will not be
applied to a single JSON object or an array.
<literal>UNCONDITIONAL</literal> is the default.
</para> </para>
</listitem>
<listitem>
<para>
If the path expression may return multiple values, it might be necessary
to wrap those values using the <literal>WITH WRAPPER</literal> clause to
make it a valid JSON string, because the default behavior is to not wrap
them, as if <literal>WITHOUT WRAPPER</literal> were specified. The
<literal>WITH WRAPPER</literal> clause is by default taken to mean
<literal>WITH UNCONDITIONAL WRAPPER</literal>, which means that even a
single result value will be wrapped. To apply the wrapper only when
multiple values are present, specify <literal>WITH CONDITIONAL WRAPPER</literal>.
Getting multiple values in result will be treated as an error if
<literal>WITHOUT WRAPPER</literal> is specified.
</para>
</listitem>
<listitem>
<para> <para>
If the result is a scalar string, by default, the returned value will If the result is a scalar string, by default, the returned value will
be surrounded by quotes, making it a valid JSON value. It can be made be surrounded by quotes, making it a valid JSON value. It can be made
explicit by specifying <literal>KEEP QUOTES</literal>. Conversely, explicit by specifying <literal>KEEP QUOTES</literal>. Conversely,
quotes can be omitted by specifying <literal>OMIT QUOTES</literal>. quotes can be omitted by specifying <literal>OMIT QUOTES</literal>.
Note that <literal>OMIT QUOTES</literal> cannot be specified when To ensure that the result is a valid JSON value, <literal>OMIT QUOTES</literal>
<literal>WITH WRAPPER</literal> is also specified. cannot be specified when <literal>WITH WRAPPER</literal> is also
</para> specified.
<para>
The <literal>RETURNING</literal> clause can be used to specify the
<replaceable>data_type</replaceable> of the result value. By default,
the returned value will be of type <type>jsonb</type>.
</para> </para>
</listitem>
<listitem>
<para> <para>
The <literal>ON EMPTY</literal> clause specifies the behavior if The <literal>ON EMPTY</literal> clause specifies the behavior if
evaluating <replaceable>path_expression</replaceable> yields no value evaluating <replaceable>path_expression</replaceable> yields an empty
at all. The default when <literal>ON EMPTY</literal> is not specified set. The <literal>ON ERROR</literal> clause specifies the behavior
is to return a null value. if an error occurs when evaluating <replaceable>path_expression</replaceable>,
when coercing the result value to the <literal>RETURNING</literal> type,
or when evaluating the <literal>ON EMPTY</literal> expression if the
<replaceable>path_expression</replaceable> evaluation returns an empty
set.
</para> </para>
</listitem>
<listitem>
<para> <para>
The <literal>ON ERROR</literal> clause specifies the For both <literal>ON EMPTY</literal> and <literal>ON ERROR</literal>,
behavior if an error occurs when evaluating specifying <literal>ERROR</literal> will cause an error to be thrown with
<replaceable>path_expression</replaceable>, including the operation to the appropriate message. Other options include returning an SQL NULL, an
coerce the result value to the output type, or during the execution of empty array (<literal>EMPTY <optional>ARRAY</optional></literal>),
<literal>ON EMPTY</literal> behavior (that is caused by empty result an empty object (<literal>EMPTY OBJECT</literal>), or a user-specified
of <replaceable>path_expression</replaceable> evaluation). The default expression (<literal>DEFAULT</literal> <replaceable>expression</replaceable>)
when <literal>ON ERROR</literal> is not specified is to return a null that can be coerced to jsonb or the type specified in <literal>RETURNING</literal>.
value. The default when <literal>ON EMPTY</literal> or <literal>ON ERROR</literal>
is not specified is to return an SQL NULL value.
</para> </para>
</listitem>
</itemizedlist>
<para> <para>
Examples: Examples:
</para> </para>
<para> <para>
<literal>select json_query(jsonb '[1,[2,3],null]', 'lax $[*][1]' WITH CONDITIONAL WRAPPER)</literal> <literal>JSON_QUERY(jsonb '[1,[2,3],null]', 'lax $[*][$off]' PASSING 1 AS off WITH CONDITIONAL WRAPPER)</literal>
<returnvalue>[3]</returnvalue> <returnvalue>3</returnvalue>
</para> </para>
<para> <para>
<literal>select json_query(jsonb '{"a": "[1, 2]"}', 'lax $.a' OMIT QUOTES);</literal> <literal>JSON_QUERY(jsonb '{"a": "[1, 2]"}', 'lax $.a' OMIT QUOTES)</literal>
<returnvalue>[1, 2]</returnvalue> <returnvalue>[1, 2]</returnvalue>
</para> </para>
<para> <para>
<literal>select json_query(jsonb '{"a": "[1, 2]"}', 'lax $.a' RETURNING int[] OMIT QUOTES ERROR ON ERROR);</literal> <literal>JSON_QUERY(jsonb '{"a": "[1, 2]"}', 'lax $.a' RETURNING int[] OMIT QUOTES ERROR ON ERROR)</literal>
<returnvalue></returnvalue> <returnvalue></returnvalue>
<programlisting> <programlisting>
ERROR: malformed array literal: "[1, 2]" ERROR: malformed array literal: "[1, 2]"
@ -18808,55 +18851,76 @@ DETAIL: Missing "]" after array dimensions.
<row> <row>
<entry role="func_table_entry"><para role="func_signature"> <entry role="func_table_entry"><para role="func_signature">
<indexterm><primary>json_value</primary></indexterm> <indexterm><primary>json_value</primary></indexterm>
<function>json_value</function> ( <synopsis>
<replaceable>context_item</replaceable>, <replaceable>path_expression</replaceable> <function>JSON_VALUE</function> (
<optional> <literal>PASSING</literal> { <replaceable>value</replaceable> <literal>AS</literal> <replaceable>varname</replaceable> } <optional>, ...</optional></optional> <replaceable>context_item</replaceable>, <replaceable>path_expression</replaceable>
<optional> <literal>RETURNING</literal> <replaceable>data_type</replaceable> </optional> <optional> <literal>PASSING</literal> { <replaceable>value</replaceable> <literal>AS</literal> <replaceable>varname</replaceable> } <optional>, ...</optional></optional>
<optional> { <literal>ERROR</literal> | <literal>NULL</literal> | <literal>DEFAULT</literal> <replaceable>expression</replaceable> } <literal>ON EMPTY</literal> </optional> <optional> <literal>RETURNING</literal> <replaceable>data_type</replaceable> </optional>
<optional> { <literal>ERROR</literal> | <literal>NULL</literal> | <literal>DEFAULT</literal> <replaceable>expression</replaceable> } <literal>ON ERROR</literal> </optional>) <optional> { <literal>ERROR</literal> | <literal>NULL</literal> | <literal>DEFAULT</literal> <replaceable>expression</replaceable> } <literal>ON EMPTY</literal> </optional>
<optional> { <literal>ERROR</literal> | <literal>NULL</literal> | <literal>DEFAULT</literal> <replaceable>expression</replaceable> } <literal>ON ERROR</literal> </optional>) <returnvalue>text</returnvalue>
</synopsis>
</para> </para>
<itemizedlist>
<listitem>
<para> <para>
Returns the result of applying the SQL/JSON Returns the result of applying the SQL/JSON
<replaceable>path_expression</replaceable> to the <replaceable>path_expression</replaceable> to the
<replaceable>context_item</replaceable> using the <replaceable>context_item</replaceable>.
<literal>PASSING</literal> <replaceable>value</replaceable>s.
</para> </para>
</listitem>
<listitem>
<para> <para>
The extracted value must be a single <acronym>SQL/JSON</acronym> Only use <function>JSON_VALUE()</function> if the extracted value is
scalar item; an error is thrown if that's not the case. If you expect expected to be a single <acronym>SQL/JSON</acronym> scalar item;
that extracted value might be an object or an array, use the getting multiple values will be treated as an error. If you expect that
<function>json_query</function> function instead. extracted value might be an object or an array, use the
<function>JSON_QUERY</function> function instead.
</para> </para>
</listitem>
<listitem>
<para> <para>
The <literal>RETURNING</literal> clause can be used to specify the By default, the result, which must be a single scalar value, is
<replaceable>data_type</replaceable> of the result value. By default, returned as a value of type <type>text</type>, though the
the returned value will be of type <type>text</type>. <literal>RETURNING</literal> clause can be used to return as some
other type to which it can be successfully coerced.
</para> </para>
</listitem>
<listitem>
<para> <para>
The <literal>ON ERROR</literal> and <literal>ON EMPTY</literal> The <literal>ON ERROR</literal> and <literal>ON EMPTY</literal>
clauses have similar semantics as mentioned in the description of clauses have similar semantics as mentioned in the description of
<function>json_query</function>. <function>JSON_QUERY</function>, except the set of values returned in
lieu of throwing an error is different.
</para> </para>
</listitem>
<listitem>
<para> <para>
Note that scalar strings returned by <function>json_value</function> Note that scalar strings returned by <function>JSON_VALUE</function>
always have their quotes removed, equivalent to specifying always have their quotes removed, equivalent to specifying
<literal>OMIT QUOTES</literal> in <function>json_query</function>. <literal>OMIT QUOTES</literal> in <function>JSON_QUERY</function>.
</para> </para>
</listitem>
</itemizedlist>
<para> <para>
Examples: Examples:
</para> </para>
<para> <para>
<literal>select json_value(jsonb '"123.45"', '$' RETURNING float)</literal> <literal>JSON_VALUE(jsonb '"123.45"', '$' RETURNING float)</literal>
<returnvalue>123.45</returnvalue> <returnvalue>123.45</returnvalue>
</para> </para>
<para> <para>
<literal>select json_value(jsonb '"03:04 2015-02-01"', '$.datetime("HH24:MI&nbsp;YYYY-MM-DD")' RETURNING date)</literal> <literal>JSON_VALUE(jsonb '"03:04 2015-02-01"', '$.datetime("HH24:MI&nbsp;YYYY-MM-DD")' RETURNING date)</literal>
<returnvalue>2015-02-01</returnvalue> <returnvalue>2015-02-01</returnvalue>
</para> </para>
<para> <para>
<literal>select json_value(jsonb '[1,2]', 'strict $[*]' DEFAULT 9 ON ERROR)</literal> <literal>JSON_VALUE(jsonb '[1,2]', 'strict $[$off]' PASSING 1 as off)</literal>
<returnvalue>2</returnvalue>
</para>
<para>
<literal>JSON_VALUE(jsonb '[1,2]', 'strict $[*]' DEFAULT 9 ON ERROR)</literal>
<returnvalue>9</returnvalue> <returnvalue>9</returnvalue>
</para></entry> </para>
</entry>
</row> </row>
</tbody> </tbody>
</tgroup> </tgroup>
@ -18871,6 +18935,14 @@ DETAIL: Missing "]" after array dimensions.
clause. clause.
</para> </para>
</note> </note>
<note>
<para>
<function>JSON_VALUE()</function> returns an SQL NULL if
<replaceable>path_expression</replaceable> returns a JSON
<literal>null</literal>, whereas <function>JSON_QUERY()</function> returns
the JSON <literal>null</literal> as is.
</para>
</note>
</sect2> </sect2>
<sect2 id="functions-sqljson-table"> <sect2 id="functions-sqljson-table">
@ -18969,14 +19041,15 @@ where <replaceable class="parameter">json_table_column</replaceable> is:
</term> </term>
<listitem> <listitem>
<para> <para>
The input data to query (<replaceable>context_item</replaceable>), The <replaceable>context_item</replaceable> specifies the input document
the JSON path expression defining the query (<replaceable>path_expression</replaceable>) to query, the <replaceable>path_expression</replaceable> is an SQL/JSON
with an optional name (<replaceable>json_path_name</replaceable>), and an path expression defining the query, and <replaceable>json_path_name</replaceable>
optional <literal>PASSING</literal> clause, which can provide data values is an optional name for the <replaceable>path_expression</replaceable>.
to the <replaceable>path_expression</replaceable>. The result of the input The optional <literal>PASSING</literal> clause provides data values for
data evaluation using the aforementioned elements is called the the variables mentioned in the <replaceable>path_expression</replaceable>.
<firstterm>row pattern</firstterm>, which is used as the source for row The result of the input data evaluation using the aforementioned elements
values in the constructed view. is called the <firstterm>row pattern</firstterm>, which is used as the
source for row values in the constructed view.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -21800,6 +21873,54 @@ SELECT NULLIF(value, '(none)') ...
<entry>No</entry> <entry>No</entry>
</row> </row>
<row>
<entry role="func_table_entry"><para role="func_signature">
<indexterm>
<primary>json_agg_strict</primary>
</indexterm>
<function>json_agg_strict</function> ( <type>anyelement</type> )
<returnvalue>json</returnvalue>
</para>
<para role="func_signature">
<indexterm>
<primary>jsonb_agg_strict</primary>
</indexterm>
<function>jsonb_agg_strict</function> ( <type>anyelement</type> )
<returnvalue>jsonb</returnvalue>
</para>
<para>
Collects all the input values, skipping nulls, into a JSON array.
Values are converted to JSON as per <function>to_json</function>
or <function>to_jsonb</function>.
</para></entry>
<entry>No</entry>
</row>
<row>
<entry role="func_table_entry"><para role="func_signature">
<indexterm><primary>json_arrayagg</primary></indexterm>
<function>json_arrayagg</function> (
<optional> <replaceable>value_expression</replaceable> </optional>
<optional> <literal>ORDER BY</literal> <replaceable>sort_expression</replaceable> </optional>
<optional> { <literal>NULL</literal> | <literal>ABSENT</literal> } <literal>ON NULL</literal> </optional>
<optional> <literal>RETURNING</literal> <replaceable>data_type</replaceable> <optional> <literal>FORMAT JSON</literal> <optional> <literal>ENCODING UTF8</literal> </optional> </optional> </optional>)
</para>
<para>
Behaves in the same way as <function>json_array</function>
but as an aggregate function so it only takes one
<replaceable>value_expression</replaceable> parameter.
If <literal>ABSENT ON NULL</literal> is specified, any NULL
values are omitted.
If <literal>ORDER BY</literal> is specified, the elements will
appear in the array in that order rather than in the input order.
</para>
<para>
<literal>SELECT json_arrayagg(v) FROM (VALUES(2),(1)) t(v)</literal>
<returnvalue>[2, 1]</returnvalue>
</para></entry>
<entry>No</entry>
</row>
<row> <row>
<entry role="func_table_entry"><para role="func_signature"> <entry role="func_table_entry"><para role="func_signature">
<indexterm><primary>json_objectagg</primary></indexterm> <indexterm><primary>json_objectagg</primary></indexterm>
@ -21910,31 +22031,6 @@ SELECT NULLIF(value, '(none)') ...
<entry>No</entry> <entry>No</entry>
</row> </row>
<row>
<entry role="func_table_entry"><para role="func_signature">
<indexterm><primary>json_arrayagg</primary></indexterm>
<function>json_arrayagg</function> (
<optional> <replaceable>value_expression</replaceable> </optional>
<optional> <literal>ORDER BY</literal> <replaceable>sort_expression</replaceable> </optional>
<optional> { <literal>NULL</literal> | <literal>ABSENT</literal> } <literal>ON NULL</literal> </optional>
<optional> <literal>RETURNING</literal> <replaceable>data_type</replaceable> <optional> <literal>FORMAT JSON</literal> <optional> <literal>ENCODING UTF8</literal> </optional> </optional> </optional>)
</para>
<para>
Behaves in the same way as <function>json_array</function>
but as an aggregate function so it only takes one
<replaceable>value_expression</replaceable> parameter.
If <literal>ABSENT ON NULL</literal> is specified, any NULL
values are omitted.
If <literal>ORDER BY</literal> is specified, the elements will
appear in the array in that order rather than in the input order.
</para>
<para>
<literal>SELECT json_arrayagg(v) FROM (VALUES(2),(1)) t(v)</literal>
<returnvalue>[2, 1]</returnvalue>
</para></entry>
<entry>No</entry>
</row>
<row> <row>
<entry role="func_table_entry"><para role="func_signature"> <entry role="func_table_entry"><para role="func_signature">
<indexterm> <indexterm>
@ -22043,29 +22139,6 @@ SELECT NULLIF(value, '(none)') ...
<entry>No</entry> <entry>No</entry>
</row> </row>
<row>
<entry role="func_table_entry"><para role="func_signature">
<indexterm>
<primary>json_agg_strict</primary>
</indexterm>
<function>json_agg_strict</function> ( <type>anyelement</type> )
<returnvalue>json</returnvalue>
</para>
<para role="func_signature">
<indexterm>
<primary>jsonb_agg_strict</primary>
</indexterm>
<function>jsonb_agg_strict</function> ( <type>anyelement</type> )
<returnvalue>jsonb</returnvalue>
</para>
<para>
Collects all the input values, skipping nulls, into a JSON array.
Values are converted to JSON as per <function>to_json</function>
or <function>to_jsonb</function>.
</para></entry>
<entry>No</entry>
</row>
<row> <row>
<entry role="func_table_entry"><para role="func_signature"> <entry role="func_table_entry"><para role="func_signature">
<indexterm> <indexterm>
@ -25147,6 +25220,10 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute');
are immediately available without doing <command>SET ROLE</command>, are immediately available without doing <command>SET ROLE</command>,
while <literal>SET</literal> denotes whether it is possible to change while <literal>SET</literal> denotes whether it is possible to change
to the role using the <literal>SET ROLE</literal> command. to the role using the <literal>SET ROLE</literal> command.
<literal>WITH ADMIN OPTION</literal> or <literal>WITH GRANT
OPTION</literal> can be added to any of these privilege types to
test whether the <literal>ADMIN</literal> privilege is held (all
six spellings test the same thing).
This function does not allow the special case of This function does not allow the special case of
setting <parameter>user</parameter> to <literal>public</literal>, setting <parameter>user</parameter> to <literal>public</literal>,
because the PUBLIC pseudo-role can never be a member of real roles. because the PUBLIC pseudo-role can never be a member of real roles.
@ -27890,6 +27967,17 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id'));
not running, it will be equal to <literal>summarized_lsn</literal>. not running, it will be equal to <literal>summarized_lsn</literal>.
<literal>summarizer_pid</literal> is the PID of the WAL summarizer <literal>summarizer_pid</literal> is the PID of the WAL summarizer
process, if it is running, and otherwise NULL. process, if it is running, and otherwise NULL.
</para>
<para>
As a special exception, the WAL summarizer will refuse to generate
WAL summary files if run on WAL generated under
<literal>wal_level=minimal</literal>, since such summaries would be
unsafe to use as the basis for an incremental backup. In this case,
the fields above will continue to advance as if summaries were being
generated, but nothing will be written to disk. Once the summarizer
reaches WAL generated while <literal>wal_level</literal> was set
to <literal>replica</literal> or higher, it will resume writing
summaries to disk.
</para></entry> </para></entry>
</row> </row>
</tbody> </tbody>
@ -29057,7 +29145,7 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset
adding the rows produced when decoding each new transaction commit. adding the rows produced when decoding each new transaction commit.
If the specified slot is a logical failover slot then the function will If the specified slot is a logical failover slot then the function will
not return until all physical slots specified in not return until all physical slots specified in
<link linkend="guc-standby-slot-names"><varname>standby_slot_names</varname></link> <link linkend="guc-synchronized-standby-slots"><varname>synchronized_standby_slots</varname></link>
have confirmed WAL receipt. have confirmed WAL receipt.
</para></entry> </para></entry>
</row> </row>
@ -29137,7 +29225,7 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset
slot may return to an earlier position. If the specified slot is a slot may return to an earlier position. If the specified slot is a
logical failover slot then the function will not return until all logical failover slot then the function will not return until all
physical slots specified in physical slots specified in
<link linkend="guc-standby-slot-names"><varname>standby_slot_names</varname></link> <link linkend="guc-synchronized-standby-slots"><varname>synchronized_standby_slots</varname></link>
have confirmed WAL receipt. have confirmed WAL receipt.
</para></entry> </para></entry>
</row> </row>
@ -31022,8 +31110,12 @@ CREATE EVENT TRIGGER test_event_trigger_for_drops
<returnvalue>integer</returnvalue> <returnvalue>integer</returnvalue>
</para> </para>
<para> <para>
Returns a code explaining the reason(s) for rewriting. The exact Returns a code explaining the reason(s) for rewriting. The value is
meaning of the codes is release dependent. a bitmap built from the following values: <literal>1</literal>
(the table has changed its persistence), <literal>2</literal>
(default value of a column has changed), <literal>4</literal>
(a column has a new data type) and <literal>8</literal>
(the table access method has changed).
</para></entry> </para></entry>
</row> </row>
</tbody> </tbody>

View File

@ -941,12 +941,10 @@ build-postgresql:
<para> <para>
<command>llvm-config</command><indexterm><primary>llvm-config</primary></indexterm> <command>llvm-config</command><indexterm><primary>llvm-config</primary></indexterm>
will be used to find the required compilation options. will be used to find the required compilation options.
<command>llvm-config</command>, and then <command>llvm-config</command> will be searched for in your
<command>llvm-config-$major-$minor</command> for all supported <envar>PATH</envar>. If that would not yield the desired program,
versions, will be searched for in your <envar>PATH</envar>. If use <envar>LLVM_CONFIG</envar> to specify a path to the correct
that would not yield the desired program, <command>llvm-config</command>. For example
use <envar>LLVM_CONFIG</envar> to specify a path to the
correct <command>llvm-config</command>. For example
<programlisting> <programlisting>
./configure ... --with-llvm LLVM_CONFIG='/path/to/llvm/bin/llvm-config' ./configure ... --with-llvm LLVM_CONFIG='/path/to/llvm/bin/llvm-config'
</programlisting> </programlisting>
@ -3781,11 +3779,11 @@ make: *** [postgres] Error 1
</sect3> </sect3>
</sect2> </sect2>
<sect2 id="installation-notes-visual"> <sect2 id="installation-notes-visual-studio">
<title>Visual</title> <title>Visual Studio</title>
<indexterm zone="installation-notes-visual"> <indexterm zone="installation-notes-visual-studio">
<primary>Visual</primary> <primary>Visual Studio</primary>
<secondary>installation on</secondary> <secondary>installation on</secondary>
</indexterm> </indexterm>
@ -3799,8 +3797,8 @@ make: *** [postgres] Error 1
</para> </para>
<para> <para>
PostgreSQL for Windows with Visual can be built using meson, as described PostgreSQL for Windows with Visual Studio can be built using Meson, as
in <xref linkend="install-meson"/>. described in <xref linkend="install-meson"/>.
The native Windows port requires a 32 or 64-bit version of Windows The native Windows port requires a 32 or 64-bit version of Windows
10 or later. 10 or later.
</para> </para>
@ -3870,14 +3868,12 @@ make: *** [postgres] Error 1
<variablelist> <variablelist>
<varlistentry> <varlistentry>
<term><productname>ActiveState Perl</productname></term> <term><productname>Strawberry Perl</productname></term>
<listitem><para> <listitem><para>
ActiveState Perl is required to run the build generation scripts. MinGW Strawberry Perl is required to run the build generation scripts. MinGW
or Cygwin Perl will not work. It must also be present in the PATH. or Cygwin Perl will not work. It must also be present in the PATH.
Binaries can be downloaded from Binaries can be downloaded from
<ulink url="https://www.activestate.com"></ulink> <ulink url="https://strawberryperl.com"></ulink>.
(Note: version 5.14 or later is required,
the free Standard Distribution is sufficient).
</para></listitem> </para></listitem>
</varlistentry> </varlistentry>
@ -3929,10 +3925,11 @@ make: *** [postgres] Error 1
<variablelist> <variablelist>
<varlistentry> <varlistentry>
<term><productname>ActiveState Tcl</productname></term> <term><productname>Magicsplat Tcl</productname></term>
<listitem><para> <listitem><para>
Required for building <application>PL/Tcl</application> (Note: version Required for building <application>PL/Tcl</application>.
8.4 is required, the free Standard Distribution is sufficient). Binaries can be downloaded from
<ulink url="https://www.magicsplat.com/tcl-installer/index.html"></ulink>.
</para></listitem> </para></listitem>
</varlistentry> </varlistentry>

View File

@ -135,4 +135,15 @@
created tuples are internally marked as null in the tuple's null bitmap, the created tuples are internally marked as null in the tuple's null bitmap, the
null bitmap also occupies space. null bitmap also occupies space.
</para> </para>
<para>
Each table can store a theoretical maximum of 2^32 out-of-line values; see
<xref linkend="storage-toast" /> for a detailed discussion of out-of-line
storage. This limit arises from the use of a 32-bit OID to identify each
such value. The practical limit is significantly less than the theoretical
limit, because as the OID space fills up, finding an OID that is still free
can become expensive, in turn slowing down INSERT/UPDATE statements.
Typically, this is only an issue for tables containing many terabytes
of data; partitioning is a possible workaround.
</para>
</appendix> </appendix>

View File

@ -701,10 +701,7 @@ ALTER SUBSCRIPTION
<link linkend="sql-createsubscription-params-with-failover"><literal>failover</literal></link> <link linkend="sql-createsubscription-params-with-failover"><literal>failover</literal></link>
parameter ensures a seamless transition of those subscriptions after the parameter ensures a seamless transition of those subscriptions after the
standby is promoted. They can continue subscribing to publications on the standby is promoted. They can continue subscribing to publications on the
new primary server without losing data. Note that in the case of new primary server.
asynchronous replication, there remains a risk of data loss for transactions
committed on the former primary server but have yet to be replicated to the new
primary server.
</para> </para>
<para> <para>
@ -713,7 +710,7 @@ ALTER SUBSCRIPTION
server before the failover happens. To ensure a successful failover, the server before the failover happens. To ensure a successful failover, the
standby server must be ahead of the subscriber. This can be achieved by standby server must be ahead of the subscriber. This can be achieved by
configuring configuring
<link linkend="guc-standby-slot-names"><varname>standby_slot_names</varname></link>. <link linkend="guc-synchronized-standby-slots"><varname>synchronized_standby_slots</varname></link>.
</para> </para>
<para> <para>
@ -725,32 +722,45 @@ ALTER SUBSCRIPTION
<procedure> <procedure>
<step performance="required"> <step performance="required">
<para> <para>
On the subscriber node, use the following SQL to identify which slots On the subscriber node, use the following SQL to identify which replication
should be synced to the standby that we plan to promote. This query will slots should be synced to the standby that we plan to promote. This query
return the relevant replication slots, including the main slots and table will return the relevant replication slots associated with the
synchronization slots associated with the failover-enabled subscriptions. failover-enabled subscriptions.
Note that the table sync slot should be synced to the standby server only <programlisting>
if the table copy is finished (See <xref linkend="catalog-pg-subscription-rel"/>). test_sub=# SELECT
array_agg(quote_literal(s.subslotname)) AS slots
FROM pg_subscription s
WHERE s.subfailover AND
s.subslotname IS NOT NULL;
slots
-------
{'sub1','sub2','sub3'}
(1 row)
</programlisting></para>
</step>
<step performance="required">
<para>
On the subscriber node, use the following SQL to identify which table
synchronization slots should be synced to the standby that we plan to promote.
This query needs to be run on each database that includes the failover-enabled
subscription(s). Note that the table sync slot should be synced to the standby
server only if the table copy is finished
(See <xref linkend="catalog-pg-subscription-rel"/>).
We don't need to ensure that the table sync slots are synced in other scenarios We don't need to ensure that the table sync slots are synced in other scenarios
as they will either be dropped or re-created on the new primary server in those as they will either be dropped or re-created on the new primary server in those
cases. cases.
<programlisting> <programlisting>
test_sub=# SELECT test_sub=# SELECT
array_agg(slot_name) AS slots array_agg(quote_literal(slot_name)) AS slots
FROM FROM
(( (
SELECT r.srsubid AS subid, CONCAT('pg_', srsubid, '_sync_', srrelid, '_', ctl.system_identifier) AS slot_name SELECT CONCAT('pg_', srsubid, '_sync_', srrelid, '_', ctl.system_identifier) AS slot_name
FROM pg_control_system() ctl, pg_subscription_rel r, pg_subscription s FROM pg_control_system() ctl, pg_subscription_rel r, pg_subscription s
WHERE r.srsubstate = 'f' AND s.oid = r.srsubid AND s.subfailover WHERE r.srsubstate = 'f' AND s.oid = r.srsubid AND s.subfailover
) UNION ( );
SELECT s.oid AS subid, s.subslotname as slot_name
FROM pg_subscription s
WHERE s.subfailover
))
WHERE slot_name IS NOT NULL;
slots slots
------- -------
{sub1,sub2,sub3} {'pg_16394_sync_16385_7394666715149055164'}
(1 row) (1 row)
</programlisting></para> </programlisting></para>
</step> </step>
@ -761,13 +771,15 @@ test_sub=# SELECT
<programlisting> <programlisting>
test_standby=# SELECT slot_name, (synced AND NOT temporary AND NOT conflicting) AS failover_ready test_standby=# SELECT slot_name, (synced AND NOT temporary AND NOT conflicting) AS failover_ready
FROM pg_replication_slots FROM pg_replication_slots
WHERE slot_name IN ('sub1','sub2','sub3'); WHERE slot_name IN
slot_name | failover_ready ('sub1','sub2','sub3', 'pg_16394_sync_16385_7394666715149055164');
-------------+---------------- slot_name | failover_ready
sub1 | t --------------------------------------------+----------------
sub2 | t sub1 | t
sub3 | t sub2 | t
(3 rows) sub3 | t
pg_16394_sync_16385_7394666715149055164 | t
(4 rows)
</programlisting></para> </programlisting></para>
</step> </step>
</procedure> </procedure>
@ -776,7 +788,7 @@ test_standby=# SELECT slot_name, (synced AND NOT temporary AND NOT conflicting)
If all the slots are present on the standby server and the result If all the slots are present on the standby server and the result
(<literal>failover_ready</literal>) of the above SQL query is true, then (<literal>failover_ready</literal>) of the above SQL query is true, then
existing subscriptions can continue subscribing to publications now on the existing subscriptions can continue subscribing to publications now on the
new primary server without losing data. new primary server.
</para> </para>
</sect1> </sect1>

View File

@ -385,16 +385,16 @@ postgres=# select * from pg_logical_slot_get_changes('regression_slot', NULL, NU
<literal>dbname</literal> in the <literal>dbname</literal> in the
<link linkend="guc-primary-conninfo"><varname>primary_conninfo</varname></link>. <link linkend="guc-primary-conninfo"><varname>primary_conninfo</varname></link>.
It's highly recommended that the said physical replication slot is named in It's highly recommended that the said physical replication slot is named in
<link linkend="guc-standby-slot-names"><varname>standby_slot_names</varname></link> <link linkend="guc-synchronized-standby-slots"><varname>synchronized_standby_slots</varname></link>
list on the primary, to prevent the subscriber from consuming changes list on the primary, to prevent the subscriber from consuming changes
faster than the hot standby. Even when correctly configured, some latency faster than the hot standby. Even when correctly configured, some latency
is expected when sending changes to logical subscribers due to the waiting is expected when sending changes to logical subscribers due to the waiting
on slots named in on slots named in
<link linkend="guc-standby-slot-names"><varname>standby_slot_names</varname></link>. <link linkend="guc-synchronized-standby-slots"><varname>synchronized_standby_slots</varname></link>.
When <varname>standby_slot_names</varname> is utilized, the When <varname>synchronized_standby_slots</varname> is utilized, the
primary server will not completely shut down until the corresponding primary server will not completely shut down until the corresponding
standbys, associated with the physical replication slots specified standbys, associated with the physical replication slots specified
in <varname>standby_slot_names</varname>, have confirmed in <varname>synchronized_standby_slots</varname>, have confirmed
receiving the WAL up to the latest flushed position on the primary server. receiving the WAL up to the latest flushed position on the primary server.
</para> </para>

View File

@ -180,12 +180,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser
<para> <para>
The parameter <xref linkend="guc-track-io-timing"/> enables monitoring The parameter <xref linkend="guc-track-io-timing"/> enables monitoring
of block read and write times. of block read, write, extend, and fsync times.
</para> </para>
<para> <para>
The parameter <xref linkend="guc-track-wal-io-timing"/> enables monitoring The parameter <xref linkend="guc-track-wal-io-timing"/> enables monitoring
of WAL write times. of WAL write and fsync times.
</para> </para>
<para> <para>
@ -2978,7 +2978,10 @@ description | Waiting for a newly initialized WAL file to reach durable storage
<structfield>num_timed</structfield> <type>bigint</type> <structfield>num_timed</structfield> <type>bigint</type>
</para> </para>
<para> <para>
Number of scheduled checkpoints that have been performed Number of scheduled checkpoints due to timeout.
Note that checkpoints may be skipped if the server has been idle
since the last one, and this value counts both completed and
skipped checkpoints
</para></entry> </para></entry>
</row> </row>

View File

@ -202,7 +202,7 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%';
</itemizedlist> </itemizedlist>
<para> <para>
Even when parallel query plan is generated for a particular query, there Even when a parallel query plan is generated for a particular query, there
are several circumstances under which it will be impossible to execute are several circumstances under which it will be impossible to execute
that plan in parallel at execution time. If this occurs, the leader that plan in parallel at execution time. If this occurs, the leader
will execute the portion of the plan below the <literal>Gather</literal> will execute the portion of the plan below the <literal>Gather</literal>
@ -510,12 +510,6 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%';
</para> </para>
</listitem> </listitem>
<listitem>
<para>
Plan nodes to which an <literal>InitPlan</literal> is attached.
</para>
</listitem>
<listitem> <listitem>
<para> <para>
Plan nodes that reference a correlated <literal>SubPlan</literal>. Plan nodes that reference a correlated <literal>SubPlan</literal>.

View File

@ -1093,6 +1093,19 @@ $$ LANGUAGE plperl;
be permitted to use this language. be permitted to use this language.
</para> </para>
<warning>
<para>
Trusted PL/Perl relies on the Perl <literal>Opcode</literal> module to
preserve security.
Perl
<ulink url="https://perldoc.perl.org/Opcode#WARNING">documents</ulink>
that the module is not effective for the trusted PL/Perl use case. If
your security needs are incompatible with the uncertainty in that warning,
consider executing <literal>REVOKE USAGE ON LANGUAGE plperl FROM
PUBLIC</literal>.
</para>
</warning>
<para> <para>
Here is an example of a function that will not work because file Here is an example of a function that will not work because file
system operations are not allowed for security reasons: system operations are not allowed for security reasons:

View File

@ -1295,7 +1295,7 @@ $$ LANGUAGE plpgsql;
On failure, this function might produce an error message such as On failure, this function might produce an error message such as
<programlisting> <programlisting>
ERROR: query returned no rows ERROR: query returned no rows
DETAIL: parameters: $1 = 'nosuchuser' DETAIL: parameters: username = 'nosuchuser'
CONTEXT: PL/pgSQL function get_userid(text) line 6 at SQL statement CONTEXT: PL/pgSQL function get_userid(text) line 6 at SQL statement
</programlisting> </programlisting>
</para> </para>
@ -3409,13 +3409,16 @@ FETCH <optional> <replaceable>direction</replaceable> { FROM | IN } </optional>
</synopsis> </synopsis>
<para> <para>
<command>FETCH</command> retrieves the next row from the <command>FETCH</command> retrieves the next row (in the indicated
direction) from the
cursor into a target, which might be a row variable, a record cursor into a target, which might be a row variable, a record
variable, or a comma-separated list of simple variables, just like variable, or a comma-separated list of simple variables, just like
<command>SELECT INTO</command>. If there is no next row, the <command>SELECT INTO</command>. If there is no suitable row, the
target is set to NULL(s). As with <command>SELECT target is set to NULL(s). As with <command>SELECT
INTO</command>, the special variable <literal>FOUND</literal> can INTO</command>, the special variable <literal>FOUND</literal> can
be checked to see whether a row was obtained or not. be checked to see whether a row was obtained or not. If no row is
obtained, the cursor is positioned after the last row or before the
first row, depending on the movement direction.
</para> </para>
<para> <para>
@ -3467,11 +3470,25 @@ MOVE <optional> <replaceable>direction</replaceable> { FROM | IN } </optional> <
<para> <para>
<command>MOVE</command> repositions a cursor without retrieving <command>MOVE</command> repositions a cursor without retrieving
any data. <command>MOVE</command> works exactly like the any data. <command>MOVE</command> works like the
<command>FETCH</command> command, except it only repositions the <command>FETCH</command> command, except it only repositions the
cursor and does not return the row moved to. As with <command>SELECT cursor and does not return the row moved to.
The <replaceable>direction</replaceable> clause can be any of the
variants allowed in the SQL <xref linkend="sql-fetch"/>
command, including those that can fetch more than one row;
the cursor is positioned to the last such row.
(However, the case in which the <replaceable>direction</replaceable>
clause is simply a <replaceable>count</replaceable> expression with
no key word is deprecated in <application>PL/pgSQL</application>.
That syntax is ambiguous with the case where
the <replaceable>direction</replaceable> clause is omitted
altogether, and hence it may fail if
the <replaceable>count</replaceable> is not a constant.)
As with <command>SELECT
INTO</command>, the special variable <literal>FOUND</literal> can INTO</command>, the special variable <literal>FOUND</literal> can
be checked to see whether there was a next row to move to. be checked to see whether there was a row to move to. If there is no
such row, the cursor is positioned after the last row or before the
first row, depending on the movement direction.
</para> </para>
<para> <para>
@ -3745,6 +3762,17 @@ CALL transaction_test1();
<command>SELECT</command> in between. <command>SELECT</command> in between.
</para> </para>
<para>
<application>PL/pgSQL</application> does not support savepoints
(<command>SAVEPOINT</command>/<command>ROLLBACK TO
SAVEPOINT</command>/<command>RELEASE SAVEPOINT</command> commands).
Typical usage patterns for savepoints can be replaced by blocks with
exception handlers (see <xref linkend="plpgsql-error-trapping"/>).
Under the hood, a block with exception handlers forms a
subtransaction, which means that transactions cannot be ended inside
such a block.
</para>
<para> <para>
Special considerations apply to cursor loops. Consider this example: Special considerations apply to cursor loops. Consider this example:
<programlisting> <programlisting>
@ -3770,7 +3798,10 @@ CALL transaction_test2();
evaluated at the first <command>COMMIT</command> or evaluated at the first <command>COMMIT</command> or
<command>ROLLBACK</command> rather than row by row. The cursor is still <command>ROLLBACK</command> rather than row by row. The cursor is still
removed automatically after the loop, so this is mostly invisible to the removed automatically after the loop, so this is mostly invisible to the
user. user. But one must keep in mind that any table or row locks taken by
the cursor's query will no longer be held after the
first <command>COMMIT</command> or
<command>ROLLBACK</command>.
</para> </para>
<para> <para>
@ -3778,10 +3809,6 @@ CALL transaction_test2();
that are not read-only (for example <command>UPDATE that are not read-only (for example <command>UPDATE
... RETURNING</command>). ... RETURNING</command>).
</para> </para>
<para>
A transaction cannot be ended inside a block with exception handlers.
</para>
</sect1> </sect1>
<sect1 id="plpgsql-errors-and-messages"> <sect1 id="plpgsql-errors-and-messages">

View File

@ -9,6 +9,7 @@
<!ENTITY % filelist SYSTEM "filelist.sgml"> <!ENTITY % filelist SYSTEM "filelist.sgml">
%filelist; %filelist;
<!ENTITY commit_baseurl "https://postgr.es/c/">
<!ENTITY reference SYSTEM "reference.sgml"> <!ENTITY reference SYSTEM "reference.sgml">
<!-- <!--

View File

@ -1506,10 +1506,10 @@ SELCT 1/0;<!-- this typo is intentional -->
<para> <para>
The frontend should also be prepared to handle an ErrorMessage The frontend should also be prepared to handle an ErrorMessage
response to SSLRequest from the server. This would only occur if response to SSLRequest from the server. The frontend should not display
the server predates the addition of <acronym>SSL</acronym> support this error message to the user/application, since the server has not been
to <productname>PostgreSQL</productname>. (Such servers are now very ancient, authenticated
and likely do not exist in the wild anymore.) (<ulink url="https://www.postgresql.org/support/security/CVE-2024-10977/">CVE-2024-10977</ulink>).
In this case the connection must In this case the connection must
be closed, but the frontend might choose to open a fresh connection be closed, but the frontend might choose to open a fresh connection
and proceed without requesting <acronym>SSL</acronym>. and proceed without requesting <acronym>SSL</acronym>.
@ -1619,12 +1619,13 @@ SELCT 1/0;<!-- this typo is intentional -->
<para> <para>
The frontend should also be prepared to handle an ErrorMessage The frontend should also be prepared to handle an ErrorMessage
response to GSSENCRequest from the server. This would only occur if response to GSSENCRequest from the server. The frontend should not display
the server predates the addition of <acronym>GSSAPI</acronym> encryption this error message to the user/application, since the server has not been
support to <productname>PostgreSQL</productname>. In this case the authenticated
connection must be closed, but the frontend might choose to open a fresh (<ulink url="https://www.postgresql.org/support/security/CVE-2024-10977/">CVE-2024-10977</ulink>).
connection and proceed without requesting <acronym>GSSAPI</acronym> In this case the connection must be closed, but the frontend might choose
encryption. to open a fresh connection and proceed without requesting
<acronym>GSSAPI</acronym> encryption.
</para> </para>
<para> <para>

View File

@ -41,6 +41,11 @@ ALTER DOMAIN <replaceable class="parameter">name</replaceable>
RENAME TO <replaceable class="parameter">new_name</replaceable> RENAME TO <replaceable class="parameter">new_name</replaceable>
ALTER DOMAIN <replaceable class="parameter">name</replaceable> ALTER DOMAIN <replaceable class="parameter">name</replaceable>
SET SCHEMA <replaceable class="parameter">new_schema</replaceable> SET SCHEMA <replaceable class="parameter">new_schema</replaceable>
<phrase>where <replaceable class="parameter">domain_constraint</replaceable> is:</phrase>
[ CONSTRAINT <replaceable class="parameter">constraint_name</replaceable> ]
{ NOT NULL | CHECK (<replaceable class="parameter">expression</replaceable>) }
</synopsis> </synopsis>
</refsynopsisdiv> </refsynopsisdiv>
@ -79,8 +84,7 @@ ALTER DOMAIN <replaceable class="parameter">name</replaceable>
<term><literal>ADD <replaceable class="parameter">domain_constraint</replaceable> [ NOT VALID ]</literal></term> <term><literal>ADD <replaceable class="parameter">domain_constraint</replaceable> [ NOT VALID ]</literal></term>
<listitem> <listitem>
<para> <para>
This form adds a new constraint to a domain using the same syntax as This form adds a new constraint to a domain.
<link linkend="sql-createdomain"><command>CREATE DOMAIN</command></link>.
When a new constraint is added to a domain, all columns using that When a new constraint is added to a domain, all columns using that
domain will be checked against the newly added constraint. These domain will be checked against the newly added constraint. These
checks can be suppressed by adding the new constraint using the checks can be suppressed by adding the new constraint using the

View File

@ -87,10 +87,11 @@ ALTER INDEX ALL IN TABLESPACE <replaceable class="parameter">name</replaceable>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><literal>ATTACH PARTITION</literal></term> <term><literal>ATTACH PARTITION <replaceable class="parameter">index_name</replaceable></literal></term>
<listitem> <listitem>
<para> <para>
Causes the named index to become attached to the altered index. Causes the named index (possibly schema-qualified) to become attached
to the altered index.
The named index must be on a partition of the table containing the The named index must be on a partition of the table containing the
index being altered, and have an equivalent definition. An attached index being altered, and have an equivalent definition. An attached
index cannot be dropped by itself, and will automatically be dropped index cannot be dropped by itself, and will automatically be dropped

View File

@ -71,8 +71,13 @@ ALTER SUBSCRIPTION <replaceable class="parameter">name</replaceable> RENAME TO <
with <literal>refresh</literal> option as <literal>true</literal> and with <literal>refresh</literal> option as <literal>true</literal> and
<command>ALTER SUBSCRIPTION ... SET (failover = true|false)</command> <command>ALTER SUBSCRIPTION ... SET (failover = true|false)</command>
cannot be executed inside a transaction block. cannot be executed inside a transaction block.
</para>
These commands also cannot be executed when the subscription has <para>
Commands <command>ALTER SUBSCRIPTION ... REFRESH PUBLICATION</command> and
<command>ALTER SUBSCRIPTION ... {SET|ADD|DROP} PUBLICATION ...</command>
with <literal>refresh</literal> option as <literal>true</literal> also cannot
be executed when the subscription has
<link linkend="sql-createsubscription-params-with-two-phase"><literal>two_phase</literal></link> <link linkend="sql-createsubscription-params-with-two-phase"><literal>two_phase</literal></link>
commit enabled, unless commit enabled, unless
<link linkend="sql-createsubscription-params-with-copy-data"><literal>copy_data</literal></link> <link linkend="sql-createsubscription-params-with-copy-data"><literal>copy_data</literal></link>

View File

@ -37,13 +37,6 @@ ALTER TABLE [ IF EXISTS ] <replaceable class="parameter">name</replaceable>
ATTACH PARTITION <replaceable class="parameter">partition_name</replaceable> { FOR VALUES <replaceable class="parameter">partition_bound_spec</replaceable> | DEFAULT } ATTACH PARTITION <replaceable class="parameter">partition_name</replaceable> { FOR VALUES <replaceable class="parameter">partition_bound_spec</replaceable> | DEFAULT }
ALTER TABLE [ IF EXISTS ] <replaceable class="parameter">name</replaceable> ALTER TABLE [ IF EXISTS ] <replaceable class="parameter">name</replaceable>
DETACH PARTITION <replaceable class="parameter">partition_name</replaceable> [ CONCURRENTLY | FINALIZE ] DETACH PARTITION <replaceable class="parameter">partition_name</replaceable> [ CONCURRENTLY | FINALIZE ]
ALTER TABLE [ IF EXISTS ] <replaceable class="parameter">name</replaceable>
SPLIT PARTITION <replaceable class="parameter">partition_name</replaceable> INTO
(PARTITION <replaceable class="parameter">partition_name1</replaceable> { FOR VALUES <replaceable class="parameter">partition_bound_spec</replaceable> | DEFAULT },
PARTITION <replaceable class="parameter">partition_name2</replaceable> { FOR VALUES <replaceable class="parameter">partition_bound_spec</replaceable> | DEFAULT } [, ...])
ALTER TABLE [ IF EXISTS ] <replaceable class="parameter">name</replaceable>
MERGE PARTITIONS (<replaceable class="parameter">partition_name1</replaceable>, <replaceable class="parameter">partition_name2</replaceable> [, ...])
INTO <replaceable class="parameter">partition_name</replaceable>
<phrase>where <replaceable class="parameter">action</replaceable> is one of:</phrase> <phrase>where <replaceable class="parameter">action</replaceable> is one of:</phrase>
@ -1017,20 +1010,18 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM
<para> <para>
A partition using <literal>FOR VALUES</literal> uses same syntax for A partition using <literal>FOR VALUES</literal> uses same syntax for
<replaceable class="parameter">partition_bound_spec</replaceable> as <replaceable class="parameter">partition_bound_spec</replaceable> as
<link linkend="sql-createtable"><command>CREATE TABLE</command></link>. The partition bound specification <link linkend="sql-createtable"><command>CREATE TABLE</command></link>.
The partition bound specification
must correspond to the partitioning strategy and partition key of the must correspond to the partitioning strategy and partition key of the
target table. The table to be attached must have all the same columns target table. The table to be attached must have all the same columns
as the target table and no more; moreover, the column types must also as the target table and no more; moreover, the column types must also
match. Also, it must have all the <literal>NOT NULL</literal> and match. Also, it must have all the <literal>NOT NULL</literal> and
<literal>CHECK</literal> constraints of the target table. Currently <literal>CHECK</literal> constraints of the target table, not marked
<literal>NO INHERIT</literal>. Currently
<literal>FOREIGN KEY</literal> constraints are not considered. <literal>FOREIGN KEY</literal> constraints are not considered.
<literal>UNIQUE</literal> and <literal>PRIMARY KEY</literal> constraints <literal>UNIQUE</literal> and <literal>PRIMARY KEY</literal> constraints
from the parent table will be created in the partition, if they don't from the parent table will be created in the partition, if they don't
already exist. already exist.
If any of the <literal>CHECK</literal> constraints of the table being
attached are marked <literal>NO INHERIT</literal>, the command will fail;
such constraints must be recreated without the
<literal>NO INHERIT</literal> clause.
</para> </para>
<para> <para>
@ -1124,138 +1115,14 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry id="sql-altertable-split-partition">
<term><literal>SPLIT PARTITION <replaceable class="parameter">partition_name</replaceable> INTO (PARTITION <replaceable class="parameter">partition_name1</replaceable> { FOR VALUES <replaceable class="parameter">partition_bound_spec</replaceable> | DEFAULT }, PARTITION <replaceable class="parameter">partition_name2</replaceable> { FOR VALUES <replaceable class="parameter">partition_bound_spec</replaceable> | DEFAULT } [, ...])</literal></term>
<listitem>
<para>
This form splits a single partition of the target table. Hash-partitioning
is not supported. Bounds of new partitions should not overlap with new and
existing partitions (except <replaceable class="parameter">partition_name</replaceable>).
If the split partition is a DEFAULT partition, one of the new partitions must be DEFAULT.
In case one of the new partitions or one of existing partitions is DEFAULT,
new partitions <replaceable class="parameter">partition_name1</replaceable>,
<replaceable class="parameter">partition_name2</replaceable>, ... can have spaces
between partitions bounds. If the partitioned table does not have a DEFAULT
partition, the DEFAULT partition can be defined as one of the new partitions.
</para>
<para>
In case new partitions do not contain a DEFAULT partition and the partitioned table
does not have a DEFAULT partition, the following must be true: sum bounds of
new partitions <replaceable class="parameter">partition_name1</replaceable>,
<replaceable class="parameter">partition_name2</replaceable>, ... should be
equal to bound of split partition <replaceable class="parameter">partition_name</replaceable>.
One of the new partitions <replaceable class="parameter">partition_name1</replaceable>,
<replaceable class="parameter">partition_name2</replaceable>, ... can have
the same name as split partition <replaceable class="parameter">partition_name</replaceable>
(this is suitable in case of splitting a DEFAULT partition: we split it, but after
splitting we have a partition with the same name).
Only simple, non-partitioned partition can be split.
</para>
<para>
The new partitions will be created the same as tables created with the
SQL command <literal>CREATE TABLE <replaceable class="parameter">partition_nameN</replaceable> (LIKE <replaceable class="parameter">name</replaceable> INCLUDING ALL EXCLUDING INDEXES EXCLUDING IDENTITY EXCLUDING STATISTICS)</literal>.
The indexes and identity are created later, after moving the data
into the new partitions.
Extended statistics aren't copied from the parent table, for consistency with
<command>CREATE TABLE PARTITION OF</command>.
New partitions will have the same table access method as the parent.
If the parent table is persistent then new partitions are created
persistent. If the parent table is temporary then new partitions
are also created temporary.
</para>
<note>
<para>
This command acquires an <literal>ACCESS EXCLUSIVE</literal> lock.
This is a significant limitation, which limits the usage of this
command with large partitioned tables under a high load.
</para>
</note>
</listitem>
</varlistentry>
<varlistentry id="sql-altertable-merge-partitions">
<term><literal>MERGE PARTITIONS (<replaceable class="parameter">partition_name1</replaceable>, <replaceable class="parameter">partition_name2</replaceable> [, ...]) INTO <replaceable class="parameter">partition_name</replaceable></literal></term>
<listitem>
<para>
This form merges several partitions into the one partition of the target table.
Hash-partitioning is not supported. If DEFAULT partition is not in the
list of partitions <replaceable class="parameter">partition_name1</replaceable>,
<replaceable class="parameter">partition_name2</replaceable> [, ...]:
<itemizedlist>
<listitem>
<para>
For range-partitioned tables it is necessary that the ranges
of the partitions <replaceable class="parameter">partition_name1</replaceable>,
<replaceable class="parameter">partition_name2</replaceable> [, ...] can
be merged into one range without spaces and overlaps (otherwise an error
will be generated). The combined range will be the range for the partition
<replaceable class="parameter">partition_name</replaceable>.
</para>
</listitem>
<listitem>
<para>
For list-partitioned tables the value lists of all partitions
<replaceable class="parameter">partition_name1</replaceable>,
<replaceable class="parameter">partition_name2</replaceable> [, ...] are
combined and form the list of values of partition
<replaceable class="parameter">partition_name</replaceable>.
</para>
</listitem>
</itemizedlist>
If DEFAULT partition is in the list of partitions <replaceable class="parameter">partition_name1</replaceable>,
<replaceable class="parameter">partition_name2</replaceable> [, ...]:
<itemizedlist>
<listitem>
<para>
The partition <replaceable class="parameter">partition_name</replaceable>
will be the DEFAULT partition.
</para>
</listitem>
<listitem>
<para>
For range- and list-partitioned tables the ranges and lists of values
of the merged partitions can be any.
</para>
</listitem>
</itemizedlist>
The new partition <replaceable class="parameter">partition_name</replaceable>
can have the same name as one of the merged partitions. Only simple,
non-partitioned partitions can be merged.
</para>
<para>
The new partition will be created the same as a table created with the
SQL command <literal>CREATE TABLE <replaceable class="parameter">partition_name</replaceable> (LIKE <replaceable class="parameter">name</replaceable> INCLUDING ALL EXCLUDING INDEXES EXCLUDING IDENTITY EXCLUDING STATISTICS)</literal>.
The indexes and identity are created later, after moving the data
into the new partition.
Extended statistics aren't copied from the parent table, for consistency with
<command>CREATE TABLE PARTITION OF</command>.
The new partition will have the same table access method as the parent.
If the parent table is persistent then the new partition is created
persistent. If the parent table is temporary then the new partition
is also created temporary.
</para>
<note>
<para>
This command acquires an <literal>ACCESS EXCLUSIVE</literal> lock.
This is a significant limitation, which limits the usage of this
command with large partitioned tables under a high load.
</para>
</note>
</listitem>
</varlistentry>
</variablelist> </variablelist>
</para> </para>
<para> <para>
All the forms of ALTER TABLE that act on a single table, except All the forms of ALTER TABLE that act on a single table, except
<literal>RENAME</literal>, <literal>SET SCHEMA</literal>, <literal>RENAME</literal>, <literal>SET SCHEMA</literal>,
<literal>ATTACH PARTITION</literal>, <literal>DETACH PARTITION</literal>, <literal>ATTACH PARTITION</literal>, and
<literal>SPLIT PARTITION</literal>, and <literal>MERGE PARTITIONS</literal> <literal>DETACH PARTITION</literal> can be combined into
can be combined into
a list of multiple alterations to be applied together. For example, it a list of multiple alterations to be applied together. For example, it
is possible to add several columns and/or alter the type of several is possible to add several columns and/or alter the type of several
columns in a single command. This is particularly useful with large columns in a single command. This is particularly useful with large
@ -1498,8 +1365,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM
<term><replaceable class="parameter">partition_name</replaceable></term> <term><replaceable class="parameter">partition_name</replaceable></term>
<listitem> <listitem>
<para> <para>
The name of the table to attach as a new partition or to detach from this table, The name of the table to attach as a new partition or to detach from this table.
or the name of split partition, or the name of the new merged partition.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -1915,31 +1781,6 @@ ALTER TABLE measurement
DETACH PARTITION measurement_y2015m12; DETACH PARTITION measurement_y2015m12;
</programlisting></para> </programlisting></para>
<para>
To split a single partition of the range-partitioned table:
<programlisting>
ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2023 INTO
(PARTITION sales_feb2023 FOR VALUES FROM ('2023-02-01') TO ('2023-03-01'),
PARTITION sales_mar2023 FOR VALUES FROM ('2023-03-01') TO ('2023-04-01'),
PARTITION sales_apr2023 FOR VALUES FROM ('2023-04-01') TO ('2023-05-01'));
</programlisting></para>
<para>
To split a single partition of the list-partitioned table:
<programlisting>
ALTER TABLE sales_list SPLIT PARTITION sales_all INTO
(PARTITION sales_west FOR VALUES IN ('Lisbon', 'New York', 'Madrid'),
PARTITION sales_east FOR VALUES IN ('Bejing', 'Delhi', 'Vladivostok'),
PARTITION sales_central FOR VALUES IN ('Warsaw', 'Berlin', 'Kyiv'));
</programlisting></para>
<para>
To merge several partitions into one partition of the target table:
<programlisting>
ALTER TABLE sales_list MERGE PARTITIONS (sales_west, sales_east, sales_central)
INTO sales_all;
</programlisting></para>
</refsect1> </refsect1>
<refsect1> <refsect1>

View File

@ -143,7 +143,9 @@ CREATE MATERIALIZED VIEW [ IF NOT EXISTS ] <replaceable>table_name</replaceable>
A <link linkend="sql-select"><command>SELECT</command></link>, <link linkend="sql-table"><command>TABLE</command></link>, A <link linkend="sql-select"><command>SELECT</command></link>, <link linkend="sql-table"><command>TABLE</command></link>,
or <link linkend="sql-values"><command>VALUES</command></link> command. This query will run within a or <link linkend="sql-values"><command>VALUES</command></link> command. This query will run within a
security-restricted operation; in particular, calls to functions that security-restricted operation; in particular, calls to functions that
themselves create temporary tables will fail. themselves create temporary tables will fail. Also, while the query is
running, the <xref linkend="guc-search-path"/> is temporarily changed to
<literal>pg_catalog, pg_temp</literal>.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>

View File

@ -924,8 +924,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM
<para> <para>
This clause creates the column as an <firstterm>identity This clause creates the column as an <firstterm>identity
column</firstterm>. It will have an implicit sequence attached to it column</firstterm>. It will have an implicit sequence attached to it
and the column in new rows will automatically have values from the and in newly-inserted rows the column will automatically have values
sequence assigned to it. from the sequence assigned to it.
Such a column is implicitly <literal>NOT NULL</literal>. Such a column is implicitly <literal>NOT NULL</literal>.
</para> </para>
@ -955,9 +955,16 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM
</para> </para>
<para> <para>
The optional <replaceable>sequence_options</replaceable> clause can be The optional <replaceable>sequence_options</replaceable> clause can
used to override the options of the sequence. be used to override the parameters of the sequence. The available
See <xref linkend="sql-createsequence"/> for details. options include those shown for <xref linkend="sql-createsequence"/>,
plus <literal>SEQUENCE NAME <replaceable>name</replaceable></literal>,
<literal>LOGGED</literal>, and <literal>UNLOGGED</literal>, which
allow selection of the name and persistence level of the
sequence. Without <literal>SEQUENCE NAME</literal>, the system
chooses an unused name for the sequence.
Without <literal>LOGGED</literal> or <literal>UNLOGGED</literal>,
the sequence will have the same persistence level as the table.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>

View File

@ -25,7 +25,7 @@ PostgreSQL documentation
DELETE FROM [ ONLY ] <replaceable class="parameter">table_name</replaceable> [ * ] [ [ AS ] <replaceable class="parameter">alias</replaceable> ] DELETE FROM [ ONLY ] <replaceable class="parameter">table_name</replaceable> [ * ] [ [ AS ] <replaceable class="parameter">alias</replaceable> ]
[ USING <replaceable class="parameter">from_item</replaceable> [, ...] ] [ USING <replaceable class="parameter">from_item</replaceable> [, ...] ]
[ WHERE <replaceable class="parameter">condition</replaceable> | WHERE CURRENT OF <replaceable class="parameter">cursor_name</replaceable> ] [ WHERE <replaceable class="parameter">condition</replaceable> | WHERE CURRENT OF <replaceable class="parameter">cursor_name</replaceable> ]
[ RETURNING * | <replaceable class="parameter">output_expression</replaceable> [ [ AS ] <replaceable class="parameter">output_name</replaceable> ] [, ...] ] [ RETURNING { * | <replaceable class="parameter">output_expression</replaceable> [ [ AS ] <replaceable class="parameter">output_name</replaceable> ] } [, ...] ]
</synopsis> </synopsis>
</refsynopsisdiv> </refsynopsisdiv>

View File

@ -82,7 +82,7 @@ DROP EXTENSION [ IF EXISTS ] <replaceable class="parameter">name</replaceable> [
<para> <para>
This option prevents the specified extensions from being dropped if This option prevents the specified extensions from being dropped if
other objects, besides these extensions, their members, and their other objects, besides these extensions, their members, and their
explicitly dependent routines, depend on them.  This is the default. explicitly dependent routines, depend on them. This is the default.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>

View File

@ -26,7 +26,7 @@ INSERT INTO <replaceable class="parameter">table_name</replaceable> [ AS <replac
[ OVERRIDING { SYSTEM | USER } VALUE ] [ OVERRIDING { SYSTEM | USER } VALUE ]
{ DEFAULT VALUES | VALUES ( { <replaceable class="parameter">expression</replaceable> | DEFAULT } [, ...] ) [, ...] | <replaceable class="parameter">query</replaceable> } { DEFAULT VALUES | VALUES ( { <replaceable class="parameter">expression</replaceable> | DEFAULT } [, ...] ) [, ...] | <replaceable class="parameter">query</replaceable> }
[ ON CONFLICT [ <replaceable class="parameter">conflict_target</replaceable> ] <replaceable class="parameter">conflict_action</replaceable> ] [ ON CONFLICT [ <replaceable class="parameter">conflict_target</replaceable> ] <replaceable class="parameter">conflict_action</replaceable> ]
[ RETURNING * | <replaceable class="parameter">output_expression</replaceable> [ [ AS ] <replaceable class="parameter">output_name</replaceable> ] [, ...] ] [ RETURNING { * | <replaceable class="parameter">output_expression</replaceable> [ [ AS ] <replaceable class="parameter">output_name</replaceable> ] } [, ...] ]
<phrase>where <replaceable class="parameter">conflict_target</replaceable> can be one of:</phrase> <phrase>where <replaceable class="parameter">conflict_target</replaceable> can be one of:</phrase>

View File

@ -25,7 +25,7 @@ PostgreSQL documentation
MERGE INTO [ ONLY ] <replaceable class="parameter">target_table_name</replaceable> [ * ] [ [ AS ] <replaceable class="parameter">target_alias</replaceable> ] MERGE INTO [ ONLY ] <replaceable class="parameter">target_table_name</replaceable> [ * ] [ [ AS ] <replaceable class="parameter">target_alias</replaceable> ]
USING <replaceable class="parameter">data_source</replaceable> ON <replaceable class="parameter">join_condition</replaceable> USING <replaceable class="parameter">data_source</replaceable> ON <replaceable class="parameter">join_condition</replaceable>
<replaceable class="parameter">when_clause</replaceable> [...] <replaceable class="parameter">when_clause</replaceable> [...]
[ RETURNING * | <replaceable class="parameter">output_expression</replaceable> [ [ AS ] <replaceable class="parameter">output_name</replaceable> ] [, ...] ] [ RETURNING { * | <replaceable class="parameter">output_expression</replaceable> [ [ AS ] <replaceable class="parameter">output_name</replaceable> ] } [, ...] ]
<phrase>where <replaceable class="parameter">data_source</replaceable> is:</phrase> <phrase>where <replaceable class="parameter">data_source</replaceable> is:</phrase>

View File

@ -807,14 +807,18 @@ PostgreSQL documentation
will override any conflicting command line options. will override any conflicting command line options.
</para> </para>
<para> <para>
The option is called <literal>--dbname</literal> for consistency with other This option is called <literal>--dbname</literal> for consistency with other
client applications, but because <application>pg_basebackup</application> client applications, but because <application>pg_basebackup</application>
doesn't connect to any particular database in the cluster, any database doesn't connect to any particular database in the cluster, any database
name in the connection string will be ignored name included in the connection string will be ignored by the server.
by <productname>PostgreSQL</productname>. Middleware, or proxies, used in However, a database name supplied that way overrides the default
connecting to <productname>PostgreSQL</productname> might however database name (<literal>replication</literal>) for purposes of
utilize the value. The database name specified in connection string can looking up the replication connection's password
also be used by <link linkend="logicaldecoding-replication-slots-synchronization"> in <filename>~/.pgpass</filename>. Similarly, middleware or proxies
used in connecting to <productname>PostgreSQL</productname> might
utilize the name for purposes such as connection routing. The
database name can also be used
by <link linkend="logicaldecoding-replication-slots-synchronization">
logical replication slot synchronization</link>. logical replication slot synchronization</link>.
</para> </para>
</listitem> </listitem>

View File

@ -57,13 +57,14 @@ PostgreSQL documentation
<para> <para>
After a successful run, the state of the target server is analogous to a After a successful run, the state of the target server is analogous to a
fresh logical replication setup. The main difference between the logical fresh logical replication setup. The main difference between the logical
replication setup and <application>pg_createsubscriber</application> is the replication setup and <application>pg_createsubscriber</application> is how
initial data copy. It does only the synchronization phase, which ensures the data synchronization is done. <application>pg_createsubscriber</application>
each table is brought up to a synchronized state. does not copy the initial table data. It does only the synchronization phase,
which ensures each table is brought up to a synchronized state.
</para> </para>
<para> <para>
The <application>pg_createsubscriber</application> targets large database <application>pg_createsubscriber</application> targets large database
systems because in logical replication setup, most of the time is spent systems because in logical replication setup, most of the time is spent
doing the initial data copy. Furthermore, a side effect of this long time doing the initial data copy. Furthermore, a side effect of this long time
spent synchronizing data is usually a large amount of changes to be applied spent synchronizing data is usually a large amount of changes to be applied
@ -87,8 +88,9 @@ PostgreSQL documentation
<term><option>--database=<replaceable class="parameter">dbname</replaceable></option></term> <term><option>--database=<replaceable class="parameter">dbname</replaceable></option></term>
<listitem> <listitem>
<para> <para>
The database name to create the subscription. Multiple databases can The name of the database in which to create a subscription. Multiple
be selected by writing multiple <option>-d</option> switches. databases can be selected by writing multiple <option>-d</option>
switches.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -139,7 +141,7 @@ PostgreSQL documentation
<varlistentry> <varlistentry>
<term><option>-s <replaceable class="parameter">dir</replaceable></option></term> <term><option>-s <replaceable class="parameter">dir</replaceable></option></term>
<term><option>--socket-directory=<replaceable class="parameter">dir</replaceable></option></term> <term><option>--socketdir=<replaceable class="parameter">dir</replaceable></option></term>
<listitem> <listitem>
<para> <para>
The directory to use for postmaster sockets on target server. The The directory to use for postmaster sockets on target server. The
@ -189,8 +191,8 @@ PostgreSQL documentation
<listitem> <listitem>
<para> <para>
Use the specified main server configuration file for the target data Use the specified main server configuration file for the target data
directory. The <application>pg_createsubscriber</application> uses directory. <application>pg_createsubscriber</application> internally uses
internally the <application>pg_ctl</application> command to start and the <application>pg_ctl</application> command to start and
stop the target server. It allows you to specify the actual stop the target server. It allows you to specify the actual
<filename>postgresql.conf</filename> configuration file if it is stored <filename>postgresql.conf</filename> configuration file if it is stored
outside the data directory. outside the data directory.

View File

@ -997,6 +997,14 @@ PostgreSQL documentation
The only exception is that an empty pattern is disallowed. The only exception is that an empty pattern is disallowed.
</para> </para>
<note>
<para>
Using wildcards in <option>--include-foreign-data</option> may result
in access to unexpected foreign servers. Also, to use this option securely,
make sure that the named server must have a trusted owner.
</para>
</note>
<note> <note>
<para> <para>
When <option>--include-foreign-data</option> is specified, When <option>--include-foreign-data</option> is specified,

View File

@ -315,13 +315,16 @@ PostgreSQL documentation
will override any conflicting command line options. will override any conflicting command line options.
</para> </para>
<para> <para>
The option is called <literal>--dbname</literal> for consistency with other This option is called <literal>--dbname</literal> for consistency with other
client applications, but because <application>pg_receivewal</application> client applications, but because <application>pg_receivewal</application>
doesn't connect to any particular database in the cluster, any database doesn't connect to any particular database in the cluster, any database
name in the connection string will be ignored by name included in the connection string will be ignored by the server.
<productname>PostgreSQL</productname>. Middleware, or proxies, used in However, a database name supplied that way overrides the default
connecting to <productname>PostgreSQL</productname> might however database name (<literal>replication</literal>) for purposes of
utilize the value. looking up the replication connection's password
in <filename>~/.pgpass</filename>. Similarly, middleware or proxies
used in connecting to <productname>PostgreSQL</productname> might
utilize the name for purposes such as connection routing.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>

View File

@ -284,7 +284,7 @@ PostgreSQL documentation
</para> </para>
<para> <para>
The full page images are saved with the following file name format: The full page images are saved with the following file name format:
<literal><replaceable>TIMELINE</replaceable>-<replaceable>LSN</replaceable>.<replaceable>RELTABLESPACE</replaceable>.<replaceable>DATOID</replaceable>.<replaceable>RELNODE</replaceable>.<replaceable>BLKNO</replaceable><replaceable>FORK</replaceable></literal> <literal><replaceable>TIMELINE</replaceable>-<replaceable>LSN</replaceable>.<replaceable>RELTABLESPACE</replaceable>.<replaceable>DATOID</replaceable>.<replaceable>RELNODE</replaceable>.<replaceable>BLKNO</replaceable>_<replaceable>FORK</replaceable></literal>
The file names are composed of the following parts: The file names are composed of the following parts:
<informaltable> <informaltable>
@ -335,8 +335,8 @@ PostgreSQL documentation
<entry>FORK</entry> <entry>FORK</entry>
<entry> <entry>
The name of the fork the full page image came from, such as The name of the fork the full page image came from, such as
<literal>_main</literal>, <literal>_fsm</literal>, <literal>main</literal>, <literal>fsm</literal>,
<literal>_vm</literal>, or <literal>_init</literal>. <literal>vm</literal>, or <literal>init</literal>.
</entry> </entry>
</row> </row>
</tbody> </tbody>

View File

@ -34,7 +34,7 @@ PostgreSQL documentation
<synopsis> <synopsis>
[ WITH [ RECURSIVE ] <replaceable class="parameter">with_query</replaceable> [, ...] ] [ WITH [ RECURSIVE ] <replaceable class="parameter">with_query</replaceable> [, ...] ]
SELECT [ ALL | DISTINCT [ ON ( <replaceable class="parameter">expression</replaceable> [, ...] ) ] ] SELECT [ ALL | DISTINCT [ ON ( <replaceable class="parameter">expression</replaceable> [, ...] ) ] ]
[ * | <replaceable class="parameter">expression</replaceable> [ [ AS ] <replaceable class="parameter">output_name</replaceable> ] [, ...] ] [ { * | <replaceable class="parameter">expression</replaceable> [ [ AS ] <replaceable class="parameter">output_name</replaceable> ] } [, ...] ]
[ FROM <replaceable class="parameter">from_item</replaceable> [, ...] ] [ FROM <replaceable class="parameter">from_item</replaceable> [, ...] ]
[ WHERE <replaceable class="parameter">condition</replaceable> ] [ WHERE <replaceable class="parameter">condition</replaceable> ]
[ GROUP BY [ ALL | DISTINCT ] <replaceable class="parameter">grouping_element</replaceable> [, ...] ] [ GROUP BY [ ALL | DISTINCT ] <replaceable class="parameter">grouping_element</replaceable> [, ...] ]

View File

@ -23,7 +23,7 @@ PostgreSQL documentation
<synopsis> <synopsis>
[ WITH [ RECURSIVE ] <replaceable class="parameter">with_query</replaceable> [, ...] ] [ WITH [ RECURSIVE ] <replaceable class="parameter">with_query</replaceable> [, ...] ]
SELECT [ ALL | DISTINCT [ ON ( <replaceable class="parameter">expression</replaceable> [, ...] ) ] ] SELECT [ ALL | DISTINCT [ ON ( <replaceable class="parameter">expression</replaceable> [, ...] ) ] ]
* | <replaceable class="parameter">expression</replaceable> [ [ AS ] <replaceable class="parameter">output_name</replaceable> ] [, ...] [ { * | <replaceable class="parameter">expression</replaceable> [ [ AS ] <replaceable class="parameter">output_name</replaceable> ] } [, ...] ]
INTO [ TEMPORARY | TEMP | UNLOGGED ] [ TABLE ] <replaceable class="parameter">new_table</replaceable> INTO [ TEMPORARY | TEMP | UNLOGGED ] [ TABLE ] <replaceable class="parameter">new_table</replaceable>
[ FROM <replaceable class="parameter">from_item</replaceable> [, ...] ] [ FROM <replaceable class="parameter">from_item</replaceable> [, ...] ]
[ WHERE <replaceable class="parameter">condition</replaceable> ] [ WHERE <replaceable class="parameter">condition</replaceable> ]

View File

@ -200,7 +200,7 @@ SELECT setseed(<replaceable>value</replaceable>);
<variablelist> <variablelist>
<varlistentry> <varlistentry>
<term><literal>'PST8PDT'</literal></term> <term><literal>'America/Los_Angeles'</literal></term>
<listitem> <listitem>
<para> <para>
The time zone for Berkeley, California. The time zone for Berkeley, California.
@ -298,7 +298,7 @@ SET datestyle TO postgres, dmy;
<para> <para>
Set the time zone for Berkeley, California: Set the time zone for Berkeley, California:
<screen> <screen>
SET TIME ZONE 'PST8PDT'; SET TIME ZONE 'America/Los_Angeles';
</screen> </screen>
</para> </para>

View File

@ -29,7 +29,7 @@ UPDATE [ ONLY ] <replaceable class="parameter">table_name</replaceable> [ * ] [
} [, ...] } [, ...]
[ FROM <replaceable class="parameter">from_item</replaceable> [, ...] ] [ FROM <replaceable class="parameter">from_item</replaceable> [, ...] ]
[ WHERE <replaceable class="parameter">condition</replaceable> | WHERE CURRENT OF <replaceable class="parameter">cursor_name</replaceable> ] [ WHERE <replaceable class="parameter">condition</replaceable> | WHERE CURRENT OF <replaceable class="parameter">cursor_name</replaceable> ]
[ RETURNING * | <replaceable class="parameter">output_expression</replaceable> [ [ AS ] <replaceable class="parameter">output_name</replaceable> ] [, ...] ] [ RETURNING { * | <replaceable class="parameter">output_expression</replaceable> [ [ AS ] <replaceable class="parameter">output_name</replaceable> ] } [, ...] ]
</synopsis> </synopsis>
</refsynopsisdiv> </refsynopsisdiv>

View File

@ -576,11 +576,11 @@ make check NO_LOCALE=1
<para> <para>
Most of the date and time results are dependent on the time zone Most of the date and time results are dependent on the time zone
environment. The reference files are generated for time zone environment. The reference files are generated for time zone
<literal>PST8PDT</literal> (Berkeley, California), and there will be <literal>America/Los_Angeles</literal>, and there will be
apparent failures if the tests are not run with that time zone setting. apparent failures if the tests are not run with that time zone setting.
The regression test driver sets environment variable The regression test driver sets environment variable
<envar>PGTZ</envar> to <literal>PST8PDT</literal>, which normally <envar>PGTZ</envar> to <literal>America/Los_Angeles</literal>,
ensures proper results. which normally ensures proper results.
</para> </para>
</sect2> </sect2>

File diff suppressed because it is too large Load Diff

View File

@ -69,6 +69,15 @@ For new features, add links to the documentation sections.
review, so each item is truly a community effort. review, so each item is truly a community effort.
</para> </para>
<para id="release-commit-links">
Section markers (&sect;) in the release notes link to <ulink
url="https://git.postgresql.org/gitweb/?p=postgresql.git"><application>gitweb</application></ulink>
pages which show the primary <application>git</application> commit
messages and source tree changes responsible for the release note item.
There might be additional <application>git</application> commits which
are not shown.
</para>
<!-- <!--
When beginning a new major-release series, create a new release-NN.sgml When beginning a new major-release series, create a new release-NN.sgml
file, removing the previous one, and change the &-reference here. file, removing the previous one, and change the &-reference here.

View File

@ -1422,11 +1422,10 @@ export PG_OOM_ADJUST_VALUE=0
with <varname>CONFIG_HUGETLBFS=y</varname> and with <varname>CONFIG_HUGETLBFS=y</varname> and
<varname>CONFIG_HUGETLB_PAGE=y</varname>. You will also have to configure <varname>CONFIG_HUGETLB_PAGE=y</varname>. You will also have to configure
the operating system to provide enough huge pages of the desired size. the operating system to provide enough huge pages of the desired size.
To determine the number of huge pages needed, use the The runtime-computed parameter
<command>postgres</command> command to see the value of <xref linkend="guc-shared-memory-size-in-huge-pages"/> reports the number
<xref linkend="guc-shared-memory-size-in-huge-pages"/>. Note that the of huge pages required. This parameter can be viewed before starting the
server must be shut down to view this runtime-computed parameter. server with a <command>postgres</command> command like:
This might look like:
<programlisting> <programlisting>
$ <userinput>postgres -D $PGDATA -C shared_memory_size_in_huge_pages</userinput> $ <userinput>postgres -D $PGDATA -C shared_memory_size_in_huge_pages</userinput>
3170 3170

View File

@ -14,6 +14,21 @@
<xsl:param name="tablecolumns.extension" select="0"></xsl:param> <xsl:param name="tablecolumns.extension" select="0"></xsl:param>
<xsl:param name="toc.max.depth">3</xsl:param> <xsl:param name="toc.max.depth">3</xsl:param>
<xsl:param name="ulink.footnotes" select="1"></xsl:param> <xsl:param name="ulink.footnotes" select="1"></xsl:param>
<!-- The release notes have too many ulinks to look good as footnotes in print mode -->
<xsl:template match="sect1[starts-with(@id, 'release-')]//ulink[starts-with(@url, 'https://postgr.es/c/')]">
<!-- Do nothing for ulink to avoid footnotes -->
</xsl:template>
<!--
Suppress the description of the commit link markers in print mode.
Use "node()" to keep the paragraph but remove all content; prevents
an "Unresolved ID reference found" warning during PDF builds.
-->
<xsl:template match="appendix[@id='release']//para[@id='release-commit-links']//node()">
<!-- Output an empty para -->
</xsl:template>
<xsl:param name="use.extensions" select="1"></xsl:param> <xsl:param name="use.extensions" select="1"></xsl:param>
<xsl:param name="variablelist.as.blocks" select="1"></xsl:param> <xsl:param name="variablelist.as.blocks" select="1"></xsl:param>
<xsl:param name="orderedlist.label.width">1.5em</xsl:param> <xsl:param name="orderedlist.label.width">1.5em</xsl:param>

View File

@ -186,7 +186,7 @@
<itemizedlist> <itemizedlist>
<listitem> <listitem>
<para> <para>
Each individual record in a WAL file is protected by a CRC-32 (32-bit) check Each individual record in a WAL file is protected by a CRC-32C (32-bit) check
that allows us to tell if record contents are correct. The CRC value that allows us to tell if record contents are correct. The CRC value
is set when we write each WAL record and checked during crash recovery, is set when we write each WAL record and checked during crash recovery,
archive recovery and replication. archive recovery and replication.
@ -212,7 +212,7 @@
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
Individual state files in <filename>pg_twophase</filename> are protected by CRC-32. Individual state files in <filename>pg_twophase</filename> are protected by CRC-32C.
</para> </para>
</listitem> </listitem>
<listitem> <listitem>

View File

@ -8,7 +8,7 @@
project('postgresql', project('postgresql',
['c'], ['c'],
version: '17beta2', version: '17.2',
license: 'PostgreSQL', license: 'PostgreSQL',
# We want < 0.56 for python 3.5 compatibility on old platforms. EPEL for # We want < 0.56 for python 3.5 compatibility on old platforms. EPEL for
@ -614,31 +614,66 @@ gssapiopt = get_option('gssapi')
krb_srvtab = '' krb_srvtab = ''
have_gssapi = false have_gssapi = false
if not gssapiopt.disabled() if not gssapiopt.disabled()
gssapi = dependency('krb5-gssapi', required: gssapiopt) gssapi = dependency('krb5-gssapi', required: false)
have_gssapi = gssapi.found() have_gssapi = gssapi.found()
if have_gssapi
gssapi_deps = [gssapi]
elif not have_gssapi
# Hardcoded lookup for gssapi. This is necessary as gssapi on windows does
# not install neither pkg-config nor cmake dependency information.
if host_system == 'windows'
is_64 = cc.sizeof('void *', args: test_c_args) == 8
if is_64
gssapi_search_libs = ['gssapi64', 'krb5_64', 'comerr64']
else
gssapi_search_libs = ['gssapi32', 'krb5_32', 'comerr32']
endif
else
gssapi_search_libs = ['gssapi_krb5']
endif
gssapi_deps = []
foreach libname : gssapi_search_libs
lib = cc.find_library(libname, dirs: test_lib_d, required: false)
if lib.found()
have_gssapi = true
gssapi_deps += lib
endif
endforeach
if have_gssapi
# Meson before 0.57.0 did not support using check_header() etc with
# declare_dependency(). Thus the tests below use the library looked up
# above. Once we require a newer meson version, we can simplify.
gssapi = declare_dependency(dependencies: gssapi_deps)
endif
endif
if not have_gssapi if not have_gssapi
elif cc.check_header('gssapi/gssapi.h', dependencies: gssapi, required: false, elif cc.check_header('gssapi/gssapi.h', dependencies: gssapi_deps, required: false,
args: test_c_args, include_directories: postgres_inc) args: test_c_args, include_directories: postgres_inc)
cdata.set('HAVE_GSSAPI_GSSAPI_H', 1) cdata.set('HAVE_GSSAPI_GSSAPI_H', 1)
elif cc.check_header('gssapi.h', args: test_c_args, dependencies: gssapi, required: gssapiopt) elif cc.check_header('gssapi.h', dependencies: gssapi_deps, required: gssapiopt,
args: test_c_args, include_directories: postgres_inc)
cdata.set('HAVE_GSSAPI_H', 1) cdata.set('HAVE_GSSAPI_H', 1)
else else
have_gssapi = false have_gssapi = false
endif endif
if not have_gssapi if not have_gssapi
elif cc.check_header('gssapi/gssapi_ext.h', dependencies: gssapi, required: false, elif cc.check_header('gssapi/gssapi_ext.h', dependencies: gssapi_deps, required: false,
args: test_c_args, include_directories: postgres_inc) args: test_c_args, include_directories: postgres_inc)
cdata.set('HAVE_GSSAPI_GSSAPI_EXT_H', 1) cdata.set('HAVE_GSSAPI_GSSAPI_EXT_H', 1)
elif cc.check_header('gssapi_ext.h', args: test_c_args, dependencies: gssapi, required: gssapiopt) elif cc.check_header('gssapi_ext.h', dependencies: gssapi_deps, required: gssapiopt,
args: test_c_args, include_directories: postgres_inc)
cdata.set('HAVE_GSSAPI_EXT_H', 1) cdata.set('HAVE_GSSAPI_EXT_H', 1)
else else
have_gssapi = false have_gssapi = false
endif endif
if not have_gssapi if not have_gssapi
elif cc.has_function('gss_store_cred_into', dependencies: gssapi, elif cc.has_function('gss_store_cred_into', dependencies: gssapi_deps,
args: test_c_args, include_directories: postgres_inc) args: test_c_args, include_directories: postgres_inc)
cdata.set('ENABLE_GSS', 1) cdata.set('ENABLE_GSS', 1)
@ -649,6 +684,11 @@ if not gssapiopt.disabled()
else else
have_gssapi = false have_gssapi = false
endif endif
if not have_gssapi and gssapiopt.enabled()
error('dependency lookup for gssapi failed')
endif
endif endif
if not have_gssapi if not have_gssapi
gssapi = not_found_dep gssapi = not_found_dep
@ -759,7 +799,10 @@ if add_languages('cpp', required: llvmopt, native: false)
llvm_binpath = llvm.get_variable(configtool: 'bindir') llvm_binpath = llvm.get_variable(configtool: 'bindir')
ccache = find_program('ccache', native: true, required: false) ccache = find_program('ccache', native: true, required: false)
clang = find_program(llvm_binpath / 'clang', required: true)
# Some distros put LLVM and clang in different paths, so fallback to
# find via PATH, too.
clang = find_program(llvm_binpath / 'clang', 'clang', required: true)
endif endif
elif llvmopt.auto() elif llvmopt.auto()
message('llvm requires a C++ compiler') message('llvm requires a C++ compiler')
@ -773,11 +816,25 @@ endif
icuopt = get_option('icu') icuopt = get_option('icu')
if not icuopt.disabled() if not icuopt.disabled()
icu = dependency('icu-uc', required: icuopt) icu = dependency('icu-uc', required: false)
icu_i18n = dependency('icu-i18n', required: icuopt) if icu.found()
icu_i18n = dependency('icu-i18n', required: true)
endif
# Unfortunately the dependency is named differently with cmake
if not icu.found() # combine with above once meson 0.60.0 is required
icu = dependency('ICU', required: icuopt,
components: ['uc'], modules: ['ICU::uc'], method: 'cmake')
if icu.found()
icu_i18n = dependency('ICU', required: true,
components: ['i18n'], modules: ['ICU::i18n'])
endif
endif
if icu.found() if icu.found()
cdata.set('USE_ICU', 1) cdata.set('USE_ICU', 1)
else
icu_i18n = not_found_dep
endif endif
else else
@ -793,7 +850,12 @@ endif
libxmlopt = get_option('libxml') libxmlopt = get_option('libxml')
if not libxmlopt.disabled() if not libxmlopt.disabled()
libxml = dependency('libxml-2.0', required: libxmlopt, version: '>= 2.6.23') libxml = dependency('libxml-2.0', required: false, version: '>= 2.6.23')
# Unfortunately the dependency is named differently with cmake
if not libxml.found() # combine with above once meson 0.60.0 is required
libxml = dependency('LibXml2', required: libxmlopt, version: '>= 2.6.23',
method: 'cmake')
endif
if libxml.found() if libxml.found()
cdata.set('USE_LIBXML', 1) cdata.set('USE_LIBXML', 1)
@ -810,7 +872,11 @@ endif
libxsltopt = get_option('libxslt') libxsltopt = get_option('libxslt')
if not libxsltopt.disabled() if not libxsltopt.disabled()
libxslt = dependency('libxslt', required: libxsltopt) libxslt = dependency('libxslt', required: false)
# Unfortunately the dependency is named differently with cmake
if not libxslt.found() # combine with above once meson 0.60.0 is required
libxslt = dependency('LibXslt', required: libxsltopt, method: 'cmake')
endif
if libxslt.found() if libxslt.found()
cdata.set('USE_LIBXSLT', 1) cdata.set('USE_LIBXSLT', 1)
@ -827,7 +893,13 @@ endif
lz4opt = get_option('lz4') lz4opt = get_option('lz4')
if not lz4opt.disabled() if not lz4opt.disabled()
lz4 = dependency('liblz4', required: lz4opt) lz4 = dependency('liblz4', required: false)
# Unfortunately the dependency is named differently with cmake
if not lz4.found() # combine with above once meson 0.60.0 is required
lz4 = dependency('lz4', required: lz4opt,
method: 'cmake', modules: ['LZ4::lz4_shared'],
)
endif
if lz4.found() if lz4.found()
cdata.set('USE_LZ4', 1) cdata.set('USE_LZ4', 1)
@ -982,7 +1054,10 @@ if not perlopt.disabled()
if cc.get_id() == 'msvc' if cc.get_id() == 'msvc'
# prevent binary mismatch between MSVC built plperl and Strawberry or # prevent binary mismatch between MSVC built plperl and Strawberry or
# msys ucrt perl libraries # msys ucrt perl libraries
perl_ccflags += ['-DNO_THREAD_SAFE_LOCALE'] perl_v = run_command(perl, '-V').stdout()
if not perl_v.contains('USE_THREAD_SAFE_LOCALE')
perl_ccflags += ['-DNO_THREAD_SAFE_LOCALE']
endif
endif endif
endif endif
@ -993,20 +1068,19 @@ if not perlopt.disabled()
# Config's ccdlflags and ldflags. (Those are the choices of those who # Config's ccdlflags and ldflags. (Those are the choices of those who
# built the Perl installation, which are not necessarily appropriate # built the Perl installation, which are not necessarily appropriate
# for building PostgreSQL.) # for building PostgreSQL.)
ldopts = run_command(perl, '-MExtUtils::Embed', '-e', 'ldopts', check: true).stdout().strip() perl_ldopts = run_command(perl, '-e', '''
undesired = run_command(perl_conf_cmd, 'ccdlflags', check: true).stdout().split() use ExtUtils::Embed;
undesired += run_command(perl_conf_cmd, 'ldflags', check: true).stdout().split() use Text::ParseWords;
# tell perl to suppress including these in ldopts
*ExtUtils::Embed::_ldflags =*ExtUtils::Embed::_ccdlflags = sub { return ""; };
# adding an argument to ldopts makes it return a value instead of printing
# print one of these per line so splitting will preserve spaces in file names.
# shellwords eats backslashes, so we need to escape them.
(my $opts = ldopts(undef)) =~ s!\\!\\\\!g;
print "$_\n" foreach shellwords($opts);
''',
check: true).stdout().strip().split('\n')
perl_ldopts = []
foreach ldopt : ldopts.split(' ')
if ldopt == '' or ldopt in undesired
continue
endif
perl_ldopts += ldopt.strip('"')
endforeach
message('LDFLAGS recommended by perl: "@0@"'.format(ldopts))
message('LDFLAGS for embedding perl: "@0@"'.format(' '.join(perl_ldopts))) message('LDFLAGS for embedding perl: "@0@"'.format(' '.join(perl_ldopts)))
perl_dep_int = declare_dependency( perl_dep_int = declare_dependency(
@ -1077,15 +1151,26 @@ endif
if not get_option('readline').disabled() if not get_option('readline').disabled()
libedit_preferred = get_option('libedit_preferred') libedit_preferred = get_option('libedit_preferred')
# Set the order of readline dependencies # Set the order of readline dependencies.
check_readline_deps = libedit_preferred ? \ # cc.find_library breaks and throws on the first dependency which
['libedit', 'readline'] : ['readline', 'libedit'] # is marked as required=true and can't be found. Thus, we only mark
# the last dependency to look up as required, to not throw too early.
check_readline_deps = [
{
'name': libedit_preferred ? 'libedit' : 'readline',
'required': false
},
{
'name': libedit_preferred ? 'readline' : 'libedit',
'required': get_option('readline')
}
]
foreach readline_dep : check_readline_deps foreach readline_dep : check_readline_deps
readline = dependency(readline_dep, required: false) readline = dependency(readline_dep['name'], required: false)
if not readline.found() if not readline.found()
readline = cc.find_library(readline_dep, readline = cc.find_library(readline_dep['name'],
required: get_option('readline'), required: readline_dep['required'],
dirs: test_lib_d) dirs: test_lib_d)
endif endif
if readline.found() if readline.found()
@ -1293,6 +1378,7 @@ if sslopt in ['auto', 'openssl']
# Function introduced in OpenSSL 1.1.1 # Function introduced in OpenSSL 1.1.1
['X509_get_signature_info'], ['X509_get_signature_info'],
['SSL_CTX_set_num_tickets'],
] ]
are_openssl_funcs_complete = true are_openssl_funcs_complete = true
@ -1346,9 +1432,26 @@ if uuidopt != 'none'
uuidfunc = 'uuid_to_string' uuidfunc = 'uuid_to_string'
uuidheader = 'uuid.h' uuidheader = 'uuid.h'
elif uuidopt == 'ossp' elif uuidopt == 'ossp'
uuid = dependency('ossp-uuid', required: true) # In upstream, the package and library is called just 'uuid', but many
# distros change it to 'ossp-uuid'.
uuid = dependency('ossp-uuid', 'uuid', required: false)
uuidfunc = 'uuid_export' uuidfunc = 'uuid_export'
uuidheader = 'uuid.h' uuidheader = 'uuid.h'
# Hardcoded lookup for ossp-uuid. This is necessary as ossp-uuid on
# windows installs neither a pkg-config nor a cmake dependency
# information. Nor is there another supported uuid implementation
# available on windows.
if not uuid.found()
uuid = cc.find_library('ossp-uuid',
required: false, dirs: test_lib_d,
has_headers: uuidheader, header_include_directories: postgres_inc)
endif
if not uuid.found()
uuid = cc.find_library('uuid',
required: true, dirs: test_lib_d,
has_headers: uuidheader, header_include_directories: postgres_inc)
endif
else else
error('unknown uuid build option value: @0@'.format(uuidopt)) error('unknown uuid build option value: @0@'.format(uuidopt))
endif endif
@ -1429,7 +1532,12 @@ endif
zstdopt = get_option('zstd') zstdopt = get_option('zstd')
if not zstdopt.disabled() if not zstdopt.disabled()
zstd = dependency('libzstd', required: zstdopt, version: '>=1.4.0') zstd = dependency('libzstd', required: false, version: '>=1.4.0')
# Unfortunately the dependency is named differently with cmake
if not zstd.found() # combine with above once meson 0.60.0 is required
zstd = dependency('zstd', required: zstdopt, version: '>=1.4.0',
method: 'cmake', modules: ['zstd::libzstd_shared'])
endif
if zstd.found() if zstd.found()
cdata.set('USE_ZSTD', 1) cdata.set('USE_ZSTD', 1)
@ -3173,15 +3281,17 @@ test_install_destdir = meson.build_root() / 'tmp_install/'
if build_system != 'windows' if build_system != 'windows'
# On unixoid systems this is trivial, we just prepend the destdir # On unixoid systems this is trivial, we just prepend the destdir
assert(dir_prefix.startswith('/')) # enforced by meson assert(dir_prefix.startswith('/')) # enforced by meson
test_install_location = '@0@@1@'.format(test_install_destdir, dir_prefix) temp_install_bindir = '@0@@1@'.format(test_install_destdir, dir_prefix / dir_bin)
temp_install_libdir = '@0@@1@'.format(test_install_destdir, dir_prefix / dir_lib)
else else
# drives, drive-relative paths, etc make this complicated on windows, call # drives, drive-relative paths, etc make this complicated on windows, call
# into a copy of meson's logic for it # into a copy of meson's logic for it
command = [ command = [
python, '-c', python, '-c',
'import sys; from pathlib import PurePath; d1=sys.argv[1]; d2=sys.argv[2]; print(str(PurePath(d1, *PurePath(d2).parts[1:])))', 'import sys; from pathlib import PurePath; d1=sys.argv[1]; d2=sys.argv[2]; print(str(PurePath(d1, *PurePath(d2).parts[1:])))',
test_install_destdir, dir_prefix] test_install_destdir]
test_install_location = run_command(command, check: true).stdout().strip() temp_install_bindir = run_command(command, dir_prefix / dir_bin, check: true).stdout().strip()
temp_install_libdir = run_command(command, dir_prefix / dir_lib, check: true).stdout().strip()
endif endif
meson_install_args = meson_args + ['install'] + { meson_install_args = meson_args + ['install'] + {
@ -3218,7 +3328,6 @@ testport = 40000
test_env = environment() test_env = environment()
temp_install_bindir = test_install_location / get_option('bindir')
test_initdb_template = meson.build_root() / 'tmp_install' / 'initdb-template' test_initdb_template = meson.build_root() / 'tmp_install' / 'initdb-template'
test_env.set('PG_REGRESS', pg_regress.full_path()) test_env.set('PG_REGRESS', pg_regress.full_path())
test_env.set('REGRESS_SHLIB', regress_module.full_path()) test_env.set('REGRESS_SHLIB', regress_module.full_path())
@ -3233,7 +3342,7 @@ test_env.set('PG_TEST_EXTRA', get_option('PG_TEST_EXTRA'))
# that works (everything but windows, basically). On windows everything # that works (everything but windows, basically). On windows everything
# library-like gets installed into bindir, solving that issue. # library-like gets installed into bindir, solving that issue.
if library_path_var != '' if library_path_var != ''
test_env.prepend(library_path_var, test_install_location / get_option('libdir')) test_env.prepend(library_path_var, temp_install_libdir)
endif endif

View File

@ -17,6 +17,7 @@
#include "access/printtup.h" #include "access/printtup.h"
#include "libpq/pqformat.h" #include "libpq/pqformat.h"
#include "libpq/protocol.h"
#include "tcop/pquery.h" #include "tcop/pquery.h"
#include "utils/lsyscache.h" #include "utils/lsyscache.h"
#include "utils/memdebug.h" #include "utils/memdebug.h"
@ -170,7 +171,7 @@ SendRowDescriptionMessage(StringInfo buf, TupleDesc typeinfo,
ListCell *tlist_item = list_head(targetlist); ListCell *tlist_item = list_head(targetlist);
/* tuple descriptor message type */ /* tuple descriptor message type */
pq_beginmessage_reuse(buf, 'T'); pq_beginmessage_reuse(buf, PqMsg_RowDescription);
/* # of attrs in tuples */ /* # of attrs in tuples */
pq_sendint16(buf, natts); pq_sendint16(buf, natts);
@ -322,7 +323,7 @@ printtup(TupleTableSlot *slot, DestReceiver *self)
/* /*
* Prepare a DataRow message (note buffer is in per-query context) * Prepare a DataRow message (note buffer is in per-query context)
*/ */
pq_beginmessage_reuse(buf, 'D'); pq_beginmessage_reuse(buf, PqMsg_DataRow);
pq_sendint16(buf, natts); pq_sendint16(buf, natts);

View File

@ -298,7 +298,9 @@ hashtext(PG_FUNCTION_ARGS)
buf = palloc(bsize + 1); buf = palloc(bsize + 1);
rsize = pg_strnxfrm(buf, bsize + 1, keydata, keylen, mylocale); rsize = pg_strnxfrm(buf, bsize + 1, keydata, keylen, mylocale);
if (rsize != bsize)
/* the second call may return a smaller value than the first */
if (rsize > bsize)
elog(ERROR, "pg_strnxfrm() returned unexpected result"); elog(ERROR, "pg_strnxfrm() returned unexpected result");
/* /*
@ -352,7 +354,9 @@ hashtextextended(PG_FUNCTION_ARGS)
buf = palloc(bsize + 1); buf = palloc(bsize + 1);
rsize = pg_strnxfrm(buf, bsize + 1, keydata, keylen, mylocale); rsize = pg_strnxfrm(buf, bsize + 1, keydata, keylen, mylocale);
if (rsize != bsize)
/* the second call may return a smaller value than the first */
if (rsize > bsize)
elog(ERROR, "pg_strnxfrm() returned unexpected result"); elog(ERROR, "pg_strnxfrm() returned unexpected result");
/* /*

View File

@ -148,6 +148,9 @@ _h_indexbuild(HSpool *hspool, Relation heapRel)
/* the tuples are sorted by hashkey, so pass 'sorted' as true */ /* the tuples are sorted by hashkey, so pass 'sorted' as true */
_hash_doinsert(hspool->index, itup, heapRel, true); _hash_doinsert(hspool->index, itup, heapRel, true);
/* allow insertion phase to be interrupted, and track progress */
CHECK_FOR_INTERRUPTS();
pgstat_progress_update_param(PROGRESS_CREATEIDX_TUPLES_DONE, pgstat_progress_update_param(PROGRESS_CREATEIDX_TUPLES_DONE,
++tups_done); ++tups_done);
} }

View File

@ -153,3 +153,56 @@ The following infomask bits are applicable:
We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit
is set. is set.
Locking to write inplace-updated tables
---------------------------------------
If IsInplaceUpdateRelation() returns true for a table, the table is a system
catalog that receives systable_inplace_update_begin() calls. Preparing a
heap_update() of these tables follows additional locking rules, to ensure we
don't lose the effects of an inplace update. In particular, consider a moment
when a backend has fetched the old tuple to modify, not yet having called
heap_update(). Another backend's inplace update starting then can't conclude
until the heap_update() places its new tuple in a buffer. We enforce that
using locktags as follows. While DDL code is the main audience, the executor
follows these rules to make e.g. "MERGE INTO pg_class" safer. Locking rules
are per-catalog:
pg_class systable_inplace_update_begin() callers: before the call, acquire a
lock on the relation in mode ShareUpdateExclusiveLock or stricter. If the
update targets a row of RELKIND_INDEX (but not RELKIND_PARTITIONED_INDEX),
that lock must be on the table. Locking the index rel is not necessary.
(This allows VACUUM to overwrite per-index pg_class while holding a lock on
the table alone.) systable_inplace_update_begin() acquires and releases
LOCKTAG_TUPLE in InplaceUpdateTupleLock, an alias for ExclusiveLock, on each
tuple it overwrites.
pg_class heap_update() callers: before copying the tuple to modify, take a
lock on the tuple, a ShareUpdateExclusiveLock on the relation, or a
ShareRowExclusiveLock or stricter on the relation.
SearchSysCacheLocked1() is one convenient way to acquire the tuple lock.
Most heap_update() callers already hold a suitable lock on the relation for
other reasons and can skip the tuple lock. If you do acquire the tuple
lock, release it immediately after the update.
pg_database: before copying the tuple to modify, all updaters of pg_database
rows acquire LOCKTAG_TUPLE. (Few updaters acquire LOCKTAG_OBJECT on the
database OID, so it wasn't worth extending that as a second option.)
Ideally, DDL might want to perform permissions checks before LockTuple(), as
we do with RangeVarGetRelidExtended() callbacks. We typically don't bother.
LOCKTAG_TUPLE acquirers release it after each row, so the potential
inconvenience is lower.
Reading inplace-updated columns
-------------------------------
Inplace updates create an exception to the rule that tuple data won't change
under a reader holding a pin. A reader of a heap_fetch() result tuple may
witness a torn read. Current inplace-updated fields are aligned and are no
wider than four bytes, and current readers don't need consistency across
fields. Hence, they get by with just fetching each field once. XXX such a
caller may also read a value that has not reached WAL; see
systable_inplace_update_finish().

View File

@ -51,6 +51,8 @@
#include "access/xloginsert.h" #include "access/xloginsert.h"
#include "access/xlogutils.h" #include "access/xlogutils.h"
#include "catalog/catalog.h" #include "catalog/catalog.h"
#include "catalog/pg_database.h"
#include "catalog/pg_database_d.h"
#include "commands/vacuum.h" #include "commands/vacuum.h"
#include "miscadmin.h" #include "miscadmin.h"
#include "pgstat.h" #include "pgstat.h"
@ -63,7 +65,6 @@
#include "storage/procarray.h" #include "storage/procarray.h"
#include "storage/standby.h" #include "storage/standby.h"
#include "utils/datum.h" #include "utils/datum.h"
#include "utils/injection_point.h"
#include "utils/inval.h" #include "utils/inval.h"
#include "utils/relcache.h" #include "utils/relcache.h"
#include "utils/snapmgr.h" #include "utils/snapmgr.h"
@ -76,6 +77,12 @@ static XLogRecPtr log_heap_update(Relation reln, Buffer oldbuf,
Buffer newbuf, HeapTuple oldtup, Buffer newbuf, HeapTuple oldtup,
HeapTuple newtup, HeapTuple old_key_tuple, HeapTuple newtup, HeapTuple old_key_tuple,
bool all_visible_cleared, bool new_all_visible_cleared); bool all_visible_cleared, bool new_all_visible_cleared);
#ifdef USE_ASSERT_CHECKING
static void check_lock_if_inplace_updateable_rel(Relation relation,
ItemPointer otid,
HeapTuple newtup);
static void check_inplace_rel_lock(HeapTuple oldtup);
#endif
static Bitmapset *HeapDetermineColumnsInfo(Relation relation, static Bitmapset *HeapDetermineColumnsInfo(Relation relation,
Bitmapset *interesting_cols, Bitmapset *interesting_cols,
Bitmapset *external_cols, Bitmapset *external_cols,
@ -122,6 +129,8 @@ static HeapTuple ExtractReplicaIdentity(Relation relation, HeapTuple tp, bool ke
* heavyweight lock mode and MultiXactStatus values to use for any particular * heavyweight lock mode and MultiXactStatus values to use for any particular
* tuple lock strength. * tuple lock strength.
* *
* These interact with InplaceUpdateTupleLock, an alias for ExclusiveLock.
*
* Don't look at lockstatus/updstatus directly! Use get_mxact_status_for_lock * Don't look at lockstatus/updstatus directly! Use get_mxact_status_for_lock
* instead. * instead.
*/ */
@ -3208,6 +3217,10 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
(errcode(ERRCODE_INVALID_TRANSACTION_STATE), (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
errmsg("cannot update tuples during a parallel operation"))); errmsg("cannot update tuples during a parallel operation")));
#ifdef USE_ASSERT_CHECKING
check_lock_if_inplace_updateable_rel(relation, otid, newtup);
#endif
/* /*
* Fetch the list of attributes to be checked for various operations. * Fetch the list of attributes to be checked for various operations.
* *
@ -4072,6 +4085,128 @@ l2:
return TM_Ok; return TM_Ok;
} }
#ifdef USE_ASSERT_CHECKING
/*
* Confirm adequate lock held during heap_update(), per rules from
* README.tuplock section "Locking to write inplace-updated tables".
*/
static void
check_lock_if_inplace_updateable_rel(Relation relation,
ItemPointer otid,
HeapTuple newtup)
{
/* LOCKTAG_TUPLE acceptable for any catalog */
switch (RelationGetRelid(relation))
{
case RelationRelationId:
case DatabaseRelationId:
{
LOCKTAG tuptag;
SET_LOCKTAG_TUPLE(tuptag,
relation->rd_lockInfo.lockRelId.dbId,
relation->rd_lockInfo.lockRelId.relId,
ItemPointerGetBlockNumber(otid),
ItemPointerGetOffsetNumber(otid));
if (LockHeldByMe(&tuptag, InplaceUpdateTupleLock, false))
return;
}
break;
default:
Assert(!IsInplaceUpdateRelation(relation));
return;
}
switch (RelationGetRelid(relation))
{
case RelationRelationId:
{
/* LOCKTAG_TUPLE or LOCKTAG_RELATION ok */
Form_pg_class classForm = (Form_pg_class) GETSTRUCT(newtup);
Oid relid = classForm->oid;
Oid dbid;
LOCKTAG tag;
if (IsSharedRelation(relid))
dbid = InvalidOid;
else
dbid = MyDatabaseId;
if (classForm->relkind == RELKIND_INDEX)
{
Relation irel = index_open(relid, AccessShareLock);
SET_LOCKTAG_RELATION(tag, dbid, irel->rd_index->indrelid);
index_close(irel, AccessShareLock);
}
else
SET_LOCKTAG_RELATION(tag, dbid, relid);
if (!LockHeldByMe(&tag, ShareUpdateExclusiveLock, false) &&
!LockHeldByMe(&tag, ShareRowExclusiveLock, true))
elog(WARNING,
"missing lock for relation \"%s\" (OID %u, relkind %c) @ TID (%u,%u)",
NameStr(classForm->relname),
relid,
classForm->relkind,
ItemPointerGetBlockNumber(otid),
ItemPointerGetOffsetNumber(otid));
}
break;
case DatabaseRelationId:
{
/* LOCKTAG_TUPLE required */
Form_pg_database dbForm = (Form_pg_database) GETSTRUCT(newtup);
elog(WARNING,
"missing lock on database \"%s\" (OID %u) @ TID (%u,%u)",
NameStr(dbForm->datname),
dbForm->oid,
ItemPointerGetBlockNumber(otid),
ItemPointerGetOffsetNumber(otid));
}
break;
}
}
/*
* Confirm adequate relation lock held, per rules from README.tuplock section
* "Locking to write inplace-updated tables".
*/
static void
check_inplace_rel_lock(HeapTuple oldtup)
{
Form_pg_class classForm = (Form_pg_class) GETSTRUCT(oldtup);
Oid relid = classForm->oid;
Oid dbid;
LOCKTAG tag;
if (IsSharedRelation(relid))
dbid = InvalidOid;
else
dbid = MyDatabaseId;
if (classForm->relkind == RELKIND_INDEX)
{
Relation irel = index_open(relid, AccessShareLock);
SET_LOCKTAG_RELATION(tag, dbid, irel->rd_index->indrelid);
index_close(irel, AccessShareLock);
}
else
SET_LOCKTAG_RELATION(tag, dbid, relid);
if (!LockHeldByMe(&tag, ShareUpdateExclusiveLock, true))
elog(WARNING,
"missing lock for relation \"%s\" (OID %u, relkind %c) @ TID (%u,%u)",
NameStr(classForm->relname),
relid,
classForm->relkind,
ItemPointerGetBlockNumber(&oldtup->t_self),
ItemPointerGetOffsetNumber(&oldtup->t_self));
}
#endif
/* /*
* Check if the specified attribute's values are the same. Subroutine for * Check if the specified attribute's values are the same. Subroutine for
* HeapDetermineColumnsInfo. * HeapDetermineColumnsInfo.
@ -6041,23 +6176,260 @@ heap_abort_speculative(Relation relation, ItemPointer tid)
} }
/* /*
* heap_inplace_update - update a tuple "in place" (ie, overwrite it) * heap_inplace_lock - protect inplace update from concurrent heap_update()
* *
* Overwriting violates both MVCC and transactional safety, so the uses * Evaluate whether the tuple's state is compatible with a no-key update.
* of this function in Postgres are extremely limited. Nonetheless we * Current transaction rowmarks are fine, as is KEY SHARE from any
* find some places to use it. * transaction. If compatible, return true with the buffer exclusive-locked,
* and the caller must release that by calling
* heap_inplace_update_and_unlock(), calling heap_inplace_unlock(), or raising
* an error. Otherwise, call release_callback(arg), wait for blocking
* transactions to end, and return false.
* *
* The tuple cannot change size, and therefore it's reasonable to assume * Since this is intended for system catalogs and SERIALIZABLE doesn't cover
* that its null bitmap (if any) doesn't change either. So we just * DDL, this doesn't guarantee any particular predicate locking.
* overwrite the data portion of the tuple without touching the null
* bitmap or any of the header fields.
* *
* tuple is an in-memory tuple structure containing the data to be written * One could modify this to return true for tuples with delete in progress,
* over the target tuple. Also, tuple->t_self identifies the target tuple. * All inplace updaters take a lock that conflicts with DROP. If explicit
* "DELETE FROM pg_class" is in progress, we'll wait for it like we would an
* update.
* *
* Note that the tuple updated here had better not come directly from the * Readers of inplace-updated fields expect changes to those fields are
* syscache if the relation has a toast relation as this tuple could * durable. For example, vac_truncate_clog() reads datfrozenxid from
* include toast values that have been expanded, causing a failure here. * pg_database tuples via catalog snapshots. A future snapshot must not
* return a lower datfrozenxid for the same database OID (lower in the
* FullTransactionIdPrecedes() sense). We achieve that since no update of a
* tuple can start while we hold a lock on its buffer. In cases like
* BEGIN;GRANT;CREATE INDEX;COMMIT we're inplace-updating a tuple visible only
* to this transaction. ROLLBACK then is one case where it's okay to lose
* inplace updates. (Restoring relhasindex=false on ROLLBACK is fine, since
* any concurrent CREATE INDEX would have blocked, then inplace-updated the
* committed tuple.)
*
* In principle, we could avoid waiting by overwriting every tuple in the
* updated tuple chain. Reader expectations permit updating a tuple only if
* it's aborted, is the tail of the chain, or we already updated the tuple
* referenced in its t_ctid. Hence, we would need to overwrite the tuples in
* order from tail to head. That would imply either (a) mutating all tuples
* in one critical section or (b) accepting a chance of partial completion.
* Partial completion of a relfrozenxid update would have the weird
* consequence that the table's next VACUUM could see the table's relfrozenxid
* move forward between vacuum_get_cutoffs() and finishing.
*/
bool
heap_inplace_lock(Relation relation,
HeapTuple oldtup_ptr, Buffer buffer,
void (*release_callback) (void *), void *arg)
{
HeapTupleData oldtup = *oldtup_ptr; /* minimize diff vs. heap_update() */
TM_Result result;
bool ret;
#ifdef USE_ASSERT_CHECKING
if (RelationGetRelid(relation) == RelationRelationId)
check_inplace_rel_lock(oldtup_ptr);
#endif
Assert(BufferIsValid(buffer));
LockTuple(relation, &oldtup.t_self, InplaceUpdateTupleLock);
LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);
/*----------
* Interpret HeapTupleSatisfiesUpdate() like heap_update() does, except:
*
* - wait unconditionally
* - already locked tuple above, since inplace needs that unconditionally
* - don't recheck header after wait: simpler to defer to next iteration
* - don't try to continue even if the updater aborts: likewise
* - no crosscheck
*/
result = HeapTupleSatisfiesUpdate(&oldtup, GetCurrentCommandId(false),
buffer);
if (result == TM_Invisible)
{
/* no known way this can happen */
ereport(ERROR,
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
errmsg_internal("attempted to overwrite invisible tuple")));
}
else if (result == TM_SelfModified)
{
/*
* CREATE INDEX might reach this if an expression is silly enough to
* call e.g. SELECT ... FROM pg_class FOR SHARE. C code of other SQL
* statements might get here after a heap_update() of the same row, in
* the absence of an intervening CommandCounterIncrement().
*/
ereport(ERROR,
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
errmsg("tuple to be updated was already modified by an operation triggered by the current command")));
}
else if (result == TM_BeingModified)
{
TransactionId xwait;
uint16 infomask;
xwait = HeapTupleHeaderGetRawXmax(oldtup.t_data);
infomask = oldtup.t_data->t_infomask;
if (infomask & HEAP_XMAX_IS_MULTI)
{
LockTupleMode lockmode = LockTupleNoKeyExclusive;
MultiXactStatus mxact_status = MultiXactStatusNoKeyUpdate;
int remain;
if (DoesMultiXactIdConflict((MultiXactId) xwait, infomask,
lockmode, NULL))
{
LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
release_callback(arg);
ret = false;
MultiXactIdWait((MultiXactId) xwait, mxact_status, infomask,
relation, &oldtup.t_self, XLTW_Update,
&remain);
}
else
ret = true;
}
else if (TransactionIdIsCurrentTransactionId(xwait))
ret = true;
else if (HEAP_XMAX_IS_KEYSHR_LOCKED(infomask))
ret = true;
else
{
LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
release_callback(arg);
ret = false;
XactLockTableWait(xwait, relation, &oldtup.t_self,
XLTW_Update);
}
}
else
{
ret = (result == TM_Ok);
if (!ret)
{
LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
release_callback(arg);
}
}
/*
* GetCatalogSnapshot() relies on invalidation messages to know when to
* take a new snapshot. COMMIT of xwait is responsible for sending the
* invalidation. We're not acquiring heavyweight locks sufficient to
* block if not yet sent, so we must take a new snapshot to ensure a later
* attempt has a fair chance. While we don't need this if xwait aborted,
* don't bother optimizing that.
*/
if (!ret)
{
UnlockTuple(relation, &oldtup.t_self, InplaceUpdateTupleLock);
InvalidateCatalogSnapshot();
}
return ret;
}
/*
* heap_inplace_update_and_unlock - core of systable_inplace_update_finish
*
* The tuple cannot change size, and therefore its header fields and null
* bitmap (if any) don't change either.
*
* Since we hold LOCKTAG_TUPLE, no updater has a local copy of this tuple.
*/
void
heap_inplace_update_and_unlock(Relation relation,
HeapTuple oldtup, HeapTuple tuple,
Buffer buffer)
{
HeapTupleHeader htup = oldtup->t_data;
uint32 oldlen;
uint32 newlen;
Assert(ItemPointerEquals(&oldtup->t_self, &tuple->t_self));
oldlen = oldtup->t_len - htup->t_hoff;
newlen = tuple->t_len - tuple->t_data->t_hoff;
if (oldlen != newlen || htup->t_hoff != tuple->t_data->t_hoff)
elog(ERROR, "wrong tuple length");
/* NO EREPORT(ERROR) from here till changes are logged */
START_CRIT_SECTION();
memcpy((char *) htup + htup->t_hoff,
(char *) tuple->t_data + tuple->t_data->t_hoff,
newlen);
/*----------
* XXX A crash here can allow datfrozenxid() to get ahead of relfrozenxid:
*
* ["D" is a VACUUM (ONLY_DATABASE_STATS)]
* ["R" is a VACUUM tbl]
* D: vac_update_datfrozenid() -> systable_beginscan(pg_class)
* D: systable_getnext() returns pg_class tuple of tbl
* R: memcpy() into pg_class tuple of tbl
* D: raise pg_database.datfrozenxid, XLogInsert(), finish
* [crash]
* [recovery restores datfrozenxid w/o relfrozenxid]
*/
MarkBufferDirty(buffer);
/* XLOG stuff */
if (RelationNeedsWAL(relation))
{
xl_heap_inplace xlrec;
XLogRecPtr recptr;
xlrec.offnum = ItemPointerGetOffsetNumber(&tuple->t_self);
XLogBeginInsert();
XLogRegisterData((char *) &xlrec, SizeOfHeapInplace);
XLogRegisterBuffer(0, buffer, REGBUF_STANDARD);
XLogRegisterBufData(0, (char *) htup + htup->t_hoff, newlen);
/* inplace updates aren't decoded atm, don't log the origin */
recptr = XLogInsert(RM_HEAP_ID, XLOG_HEAP_INPLACE);
PageSetLSN(BufferGetPage(buffer), recptr);
}
END_CRIT_SECTION();
heap_inplace_unlock(relation, oldtup, buffer);
/*
* Send out shared cache inval if necessary. Note that because we only
* pass the new version of the tuple, this mustn't be used for any
* operations that could change catcache lookup keys. But we aren't
* bothering with index updates either, so that's true a fortiori.
*
* XXX ROLLBACK discards the invalidation. See test inplace-inval.spec.
*/
if (!IsBootstrapProcessingMode())
CacheInvalidateHeapTuple(relation, tuple, NULL);
}
/*
* heap_inplace_unlock - reverse of heap_inplace_lock
*/
void
heap_inplace_unlock(Relation relation,
HeapTuple oldtup, Buffer buffer)
{
LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
UnlockTuple(relation, &oldtup->t_self, InplaceUpdateTupleLock);
}
/*
* heap_inplace_update - deprecated
*
* This exists only to keep modules working in back branches. Affected
* modules should migrate to systable_inplace_update_begin().
*/ */
void void
heap_inplace_update(Relation relation, HeapTuple tuple) heap_inplace_update(Relation relation, HeapTuple tuple)
@ -6081,7 +6453,6 @@ heap_inplace_update(Relation relation, HeapTuple tuple)
(errcode(ERRCODE_INVALID_TRANSACTION_STATE), (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
errmsg("cannot update tuples during a parallel operation"))); errmsg("cannot update tuples during a parallel operation")));
INJECTION_POINT("inplace-before-pin");
buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(&(tuple->t_self))); buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(&(tuple->t_self)));
LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE); LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);
page = (Page) BufferGetPage(buffer); page = (Page) BufferGetPage(buffer);

View File

@ -325,6 +325,8 @@ heap_page_prune_opt(Relation relation, Buffer buffer)
* *
* cutoffs contains the freeze cutoffs, established by VACUUM at the beginning * cutoffs contains the freeze cutoffs, established by VACUUM at the beginning
* of vacuuming the relation. Required if HEAP_PRUNE_FREEZE option is set. * of vacuuming the relation. Required if HEAP_PRUNE_FREEZE option is set.
* cutoffs->OldestXmin is also used to determine if dead tuples are
* HEAPTUPLE_RECENTLY_DEAD or HEAPTUPLE_DEAD.
* *
* presult contains output parameters needed by callers, such as the number of * presult contains output parameters needed by callers, such as the number of
* tuples removed and the offsets of dead items on the page after pruning. * tuples removed and the offsets of dead items on the page after pruning.
@ -922,8 +924,27 @@ heap_prune_satisfies_vacuum(PruneState *prstate, HeapTuple tup, Buffer buffer)
if (res != HEAPTUPLE_RECENTLY_DEAD) if (res != HEAPTUPLE_RECENTLY_DEAD)
return res; return res;
/*
* For VACUUM, we must be sure to prune tuples with xmax older than
* OldestXmin -- a visibility cutoff determined at the beginning of
* vacuuming the relation. OldestXmin is used for freezing determination
* and we cannot freeze dead tuples' xmaxes.
*/
if (prstate->cutoffs &&
TransactionIdIsValid(prstate->cutoffs->OldestXmin) &&
NormalTransactionIdPrecedes(dead_after, prstate->cutoffs->OldestXmin))
return HEAPTUPLE_DEAD;
/*
* Determine whether or not the tuple is considered dead when compared
* with the provided GlobalVisState. On-access pruning does not provide
* VacuumCutoffs. And for vacuum, even if the tuple's xmax is not older
* than OldestXmin, GlobalVisTestIsRemovableXid() could find the row dead
* if the GlobalVisState has been updated since the beginning of vacuuming
* the relation.
*/
if (GlobalVisTestIsRemovableXid(prstate->vistest, dead_after)) if (GlobalVisTestIsRemovableXid(prstate->vistest, dead_after))
res = HEAPTUPLE_DEAD; return HEAPTUPLE_DEAD;
return res; return res;
} }

View File

@ -438,13 +438,13 @@ heap_vacuum_rel(Relation rel, VacuumParams *params,
* as an upper bound on the XIDs stored in the pages we'll actually scan * as an upper bound on the XIDs stored in the pages we'll actually scan
* (NewRelfrozenXid tracking must never be allowed to miss unfrozen XIDs). * (NewRelfrozenXid tracking must never be allowed to miss unfrozen XIDs).
* *
* Next acquire vistest, a related cutoff that's used in pruning. We * Next acquire vistest, a related cutoff that's used in pruning. We use
* expect vistest will always make heap_page_prune_and_freeze() remove any * vistest in combination with OldestXmin to ensure that
* deleted tuple whose xmax is < OldestXmin. lazy_scan_prune must never * heap_page_prune_and_freeze() always removes any deleted tuple whose
* become confused about whether a tuple should be frozen or removed. (In * xmax is < OldestXmin. lazy_scan_prune must never become confused about
* the future we might want to teach lazy_scan_prune to recompute vistest * whether a tuple should be frozen or removed. (In the future we might
* from time to time, to increase the number of dead tuples it can prune * want to teach lazy_scan_prune to recompute vistest from time to time,
* away.) * to increase the number of dead tuples it can prune away.)
*/ */
vacrel->aggressive = vacuum_get_cutoffs(rel, params, &vacrel->cutoffs); vacrel->aggressive = vacuum_get_cutoffs(rel, params, &vacrel->cutoffs);
vacrel->rel_pages = orig_rel_pages = RelationGetNumberOfBlocks(rel); vacrel->rel_pages = orig_rel_pages = RelationGetNumberOfBlocks(rel);

View File

@ -20,6 +20,7 @@
#include "postgres.h" #include "postgres.h"
#include "access/genam.h" #include "access/genam.h"
#include "access/heapam.h"
#include "access/relscan.h" #include "access/relscan.h"
#include "access/tableam.h" #include "access/tableam.h"
#include "access/transam.h" #include "access/transam.h"
@ -29,6 +30,7 @@
#include "storage/bufmgr.h" #include "storage/bufmgr.h"
#include "storage/procarray.h" #include "storage/procarray.h"
#include "utils/acl.h" #include "utils/acl.h"
#include "utils/injection_point.h"
#include "utils/lsyscache.h" #include "utils/lsyscache.h"
#include "utils/rel.h" #include "utils/rel.h"
#include "utils/rls.h" #include "utils/rls.h"
@ -700,6 +702,14 @@ systable_beginscan_ordered(Relation heapRelation,
index_rescan(sysscan->iscan, key, nkeys, NULL, 0); index_rescan(sysscan->iscan, key, nkeys, NULL, 0);
sysscan->scan = NULL; sysscan->scan = NULL;
/*
* If CheckXidAlive is set then set a flag to indicate that system table
* scan is in-progress. See detailed comments in xact.c where these
* variables are declared.
*/
if (TransactionIdIsValid(CheckXidAlive))
bsysscan = true;
return sysscan; return sysscan;
} }
@ -744,5 +754,150 @@ systable_endscan_ordered(SysScanDesc sysscan)
index_endscan(sysscan->iscan); index_endscan(sysscan->iscan);
if (sysscan->snapshot) if (sysscan->snapshot)
UnregisterSnapshot(sysscan->snapshot); UnregisterSnapshot(sysscan->snapshot);
/*
* Reset the bsysscan flag at the end of the systable scan. See detailed
* comments in xact.c where these variables are declared.
*/
if (TransactionIdIsValid(CheckXidAlive))
bsysscan = false;
pfree(sysscan); pfree(sysscan);
} }
/*
* systable_inplace_update_begin --- update a row "in place" (overwrite it)
*
* Overwriting violates both MVCC and transactional safety, so the uses of
* this function in Postgres are extremely limited. Nonetheless we find some
* places to use it. See README.tuplock section "Locking to write
* inplace-updated tables" and later sections for expectations of readers and
* writers of a table that gets inplace updates. Standard flow:
*
* ... [any slow preparation not requiring oldtup] ...
* systable_inplace_update_begin([...], &tup, &inplace_state);
* if (!HeapTupleIsValid(tup))
* elog(ERROR, [...]);
* ... [buffer is exclusive-locked; mutate "tup"] ...
* if (dirty)
* systable_inplace_update_finish(inplace_state, tup);
* else
* systable_inplace_update_cancel(inplace_state);
*
* The first several params duplicate the systable_beginscan() param list.
* "oldtupcopy" is an output parameter, assigned NULL if the key ceases to
* find a live tuple. (In PROC_IN_VACUUM, that is a low-probability transient
* condition.) If "oldtupcopy" gets non-NULL, you must pass output parameter
* "state" to systable_inplace_update_finish() or
* systable_inplace_update_cancel().
*/
void
systable_inplace_update_begin(Relation relation,
Oid indexId,
bool indexOK,
Snapshot snapshot,
int nkeys, const ScanKeyData *key,
HeapTuple *oldtupcopy,
void **state)
{
ScanKey mutable_key = palloc(sizeof(ScanKeyData) * nkeys);
int retries = 0;
SysScanDesc scan;
HeapTuple oldtup;
BufferHeapTupleTableSlot *bslot;
/*
* For now, we don't allow parallel updates. Unlike a regular update,
* this should never create a combo CID, so it might be possible to relax
* this restriction, but not without more thought and testing. It's not
* clear that it would be useful, anyway.
*/
if (IsInParallelMode())
ereport(ERROR,
(errcode(ERRCODE_INVALID_TRANSACTION_STATE),
errmsg("cannot update tuples during a parallel operation")));
/*
* Accept a snapshot argument, for symmetry, but this function advances
* its snapshot as needed to reach the tail of the updated tuple chain.
*/
Assert(snapshot == NULL);
Assert(IsInplaceUpdateRelation(relation) || !IsSystemRelation(relation));
/* Loop for an exclusive-locked buffer of a non-updated tuple. */
do
{
TupleTableSlot *slot;
CHECK_FOR_INTERRUPTS();
/*
* Processes issuing heap_update (e.g. GRANT) at maximum speed could
* drive us to this error. A hostile table owner has stronger ways to
* damage their own table, so that's minor.
*/
if (retries++ > 10000)
elog(ERROR, "giving up after too many tries to overwrite row");
memcpy(mutable_key, key, sizeof(ScanKeyData) * nkeys);
INJECTION_POINT("inplace-before-pin");
scan = systable_beginscan(relation, indexId, indexOK, snapshot,
nkeys, mutable_key);
oldtup = systable_getnext(scan);
if (!HeapTupleIsValid(oldtup))
{
systable_endscan(scan);
*oldtupcopy = NULL;
return;
}
slot = scan->slot;
Assert(TTS_IS_BUFFERTUPLE(slot));
bslot = (BufferHeapTupleTableSlot *) slot;
} while (!heap_inplace_lock(scan->heap_rel,
bslot->base.tuple, bslot->buffer,
(void (*) (void *)) systable_endscan, scan));
*oldtupcopy = heap_copytuple(oldtup);
*state = scan;
}
/*
* systable_inplace_update_finish --- second phase of inplace update
*
* The tuple cannot change size, and therefore its header fields and null
* bitmap (if any) don't change either.
*/
void
systable_inplace_update_finish(void *state, HeapTuple tuple)
{
SysScanDesc scan = (SysScanDesc) state;
Relation relation = scan->heap_rel;
TupleTableSlot *slot = scan->slot;
BufferHeapTupleTableSlot *bslot = (BufferHeapTupleTableSlot *) slot;
HeapTuple oldtup = bslot->base.tuple;
Buffer buffer = bslot->buffer;
heap_inplace_update_and_unlock(relation, oldtup, tuple, buffer);
systable_endscan(scan);
}
/*
* systable_inplace_update_cancel --- abandon inplace update
*
* This is an alternative to making a no-op update.
*/
void
systable_inplace_update_cancel(void *state)
{
SysScanDesc scan = (SysScanDesc) state;
Relation relation = scan->heap_rel;
TupleTableSlot *slot = scan->slot;
BufferHeapTupleTableSlot *bslot = (BufferHeapTupleTableSlot *) slot;
HeapTuple oldtup = bslot->base.tuple;
Buffer buffer = bslot->buffer;
heap_inplace_unlock(relation, oldtup, buffer);
systable_endscan(scan);
}

View File

@ -585,7 +585,10 @@ btparallelrescan(IndexScanDesc scan)
* or _bt_parallel_done(). * or _bt_parallel_done().
* *
* The return value is true if we successfully seized the scan and false * The return value is true if we successfully seized the scan and false
* if we did not. The latter case occurs if no pages remain. * if we did not. The latter case occurs when no pages remain, or when
* another primitive index scan is scheduled that caller's backend cannot
* start just yet (only backends that call from _bt_first are capable of
* starting primitive index scans, which they indicate by passing first=true).
* *
* If the return value is true, *pageno returns the next or current page * If the return value is true, *pageno returns the next or current page
* of the scan (depending on the scan direction). An invalid block number * of the scan (depending on the scan direction). An invalid block number
@ -596,10 +599,6 @@ btparallelrescan(IndexScanDesc scan)
* scan will return false. * scan will return false.
* *
* Callers should ignore the value of pageno if the return value is false. * Callers should ignore the value of pageno if the return value is false.
*
* Callers that are in a position to start a new primitive index scan must
* pass first=true (all other callers pass first=false). We just return false
* for first=false callers that require another primitive index scan.
*/ */
bool bool
_bt_parallel_seize(IndexScanDesc scan, BlockNumber *pageno, bool first) _bt_parallel_seize(IndexScanDesc scan, BlockNumber *pageno, bool first)
@ -616,13 +615,7 @@ _bt_parallel_seize(IndexScanDesc scan, BlockNumber *pageno, bool first)
{ {
/* /*
* Initialize array related state when called from _bt_first, assuming * Initialize array related state when called from _bt_first, assuming
* that this will either be the first primitive index scan for the * that this will be the first primitive index scan for the scan
* scan, or a previous explicitly scheduled primitive scan.
*
* Note: so->needPrimScan is only set when a scheduled primitive index
* scan is set to be performed in caller's worker process. It should
* not be set here by us for the first primitive scan, nor should we
* ever set it for a parallel scan that has no array keys.
*/ */
so->needPrimScan = false; so->needPrimScan = false;
so->scanBehind = false; so->scanBehind = false;
@ -630,8 +623,8 @@ _bt_parallel_seize(IndexScanDesc scan, BlockNumber *pageno, bool first)
else else
{ {
/* /*
* Don't attempt to seize the scan when backend requires another * Don't attempt to seize the scan when it requires another primitive
* primitive index scan unless we're in a position to start it now * index scan, since caller's backend cannot start it right now
*/ */
if (so->needPrimScan) if (so->needPrimScan)
return false; return false;
@ -653,12 +646,9 @@ _bt_parallel_seize(IndexScanDesc scan, BlockNumber *pageno, bool first)
{ {
Assert(so->numArrayKeys); Assert(so->numArrayKeys);
/*
* If we can start another primitive scan right away, do so.
* Otherwise just wait.
*/
if (first) if (first)
{ {
/* Can start scheduled primitive scan right away, so do so */
btscan->btps_pageStatus = BTPARALLEL_ADVANCING; btscan->btps_pageStatus = BTPARALLEL_ADVANCING;
for (int i = 0; i < so->numArrayKeys; i++) for (int i = 0; i < so->numArrayKeys; i++)
{ {
@ -668,11 +658,25 @@ _bt_parallel_seize(IndexScanDesc scan, BlockNumber *pageno, bool first)
array->cur_elem = btscan->btps_arrElems[i]; array->cur_elem = btscan->btps_arrElems[i];
skey->sk_argument = array->elem_values[array->cur_elem]; skey->sk_argument = array->elem_values[array->cur_elem];
} }
so->needPrimScan = true;
so->scanBehind = false;
*pageno = InvalidBlockNumber; *pageno = InvalidBlockNumber;
exit_loop = true; exit_loop = true;
} }
else
{
/*
* Don't attempt to seize the scan when it requires another
* primitive index scan, since caller's backend cannot start
* it right now
*/
status = false;
}
/*
* Either way, update backend local state to indicate that a
* pending primitive scan is required
*/
so->needPrimScan = true;
so->scanBehind = false;
} }
else if (btscan->btps_pageStatus != BTPARALLEL_ADVANCING) else if (btscan->btps_pageStatus != BTPARALLEL_ADVANCING)
{ {
@ -731,6 +735,7 @@ _bt_parallel_release(IndexScanDesc scan, BlockNumber scan_page)
void void
_bt_parallel_done(IndexScanDesc scan) _bt_parallel_done(IndexScanDesc scan)
{ {
BTScanOpaque so = (BTScanOpaque) scan->opaque;
ParallelIndexScanDesc parallel_scan = scan->parallel_scan; ParallelIndexScanDesc parallel_scan = scan->parallel_scan;
BTParallelScanDesc btscan; BTParallelScanDesc btscan;
bool status_changed = false; bool status_changed = false;
@ -739,6 +744,13 @@ _bt_parallel_done(IndexScanDesc scan)
if (parallel_scan == NULL) if (parallel_scan == NULL)
return; return;
/*
* Should not mark parallel scan done when there's still a pending
* primitive index scan
*/
if (so->needPrimScan)
return;
btscan = (BTParallelScanDesc) OffsetToPointer((void *) parallel_scan, btscan = (BTParallelScanDesc) OffsetToPointer((void *) parallel_scan,
parallel_scan->ps_offset); parallel_scan->ps_offset);
@ -747,6 +759,7 @@ _bt_parallel_done(IndexScanDesc scan)
* already * already
*/ */
SpinLockAcquire(&btscan->btps_mutex); SpinLockAcquire(&btscan->btps_mutex);
Assert(btscan->btps_pageStatus != BTPARALLEL_NEED_PRIMSCAN);
if (btscan->btps_pageStatus != BTPARALLEL_DONE) if (btscan->btps_pageStatus != BTPARALLEL_DONE)
{ {
btscan->btps_pageStatus = BTPARALLEL_DONE; btscan->btps_pageStatus = BTPARALLEL_DONE;

View File

@ -893,8 +893,6 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
Assert(!BTScanPosIsValid(so->currPos)); Assert(!BTScanPosIsValid(so->currPos));
pgstat_count_index_scan(rel);
/* /*
* Examine the scan keys and eliminate any redundant keys; also mark the * Examine the scan keys and eliminate any redundant keys; also mark the
* keys that must be matched to continue the scan. * keys that must be matched to continue the scan.
@ -957,6 +955,12 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
_bt_start_array_keys(scan, dir); _bt_start_array_keys(scan, dir);
} }
/*
* Count an indexscan for stats, now that we know that we'll call
* _bt_search/_bt_endpoint below
*/
pgstat_count_index_scan(rel);
/*---------- /*----------
* Examine the scan keys to discover where we need to start the scan. * Examine the scan keys to discover where we need to start the scan.
* *
@ -1624,6 +1628,7 @@ _bt_readpage(IndexScanDesc scan, ScanDirection dir, OffsetNumber offnum,
* corresponding need for the left-link, since splits always go right. * corresponding need for the left-link, since splits always go right.
*/ */
so->currPos.nextPage = opaque->btpo_next; so->currPos.nextPage = opaque->btpo_next;
so->currPos.dir = dir;
/* initialize tuple workspace to empty */ /* initialize tuple workspace to empty */
so->currPos.nextTupleOffset = 0; so->currPos.nextTupleOffset = 0;
@ -2079,16 +2084,24 @@ _bt_steppage(IndexScanDesc scan, ScanDirection dir)
* In effect, btrestpos leaves advancing the arrays up to the first * In effect, btrestpos leaves advancing the arrays up to the first
* _bt_readpage call (that takes place after it has restored markPos). * _bt_readpage call (that takes place after it has restored markPos).
*/ */
Assert(so->markPos.dir == dir);
if (so->needPrimScan) if (so->needPrimScan)
{ {
if (ScanDirectionIsForward(dir)) if (ScanDirectionIsForward(so->currPos.dir))
so->markPos.moreRight = true; so->markPos.moreRight = true;
else else
so->markPos.moreLeft = true; so->markPos.moreLeft = true;
} }
} }
/*
* Cancel primitive index scans that were scheduled when the call to
* _bt_readpage for currPos happened to use the opposite direction to the
* one that we're stepping in now. (It's okay to leave the scan's array
* keys as-is, since the next _bt_readpage will advance them.)
*/
if (so->currPos.dir != dir)
so->needPrimScan = false;
if (ScanDirectionIsForward(dir)) if (ScanDirectionIsForward(dir))
{ {
/* Walk right to the next page with data */ /* Walk right to the next page with data */
@ -2649,7 +2662,6 @@ _bt_endpoint(IndexScanDesc scan, ScanDirection dir)
static inline void static inline void
_bt_initialize_more_data(BTScanOpaque so, ScanDirection dir) _bt_initialize_more_data(BTScanOpaque so, ScanDirection dir)
{ {
so->currPos.dir = dir;
if (so->needPrimScan) if (so->needPrimScan)
{ {
Assert(so->numArrayKeys); Assert(so->numArrayKeys);

View File

@ -2426,8 +2426,10 @@ new_prim_scan:
/* /*
* End this primitive index scan, but schedule another. * End this primitive index scan, but schedule another.
* *
* Note: If the scan direction happens to change, this scheduled primitive * Note: We make a soft assumption that the current scan direction will
* index scan won't go ahead after all. * also be used within _bt_next, when it is asked to step off this page.
* It is up to _bt_next to cancel this scheduled primitive index scan
* whenever it steps to a page in the direction opposite currPos.dir.
*/ */
pstate->continuescan = false; /* Tell _bt_readpage we're done... */ pstate->continuescan = false; /* Tell _bt_readpage we're done... */
so->needPrimScan = true; /* ...but call _bt_first again */ so->needPrimScan = true; /* ...but call _bt_first again */
@ -4091,7 +4093,7 @@ _bt_checkkeys_look_ahead(IndexScanDesc scan, BTReadPageState *pstate,
*/ */
if (!pstate->targetdistance) if (!pstate->targetdistance)
pstate->targetdistance = LOOK_AHEAD_DEFAULT_DISTANCE; pstate->targetdistance = LOOK_AHEAD_DEFAULT_DISTANCE;
else else if (pstate->targetdistance < MaxIndexTuplesPerPage / 2)
pstate->targetdistance *= 2; pstate->targetdistance *= 2;
/* Don't read past the end (or before the start) of the page, though */ /* Don't read past the end (or before the start) of the page, though */

View File

@ -33,6 +33,27 @@ const struct config_enum_entry wal_level_options[] = {
{NULL, 0, false} {NULL, 0, false}
}; };
/*
* Find a string representation for wal_level
*/
static const char *
get_wal_level_string(int wal_level)
{
const struct config_enum_entry *entry;
const char *wal_level_str = "?";
for (entry = wal_level_options; entry->name; entry++)
{
if (entry->val == wal_level)
{
wal_level_str = entry->name;
break;
}
}
return wal_level_str;
}
void void
xlog_desc(StringInfo buf, XLogReaderState *record) xlog_desc(StringInfo buf, XLogReaderState *record)
{ {
@ -45,7 +66,7 @@ xlog_desc(StringInfo buf, XLogReaderState *record)
CheckPoint *checkpoint = (CheckPoint *) rec; CheckPoint *checkpoint = (CheckPoint *) rec;
appendStringInfo(buf, "redo %X/%X; " appendStringInfo(buf, "redo %X/%X; "
"tli %u; prev tli %u; fpw %s; xid %u:%u; oid %u; multi %u; offset %u; " "tli %u; prev tli %u; fpw %s; wal_level %s; xid %u:%u; oid %u; multi %u; offset %u; "
"oldest xid %u in DB %u; oldest multi %u in DB %u; " "oldest xid %u in DB %u; oldest multi %u in DB %u; "
"oldest/newest commit timestamp xid: %u/%u; " "oldest/newest commit timestamp xid: %u/%u; "
"oldest running xid %u; %s", "oldest running xid %u; %s",
@ -53,6 +74,7 @@ xlog_desc(StringInfo buf, XLogReaderState *record)
checkpoint->ThisTimeLineID, checkpoint->ThisTimeLineID,
checkpoint->PrevTimeLineID, checkpoint->PrevTimeLineID,
checkpoint->fullPageWrites ? "true" : "false", checkpoint->fullPageWrites ? "true" : "false",
get_wal_level_string(checkpoint->wal_level),
EpochFromFullTransactionId(checkpoint->nextXid), EpochFromFullTransactionId(checkpoint->nextXid),
XidFromFullTransactionId(checkpoint->nextXid), XidFromFullTransactionId(checkpoint->nextXid),
checkpoint->nextOid, checkpoint->nextOid,
@ -95,20 +117,9 @@ xlog_desc(StringInfo buf, XLogReaderState *record)
{ {
xl_parameter_change xlrec; xl_parameter_change xlrec;
const char *wal_level_str; const char *wal_level_str;
const struct config_enum_entry *entry;
memcpy(&xlrec, rec, sizeof(xl_parameter_change)); memcpy(&xlrec, rec, sizeof(xl_parameter_change));
wal_level_str = get_wal_level_string(xlrec.wal_level);
/* Find a string representation for wal_level */
wal_level_str = "?";
for (entry = wal_level_options; entry->name; entry++)
{
if (entry->val == xlrec.wal_level)
{
wal_level_str = entry->name;
break;
}
}
appendStringInfo(buf, "max_connections=%d max_worker_processes=%d " appendStringInfo(buf, "max_connections=%d max_worker_processes=%d "
"max_wal_senders=%d max_prepared_xacts=%d " "max_wal_senders=%d max_prepared_xacts=%d "
@ -135,9 +146,10 @@ xlog_desc(StringInfo buf, XLogReaderState *record)
xl_end_of_recovery xlrec; xl_end_of_recovery xlrec;
memcpy(&xlrec, rec, sizeof(xl_end_of_recovery)); memcpy(&xlrec, rec, sizeof(xl_end_of_recovery));
appendStringInfo(buf, "tli %u; prev tli %u; time %s", appendStringInfo(buf, "tli %u; prev tli %u; time %s; wal_level %s",
xlrec.ThisTimeLineID, xlrec.PrevTimeLineID, xlrec.ThisTimeLineID, xlrec.PrevTimeLineID,
timestamptz_to_str(xlrec.end_time)); timestamptz_to_str(xlrec.end_time),
get_wal_level_string(xlrec.wal_level));
} }
else if (info == XLOG_OVERWRITE_CONTRECORD) else if (info == XLOG_OVERWRITE_CONTRECORD)
{ {
@ -150,7 +162,10 @@ xlog_desc(StringInfo buf, XLogReaderState *record)
} }
else if (info == XLOG_CHECKPOINT_REDO) else if (info == XLOG_CHECKPOINT_REDO)
{ {
/* No details to write out */ int wal_level;
memcpy(&wal_level, rec, sizeof(int));
appendStringInfo(buf, "wal_level %s", get_wal_level_string(wal_level));
} }
} }

Some files were not shown because too many files have changed in this diff Show More