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