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