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"
NUMrotationsPointInPolygon(double x0,double y0,integer n,double x[],double y[])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 {
65 	uint32		magic;
66 } sequence_magic;
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 
87 typedef SeqTableData *SeqTable;
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);
98 static Relation lock_and_open_sequence(SeqTable seq);
99 static void create_seq_hashtable(void);
100 static void init_sequence(Oid relid, SeqTable *p_elm, Relation *p_rel);
101 static Form_pg_sequence_data read_seq_tuple(Relation 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  */
117 ObjectAddress
118 DefineSequence(ParseState *pstate, CreateSeqStmt *seq)
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;
130 	Datum		value[SEQ_COL_LASTCOL];
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 	{
149 		RangeVarGetAndCheckCreationNamespace(seq->sequence, NoLock, &seqoid);
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);
252 	table_close(rel, RowExclusiveLock);
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;
274 	Form_pg_sequence_data seq;
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
343 fill_seq_with_data(Relation rel, HeapTuple tuple)
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 
363 	LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE);
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 	 */
372 	HeapTupleHeaderSetXmin(tuple->t_data, FrozenTransactionId);
373 	HeapTupleHeaderSetXminFrozen(tuple->t_data);
374 	HeapTupleHeaderSetCmin(tuple->t_data, FirstCommandId);
375 	HeapTupleHeaderSetXmax(tuple->t_data, InvalidTransactionId);
376 	tuple->t_data->t_infomask |= HEAP_XMAX_INVALID;
377 	ItemPointerSet(&tuple->t_data->t_ctid, 0, FirstOffsetNumber);
378 
379 	/* check the comment above nextval_internal()'s equivalent call. */
380 	if (RelationNeedsWAL(rel))
381 		GetTopTransactionId();
382 
383 	START_CRIT_SECTION();
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();
399 		XLogRegisterBuffer(0, buf, REGBUF_WILL_INIT);
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 
411 	END_CRIT_SECTION();
412 
413 	UnlockReleaseBuffer(buf);
414 }
415 
416 /*
417  * AlterSequence
418  *
419  * Modify the definition of a sequence relation
420  */
421 ObjectAddress
422 AlterSequence(ParseState *pstate, AlterSeqStmt *stmt)
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,
440 									 ShareRowExclusiveLock,
441 									 stmt->missing_ok ? RVR_MISSING_OK : 0,
442 									 RangeVarCallbackOwnsRelation,
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))
486 			GetTopTransactionId();
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 
519 	table_close(rel, RowExclusiveLock);
520 	relation_close(seqrel, NoLock);
521 
522 	return address;
523 }
524 
525 void
526 DeleteSequenceTuple(Oid relid)
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);
540 	table_close(rel, RowExclusiveLock);
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
549 nextval(PG_FUNCTION_ARGS)
550 {
551 	text	   *seqin = PG_GETARG_TEXT_PP(0);
552 	RangeVar   *sequence;
553 	Oid			relid;
554 
555 	sequence = makeRangeVarFromNameList(textToQualifiedNameList(seqin));
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
571 nextval_oid(PG_FUNCTION_ARGS)
572 {
573 	Oid			relid = PG_GETARG_OID(0);
574 
575 	PG_RETURN_INT64(nextval_internal(relid, true));
576 }
577 
578 int64
579 nextval_internal(Oid relid, bool check_permissions)
580 {
581 	SeqTable	elm;
582 	Relation	seqrel;
583 	Buffer		buf;
584 	Page		page;
585 	HeapTuple	pgstuple;
586 	Form_pg_sequence pgsform;
587 	HeapTupleData seqdatatuple;
588 	Form_pg_sequence_data seq;
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 &&
606 		pg_class_aclcheck(elm->relid, GetUserId(),
607 						  ACL_USAGE | ACL_UPDATE) != ACLCHECK_OK)
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))
769 		GetTopTransactionId();
770 
771 	/* ready to change the on-disk (or really, in-buffer) tuple */
772 	START_CRIT_SECTION();
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();
798 		XLogRegisterBuffer(0, buf, REGBUF_WILL_INIT);
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 
820 	END_CRIT_SECTION();
821 
822 	UnlockReleaseBuffer(buf);
823 
824 	relation_close(seqrel, NoLock);
825 
826 	return result;
827 }
828 
829 Datum
830 currval_oid(PG_FUNCTION_ARGS)
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(),
841 						  ACL_SELECT | ACL_USAGE) != ACLCHECK_OK)
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
861 lastval(PG_FUNCTION_ARGS)
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(),
883 						  ACL_SELECT | ACL_USAGE) != ACLCHECK_OK)
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;
915 	Form_pg_sequence_data seq;
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 
924 	if (pg_class_aclcheck(elm->relid, GetUserId(), ACL_UPDATE) != ACLCHECK_OK)
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))
980 		GetTopTransactionId();
981 
982 	/* ready to change the on-disk (or really, in-buffer) tuple */
983 	START_CRIT_SECTION();
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();
999 		XLogRegisterBuffer(0, buf, REGBUF_WILL_INIT);
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
1022 setval_oid(PG_FUNCTION_ARGS)
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
1037 setval3_oid(PG_FUNCTION_ARGS)
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
1058 lock_and_open_sequence(SeqTable seq)
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;
1068 		CurrentResourceOwner = TopTransactionResourceOwner;
1069 
1070 		LockRelationOid(seq->relid, RowExclusiveLock);
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
1086 create_seq_hashtable(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)
1111 		create_seq_hashtable();
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: seqtable 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;
1127 		elm->lxid = InvalidLocalTransactionId;
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
1170 read_seq_tuple(Relation rel, Buffer *buf, HeapTuple seqdatatuple)
1171 {
1172 	Page		page;
1173 	ItemId		lp;
1174 	sequence_magic *sm;
1175 	Form_pg_sequence_data seq;
1176 
1177 	*buf = ReadBuffer(rel, 0);
1178 	LockBuffer(*buf, BUFFER_LOCK_EXCLUSIVE);
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));
1203 	if (HeapTupleHeaderGetRawXmax(seqdatatuple->t_data) != InvalidTransactionId)
1204 	{
1205 		HeapTupleHeaderSetXmax(seqdatatuple->t_data, InvalidTransactionId);
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;
1646 	AttrNumber	attnum;
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 *
1754 sequence_options(Oid relid)
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
1788 pg_sequence_parameters(PG_FUNCTION_ARGS)
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 
1797 	if (pg_class_aclcheck(relid, GetUserId(), ACL_SELECT | ACL_UPDATE | ACL_USAGE) != ACLCHECK_OK)
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
1847 pg_sequence_last_value(PG_FUNCTION_ARGS)
1848 {
1849 	Oid			relid = PG_GETARG_OID(0);
1850 	SeqTable	elm;
1851 	Relation	seqrel;
1852 	Buffer		buf;
1853 	HeapTupleData seqtuple;
1854 	Form_pg_sequence_data seq;
1855 	bool		is_called;
1856 	int64		result;
1857 
1858 	/* open and lock sequence */
1859 	init_sequence(relid, &elm, &seqrel);
1860 
1861 	if (pg_class_aclcheck(relid, GetUserId(), ACL_SELECT | ACL_USAGE) != ACLCHECK_OK)
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
1883 seq_redo(XLogReaderState *record)
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
1936 ResetSequenceCaches(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 {
1953 	mask_page_lsn_and_checksum(page);
1954 
1955 	mask_unused_space(page);
1956 }
1957