PostgreSQL Source Code git master
Loading...
Searching...
No Matches
sequence.h File Reference
#include "catalog/objectaddress.h"
#include "fmgr.h"
#include "nodes/parsenodes.h"
#include "parser/parse_node.h"
Include dependency graph for sequence.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  FormData_pg_sequence_data
 

Macros

#define SEQ_COL_LASTVAL   1
 
#define SEQ_COL_LOG   2
 
#define SEQ_COL_CALLED   3
 
#define SEQ_COL_FIRSTCOL   SEQ_COL_LASTVAL
 
#define SEQ_COL_LASTCOL   SEQ_COL_CALLED
 

Typedefs

typedef struct FormData_pg_sequence_data FormData_pg_sequence_data
 
typedef FormData_pg_sequence_dataForm_pg_sequence_data
 

Functions

int64 nextval_internal (Oid relid, bool check_permissions)
 
Datum nextval (PG_FUNCTION_ARGS)
 
Listsequence_options (Oid relid)
 
ObjectAddress DefineSequence (ParseState *pstate, CreateSeqStmt *seq)
 
ObjectAddress AlterSequence (ParseState *pstate, AlterSeqStmt *stmt)
 
void SequenceChangePersistence (Oid relid, char newrelpersistence)
 
void DeleteSequenceTuple (Oid relid)
 
void ResetSequence (Oid seq_relid)
 
void SetSequence (Oid relid, int64 next, bool iscalled)
 
void ResetSequenceCaches (void)
 

Macro Definition Documentation

◆ SEQ_COL_CALLED

#define SEQ_COL_CALLED   3

Definition at line 36 of file sequence.h.

◆ SEQ_COL_FIRSTCOL

#define SEQ_COL_FIRSTCOL   SEQ_COL_LASTVAL

Definition at line 38 of file sequence.h.

◆ SEQ_COL_LASTCOL

#define SEQ_COL_LASTCOL   SEQ_COL_CALLED

Definition at line 39 of file sequence.h.

◆ SEQ_COL_LASTVAL

#define SEQ_COL_LASTVAL   1

Definition at line 34 of file sequence.h.

◆ SEQ_COL_LOG

#define SEQ_COL_LOG   2

Definition at line 35 of file sequence.h.

Typedef Documentation

◆ Form_pg_sequence_data

◆ FormData_pg_sequence_data

Function Documentation

◆ AlterSequence()

ObjectAddress AlterSequence ( ParseState pstate,
AlterSeqStmt stmt 
)
extern

Definition at line 429 of file sequence.c.

430{
431 Oid relid;
432 SeqTable elm;
434 Buffer buf;
438 bool need_seq_rewrite;
439 List *owned_by;
440 ObjectAddress address;
441 Relation rel;
443 bool reset_state = false;
444 bool is_called;
445 int64 last_value;
447
448 /* Open and lock sequence, and check for ownership along the way. */
449 relid = RangeVarGetRelidExtended(stmt->sequence,
451 stmt->missing_ok ? RVR_MISSING_OK : 0,
453 NULL);
454 if (relid == InvalidOid)
455 {
457 (errmsg("relation \"%s\" does not exist, skipping",
458 stmt->sequence->relname)));
460 }
461
462 init_sequence(relid, &elm, &seqrel);
463
466 ObjectIdGetDatum(relid));
468 elog(ERROR, "cache lookup failed for sequence %u",
469 relid);
470
472
473 /* lock page buffer and read tuple into new sequence structure */
475
476 /* copy the existing sequence data tuple, so it can be modified locally */
479 last_value = newdataform->last_value;
480 is_called = newdataform->is_called;
481
483
484 /* Check and set new values */
485 init_params(pstate, stmt->options, stmt->for_identity, false,
486 seqform, &last_value, &reset_state, &is_called,
488
489 /* If needed, rewrite the sequence relation itself */
491 {
492 /* check the comment above nextval_internal()'s equivalent call. */
495
496 /*
497 * Create a new storage file for the sequence, making the state
498 * changes transactional.
499 */
500 RelationSetNewRelfilenumber(seqrel, seqrel->rd_rel->relpersistence);
501
502 /*
503 * Ensure sequence's relfrozenxid is at 0, since it won't contain any
504 * unfrozen XIDs. Same with relminmxid, since a sequence will never
505 * contain multixacts.
506 */
507 Assert(seqrel->rd_rel->relfrozenxid == InvalidTransactionId);
508 Assert(seqrel->rd_rel->relminmxid == InvalidMultiXactId);
509
510 /*
511 * Insert the modified tuple into the new storage file.
512 */
513 newdataform->last_value = last_value;
514 newdataform->is_called = is_called;
515 if (reset_state)
516 newdataform->log_cnt = 0;
518 }
519
520 /* Clear local cache so that we don't think we have cached numbers */
521 /* Note that we do not change the currval() state */
522 elm->cached = elm->last;
523
524 /* process OWNED BY if given */
525 if (owned_by)
526 process_owned_by(seqrel, owned_by, stmt->for_identity);
527
528 /* update the pg_sequence tuple (we could skip this in some cases...) */
529 CatalogTupleUpdate(rel, &seqtuple->t_self, seqtuple);
530
532
533 ObjectAddressSet(address, RelationRelationId, relid);
534
537
538 return address;
539}
void sequence_close(Relation relation, LOCKMODE lockmode)
Definition sequence.c:58
int Buffer
Definition buf.h:23
void UnlockReleaseBuffer(Buffer buffer)
Definition bufmgr.c:5518
#define Assert(condition)
Definition c.h:873
int64_t int64
Definition c.h:543
static void fill_seq_with_data(Relation rel, HeapTuple tuple)
Definition sequence.c:331
static void init_sequence(Oid relid, SeqTable *p_elm, Relation *p_rel)
Definition sequence.c:1130
static Form_pg_sequence_data read_seq_tuple(Relation rel, Buffer *buf, HeapTuple seqdatatuple)
Definition sequence.c:1191
static void process_owned_by(Relation seqrel, List *owned_by, bool for_identity)
Definition sequence.c:1598
static void init_params(ParseState *pstate, List *options, bool for_identity, bool isInit, Form_pg_sequence seqform, int64 *last_value, bool *reset_state, bool *is_called, bool *need_seq_rewrite, List **owned_by)
Definition sequence.c:1260
FormData_pg_sequence_data * Form_pg_sequence_data
Definition sequence.h:28
int errmsg(const char *fmt,...)
Definition elog.c:1080
#define ERROR
Definition elog.h:39
#define elog(elevel,...)
Definition elog.h:226
#define NOTICE
Definition elog.h:35
#define ereport(elevel,...)
Definition elog.h:150
HeapTuple heap_copytuple(HeapTuple tuple)
Definition heaptuple.c:778
#define HeapTupleIsValid(tuple)
Definition htup.h:78
static void * GETSTRUCT(const HeapTupleData *tuple)
#define stmt
void CatalogTupleUpdate(Relation heapRel, const ItemPointerData *otid, HeapTuple tup)
Definition indexing.c:313
#define NoLock
Definition lockdefs.h:34
#define ShareRowExclusiveLock
Definition lockdefs.h:41
#define RowExclusiveLock
Definition lockdefs.h:38
#define InvalidMultiXactId
Definition multixact.h:25
Oid RangeVarGetRelidExtended(const RangeVar *relation, LOCKMODE lockmode, uint32 flags, RangeVarGetRelidCallback callback, void *callback_arg)
Definition namespace.c:440
@ RVR_MISSING_OK
Definition namespace.h:90
#define InvokeObjectPostAlterHook(classId, objectId, subId)
const ObjectAddress InvalidObjectAddress
#define ObjectAddressSet(addr, class_id, object_id)
FormData_pg_sequence * Form_pg_sequence
Definition pg_sequence.h:40
static char buf[DEFAULT_XLOG_SEG_SIZE]
static Datum ObjectIdGetDatum(Oid X)
Definition postgres.h:262
#define InvalidOid
unsigned int Oid
static int fb(int x)
#define RelationNeedsWAL(relation)
Definition rel.h:637
void RelationSetNewRelfilenumber(Relation relation, char persistence)
Definition relcache.c:3768
Definition pg_list.h:54
int64 cached
Definition sequence.c:73
int64 last
Definition sequence.c:72
#define SearchSysCacheCopy1(cacheId, key1)
Definition syscache.h:91
void table_close(Relation relation, LOCKMODE lockmode)
Definition table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition table.c:40
void RangeVarCallbackOwnsRelation(const RangeVar *relation, Oid relId, Oid oldRelId, void *arg)
#define InvalidTransactionId
Definition transam.h:31
TransactionId GetTopTransactionId(void)
Definition xact.c:427

References Assert, buf, SeqTableData::cached, CatalogTupleUpdate(), elog, ereport, errmsg(), ERROR, fb(), fill_seq_with_data(), GETSTRUCT(), GetTopTransactionId(), heap_copytuple(), HeapTupleIsValid, init_params(), init_sequence(), InvalidMultiXactId, InvalidObjectAddress, InvalidOid, InvalidTransactionId, InvokeObjectPostAlterHook, SeqTableData::last, NoLock, NOTICE, ObjectAddressSet, ObjectIdGetDatum(), process_owned_by(), RangeVarCallbackOwnsRelation(), RangeVarGetRelidExtended(), read_seq_tuple(), RelationNeedsWAL, RelationSetNewRelfilenumber(), RowExclusiveLock, RVR_MISSING_OK, SearchSysCacheCopy1, sequence_close(), ShareRowExclusiveLock, stmt, table_close(), table_open(), and UnlockReleaseBuffer().

