Skip to content

Commit c871423

Browse files
Fix pg_sequence_last_value() for unlogged sequences on standbys.
Presently, when this function is called for an unlogged sequence on a standby server, it will error out with a message like ERROR: could not open file "base/5/16388": No such file or directory Since the pg_sequences system view uses pg_sequence_last_value(), it can error similarly. To fix, modify the function to return NULL for unlogged sequences on standby servers. Since this bug is present on all versions since v15, this approach is preferable to making the ERROR nicer because we need to repair the pg_sequences view without modifying its definition on released versions. For consistency, this commit also modifies the function to return NULL for other sessions' temporary sequences. The pg_sequences view already appropriately filters out such sequences, so there's no bug there, but we might as well offer some defense in case someone invokes this function directly. Unlogged sequences were first introduced in v15, but temporary sequences are much older, so while the fix for unlogged sequences is only back-patched to v15, the temporary sequence portion is back-patched to all supported versions. We could also remove the privilege check in the pg_sequences view definition in v18 if we modify this function to return NULL for sequences for which the current user lacks privileges, but that is left as a future exercise for when v18 development begins. Reviewed-by: Tom Lane, Michael Paquier Discussion: https://postgr.es/m/20240501005730.GA594666%40nathanxps13 Backpatch-through: 12
1 parent d393370 commit c871423

File tree

1 file changed

+18
-9
lines changed

1 file changed

+18
-9
lines changed

src/backend/commands/sequence.c

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1856,11 +1856,8 @@ pg_sequence_last_value(PG_FUNCTION_ARGS)
18561856
Oid relid = PG_GETARG_OID(0);
18571857
SeqTable elm;
18581858
Relation seqrel;
1859-
Buffer buf;
1860-
HeapTupleData seqtuple;
1861-
Form_pg_sequence_data seq;
1862-
bool is_called;
1863-
int64 result;
1859+
bool is_called = false;
1860+
int64 result = 0;
18641861

18651862
/* open and lock sequence */
18661863
init_sequence(relid, &elm, &seqrel);
@@ -1871,12 +1868,24 @@ pg_sequence_last_value(PG_FUNCTION_ARGS)
18711868
errmsg("permission denied for sequence %s",
18721869
RelationGetRelationName(seqrel))));
18731870

1874-
seq = read_seq_tuple(seqrel, &buf, &seqtuple);
1871+
/*
1872+
* We return NULL for other sessions' temporary sequences. The
1873+
* pg_sequences system view already filters those out, but this offers a
1874+
* defense against ERRORs in case someone invokes this function directly.
1875+
*/
1876+
if (!RELATION_IS_OTHER_TEMP(seqrel))
1877+
{
1878+
Buffer buf;
1879+
HeapTupleData seqtuple;
1880+
Form_pg_sequence_data seq;
18751881

1876-
is_called = seq->is_called;
1877-
result = seq->last_value;
1882+
seq = read_seq_tuple(seqrel, &buf, &seqtuple);
18781883

1879-
UnlockReleaseBuffer(buf);
1884+
is_called = seq->is_called;
1885+
result = seq->last_value;
1886+
1887+
UnlockReleaseBuffer(buf);
1888+
}
18801889
relation_close(seqrel, NoLock);
18811890

18821891
if (is_called)

0 commit comments

Comments
 (0)