Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit737b025

Browse files
kelvicharssher
authored andcommitted
[PGPRO-4074] Sequence hooks for mm
(cherry picked from commit 259711d6d874cf13fceb566f07128f21b5a4e9dc)tags: multimaster(cherry picked from commit 5b18256fd471a9e40d11ed516531e1c5a3269939)
1 parentc9bcd7f commit737b025

File tree

2 files changed

+147
-0
lines changed

2 files changed

+147
-0
lines changed

‎src/backend/commands/sequence.c

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ typedef struct SeqTableData
8686

8787
typedefSeqTableData*SeqTable;
8888

89+
seq_nextval_hook_tSeqNextvalHook;
90+
8991
staticHTAB*seqhashtab=NULL;/* hash table for SeqTable items */
9092

9193
/*
@@ -628,6 +630,10 @@ nextval_internal(Oid relid, bool check_permissions)
628630
elm->last+=elm->increment;
629631
relation_close(seqrel,NoLock);
630632
last_used_seq=elm;
633+
634+
if (SeqNextvalHook)
635+
SeqNextvalHook(relid,elm->last);
636+
631637
returnelm->last;
632638
}
633639

@@ -823,6 +829,9 @@ nextval_internal(Oid relid, bool check_permissions)
823829

824830
relation_close(seqrel,NoLock);
825831

832+
if (SeqNextvalHook)
833+
SeqNextvalHook(relid,result);
834+
826835
returnresult;
827836
}
828837

@@ -892,6 +901,139 @@ lastval(PG_FUNCTION_ARGS)
892901
PG_RETURN_INT64(result);
893902
}
894903

904+
/*
905+
* Bump last value to next iff next > value.
906+
* Support routine for multimaster's monotonic sequences.
907+
*/
908+
void
909+
AdjustSequence(Oidrelid,int64next)
910+
{
911+
SeqTableelm;
912+
Relationseqrel;
913+
Bufferbuf;
914+
HeapTupleDataseqdatatuple;
915+
Form_pg_sequence_dataseq;
916+
HeapTuplepgstuple;
917+
Form_pg_sequencepgsform;
918+
int64maxv,
919+
minv,
920+
incby,
921+
cache;
922+
int64last;
923+
924+
/* open and lock sequence */
925+
init_sequence(relid,&elm,&seqrel);
926+
927+
if (pg_class_aclcheck(elm->relid,GetUserId(),ACL_UPDATE)!=ACLCHECK_OK)
928+
ereport(ERROR,
929+
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
930+
errmsg("permission denied for sequence %s",
931+
RelationGetRelationName(seqrel))));
932+
933+
pgstuple=SearchSysCache1(SEQRELID,ObjectIdGetDatum(relid));
934+
if (!HeapTupleIsValid(pgstuple))
935+
elog(ERROR,"cache lookup failed for sequence %u",relid);
936+
pgsform= (Form_pg_sequence)GETSTRUCT(pgstuple);
937+
maxv=pgsform->seqmax;
938+
minv=pgsform->seqmin;
939+
incby=pgsform->seqincrement;
940+
cache=pgsform->seqcache;
941+
ReleaseSysCache(pgstuple);
942+
943+
/* cached number is greater than received */
944+
if (elm->last!=cache&&elm->last+incby>next)
945+
{
946+
relation_close(seqrel,NoLock);
947+
return;
948+
}
949+
950+
/* read-only transactions may only modify temp sequences */
951+
if (!seqrel->rd_islocaltemp)
952+
PreventCommandIfReadOnly("setval()");
953+
954+
/*
955+
* Forbid this during parallel operation because, to make it work, the
956+
* cooperating backends would need to share the backend-local cached
957+
* sequence information. Currently, we don't support that.
958+
*/
959+
PreventCommandIfParallelMode("setval()");
960+
961+
/* lock page' buffer and read tuple */
962+
seq=read_seq_tuple(seqrel,&buf,&seqdatatuple);
963+
964+
if ((next<minv)|| (next>maxv))
965+
{
966+
charbufv[100],
967+
bufm[100],
968+
bufx[100];
969+
970+
snprintf(bufv,sizeof(bufv),INT64_FORMAT,next);
971+
snprintf(bufm,sizeof(bufm),INT64_FORMAT,minv);
972+
snprintf(bufx,sizeof(bufx),INT64_FORMAT,maxv);
973+
ereport(ERROR,
974+
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
975+
errmsg("setval: value %s is out of bounds for sequence \"%s\" (%s..%s)",
976+
bufv,RelationGetRelationName(seqrel),
977+
bufm,bufx)));
978+
}
979+
980+
last=seq->last_value;
981+
if (seq->is_called)
982+
{
983+
last+=incby;
984+
}
985+
if (last <=next)
986+
{
987+
next=last+incby*((next-last+incby)/incby);
988+
989+
/* Set the currval() state only if iscalled = true */
990+
if (seq->is_called)
991+
{
992+
elm->last=next;/* last returned number */
993+
elm->last_valid= true;
994+
}
995+
996+
/* In any case, forget any future cached numbers */
997+
elm->cached=elm->last;
998+
999+
/* check the comment above nextval_internal()'s equivalent call. */
1000+
if (RelationNeedsWAL(seqrel))
1001+
GetTopTransactionId();
1002+
1003+
START_CRIT_SECTION();
1004+
1005+
seq->last_value=next;/* last fetched number */
1006+
seq->log_cnt=0;
1007+
1008+
MarkBufferDirty(buf);
1009+
1010+
/* XLOG stuff */
1011+
if (RelationNeedsWAL(seqrel))
1012+
{
1013+
xl_seq_recxlrec;
1014+
XLogRecPtrrecptr;
1015+
Pagepage=BufferGetPage(buf);
1016+
1017+
XLogBeginInsert();
1018+
XLogRegisterBuffer(0,buf,REGBUF_WILL_INIT);
1019+
1020+
xlrec.node=seqrel->rd_node;
1021+
XLogRegisterData((char*)&xlrec,sizeof(xl_seq_rec));
1022+
XLogRegisterData((char*)seqdatatuple.t_data,seqdatatuple.t_len);
1023+
1024+
recptr=XLogInsert(RM_SEQ_ID,XLOG_SEQ_LOG);
1025+
1026+
PageSetLSN(page,recptr);
1027+
}
1028+
1029+
END_CRIT_SECTION();
1030+
}
1031+
1032+
UnlockReleaseBuffer(buf);
1033+
1034+
relation_close(seqrel,NoLock);
1035+
}
1036+
8951037
/*
8961038
* Main internal procedure that handles 2 & 3 arg forms of SETVAL.
8971039
*

‎src/include/commands/sequence.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,9 @@ extern void seq_desc(StringInfo buf, XLogReaderState *rptr);
6666
externconstchar*seq_identify(uint8info);
6767
externvoidseq_mask(char*pagedata,BlockNumberblkno);
6868

69+
typedefvoid (*seq_nextval_hook_t)(Oidseq_relid,int64next);
70+
externseq_nextval_hook_tSeqNextvalHook;
71+
72+
externvoidAdjustSequence(Oidrelid,int64next);
73+
6974
#endif/* SEQUENCE_H */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp