PostgreSQL Source Code  git master
sequence.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * sequence.c
4  * PostgreSQL sequences support 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/commands/sequence.c
12  *
13  *-------------------------------------------------------------------------
14  */
15 #include "postgres.h"
16 
17 #include "access/bufmask.h"
18 #include "access/htup_details.h"
19 #include "access/multixact.h"
20 #include "access/relation.h"
21 #include "access/sequence.h"
22 #include "access/table.h"
23 #include "access/transam.h"
24 #include "access/xact.h"
25 #include "access/xlog.h"
26 #include "access/xloginsert.h"
27 #include "access/xlogutils.h"
28 #include "catalog/dependency.h"
29 #include "catalog/indexing.h"
30 #include "catalog/namespace.h"
31 #include "catalog/objectaccess.h"
32 #include "catalog/pg_sequence.h"
33 #include "catalog/pg_type.h"
34 #include "catalog/storage_xlog.h"
35 #include "commands/defrem.h"
36 #include "commands/sequence.h"
37 #include "commands/tablecmds.h"
38 #include "funcapi.h"
39 #include "miscadmin.h"
40 #include "nodes/makefuncs.h"
41 #include "parser/parse_type.h"
42 #include "storage/lmgr.h"
43 #include "storage/proc.h"
44 #include "storage/smgr.h"
45 #include "utils/acl.h"
46 #include "utils/builtins.h"
47 #include "utils/lsyscache.h"
48 #include "utils/resowner.h"
49 #include "utils/syscache.h"
50 #include "utils/varlena.h"
51 
52 
53 /*
54  * We don't want to log each fetching of a value from a sequence,
55  * so we pre-log a few fetches in advance. In the event of
56  * crash we can lose (skip over) as many values as we pre-logged.
57  */
58 #define SEQ_LOG_VALS 32
59 
60 /*
61  * The "special area" of a sequence's buffer page looks like this.
62  */
63 #define SEQ_MAGIC 0x1717
64 
65 typedef struct sequence_magic
66 {
69 
70 /*
71  * We store a SeqTable item for every sequence we have touched in the current
72  * session. This is needed to hold onto nextval/currval state. (We can't
73  * rely on the relcache, since it's only, well, a cache, and may decide to
74  * discard entries.)
75  */
76 typedef struct SeqTableData
77 {
78  Oid relid; /* pg_class OID of this sequence (hash key) */
79  RelFileNumber filenumber; /* last seen relfilenumber of this sequence */
80  LocalTransactionId lxid; /* xact in which we last did a seq op */
81  bool last_valid; /* do we have a valid "last" value? */
82  int64 last; /* value last returned by nextval */
83  int64 cached; /* last value already cached for nextval */
84  /* if last != cached, we have not used up all the cached values */
85  int64 increment; /* copy of sequence's increment field */
86  /* note that increment is zero until we first do nextval_internal() */
88 
90 
91 static HTAB *seqhashtab = NULL; /* hash table for SeqTable items */
92 
93 /*
94  * last_used_seq is updated by nextval() to point to the last used
95  * sequence.
96  */
97 static SeqTableData *last_used_seq = NULL;
98 
99 static void fill_seq_with_data(Relation rel, HeapTuple tuple);
100 static void fill_seq_fork_with_data(Relation rel, HeapTuple tuple, ForkNumber forkNum);
102 static void create_seq_hashtable(void);
103 static void init_sequence(Oid relid, SeqTable *p_elm, Relation *p_rel);
105  Buffer *buf, HeapTuple seqdatatuple);
106 static void init_params(ParseState *pstate, List *options, bool for_identity,
107  bool isInit,
108  Form_pg_sequence seqform,
109  Form_pg_sequence_data seqdataform,
110  bool *need_seq_rewrite,
111  List **owned_by);
112 static void do_setval(Oid relid, int64 next, bool iscalled);
113 static void process_owned_by(Relation seqrel, List *owned_by, bool for_identity);
114 
115 
116 /*
117  * DefineSequence
118  * Creates a new sequence relation
119  */
122 {
123  FormData_pg_sequence seqform;
124  FormData_pg_sequence_data seqdataform;
125  bool need_seq_rewrite;
126  List *owned_by;
128  Oid seqoid;
129  ObjectAddress address;
130  Relation rel;
131  HeapTuple tuple;
132  TupleDesc tupDesc;
134  bool null[SEQ_COL_LASTCOL];
135  Datum pgs_values[Natts_pg_sequence];
136  bool pgs_nulls[Natts_pg_sequence];
137  int i;
138 
139  /*
140  * If if_not_exists was given and a relation with the same name already
141  * exists, bail out. (Note: we needn't check this when not if_not_exists,
142  * because DefineRelation will complain anyway.)
143  */
144  if (seq->if_not_exists)
145  {
147  if (OidIsValid(seqoid))
148  {
149  /*
150  * If we are in an extension script, insist that the pre-existing
151  * object be a member of the extension, to avoid security risks.
152  */
153  ObjectAddressSet(address, RelationRelationId, seqoid);
155 
156  /* OK to skip */
157  ereport(NOTICE,
158  (errcode(ERRCODE_DUPLICATE_TABLE),
159  errmsg("relation \"%s\" already exists, skipping",
160  seq->sequence->relname)));
161  return InvalidObjectAddress;
162  }
163  }
164 
165  /* Check and set all option values */
166  init_params(pstate, seq->options, seq->for_identity, true,
167  &seqform, &seqdataform,
168  &need_seq_rewrite, &owned_by);
169 
170  /*
171  * Create relation (and fill value[] and null[] for the tuple)
172  */
173  stmt->tableElts = NIL;
174  for (i = SEQ_COL_FIRSTCOL; i <= SEQ_COL_LASTCOL; i++)
175  {
176  ColumnDef *coldef = NULL;
177 
178  switch (i)
179  {
180  case SEQ_COL_LASTVAL:
181  coldef = makeColumnDef("last_value", INT8OID, -1, InvalidOid);
182  value[i - 1] = Int64GetDatumFast(seqdataform.last_value);
183  break;
184  case SEQ_COL_LOG:
185  coldef = makeColumnDef("log_cnt", INT8OID, -1, InvalidOid);
186  value[i - 1] = Int64GetDatum((int64) 0);
187  break;
188  case SEQ_COL_CALLED:
189  coldef = makeColumnDef("is_called", BOOLOID, -1, InvalidOid);
190  value[i - 1] = BoolGetDatum(false);
191  break;
192  }
193 
194  coldef->is_not_null = true;
195  null[i - 1] = false;
196 
197  stmt->tableElts = lappend(stmt->tableElts, coldef);
198  }
199 
200  stmt->relation = seq->sequence;
201  stmt->inhRelations = NIL;
202  stmt->constraints = NIL;
203  stmt->options = NIL;
204  stmt->oncommit = ONCOMMIT_NOOP;
205  stmt->tablespacename = NULL;
206  stmt->if_not_exists = seq->if_not_exists;
207 
208  address = DefineRelation(stmt, RELKIND_SEQUENCE, seq->ownerId, NULL, NULL);
209  seqoid = address.objectId;
210  Assert(seqoid != InvalidOid);
211 
212  rel = sequence_open(seqoid, AccessExclusiveLock);
213  tupDesc = RelationGetDescr(rel);
214 
215  /* now initialize the sequence's data */
216  tuple = heap_form_tuple(tupDesc, value, null);
217  fill_seq_with_data(rel, tuple);
218 
219  /* process OWNED BY if given */
220  if (owned_by)
221  process_owned_by(rel, owned_by, seq->for_identity);
222 
223  sequence_close(rel, NoLock);
224 
225  /* fill in pg_sequence */
226  rel = table_open(SequenceRelationId, RowExclusiveLock);
227  tupDesc = RelationGetDescr(rel);
228 
229  memset(pgs_nulls, 0, sizeof(pgs_nulls));
230 
231  pgs_values[Anum_pg_sequence_seqrelid - 1] = ObjectIdGetDatum(seqoid);
232  pgs_values[Anum_pg_sequence_seqtypid - 1] = ObjectIdGetDatum(seqform.seqtypid);
233  pgs_values[Anum_pg_sequence_seqstart - 1] = Int64GetDatumFast(seqform.seqstart);
234  pgs_values[Anum_pg_sequence_seqincrement - 1] = Int64GetDatumFast(seqform.seqincrement);
235  pgs_values[Anum_pg_sequence_seqmax - 1] = Int64GetDatumFast(seqform.seqmax);
236  pgs_values[Anum_pg_sequence_seqmin - 1] = Int64GetDatumFast(seqform.seqmin);
237  pgs_values[Anum_pg_sequence_seqcache - 1] = Int64GetDatumFast(seqform.seqcache);
238  pgs_values[Anum_pg_sequence_seqcycle - 1] = BoolGetDatum(seqform.seqcycle);
239 
240  tuple = heap_form_tuple(tupDesc, pgs_values, pgs_nulls);
241  CatalogTupleInsert(rel, tuple);
242 
243  heap_freetuple(tuple);
245 
246  return address;
247 }
248 
249 /*
250  * Reset a sequence to its initial value.
251  *
252  * The change is made transactionally, so that on failure of the current
253  * transaction, the sequence will be restored to its previous state.
254  * We do that by creating a whole new relfilenumber for the sequence; so this
255  * works much like the rewriting forms of ALTER TABLE.
256  *
257  * Caller is assumed to have acquired AccessExclusiveLock on the sequence,
258  * which must not be released until end of transaction. Caller is also
259  * responsible for permissions checking.
260  */
261 void
262 ResetSequence(Oid seq_relid)
263 {
264  Relation seq_rel;
265  SeqTable elm;
267  Buffer buf;
268  HeapTupleData seqdatatuple;
269  HeapTuple tuple;
270  HeapTuple pgstuple;
271  Form_pg_sequence pgsform;
272  int64 startv;
273 
274  /*
275  * Read the old sequence. This does a bit more work than really
276  * necessary, but it's simple, and we do want to double-check that it's
277  * indeed a sequence.
278  */
279  init_sequence(seq_relid, &elm, &seq_rel);
280  (void) read_seq_tuple(seq_rel, &buf, &seqdatatuple);
281 
282  pgstuple = SearchSysCache1(SEQRELID, ObjectIdGetDatum(seq_relid));
283  if (!HeapTupleIsValid(pgstuple))
284  elog(ERROR, "cache lookup failed for sequence %u", seq_relid);
285  pgsform = (Form_pg_sequence) GETSTRUCT(pgstuple);
286  startv = pgsform->seqstart;
287  ReleaseSysCache(pgstuple);
288 
289  /*
290  * Copy the existing sequence tuple.
291  */
292  tuple = heap_copytuple(&seqdatatuple);
293 
294  /* Now we're done with the old page */
296 
297  /*
298  * Modify the copied tuple to execute the restart (compare the RESTART
299  * action in AlterSequence)
300  */
301  seq = (Form_pg_sequence_data) GETSTRUCT(tuple);
302  seq->last_value = startv;
303  seq->is_called = false;
304  seq->log_cnt = 0;
305 
306  /*
307  * Create a new storage file for the sequence.
308  */
309  RelationSetNewRelfilenumber(seq_rel, seq_rel->rd_rel->relpersistence);
310 
311  /*
312  * Ensure sequence's relfrozenxid is at 0, since it won't contain any
313  * unfrozen XIDs. Same with relminmxid, since a sequence will never
314  * contain multixacts.
315  */
316  Assert(seq_rel->rd_rel->relfrozenxid == InvalidTransactionId);
317  Assert(seq_rel->rd_rel->relminmxid == InvalidMultiXactId);
318 
319  /*
320  * Insert the modified tuple into the new storage file.
321  */
322  fill_seq_with_data(seq_rel, tuple);
323 
324  /* Clear local cache so that we don't think we have cached numbers */
325  /* Note that we do not change the currval() state */
326  elm->cached = elm->last;
327 
328  sequence_close(seq_rel, NoLock);
329 }
330 
331 /*
332  * Initialize a sequence's relation with the specified tuple as content
333  *
334  * This handles unlogged sequences by writing to both the main and the init
335  * fork as necessary.
336  */
337 static void
339 {
341 
342  if (rel->rd_rel->relpersistence == RELPERSISTENCE_UNLOGGED)
343  {
344  SMgrRelation srel;
345 
347  smgrcreate(srel, INIT_FORKNUM, false);
351  smgrclose(srel);
352  }
353 }
354 
355 /*
356  * Initialize a sequence's relation fork with the specified tuple as content
357  */
358 static void
360 {
361  Buffer buf;
362  Page page;
363  sequence_magic *sm;
364  OffsetNumber offnum;
365 
366  /* Initialize first page of relation with special magic number */
367 
368  buf = ExtendBufferedRel(BMR_REL(rel), forkNum, NULL,
371 
372  page = BufferGetPage(buf);
373 
374  PageInit(page, BufferGetPageSize(buf), sizeof(sequence_magic));
375  sm = (sequence_magic *) PageGetSpecialPointer(page);
376  sm->magic = SEQ_MAGIC;
377 
378  /* Now insert sequence tuple */
379 
380  /*
381  * Since VACUUM does not process sequences, we have to force the tuple to
382  * have xmin = FrozenTransactionId now. Otherwise it would become
383  * invisible to SELECTs after 2G transactions. It is okay to do this
384  * because if the current transaction aborts, no other xact will ever
385  * examine the sequence tuple anyway.
386  */
393 
394  /* check the comment above nextval_internal()'s equivalent call. */
395  if (RelationNeedsWAL(rel))
397 
399 
401 
402  offnum = PageAddItem(page, (Item) tuple->t_data, tuple->t_len,
403  InvalidOffsetNumber, false, false);
404  if (offnum != FirstOffsetNumber)
405  elog(ERROR, "failed to add sequence tuple to page");
406 
407  /* XLOG stuff */
408  if (RelationNeedsWAL(rel) || forkNum == INIT_FORKNUM)
409  {
410  xl_seq_rec xlrec;
411  XLogRecPtr recptr;
412 
413  XLogBeginInsert();
415 
416  xlrec.locator = rel->rd_locator;
417 
418  XLogRegisterData((char *) &xlrec, sizeof(xl_seq_rec));
419  XLogRegisterData((char *) tuple->t_data, tuple->t_len);
420 
421  recptr = XLogInsert(RM_SEQ_ID, XLOG_SEQ_LOG);
422 
423  PageSetLSN(page, recptr);
424  }
425 
427 
429 }
430 
431 /*
432  * AlterSequence
433  *
434  * Modify the definition of a sequence relation
435  */
438 {
439  Oid relid;
440  SeqTable elm;
441  Relation seqrel;
442  Buffer buf;
443  HeapTupleData datatuple;
444  Form_pg_sequence seqform;
445  Form_pg_sequence_data newdataform;
446  bool need_seq_rewrite;
447  List *owned_by;
448  ObjectAddress address;
449  Relation rel;
450  HeapTuple seqtuple;
451  HeapTuple newdatatuple;
452 
453  /* Open and lock sequence, and check for ownership along the way. */
454  relid = RangeVarGetRelidExtended(stmt->sequence,
456  stmt->missing_ok ? RVR_MISSING_OK : 0,
458  NULL);
459  if (relid == InvalidOid)
460  {
461  ereport(NOTICE,
462  (errmsg("relation \"%s\" does not exist, skipping",
463  stmt->sequence->relname)));
464  return InvalidObjectAddress;
465  }
466 
467  init_sequence(relid, &elm, &seqrel);
468 
469  rel = table_open(SequenceRelationId, RowExclusiveLock);
470  seqtuple = SearchSysCacheCopy1(SEQRELID,
471  ObjectIdGetDatum(relid));
472  if (!HeapTupleIsValid(seqtuple))
473  elog(ERROR, "cache lookup failed for sequence %u",
474  relid);
475 
476  seqform = (Form_pg_sequence) GETSTRUCT(seqtuple);
477 
478  /* lock page buffer and read tuple into new sequence structure */
479  (void) read_seq_tuple(seqrel, &buf, &datatuple);
480 
481  /* copy the existing sequence data tuple, so it can be modified locally */
482  newdatatuple = heap_copytuple(&datatuple);
483  newdataform = (Form_pg_sequence_data) GETSTRUCT(newdatatuple);
484 
486 
487  /* Check and set new values */
488  init_params(pstate, stmt->options, stmt->for_identity, false,
489  seqform, newdataform,
490  &need_seq_rewrite, &owned_by);
491 
492  /* If needed, rewrite the sequence relation itself */
493  if (need_seq_rewrite)
494  {
495  /* check the comment above nextval_internal()'s equivalent call. */
496  if (RelationNeedsWAL(seqrel))
498 
499  /*
500  * Create a new storage file for the sequence, making the state
501  * changes transactional.
502  */
503  RelationSetNewRelfilenumber(seqrel, seqrel->rd_rel->relpersistence);
504 
505  /*
506  * Ensure sequence's relfrozenxid is at 0, since it won't contain any
507  * unfrozen XIDs. Same with relminmxid, since a sequence will never
508  * contain multixacts.
509  */
510  Assert(seqrel->rd_rel->relfrozenxid == InvalidTransactionId);
511  Assert(seqrel->rd_rel->relminmxid == InvalidMultiXactId);
512 
513  /*
514  * Insert the modified tuple into the new storage file.
515  */
516  fill_seq_with_data(seqrel, newdatatuple);
517  }
518 
519  /* Clear local cache so that we don't think we have cached numbers */
520  /* Note that we do not change the currval() state */
521  elm->cached = elm->last;
522 
523  /* process OWNED BY if given */
524  if (owned_by)
525  process_owned_by(seqrel, owned_by, stmt->for_identity);
526 
527  /* update the pg_sequence tuple (we could skip this in some cases...) */
528  CatalogTupleUpdate(rel, &seqtuple->t_self, seqtuple);
529 
530  InvokeObjectPostAlterHook(RelationRelationId, relid, 0);
531 
532  ObjectAddressSet(address, RelationRelationId, relid);
533 
535  sequence_close(seqrel, NoLock);
536 
537  return address;
538 }
539 
540 void
541 SequenceChangePersistence(Oid relid, char newrelpersistence)
542 {
543  SeqTable elm;
544  Relation seqrel;
545  Buffer buf;
546  HeapTupleData seqdatatuple;
547 
548  /*
549  * ALTER SEQUENCE acquires this lock earlier. If we're processing an
550  * owned sequence for ALTER TABLE, lock now. Without the lock, we'd
551  * discard increments from nextval() calls (in other sessions) between
552  * this function's buffer unlock and this transaction's commit.
553  */
555  init_sequence(relid, &elm, &seqrel);
556 
557  /* check the comment above nextval_internal()'s equivalent call. */
558  if (RelationNeedsWAL(seqrel))
560 
561  (void) read_seq_tuple(seqrel, &buf, &seqdatatuple);
562  RelationSetNewRelfilenumber(seqrel, newrelpersistence);
563  fill_seq_with_data(seqrel, &seqdatatuple);
565 
566  sequence_close(seqrel, NoLock);
567 }
568 
569 void
571 {
572  Relation rel;
573  HeapTuple tuple;
574 
575  rel = table_open(SequenceRelationId, RowExclusiveLock);
576 
577  tuple = SearchSysCache1(SEQRELID, ObjectIdGetDatum(relid));
578  if (!HeapTupleIsValid(tuple))
579  elog(ERROR, "cache lookup failed for sequence %u", relid);
580 
581  CatalogTupleDelete(rel, &tuple->t_self);
582 
583  ReleaseSysCache(tuple);
585 }
586 
587 /*
588  * Note: nextval with a text argument is no longer exported as a pg_proc
589  * entry, but we keep it around to ease porting of C code that may have
590  * called the function directly.
591  */
592 Datum
594 {
595  text *seqin = PG_GETARG_TEXT_PP(0);
596  RangeVar *sequence;
597  Oid relid;
598 
600 
601  /*
602  * XXX: This is not safe in the presence of concurrent DDL, but acquiring
603  * a lock here is more expensive than letting nextval_internal do it,
604  * since the latter maintains a cache that keeps us from hitting the lock
605  * manager more than once per transaction. It's not clear whether the
606  * performance penalty is material in practice, but for now, we do it this
607  * way.
608  */
609  relid = RangeVarGetRelid(sequence, NoLock, false);
610 
611  PG_RETURN_INT64(nextval_internal(relid, true));
612 }
613 
614 Datum
616 {
617  Oid relid = PG_GETARG_OID(0);
618 
619  PG_RETURN_INT64(nextval_internal(relid, true));
620 }
621 
622 int64
623 nextval_internal(Oid relid, bool check_permissions)
624 {
625  SeqTable elm;
626  Relation seqrel;
627  Buffer buf;
628  Page page;
629  HeapTuple pgstuple;
630  Form_pg_sequence pgsform;
631  HeapTupleData seqdatatuple;
633  int64 incby,
634  maxv,
635  minv,
636  cache,
637  log,
638  fetch,
639  last;
640  int64 result,
641  next,
642  rescnt = 0;
643  bool cycle;
644  bool logit = false;
645 
646  /* open and lock sequence */
647  init_sequence(relid, &elm, &seqrel);
648 
649  if (check_permissions &&
652  ereport(ERROR,
653  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
654  errmsg("permission denied for sequence %s",
655  RelationGetRelationName(seqrel))));
656 
657  /* read-only transactions may only modify temp sequences */
658  if (!seqrel->rd_islocaltemp)
659  PreventCommandIfReadOnly("nextval()");
660 
661  /*
662  * Forbid this during parallel operation because, to make it work, the
663  * cooperating backends would need to share the backend-local cached
664  * sequence information. Currently, we don't support that.
665  */
666  PreventCommandIfParallelMode("nextval()");
667 
668  if (elm->last != elm->cached) /* some numbers were cached */
669  {
670  Assert(elm->last_valid);
671  Assert(elm->increment != 0);
672  elm->last += elm->increment;
673  sequence_close(seqrel, NoLock);
674  last_used_seq = elm;
675  return elm->last;
676  }
677 
678  pgstuple = SearchSysCache1(SEQRELID, ObjectIdGetDatum(relid));
679  if (!HeapTupleIsValid(pgstuple))
680  elog(ERROR, "cache lookup failed for sequence %u", relid);
681  pgsform = (Form_pg_sequence) GETSTRUCT(pgstuple);
682  incby = pgsform->seqincrement;
683  maxv = pgsform->seqmax;
684  minv = pgsform->seqmin;
685  cache = pgsform->seqcache;
686  cycle = pgsform->seqcycle;
687  ReleaseSysCache(pgstuple);
688 
689  /* lock page buffer and read tuple */
690  seq = read_seq_tuple(seqrel, &buf, &seqdatatuple);
691  page = BufferGetPage(buf);
692 
693  last = next = result = seq->last_value;
694  fetch = cache;
695  log = seq->log_cnt;
696 
697  if (!seq->is_called)
698  {
699  rescnt++; /* return last_value if not is_called */
700  fetch--;
701  }
702 
703  /*
704  * Decide whether we should emit a WAL log record. If so, force up the
705  * fetch count to grab SEQ_LOG_VALS more values than we actually need to
706  * cache. (These will then be usable without logging.)
707  *
708  * If this is the first nextval after a checkpoint, we must force a new
709  * WAL record to be written anyway, else replay starting from the
710  * checkpoint would fail to advance the sequence past the logged values.
711  * In this case we may as well fetch extra values.
712  */
713  if (log < fetch || !seq->is_called)
714  {
715  /* forced log to satisfy local demand for values */
716  fetch = log = fetch + SEQ_LOG_VALS;
717  logit = true;
718  }
719  else
720  {
721  XLogRecPtr redoptr = GetRedoRecPtr();
722 
723  if (PageGetLSN(page) <= redoptr)
724  {
725  /* last update of seq was before checkpoint */
726  fetch = log = fetch + SEQ_LOG_VALS;
727  logit = true;
728  }
729  }
730 
731  while (fetch) /* try to fetch cache [+ log ] numbers */
732  {
733  /*
734  * Check MAXVALUE for ascending sequences and MINVALUE for descending
735  * sequences
736  */
737  if (incby > 0)
738  {
739  /* ascending sequence */
740  if ((maxv >= 0 && next > maxv - incby) ||
741  (maxv < 0 && next + incby > maxv))
742  {
743  if (rescnt > 0)
744  break; /* stop fetching */
745  if (!cycle)
746  ereport(ERROR,
747  (errcode(ERRCODE_SEQUENCE_GENERATOR_LIMIT_EXCEEDED),
748  errmsg("nextval: reached maximum value of sequence \"%s\" (%lld)",
749  RelationGetRelationName(seqrel),
750  (long long) maxv)));
751  next = minv;
752  }
753  else
754  next += incby;
755  }
756  else
757  {
758  /* descending sequence */
759  if ((minv < 0 && next < minv - incby) ||
760  (minv >= 0 && next + incby < minv))
761  {
762  if (rescnt > 0)
763  break; /* stop fetching */
764  if (!cycle)
765  ereport(ERROR,
766  (errcode(ERRCODE_SEQUENCE_GENERATOR_LIMIT_EXCEEDED),
767  errmsg("nextval: reached minimum value of sequence \"%s\" (%lld)",
768  RelationGetRelationName(seqrel),
769  (long long) minv)));
770  next = maxv;
771  }
772  else
773  next += incby;
774  }
775  fetch--;
776  if (rescnt < cache)
777  {
778  log--;
779  rescnt++;
780  last = next;
781  if (rescnt == 1) /* if it's first result - */
782  result = next; /* it's what to return */
783  }
784  }
785 
786  log -= fetch; /* adjust for any unfetched numbers */
787  Assert(log >= 0);
788 
789  /* save info in local cache */
790  elm->increment = incby;
791  elm->last = result; /* last returned number */
792  elm->cached = last; /* last fetched number */
793  elm->last_valid = true;
794 
795  last_used_seq = elm;
796 
797  /*
798  * If something needs to be WAL logged, acquire an xid, so this
799  * transaction's commit will trigger a WAL flush and wait for syncrep.
800  * It's sufficient to ensure the toplevel transaction has an xid, no need
801  * to assign xids subxacts, that'll already trigger an appropriate wait.
802  * (Have to do that here, so we're outside the critical section)
803  */
804  if (logit && RelationNeedsWAL(seqrel))
806 
807  /* ready to change the on-disk (or really, in-buffer) tuple */
809 
810  /*
811  * We must mark the buffer dirty before doing XLogInsert(); see notes in
812  * SyncOneBuffer(). However, we don't apply the desired changes just yet.
813  * This looks like a violation of the buffer update protocol, but it is in
814  * fact safe because we hold exclusive lock on the buffer. Any other
815  * process, including a checkpoint, that tries to examine the buffer
816  * contents will block until we release the lock, and then will see the
817  * final state that we install below.
818  */
820 
821  /* XLOG stuff */
822  if (logit && RelationNeedsWAL(seqrel))
823  {
824  xl_seq_rec xlrec;
825  XLogRecPtr recptr;
826 
827  /*
828  * We don't log the current state of the tuple, but rather the state
829  * as it would appear after "log" more fetches. This lets us skip
830  * that many future WAL records, at the cost that we lose those
831  * sequence values if we crash.
832  */
833  XLogBeginInsert();
835 
836  /* set values that will be saved in xlog */
837  seq->last_value = next;
838  seq->is_called = true;
839  seq->log_cnt = 0;
840 
841  xlrec.locator = seqrel->rd_locator;
842 
843  XLogRegisterData((char *) &xlrec, sizeof(xl_seq_rec));
844  XLogRegisterData((char *) seqdatatuple.t_data, seqdatatuple.t_len);
845 
846  recptr = XLogInsert(RM_SEQ_ID, XLOG_SEQ_LOG);
847 
848  PageSetLSN(page, recptr);
849  }
850 
851  /* Now update sequence tuple to the intended final state */
852  seq->last_value = last; /* last fetched number */
853  seq->is_called = true;
854  seq->log_cnt = log; /* how much is logged */
855 
857 
859 
860  sequence_close(seqrel, NoLock);
861 
862  return result;
863 }
864 
865 Datum
867 {
868  Oid relid = PG_GETARG_OID(0);
869  int64 result;
870  SeqTable elm;
871  Relation seqrel;
872 
873  /* open and lock sequence */
874  init_sequence(relid, &elm, &seqrel);
875 
876  if (pg_class_aclcheck(elm->relid, GetUserId(),
878  ereport(ERROR,
879  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
880  errmsg("permission denied for sequence %s",
881  RelationGetRelationName(seqrel))));
882 
883  if (!elm->last_valid)
884  ereport(ERROR,
885  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
886  errmsg("currval of sequence \"%s\" is not yet defined in this session",
887  RelationGetRelationName(seqrel))));
888 
889  result = elm->last;
890 
891  sequence_close(seqrel, NoLock);
892 
893  PG_RETURN_INT64(result);
894 }
895 
896 Datum
898 {
899  Relation seqrel;
900  int64 result;
901 
902  if (last_used_seq == NULL)
903  ereport(ERROR,
904  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
905  errmsg("lastval is not yet defined in this session")));
906 
907  /* Someone may have dropped the sequence since the last nextval() */
909  ereport(ERROR,
910  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
911  errmsg("lastval is not yet defined in this session")));
912 
914 
915  /* nextval() must have already been called for this sequence */
917 
920  ereport(ERROR,
921  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
922  errmsg("permission denied for sequence %s",
923  RelationGetRelationName(seqrel))));
924 
925  result = last_used_seq->last;
926  sequence_close(seqrel, NoLock);
927 
928  PG_RETURN_INT64(result);
929 }
930 
931 /*
932  * Main internal procedure that handles 2 & 3 arg forms of SETVAL.
933  *
934  * Note that the 3 arg version (which sets the is_called flag) is
935  * only for use in pg_dump, and setting the is_called flag may not
936  * work if multiple users are attached to the database and referencing
937  * the sequence (unlikely if pg_dump is restoring it).
938  *
939  * It is necessary to have the 3 arg version so that pg_dump can
940  * restore the state of a sequence exactly during data-only restores -
941  * it is the only way to clear the is_called flag in an existing
942  * sequence.
943  */
944 static void
945 do_setval(Oid relid, int64 next, bool iscalled)
946 {
947  SeqTable elm;
948  Relation seqrel;
949  Buffer buf;
950  HeapTupleData seqdatatuple;
952  HeapTuple pgstuple;
953  Form_pg_sequence pgsform;
954  int64 maxv,
955  minv;
956 
957  /* open and lock sequence */
958  init_sequence(relid, &elm, &seqrel);
959 
961  ereport(ERROR,
962  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
963  errmsg("permission denied for sequence %s",
964  RelationGetRelationName(seqrel))));
965 
966  pgstuple = SearchSysCache1(SEQRELID, ObjectIdGetDatum(relid));
967  if (!HeapTupleIsValid(pgstuple))
968  elog(ERROR, "cache lookup failed for sequence %u", relid);
969  pgsform = (Form_pg_sequence) GETSTRUCT(pgstuple);
970  maxv = pgsform->seqmax;
971  minv = pgsform->seqmin;
972  ReleaseSysCache(pgstuple);
973 
974  /* read-only transactions may only modify temp sequences */
975  if (!seqrel->rd_islocaltemp)
976  PreventCommandIfReadOnly("setval()");
977 
978  /*
979  * Forbid this during parallel operation because, to make it work, the
980  * cooperating backends would need to share the backend-local cached
981  * sequence information. Currently, we don't support that.
982  */
983  PreventCommandIfParallelMode("setval()");
984 
985  /* lock page buffer and read tuple */
986  seq = read_seq_tuple(seqrel, &buf, &seqdatatuple);
987 
988  if ((next < minv) || (next > maxv))
989  ereport(ERROR,
990  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
991  errmsg("setval: value %lld is out of bounds for sequence \"%s\" (%lld..%lld)",
992  (long long) next, RelationGetRelationName(seqrel),
993  (long long) minv, (long long) maxv)));
994 
995  /* Set the currval() state only if iscalled = true */
996  if (iscalled)
997  {
998  elm->last = next; /* last returned number */
999  elm->last_valid = true;
1000  }
1001 
1002  /* In any case, forget any future cached numbers */
1003  elm->cached = elm->last;
1004 
1005  /* check the comment above nextval_internal()'s equivalent call. */
1006  if (RelationNeedsWAL(seqrel))
1008 
1009  /* ready to change the on-disk (or really, in-buffer) tuple */
1011 
1012  seq->last_value = next; /* last fetched number */
1013  seq->is_called = iscalled;
1014  seq->log_cnt = 0;
1015 
1017 
1018  /* XLOG stuff */
1019  if (RelationNeedsWAL(seqrel))
1020  {
1021  xl_seq_rec xlrec;
1022  XLogRecPtr recptr;
1023  Page page = BufferGetPage(buf);
1024 
1025  XLogBeginInsert();
1027 
1028  xlrec.locator = seqrel->rd_locator;
1029  XLogRegisterData((char *) &xlrec, sizeof(xl_seq_rec));
1030  XLogRegisterData((char *) seqdatatuple.t_data, seqdatatuple.t_len);
1031 
1032  recptr = XLogInsert(RM_SEQ_ID, XLOG_SEQ_LOG);
1033 
1034  PageSetLSN(page, recptr);
1035  }
1036 
1037  END_CRIT_SECTION();
1038 
1040 
1041  sequence_close(seqrel, NoLock);
1042 }
1043 
1044 /*
1045  * Implement the 2 arg setval procedure.
1046  * See do_setval for discussion.
1047  */
1048 Datum
1050 {
1051  Oid relid = PG_GETARG_OID(0);
1052  int64 next = PG_GETARG_INT64(1);
1053 
1054  do_setval(relid, next, true);
1055 
1057 }
1058 
1059 /*
1060  * Implement the 3 arg setval procedure.
1061  * See do_setval for discussion.
1062  */
1063 Datum
1065 {
1066  Oid relid = PG_GETARG_OID(0);
1067  int64 next = PG_GETARG_INT64(1);
1068  bool iscalled = PG_GETARG_BOOL(2);
1069 
1070  do_setval(relid, next, iscalled);
1071 
1073 }
1074 
1075 
1076 /*
1077  * Open the sequence and acquire lock if needed
1078  *
1079  * If we haven't touched the sequence already in this transaction,
1080  * we need to acquire a lock. We arrange for the lock to
1081  * be owned by the top transaction, so that we don't need to do it
1082  * more than once per xact.
1083  */
1084 static Relation
1086 {
1087  LocalTransactionId thislxid = MyProc->vxid.lxid;
1088 
1089  /* Get the lock if not already held in this xact */
1090  if (seq->lxid != thislxid)
1091  {
1092  ResourceOwner currentOwner;
1093 
1094  currentOwner = CurrentResourceOwner;
1096 
1098 
1099  CurrentResourceOwner = currentOwner;
1100 
1101  /* Flag that we have a lock in the current xact */
1102  seq->lxid = thislxid;
1103  }
1104 
1105  /* We now know we have the lock, and can safely open the rel */
1106  return sequence_open(seq->relid, NoLock);
1107 }
1108 
1109 /*
1110  * Creates the hash table for storing sequence data
1111  */
1112 static void
1114 {
1115  HASHCTL ctl;
1116 
1117  ctl.keysize = sizeof(Oid);
1118  ctl.entrysize = sizeof(SeqTableData);
1119 
1120  seqhashtab = hash_create("Sequence values", 16, &ctl,
1121  HASH_ELEM | HASH_BLOBS);
1122 }
1123 
1124 /*
1125  * Given a relation OID, open and lock the sequence. p_elm and p_rel are
1126  * output parameters.
1127  */
1128 static void
1129 init_sequence(Oid relid, SeqTable *p_elm, Relation *p_rel)
1130 {
1131  SeqTable elm;
1132  Relation seqrel;
1133  bool found;
1134 
1135  /* Find or create a hash table entry for this sequence */
1136  if (seqhashtab == NULL)
1138 
1139  elm = (SeqTable) hash_search(seqhashtab, &relid, HASH_ENTER, &found);
1140 
1141  /*
1142  * Initialize the new hash table entry if it did not exist already.
1143  *
1144  * NOTE: seqhashtab entries are stored for the life of a backend (unless
1145  * explicitly discarded with DISCARD). If the sequence itself is deleted
1146  * then the entry becomes wasted memory, but it's small enough that this
1147  * should not matter.
1148  */
1149  if (!found)
1150  {
1151  /* relid already filled in */
1154  elm->last_valid = false;
1155  elm->last = elm->cached = 0;
1156  }
1157 
1158  /*
1159  * Open the sequence relation.
1160  */
1161  seqrel = lock_and_open_sequence(elm);
1162 
1163  /*
1164  * If the sequence has been transactionally replaced since we last saw it,
1165  * discard any cached-but-unissued values. We do not touch the currval()
1166  * state, however.
1167  */
1168  if (seqrel->rd_rel->relfilenode != elm->filenumber)
1169  {
1170  elm->filenumber = seqrel->rd_rel->relfilenode;
1171  elm->cached = elm->last;
1172  }
1173 
1174  /* Return results */
1175  *p_elm = elm;
1176  *p_rel = seqrel;
1177 }
1178 
1179 
1180 /*
1181  * Given an opened sequence relation, lock the page buffer and find the tuple
1182  *
1183  * *buf receives the reference to the pinned-and-ex-locked buffer
1184  * *seqdatatuple receives the reference to the sequence tuple proper
1185  * (this arg should point to a local variable of type HeapTupleData)
1186  *
1187  * Function's return value points to the data payload of the tuple
1188  */
1189 static Form_pg_sequence_data
1191 {
1192  Page page;
1193  ItemId lp;
1194  sequence_magic *sm;
1196 
1197  *buf = ReadBuffer(rel, 0);
1199 
1200  page = BufferGetPage(*buf);
1201  sm = (sequence_magic *) PageGetSpecialPointer(page);
1202 
1203  if (sm->magic != SEQ_MAGIC)
1204  elog(ERROR, "bad magic number in sequence \"%s\": %08X",
1205  RelationGetRelationName(rel), sm->magic);
1206 
1207  lp = PageGetItemId(page, FirstOffsetNumber);
1208  Assert(ItemIdIsNormal(lp));
1209 
1210  /* Note we currently only bother to set these two fields of *seqdatatuple */
1211  seqdatatuple->t_data = (HeapTupleHeader) PageGetItem(page, lp);
1212  seqdatatuple->t_len = ItemIdGetLength(lp);
1213 
1214  /*
1215  * Previous releases of Postgres neglected to prevent SELECT FOR UPDATE on
1216  * a sequence, which would leave a non-frozen XID in the sequence tuple's
1217  * xmax, which eventually leads to clog access failures or worse. If we
1218  * see this has happened, clean up after it. We treat this like a hint
1219  * bit update, ie, don't bother to WAL-log it, since we can certainly do
1220  * this again if the update gets lost.
1221  */
1222  Assert(!(seqdatatuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI));
1224  {
1226  seqdatatuple->t_data->t_infomask &= ~HEAP_XMAX_COMMITTED;
1227  seqdatatuple->t_data->t_infomask |= HEAP_XMAX_INVALID;
1228  MarkBufferDirtyHint(*buf, true);
1229  }
1230 
1231  seq = (Form_pg_sequence_data) GETSTRUCT(seqdatatuple);
1232 
1233  return seq;
1234 }
1235 
1236 /*
1237  * init_params: process the options list of CREATE or ALTER SEQUENCE, and
1238  * store the values into appropriate fields of seqform, for changes that go
1239  * into the pg_sequence catalog, and fields of seqdataform for changes to the
1240  * sequence relation itself. Set *need_seq_rewrite to true if we changed any
1241  * parameters that require rewriting the sequence's relation (interesting for
1242  * ALTER SEQUENCE). Also set *owned_by to any OWNED BY option, or to NIL if
1243  * there is none.
1244  *
1245  * If isInit is true, fill any unspecified options with default values;
1246  * otherwise, do not change existing options that aren't explicitly overridden.
1247  *
1248  * Note: we force a sequence rewrite whenever we change parameters that affect
1249  * generation of future sequence values, even if the seqdataform per se is not
1250  * changed. This allows ALTER SEQUENCE to behave transactionally. Currently,
1251  * the only option that doesn't cause that is OWNED BY. It's *necessary* for
1252  * ALTER SEQUENCE OWNED BY to not rewrite the sequence, because that would
1253  * break pg_upgrade by causing unwanted changes in the sequence's
1254  * relfilenumber.
1255  */
1256 static void
1257 init_params(ParseState *pstate, List *options, bool for_identity,
1258  bool isInit,
1259  Form_pg_sequence seqform,
1260  Form_pg_sequence_data seqdataform,
1261  bool *need_seq_rewrite,
1262  List **owned_by)
1263 {
1264  DefElem *as_type = NULL;
1265  DefElem *start_value = NULL;
1266  DefElem *restart_value = NULL;
1267  DefElem *increment_by = NULL;
1268  DefElem *max_value = NULL;
1269  DefElem *min_value = NULL;
1270  DefElem *cache_value = NULL;
1271  DefElem *is_cycled = NULL;
1272  ListCell *option;
1273  bool reset_max_value = false;
1274  bool reset_min_value = false;
1275 
1276  *need_seq_rewrite = false;
1277  *owned_by = NIL;
1278 
1279  foreach(option, options)
1280  {
1281  DefElem *defel = (DefElem *) lfirst(option);
1282 
1283  if (strcmp(defel->defname, "as") == 0)
1284  {
1285  if (as_type)
1286  errorConflictingDefElem(defel, pstate);
1287  as_type = defel;
1288  *need_seq_rewrite = true;
1289  }
1290  else if (strcmp(defel->defname, "increment") == 0)
1291  {
1292  if (increment_by)
1293  errorConflictingDefElem(defel, pstate);
1294  increment_by = defel;
1295  *need_seq_rewrite = true;
1296  }
1297  else if (strcmp(defel->defname, "start") == 0)
1298  {
1299  if (start_value)
1300  errorConflictingDefElem(defel, pstate);
1301  start_value = defel;
1302  *need_seq_rewrite = true;
1303  }
1304  else if (strcmp(defel->defname, "restart") == 0)
1305  {
1306  if (restart_value)
1307  errorConflictingDefElem(defel, pstate);
1308  restart_value = defel;
1309  *need_seq_rewrite = true;
1310  }
1311  else if (strcmp(defel->defname, "maxvalue") == 0)
1312  {
1313  if (max_value)
1314  errorConflictingDefElem(defel, pstate);
1315  max_value = defel;
1316  *need_seq_rewrite = true;
1317  }
1318  else if (strcmp(defel->defname, "minvalue") == 0)
1319  {
1320  if (min_value)
1321  errorConflictingDefElem(defel, pstate);
1322  min_value = defel;
1323  *need_seq_rewrite = true;
1324  }
1325  else if (strcmp(defel->defname, "cache") == 0)
1326  {
1327  if (cache_value)
1328  errorConflictingDefElem(defel, pstate);
1329  cache_value = defel;
1330  *need_seq_rewrite = true;
1331  }
1332  else if (strcmp(defel->defname, "cycle") == 0)
1333  {
1334  if (is_cycled)
1335  errorConflictingDefElem(defel, pstate);
1336  is_cycled = defel;
1337  *need_seq_rewrite = true;
1338  }
1339  else if (strcmp(defel->defname, "owned_by") == 0)
1340  {
1341  if (*owned_by)
1342  errorConflictingDefElem(defel, pstate);
1343  *owned_by = defGetQualifiedName(defel);
1344  }
1345  else if (strcmp(defel->defname, "sequence_name") == 0)
1346  {
1347  /*
1348  * The parser allows this, but it is only for identity columns, in
1349  * which case it is filtered out in parse_utilcmd.c. We only get
1350  * here if someone puts it into a CREATE SEQUENCE, where it'd be
1351  * redundant. (The same is true for the equally-nonstandard
1352  * LOGGED and UNLOGGED options, but for those, the default error
1353  * below seems sufficient.)
1354  */
1355  ereport(ERROR,
1356  (errcode(ERRCODE_SYNTAX_ERROR),
1357  errmsg("invalid sequence option SEQUENCE NAME"),
1358  parser_errposition(pstate, defel->location)));
1359  }
1360  else
1361  elog(ERROR, "option \"%s\" not recognized",
1362  defel->defname);
1363  }
1364 
1365  /*
1366  * We must reset log_cnt when isInit or when changing any parameters that
1367  * would affect future nextval allocations.
1368  */
1369  if (isInit)
1370  seqdataform->log_cnt = 0;
1371 
1372  /* AS type */
1373  if (as_type != NULL)
1374  {
1375  Oid newtypid = typenameTypeId(pstate, defGetTypeName(as_type));
1376 
1377  if (newtypid != INT2OID &&
1378  newtypid != INT4OID &&
1379  newtypid != INT8OID)
1380  ereport(ERROR,
1381  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1382  for_identity
1383  ? errmsg("identity column type must be smallint, integer, or bigint")
1384  : errmsg("sequence type must be smallint, integer, or bigint")));
1385 
1386  if (!isInit)
1387  {
1388  /*
1389  * When changing type and the old sequence min/max values were the
1390  * min/max of the old type, adjust sequence min/max values to
1391  * min/max of new type. (Otherwise, the user chose explicit
1392  * min/max values, which we'll leave alone.)
1393  */
1394  if ((seqform->seqtypid == INT2OID && seqform->seqmax == PG_INT16_MAX) ||
1395  (seqform->seqtypid == INT4OID && seqform->seqmax == PG_INT32_MAX) ||
1396  (seqform->seqtypid == INT8OID && seqform->seqmax == PG_INT64_MAX))
1397  reset_max_value = true;
1398  if ((seqform->seqtypid == INT2OID && seqform->seqmin == PG_INT16_MIN) ||
1399  (seqform->seqtypid == INT4OID && seqform->seqmin == PG_INT32_MIN) ||
1400  (seqform->seqtypid == INT8OID && seqform->seqmin == PG_INT64_MIN))
1401  reset_min_value = true;
1402  }
1403 
1404  seqform->seqtypid = newtypid;
1405  }
1406  else if (isInit)
1407  {
1408  seqform->seqtypid = INT8OID;
1409  }
1410 
1411  /* INCREMENT BY */
1412  if (increment_by != NULL)
1413  {
1414  seqform->seqincrement = defGetInt64(increment_by);
1415  if (seqform->seqincrement == 0)
1416  ereport(ERROR,
1417  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1418  errmsg("INCREMENT must not be zero")));
1419  seqdataform->log_cnt = 0;
1420  }
1421  else if (isInit)
1422  {
1423  seqform->seqincrement = 1;
1424  }
1425 
1426  /* CYCLE */
1427  if (is_cycled != NULL)
1428  {
1429  seqform->seqcycle = boolVal(is_cycled->arg);
1430  Assert(BoolIsValid(seqform->seqcycle));
1431  seqdataform->log_cnt = 0;
1432  }
1433  else if (isInit)
1434  {
1435  seqform->seqcycle = false;
1436  }
1437 
1438  /* MAXVALUE (null arg means NO MAXVALUE) */
1439  if (max_value != NULL && max_value->arg)
1440  {
1441  seqform->seqmax = defGetInt64(max_value);
1442  seqdataform->log_cnt = 0;
1443  }
1444  else if (isInit || max_value != NULL || reset_max_value)
1445  {
1446  if (seqform->seqincrement > 0 || reset_max_value)
1447  {
1448  /* ascending seq */
1449  if (seqform->seqtypid == INT2OID)
1450  seqform->seqmax = PG_INT16_MAX;
1451  else if (seqform->seqtypid == INT4OID)
1452  seqform->seqmax = PG_INT32_MAX;
1453  else
1454  seqform->seqmax = PG_INT64_MAX;
1455  }
1456  else
1457  seqform->seqmax = -1; /* descending seq */
1458  seqdataform->log_cnt = 0;
1459  }
1460 
1461  /* Validate maximum value. No need to check INT8 as seqmax is an int64 */
1462  if ((seqform->seqtypid == INT2OID && (seqform->seqmax < PG_INT16_MIN || seqform->seqmax > PG_INT16_MAX))
1463  || (seqform->seqtypid == INT4OID && (seqform->seqmax < PG_INT32_MIN || seqform->seqmax > PG_INT32_MAX)))
1464  ereport(ERROR,
1465  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1466  errmsg("MAXVALUE (%lld) is out of range for sequence data type %s",
1467  (long long) seqform->seqmax,
1468  format_type_be(seqform->seqtypid))));
1469 
1470  /* MINVALUE (null arg means NO MINVALUE) */
1471  if (min_value != NULL && min_value->arg)
1472  {
1473  seqform->seqmin = defGetInt64(min_value);
1474  seqdataform->log_cnt = 0;
1475  }
1476  else if (isInit || min_value != NULL || reset_min_value)
1477  {
1478  if (seqform->seqincrement < 0 || reset_min_value)
1479  {
1480  /* descending seq */
1481  if (seqform->seqtypid == INT2OID)
1482  seqform->seqmin = PG_INT16_MIN;
1483  else if (seqform->seqtypid == INT4OID)
1484  seqform->seqmin = PG_INT32_MIN;
1485  else
1486  seqform->seqmin = PG_INT64_MIN;
1487  }
1488  else
1489  seqform->seqmin = 1; /* ascending seq */
1490  seqdataform->log_cnt = 0;
1491  }
1492 
1493  /* Validate minimum value. No need to check INT8 as seqmin is an int64 */
1494  if ((seqform->seqtypid == INT2OID && (seqform->seqmin < PG_INT16_MIN || seqform->seqmin > PG_INT16_MAX))
1495  || (seqform->seqtypid == INT4OID && (seqform->seqmin < PG_INT32_MIN || seqform->seqmin > PG_INT32_MAX)))
1496  ereport(ERROR,
1497  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1498  errmsg("MINVALUE (%lld) is out of range for sequence data type %s",
1499  (long long) seqform->seqmin,
1500  format_type_be(seqform->seqtypid))));
1501 
1502  /* crosscheck min/max */
1503  if (seqform->seqmin >= seqform->seqmax)
1504  ereport(ERROR,
1505  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1506  errmsg("MINVALUE (%lld) must be less than MAXVALUE (%lld)",
1507  (long long) seqform->seqmin,
1508  (long long) seqform->seqmax)));
1509 
1510  /* START WITH */
1511  if (start_value != NULL)
1512  {
1513  seqform->seqstart = defGetInt64(start_value);
1514  }
1515  else if (isInit)
1516  {
1517  if (seqform->seqincrement > 0)
1518  seqform->seqstart = seqform->seqmin; /* ascending seq */
1519  else
1520  seqform->seqstart = seqform->seqmax; /* descending seq */
1521  }
1522 
1523  /* crosscheck START */
1524  if (seqform->seqstart < seqform->seqmin)
1525  ereport(ERROR,
1526  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1527  errmsg("START value (%lld) cannot be less than MINVALUE (%lld)",
1528  (long long) seqform->seqstart,
1529  (long long) seqform->seqmin)));
1530  if (seqform->seqstart > seqform->seqmax)
1531  ereport(ERROR,
1532  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1533  errmsg("START value (%lld) cannot be greater than MAXVALUE (%lld)",
1534  (long long) seqform->seqstart,
1535  (long long) seqform->seqmax)));
1536 
1537  /* RESTART [WITH] */
1538  if (restart_value != NULL)
1539  {
1540  if (restart_value->arg != NULL)
1541  seqdataform->last_value = defGetInt64(restart_value);
1542  else
1543  seqdataform->last_value = seqform->seqstart;
1544  seqdataform->is_called = false;
1545  seqdataform->log_cnt = 0;
1546  }
1547  else if (isInit)
1548  {
1549  seqdataform->last_value = seqform->seqstart;
1550  seqdataform->is_called = false;
1551  }
1552 
1553  /* crosscheck RESTART (or current value, if changing MIN/MAX) */
1554  if (seqdataform->last_value < seqform->seqmin)
1555  ereport(ERROR,
1556  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1557  errmsg("RESTART value (%lld) cannot be less than MINVALUE (%lld)",
1558  (long long) seqdataform->last_value,
1559  (long long) seqform->seqmin)));
1560  if (seqdataform->last_value > seqform->seqmax)
1561  ereport(ERROR,
1562  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1563  errmsg("RESTART value (%lld) cannot be greater than MAXVALUE (%lld)",
1564  (long long) seqdataform->last_value,
1565  (long long) seqform->seqmax)));
1566 
1567  /* CACHE */
1568  if (cache_value != NULL)
1569  {
1570  seqform->seqcache = defGetInt64(cache_value);
1571  if (seqform->seqcache <= 0)
1572  ereport(ERROR,
1573  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1574  errmsg("CACHE (%lld) must be greater than zero",
1575  (long long) seqform->seqcache)));
1576  seqdataform->log_cnt = 0;
1577  }
1578  else if (isInit)
1579  {
1580  seqform->seqcache = 1;
1581  }
1582 }
1583 
1584 /*
1585  * Process an OWNED BY option for CREATE/ALTER SEQUENCE
1586  *
1587  * Ownership permissions on the sequence are already checked,
1588  * but if we are establishing a new owned-by dependency, we must
1589  * enforce that the referenced table has the same owner and namespace
1590  * as the sequence.
1591  */
1592 static void
1593 process_owned_by(Relation seqrel, List *owned_by, bool for_identity)
1594 {
1595  DependencyType deptype;
1596  int nnames;
1597  Relation tablerel;
1599 
1600  deptype = for_identity ? DEPENDENCY_INTERNAL : DEPENDENCY_AUTO;
1601 
1602  nnames = list_length(owned_by);
1603  Assert(nnames > 0);
1604  if (nnames == 1)
1605  {
1606  /* Must be OWNED BY NONE */
1607  if (strcmp(strVal(linitial(owned_by)), "none") != 0)
1608  ereport(ERROR,
1609  (errcode(ERRCODE_SYNTAX_ERROR),
1610  errmsg("invalid OWNED BY option"),
1611  errhint("Specify OWNED BY table.column or OWNED BY NONE.")));
1612  tablerel = NULL;
1613  attnum = 0;
1614  }
1615  else
1616  {
1617  List *relname;
1618  char *attrname;
1619  RangeVar *rel;
1620 
1621  /* Separate relname and attr name */
1622  relname = list_copy_head(owned_by, nnames - 1);
1623  attrname = strVal(llast(owned_by));
1624 
1625  /* Open and lock rel to ensure it won't go away meanwhile */
1627  tablerel = relation_openrv(rel, AccessShareLock);
1628 
1629  /* Must be a regular or foreign table */
1630  if (!(tablerel->rd_rel->relkind == RELKIND_RELATION ||
1631  tablerel->rd_rel->relkind == RELKIND_FOREIGN_TABLE ||
1632  tablerel->rd_rel->relkind == RELKIND_VIEW ||
1633  tablerel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE))
1634  ereport(ERROR,
1635  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1636  errmsg("sequence cannot be owned by relation \"%s\"",
1637  RelationGetRelationName(tablerel)),
1638  errdetail_relkind_not_supported(tablerel->rd_rel->relkind)));
1639 
1640  /* We insist on same owner and schema */
1641  if (seqrel->rd_rel->relowner != tablerel->rd_rel->relowner)
1642  ereport(ERROR,
1643  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1644  errmsg("sequence must have same owner as table it is linked to")));
1645  if (RelationGetNamespace(seqrel) != RelationGetNamespace(tablerel))
1646  ereport(ERROR,
1647  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1648  errmsg("sequence must be in same schema as table it is linked to")));
1649 
1650  /* Now, fetch the attribute number from the system cache */
1651  attnum = get_attnum(RelationGetRelid(tablerel), attrname);
1652  if (attnum == InvalidAttrNumber)
1653  ereport(ERROR,
1654  (errcode(ERRCODE_UNDEFINED_COLUMN),
1655  errmsg("column \"%s\" of relation \"%s\" does not exist",
1656  attrname, RelationGetRelationName(tablerel))));
1657  }
1658 
1659  /*
1660  * Catch user explicitly running OWNED BY on identity sequence.
1661  */
1662  if (deptype == DEPENDENCY_AUTO)
1663  {
1664  Oid tableId;
1665  int32 colId;
1666 
1667  if (sequenceIsOwned(RelationGetRelid(seqrel), DEPENDENCY_INTERNAL, &tableId, &colId))
1668  ereport(ERROR,
1669  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1670  errmsg("cannot change ownership of identity sequence"),
1671  errdetail("Sequence \"%s\" is linked to table \"%s\".",
1672  RelationGetRelationName(seqrel),
1673  get_rel_name(tableId))));
1674  }
1675 
1676  /*
1677  * OK, we are ready to update pg_depend. First remove any existing
1678  * dependencies for the sequence, then optionally add a new one.
1679  */
1680  deleteDependencyRecordsForClass(RelationRelationId, RelationGetRelid(seqrel),
1681  RelationRelationId, deptype);
1682 
1683  if (tablerel)
1684  {
1685  ObjectAddress refobject,
1686  depobject;
1687 
1688  refobject.classId = RelationRelationId;
1689  refobject.objectId = RelationGetRelid(tablerel);
1690  refobject.objectSubId = attnum;
1691  depobject.classId = RelationRelationId;
1692  depobject.objectId = RelationGetRelid(seqrel);
1693  depobject.objectSubId = 0;
1694  recordDependencyOn(&depobject, &refobject, deptype);
1695  }
1696 
1697  /* Done, but hold lock until commit */
1698  if (tablerel)
1699  relation_close(tablerel, NoLock);
1700 }
1701 
1702 
1703 /*
1704  * Return sequence parameters in a list of the form created by the parser.
1705  */
1706 List *
1708 {
1709  HeapTuple pgstuple;
1710  Form_pg_sequence pgsform;
1711  List *options = NIL;
1712 
1713  pgstuple = SearchSysCache1(SEQRELID, ObjectIdGetDatum(relid));
1714  if (!HeapTupleIsValid(pgstuple))
1715  elog(ERROR, "cache lookup failed for sequence %u", relid);
1716  pgsform = (Form_pg_sequence) GETSTRUCT(pgstuple);
1717 
1718  /* Use makeFloat() for 64-bit integers, like gram.y does. */
1720  makeDefElem("cache", (Node *) makeFloat(psprintf(INT64_FORMAT, pgsform->seqcache)), -1));
1722  makeDefElem("cycle", (Node *) makeBoolean(pgsform->seqcycle), -1));
1724  makeDefElem("increment", (Node *) makeFloat(psprintf(INT64_FORMAT, pgsform->seqincrement)), -1));
1726  makeDefElem("maxvalue", (Node *) makeFloat(psprintf(INT64_FORMAT, pgsform->seqmax)), -1));
1728  makeDefElem("minvalue", (Node *) makeFloat(psprintf(INT64_FORMAT, pgsform->seqmin)), -1));
1730  makeDefElem("start", (Node *) makeFloat(psprintf(INT64_FORMAT, pgsform->seqstart)), -1));
1731 
1732  ReleaseSysCache(pgstuple);
1733 
1734  return options;
1735 }
1736 
1737 /*
1738  * Return sequence parameters (formerly for use by information schema)
1739  */
1740 Datum
1742 {
1743  Oid relid = PG_GETARG_OID(0);
1744  TupleDesc tupdesc;
1745  Datum values[7];
1746  bool isnull[7];
1747  HeapTuple pgstuple;
1748  Form_pg_sequence pgsform;
1749 
1751  ereport(ERROR,
1752  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1753  errmsg("permission denied for sequence %s",
1754  get_rel_name(relid))));
1755 
1756  if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
1757  elog(ERROR, "return type must be a row type");
1758 
1759  memset(isnull, 0, sizeof(isnull));
1760 
1761  pgstuple = SearchSysCache1(SEQRELID, ObjectIdGetDatum(relid));
1762  if (!HeapTupleIsValid(pgstuple))
1763  elog(ERROR, "cache lookup failed for sequence %u", relid);
1764  pgsform = (Form_pg_sequence) GETSTRUCT(pgstuple);
1765 
1766  values[0] = Int64GetDatum(pgsform->seqstart);
1767  values[1] = Int64GetDatum(pgsform->seqmin);
1768  values[2] = Int64GetDatum(pgsform->seqmax);
1769  values[3] = Int64GetDatum(pgsform->seqincrement);
1770  values[4] = BoolGetDatum(pgsform->seqcycle);
1771  values[5] = Int64GetDatum(pgsform->seqcache);
1772  values[6] = ObjectIdGetDatum(pgsform->seqtypid);
1773 
1774  ReleaseSysCache(pgstuple);
1775 
1776  return HeapTupleGetDatum(heap_form_tuple(tupdesc, values, isnull));
1777 }
1778 
1779 
1780 /*
1781  * Return the sequence tuple.
1782  *
1783  * This is primarily intended for use by pg_dump to gather sequence data
1784  * without needing to individually query each sequence relation.
1785  */
1786 Datum
1788 {
1789 #define PG_GET_SEQUENCE_DATA_COLS 2
1790  Oid relid = PG_GETARG_OID(0);
1791  SeqTable elm;
1792  Relation seqrel;
1794  bool isnull[PG_GET_SEQUENCE_DATA_COLS] = {0};
1795  TupleDesc resultTupleDesc;
1796  HeapTuple resultHeapTuple;
1797  Datum result;
1798 
1800  TupleDescInitEntry(resultTupleDesc, (AttrNumber) 1, "last_value",
1801  INT8OID, -1, 0);
1802  TupleDescInitEntry(resultTupleDesc, (AttrNumber) 2, "is_called",
1803  BOOLOID, -1, 0);
1804  resultTupleDesc = BlessTupleDesc(resultTupleDesc);
1805 
1806  init_sequence(relid, &elm, &seqrel);
1807 
1808  /*
1809  * Return all NULLs for sequences for which we lack privileges, other
1810  * sessions' temporary sequences, and unlogged sequences on standbys.
1811  */
1812  if (pg_class_aclcheck(relid, GetUserId(), ACL_SELECT) == ACLCHECK_OK &&
1813  !RELATION_IS_OTHER_TEMP(seqrel) &&
1814  (RelationIsPermanent(seqrel) || !RecoveryInProgress()))
1815  {
1816  Buffer buf;
1817  HeapTupleData seqtuple;
1819 
1820  seq = read_seq_tuple(seqrel, &buf, &seqtuple);
1821 
1822  values[0] = Int64GetDatum(seq->last_value);
1823  values[1] = BoolGetDatum(seq->is_called);
1824 
1826  }
1827  else
1828  memset(isnull, true, sizeof(isnull));
1829 
1830  sequence_close(seqrel, NoLock);
1831 
1832  resultHeapTuple = heap_form_tuple(resultTupleDesc, values, isnull);
1833  result = HeapTupleGetDatum(resultHeapTuple);
1834  PG_RETURN_DATUM(result);
1835 #undef PG_GET_SEQUENCE_DATA_COLS
1836 }
1837 
1838 
1839 /*
1840  * Return the last value from the sequence
1841  *
1842  * Note: This has a completely different meaning than lastval().
1843  */
1844 Datum
1846 {
1847  Oid relid = PG_GETARG_OID(0);
1848  SeqTable elm;
1849  Relation seqrel;
1850  bool is_called = false;
1851  int64 result = 0;
1852 
1853  /* open and lock sequence */
1854  init_sequence(relid, &elm, &seqrel);
1855 
1856  /*
1857  * We return NULL for other sessions' temporary sequences. The
1858  * pg_sequences system view already filters those out, but this offers a
1859  * defense against ERRORs in case someone invokes this function directly.
1860  *
1861  * Also, for the benefit of the pg_sequences view, we return NULL for
1862  * unlogged sequences on standbys and for sequences for which the current
1863  * user lacks privileges instead of throwing an error.
1864  */
1866  !RELATION_IS_OTHER_TEMP(seqrel) &&
1867  (RelationIsPermanent(seqrel) || !RecoveryInProgress()))
1868  {
1869  Buffer buf;
1870  HeapTupleData seqtuple;
1872 
1873  seq = read_seq_tuple(seqrel, &buf, &seqtuple);
1874 
1875  is_called = seq->is_called;
1876  result = seq->last_value;
1877 
1879  }
1880  sequence_close(seqrel, NoLock);
1881 
1882  if (is_called)
1883  PG_RETURN_INT64(result);
1884  else
1885  PG_RETURN_NULL();
1886 }
1887 
1888 
1889 void
1891 {
1892  XLogRecPtr lsn = record->EndRecPtr;
1893  uint8 info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
1894  Buffer buffer;
1895  Page page;
1896  Page localpage;
1897  char *item;
1898  Size itemsz;
1899  xl_seq_rec *xlrec = (xl_seq_rec *) XLogRecGetData(record);
1900  sequence_magic *sm;
1901 
1902  if (info != XLOG_SEQ_LOG)
1903  elog(PANIC, "seq_redo: unknown op code %u", info);
1904 
1905  buffer = XLogInitBufferForRedo(record, 0);
1906  page = (Page) BufferGetPage(buffer);
1907 
1908  /*
1909  * We always reinit the page. However, since this WAL record type is also
1910  * used for updating sequences, it's possible that a hot-standby backend
1911  * is examining the page concurrently; so we mustn't transiently trash the
1912  * buffer. The solution is to build the correct new page contents in
1913  * local workspace and then memcpy into the buffer. Then only bytes that
1914  * are supposed to change will change, even transiently. We must palloc
1915  * the local page for alignment reasons.
1916  */
1917  localpage = (Page) palloc(BufferGetPageSize(buffer));
1918 
1919  PageInit(localpage, BufferGetPageSize(buffer), sizeof(sequence_magic));
1920  sm = (sequence_magic *) PageGetSpecialPointer(localpage);
1921  sm->magic = SEQ_MAGIC;
1922 
1923  item = (char *) xlrec + sizeof(xl_seq_rec);
1924  itemsz = XLogRecGetDataLen(record) - sizeof(xl_seq_rec);
1925 
1926  if (PageAddItem(localpage, (Item) item, itemsz,
1927  FirstOffsetNumber, false, false) == InvalidOffsetNumber)
1928  elog(PANIC, "seq_redo: failed to add item to page");
1929 
1930  PageSetLSN(localpage, lsn);
1931 
1932  memcpy(page, localpage, BufferGetPageSize(buffer));
1933  MarkBufferDirty(buffer);
1934  UnlockReleaseBuffer(buffer);
1935 
1936  pfree(localpage);
1937 }
1938 
1939 /*
1940  * Flush cached sequence information.
1941  */
1942 void
1944 {
1945  if (seqhashtab)
1946  {
1948  seqhashtab = NULL;
1949  }
1950 
1951  last_used_seq = NULL;
1952 }
1953 
1954 /*
1955  * Mask a Sequence page before performing consistency checks on it.
1956  */
1957 void
1958 seq_mask(char *page, BlockNumber blkno)
1959 {
1961 
1962  mask_unused_space(page);
1963 }
Relation sequence_open(Oid relationId, LOCKMODE lockmode)
Definition: sequence.c:37
void sequence_close(Relation relation, LOCKMODE lockmode)
Definition: sequence.c:58
@ ACLCHECK_OK
Definition: acl.h:183
AclResult pg_class_aclcheck(Oid table_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4094
int16 AttrNumber
Definition: attnum.h:21
#define InvalidAttrNumber
Definition: attnum.h:23
uint32 BlockNumber
Definition: block.h:31
static int32 next
Definition: blutils.c:222
static Datum values[MAXATTR]
Definition: bootstrap.c:150
int Buffer
Definition: buf.h:23
void mask_page_lsn_and_checksum(Page page)
Definition: bufmask.c:31
void mask_unused_space(Page page)
Definition: bufmask.c:71
BlockNumber BufferGetBlockNumber(Buffer buffer)
Definition: bufmgr.c:3724
Buffer ExtendBufferedRel(BufferManagerRelation bmr, ForkNumber forkNum, BufferAccessStrategy strategy, uint32 flags)
Definition: bufmgr.c:846
void UnlockReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:4941
void MarkBufferDirty(Buffer buffer)
Definition: bufmgr.c:2532
void LockBuffer(Buffer buffer, int mode)
Definition: bufmgr.c:5158
void MarkBufferDirtyHint(Buffer buffer, bool buffer_std)
Definition: bufmgr.c:4988
void FlushRelationBuffers(Relation rel)
Definition: bufmgr.c:4492
Buffer ReadBuffer(Relation reln, BlockNumber blockNum)
Definition: bufmgr.c:746
static Page BufferGetPage(Buffer buffer)
Definition: bufmgr.h:400
static Size BufferGetPageSize(Buffer buffer)
Definition: bufmgr.h:389
@ EB_SKIP_EXTENSION_LOCK
Definition: bufmgr.h:74
@ EB_LOCK_FIRST
Definition: bufmgr.h:86
#define BUFFER_LOCK_EXCLUSIVE
Definition: bufmgr.h:191
#define BMR_REL(p_rel)
Definition: bufmgr.h:107
void PageInit(Page page, Size pageSize, Size specialSize)
Definition: bufpage.c:42
Pointer Page
Definition: bufpage.h:81
static Item PageGetItem(Page page, ItemId itemId)
Definition: bufpage.h:354
static ItemId PageGetItemId(Page page, OffsetNumber offsetNumber)
Definition: bufpage.h:243
static void PageSetLSN(Page page, XLogRecPtr lsn)
Definition: bufpage.h:391
static char * PageGetSpecialPointer(Page page)
Definition: bufpage.h:339
static XLogRecPtr PageGetLSN(const char *page)
Definition: bufpage.h:386
#define PageAddItem(page, item, size, offsetNumber, overwrite, is_heap)
Definition: bufpage.h:471
unsigned int uint32
Definition: c.h:506
#define PG_INT32_MAX
Definition: c.h:580
signed int int32
Definition: c.h:496
#define INT64_FORMAT
Definition: c.h:539
#define Assert(condition)
Definition: c.h:849
#define BoolIsValid(boolean)
Definition: c.h:748
#define FirstCommandId
Definition: c.h:659
#define PG_INT16_MIN
Definition: c.h:576
#define PG_INT64_MAX
Definition: c.h:583
#define PG_INT64_MIN
Definition: c.h:582
#define PG_INT32_MIN
Definition: c.h:579
uint32 LocalTransactionId
Definition: c.h:645
unsigned char uint8
Definition: c.h:504
#define PG_INT16_MAX
Definition: c.h:577
#define OidIsValid(objectId)
Definition: c.h:766
size_t Size
Definition: c.h:596
ObjectAddress DefineSequence(ParseState *pstate, CreateSeqStmt *seq)
Definition: sequence.c:121
static void fill_seq_fork_with_data(Relation rel, HeapTuple tuple, ForkNumber forkNum)
Definition: sequence.c:359
void ResetSequence(Oid seq_relid)
Definition: sequence.c:262
static void fill_seq_with_data(Relation rel, HeapTuple tuple)
Definition: sequence.c:338
struct sequence_magic sequence_magic
Datum setval_oid(PG_FUNCTION_ARGS)
Definition: sequence.c:1049
static SeqTableData * last_used_seq
Definition: sequence.c:97
ObjectAddress AlterSequence(ParseState *pstate, AlterSeqStmt *stmt)
Definition: sequence.c:437
Datum pg_sequence_parameters(PG_FUNCTION_ARGS)
Definition: sequence.c:1741
Datum nextval_oid(PG_FUNCTION_ARGS)
Definition: sequence.c:615
static void init_sequence(Oid relid, SeqTable *p_elm, Relation *p_rel)
Definition: sequence.c:1129
#define SEQ_MAGIC
Definition: sequence.c:63
Datum setval3_oid(PG_FUNCTION_ARGS)
Definition: sequence.c:1064
#define SEQ_LOG_VALS
Definition: sequence.c:58
static Form_pg_sequence_data read_seq_tuple(Relation rel, Buffer *buf, HeapTuple seqdatatuple)
Definition: sequence.c:1190
Datum pg_get_sequence_data(PG_FUNCTION_ARGS)
Definition: sequence.c:1787
Datum lastval(PG_FUNCTION_ARGS)
Definition: sequence.c:897
void seq_mask(char *page, BlockNumber blkno)
Definition: sequence.c:1958
Datum nextval(PG_FUNCTION_ARGS)
Definition: sequence.c:593
int64 nextval_internal(Oid relid, bool check_permissions)
Definition: sequence.c:623
void SequenceChangePersistence(Oid relid, char newrelpersistence)
Definition: sequence.c:541
#define PG_GET_SEQUENCE_DATA_COLS
static void process_owned_by(Relation seqrel, List *owned_by, bool for_identity)
Definition: sequence.c:1593
static HTAB * seqhashtab
Definition: sequence.c:91
Datum pg_sequence_last_value(PG_FUNCTION_ARGS)
Definition: sequence.c:1845
Datum currval_oid(PG_FUNCTION_ARGS)
Definition: sequence.c:866
static void do_setval(Oid relid, int64 next, bool iscalled)
Definition: sequence.c:945
List * sequence_options(Oid relid)
Definition: sequence.c:1707
static void init_params(ParseState *pstate, List *options, bool for_identity, bool isInit, Form_pg_sequence seqform, Form_pg_sequence_data seqdataform, bool *need_seq_rewrite, List **owned_by)
Definition: sequence.c:1257
SeqTableData * SeqTable
Definition: sequence.c:89
void seq_redo(XLogReaderState *record)
Definition: sequence.c:1890
struct SeqTableData SeqTableData
void ResetSequenceCaches(void)
Definition: sequence.c:1943
static void create_seq_hashtable(void)
Definition: sequence.c:1113
static Relation lock_and_open_sequence(SeqTable seq)
Definition: sequence.c:1085
void DeleteSequenceTuple(Oid relid)
Definition: sequence.c:570
#define SEQ_COL_LASTVAL
Definition: sequence.h:38
FormData_pg_sequence_data * Form_pg_sequence_data
Definition: sequence.h:32
#define SEQ_COL_CALLED
Definition: sequence.h:40
#define SEQ_COL_LASTCOL
Definition: sequence.h:43
#define SEQ_COL_LOG
Definition: sequence.h:39
#define SEQ_COL_FIRSTCOL
Definition: sequence.h:42
struct xl_seq_rec xl_seq_rec
#define XLOG_SEQ_LOG
Definition: sequence.h:46
List * defGetQualifiedName(DefElem *def)
Definition: define.c:252
int64 defGetInt64(DefElem *def)
Definition: define.c:186
void errorConflictingDefElem(DefElem *defel, ParseState *pstate)
Definition: define.c:384
TypeName * defGetTypeName(DefElem *def)
Definition: define.c:284
DependencyType
Definition: dependency.h:32
@ DEPENDENCY_AUTO
Definition: dependency.h:34
@ DEPENDENCY_INTERNAL
Definition: dependency.h:35
void hash_destroy(HTAB *hashp)
Definition: dynahash.c:865
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
Definition: dynahash.c:955
HTAB * hash_create(const char *tabname, long nelem, const HASHCTL *info, int flags)
Definition: dynahash.c:352
int errdetail(const char *fmt,...)
Definition: elog.c:1203
int errhint(const char *fmt,...)
Definition: elog.c:1317
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define PANIC
Definition: elog.h:42
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:225
#define NOTICE
Definition: elog.h:35
#define ereport(elevel,...)
Definition: elog.h:149
TupleDesc BlessTupleDesc(TupleDesc tupdesc)
Definition: execTuples.c:2158
Datum Int64GetDatum(int64 X)
Definition: fmgr.c:1807
#define PG_GETARG_OID(n)
Definition: fmgr.h:275
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:309
#define PG_RETURN_INT64(x)
Definition: fmgr.h:368
#define PG_RETURN_NULL()
Definition: fmgr.h:345
#define PG_GETARG_INT64(n)
Definition: fmgr.h:283
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:274
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:353
#define PG_FUNCTION_ARGS
Definition: fmgr.h:193
char * format_type_be(Oid type_oid)
Definition: format_type.c:343
TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc)
Definition: funcapi.c:276
@ TYPEFUNC_COMPOSITE
Definition: funcapi.h:149
static Datum HeapTupleGetDatum(const HeapTupleData *tuple)
Definition: funcapi.h:230
HeapTuple heap_copytuple(HeapTuple tuple)
Definition: heaptuple.c:776
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
Definition: heaptuple.c:1116
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1434
@ HASH_ENTER
Definition: hsearch.h:114
#define HASH_ELEM
Definition: hsearch.h:95
#define HASH_BLOBS
Definition: hsearch.h:97
HeapTupleHeaderData * HeapTupleHeader
Definition: htup.h:23
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define HeapTupleHeaderSetXminFrozen(tup)
Definition: htup_details.h:348
#define HeapTupleHeaderSetXmin(tup, xid)
Definition: htup_details.h:315
#define HeapTupleHeaderSetXmax(tup, xid)
Definition: htup_details.h:376
#define HeapTupleHeaderSetCmin(tup, cid)
Definition: htup_details.h:393
#define HEAP_XMAX_IS_MULTI
Definition: htup_details.h:209
#define HEAP_XMAX_COMMITTED
Definition: htup_details.h:207
#define GETSTRUCT(TUP)
Definition: htup_details.h:653
#define HEAP_XMAX_INVALID
Definition: htup_details.h:208
#define HeapTupleHeaderGetRawXmax(tup)
Definition: htup_details.h:371
#define stmt
Definition: indent_codes.h:59
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:313
void CatalogTupleInsert(Relation heapRel, HeapTuple tup)
Definition: indexing.c:233
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:365
static struct @157 value
int i
Definition: isn.c:73
Pointer Item
Definition: item.h:17
#define ItemIdGetLength(itemId)
Definition: itemid.h:59
#define ItemIdIsNormal(itemId)
Definition: itemid.h:99
static void ItemPointerSet(ItemPointerData *pointer, BlockNumber blockNumber, OffsetNumber offNum)
Definition: itemptr.h:135
List * lappend(List *list, void *datum)
Definition: list.c:339
List * list_copy_head(const List *oldlist, int len)
Definition: list.c:1593
void LockRelationOid(Oid relid, LOCKMODE lockmode)
Definition: lmgr.c:108
#define InvalidLocalTransactionId
Definition: lock.h:65
#define NoLock
Definition: lockdefs.h:34
#define AccessExclusiveLock
Definition: lockdefs.h:43
#define ShareRowExclusiveLock
Definition: lockdefs.h:41
#define AccessShareLock
Definition: lockdefs.h:36
#define RowExclusiveLock
Definition: lockdefs.h:38
AttrNumber get_attnum(Oid relid, const char *attname)
Definition: lsyscache.c:858
char * get_rel_name(Oid relid)
Definition: lsyscache.c:1928
DefElem * makeDefElem(char *name, Node *arg, int location)
Definition: makefuncs.c:564
ColumnDef * makeColumnDef(const char *colname, Oid typeOid, int32 typmod, Oid collOid)
Definition: makefuncs.c:492
void pfree(void *pointer)
Definition: mcxt.c:1521
void * palloc(Size size)
Definition: mcxt.c:1317
#define START_CRIT_SECTION()
Definition: miscadmin.h:149
#define END_CRIT_SECTION()
Definition: miscadmin.h:151
Oid GetUserId(void)
Definition: miscinit.c:514
#define InvalidMultiXactId
Definition: multixact.h:24
Oid RangeVarGetAndCheckCreationNamespace(RangeVar *relation, LOCKMODE lockmode, Oid *existing_relation_id)
Definition: namespace.c:739
RangeVar * makeRangeVarFromNameList(const List *names)
Definition: namespace.c:3554
Oid RangeVarGetRelidExtended(const RangeVar *relation, LOCKMODE lockmode, uint32 flags, RangeVarGetRelidCallback callback, void *callback_arg)
Definition: namespace.c:441
@ RVR_MISSING_OK
Definition: namespace.h:72
#define RangeVarGetRelid(relation, lockmode, missing_ok)
Definition: namespace.h:80
#define makeNode(_type_)
Definition: nodes.h:155
#define InvokeObjectPostAlterHook(classId, objectId, subId)
Definition: objectaccess.h:197
const ObjectAddress InvalidObjectAddress
#define ObjectAddressSet(addr, class_id, object_id)
Definition: objectaddress.h:40
#define InvalidOffsetNumber
Definition: off.h:26
uint16 OffsetNumber
Definition: off.h:24
#define FirstOffsetNumber
Definition: off.h:27
int parser_errposition(ParseState *pstate, int location)
Definition: parse_node.c:106
Oid typenameTypeId(ParseState *pstate, const TypeName *typeName)
Definition: parse_type.c:291
#define ACL_USAGE
Definition: parsenodes.h:84
#define ACL_UPDATE
Definition: parsenodes.h:78
#define ACL_SELECT
Definition: parsenodes.h:77
int16 attnum
Definition: pg_attribute.h:74
int errdetail_relkind_not_supported(char relkind)
Definition: pg_class.c:24
NameData relname
Definition: pg_class.h:38
void checkMembershipInCurrentExtension(const ObjectAddress *object)
Definition: pg_depend.c:259
void recordDependencyOn(const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
Definition: pg_depend.c:46
long deleteDependencyRecordsForClass(Oid classId, Oid objectId, Oid refclassId, char deptype)
Definition: pg_depend.c:352
bool sequenceIsOwned(Oid seqId, char deptype, Oid *tableId, int32 *colId)
Definition: pg_depend.c:829
#define lfirst(lc)
Definition: pg_list.h:172
#define llast(l)
Definition: pg_list.h:198
static int list_length(const List *l)
Definition: pg_list.h:152
#define NIL
Definition: pg_list.h:68
#define linitial(l)
Definition: pg_list.h:178
static char ** options
FormData_pg_sequence
Definition: pg_sequence.h:33
FormData_pg_sequence * Form_pg_sequence
Definition: pg_sequence.h:40
static char * buf
Definition: pg_test_fsync.c:73
#define Int64GetDatumFast(X)
Definition: postgres.h:554
uintptr_t Datum
Definition: postgres.h:64
static Datum BoolGetDatum(bool X)
Definition: postgres.h:102
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:252
#define InvalidOid
Definition: postgres_ext.h:36
unsigned int Oid
Definition: postgres_ext.h:31
@ ONCOMMIT_NOOP
Definition: primnodes.h:57
#define INVALID_PROC_NUMBER
Definition: procnumber.h:26
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
tree ctl
Definition: radixtree.h:1853
#define RelationGetRelid(relation)
Definition: rel.h:505
#define RelationGetDescr(relation)
Definition: rel.h:531
#define RelationGetRelationName(relation)
Definition: rel.h:539
#define RelationNeedsWAL(relation)
Definition: rel.h:628
#define RELATION_IS_OTHER_TEMP(relation)
Definition: rel.h:658
#define RelationGetNamespace(relation)
Definition: rel.h:546
#define RelationIsPermanent(relation)
Definition: rel.h:617
void RelationSetNewRelfilenumber(Relation relation, char persistence)
Definition: relcache.c:3767
Oid RelFileNumber
Definition: relpath.h:25
ForkNumber
Definition: relpath.h:56
@ MAIN_FORKNUM
Definition: relpath.h:58
@ INIT_FORKNUM
Definition: relpath.h:61
#define InvalidRelFileNumber
Definition: relpath.h:26
ResourceOwner TopTransactionResourceOwner
Definition: resowner.c:167
ResourceOwner CurrentResourceOwner
Definition: resowner.c:165
SMgrRelation smgropen(RelFileLocator rlocator, ProcNumber backend)
Definition: smgr.c:201
void smgrcreate(SMgrRelation reln, ForkNumber forknum, bool isRedo)
Definition: smgr.c:414
void smgrclose(SMgrRelation reln)
Definition: smgr.c:323
void relation_close(Relation relation, LOCKMODE lockmode)
Definition: relation.c:205
Relation relation_openrv(const RangeVar *relation, LOCKMODE lockmode)
Definition: relation.c:137
PGPROC * MyProc
Definition: proc.c:67
void log_smgrcreate(const RelFileLocator *rlocator, ForkNumber forkNum)
Definition: storage.c:186
bool is_not_null
Definition: parsenodes.h:733
bool if_not_exists
Definition: parsenodes.h:3140
List * options
Definition: parsenodes.h:3137
RangeVar * sequence
Definition: parsenodes.h:3136
char * defname
Definition: parsenodes.h:817
ParseLoc location
Definition: parsenodes.h:821
Node * arg
Definition: parsenodes.h:818
Definition: dynahash.c:220
ItemPointerData t_self
Definition: htup.h:65
uint32 t_len
Definition: htup.h:64
HeapTupleHeader t_data
Definition: htup.h:68
ItemPointerData t_ctid
Definition: htup_details.h:161
Definition: pg_list.h:54
Definition: nodes.h:129
LocalTransactionId lxid
Definition: proc.h:200
struct PGPROC::@119 vxid
char * relname
Definition: primnodes.h:82
bool rd_islocaltemp
Definition: rel.h:61
RelFileLocator rd_locator
Definition: rel.h:57
Form_pg_class rd_rel
Definition: rel.h:111
RelFileNumber filenumber
Definition: sequence.c:79
LocalTransactionId lxid
Definition: sequence.c:80
int64 cached
Definition: sequence.c:83
bool last_valid
Definition: sequence.c:81
int64 last
Definition: sequence.c:82
int64 increment
Definition: sequence.c:85
XLogRecPtr EndRecPtr
Definition: xlogreader.h:207
uint32 magic
Definition: sequence.c:67
Definition: c.h:678
RelFileLocator locator
Definition: sequence.h:50
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:269
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:221
#define SearchSysCacheCopy1(cacheId, key1)
Definition: syscache.h:91
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:100
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:40
ObjectAddress DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ObjectAddress *typaddress, const char *queryString)
Definition: tablecmds.c:706
void RangeVarCallbackOwnsRelation(const RangeVar *relation, Oid relId, Oid oldRelId, void *arg)
Definition: tablecmds.c:17899
#define FrozenTransactionId
Definition: transam.h:33
#define InvalidTransactionId
Definition: transam.h:31
TupleDesc CreateTemplateTupleDesc(int natts)
Definition: tupdesc.c:67
void TupleDescInitEntry(TupleDesc desc, AttrNumber attributeNumber, const char *attributeName, Oid oidtypeid, int32 typmod, int attdim)
Definition: tupdesc.c:651
void PreventCommandIfReadOnly(const char *cmdname)
Definition: utility.c:404
void PreventCommandIfParallelMode(const char *cmdname)
Definition: utility.c:422
Boolean * makeBoolean(bool val)
Definition: value.c:49
Float * makeFloat(char *numericStr)
Definition: value.c:37
#define boolVal(v)
Definition: value.h:81
#define strVal(v)
Definition: value.h:82
List * textToQualifiedNameList(text *textval)
Definition: varlena.c:3374
TransactionId GetTopTransactionId(void)
Definition: xact.c:425
bool RecoveryInProgress(void)
Definition: xlog.c:6333
XLogRecPtr GetRedoRecPtr(void)
Definition: xlog.c:6436
uint64 XLogRecPtr
Definition: xlogdefs.h:21
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition: xloginsert.c:474
void XLogRegisterData(const char *data, uint32 len)
Definition: xloginsert.c:364
void XLogRegisterBuffer(uint8 block_id, Buffer buffer, uint8 flags)
Definition: xloginsert.c:242
void XLogBeginInsert(void)
Definition: xloginsert.c:149
#define REGBUF_WILL_INIT
Definition: xloginsert.h:33
#define XLogRecGetDataLen(decoder)
Definition: xlogreader.h:416
#define XLogRecGetInfo(decoder)
Definition: xlogreader.h:410
#define XLogRecGetData(decoder)
Definition: xlogreader.h:415
#define XLR_INFO_MASK
Definition: xlogrecord.h:62
Buffer XLogInitBufferForRedo(XLogReaderState *record, uint8 block_id)
Definition: xlogutils.c:326