58 #define SEQ_LOG_VALS 32
63 #define SEQ_MAGIC 0x1717
110 bool *need_seq_rewrite,
125 bool need_seq_rewrite;
135 Datum pgs_values[Natts_pg_sequence];
136 bool pgs_nulls[Natts_pg_sequence];
158 (
errcode(ERRCODE_DUPLICATE_TABLE),
159 errmsg(
"relation \"%s\" already exists, skipping",
167 &seqform, &seqdataform,
168 &need_seq_rewrite, &owned_by);
205 stmt->tablespacename = NULL;
229 memset(pgs_nulls, 0,
sizeof(pgs_nulls));
232 pgs_values[Anum_pg_sequence_seqtypid - 1] =
ObjectIdGetDatum(seqform.seqtypid);
234 pgs_values[Anum_pg_sequence_seqincrement - 1] =
Int64GetDatumFast(seqform.seqincrement);
238 pgs_values[Anum_pg_sequence_seqcycle - 1] =
BoolGetDatum(seqform.seqcycle);
284 elog(
ERROR,
"cache lookup failed for sequence %u", seq_relid);
286 startv = pgsform->seqstart;
342 if (rel->
rd_rel->relpersistence == RELPERSISTENCE_UNLOGGED)
405 elog(
ERROR,
"failed to add sequence tuple to page");
446 bool need_seq_rewrite;
462 (
errmsg(
"relation \"%s\" does not exist, skipping",
463 stmt->sequence->relname)));
473 elog(
ERROR,
"cache lookup failed for sequence %u",
489 seqform, newdataform,
490 &need_seq_rewrite, &owned_by);
493 if (need_seq_rewrite)
579 elog(
ERROR,
"cache lookup failed for sequence %u", relid);
649 if (check_permissions &&
653 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
654 errmsg(
"permission denied for sequence %s",
680 elog(
ERROR,
"cache lookup failed for sequence %u", relid);
682 incby = pgsform->seqincrement;
683 maxv = pgsform->seqmax;
684 minv = pgsform->seqmin;
685 cache = pgsform->seqcache;
686 cycle = pgsform->seqcycle;
713 if (log < fetch || !seq->is_called)
740 if ((maxv >= 0 &&
next > maxv - incby) ||
741 (maxv < 0 && next + incby > maxv))
747 (
errcode(ERRCODE_SEQUENCE_GENERATOR_LIMIT_EXCEEDED),
748 errmsg(
"nextval: reached maximum value of sequence \"%s\" (%lld)",
759 if ((minv < 0 &&
next < minv - incby) ||
760 (minv >= 0 &&
next + incby < minv))
766 (
errcode(ERRCODE_SEQUENCE_GENERATOR_LIMIT_EXCEEDED),
767 errmsg(
"nextval: reached minimum value of sequence \"%s\" (%lld)",
879 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
880 errmsg(
"permission denied for sequence %s",
885 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
886 errmsg(
"currval of sequence \"%s\" is not yet defined in this session",
904 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
905 errmsg(
"lastval is not yet defined in this session")));
910 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
911 errmsg(
"lastval is not yet defined in this session")));
921 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
922 errmsg(
"permission denied for sequence %s",
962 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
963 errmsg(
"permission denied for sequence %s",
968 elog(
ERROR,
"cache lookup failed for sequence %u", relid);
970 maxv = pgsform->seqmax;
971 minv = pgsform->seqmin;
990 (
errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
991 errmsg(
"setval: value %lld is out of bounds for sequence \"%s\" (%lld..%lld)",
993 (
long long) minv, (
long long) maxv)));
1090 if (seq->
lxid != thislxid)
1102 seq->
lxid = thislxid;
1117 ctl.keysize =
sizeof(
Oid);
1204 elog(
ERROR,
"bad magic number in sequence \"%s\": %08X",
1261 bool *need_seq_rewrite,
1266 DefElem *restart_value = NULL;
1273 bool reset_max_value =
false;
1274 bool reset_min_value =
false;
1276 *need_seq_rewrite =
false;
1283 if (strcmp(defel->
defname,
"as") == 0)
1288 *need_seq_rewrite =
true;
1290 else if (strcmp(defel->
defname,
"increment") == 0)
1294 increment_by = defel;
1295 *need_seq_rewrite =
true;
1297 else if (strcmp(defel->
defname,
"start") == 0)
1301 start_value = defel;
1302 *need_seq_rewrite =
true;
1304 else if (strcmp(defel->
defname,
"restart") == 0)
1308 restart_value = defel;
1309 *need_seq_rewrite =
true;
1311 else if (strcmp(defel->
defname,
"maxvalue") == 0)
1316 *need_seq_rewrite =
true;
1318 else if (strcmp(defel->
defname,
"minvalue") == 0)
1323 *need_seq_rewrite =
true;
1325 else if (strcmp(defel->
defname,
"cache") == 0)
1329 cache_value = defel;
1330 *need_seq_rewrite =
true;
1332 else if (strcmp(defel->
defname,
"cycle") == 0)
1337 *need_seq_rewrite =
true;
1339 else if (strcmp(defel->
defname,
"owned_by") == 0)
1345 else if (strcmp(defel->
defname,
"sequence_name") == 0)
1356 (
errcode(ERRCODE_SYNTAX_ERROR),
1357 errmsg(
"invalid sequence option SEQUENCE NAME"),
1361 elog(
ERROR,
"option \"%s\" not recognized",
1373 if (as_type != NULL)
1377 if (newtypid != INT2OID &&
1378 newtypid != INT4OID &&
1379 newtypid != INT8OID)
1381 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1383 ?
errmsg(
"identity column type must be smallint, integer, or bigint")
1384 :
errmsg(
"sequence type must be smallint, integer, or bigint")));
1394 if ((seqform->seqtypid == INT2OID && seqform->seqmax ==
PG_INT16_MAX) ||
1395 (seqform->seqtypid == INT4OID && seqform->seqmax ==
PG_INT32_MAX) ||
1396 (seqform->seqtypid == INT8OID && seqform->seqmax ==
PG_INT64_MAX))
1397 reset_max_value =
true;
1398 if ((seqform->seqtypid == INT2OID && seqform->seqmin ==
PG_INT16_MIN) ||
1399 (seqform->seqtypid == INT4OID && seqform->seqmin ==
PG_INT32_MIN) ||
1400 (seqform->seqtypid == INT8OID && seqform->seqmin ==
PG_INT64_MIN))
1401 reset_min_value =
true;
1404 seqform->seqtypid = newtypid;
1408 seqform->seqtypid = INT8OID;
1412 if (increment_by != NULL)
1414 seqform->seqincrement =
defGetInt64(increment_by);
1415 if (seqform->seqincrement == 0)
1417 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1418 errmsg(
"INCREMENT must not be zero")));
1423 seqform->seqincrement = 1;
1427 if (is_cycled != NULL)
1435 seqform->seqcycle =
false;
1439 if (max_value != NULL && max_value->
arg)
1444 else if (isInit || max_value != NULL || reset_max_value)
1446 if (seqform->seqincrement > 0 || reset_max_value)
1449 if (seqform->seqtypid == INT2OID)
1451 else if (seqform->seqtypid == INT4OID)
1457 seqform->seqmax = -1;
1465 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1466 errmsg(
"MAXVALUE (%lld) is out of range for sequence data type %s",
1467 (
long long) seqform->seqmax,
1471 if (min_value != NULL && min_value->
arg)
1476 else if (isInit || min_value != NULL || reset_min_value)
1478 if (seqform->seqincrement < 0 || reset_min_value)
1481 if (seqform->seqtypid == INT2OID)
1483 else if (seqform->seqtypid == INT4OID)
1489 seqform->seqmin = 1;
1497 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1498 errmsg(
"MINVALUE (%lld) is out of range for sequence data type %s",
1499 (
long long) seqform->seqmin,
1503 if (seqform->seqmin >= seqform->seqmax)
1505 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1506 errmsg(
"MINVALUE (%lld) must be less than MAXVALUE (%lld)",
1507 (
long long) seqform->seqmin,
1508 (
long long) seqform->seqmax)));
1511 if (start_value != NULL)
1517 if (seqform->seqincrement > 0)
1518 seqform->seqstart = seqform->seqmin;
1520 seqform->seqstart = seqform->seqmax;
1524 if (seqform->seqstart < seqform->seqmin)
1526 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1527 errmsg(
"START value (%lld) cannot be less than MINVALUE (%lld)",
1528 (
long long) seqform->seqstart,
1529 (
long long) seqform->seqmin)));
1530 if (seqform->seqstart > seqform->seqmax)
1532 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1533 errmsg(
"START value (%lld) cannot be greater than MAXVALUE (%lld)",
1534 (
long long) seqform->seqstart,
1535 (
long long) seqform->seqmax)));
1538 if (restart_value != NULL)
1540 if (restart_value->
arg != NULL)
1554 if (seqdataform->
last_value < seqform->seqmin)
1556 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1557 errmsg(
"RESTART value (%lld) cannot be less than MINVALUE (%lld)",
1559 (
long long) seqform->seqmin)));
1560 if (seqdataform->
last_value > seqform->seqmax)
1562 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1563 errmsg(
"RESTART value (%lld) cannot be greater than MAXVALUE (%lld)",
1565 (
long long) seqform->seqmax)));
1568 if (cache_value != NULL)
1571 if (seqform->seqcache <= 0)
1573 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1574 errmsg(
"CACHE (%lld) must be greater than zero",
1575 (
long long) seqform->seqcache)));
1580 seqform->seqcache = 1;
1609 (
errcode(ERRCODE_SYNTAX_ERROR),
1610 errmsg(
"invalid OWNED BY option"),
1611 errhint(
"Specify OWNED BY table.column or OWNED BY NONE.")));
1630 if (!(tablerel->
rd_rel->relkind == RELKIND_RELATION ||
1631 tablerel->
rd_rel->relkind == RELKIND_FOREIGN_TABLE ||
1632 tablerel->
rd_rel->relkind == RELKIND_VIEW ||
1633 tablerel->
rd_rel->relkind == RELKIND_PARTITIONED_TABLE))
1635 (
errcode(ERRCODE_WRONG_OBJECT_TYPE),
1636 errmsg(
"sequence cannot be owned by relation \"%s\"",
1641 if (seqrel->
rd_rel->relowner != tablerel->
rd_rel->relowner)
1643 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1644 errmsg(
"sequence must have same owner as table it is linked to")));
1647 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1648 errmsg(
"sequence must be in same schema as table it is linked to")));
1654 (
errcode(ERRCODE_UNDEFINED_COLUMN),
1655 errmsg(
"column \"%s\" of relation \"%s\" does not exist",
1669 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1670 errmsg(
"cannot change ownership of identity sequence"),
1671 errdetail(
"Sequence \"%s\" is linked to table \"%s\".",
1681 RelationRelationId, deptype);
1688 refobject.
classId = RelationRelationId;
1691 depobject.
classId = RelationRelationId;
1715 elog(
ERROR,
"cache lookup failed for sequence %u", relid);
1752 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1753 errmsg(
"permission denied for sequence %s",
1757 elog(
ERROR,
"return type must be a row type");
1759 memset(isnull, 0,
sizeof(isnull));
1763 elog(
ERROR,
"cache lookup failed for sequence %u", relid);
1789 #define PG_GET_SEQUENCE_DATA_COLS 2
1828 memset(isnull,
true,
sizeof(isnull));
1835 #undef PG_GET_SEQUENCE_DATA_COLS
1850 bool is_called =
false;
1903 elog(
PANIC,
"seq_redo: unknown op code %u", info);
1928 elog(
PANIC,
"seq_redo: failed to add item to page");
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]
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 char * PageGetSpecialPointer(Page page)
static XLogRecPtr PageGetLSN(const char *page)
#define PageAddItem(page, item, size, offsetNumber, overwrite, is_heap)
#define Assert(condition)
#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)
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 pg_get_sequence_data(PG_FUNCTION_ARGS)
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)
#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)
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
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,...)
TupleDesc BlessTupleDesc(TupleDesc tupdesc)
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)
#define PG_RETURN_DATUM(x)
TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc)
static Datum HeapTupleGetDatum(const HeapTupleData *tuple)
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)
#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)
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)
#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)
Boolean * makeBoolean(bool val)
Float * makeFloat(char *numericStr)
List * textToQualifiedNameList(text *textval)
TransactionId GetTopTransactionId(void)
bool RecoveryInProgress(void)
XLogRecPtr GetRedoRecPtr(void)
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
void XLogRegisterData(const char *data, uint32 len)
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)