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