Referenced by ProcessUtilitySlow().

◆ DefineSequence()

ObjectAddress DefineSequence ( ParseState pstate,
CreateSeqStmt seq 
)
extern

Definition at line 112 of file sequence.c.

113{
115 int64 last_value;
116 bool reset_state;
117 bool is_called;
118 bool need_seq_rewrite;
119 List *owned_by;
121 Oid seqoid;
122 ObjectAddress address;
123 Relation rel;
124 HeapTuple tuple;
125 TupleDesc tupDesc;
127 bool null[SEQ_COL_LASTCOL];
130 int i;
131
132 /*
133 * If if_not_exists was given and a relation with the same name already
134 * exists, bail out. (Note: we needn't check this when not if_not_exists,
135 * because DefineRelation will complain anyway.)
136 */
137 if (seq->if_not_exists)
138 {
140 if (OidIsValid(seqoid))
141 {
142 /*
143 * If we are in an extension script, insist that the pre-existing
144 * object be a member of the extension, to avoid security risks.
145 */
148
149 /* OK to skip */
152 errmsg("relation \"%s\" already exists, skipping",
153 seq->sequence->relname)));
155 }
156 }
157
158 /* Check and set all option values */
159 init_params(pstate, seq->options, seq->for_identity, true,
160 &seqform, &last_value, &reset_state, &is_called,
162
163 /*
164 * Create relation (and fill value[] and null[] for the tuple)
165 */
166 stmt->tableElts = NIL;
167 for (i = SEQ_COL_FIRSTCOL; i <= SEQ_COL_LASTCOL; i++)
168 {
170
171 switch (i)
172 {
173 case SEQ_COL_LASTVAL:
174 coldef = makeColumnDef("last_value", INT8OID, -1, InvalidOid);
175 value[i - 1] = Int64GetDatumFast(last_value);
176 break;
177 case SEQ_COL_LOG:
178 coldef = makeColumnDef("log_cnt", INT8OID, -1, InvalidOid);
179 value[i - 1] = Int64GetDatum((int64) 0);
180 break;
181 case SEQ_COL_CALLED:
182 coldef = makeColumnDef("is_called", BOOLOID, -1, InvalidOid);
183 value[i - 1] = BoolGetDatum(false);
184 break;
185 }
186
187 coldef->is_not_null = true;
188 null[i - 1] = false;
189
190 stmt->tableElts = lappend(stmt->tableElts, coldef);
191 }
192
193 stmt->relation = seq->sequence;
194 stmt->inhRelations = NIL;
195 stmt->constraints = NIL;
196 stmt->options = NIL;
197 stmt->oncommit = ONCOMMIT_NOOP;
198 stmt->tablespacename = NULL;
199 stmt->if_not_exists = seq->if_not_exists;
200
201 address = DefineRelation(stmt, RELKIND_SEQUENCE, seq->ownerId, NULL, NULL);
202 seqoid = address.objectId;
204
206 tupDesc = RelationGetDescr(rel);
207
208 /* now initialize the sequence's data */
209 tuple = heap_form_tuple(tupDesc, value, null);
210 fill_seq_with_data(rel, tuple);
211
212 /* process OWNED BY if given */
213 if (owned_by)
214 process_owned_by(rel, owned_by, seq->for_identity);
215
217
218 /* fill in pg_sequence */
220 tupDesc = RelationGetDescr(rel);
221
222 memset(pgs_nulls, 0, sizeof(pgs_nulls));
223
232
233 tuple = heap_form_tuple(tupDesc, pgs_values, pgs_nulls);
234 CatalogTupleInsert(rel, tuple);
235
236 heap_freetuple(tuple);
238
239 return address;
240}
Relation sequence_open(Oid relationId, LOCKMODE lockmode)
Definition sequence.c:37
#define OidIsValid(objectId)
Definition c.h:788
#define SEQ_COL_LASTVAL
Definition sequence.h:34
#define SEQ_COL_CALLED
Definition sequence.h:36
#define SEQ_COL_LASTCOL
Definition sequence.h:39
#define SEQ_COL_LOG
Definition sequence.h:35
#define SEQ_COL_FIRSTCOL
Definition sequence.h:38
int errcode(int sqlerrcode)
Definition elog.c:863
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
Definition heaptuple.c:1117
void heap_freetuple(HeapTuple htup)
Definition heaptuple.c:1435
void CatalogTupleInsert(Relation heapRel, HeapTuple tup)
Definition indexing.c:233
static struct @172 value
int i
Definition isn.c:77
List * lappend(List *list, void *datum)
Definition list.c:339
#define AccessExclusiveLock
Definition lockdefs.h:43
ColumnDef * makeColumnDef(const char *colname, Oid typeOid, int32 typmod, Oid collOid)
Definition makefuncs.c:565
Oid RangeVarGetAndCheckCreationNamespace(RangeVar *relation, LOCKMODE lockmode, Oid *existing_relation_id)
Definition namespace.c:738
#define makeNode(_type_)
Definition nodes.h:161
void checkMembershipInCurrentExtension(const ObjectAddress *object)
Definition pg_depend.c:258
#define NIL
Definition pg_list.h:68
FormData_pg_sequence
Definition pg_sequence.h:33
static Datum Int64GetDatum(int64 X)
Definition postgres.h:423
#define Int64GetDatumFast(X)
Definition postgres.h:535
static Datum BoolGetDatum(bool X)
Definition postgres.h:112
uint64_t Datum
Definition postgres.h:70
@ ONCOMMIT_NOOP
Definition primnodes.h:58
#define RelationGetDescr(relation)
Definition rel.h:540
ObjectAddress DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ObjectAddress *typaddress, const char *queryString)
Definition tablecmds.c:769

