59#define SEQ_LOG_VALS 32
64#define SEQ_MAGIC 0x1717
113 bool *need_seq_rewrite,
130 bool need_seq_rewrite;
140 Datum pgs_values[Natts_pg_sequence];
141 bool pgs_nulls[Natts_pg_sequence];
163 (
errcode(ERRCODE_DUPLICATE_TABLE),
164 errmsg(
"relation \"%s\" already exists, skipping",
172 &seqform, &last_value, &reset_state, &is_called,
173 &need_seq_rewrite, &owned_by);
210 stmt->tablespacename = NULL;
234 memset(pgs_nulls, 0,
sizeof(pgs_nulls));
237 pgs_values[Anum_pg_sequence_seqtypid - 1] =
ObjectIdGetDatum(seqform.seqtypid);
239 pgs_values[Anum_pg_sequence_seqincrement - 1] =
Int64GetDatumFast(seqform.seqincrement);
243 pgs_values[Anum_pg_sequence_seqcycle - 1] =
BoolGetDatum(seqform.seqcycle);
289 elog(
ERROR,
"cache lookup failed for sequence %u", seq_relid);
291 startv = pgsform->seqstart;
347 if (rel->
rd_rel->relpersistence == RELPERSISTENCE_UNLOGGED)
410 elog(
ERROR,
"failed to add sequence tuple to page");
451 bool need_seq_rewrite;
456 bool reset_state =
false;
470 (
errmsg(
"relation \"%s\" does not exist, skipping",
471 stmt->sequence->relname)));
481 elog(
ERROR,
"cache lookup failed for sequence %u",
499 seqform, &last_value, &reset_state, &is_called,
500 &need_seq_rewrite, &owned_by);
503 if (need_seq_rewrite)
593 elog(
ERROR,
"cache lookup failed for sequence %u", relid);
663 if (check_permissions &&
667 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
668 errmsg(
"permission denied for sequence %s",
694 elog(
ERROR,
"cache lookup failed for sequence %u", relid);
696 incby = pgsform->seqincrement;
697 maxv = pgsform->seqmax;
698 minv = pgsform->seqmin;
699 cache = pgsform->seqcache;
700 cycle = pgsform->seqcycle;
727 if (log < fetch || !seq->is_called)
754 if ((maxv >= 0 &&
next > maxv - incby) ||
755 (maxv < 0 && next + incby > maxv))
761 (
errcode(ERRCODE_SEQUENCE_GENERATOR_LIMIT_EXCEEDED),
762 errmsg(
"nextval: reached maximum value of sequence \"%s\" (%" PRId64
")",
773 if ((minv < 0 &&
next < minv - incby) ||
774 (minv >= 0 &&
next + incby < minv))
780 (
errcode(ERRCODE_SEQUENCE_GENERATOR_LIMIT_EXCEEDED),
781 errmsg(
"nextval: reached minimum value of sequence \"%s\" (%" PRId64
")",
893 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
894 errmsg(
"permission denied for sequence %s",
899 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
900 errmsg(
"currval of sequence \"%s\" is not yet defined in this session",
918 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
919 errmsg(
"lastval is not yet defined in this session")));
924 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
925 errmsg(
"lastval is not yet defined in this session")));
935 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
936 errmsg(
"permission denied for sequence %s",
976 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
977 errmsg(
"permission denied for sequence %s",
982 elog(
ERROR,
"cache lookup failed for sequence %u", relid);
984 maxv = pgsform->seqmax;
985 minv = pgsform->seqmin;
1002 if ((
next < minv) || (
next > maxv))
1004 (
errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1005 errmsg(
"setval: value %" PRId64
" is out of bounds for sequence \"%s\" (%" PRId64
"..%" PRId64
")",
1104 if (seq->
lxid != thislxid)
1116 seq->
lxid = thislxid;
1131 ctl.keysize =
sizeof(
Oid);
1218 elog(
ERROR,
"bad magic number in sequence \"%s\": %08X",
1279 bool *need_seq_rewrite,
1284 DefElem *restart_value = NULL;
1291 bool reset_max_value =
false;
1292 bool reset_min_value =
false;
1294 *need_seq_rewrite =
false;
1301 if (strcmp(defel->
defname,
"as") == 0)
1306 *need_seq_rewrite =
true;
1308 else if (strcmp(defel->
defname,
"increment") == 0)
1312 increment_by = defel;
1313 *need_seq_rewrite =
true;
1315 else if (strcmp(defel->
defname,
"start") == 0)
1319 start_value = defel;
1320 *need_seq_rewrite =
true;
1322 else if (strcmp(defel->
defname,
"restart") == 0)
1326 restart_value = defel;
1327 *need_seq_rewrite =
true;
1329 else if (strcmp(defel->
defname,
"maxvalue") == 0)
1334 *need_seq_rewrite =
true;
1336 else if (strcmp(defel->
defname,
"minvalue") == 0)
1341 *need_seq_rewrite =
true;
1343 else if (strcmp(defel->
defname,
"cache") == 0)
1347 cache_value = defel;
1348 *need_seq_rewrite =
true;
1350 else if (strcmp(defel->
defname,
"cycle") == 0)
1355 *need_seq_rewrite =
true;
1357 else if (strcmp(defel->
defname,
"owned_by") == 0)
1363 else if (strcmp(defel->
defname,
"sequence_name") == 0)
1374 (
errcode(ERRCODE_SYNTAX_ERROR),
1375 errmsg(
"invalid sequence option SEQUENCE NAME"),
1379 elog(
ERROR,
"option \"%s\" not recognized",
1388 *reset_state =
true;
1391 if (as_type != NULL)
1395 if (newtypid != INT2OID &&
1396 newtypid != INT4OID &&
1397 newtypid != INT8OID)
1399 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1401 ?
errmsg(
"identity column type must be smallint, integer, or bigint")
1402 :
errmsg(
"sequence type must be smallint, integer, or bigint")));
1412 if ((seqform->seqtypid == INT2OID && seqform->seqmax ==
PG_INT16_MAX) ||
1413 (seqform->seqtypid == INT4OID && seqform->seqmax ==
PG_INT32_MAX) ||
1414 (seqform->seqtypid == INT8OID && seqform->seqmax ==
PG_INT64_MAX))
1415 reset_max_value =
true;
1416 if ((seqform->seqtypid == INT2OID && seqform->seqmin ==
PG_INT16_MIN) ||
1417 (seqform->seqtypid == INT4OID && seqform->seqmin ==
PG_INT32_MIN) ||
1418 (seqform->seqtypid == INT8OID && seqform->seqmin ==
PG_INT64_MIN))
1419 reset_min_value =
true;
1422 seqform->seqtypid = newtypid;
1426 seqform->seqtypid = INT8OID;
1430 if (increment_by != NULL)
1432 seqform->seqincrement =
defGetInt64(increment_by);
1433 if (seqform->seqincrement == 0)
1435 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1436 errmsg(
"INCREMENT must not be zero")));
1437 *reset_state =
true;
1441 seqform->seqincrement = 1;
1445 if (is_cycled != NULL)
1449 *reset_state =
true;
1453 seqform->seqcycle =
false;
1457 if (max_value != NULL && max_value->
arg)
1460 *reset_state =
true;
1462 else if (isInit || max_value != NULL || reset_max_value)
1464 if (seqform->seqincrement > 0 || reset_max_value)
1467 if (seqform->seqtypid == INT2OID)
1469 else if (seqform->seqtypid == INT4OID)
1475 seqform->seqmax = -1;
1476 *reset_state =
true;
1483 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1484 errmsg(
"MAXVALUE (%" PRId64
") is out of range for sequence data type %s",
1489 if (min_value != NULL && min_value->
arg)
1492 *reset_state =
true;
1494 else if (isInit || min_value != NULL || reset_min_value)
1496 if (seqform->seqincrement < 0 || reset_min_value)
1499 if (seqform->seqtypid == INT2OID)
1501 else if (seqform->seqtypid == INT4OID)
1507 seqform->seqmin = 1;
1508 *reset_state =
true;
1515 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1516 errmsg(
"MINVALUE (%" PRId64
") is out of range for sequence data type %s",
1521 if (seqform->seqmin >= seqform->seqmax)
1523 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1524 errmsg(
"MINVALUE (%" PRId64
") must be less than MAXVALUE (%" PRId64
")",
1529 if (start_value != NULL)
1535 if (seqform->seqincrement > 0)
1536 seqform->seqstart = seqform->seqmin;
1538 seqform->seqstart = seqform->seqmax;
1542 if (seqform->seqstart < seqform->seqmin)
1544 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1545 errmsg(
"START value (%" PRId64
") cannot be less than MINVALUE (%" PRId64
")",
1548 if (seqform->seqstart > seqform->seqmax)
1550 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1551 errmsg(
"START value (%" PRId64
") cannot be greater than MAXVALUE (%" PRId64
")",
1556 if (restart_value != NULL)
1558 if (restart_value->
arg != NULL)
1561 *last_value = seqform->seqstart;
1563 *reset_state =
true;
1567 *last_value = seqform->seqstart;
1572 if (*last_value < seqform->seqmin)
1574 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1575 errmsg(
"RESTART value (%" PRId64
") cannot be less than MINVALUE (%" PRId64
")",
1578 if (*last_value > seqform->seqmax)
1580 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1581 errmsg(
"RESTART value (%" PRId64
") cannot be greater than MAXVALUE (%" PRId64
")",
1586 if (cache_value != NULL)
1589 if (seqform->seqcache <= 0)
1591 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1592 errmsg(
"CACHE (%" PRId64
") must be greater than zero",
1593 seqform->seqcache)));
1594 *reset_state =
true;
1598 seqform->seqcache = 1;
1627 (
errcode(ERRCODE_SYNTAX_ERROR),
1628 errmsg(
"invalid OWNED BY option"),
1629 errhint(
"Specify OWNED BY table.column or OWNED BY NONE.")));
1648 if (!(tablerel->
rd_rel->relkind == RELKIND_RELATION ||
1649 tablerel->
rd_rel->relkind == RELKIND_FOREIGN_TABLE ||
1650 tablerel->
rd_rel->relkind == RELKIND_VIEW ||
1651 tablerel->
rd_rel->relkind == RELKIND_PARTITIONED_TABLE))
1653 (
errcode(ERRCODE_WRONG_OBJECT_TYPE),
1654 errmsg(
"sequence cannot be owned by relation \"%s\"",
1659 if (seqrel->
rd_rel->relowner != tablerel->
rd_rel->relowner)
1661 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1662 errmsg(
"sequence must have same owner as table it is linked to")));
1665 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1666 errmsg(
"sequence must be in same schema as table it is linked to")));
1672 (
errcode(ERRCODE_UNDEFINED_COLUMN),
1673 errmsg(
"column \"%s\" of relation \"%s\" does not exist",
1687 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1688 errmsg(
"cannot change ownership of identity sequence"),
1689 errdetail(
"Sequence \"%s\" is linked to table \"%s\".",
1699 RelationRelationId, deptype);
1706 refobject.
classId = RelationRelationId;
1709 depobject.
classId = RelationRelationId;
1733 elog(
ERROR,
"cache lookup failed for sequence %u", relid);
1770 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1771 errmsg(
"permission denied for sequence %s",
1775 elog(
ERROR,
"return type must be a row type");
1777 memset(isnull, 0,
sizeof(isnull));
1781 elog(
ERROR,
"cache lookup failed for sequence %u", relid);
1807#define PG_GET_SEQUENCE_DATA_COLS 3
1851 memset(isnull,
true,
sizeof(isnull));
1858#undef PG_GET_SEQUENCE_DATA_COLS
1873 bool is_called =
false;
1926 elog(
PANIC,
"seq_redo: unknown op code %u", info);
1951 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)
#define PageGetSpecialPointer(page)
static Item 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)
struct sequence_magic sequence_magic
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)
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)
void seq_redo(XLogReaderState *record)
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
struct xl_seq_rec xl_seq_rec
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, 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
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)
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)
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)
#define XLogRecGetDataLen(decoder)
#define XLogRecGetInfo(decoder)
#define XLogRecGetData(decoder)
Buffer XLogInitBufferForRedo(XLogReaderState *record, uint8 block_id)