Skip to content

Commit 449e798

Browse files
committed
Introduce sequence_*() access functions
Similarly to tables and indexes, these functions are able to open relations with a sequence relkind, which is useful to make a distinction with the other relation kinds. Previously, commands/sequence.c used a mix of table_{close,open}() and relation_{close,open}() routines when manipulating sequence relations, so this clarifies the code. A direct effect of this change is to align the error messages produced when attempting DDLs for sequences on relations with an unexpected relkind, like a table or an index with ALTER SEQUENCE, providing an extra error detail about the relkind of the relation used in the DDL query. Author: Michael Paquier Reviewed-by: Tomas Vondra Discussion: https://postgr.es/m/ZWlohtKAs0uVVpZ3@paquier.xyz
1 parent 025f0a6 commit 449e798

File tree

8 files changed

+140
-20
lines changed

8 files changed

+140
-20
lines changed

src/backend/access/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,6 @@ top_builddir = ../../..
99
include $(top_builddir)/src/Makefile.global
1010

1111
SUBDIRS = brin common gin gist hash heap index nbtree rmgrdesc spgist \
12-
table tablesample transam
12+
sequence table tablesample transam
1313

1414
include $(top_srcdir)/src/backend/common.mk

src/backend/access/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ subdir('heap')
99
subdir('index')
1010
subdir('nbtree')
1111
subdir('rmgrdesc')
12+
subdir('sequence')
1213
subdir('spgist')
1314
subdir('table')
1415
subdir('tablesample')

src/backend/access/sequence/Makefile

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#-------------------------------------------------------------------------
2+
#
3+
# Makefile
4+
# Makefile for access/sequence
5+
#
6+
# IDENTIFICATION
7+
# src/backend/access/sequence/Makefile
8+
#
9+
#-------------------------------------------------------------------------
10+
11+
subdir = src/backend/access/sequence
12+
top_builddir = ../../../..
13+
include $(top_builddir)/src/Makefile.global
14+
15+
OBJS = sequence.o
16+
17+
include $(top_srcdir)/src/backend/common.mk
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Copyright (c) 2022-2024, PostgreSQL Global Development Group
2+
3+
backend_sources += files(
4+
'sequence.c',
5+
)
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/*-------------------------------------------------------------------------
2+
*
3+
* sequence.c
4+
* Generic routines for sequence-related code.
5+
*
6+
* Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
7+
* Portions Copyright (c) 1994, Regents of the University of California
8+
*
9+
*
10+
* IDENTIFICATION
11+
* src/backend/access/sequence/sequence.c
12+
*
13+
*
14+
* NOTES
15+
* This file contains sequence_ routines that implement access to sequences
16+
* (in contrast to other relation types like indexes).
17+
*
18+
*-------------------------------------------------------------------------
19+
*/
20+
21+
#include "postgres.h"
22+
23+
#include "access/relation.h"
24+
#include "access/sequence.h"
25+
#include "storage/lmgr.h"
26+
27+
static inline void validate_relation_kind(Relation r);
28+
29+
/* ----------------
30+
* sequence_open - open a sequence relation by relation OID
31+
*
32+
* This is essentially relation_open plus check that the relation
33+
* is a sequence.
34+
* ----------------
35+
*/
36+
Relation
37+
sequence_open(Oid relationId, LOCKMODE lockmode)
38+
{
39+
Relation r;
40+
41+
r = relation_open(relationId, lockmode);
42+
43+
validate_relation_kind(r);
44+
45+
return r;
46+
}
47+
48+
/* ----------------
49+
* sequence_close - close a sequence
50+
*
51+
* If lockmode is not "NoLock", we then release the specified lock.
52+
*
53+
* Note that it is often sensible to hold a lock beyond relation_close;
54+
* in that case, the lock is released automatically at xact end.
55+
* ----------------
56+
*/
57+
void
58+
sequence_close(Relation relation, LOCKMODE lockmode)
59+
{
60+
relation_close(relation, lockmode);
61+
}
62+
63+
/* ----------------
64+
* validate_relation_kind - check the relation's kind
65+
*
66+
* Make sure relkind is from an index
67+
* ----------------
68+
*/
69+
static inline void
70+
validate_relation_kind(Relation r)
71+
{
72+
if (r->rd_rel->relkind != RELKIND_SEQUENCE)
73+
ereport(ERROR,
74+
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
75+
errmsg("cannot open relation \"%s\"",
76+
RelationGetRelationName(r)),
77+
errdetail_relkind_not_supported(r->rd_rel->relkind)));
78+
}

src/backend/commands/sequence.c

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "access/htup_details.h"
1919
#include "access/multixact.h"
2020
#include "access/relation.h"
21+
#include "access/sequence.h"
2122
#include "access/table.h"
2223
#include "access/transam.h"
2324
#include "access/xact.h"
@@ -208,7 +209,7 @@ DefineSequence(ParseState *pstate, CreateSeqStmt *seq)
208209
seqoid = address.objectId;
209210
Assert(seqoid != InvalidOid);
210211

211-
rel = table_open(seqoid, AccessExclusiveLock);
212+
rel = sequence_open(seqoid, AccessExclusiveLock);
212213
tupDesc = RelationGetDescr(rel);
213214

214215
/* now initialize the sequence's data */
@@ -219,7 +220,7 @@ DefineSequence(ParseState *pstate, CreateSeqStmt *seq)
219220
if (owned_by)
220221
process_owned_by(rel, owned_by, seq->for_identity);
221222

222-
table_close(rel, NoLock);
223+
sequence_close(rel, NoLock);
223224