References AccessExclusiveLock, Assert, BoolGetDatum(), CatalogTupleInsert(), checkMembershipInCurrentExtension(), DefineRelation(), ereport, errcode(), errmsg(), fb(), fill_seq_with_data(), FormData_pg_sequence, heap_form_tuple(), heap_freetuple(), i, init_params(), Int64GetDatum(), Int64GetDatumFast, InvalidObjectAddress, InvalidOid, lappend(), makeColumnDef(), makeNode, NIL, NoLock, NOTICE, ObjectAddressSet, ObjectAddress::objectId, ObjectIdGetDatum(), OidIsValid, ONCOMMIT_NOOP, process_owned_by(), RangeVarGetAndCheckCreationNamespace(), RelationGetDescr, RowExclusiveLock, SEQ_COL_CALLED, SEQ_COL_FIRSTCOL, SEQ_COL_LASTCOL, SEQ_COL_LASTVAL, SEQ_COL_LOG, sequence_close(), sequence_open(), stmt, table_close(), table_open(), and value.

Referenced by ProcessUtilitySlow().

◆ DeleteSequenceTuple()

void DeleteSequenceTuple ( Oid  relid)
extern

Definition at line 571 of file sequence.c.

572{
573 Relation rel;
574 HeapTuple tuple;
575
577
579 if (!HeapTupleIsValid(tuple))
580 elog(ERROR, "cache lookup failed for sequence %u", relid);
581
582 CatalogTupleDelete(rel, &tuple->t_self);
583
584 ReleaseSysCache(tuple);
586}
void CatalogTupleDelete(Relation heapRel, const ItemPointerData *tid)
Definition indexing.c:365
ItemPointerData t_self
Definition htup.h:65
void ReleaseSysCache(HeapTuple tuple)
Definition syscache.c:264
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition syscache.c:220

References CatalogTupleDelete(), elog, ERROR, fb(), HeapTupleIsValid, ObjectIdGetDatum(), ReleaseSysCache(), RowExclusiveLock, SearchSysCache1(), HeapTupleData::t_self, table_close(), and table_open().

Referenced by doDeletion().

◆ nextval()

Datum nextval ( PG_FUNCTION_ARGS  )
extern

Definition at line 594 of file sequence.c.

595{
597 RangeVar *sequence;
598 Oid relid;
599
601
602 /*
603 * XXX: This is not safe in the presence of concurrent DDL, but acquiring
604 * a lock here is more expensive than letting nextval_internal do it,
605 * since the latter maintains a cache that keeps us from hitting the lock
606 * manager more than once per transaction. It's not clear whether the
607 * performance penalty is material in practice, but for now, we do it this
608 * way.
609 */
610 relid = RangeVarGetRelid(sequence, NoLock, false);
611
612 PG_RETURN_INT64(nextval_internal(relid, true));
613}
int64 nextval_internal(Oid relid, bool check_permissions)
Definition sequence.c:624
#define PG_GETARG_TEXT_PP(n)
Definition fmgr.h:310
#define PG_RETURN_INT64(x)
Definition fmgr.h:370
RangeVar * makeRangeVarFromNameList(const List *names)
Definition namespace.c:3624
#define RangeVarGetRelid(relation, lockmode, missing_ok)
Definition namespace.h:98
Definition c.h:706
List * textToQualifiedNameList(text *textval)
Definition varlena.c:2672

References fb(), makeRangeVarFromNameList(), nextval_internal(), NoLock, PG_GETARG_TEXT_PP, PG_RETURN_INT64, RangeVarGetRelid, and textToQualifiedNameList().

Referenced by autoinc().

◆ nextval_internal()

int64 nextval_internal ( Oid  relid,
bool  check_permissions 
)
extern

Definition at line 624 of file sequence.c.

625{
626 SeqTable elm;
628 Buffer buf;
629 Page page;
634 int64 incby,
635 maxv,
636 minv,
637 cache,
638 log,
639 fetch,
640 last;
641 int64 result,
642 next,
643 rescnt = 0;
644 bool cycle;
645 bool logit = false;
646
647 /* open and lock sequence */
648 init_sequence(relid, &elm, &seqrel);
649
650 if (check_permissions &&
655 errmsg("permission denied for sequence %s",
657
658 /* read-only transactions may only modify temp sequences */
659 if (!seqrel->rd_islocaltemp)
660 PreventCommandIfReadOnly("nextval()");
661
662 /*
663 * Forbid this during parallel operation because, to make it work, the
664 * cooperating backends would need to share the backend-local cached
665 * sequence information. Currently, we don't support that.
666 */
667 PreventCommandIfParallelMode("nextval()");
668
669 if (elm->last != elm->cached) /* some numbers were cached */
670 {
671 Assert(elm->last_valid);
672 Assert(elm->increment != 0);
673 elm->last += elm->increment;
675 last_used_seq = elm;
676 return elm->last;
677 }
678
681 elog(ERROR, "cache lookup failed for sequence %u", relid);
683 incby = pgsform->seqincrement;
684 maxv = pgsform->seqmax;
685 minv = pgsform->seqmin;
686 cache = pgsform->seqcache;
687 cycle = pgsform->seqcycle;
689
690 /* lock page buffer and read tuple */
692 page = BufferGetPage(buf);
693
694 last = next = result = seq->last_value;
695 fetch = cache;
696 log = seq->log_cnt;
697
698 if (!seq->is_called)
699 {
700 rescnt++; /* return last_value if not is_called */
701 fetch--;
702 }
703
704 /*
705 * Decide whether we should emit a WAL log record. If so, force up the
706 * fetch count to grab SEQ_LOG_VALS more values than we actually need to
707 * cache. (These will then be usable without logging.)
708 *
709 * If this is the first nextval after a checkpoint, we must force a new
710 * WAL record to be written anyway, else replay starting from the
711 * checkpoint would fail to advance the sequence past the logged values.
712 * In this case we may as well fetch extra values.
713 */
714 if (log < fetch || !seq->is_called)
715 {
716 /* forced log to satisfy local demand for values */
717 fetch = log = fetch + SEQ_LOG_VALS;
718 logit = true;
719 }
720 else
721 {
723
724 if (PageGetLSN(page) <= redoptr)
725 {
726 /* last update of seq was before checkpoint */
727 fetch = log = fetch + SEQ_LOG_VALS;
728 logit = true;
729 }
730 }
731
732 while (fetch) /* try to fetch cache [+ log ] numbers */
733 {
734 /*
735 * Check MAXVALUE for ascending sequences and MINVALUE for descending
736 * sequences
737 */
738 if (incby > 0)
739 {
740 /* ascending sequence */
741 if ((maxv >= 0 && next > maxv - incby) ||
743 {
744 if (rescnt > 0)
745 break; /* stop fetching */
746 if (!cycle)
749 errmsg("nextval: reached maximum value of sequence \"%s\" (%" PRId64 ")",
751 maxv)));
752 next = minv;
753 }
754 else
755 next += incby;
756 }
757 else
758 {
759 /* descending sequence */
760 if ((minv < 0 && next < minv - incby) ||
761 (minv >= 0 && next + incby < minv))
762 {
763 if (rescnt > 0)
764 break; /* stop fetching */
765 if (!cycle)
768 errmsg("nextval: reached minimum value of sequence \"%s\" (%" PRId64 ")",
770 minv)));
771 next = maxv;
772 }
773 else
774 next += incby;
775 }
776 fetch--;
777 if (rescnt < cache)
778 {
779 log--;
780 rescnt++;
781 last = next;
782 if (rescnt == 1) /* if it's first result - */
783 result = next; /* it's what to return */
784 }
785 }
786
787 log -= fetch; /* adjust for any unfetched numbers */
788 Assert(log >= 0);
789
790 /* save info in local cache */
791 elm->increment = incby;
792 elm->last = result; /* last returned number */
793 elm->cached = last; /* last fetched number */
794 elm->last_valid = true;
795
796 last_used_seq = elm;
797
798 /*
799 * If something needs to be WAL logged, acquire an xid, so this
800 * transaction's commit will trigger a WAL flush and wait for syncrep.
801 * It's sufficient to ensure the toplevel transaction has an xid, no need
802 * to assign xids subxacts, that'll already trigger an appropriate wait.
803 * (Have to do that here, so we're outside the critical section)
804 */
807
808 /* ready to change the on-disk (or really, in-buffer) tuple */
810
811 /*
812 * We must mark the buffer dirty before doing XLogInsert(); see notes in
813 * SyncOneBuffer(). However, we don't apply the desired changes just yet.
814 * This looks like a violation of the buffer update protocol, but it is in
815 * fact safe because we hold exclusive lock on the buffer. Any other
816 * process, including a checkpoint, that tries to examine the buffer
817 * contents will block until we release the lock, and then will see the
818 * final state that we install below.
819 */
821
822 /* XLOG stuff */
824 {
827
828 /*
829 * We don't log the current state of the tuple, but rather the state
830 * as it would appear after "log" more fetches. This lets us skip
831 * that many future WAL records, at the cost that we lose those
832 * sequence values if we crash.
833 */
836
837 /* set values that will be saved in xlog */
838 seq->last_value = next;
839 seq->is_called = true;
840 seq->log_cnt = 0;
841
842 xlrec.locator = seqrel->rd_locator;
843
846
848
849 PageSetLSN(page, recptr);
850 }
851
852 /* Now update sequence tuple to the intended final state */
853 seq->last_value = last; /* last fetched number */
854 seq->is_called = true;
855 seq->log_cnt = log; /* how much is logged */
856
858
860
862
863 return result;
864}
@ ACLCHECK_OK
Definition acl.h:183
AclResult pg_class_aclcheck(Oid table_oid, Oid roleid, AclMode mode)
Definition aclchk.c:4039
static int32 next
Definition blutils.c:225
void MarkBufferDirty(Buffer buffer)
Definition bufmgr.c:3056
static Page BufferGetPage(Buffer buffer)
Definition bufmgr.h:466
static void PageSetLSN(Page page, XLogRecPtr lsn)
Definition bufpage.h:390
PageData * Page
Definition bufpage.h:81
static XLogRecPtr PageGetLSN(const PageData *page)
Definition bufpage.h:385
static SeqTableData * last_used_seq
Definition sequence.c:87
#define SEQ_LOG_VALS
Definition sequence.c:58
#define START_CRIT_SECTION()
Definition miscadmin.h:150
#define END_CRIT_SECTION()
Definition miscadmin.h:152
Oid GetUserId(void)
Definition miscinit.c:469
#define ACL_USAGE
Definition parsenodes.h:84
#define ACL_UPDATE
Definition parsenodes.h:78
#define RelationGetRelationName(relation)
Definition rel.h:548
#define XLOG_SEQ_LOG
bool last_valid
Definition sequence.c:71
int64 increment
Definition sequence.c:75
void PreventCommandIfReadOnly(const char *cmdname)
Definition utility.c:406
void PreventCommandIfParallelMode(const char *cmdname)
Definition utility.c:424
XLogRecPtr GetRedoRecPtr(void)
Definition xlog.c:6563
uint64 XLogRecPtr
Definition xlogdefs.h:21
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition xloginsert.c:478
void XLogRegisterData(const void *data, uint32 len)
Definition xloginsert.c:368
void XLogRegisterBuffer(uint8 block_id, Buffer buffer, uint8 flags)
Definition xloginsert.c:245
void XLogBeginInsert(void)
Definition xloginsert.c:152
#define REGBUF_WILL_INIT
Definition xloginsert.h:34

