58#define SEQ_LOG_VALS 32
102 bool *need_seq_rewrite,
118 bool need_seq_rewrite;
128 Datum pgs_values[Natts_pg_sequence];
129 bool pgs_nulls[Natts_pg_sequence];
151 (
errcode(ERRCODE_DUPLICATE_TABLE),
152 errmsg(
"relation \"%s\" already exists, skipping",
160 &seqform, &last_value, &reset_state, &is_called,
161 &need_seq_rewrite, &owned_by);
198 stmt->tablespacename = NULL;
222 memset(pgs_nulls, 0,
sizeof(pgs_nulls));
225 pgs_values[Anum_pg_sequence_seqtypid - 1] =
ObjectIdGetDatum(seqform.seqtypid);
227 pgs_values[Anum_pg_sequence_seqincrement - 1] =
Int64GetDatumFast(seqform.seqincrement);
231 pgs_values[Anum_pg_sequence_seqcycle - 1] =
BoolGetDatum(seqform.seqcycle);
277 elog(
ERROR,
"cache lookup failed for sequence %u", seq_relid);
279 startv = pgsform->seqstart;
335 if (rel->
rd_rel->relpersistence == RELPERSISTENCE_UNLOGGED)
397 elog(
ERROR,
"failed to add sequence tuple to page");
438 bool need_seq_rewrite;
443 bool reset_state =
false;
457 (
errmsg(
"relation \"%s\" does not exist, skipping",
458 stmt->sequence->relname)));
468 elog(
ERROR,
"cache lookup failed for sequence %u",
486 seqform, &last_value, &reset_state, &is_called,
487 &need_seq_rewrite, &owned_by);
490 if (need_seq_rewrite)
580 elog(
ERROR,
"cache lookup failed for sequence %u", relid);
650 if (check_permissions &&
654 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
655 errmsg(
"permission denied for sequence %s",
681 elog(
ERROR,
"cache lookup failed for sequence %u", relid);
683 incby = pgsform->seqincrement;
684 maxv = pgsform->seqmax;
685 minv = pgsform->seqmin;
686 cache = pgsform->seqcache;
687 cycle = pgsform->seqcycle;
714 if (log < fetch || !seq->is_called)
741 if ((maxv >= 0 &&
next > maxv - incby) ||
742 (maxv < 0 && next + incby > maxv))
748 (
errcode(ERRCODE_SEQUENCE_GENERATOR_LIMIT_EXCEEDED),
749 errmsg(
"nextval: reached maximum value of sequence \"%s\" (%" PRId64
")",
760 if ((minv < 0 &&
next < minv - incby) ||
761 (minv >= 0 &&
next + incby < minv))
767 (
errcode(ERRCODE_SEQUENCE_GENERATOR_LIMIT_EXCEEDED),
768 errmsg(
"nextval: reached minimum value of sequence \"%s\" (%" PRId64
")",
880 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
881 errmsg(
"permission denied for sequence %s",
886 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
887 errmsg(
"currval of sequence \"%s\" is not yet defined in this session",
905 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
906 errmsg(
"lastval is not yet defined in this session")));
911 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
912 errmsg(
"lastval is not yet defined in this session")));
922 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
923 errmsg(
"permission denied for sequence %s",
963 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
964 errmsg(
"permission denied for sequence %s",
969 elog(
ERROR,
"cache lookup failed for sequence %u", relid);
971 maxv = pgsform->seqmax;
972 minv = pgsform->seqmin;
991 (
errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
992 errmsg(
"setval: value %" PRId64
" is out of bounds for sequence \"%s\" (%" PRId64
"..%" PRId64
")",
1091 if (seq->
lxid != thislxid)
1103 seq->
lxid = thislxid;
1118 ctl.keysize =
sizeof(
Oid);
1205 elog(
ERROR,
"bad magic number in sequence \"%s\": %08X",
1266 bool *need_seq_rewrite,
1271 DefElem *restart_value = NULL;
1278 bool reset_max_value =
false;
1279 bool reset_min_value =
false;
1281 *need_seq_rewrite =
false;
1288 if (strcmp(defel->
defname,
"as") == 0)
1293 *need_seq_rewrite =
true;
1295 else if (strcmp(defel->
defname,
"increment") == 0)
1299 increment_by = defel;
1300 *need_seq_rewrite =
true;
1302 else if (strcmp(defel->
defname,
"start") == 0)
1306 start_value = defel;
1307 *need_seq_rewrite =
true;
1309 else if (strcmp(defel->
defname,
"restart") == 0)
1313 restart_value = defel;
1314 *need_seq_rewrite =
true;
1316 else if (strcmp(defel->
defname,
"maxvalue") == 0)
1321 *need_seq_rewrite =
true;
1323 else if (strcmp(defel->
defname,
"minvalue") == 0)
1328 *need_seq_rewrite =
true;
1330 else if (strcmp(defel->
defname,
"cache") == 0)
1334 cache_value = defel;
1335 *need_seq_rewrite =
true;
1337 else if (strcmp(defel->
defname,
"cycle") == 0)
1342 *need_seq_rewrite =
true;
1344 else if (strcmp(defel->
defname,
"owned_by") == 0)
1350 else if (strcmp(defel->
defname,
"sequence_name") == 0)
1361 (
errcode(ERRCODE_SYNTAX_ERROR),
1362 errmsg(
"invalid sequence option SEQUENCE NAME"),
1366 elog(
ERROR,
"option \"%s\" not recognized",
1375 *reset_state =
true;
1378 if (as_type != NULL)
1382 if (newtypid != INT2OID &&
1383 newtypid != INT4OID &&
1384 newtypid != INT8OID)
1386 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1388 ?
errmsg(
"identity column type must be smallint, integer, or bigint")
1389 :
errmsg(
"sequence type must be smallint, integer, or bigint")));
1399 if ((seqform->seqtypid == INT2OID && seqform->seqmax ==
PG_INT16_MAX) ||
1400 (seqform->seqtypid == INT4OID && seqform->seqmax ==
PG_INT32_MAX) ||
1401 (seqform->seqtypid == INT8OID && seqform->seqmax ==
PG_INT64_MAX))
1402 reset_max_value =
true;
1403 if ((seqform->seqtypid == INT2OID && seqform->seqmin ==
PG_INT16_MIN) ||
1404 (seqform->seqtypid == INT4OID && seqform->seqmin ==
PG_INT32_MIN) ||
1405 (seqform->seqtypid == INT8OID && seqform->seqmin ==
PG_INT64_MIN))
1406 reset_min_value =
true;
1409 seqform->seqtypid = newtypid;
1413 seqform->seqtypid = INT8OID;
1417 if (increment_by != NULL)
1419 seqform->seqincrement =
defGetInt64(increment_by);
1420 if (seqform->seqincrement == 0)
1422 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1423 errmsg(
"INCREMENT must not be zero")));
1424 *reset_state =
true;
1428 seqform->seqincrement = 1;
1432 if (is_cycled != NULL)
1436 *reset_state =
true;
1440 seqform->seqcycle =
false;
1444 if (max_value != NULL && max_value->
arg)
1447 *reset_state =
true;
1449 else if (isInit || max_value != NULL || reset_max_value)
1451 if (seqform->seqincrement > 0 || reset_max_value)
1454 if (seqform->seqtypid == INT2OID)
1456 else if (seqform->seqtypid == INT4OID)
1462 seqform->seqmax = -1;
1463 *reset_state =
true;
1470 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1471 errmsg(
"MAXVALUE (%" PRId64
") is out of range for sequence data type %s",
1476 if (min_value != NULL && min_value->
arg)
1479 *reset_state =
true;
1481 else if (isInit || min_value != NULL || reset_min_value)
1483 if (seqform->seqincrement < 0 || reset_min_value)
1486 if (seqform->seqtypid == INT2OID)
1488 else if (seqform->seqtypid == INT4OID)
1494 seqform->seqmin = 1;
1495 *reset_state =
true;
1502 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1503 errmsg(
"MINVALUE (%" PRId64
") is out of range for sequence data type %s",
1508 if (seqform->seqmin >= seqform->seqmax)
1510 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1511 errmsg(
"MINVALUE (%" PRId64
") must be less than MAXVALUE (%" PRId64
")",
1516 if (start_value != NULL)
1522 if (seqform->seqincrement > 0)
1523 seqform->seqstart = seqform->seqmin;
1525 seqform->seqstart = seqform->seqmax;
1529 if (seqform->seqstart < seqform->seqmin)
1531 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1532 errmsg(
"START value (%" PRId64
") cannot be less than MINVALUE (%" PRId64
")",
1535 if (seqform->seqstart > seqform->seqmax)
1537 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1538 errmsg(
"START value (%" PRId64
") cannot be greater than MAXVALUE (%" PRId64
")",
1543 if (restart_value != NULL)
1545 if (restart_value->
arg != NULL)
1548 *last_value = seqform->seqstart;
1550 *reset_state =
true;
1554 *last_value = seqform->seqstart;
1559 if (*last_value < seqform->seqmin)
1561 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1562 errmsg(
"RESTART value (%" PRId64
") cannot be less than MINVALUE (%" PRId64
")",
1565 if (*last_value > seqform->seqmax)
1567 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1568 errmsg(
"RESTART value (%" PRId64
") cannot be greater than MAXVALUE (%" PRId64
")",
1573 if (cache_value != NULL)
1576 if (seqform->seqcache <= 0)
1578 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1579 errmsg(
"CACHE (%" PRId64
") must be greater than zero",
1580 seqform->seqcache)));
1581 *reset_state =
true;
1585 seqform->seqcache = 1;
1614 (
errcode(ERRCODE_SYNTAX_ERROR),
1615 errmsg(
"invalid OWNED BY option"),
1616 errhint(
"Specify OWNED BY table.column or OWNED BY NONE.")));
1635 if (!(tablerel->
rd_rel->relkind == RELKIND_RELATION ||
1636 tablerel->
rd_rel->relkind == RELKIND_FOREIGN_TABLE ||
1637 tablerel->
rd_rel->relkind == RELKIND_VIEW ||
1638 tablerel->
rd_rel->relkind == RELKIND_PARTITIONED_TABLE))
1640 (
errcode(ERRCODE_WRONG_OBJECT_TYPE),
1641 errmsg(
"sequence cannot be owned by relation \"%s\"",
1646 if (seqrel->
rd_rel->relowner != tablerel->
rd_rel->relowner)
1648 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1649 errmsg(
"sequence must have same owner as table it is linked to")));
1652 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1653 errmsg(
"sequence must be in same schema as table it is linked to")));
1659 (
errcode(ERRCODE_UNDEFINED_COLUMN),
1660 errmsg(
"column \"%s\" of relation \"%s\" does not exist",
1674 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1675 errmsg(
"cannot change ownership of identity sequence"),
1676 errdetail(
"Sequence \"%s\" is linked to table \"%s\".",
1686 RelationRelationId, deptype);
1693 refobject.
classId = RelationRelationId;
1696 depobject.
classId = RelationRelationId;
1720 elog(
ERROR,
"cache lookup failed for sequence %u", relid);
1757 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1758 errmsg(
"permission denied for sequence %s",
1762 elog(
ERROR,
"return type must be a row type");
1764 memset(isnull, 0,
sizeof(isnull));
1768 elog(
ERROR,
"cache lookup failed for sequence %u", relid);
1795#define PG_GET_SEQUENCE_DATA_COLS 3
1839 memset(isnull,
true,
sizeof(isnull));
1846#undef PG_GET_SEQUENCE_DATA_COLS
1861 bool is_called =
false;
Relation sequence_open(Oid relationId, LOCKMODE lockmode)
void sequence_close(Relation relation, LOCKMODE lockmode)
AclResult pg_class_aclcheck(Oid table_oid, Oid roleid, AclMode mode)
#define InvalidAttrNumber
static Datum values[MAXATTR]
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)
#define PageGetSpecialPointer(page)
static void * PageGetItem(const PageData *page, const ItemIdData *itemId)
static ItemId PageGetItemId(Page page, OffsetNumber offsetNumber)
static void PageSetLSN(Page page, XLogRecPtr lsn)
static XLogRecPtr PageGetLSN(const PageData *page)
#define PageAddItem(page, item, size, offsetNumber, overwrite, is_heap)
#define BoolIsValid(boolean)
uint32 LocalTransactionId
#define OidIsValid(objectId)
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)
Datum setval_oid(PG_FUNCTION_ARGS)
List * sequence_options(Oid relid)
static SeqTableData * last_used_seq
ObjectAddress AlterSequence(ParseState *pstate, AlterSeqStmt *stmt)
Datum pg_sequence_parameters(PG_FUNCTION_ARGS)
void SetSequence(Oid relid, int64 next, bool iscalled)
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 pg_get_sequence_data(PG_FUNCTION_ARGS)
Datum lastval(PG_FUNCTION_ARGS)
Datum nextval(PG_FUNCTION_ARGS)
int64 nextval_internal(Oid relid, bool check_permissions)
void SequenceChangePersistence(Oid relid, char newrelpersistence)
#define PG_GET_SEQUENCE_DATA_COLS
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)
struct SeqTableData SeqTableData
void ResetSequenceCaches(void)
static void create_seq_hashtable(void)
static void init_params(ParseState *pstate, List *options, bool for_identity, bool isInit, Form_pg_sequence seqform, int64 *last_value, bool *reset_state, bool *is_called, bool *need_seq_rewrite, List **owned_by)
static Relation lock_and_open_sequence(SeqTable seq)
void DeleteSequenceTuple(Oid relid)
FormData_pg_sequence_data * Form_pg_sequence_data
TypeName * defGetTypeName(DefElem *def)
List * defGetQualifiedName(DefElem *def)
int64 defGetInt64(DefElem *def)
void errorConflictingDefElem(DefElem *defel, ParseState *pstate)
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
HTAB * hash_create(const char *tabname, int64 nelem, const HASHCTL *info, int flags)
void hash_destroy(HTAB *hashp)
int errdetail(const char *fmt,...)
int errhint(const char *fmt,...)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
TupleDesc BlessTupleDesc(TupleDesc tupdesc)
#define PG_GETARG_TEXT_PP(n)
#define PG_RETURN_INT64(x)
#define PG_GETARG_INT64(n)
#define PG_GETARG_BOOL(n)
#define PG_RETURN_DATUM(x)
TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc)
static Datum HeapTupleGetDatum(const HeapTupleData *tuple)
Assert(PointerIsAligned(start, uint64))
HeapTuple heap_copytuple(HeapTuple tuple)
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
void heap_freetuple(HeapTuple htup)
HeapTupleHeaderData * HeapTupleHeader
#define HeapTupleIsValid(tuple)
static void HeapTupleHeaderSetXminFrozen(HeapTupleHeaderData *tup)
static void HeapTupleHeaderSetCmin(HeapTupleHeaderData *tup, CommandId cid)
static TransactionId HeapTupleHeaderGetRawXmax(const HeapTupleHeaderData *tup)
#define HEAP_XMAX_IS_MULTI
#define HEAP_XMAX_INVALID
static void * GETSTRUCT(const HeapTupleData *tuple)
static void HeapTupleHeaderSetXmin(HeapTupleHeaderData *tup, TransactionId xid)
static void HeapTupleHeaderSetXmax(HeapTupleHeaderData *tup, TransactionId xid)
void CatalogTupleUpdate(Relation heapRel, const ItemPointerData *otid, HeapTuple tup)
void CatalogTupleInsert(Relation heapRel, HeapTuple tup)
void CatalogTupleDelete(Relation heapRel, const ItemPointerData *tid)
#define ItemIdGetLength(itemId)
#define ItemIdIsNormal(itemId)
static void ItemPointerSet(ItemPointerData *pointer, BlockNumber blockNumber, OffsetNumber offNum)
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
char * get_rel_name(Oid relid)
AttrNumber get_attnum(Oid relid, const char *attname)
DefElem * makeDefElem(char *name, Node *arg, int location)
ColumnDef * makeColumnDef(const char *colname, Oid typeOid, int32 typmod, Oid collOid)
#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)
static Datum LSNGetDatum(XLogRecPtr X)
FormData_pg_sequence * Form_pg_sequence
static Datum Int64GetDatum(int64 X)
#define Int64GetDatumFast(X)
static Datum BoolGetDatum(bool X)
static Datum ObjectIdGetDatum(Oid X)
#define INVALID_PROC_NUMBER
char * psprintf(const char *fmt,...)
#define RelationGetRelid(relation)
#define RelationGetDescr(relation)
#define RelationGetRelationName(relation)
#define RelationNeedsWAL(relation)
#define RELATION_IS_OTHER_TEMP(relation)
#define RelationGetNamespace(relation)
#define RelationIsPermanent(relation)
void RelationSetNewRelfilenumber(Relation relation, char persistence)
#define InvalidRelFileNumber
ResourceOwner TopTransactionResourceOwner
ResourceOwner CurrentResourceOwner
SMgrRelation smgropen(RelFileLocator rlocator, ProcNumber backend)
void smgrcreate(SMgrRelation reln, ForkNumber forknum, bool isRedo)
void smgrclose(SMgrRelation reln)
void relation_close(Relation relation, LOCKMODE lockmode)
Relation relation_openrv(const RangeVar *relation, 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
TupleDesc CreateTemplateTupleDesc(int natts)
void TupleDescInitEntry(TupleDesc desc, AttrNumber attributeNumber, const char *attributeName, Oid oidtypeid, int32 typmod, int attdim)
void PreventCommandIfReadOnly(const char *cmdname)
void PreventCommandIfParallelMode(const char *cmdname)
Float * makeFloat(char *numericStr)
Boolean * makeBoolean(bool val)
List * textToQualifiedNameList(text *textval)
TransactionId GetTopTransactionId(void)
bool RecoveryInProgress(void)
XLogRecPtr GetRedoRecPtr(void)
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
void XLogRegisterData(const void *data, uint32 len)
void XLogRegisterBuffer(uint8 block_id, Buffer buffer, uint8 flags)
void XLogBeginInsert(void)