summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael P2011-03-10 09:19:26 +0000
committerPavan Deolasee2011-05-24 09:42:01 +0000
commitdbd5de39c35a19e086e4680271674dbaa4141b67 (patch)
tree3f51ea818a7a720690cb499c3f2dc4d5dc22b018
parent56648b6ea8d0f36b33336fc6f36a4be9da2f07d2 (diff)
Fix for bug 3202643: Sequence error
For the following sequence: create SEQUENCE seq; select nextval('seq'); select currval('seq'); select nextval('seq'); XC was returning 1 -> 100 -> 100 -> 101 PostgreSQL was returning 1 -> 100 -> 1 -> 100 This is corrected. We also check if nextval has been called once in a session when using currval. This is to correspond with PostgreSQL.
-rw-r--r--src/backend/commands/sequence.c38
-rw-r--r--src/gtm/main/gtm_seq.c26
2 files changed, 29 insertions, 35 deletions
diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c
index a0be960859..5105200417 100644
--- a/src/backend/commands/sequence.c
+++ b/src/backend/commands/sequence.c
@@ -619,7 +619,13 @@ nextval_internal(Oid relid)
/* Update the on-disk data */
seq->last_value = result; /* last fetched number */
seq->is_called = true;
- } else
+
+ /* save info in local cache */
+ elm->last = result; /* last returned number */
+ elm->cached = result; /* last fetched number */
+ elm->last_valid = true;
+ }
+ else
{
#endif
last = next = result = seq->last_value;
@@ -798,21 +804,6 @@ currval_oid(PG_FUNCTION_ARGS)
/* open and AccessShareLock sequence */
init_sequence(relid, &elm, &seqrel);
-#ifdef PGXC
- if (IS_PGXC_COORDINATOR)
- {
- char *seqname = GetGlobalSeqName(seqrel, NULL, NULL);
-
- result = (int64) GetCurrentValGTM(seqname);
- if (result < 0)
- ereport(ERROR,
- (errcode(ERRCODE_CONNECTION_FAILURE),
- errmsg("GTM error, could not obtain sequence value")));
- pfree(seqname);
- }
- else
- {
-#endif
if (pg_class_aclcheck(elm->relid, GetUserId(), ACL_SELECT) != ACLCHECK_OK &&
pg_class_aclcheck(elm->relid, GetUserId(), ACL_USAGE) != ACLCHECK_OK)
@@ -827,12 +818,21 @@ currval_oid(PG_FUNCTION_ARGS)
errmsg("currval of sequence \"%s\" is not yet defined in this session",
RelationGetRelationName(seqrel))));
- result = elm->last;
-
#ifdef PGXC
+ if (IS_PGXC_COORDINATOR)
+ {
+ char *seqname = GetGlobalSeqName(seqrel, NULL, NULL);
+
+ result = (int64) GetCurrentValGTM(seqname);
+ if (result < 0)
+ ereport(ERROR,
+ (errcode(ERRCODE_CONNECTION_FAILURE),
+ errmsg("GTM error, could not obtain sequence value")));
+ pfree(seqname);
}
+#else
+ result = elm->last;
#endif
-
relation_close(seqrel, NoLock);
PG_RETURN_INT64(result);
diff --git a/src/gtm/main/gtm_seq.c b/src/gtm/main/gtm_seq.c
index 570636be58..caccd35a2b 100644
--- a/src/gtm/main/gtm_seq.c
+++ b/src/gtm/main/gtm_seq.c
@@ -660,16 +660,8 @@ GTM_SeqGetCurrent(GTM_SequenceKey seqkey)
GTM_RWLockAcquire(&seqinfo->gs_lock, GTM_LOCKMODE_WRITE);
- /*
- * If this is the first call to the sequence, set the value to the start
- * value and mark the sequence as 'called'
- */
- if (!SEQ_IS_CALLED(seqinfo))
- {
- seqinfo->gs_value = seqinfo->gs_init_value;
- seqinfo->gs_called = true;
- }
- value = seqinfo->gs_value;
+ value = seqinfo->gs_last_value;
+
GTM_RWLockRelease(&seqinfo->gs_lock);
seq_release_seqinfo(seqinfo);
return value;
@@ -693,6 +685,8 @@ GTM_SeqSetVal(GTM_SequenceKey seqkey, GTM_Sequence nextval, bool iscalled)
GTM_RWLockAcquire(&seqinfo->gs_lock, GTM_LOCKMODE_WRITE);
+ seqinfo->gs_last_value = seqinfo->gs_value;
+
if (seqinfo->gs_value != nextval)
seqinfo->gs_value = nextval;
@@ -734,7 +728,7 @@ GTM_SeqGetNext(GTM_SequenceKey seqkey)
*/
if (!SEQ_IS_CALLED(seqinfo))
{
- value = seqinfo->gs_value = seqinfo->gs_init_value;
+ value = seqinfo->gs_last_value = seqinfo->gs_value = seqinfo->gs_init_value;
seqinfo->gs_called = true;
GTM_RWLockRelease(&seqinfo->gs_lock);
seq_release_seqinfo(seqinfo);
@@ -749,9 +743,9 @@ GTM_SeqGetNext(GTM_SequenceKey seqkey)
* InvalidSequenceValue
*/
if (seqinfo->gs_max_value - seqinfo->gs_increment_by >= seqinfo->gs_value)
- value = seqinfo->gs_value = seqinfo->gs_value + seqinfo->gs_increment_by;
+ value = seqinfo->gs_last_value = seqinfo->gs_value = seqinfo->gs_value + seqinfo->gs_increment_by;
else if (SEQ_IS_CYCLE(seqinfo))
- value = seqinfo->gs_value = seqinfo->gs_min_value;
+ value = seqinfo->gs_last_value = seqinfo->gs_value = seqinfo->gs_min_value;
else
{
GTM_RWLockRelease(&seqinfo->gs_lock);
@@ -774,9 +768,9 @@ GTM_SeqGetNext(GTM_SequenceKey seqkey)
* descending sequences. So we don't need special handling below
*/
if (seqinfo->gs_min_value - seqinfo->gs_increment_by <= seqinfo->gs_value)
- value = seqinfo->gs_value = seqinfo->gs_value + seqinfo->gs_increment_by;
+ value = seqinfo->gs_value = seqinfo->gs_last_value = seqinfo->gs_value + seqinfo->gs_increment_by;
else if (SEQ_IS_CYCLE(seqinfo))
- value = seqinfo->gs_value = seqinfo->gs_max_value;
+ value = seqinfo->gs_value = seqinfo->gs_last_value = seqinfo->gs_max_value;
else
{
GTM_RWLockRelease(&seqinfo->gs_lock);
@@ -810,7 +804,7 @@ GTM_SeqReset(GTM_SequenceKey seqkey)
}
GTM_RWLockAcquire(&seqinfo->gs_lock, GTM_LOCKMODE_WRITE);
- seqinfo->gs_value = seqinfo->gs_init_value;
+ seqinfo->gs_value = seqinfo->gs_last_value = seqinfo->gs_init_value;
GTM_RWLockRelease(&seqinfo->gs_lock);
seq_release_seqinfo(seqinfo);