224225
/* fill in pg_sequence */
225226
rel = table_open(SequenceRelationId, RowExclusiveLock);
@@ -324,7 +325,7 @@ ResetSequence(Oid seq_relid)
324325
/* Note that we do not change the currval() state */
325326
elm->cached = elm->last;
326327

327-
relation_close(seq_rel, NoLock);
328+
sequence_close(seq_rel, NoLock);
328329
}
329330

330331
/*
@@ -531,7 +532,7 @@ AlterSequence(ParseState *pstate, AlterSeqStmt *stmt)
531532
ObjectAddressSet(address, RelationRelationId, relid);
532533

533534
table_close(rel, RowExclusiveLock);
534-
relation_close(seqrel, NoLock);
535+
sequence_close(seqrel, NoLock);
535536

536537
return address;
537538
}
@@ -555,7 +556,7 @@ SequenceChangePersistence(Oid relid, char newrelpersistence)
555556
fill_seq_with_data(seqrel, &seqdatatuple);
556557
UnlockReleaseBuffer(buf);
557558

558-
relation_close(seqrel, NoLock);
559+
sequence_close(seqrel, NoLock);
559560
}
560561

561562
void
@@ -662,7 +663,7 @@ nextval_internal(Oid relid, bool check_permissions)
662663
Assert(elm->last_valid);
663664
Assert(elm->increment != 0);
664665
elm->last += elm->increment;
665-
relation_close(seqrel, NoLock);
666+
sequence_close(seqrel, NoLock);
666667
last_used_seq = elm;
667668
return elm->last;
668669
}
@@ -849,7 +850,7 @@ nextval_internal(Oid relid, bool check_permissions)
849850

850851
UnlockReleaseBuffer(buf);
851852

852-
relation_close(seqrel, NoLock);
853+
sequence_close(seqrel, NoLock);
853854

854855
return result;
855856
}
@@ -880,7 +881,7 @@ currval_oid(PG_FUNCTION_ARGS)
880881

881882
result = elm->last;
882883

883-
relation_close(seqrel, NoLock);
884+
sequence_close(seqrel, NoLock);
884885

885886
PG_RETURN_INT64(result);
886887
}
@@ -915,7 +916,7 @@ lastval(PG_FUNCTION_ARGS)
915916
RelationGetRelationName(seqrel))));
916917

917918
result = last_used_seq->last;
918-
relation_close(seqrel, NoLock);
919+
sequence_close(seqrel, NoLock);
919920

920921
PG_RETURN_INT64(result);
921922
}
@@ -1030,7 +1031,7 @@ do_setval(Oid relid, int64 next, bool iscalled)
10301031

10311032
UnlockReleaseBuffer(buf);
10321033

1033-
relation_close(seqrel, NoLock);
1034+
sequence_close(seqrel, NoLock);
10341035
}
10351036

10361037
/*
@@ -1095,7 +1096,7 @@ lock_and_open_sequence(SeqTable seq)
10951096
}
10961097

10971098
/* We now know we have the lock, and can safely open the rel */
1098-
return relation_open(seq->relid, NoLock);
1099+
return sequence_open(seq->relid, NoLock);
10991100
}
11001101

11011102
/*
@@ -1152,12 +1153,6 @@ init_sequence(Oid relid, SeqTable *p_elm, Relation *p_rel)
11521153
*/
11531154
seqrel = lock_and_open_sequence(elm);
11541155

1155-
if (seqrel->rd_rel->relkind != RELKIND_SEQUENCE)
1156-
ereport(ERROR,
1157-
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
1158-
errmsg("\"%s\" is not a sequence",
1159-
RelationGetRelationName(seqrel))));
1160-
11611156
/*
11621157
* If the sequence has been transactionally replaced since we last saw it,
11631158
* discard any cached-but-unissued values. We do not touch the currval()
@@ -1803,7 +1798,7 @@ pg_sequence_last_value(PG_FUNCTION_ARGS)
18031798
result = seq->last_value;
18041799

18051800
UnlockReleaseBuffer(buf);
1806-
relation_close(seqrel, NoLock);
1801+
sequence_close(seqrel, NoLock);
18071802

18081803
if (is_called)
18091804
PG_RETURN_INT64(result);

src/include/access/sequence.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*-------------------------------------------------------------------------
2+
*
3+
* sequence.h
4+
* Generic routines for sequence-related code.
5+
*
6+
*
7+
* Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
8+
* Portions Copyright (c) 1994, Regents of the University of California
9+
*
10+
* src/include/access/sequence.h
11+
*
12+
*-------------------------------------------------------------------------
13+
*/
14+
#ifndef ACCESS_SEQUENCE_H
15+
#define ACCESS_SEQUENCE_H
16+
17+
#include "storage/lockdefs.h"
18+
#include "utils/relcache.h"
19+
20+
extern Relation sequence_open(Oid relationId, LOCKMODE lockmode);
21+
extern void sequence_close(Relation relation, LOCKMODE lockmode);
22+
23+
#endif /* ACCESS_SEQUENCE_H */

src/test/regress/expected/sequence.out

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,8 @@ ALTER SEQUENCE IF EXISTS sequence_test2 RESTART WITH 24
313313
INCREMENT BY 4 MAXVALUE 36 MINVALUE 5 CYCLE;
314314
NOTICE: relation "sequence_test2" does not exist, skipping
315315
ALTER SEQUENCE serialTest1 CYCLE; -- error, not a sequence
316-
ERROR: "serialtest1" is not a sequence
316+
ERROR: cannot open relation "serialtest1"
317+
DETAIL: This operation is not supported for tables.
317318
CREATE SEQUENCE sequence_test2 START WITH 32;
318319
CREATE SEQUENCE sequence_test4 INCREMENT BY -1;
319320
SELECT nextval('sequence_test2');

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy