From 691d99de386aa1f5a858e04634dbaaba48488ef8 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Sat, 7 May 2016 13:16:50 -0400 Subject: [PATCH] Docs: improve warnings about nextval() not producing gapless sequences. In the documentation for nextval(), point out explicitly that INSERT ... ON CONFLICT will call nextval() if needed for the insertion case, whether or not it ends up following the ON CONFLICT path. This seems to be a matter of some confusion, cf bug #14126, so let's be clear about it. Also mention the issue in the CREATE SEQUENCE reference page, since that is another place where people might expect such things to be covered. Minor wording improvements nearby, as well. Back-patch to 9.5 where ON CONFLICT was introduced. --- doc/src/sgml/func.sgml | 22 ++++++++++++++-------- doc/src/sgml/ref/create_sequence.sgml | 10 ++++++++++ 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index c8dd838d253..3f627dc885f 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -11512,13 +11512,19 @@ nextval('foo'::text) foo is looked up at - To avoid blocking concurrent transactions that obtain numbers from the - same sequence, a nextval operation is never + To avoid blocking 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 might leave unused holes in the sequence - of assigned values. + used and will not be returned again. This is true even if the + surrounding transaction later aborts, or if the calling query ends + up not using the value. For example an INSERT with + an ON CONFLICT clause will compute the to-be-inserted + tuple, including doing any required nextval + calls, before detecting any conflict that would cause it to follow + the ON CONFLICT rule instead. Such cases will leave + unused holes in the sequence of assigned values. + Thus, PostgreSQL sequence objects cannot + be used to obtain gapless sequences. @@ -11547,8 +11553,8 @@ nextval('foo'::text) foo is looked up at Return the value most recently returned by nextval in the current session. This function is identical to currval, except that instead - of taking the sequence name as an argument it fetches the - value of the last sequence used by nextval + of taking the sequence name as an argument it refers to whichever + sequence nextval was most recently applied to in the current session. It is an error to call lastval if nextval has not yet been called in the current session. diff --git a/doc/src/sgml/ref/create_sequence.sgml b/doc/src/sgml/ref/create_sequence.sgml index 9e364ff2409..c9591462eed 100644 --- a/doc/src/sgml/ref/create_sequence.sgml +++ b/doc/src/sgml/ref/create_sequence.sgml @@ -239,6 +239,16 @@ SELECT * FROM name; (-9223372036854775808 to 9223372036854775807). + + Because nextval and setval calls are never + rolled back, sequence objects cannot be used if gapless + assignment of sequence numbers is needed. It is possible to build + gapless assignment by using exclusive locking of a table containing a + counter; but this solution is much more expensive than sequence + objects, especially if many transactions need sequence numbers + concurrently. + + Unexpected results might be obtained if a cache setting greater than one is