References ACL_UPDATE, ACL_USAGE, ACLCHECK_OK, Assert, buf, BufferGetPage(), SeqTableData::cached, elog, END_CRIT_SECTION, ereport, errcode(), errmsg(), ERROR, fb(), GetRedoRecPtr(), GETSTRUCT(), GetTopTransactionId(), GetUserId(), HeapTupleIsValid, SeqTableData::increment, init_sequence(), SeqTableData::last, last_used_seq, SeqTableData::last_valid, MarkBufferDirty(), next, NoLock, ObjectIdGetDatum(), PageGetLSN(), PageSetLSN(), pg_class_aclcheck(), PreventCommandIfParallelMode(), PreventCommandIfReadOnly(), read_seq_tuple(), REGBUF_WILL_INIT, RelationGetRelationName, RelationNeedsWAL, ReleaseSysCache(), SeqTableData::relid, SearchSysCache1(), SEQ_LOG_VALS, sequence_close(), START_CRIT_SECTION, UnlockReleaseBuffer(), XLOG_SEQ_LOG, XLogBeginInsert(), XLogInsert(), XLogRegisterBuffer(), and XLogRegisterData().

Referenced by ExecEvalNextValueExpr(), nextval(), and nextval_oid().

◆ ResetSequence()

void ResetSequence ( Oid  seq_relid)
extern

