57 #define SEQ_LOG_VALS 32
62 #define SEQ_MAGIC 0x1717
109 bool *need_seq_rewrite,
124 bool need_seq_rewrite;
134 Datum pgs_values[Natts_pg_sequence];
135 bool pgs_nulls[Natts_pg_sequence];
157 (
errcode(ERRCODE_DUPLICATE_TABLE),
158 errmsg(
"relation \"%s\" already exists, skipping",
166 &seqform, &seqdataform,
167 &need_seq_rewrite, &owned_by);
204 stmt->tablespacename = NULL;
228 memset(pgs_nulls, 0,
sizeof(pgs_nulls));
231 pgs_values[Anum_pg_sequence_seqtypid - 1] =
ObjectIdGetDatum(seqform.seqtypid);
233 pgs_values[Anum_pg_sequence_seqincrement - 1] =
Int64GetDatumFast(seqform.seqincrement);
237 pgs_values[Anum_pg_sequence_seqcycle - 1] =
BoolGetDatum(seqform.seqcycle);
283 elog(
ERROR,
"cache lookup failed for sequence %u", seq_relid);
285 startv = pgsform->seqstart;
341 if (rel->
rd_rel->relpersistence == RELPERSISTENCE_UNLOGGED)
404 elog(
ERROR,
"failed to add sequence tuple to page");
445 bool need_seq_rewrite;
461 (
errmsg(
"relation \"%s\" does not exist, skipping",
462 stmt->sequence->relname)));
472 elog(
ERROR,
"cache lookup failed for sequence %u",
488 seqform, newdataform,
489 &need_seq_rewrite, &owned_by);
496 if (need_seq_rewrite)
571 elog(
ERROR,
"cache lookup failed for sequence %u", relid);
641 if (check_permissions &&
645 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
646 errmsg(
"permission denied for sequence %s",
672 elog(
ERROR,
"cache lookup failed for sequence %u", relid);
674 incby = pgsform->seqincrement;
675 maxv = pgsform->seqmax;
676 minv = pgsform->seqmin;
677 cache = pgsform->seqcache;
678 cycle = pgsform->seqcycle;
706 if (log < fetch || !seq->is_called)
733 if ((maxv >= 0 &&
next > maxv - incby) ||
734 (maxv < 0 && next + incby > maxv))
740 (
errcode(ERRCODE_SEQUENCE_GENERATOR_LIMIT_EXCEEDED),
741 errmsg(
"nextval: reached maximum value of sequence \"%s\" (%lld)",
752 if ((minv < 0 &&
next < minv - incby) ||
753 (minv >= 0 &&
next + incby < minv))
759 (
errcode(ERRCODE_SEQUENCE_GENERATOR_LIMIT_EXCEEDED),
760 errmsg(
"nextval: reached minimum value of sequence \"%s\" (%lld)",
871 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
872 errmsg(
"permission denied for sequence %s",
877 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
878 errmsg(
"currval of sequence \"%s\" is not yet defined in this session",
896 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
897 errmsg(
"lastval is not yet defined in this session")));
902 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
903 errmsg(
"lastval is not yet defined in this session")));
913 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
914 errmsg(
"permission denied for sequence %s",
954 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
955 errmsg(
"permission denied for sequence %s",
960 elog(
ERROR,
"cache lookup failed for sequence %u", relid);
962 maxv = pgsform->seqmax;
963 minv = pgsform->seqmin;
982 (
errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
983 errmsg(
"setval: value %lld is out of bounds for sequence \"%s\" (%lld..%lld)",
985 (
long long) minv, (
long long) maxv)));
1082 if (seq->
lxid != thislxid)
1094 seq->
lxid = thislxid;
1155 if (seqrel->
rd_rel->relkind != RELKIND_SEQUENCE)
1157 (
errcode(ERRCODE_WRONG_OBJECT_TYPE),
1158 errmsg(
"\"%s\" is not a sequence",
1202 elog(
ERROR,
"bad magic number in sequence \"%s\": %08X",
1259 bool *need_seq_rewrite,
1264 DefElem *restart_value = NULL;
1271 bool reset_max_value =
false;
1272 bool reset_min_value =
false;
1274 *need_seq_rewrite =
false;
1281 if (strcmp(defel->
defname,
"as") == 0)
1286 *need_seq_rewrite =
true;
1288 else if (strcmp(defel->
defname,
"increment") == 0)
1292 increment_by = defel;
1293 *need_seq_rewrite =
true;
1295 else if (strcmp(defel->
defname,
"start") == 0)
1299 start_value = defel;
1300 *need_seq_rewrite =
true;
1302 else if (strcmp(defel->
defname,
"restart") == 0)
1306 restart_value = defel;
1307 *need_seq_rewrite =
true;
1309 else if (strcmp(defel->
defname,
"maxvalue") == 0)
1314 *need_seq_rewrite =
true;
1316 else if (strcmp(defel->
defname,
"minvalue") == 0)
1321 *need_seq_rewrite =
true;
1323 else if (strcmp(defel->
defname,
"cache") == 0)
1327 cache_value = defel;
1328 *need_seq_rewrite =
true;
1330 else if (strcmp(defel->
defname,
"cycle") == 0)
1335 *need_seq_rewrite =
true;
1337 else if (strcmp(defel->
defname,
"owned_by") == 0)
1343 else if (strcmp(defel->
defname,
"sequence_name") == 0)
1351 (
errcode(ERRCODE_SYNTAX_ERROR),
1352 errmsg(
"invalid sequence option SEQUENCE NAME"),
1356 elog(
ERROR,
"option \"%s\" not recognized",
1368 if (as_type != NULL)
1372 if (newtypid != INT2OID &&
1373 newtypid != INT4OID &&
1374 newtypid != INT8OID)
1376 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1378 ?
errmsg(
"identity column type must be smallint, integer, or bigint")
1379 :
errmsg(
"sequence type must be smallint, integer, or bigint")));
1389 if ((seqform->seqtypid == INT2OID && seqform->seqmax ==
PG_INT16_MAX) ||
1390 (seqform->seqtypid == INT4OID && seqform->seqmax ==
PG_INT32_MAX) ||
1391 (seqform->seqtypid == INT8OID && seqform->seqmax ==
PG_INT64_MAX))
1392 reset_max_value =
true;
1393 if ((seqform->seqtypid == INT2OID && seqform->seqmin ==
PG_INT16_MIN) ||
1394 (seqform->seqtypid == INT4OID && seqform->seqmin ==
PG_INT32_MIN) ||
1395 (seqform->seqtypid == INT8OID && seqform->seqmin ==
PG_INT64_MIN))
1396 reset_min_value =
true;
1399 seqform->seqtypid = newtypid;
1403 seqform->seqtypid = INT8OID;
1407 if (increment_by != NULL)
1409 seqform->seqincrement =
defGetInt64(increment_by);
1410 if (seqform->seqincrement == 0)
1412 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1413 errmsg(
"INCREMENT must not be zero")));
1418 seqform->seqincrement = 1;
1422 if (is_cycled != NULL)
1430 seqform->seqcycle =
false;
1434 if (max_value != NULL && max_value->
arg)
1439 else if (isInit || max_value != NULL || reset_max_value)
1441 if (seqform->seqincrement > 0 || reset_max_value)
1444 if (seqform->seqtypid == INT2OID)
1446 else if (seqform->seqtypid == INT4OID)
1452 seqform->seqmax = -1;
1460 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1461 errmsg(
"MAXVALUE (%lld) is out of range for sequence data type %s",
1462 (
long long) seqform->seqmax,
1466 if (min_value != NULL && min_value->
arg)
1471 else if (isInit || min_value != NULL || reset_min_value)
1473 if (seqform->seqincrement < 0 || reset_min_value)
1476 if (seqform->seqtypid == INT2OID)
1478 else if (seqform->seqtypid == INT4OID)
1484 seqform->seqmin = 1;
1492 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1493 errmsg(
"MINVALUE (%lld) is out of range for sequence data type %s",
1494 (
long long) seqform->seqmin,
1498 if (seqform->seqmin >= seqform->seqmax)
1500 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1501 errmsg(
"MINVALUE (%lld) must be less than MAXVALUE (%lld)",
1502 (
long long) seqform->seqmin,
1503 (
long long) seqform->seqmax)));
1506 if (start_value != NULL)
1512 if (seqform->seqincrement > 0)
1513 seqform->seqstart = seqform->seqmin;
1515 seqform->seqstart = seqform->seqmax;
1519 if (seqform->seqstart < seqform->seqmin)
1521 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1522 errmsg(
"START value (%lld) cannot be less than MINVALUE (%lld)",
1523 (
long long) seqform->seqstart,
1524 (
long long) seqform->seqmin)));
1525 if (seqform->seqstart > seqform->seqmax)
1527 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1528 errmsg(
"START value (%lld) cannot be greater than MAXVALUE (%lld)",
1529 (
long long) seqform->seqstart,
1530 (
long long) seqform->seqmax)));
1533 if (restart_value != NULL)
1535 if (restart_value->
arg != NULL)
1549 if (seqdataform->
last_value < seqform->seqmin)
1551 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1552 errmsg(
"RESTART value (%lld) cannot be less than MINVALUE (%lld)",
1554 (
long long) seqform->seqmin)));
1555 if (seqdataform->
last_value > seqform->seqmax)
1557 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1558 errmsg(
"RESTART value (%lld) cannot be greater than MAXVALUE (%lld)",
1560 (
long long) seqform->seqmax)));
1563 if (cache_value != NULL)
1566 if (seqform->seqcache <= 0)
1568 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1569 errmsg(
"CACHE (%lld) must be greater than zero",
1570 (
long long) seqform->seqcache)));
1575 seqform->seqcache = 1;
1604 (
errcode(ERRCODE_SYNTAX_ERROR),
1605 errmsg(
"invalid OWNED BY option"),
1606 errhint(
"Specify OWNED BY table.column or OWNED BY NONE.")));
1625 if (!(tablerel->
rd_rel->relkind == RELKIND_RELATION ||
1626 tablerel->
rd_rel->relkind == RELKIND_FOREIGN_TABLE ||
1627 tablerel->
rd_rel->relkind == RELKIND_VIEW ||
1628 tablerel->
rd_rel->relkind == RELKIND_PARTITIONED_TABLE))
1630 (
errcode(ERRCODE_WRONG_OBJECT_TYPE),
1631 errmsg(
"sequence cannot be owned by relation \"%s\"",
1636 if (seqrel->
rd_rel->relowner != tablerel->
rd_rel->relowner)
1638 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1639 errmsg(
"sequence must have same owner as table it is linked to")));
1642 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1643 errmsg(
"sequence must be in same schema as table it is linked to")));
1649 (
errcode(ERRCODE_UNDEFINED_COLUMN),
1650 errmsg(
"column \"%s\" of relation \"%s\" does not exist",
1664 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1665 errmsg(
"cannot change ownership of identity sequence"),
1666 errdetail(
"Sequence \"%s\" is linked to table \"%s\".",
1676 RelationRelationId, deptype);
1683 refobject.
classId = RelationRelationId;
1686 depobject.
classId = RelationRelationId;
1710 elog(
ERROR,
"cache lookup failed for sequence %u", relid);
1747 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1748 errmsg(
"permission denied for sequence %s",
1752 elog(
ERROR,
"return type must be a row type");
1754 memset(isnull, 0,
sizeof(isnull));
1758 elog(
ERROR,
"cache lookup failed for sequence %u", relid);
1796 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1797 errmsg(
"permission denied for sequence %s",
1829 elog(
PANIC,
"seq_redo: unknown op code %u", info);
1854 elog(
PANIC,
"seq_redo: failed to add item to page");
AclResult pg_class_aclcheck(Oid table_oid, Oid roleid, AclMode mode)
#define InvalidAttrNumber
static Datum values[MAXATTR]
void mask_page_lsn_and_checksum(Page page)
void mask_unused_space(Page page)
BlockNumber BufferGetBlockNumber(Buffer buffer)
Buffer ExtendBufferedRel(BufferManagerRelation bmr, ForkNumber forkNum, BufferAccessStrategy strategy, uint32 flags)
void UnlockReleaseBuffer(Buffer buffer)
void MarkBufferDirty(Buffer buffer)
void LockBuffer(Buffer buffer, int mode)
void MarkBufferDirtyHint(Buffer buffer, bool buffer_std)
void FlushRelationBuffers(Relation rel)
Buffer ReadBuffer(Relation reln, BlockNumber blockNum)
static Page BufferGetPage(Buffer buffer)
static Size BufferGetPageSize(Buffer buffer)
#define BUFFER_LOCK_EXCLUSIVE
void PageInit(Page page, Size pageSize, Size specialSize)
static Item PageGetItem(Page page, ItemId itemId)
static ItemId PageGetItemId(Page page, OffsetNumber offsetNumber)
static void PageSetLSN(Page page, XLogRecPtr lsn)
static XLogRecPtr PageGetLSN(Page page)
static char * PageGetSpecialPointer(Page page)
#define PageAddItem(page, item, size, offsetNumber, overwrite, is_heap)
#define BoolIsValid(boolean)
uint32 LocalTransactionId
#define OidIsValid(objectId)
elog(ERROR, "%s: %s", p2, msg)
List * defGetQualifiedName(DefElem *def)
int64 defGetInt64(DefElem *def)
void errorConflictingDefElem(DefElem *defel, ParseState *pstate)
TypeName * defGetTypeName(DefElem *def)
void hash_destroy(HTAB *hashp)
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
HTAB * hash_create(const char *tabname, long nelem, const HASHCTL *info, int flags)
int errdetail(const char *fmt,...)
int errhint(const char *fmt,...)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
Datum Int64GetDatum(int64 X)
#define PG_GETARG_TEXT_PP(n)
#define PG_RETURN_INT64(x)
#define PG_GETARG_INT64(n)
#define PG_GETARG_BOOL(n)
TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc)
static Datum HeapTupleGetDatum(const HeapTupleData *tuple)
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
HeapTuple heap_copytuple(HeapTuple tuple)
void heap_freetuple(HeapTuple htup)
HeapTupleHeaderData * HeapTupleHeader
#define HeapTupleIsValid(tuple)
#define HeapTupleHeaderSetXminFrozen(tup)
#define HeapTupleHeaderSetXmin(tup, xid)
#define HeapTupleHeaderSetXmax(tup, xid)
#define HeapTupleHeaderSetCmin(tup, cid)
#define HEAP_XMAX_IS_MULTI
#define HEAP_XMAX_COMMITTED
#define HEAP_XMAX_INVALID
#define HeapTupleHeaderGetRawXmax(tup)
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
void CatalogTupleInsert(Relation heapRel, HeapTuple tup)
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
#define ItemIdGetLength(itemId)
#define ItemIdIsNormal(itemId)
static void ItemPointerSet(ItemPointerData *pointer, BlockNumber blockNumber, OffsetNumber offNum)
Assert(fmt[strlen(fmt) - 1] !='\n')
List * lappend(List *list, void *datum)
List * list_copy_head(const List *oldlist, int len)
void LockRelationOid(Oid relid, LOCKMODE lockmode)
#define InvalidLocalTransactionId
#define AccessExclusiveLock
#define ShareRowExclusiveLock
AttrNumber get_attnum(Oid relid, const char *attname)
char * get_rel_name(Oid relid)
DefElem * makeDefElem(char *name, Node *arg, int location)
ColumnDef * makeColumnDef(const char *colname, Oid typeOid, int32 typmod, Oid collOid)
void pfree(void *pointer)
#define START_CRIT_SECTION()
#define END_CRIT_SECTION()
#define InvalidMultiXactId
Oid RangeVarGetAndCheckCreationNamespace(RangeVar *relation, LOCKMODE lockmode, Oid *existing_relation_id)
RangeVar * makeRangeVarFromNameList(const List *names)
Oid RangeVarGetRelidExtended(const RangeVar *relation, LOCKMODE lockmode, uint32 flags, RangeVarGetRelidCallback callback, void *callback_arg)
#define RangeVarGetRelid(relation, lockmode, missing_ok)
#define InvokeObjectPostAlterHook(classId, objectId, subId)
const ObjectAddress InvalidObjectAddress
#define ObjectAddressSet(addr, class_id, object_id)
#define InvalidOffsetNumber
#define FirstOffsetNumber
int parser_errposition(ParseState *pstate, int location)
Oid typenameTypeId(ParseState *pstate, const TypeName *typeName)
int errdetail_relkind_not_supported(char relkind)
void checkMembershipInCurrentExtension(const ObjectAddress *object)
void recordDependencyOn(const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
long deleteDependencyRecordsForClass(Oid classId, Oid objectId, Oid refclassId, char deptype)
bool sequenceIsOwned(Oid seqId, char deptype, Oid *tableId, int32 *colId)
static int list_length(const List *l)
FormData_pg_sequence * Form_pg_sequence
#define Int64GetDatumFast(X)
static Datum BoolGetDatum(bool X)
static Datum ObjectIdGetDatum(Oid X)
char * psprintf(const char *fmt,...)
#define RelationGetRelid(relation)
#define RelationGetDescr(relation)
#define RelationGetRelationName(relation)
#define RelationNeedsWAL(relation)
#define RelationGetNamespace(relation)
void RelationSetNewRelfilenumber(Relation relation, char persistence)
#define InvalidRelFileNumber
ResourceOwner TopTransactionResourceOwner
ResourceOwner CurrentResourceOwner
ObjectAddress DefineSequence(ParseState *pstate, CreateSeqStmt *seq)
static void fill_seq_fork_with_data(Relation rel, HeapTuple tuple, ForkNumber forkNum)
void ResetSequence(Oid seq_relid)
static void fill_seq_with_data(Relation rel, HeapTuple tuple)
struct sequence_magic sequence_magic
Datum setval_oid(PG_FUNCTION_ARGS)
static SeqTableData * last_used_seq
ObjectAddress AlterSequence(ParseState *pstate, AlterSeqStmt *stmt)
Datum pg_sequence_parameters(PG_FUNCTION_ARGS)
Datum nextval_oid(PG_FUNCTION_ARGS)
static void init_sequence(Oid relid, SeqTable *p_elm, Relation *p_rel)
Datum setval3_oid(PG_FUNCTION_ARGS)
static Form_pg_sequence_data read_seq_tuple(Relation rel, Buffer *buf, HeapTuple seqdatatuple)
Datum lastval(PG_FUNCTION_ARGS)
void seq_mask(char *page, BlockNumber blkno)
Datum nextval(PG_FUNCTION_ARGS)
int64 nextval_internal(Oid relid, bool check_permissions)
void SequenceChangePersistence(Oid relid, char newrelpersistence)
static void process_owned_by(Relation seqrel, List *owned_by, bool for_identity)
Datum pg_sequence_last_value(PG_FUNCTION_ARGS)
Datum currval_oid(PG_FUNCTION_ARGS)
static void do_setval(Oid relid, int64 next, bool iscalled)
List * sequence_options(Oid relid)
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)
void seq_redo(XLogReaderState *record)
struct SeqTableData SeqTableData
void ResetSequenceCaches(void)
static void create_seq_hashtable(void)
static Relation lock_and_open_sequence(SeqTable seq)
void DeleteSequenceTuple(Oid relid)
FormData_pg_sequence_data * Form_pg_sequence_data
struct xl_seq_rec xl_seq_rec
void smgrcreate(SMgrRelation reln, ForkNumber forknum, bool isRedo)
void smgrclose(SMgrRelation reln)
SMgrRelation smgropen(RelFileLocator rlocator, BackendId backend)
void relation_close(Relation relation, LOCKMODE lockmode)
Relation relation_openrv(const RangeVar *relation, LOCKMODE lockmode)
Relation relation_open(Oid relationId, LOCKMODE lockmode)
void log_smgrcreate(const RelFileLocator *rlocator, ForkNumber forkNum)
RelFileLocator rd_locator
void ReleaseSysCache(HeapTuple tuple)
HeapTuple SearchSysCache1(int cacheId, Datum key1)
#define SearchSysCacheCopy1(cacheId, key1)
#define SearchSysCacheExists1(cacheId, key1)
void table_close(Relation relation, LOCKMODE lockmode)
Relation table_open(Oid relationId, LOCKMODE lockmode)
ObjectAddress DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ObjectAddress *typaddress, const char *queryString)
void RangeVarCallbackOwnsRelation(const RangeVar *relation, Oid relId, Oid oldRelId, void *arg)
#define FrozenTransactionId
#define InvalidTransactionId
void PreventCommandIfReadOnly(const char *cmdname)
void PreventCommandIfParallelMode(const char *cmdname)
Boolean * makeBoolean(bool val)
Float * makeFloat(char *numericStr)
List * textToQualifiedNameList(text *textval)
TransactionId GetTopTransactionId(void)
XLogRecPtr GetRedoRecPtr(void)
void XLogRegisterData(char *data, uint32 len)
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
void XLogRegisterBuffer(uint8 block_id, Buffer buffer, uint8 flags)
void XLogBeginInsert(void)
#define XLogRecGetDataLen(decoder)
#define XLogRecGetInfo(decoder)
#define XLogRecGetData(decoder)
Buffer XLogInitBufferForRedo(XLogReaderState *record, uint8 block_id)