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