Example in plpgsql docs can lead to infinite loop

From: Phil Sorber <phil(at)omniti(dot)com>
To: pgsql-bugs(at)postgresql(dot)org
Subject: Example in plpgsql docs can lead to infinite loop
Date: 2012-01-27 20:56:07
Message-ID: CADAkt-g8FA4kfqMpmWix+6sPQ5vWz2U0CBCUKHfN=wS3o0R3uQ@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

http://www.postgresql.org/docs/devel/static/plpgsql-control-structures.html#PLPGSQL-UPSERT-EXAMPLE

This example can lead to an infinite loop if there is another column
that has a unique key constraint on it in addition to the primary key
and someone tries to execute the function with a unique primary key
but a duplicate value for the column with the unique constraint.

CREATE TABLE db (a INT PRIMARY KEY, b TEXT UNIQUE);

CREATE FUNCTION merge_db(key INT, data TEXT) RETURNS VOID AS
$$
BEGIN
LOOP
-- first try to update the key
UPDATE db SET b = data WHERE a = key;
IF found THEN
RETURN;
END IF;
-- not there, so try to insert the key
-- if someone else inserts the same key concurrently,
-- we could get a unique-key failure
BEGIN
INSERT INTO db(a,b) VALUES (key, data);
RETURN;
EXCEPTION WHEN unique_violation THEN
-- Do nothing, and loop to try the UPDATE again.
END;
END LOOP;
END;
$$
LANGUAGE plpgsql;

SELECT merge_db(1, 'david');
SELECT merge_db(2, 'david');

The update effects no rows because the primary key value doesn't exist
and the insert fails because the unique key constraint fails but the
exception handling ignores the error. It almost seems like there
should be a primary_key_violation exception type to distinguish, but
all I am suggesting right now is that we make a note of that case in
the docs so that fewer people get stung by this. I have attached a
patch with some suggested wording.

Attachment Content-Type Size
plpgsql-docs.patch text/x-patch 1.1 KB

Responses

Browse pgsql-bugs by date

  From Date Subject
Next Message agrimm 2012-01-28 02:15:20 BUG #6412: psql & fe-connect truncate passwords
Previous Message Eric Borts 2012-01-27 20:47:02 Re: Windows x86-64 One-Click Install (9.1.2-1, 9.0.6-1) hangs on "initialising the database cluster" (with work-around)