diff --git a/doc/src/sgml/ref/create_sequence.sgml b/doc/src/sgml/ref/create_sequence.sgml index 4916b8b649b..718037785c2 100644 --- a/doc/src/sgml/ref/create_sequence.sgml +++ b/doc/src/sgml/ref/create_sequence.sgml @@ -1,5 +1,5 @@ @@ -77,9 +77,9 @@ CREATE SEQUENCE seqname [ INCREMENT maxvalue - Use the optional clause to - determine the maximum + The optional clause + determines the maximum value for the sequence. The defaults are 2147483647 and -1 for ascending and descending sequences, respectively. @@ -120,15 +120,15 @@ CREATE SEQUENCE seqname [ INCREMENT The optional CYCLE keyword may be used to enable the sequence - to continue when the + to wrap around when the maxvalue or minvalue has been reached by an ascending or descending sequence respectively. If the limit is - reached, the next number generated will be whatever the + reached, the next number generated will be the minvalue or - maxvalue is, - as appropriate. + maxvalue, + respectively. @@ -192,7 +192,7 @@ ERROR: DefineSequence: MINVALUE (min - If the minimum and maximum values are inconsistant. + If the minimum and maximum values are inconsistent. @@ -213,24 +213,24 @@ ERROR: DefineSequence: MINVALUE (minseqname. - The generator will be "owned" by the user issuing the command. + The generator will be owned by the user issuing the command. After a sequence is created, you may use the function - nextval(seqname) + nextval('seqname') to get a new number from the sequence. The function currval('seqname') may be used to determine the number returned by the last call to - nextval(seqname) + nextval('seqname') for the specified sequence in the current session. The function setval('seqname', newvalue) may be used to set the current value of the specified sequence. The next call to - nextval(seqname) + nextval('seqname') will return the given value plus the sequence increment. @@ -241,7 +241,7 @@ ERROR: DefineSequence: MINVALUE (minseqname; - to get the parameters of a sequence. + to examine the parameters of a sequence. As an alternative to fetching the parameters from the original definition as above, you can use @@ -254,8 +254,13 @@ SELECT last_value FROM seqname; - Low-level locking is used to enable multiple simultaneous - calls to a generator. + To avoid blocking of concurrent transactions + that obtain numbers from the same sequence, a nextval operation + is never rolled back; that is, once a value has been fetched it is + considered used, even if the transaction that did the nextval later + aborts. This means that aborted transactions may leave unused "holes" + in the sequence of assigned values. setval operations are never + rolled back, either. @@ -279,6 +284,9 @@ SELECT last_value FROM seqname; are all distinct, not that they are generated purely sequentially. Also, last_value will reflect the latest value reserved by any backend, whether or not it has yet been returned by nextval. + Another consideration is that a setval executed on such a sequence + will not be noticed by other backends until they have used up any + preallocated values they have cached. @@ -293,7 +301,7 @@ SELECT last_value FROM seqname; Use DROP SEQUENCE to remove a sequence. - Each backend uses its own cache to store allocated numbers. + Each backend uses its own cache to store preallocated numbers. Numbers that are cached but not used in the current session will be lost, resulting in "holes" in the sequence. diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c index ca73318dc54..bb9659f359c 100644 --- a/src/backend/commands/sequence.c +++ b/src/backend/commands/sequence.c @@ -257,7 +257,7 @@ nextval(PG_FUNCTION_ARGS) if (rescnt > 0) break; /* stop fetching */ if (seq->is_cycled != 't') - elog(ERROR, "%s.nextval: got MAXVALUE (%d)", + elog(ERROR, "%s.nextval: reached MAXVALUE (%d)", elm->name, maxv); next = minv; } @@ -273,7 +273,7 @@ nextval(PG_FUNCTION_ARGS) if (rescnt > 0) break; /* stop fetching */ if (seq->is_cycled != 't') - elog(ERROR, "%s.nextval: got MINVALUE (%d)", + elog(ERROR, "%s.nextval: reached MINVALUE (%d)", elm->name, minv); next = maxv; } @@ -371,21 +371,13 @@ do_setval(char *seqname, int32 next, bool iscalled) seq = read_info("setval", elm, &buf); /* lock page' buffer and * read tuple */ - if (seq->cache_value != 1) - { - elog(ERROR, "%s.setval: can't set value of sequence %s, cache != 1", - seqname, seqname); - } - if ((next < seq->min_value) || (next > seq->max_value)) - { - elog(ERROR, "%s.setval: value %d is of of bounds (%d,%d)", + elog(ERROR, "%s.setval: value %d is out of bounds (%d,%d)", seqname, next, seq->min_value, seq->max_value); - } /* save info in local cache */ elm->last = next; /* last returned number */ - elm->cached = next; /* last cached number */ + elm->cached = next; /* last cached number (forget cached values) */ /* save info in sequence relation */ START_CRIT_CODE; @@ -540,7 +532,7 @@ init_sequence(char *caller, char *name) /* Else open and check it */ seqrel = heap_openr(name, AccessShareLock); if (seqrel->rd_rel->relkind != RELKIND_SEQUENCE) - elog(ERROR, "%s.%s: %s is not sequence !", name, caller, name); + elog(ERROR, "%s.%s: %s is not a sequence", name, caller, name); if (elm != (SeqTable) NULL) { @@ -704,7 +696,7 @@ get_param(DefElem *def) if (nodeTag(def->arg) == T_Integer) return intVal(def->arg); - elog(ERROR, "DefineSequence: \"%s\" is to be integer", def->defname); + elog(ERROR, "DefineSequence: \"%s\" value must be integer", def->defname); return -1; }