Definition at line 255 of file sequence.c.

256{
258 SeqTable elm;
260 Buffer buf;
262 HeapTuple tuple;
265 int64 startv;
266
267 /*
268 * Read the old sequence. This does a bit more work than really
269 * necessary, but it's simple, and we do want to double-check that it's
270 * indeed a sequence.
271 */
274
277 elog(ERROR, "cache lookup failed for sequence %u", seq_relid);
279 startv = pgsform->seqstart;
281
282 /*
283 * Copy the existing sequence tuple.
284 */
286
287 /* Now we're done with the old page */
289
290 /*
291 * Modify the copied tuple to execute the restart (compare the RESTART
292 * action in AlterSequence)
293 */
295 seq->last_value = startv;
296 seq->is_called = false;
297 seq->log_cnt = 0;
298
299 /*
300 * Create a new storage file for the sequence.
301 */
302 RelationSetNewRelfilenumber(seq_rel, seq_rel->rd_rel->relpersistence);
303
304 /*
305 * Ensure sequence's relfrozenxid is at 0, since it won't contain any
306 * unfrozen XIDs. Same with relminmxid, since a sequence will never
307 * contain multixacts.
308 */
309 Assert(seq_rel->rd_rel->relfrozenxid == InvalidTransactionId);
310 Assert(seq_rel->rd_rel->relminmxid == InvalidMultiXactId);
311
312 /*
313 * Insert the modified tuple into the new storage file.
314 */
316
317 /* Clear local cache so that we don't think we have cached numbers */
318 /* Note that we do not change the currval() state */
319 elm->cached = elm->last;
320
322}

References Assert, buf, SeqTableData::cached, elog, ERROR, fb(), fill_seq_with_data(), GETSTRUCT(), heap_copytuple(), HeapTupleIsValid, init_sequence(), InvalidMultiXactId, InvalidTransactionId, SeqTableData::last, NoLock, ObjectIdGetDatum(), read_seq_tuple(), RelationSetNewRelfilenumber(), ReleaseSysCache(), SearchSysCache1(), sequence_close(), and UnlockReleaseBuffer().

Referenced by ExecuteTruncateGuts().

◆ ResetSequenceCaches()

void ResetSequenceCaches ( void  )
extern

Definition at line 1905 of file sequence.c.

1906{
1907 if (seqhashtab)
1908 {
1910 seqhashtab = NULL;
1911 }
1912
1914}
static HTAB * seqhashtab
Definition sequence.c:81
void hash_destroy(HTAB *hashp)
Definition dynahash.c:865

References fb(), hash_destroy(), last_used_seq, and seqhashtab.

Referenced by DiscardAll(), and DiscardCommand().

◆ sequence_options()

List * sequence_options ( Oid  relid)
extern

Definition at line 1712 of file sequence.c.

1713{
1716 List *options = NIL;
1717
1720 elog(ERROR, "cache lookup failed for sequence %u", relid);
1722
1723 /* Use makeFloat() for 64-bit integers, like gram.y does. */
1725 makeDefElem("cache", (Node *) makeFloat(psprintf(INT64_FORMAT, pgsform->seqcache)), -1));
1727 makeDefElem("cycle", (Node *) makeBoolean(pgsform->seqcycle), -1));
1729 makeDefElem("increment", (Node *) makeFloat(psprintf(INT64_FORMAT, pgsform->seqincrement)), -1));
1731 makeDefElem("maxvalue", (Node *) makeFloat(psprintf(INT64_FORMAT, pgsform->seqmax)), -1));
1733 makeDefElem("minvalue", (Node *) makeFloat(psprintf(INT64_FORMAT, pgsform->seqmin)), -1));
1735 makeDefElem("start", (Node *) makeFloat(psprintf(INT64_FORMAT, pgsform->seqstart)), -1));
1736
1738
1739 return options;
1740}
#define INT64_FORMAT
Definition c.h:564
DefElem * makeDefElem(char *name, Node *arg, int location)
Definition makefuncs.c:637
char * psprintf(const char *fmt,...)
Definition psprintf.c:43
Definition nodes.h:135
Float * makeFloat(char *numericStr)
Definition value.c:37
Boolean * makeBoolean(bool val)
Definition value.c:49

References elog, ERROR, fb(), GETSTRUCT(), HeapTupleIsValid, INT64_FORMAT, lappend(), makeBoolean(), makeDefElem(), makeFloat(), NIL, ObjectIdGetDatum(), psprintf(), ReleaseSysCache(), and SearchSysCache1().

Referenced by transformTableLikeClause().

◆ SequenceChangePersistence()

void SequenceChangePersistence ( Oid  relid,
char  newrelpersistence 
)
extern

Definition at line 542 of file sequence.c.

543{
544 SeqTable elm;
546 Buffer buf;
548
549 /*
550 * ALTER SEQUENCE acquires this lock earlier. If we're processing an
551 * owned sequence for ALTER TABLE, lock now. Without the lock, we'd
552 * discard increments from nextval() calls (in other sessions) between
553 * this function's buffer unlock and this transaction's commit.
554 */
556 init_sequence(relid, &elm, &seqrel);
557
558 /* check the comment above nextval_internal()'s equivalent call. */
561
563 RelationSetNewRelfilenumber(seqrel, newrelpersistence);
566
568}
void LockRelationOid(Oid relid, LOCKMODE lockmode)
Definition lmgr.c:107

References AccessExclusiveLock, buf, fb(), fill_seq_with_data(), GetTopTransactionId(), init_sequence(), LockRelationOid(), NoLock, read_seq_tuple(), RelationNeedsWAL, RelationSetNewRelfilenumber(), sequence_close(), and UnlockReleaseBuffer().

Referenced by ATRewriteTables().

◆ SetSequence()

void SetSequence ( Oid  relid,
int64  next,
bool  iscalled 
)
extern

Definition at line 946 of file sequence.c.

947{
948 SeqTable elm;
950 Buffer buf;
955 int64 maxv,
956 minv;
957
958 /* open and lock sequence */
959 init_sequence(relid, &elm, &seqrel);
960
964 errmsg("permission denied for sequence %s",
966
969 elog(ERROR, "cache lookup failed for sequence %u", relid);
971 maxv = pgsform->seqmax;
972 minv = pgsform->seqmin;
974
975 /* read-only transactions may only modify temp sequences */
976 if (!seqrel->rd_islocaltemp)
977 PreventCommandIfReadOnly("setval()");
978
979 /*
980 * Forbid this during parallel operation because, to make it work, the
981 * cooperating backends would need to share the backend-local cached
982 * sequence information. Currently, we don't support that.
983 */
985
986 /* lock page buffer and read tuple */
988
989 if ((next < minv) || (next > maxv))
992 errmsg("setval: value %" PRId64 " is out of bounds for sequence \"%s\" (%" PRId64 "..%" PRId64 ")",
994 minv, maxv)));
995
996 /* Set the currval() state only if iscalled = true */
997 if (iscalled)
998 {
999 elm->last = next; /* last returned number */
1000 elm->last_valid = true;
1001 }
1002
1003 /* In any case, forget any future cached numbers */
1004 elm->cached = elm->last;
1005
1006 /* check the comment above nextval_internal()'s equivalent call. */
1009
1010 /* ready to change the on-disk (or really, in-buffer) tuple */
1012
1013 seq->last_value = next; /* last fetched number */
1014 seq->is_called = iscalled;
1015 seq->log_cnt = 0;
1016
1018
1019 /* XLOG stuff */
1021 {
1024 Page page = BufferGetPage(buf);
1025
1028
1029 xlrec.locator = seqrel->rd_locator;
1032
1034
1035 PageSetLSN(page, recptr);
1036 }
1037
1039
1041
1043}

References ACL_UPDATE, ACLCHECK_OK, buf, BufferGetPage(), SeqTableData::cached, elog, END_CRIT_SECTION, ereport, errcode(), errmsg(), ERROR, fb(), GETSTRUCT(), GetTopTransactionId(), GetUserId(), HeapTupleIsValid, init_sequence(), SeqTableData::last, SeqTableData::last_valid, MarkBufferDirty(), next, NoLock, ObjectIdGetDatum(), PageSetLSN(), pg_class_aclcheck(), PreventCommandIfParallelMode(), PreventCommandIfReadOnly(), read_seq_tuple(), REGBUF_WILL_INIT, RelationGetRelationName, RelationNeedsWAL, ReleaseSysCache(), SeqTableData::relid, SearchSysCache1(), sequence_close(), START_CRIT_SECTION, UnlockReleaseBuffer(), XLOG_SEQ_LOG, XLogBeginInsert(), XLogInsert(), XLogRegisterBuffer(), and XLogRegisterData().

Referenced by copy_sequence(), setval3_oid(), and setval_oid().