Ask a Question related to PostgreSQL / PGSQL, Design and Development.
-
David Kammer #1
serial increments on failed insert
Ive noticed what seems to be an odd effect in psql 7.3. It works like this:
1> Create a table:
CREATE TABLE foo
(
sval serial,
uval int UNIQUE
);
2> Run 3 inserts, the second of which fails because it fails the
unique constraint:
INSERT INTO foo VALUES (DEFAULT,1);
INSERT INTO foo VALUES (DEFAULT,1); <--- This fails
INSERT INTO foo VALUES (DEFAULT,2);
3> look at the table:
SELECT * FROM foo;
sval | uval
------+------
1 | 1
3 | 2 <--- look here
(2 rows)
Notice that even though the second insert failed, it still incremented
the serial value. This seems counter intuative to the way that serial
should work. Is this truly a bug, or is there a good work around?
Thanks,
Dave
---------------------------(end of broadcast)---------------------------
TIP 7: don't forget to increase your free space map settings
David Kammer Guest
-
insert failed
hope you can help solve this problem, ok my database field: tblA TSK_ID (autonumber) key (not Null) USR_ID (autonumber) (not Null) TSKCTDT... -
cmin increments by 2 except in 7.4?
I've noticed that in PostgreSQL 7.4, successive commands in a transaction get cmin values that increment by 1, but in other versions cmin... -
Return value of 'serial' column on insert
Hi all, I have several tables with an 'id' column which is a simple 'serial unique' type. Often when I insert a record the next thing I need is... -
string comparison and increments
on our work registration system we use the first part of the email address (eg. john.smith) as the username for the registrant, the user has no... -
OT: rotate in smaller increments?
Sorry, Sam, this was an old post, but I can't help but wonder...what's the story behind this? "Sam Poikail" <indigo_wolf@hotmail.com> wrote in... -
David Kammer #2
serial increments on failed insert
I've noticed what seems to be an odd effect in psql 7.3. It works like
this:
1> Create a table:
CREATE TABLE foo
(
sval serial,
uval int UNIQUE
);
2> Run 3 inserts, the second of which fails because it fails the
unique constraint:
INSERT INTO foo VALUES (DEFAULT,1);
INSERT INTO foo VALUES (DEFAULT,1); <--- This fails
INSERT INTO foo VALUES (DEFAULT,2);
3> look at the table:
SELECT * FROM foo;
sval | uval
------+------
1 | 1
3 | 2 <--- look here
(2 rows)
Notice that even though the second insert failed, it still incremented
the serial value. This seems counter intuative to the way that serial
should work. Is this truly a bug, or is there a good work around?
Thanks,
Dave
---------------------------(end of broadcast)---------------------------
TIP 8: explain analyze is your friend
David Kammer Guest
-
Tom Lane #3
Re: serial increments on failed insert
David Kammer <djkammer@u.washington.edu> writes:
No. nextval() calls never roll back; see the documentation.> Notice that even though the second insert failed, it still incremented
> the serial value. This seems counter intuative to the way that serial
> should work. Is this truly a bug,
Don't assume that a serial column is without gaps. It's only intended> is there a good work around?
to be unique.
regards, tom lane
---------------------------(end of broadcast)---------------------------
TIP 1: subscribe and unsubscribe commands go to [email]majordomo@postgresql.org[/email]
Tom Lane Guest
-
Steve Atkins #4
Re: serial increments on failed insert
On Fri, Jan 14, 2005 at 04:57:19PM -0800, David Kammer wrote:
That's correct, documented behaviour. A serial column is mostly just a> Notice that even though the second insert failed, it still incremented
> the serial value. This seems counter intuative to the way that serial
> should work. Is this truly a bug, or is there a good work around?
sequence in disguise. A sequence is guaranteed to give unique,
increasing values, but in many cases may miss a value (for several
reasons - in this case because once a sequence value is used, it's
used, even if the transaction it was used in is rolled back).
Do you really need that column to increase one at a time? Or just
to increase and be unique?
You could look at the maximum value in the column and use the maximum
value plus one (and be prepared to retry if there's an index on that
column to guarantee uniqueness).
Cheers,
Steve
---------------------------(end of broadcast)---------------------------
TIP 3: if posting/reading through Usenet, please send an appropriate
subscribe-nomail command to [email]majordomo@postgresql.org[/email] so that your
message can get through to the mailing list cleanly
Steve Atkins Guest
-
Michael Fuhr #5
Re: serial increments on failed insert
On Fri, Jan 14, 2005 at 04:57:19PM -0800, David Kammer wrote:
See the "Sequence Manipulation Functions" section in the "Functions> Notice that even though the second insert failed, it still incremented
> the serial value. This seems counter intuative to the way that serial
> should work. Is this truly a bug, or is there a good work around?
and Operators" chapter of the documentation. The page contains
the following note:
Important: 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.
Sequences are for obtaining numbers guaranteed to be unique; other
assumptions about their behavior are probably unwarranted.
--
Michael Fuhr
[url]http://www.fuhr.org/~mfuhr/[/url]
---------------------------(end of broadcast)---------------------------
TIP 8: explain analyze is your friend
Michael Fuhr Guest
-
Bruno Wolff III #6
Re: serial increments on failed insert
On Fri, Jan 14, 2005 at 17:49:42 -0800,
Steve Atkins <steve@blighty.com> wrote:Note that the increasing part is only guarenteed within a session,>
> That's correct, documented behaviour. A serial column is mostly just a
> sequence in disguise. A sequence is guaranteed to give unique,
> increasing values, but in many cases may miss a value (for several
> reasons - in this case because once a sequence value is used, it's
> used, even if the transaction it was used in is rolled back).
not accross sessions and only if you haven't changed the sequence
to allow it to roll over.
---------------------------(end of broadcast)---------------------------
TIP 5: Have you checked our extensive FAQ?
[url]http://www.postgresql.org/docs/faqs/FAQ.html[/url]
Bruno Wolff III Guest
-
David Fetter #7
Re: serial increments on failed insert
On Fri, Jan 14, 2005 at 04:48:12PM -0800, David Kammer wrote:
Perhaps the docs need revision to clarify this. The SERIAL type is> Ive noticed what seems to be an odd effect in psql 7.3. It works like this:
>
> 1> Create a table:
> CREATE TABLE foo
> (
> sval serial,
> uval int UNIQUE
> );
>
> 2> Run 3 inserts, the second of which fails because it fails the
> unique constraint:
> INSERT INTO foo VALUES (DEFAULT,1);
> INSERT INTO foo VALUES (DEFAULT,1); <--- This fails
> INSERT INTO foo VALUES (DEFAULT,2);
>
> 3> look at the table:
> SELECT * FROM foo;
> sval | uval
> ------+------
> 1 | 1
> 3 | 2 <--- look here
> (2 rows)
>
> Notice that even though the second insert failed, it still
> incremented the serial value. This seems counter intuative to the
> way that serial should work. Is this truly a bug, or is there a
> good work around?
meant to generate id's (in this case, integers) which are guaranteed
to be unique. Because they have this uniqueness property, they are
*not* guaranteed to be gapless.
Cheers,
D
--
David Fetter [email]david@fetter.org[/email] [url]http://fetter.org/[/url]
phone: +1 510 893 6100 mobile: +1 415 235 3778
Remember to vote!
---------------------------(end of broadcast)---------------------------
TIP 5: Have you checked our extensive FAQ?
[url]http://www.postgresql.org/docs/faqs/FAQ.html[/url]
David Fetter Guest
-
rp71 #8
Re: serial increments on failed insert
I had the same problem on one of my tables. What I did was change the column to an integer, create a sequence, create a trigger function, and set a before insert trigger:
<modify the table so the column is an integer>
CREATE SEQUENCE tblloc_rowid;
CREATE OR REPLACE FUNCTION process_tblloc() RETURNS TRIGGER AS $process_tblloc$
BEGIN
IF (TG_OP = 'INSERT') THEN
NEW.rowid = nextval('tblloc_rowid'::regclass);
RETURN NEW;
END IF;
RETURN NULL; -- result is ignored since this is an AFTER trigger
END;
$process_tblloc$ LANGUAGE plpgsql;
CREATE TRIGGER tblloc_insert_rowid BEFORE INSERT ON tblloc FOR EACH ROW EXECUTE PROCEDURE process_tblloc();
This only gets the next sequence when a row is being inserted (it isn't called on a failed insert), keeping the sequence from skipping numbers.
Anyway - works for me, maybe it'll work for you too.
Regards,
Ronrp71 Guest



Reply With Quote

