This marker could break translated strings if used, so let's remove it
and encourage instead the use of PRIu64, something that xgettext is able
to digest.
This marker has been introduced in b139bd3b6e, down to v19 that has
not been officially released yet, so a removal is still possible without
breaking the ABI requirements.
Discussion: https://postgr.es/m/aqeO1OU7uZjhioAq@alvherre.pgsql
Backpatch-through: 19
The OID8_FORMAT marker could break translated messages, as proven by
ceae3099da, so let's remove it while we can instead of encouraging its
use.
An alternative solution that would allow OID8_FORMAT is to save the
result into an intermediate string, itself used in the translated
strings, but per discussion this is not an appealing long-term approach.
Note that this commit partially reworks 072d4c4240.
Per discussion with Peter Eisentraut, Álvaro Herrera and Tom Lane.
Discussion: https://postgr.es/m/aqeO1OU7uZjhioAq@alvherre.pgsql
toast_save_datum() ended with two copies of the same three steps, one
each external on-disk TOAST pointer: allocate a datum, set its tag, then
copy the contents from a varatt_external_oid or a varatt_external_oid8
into it.
These steps are moved into a new helper function, toast_pointer_build(),
which takes the tag and a pointer to the struct and derives everything
else from the tag. For now, only two varatt_external_* exist for
external on-disk TOAST pointers. Some more are under discussion, where
this refactoring shows some benefits in the shape of less duplication.
There should be no behavior change.
Author: Nikhil Kumar Veldanda <veldanda.nikhilkumar17@gmail.com>
Discussion: https://postgr.es/m/CAFAfj_FeJQZrKyVn7ur0aJx8iz8SR14NheVJNyc8JNoqtMX+og@mail.gmail.com
_reconnectToDB() failed to consider the possibility that it could
be called without any restrict_key set. This is reachable while
generating the "restore.sql" file in tar dump mode, which nobody
noticed because that file is mostly unused (and nothing really
bad happens anyway unless you specified --inserts mode). But
I wonder if there are other code paths that reach the issue.
Bug: #19718
Reported-by: Pavel Kopylov <pkopylov@cloudlinux.com>
Author: Pavel Kopylov <pkopylov@cloudlinux.com>
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/19718-7e945d0ff9b5a589@postgresql.org
Backpatch-through: 14
When ANALYZE imports statistics from a remote server, it fetched/stored
the statistics while still running as the user executing ANALYZE, not as
the foreign table's owner. This is inconsistent with the sampling path,
and it causes a security issue: a role that owns a foreign table but has
no access to the underlying remote data (eg, no access privileges on the
remote server) could obtain that data by having a privileged user run
ANALYZE on the table; the imported statistics like most_common_vals then
expose sampled values from the remote data, as shown in the reproducer
on the discussion thread.
To fix, switch to the foreign table owner's userid in analyze_rel()
before calling the ImportForeignStatistics() routine, mirroring the
identity used by the sampling path. This not only makes the privilege
handling consistent between the sampling/import paths, but also prevents
statistics import from disclosing data the table owner couldn't
otherwise obtain.
Oversight in commit 28972b6fc.
Reported-by: Fujii Masao <masao.fujii@gmail.com>
Reported-by: Osama Abdul Qader <osamaabdulqader.cs@gmail.com>
Reported-by: Noah Misch <noah@leadboat.com>
Author: Noah Misch <noah@leadboat.com>
Reviewed-by: Matheus Alcantara <matheusssilv97@gmail.com>
Reviewed-by: Etsuro Fujita <etsuro.fujita@gmail.com>
Discussion: https://postgr.es/m/CAPmGK16jVk+i2KMkkgR9ajoPdaUAinvcspkk5Bc6urbo2xYTMQ@mail.gmail.com
Backpatch-through: 19
ri_FastPathCheck() invokes two functions on the FK values: the
equality operator's function, via the ScanKey the index AM evaluates,
and, when the FK column's type differs from the PK column's, the
implicit cast function. The SPI path gets EXECUTE on both checked by
ExecInitFunc() when it initializes the generated query, as the
referenced table's owner, but the fast path performed neither check.
Add ri_CheckFunctionPermissions() and call it once the fast-path
metadata is populated, under the switch to the referenced table's
owner, so the checks happen at the same point as the existing relation
permission check. Add a regression test for each function, reaching
the fast path through per-row validation of a new constraint, and
repeat each against a partitioned referenced table, which takes the
SPI path, to show that the two behave identically.
Reported-by: Nikolay Samokhvalov <nik@postgres.ai> (offlist)
Reviewed-by: Matheus Alcantara <matheusssilv97@gmail.com>
Discussion: https://postgr.es/m/CA+HiwqGH+b7sXmsH8sT18diujbheSObWs0gWXqLZqRccMKvZAA@mail.gmail.com
Backpatch-through: 19
pg_restore_attribute_stats() rejected range_length_histogram,
range_empty_frac and range_bounds_histogram for a column whose type is a
domain over a range or a multirange type. The same issue existed for
most_common_elems and elem_count_histogram for a domain over tsvector.
pg_restore_extended_stats() had the same set of problems for expressions
whose type is a domain over a range, a multirange type, or tsvector.
ANALYZE is able to generate such stats, incorporating the knowledge to
handle domains in the in-core typanalyze callbacks.
This problem is resolved by being more aggressive with the fetch of the
base type of a domain in the early phases of restore for attribute and
extended stats (special tip to Jian He for pointing out the unnecessary
typcache lookups), reflecting on the surrounding helper routines shared
by both code paths. The fix for v18 is local to attribute_stats.c, as
only attribute stats need to be touched.
Tests are included in a fashion consistent with the surroundings. The
consequence of this issue was the rejection of stats that ANALYZE was
able to build, which was not critical but annoying as it would lead to a
gap in the stats restored.
Reported-by: Qifan Liu <imchifan@163.com>
Author: Michael Paquier <michael@paquier.xyz>
Reviewed-by: Jian He <jian.universality@gmail.com>
Reviewed-by: Corey Huinker <corey.huinker@gmail.com>
Discussion: https://postgr.es/m/19715-b8be35083016f289@postgresql.org
Backpatch-through: 18
The header comment for this file says it assumes that "the CPU is not
picky about alignment", which we wouldn't really accept for Postgres.
The two functions that have alignment requirements have been hacked in
ways that are inconsistent and yet both ugly. des_setkey just casts
its "const char *" argument to "const uint32 *", relying on the caller
to ensure that that pointer is actually word-aligned, which the caller
does by declaring the buffer as uint32[] and then casting to "char *".
Meanwhile des_cipher carefully memcpy's to and from an internal
uint32[] buffer, which is pretty silly given that what it's passed
must be word-aligned for the benefit of des_setkey. And on top of
that we have a bunch of ugly casting and oddly-written pointer
arithmetic in the caller px_crypt_des. The odd pointer arithmetic
causes warnings about possible buffer overrun when using recent gcc
at -O3 or higher.
Let's clean this up by converting the buffer variable into a union
of a uint8 array and a uint32 array, so that we can remove all these
casts, and also replace the strange loop logic with a simple subscript
variable to satisfy gcc.
Reported-by: Andres Freund <andres@anarazel.de>
Author: Tom Lane <tgl@sss.pgh.pa.us>
Co-authored-by: Ayush Tiwari <ayushtiwari.slg01@gmail.com>
Discussion: https://postgr.es/m/2005885.1790359097@sss.pgh.pa.us
Discussion: https://postgr.es/m/3nuudxv365kjnmwjhnygdakhxuktpdjvf26rt26eb44esgqdrj@y2x3vomkrfoo
Backpatch-through: 14
When applying the concurrent data changes, REPACK deformed the decoded
tuples with the descriptor of the transient relation. That descriptor
has no "missing" values, because make_new_heap() gives the transient
relation none of the defaults and constraints of the source relation. A
tuple written before an ALTER TABLE ... ADD COLUMN that did not rewrite
the table has fewer attributes than the descriptor, so the missing
values came out as NULL, even in a column declared NOT NULL. If such a
value belongs to the replica identity, the key used to find the target
tuple was NULL too, so the tuple to modify cannot not be found. The
scan key does not remember that a value is NULL, so a pass-by-reference
key would even crash the comparison function. Such tuples will be rare,
because new row versions are normally formed with the current
descriptor. A BEFORE ROW UPDATE trigger returning OLD is one way to
produce one.
Fix by deforming the decoded tuples with the descriptor of the source
relation, which does have the missing values. Tuples formed with it are
still valid for the transient relation, whose attributes are a copy of
the source relation ones. Commit 20d3fe9009 took the same approach
for INSERT and UPDATE in the executor. Expanding the decoded tuple with
heap_expand_tuple() would be the other option, but that is the
workaround of commit ba9f18abd that 20d3fe9009 got rid of, so do not
bring it back.
Add an isolation test.
Author: Sami Imseih <samimseih.pg@gmail.com>
Reported-by: Shihao Zhong <zhong950419@gmail.com>
Reviewed-by: Kirill Reshke <reshkekirill@gmail.com>
Backpatch-through: 19
Discussion: https://postgr.es/m/CAN12+Y+NJwr5EqKVrHpPD=5+b_NRAOzU9fhrVDO3H46x2WRxoA@mail.gmail.com
Variable-length catalog columns have been declared like
text attoptions[1];
but that "1" has always been a fiction. Before the use of #ifdef
CATALOG_VARLEN, these declarations were visible to the C compiler, and
this was also before flexible array members were universally
available, so this was just a convenient workaround to make this
compile. But these reasons are long gone, and the "1" is now just a
confusing relic. Change this to
text attoptions[];
which more intuitively reflects the actual nature of these
fields (while still being syntactically valid but semantically invalid
C code).
Catalog.pm could already parse both spellings, but no existing code
used bare []. To enforce future consistency, it is changed to no
longer permit digits between the brackets. But to help developers
transition, it still recognizes the old style and gives an explicit
error message. (Otherwise it would produce some garbage output and
give confusing errors later.)
Reviewed-by: Heikki Linnakangas <hlinnaka@iki.fi>
Reviewed-by: Daniel Gustafsson <daniel@yesql.se>
Reviewed-by: Chao Li <li.evan.chao@gmail.com>
Discussion: https://www.postgresql.org/message-id/flat/963b2109-833c-4e93-bdb1-546741d893f4%40eisentraut.org
toast_internals.h described the header of a compressed-in-line varlena
a second time, as toast_compress_header, with its own TOAST_COMPRESS_*
macros to read and write the tcinfo word. varatt.h already describes
the same bytes as varattrib_4b.va_compressed and provides equivalent
macros that act as setter and getter of this information, as of
VARDATA_COMPRESSED_GET_EXTSIZE() and GET_COMPRESS_METHOD().
Let's remove the duplicate definition, and switch the TOAST code to use
the macros from varatt.h. There should be no behavior change.
Note that toast_compression.h is removed from toast_internals.h, added
to the C files where its declarations are required.
Author: Nikhil Kumar Veldanda <veldanda.nikhilkumar17@gmail.com>
Author: Michael Paquier <michael@paquier.xyz>
Discussion: https://postgr.es/m/CAFAfj_FeJQZrKyVn7ur0aJx8iz8SR14NheVJNyc8JNoqtMX+og@mail.gmail.com
gcc 12.5.0 complains about this instance in LookupFuncWithArgs().
This is the same type of problem fixed in commit f04781df5, and
it's just as obscure why this compiler version picks on this case
when others don't. Still, silence it in the same way as f04781df5.
Author: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/1812498.1790279465@sss.pgh.pa.us
Backpatch-through: 14
Currently, the message numbers in sinvaladt.c are ints, but they
are never negative, and the code already takes pains to keep them
from overflowing. This commit changes them to uint32. The only
wrinkle is that SICleanupQueue() computes two thresholds by
subtracting from maxMsgNum, and those could previously go negative.
They are now clamped at zero, which disables the corresponding
checks just as a negative threshold did.
This is preparatory work for a follow-up commit that will convert
maxMsgNum to an unsigned atomic variable.
Author: Yura Sokolov <y.sokolov@postgrespro.ru>
Reviewed-by: Heikki Linnakangas <hlinnaka@iki.fi>
Reviewed-by: Peter Eisentraut <peter@eisentraut.org>
Reviewed-by: Andres Freund <andres@anarazel.de>
Discussion: https://postgr.es/m/30aa0030-f694-44ef-a19d-6ef7ddb69374%40postgrespro.ru
Discussion: https://postgr.es/m/alAJeRRzehDjLaF1%40nathan
The sequencesync worker asks the publisher about a batch of sequences,
tagging each one with its position in the worker's own list, and the
publisher returns that position alongside the sequence's data. The
received position is used to subscript the list using list_nth(),
which bounds-checks only on assert builds, so it was possible that an
index we never sent made the worker read a pointer from past the end
of the list and then store the remote last_value through it.
Check the position against the list before using it. No sane publisher
can trigger this, but we should not let a remote server steer a memory
access. An in-range position from another batch still gets through and
would attach one sequence's data to another, but that's a wrong value
rather than a corrupt process.
Also, receive the index as int4 rather than int8. Previously, an
out-of-range int8 value was silently truncated to its lower 32 bits by
DatumGetInt32(), which could turn it into a valid index and defeat the
check.
Backpatch to v19, where sequence synchronization was introduced.
Reported-by: Anthropic OSS program
Reviewed-by: Amit Kapila <amit.kapila16@gmail.com>
Reviewed-by: Chao Li <li.evan.chao@gmail.com>
Discussion: https://postgr.es/m/CAD21AoBWDMuMmnevZaZ1xSOi75eUx8X7LbVQzmUZudk6F8Bdgg@mail.gmail.com
Backpatch-through: 19
Autovacuum doesn't necessarily fully empty the GIN pending list. It
stops at the tail as of the start of cleanup, so that it doesn't keep
chasing pages appended by concurrent inserters. GIN decided this with
AmAutoVacuumWorkerProcess(), which returns false in parallel vacuum
workers launched by an autovacuum worker, so those workers tried to
fully empty the list as a manual VACUUM does.
Fix this by adding an is_autovacuum field to IndexVacuumInfo, set from
the shared parallel vacuum state in parallel workers, and using it in
GIN instead of checking the process type.
Oversight in commit 1ff3180ca0.
Reported-by: Jingtang Zhang <mrdrivingduck@gmail.com>
Author: Jingtang Zhang <mrdrivingduck@gmail.com>
Reviewed-by: Andrey Borodin <x4mmm@yandex-team.ru>
Reviewed-by: Yuhang Qiu <iamqyh@gmail.com>
Reviewed-by: Masahiko Sawada <sawada.mshk@gmail.com>
Discussion: https://postgr.es/m/CAPsk3_DiF2i1o=JRXRk1YPVMv1VzJaCAbfiEqgwCva4=ZewVAw@mail.gmail.com
Backpatch-through: 19
Our Solaris-camp buildfarm animals (billbug, hake, pollock, so far)
are complaining about dumpcolors()'s local variables in the wake of
3ee0edb91. This is unsurprising on one level, since that code
clearly violates the new expectation; but AFAICS these animals
aren't explicitly enabling -DREG_DEBUG, so how are they reaching
the now-faulty code? Do Solaris' headers #define that?
In any case, the fix is simple enough, just narrow the
declaration scopes of this function's loop variables.
(I could have done that only to "c", but thought it best
to maintain a consistent style in this function.)
I don't see any need to back-patch this.
ShmemInitStruct() only looked for an existing allocation when
IsUnderPostmaster was true. Because of that, you could not reattach
to an existing shmem area in a standalone backend.
Usually, you only call ShmemInitStruct() for the same shmem area once
in a process and hold onto the returned pointer, but there was no rule
that you couldn't call it twice for the same area if you wanted to,
and before commit 283e823f9d, it worked. To fix, check for an
existing allocation regardless of process type, like the old
implementation did.
Author: Ayush Tiwari <ayushtiwari.slg01@gmail.com>
Reviewed-by: Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
Discusssion: https://www.postgresql.org/message-id/CAJTYsWXREGXCnWdZJsXt8pT2UY_Y2GSx+HOUu2X3s8YDCLj0_A@mail.gmail.com
Backpatch-through: 19
Remove assertion that was too strict, and tripped if you queried the
pg_shmem_allocations_numa or the pg_buffercache_os_pages view in
single-user mode.
The point of the assertion was that the function should only be called
after "the server has started", but it would be OK to call it from the
postmaster, too, as long as it's after startup, specifically after
huge_pages_status has been set. We already have a direct assertion
for that.
Author: Ayush Tiwari <ayushtiwari.slg01@gmail.com>
Discussion: https://www.postgresql.org/message-id/CAJTYsWV-=w5_oFgCnfAixWGc=gMa2pkDinLyGLsb4sKcDaf2FA@mail.gmail.com
Backpatch-through: 18
The fast path's ri_CheckPermissions() called ExecCheckOneRelPerms()
directly, so ExecutorCheckPerms_hook never saw the referenced-table
access that the SPI path's query exposed to it via ExecutorStart().
Modules such as sepgsql that rely on this hook therefore lost control
over FK checks against referenced tables that go through the fast
path.
So, build a one-entry range table and permission-info list and call
ExecCheckPermissions(). The hook now sees the same relation and
requiredPerms as before, once per check that goes through the fast
path. This also drops the shortcut that skipped the column-level
check when table-level privileges sufficed, since the hook must run
regardless. While at it, drop the explicit frees in the old code,
because both callers run ri_CheckPermissions() in a per-tuple context
that is reset after each check, so they were redundant.
Reported-by: Noah Misch <noah@leadboat.com>
Discussion: https://postgr.es/m/20260705210533.ee.noahmisch%40microsoft.com
Backpatch-through: 19
SnapBuildInitialSnapshot() converts the snapshot builder's list of
committed transactions into a regular MVCC snapshot, which is then used
with HeapTupleSatisfiesMVCC(). However, a snapshot produced that way
and used as an MVCC snapshot can potentially cause data corruption, if
it captures a transaction after it writes its commit WAL record but
before it has updated its CLOG entry: it will be incorrectly used to set
hint bits as if that transaction had aborted.
Fix by having SnapBuildInitialSnapshot() wait until such transactions
have removed themselves from procarray, which guarantees correct
visibility.
Other uses of SnapBuildBuildSnapshot only use the snapshot as
historical, so they don't need the waits, but add commentary in that
function to alert possible future callers.
While at this, backpatch commit 504fe10d1d, "Fix misplaced comment in
snapbuild.c." The comment it moved was nearby the place we modify.
This bug was diagnosed by stress-testing of REPACK (CONCURRENTLY) in
branch 19, so add a test case that tickles it using that feature in that
branch and master. However, the bug exists in all branches, and in
branch 18 we can add a test with regular logical decoding using
injection points that tickles it. Unfortunately that test cannot be
backpatched to earlier branches for lack of facilities.
Reported-by: Mihail Nikalayeu <mihailnikalayeu@gmail.com>
Author: Antonin Houska <ah@cybertec.at>
Author: Rui Zhao <zhaorui126@gmail.com>
Backpatch-through: 14
Discussion: https://postgr.es/m/85833.1768840165@localhost
Discussion: https://postgr.es/m/CADzfLwU78as45To9a%3D-Qkr5jEg3tMxc5rUtdKy2MTv4r_SDGng%40mail.gmail.com
Change the existing -Wshadow=compatible-local to -Wshadow=local. This
covers more cases than before. In particular, some types are
assignable to each other, such as char * and const char *, or bool and
some integer type, but they are not "compatible" in the C sense, so
they are missed by the previous warning setting, but they are really
the same basic problem.
The warnings were already fixed in commit f9fc9a78a3. This just
enables the compiler option.
But: The LLVM headers are not clean for this option, so we need to
disable this option for those headers. We do this by also detecting
in configure and meson the negative form of the warning option and
applying it when compiling the respective files, similar to how other
per-file warning disabling already works.
This technically loses the previous -Wshadow=compatible-local checking
of the LLVM-using files, but this worked only by accident anyway and
there is no guarantee that future LLVM versions wouldn't run afoul of
that warning level.
The variables are intentionally named "...shadow", not
"...shadow_local" or similar, so that other shadow warning option
variants could be substituted easily.
In the long run, a better solution might be to use -isystem for the
LLVM include directories, as was attempted in commit 704ef84ef2 but
then reverted in 7a0aa99e51, because porting that logic from meson
accurately to configure is complicated and fragile and hard to test
and maintain.
Discussion: https://www.postgresql.org/message-id/flat/84b6f128-91f5-480e-8a9e-7d0e8f538cea%40eisentraut.org
MultiXactState->oldestOffset is not maintained during recovery, so
calling pg_get_multixact_stats() in this context would report misleading
information. We could try to work this out by adding this field to the
control file, for example, but such a change would be too invasive at
this stage of the v19 development cycle.
The information of pg_get_multixact_stats() is usually useful to control
the need of some VACUUM or some freezing, operations that cannot happen
on a standby, so the argument to make the function work while recovery
is in progress gets thinner with this point in the balance.
The function is updated to return an ERROR when called under
RecoveryInProgress().
Per discussion with Heikki Linnakangas and Naga Appani.
Reported-by: Noah Misch <noah@leadboat.com>
Discussion: https://postgr.es/m/CA+QeY+DcnsZRL4GZD8JyJu5HD-d6p8_9M5kT4jgF3gq3Rh8n4w@mail.gmail.com
Discussion: https://postgr.es/m/20260827231757.78.noahmisch@microsoft.com
Backpatch-through: 19
8191e0c16a made pgstat_init_entry() return NULL on DSA allocation
failure so callers could delete a just-inserted hash entry. That works
when dsa_allocate_extended(DSA_ALLOC_NO_OOM) returns InvalidDsaPointer,
but not when the creation of a new DSM segment raises ERROR.
Under this type of failure, pgstat_init_entry() would mark the hash
entry live before allocating the body and cause an inconsistent state in
shared memory. The next backend trying to acquire the existing,
partially-initialized entry in pgstat_acquire_entry_ref() would crash,
taking down the server. Some of the public reports mentioned ENOSPC on
POSIX shared memory as one initial cause.
This commit refactors the pgstats entry initialization to happen in two
phases:
- Allocate the DSA chunk.
- Insert the hash entry with a valid segment.
If a concurrent insert wins, the allocation of the first phase needs an
extra set of dsa_free() calls (pulling back a DSM into its free list).
As this changes the signature of pgstat_init_entry(), no backpatch is
done.
Author: Yuriy Grigoryev <ju.grigorev@ftdata.ru>
Author: Michael Paquier <michael@paquier.xyz>
Discussion: https://postgr.es/m/ddc3ecfb01ce4e9698b23cc59767f016@localhost.localdomain
The "initializing" phase was described as expected to be very brief,
but for REPACK (CONCURRENTLY), it also covers enabling and
initializing logical decoding, either of which can take a long
time. Also, the "catch-up" phase includes waiting for the ACCESS
EXCLUSIVE lock needed to swap the files, which was not mentioned.
Adding separate progress phases for these steps is left for v20; for
v19 we only clarify the description.
Author: Sami Imseih <samimseih.pg@gmail.com>
Reviewed-by: Masahiko Sawada <sawada.mshk@gmail.com>
Reviewed-by: Manuel Reyes Bravo <manuelreyesbravo@gmail.com>
Discussion: https://postgr.es/m/CAN12%2BYJOeOyPYB5JS28VE_%2Brzg%3DRbzQXfj58TGfMYwv-TX9mJA%40mail.gmail.com
Backpatch-through: 19
The heuristic to avoid setting the VM during on-access pruning when
doing so would emit an extra FPI missed a few cases. First it missed
temp and unlogged tables. Those will never emit an FPI, so they can
always set the VM if the page is all-visible. It also missed that if
hint bits are not WAL-logged, setting only the VM passes REGBUF_NO_IMAGE
for an already WAL-logged heap page, forbidding a heap FPI in the WAL
record. A page that has never been WAL-logged still requires a heap FPI.
The third is more subtle: If the page is all-visible, the new prune xid
will be InvalidTransactionId. On-access pruning only executes when the
current pd_prune_xid is valid and visible. So, when on-access pruning
finds the page all-visible, it will always clear pd_prune_xid, modifying
the page.
Knowing this means we can set the VM without emitting an extra heap FPI
in more cases. When hint bits are WAL-logged, if the heap buffer is
clean, modifying pd_prune_xid will emit an FPI if one is required. There
is no reason to try to avoid an FPI by not setting the VM. So, set the
VM in this case. However, when the heap buffer is already dirty,
modifying pd_prune_xid can avoid an FPI; so if the page hasn't been
logged since the last checkpoint, setting it all-visible will emit an
extra heap page FPI. We will still avoid setting the VM in this case.
This is being backpatched to 19 because since 378a216187 pd_prune_xid
is set on insert, and if we execute a prune cycle and skip setting the
VM because of an incorrect heuristic, we have added new wasted work in
PG 19.
This commit adds some tests covering these cases. It also updates one of
the existing temp table tests to avoid exceeding the pin limit. Setting
the VM and FSM on-access when querying temp tables takes more local pins
and can run into the limit with fewer heap buffers pinned.
Reported-by: Melanie Plageman <melanieplageman@gmail.com>
Author: Melanie Plageman <melanieplageman@gmail.com>
Reviewed-by: Andrey Borodin <x4mmm@yandex-team.ru>
Discussion: https://postgr.es/m/CAAKRu_amj7qLF4c=9ijd=708Fu2G8gg-2EqwBu=aCdAHU2sPHg@mail.gmail.com
Backpatch-through: 19
heapgettup_advance_block() (or heapgettup() and heapgettup_pagemode() in
versions before v16) would incorrectly decrement rs_numblocks when
advancing to the next block. Ordinarily this was fine, but if the TID
Range scan plan was used by a scrollable cursor and the cursor was fetched
backwards enough to result in another block being required, then
rs_numblocks may have reached 0 prematurely resulting in the scan ending
prematurely.
Reported-by: Jeff Davis <pgsql@j-davis.com>
Author: Ewan Young <kdbase.hack@gmail.com>
Author: David Rowley <dgrowleyml@gmail.com>
Discussion: https://postgr.es/m/6b50233fcc0f7d6f4845f083777fa9702d9612e4.camel@j-davis.com
Backpatch-through: 14
Back in the days before a91e2fa94, hash_any() was the primary hash
function and it returned a Datum. That commit changed hash_any() to a
wrapper over hash_bytes(). Some places actually wanted the underlying
uint32 from hash_bytes(), but that now presents as useless round-trip
casting, so update the call sites where we don't immediately need a
Datum.
hash_numeric() didn't have round-trip casting, but it was internally
inconsistent: Paths returning a constant used PG_RETURN_UINT32(), but
the path using the result of hash_any() used PG_RETURN_DATUM. Change
it to use uint32 throughout.
Author: Aleksander Alekseev <aleksander@tigerdata.com>
Suggested-by: John Naylor <johncnaylorls@gmail.com>
Reviewed-by: Zsolt Parragi <zsolt.parragi@percona.com>
Discussion: https://postgr.es/m/CAJ7c6TMPhDRQMmkUHPv8oOK97B1mR8NRS61DgjpdaZUPAwaeZQ%40mail.gmail.com
When executing a WHEN NOT MATCHED BY SOURCE action in MERGE, if the
tuple from the target table was concurrently deleted, the retry code
would incorrectly execute a WHEN NOT MATCHED BY TARGET action for the
row instead, giving incorrect results.
Fix in ExecMergeMatched() -- when handling a TM_Deleted failure
status, it should only set *matched to false (telling the caller to
execute any WHEN NOT MATCHED BY TARGET actions) if the failed action
was a WHEN MATCHED action. For a failed WHEN NOT MATCHED BY SOURCE
action, the source tuple did not exist, and the target tuple has just
been deleted, so it should do nothing.
Back-patch to v17, where support for WHEN NOT MATCHED BY SOURCE
actions was introduced.
Reported-by: Jeff Davis <pgsql@j-davis.com>
Author: Tender Wang <tndrwang@gmail.com>
Reviewed-by: Dean Rasheed <dean.a.rasheed@gmail.com>
Discussion: https://postgr.es/m/ccdab5ba02c65af195b5a6d2d744a01d9de47cd3.camel@j-davis.com
Backpatch-through: 17
Commit bad8829872 added an alignas specifier, and placed it in the
middle of the declaration, unlike most existing uses, possibly to
avoid the indentation problem recently fixed in commit 884f82ae26.
This placement is valid in C but not in C++, which requires it to be
at the beginning. This results in a warning in g++ and an error in
clang++. Fix by moving it accordingly.
A sequencesync worker builds its list of sequences and then processes them
in batches. If ALTER SUBSCRIPTION ... REFRESH PUBLICATION removes one of
those sequences in the meantime, the worker updated the local sequence and
then failed while marking it READY, because its catalog row was gone. That
rolled back the batch, and with disable_on_error the entire subscription
was disabled.
The worker now checks that the sequence is still part of the subscription
before updating it, and skips it if not. The check is done under the lock
on the subscription that the refresh also takes, so the row cannot go away
in between.
Reported-by: Nikolay Samokhvalov <nik@postgres.ai>
Author: vignesh C <vignesh21@gmail.com>
Reviewed-by: shveta malik <shveta.malik@gmail.com>
Reviewed-by: Zhijie Hou <houzj.fnst@fujitsu.com>
Reviewed-by: Andrey Borodin <x4mmm@yandex-team.ru>
Discussion: https://postgr.es/m/CAM527d9mL-bOofX-G7Sp441vA3Y_fa_7JBh03m-ZPduikn_XUg@mail.gmail.com
Backpatch-through: 19, where it was introduced
6dbb490261 combined pruning and freezing in a single WAL record but
unconditionally requested a cleanup lock during replay. Prior to version
17, freeze-only records were replayed under an ordinary exclusive lock.
1252a4ee28 subsequently folded visibility map updates into the same
records, extending the unnecessary cleanup-lock requirement to VM-only
updates starting in version 19.
Request a cleanup lock in redo only when the record actually prunes.
Freezing and visibility updates do not move or remove tuple storage, so
they need not wait for other buffer pins to be released. This avoids
unnecessary replay delays and cancellation of standby queries holding
buffer pins.
The fix is the same for all versions, though it addresses two oversights
in master/19 and one in 18/17.
Reported-by: Satyanarayana Narlapuram <satyanarlapuram@gmail.com>
Reported-by: Andrey Borodin <x4mmm@yandex-team.ru>
Reviewed-by: Andrey Borodin <x4mmm@yandex-team.ru>
Discussion: https://postgr.es/m/85b6968b-49f2-4243-86a6-9b4116e6439b@iki.fi
Discussion: https://postgr.es/m/CAHg+QDf3NcB3vOAqQ5EFcV5DYYUZ9snCSJAU-x1JDbtcjK3eBQ@mail.gmail.com
Discussion: https://postgr.es/m/F9BF304E-1298-481C-829A-B4E10AED025A@yandex-team.ru
Backpatch-through: 17
Before pruning a heap page, we get the current status of the
corresponding VM page. If the passed in vmbuffer isn't the right one,
visibilitymap_get_status() will silently unpin it and pin the correct
page. Pruning assumes the caller manages the vmbuffer lifecycle, so this
would leave the caller with a stale VM reference and would leak the new
VM pin. To avoid mistakes in development, assert that the correct VM
page is pinned before beginning.
Reported-by: Melanie Plageman <melanieplageman@gmail.com>
Reviewed-by: Andrey Borodin <x4mmm@yandex-team.ru>
Discussion: https://postgr.es/m/CAAKRu_amj7qLF4c=9ijd=708Fu2G8gg-2EqwBu=aCdAHU2sPHg@mail.gmail.com
Backpatch-through: 19
Currently, this variable is an int protected by a spinlock. By
converting it to an atomic variable, we can remove the spinlock.
Detaching becomes an atomic subtract, and attaching becomes a
compare-and-exchange loop, since it must not resurrect a fileset
whose reference count has already reached zero.
Reviewed-by: Zsolt Parragi <zsolt.parragi@percona.com>
Tested-by: solai v <solai.cdac@gmail.com>
Discussion: https://postgr.es/m/alAJeRRzehDjLaF1%40nathan
Currently, currentWorker and workersFinished are ints protected by
a spinlock. By converting them to atomic variables, we can remove
the spinlock. Note that the spinlock also covered the write of
each worker's tape metadata. Removing it is still okay: each
worker writes only its own slot, and the atomic increment that
follows is a full barrier. Furthermore, the leader doesn't read
the slot values until all workers have finished.
Reviewed-by: Zsolt Parragi <zsolt.parragi@percona.com>
Tested-by: solai v <solai.cdac@gmail.com>
Discussion: https://postgr.es/m/alAJeRRzehDjLaF1%40nathan
Currently, this variable is a Buffer that is accessed via a
volatile pointer. By converting it to an atomic variable, we can
remove the volatile qualifiers. No barriers are needed because the
value is published before the backends that read it are signaled.
Reviewed-by: Peter Eisentraut <peter@eisentraut.org>
Reviewed-by: Andres Freund <andres@anarazel.de>
Reviewed-by: Zsolt Parragi <zsolt.parragi@percona.com>
Tested-by: solai v <solai.cdac@gmail.com>
Discussion: https://postgr.es/m/alAJeRRzehDjLaF1%40nathan
Similar to commit "Remove unused global variables", silence
-Wunused-but-set-global warnings from clang 23 (included in -Wall).
These are variables that are used in assert-enabled builds only, so
annotate them with PG_USED_FOR_ASSERTS_ONLY.
The error code paths adjusted in this commit are reachable via SQL
functions that are documented. Previously, they generated an internal
error code, causing the messages to not be translated. They are now
upgraded with a suitable error code.
Note the extra consistency in the three typmod errors, and the tweaks in
acldefault_sql() to show correctly non-printable characters.
Author: Alexander Lakhin <exclusion@gmail.com>
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/94ac928b-8370-4db5-ada5-579a9ebc089d@gmail.com
Array values embed their element type's OID, and pg_upgrade does not
rewrite user data. The OIDs of information_schema domains can vary
between major versions, so a stored array over one (e.g. by aggregating
an information_schema query into a table) comes through the upgrade
with at best a dangling element OID. Whole-array reads and pg_dump
of the upgraded cluster then fail with "cache lookup failed for type
N". Worst case, the OID has been reassigned, leading to values being
misread instead.
The data type checks miss this because nothing flags the domain itself:
domain storage is just the base type, so the recursive expansion in
data_type_check_query() never reaches the array type.
Add a check for arrays whose element type OID was assigned by genbki.pl
or initdb, including anything in information_schema in case it was
dropped and reloaded.
The scenarios that hit this are fairly contrived, which probably
explains the lack of field reports, so no backpatch for now.
Reviewed-by: Chengpeng Yan <chengpeng_yan@outlook.com>
Discussion: https://postgr.es/m/CANWCAZbusXHWWSq_9NpxtOGvR=M5MH4Uj+wO0f1_rtC0uMeSWg@mail.gmail.com