Re: PL/pgSQL trigger and sequence increment

From: jonesd(at)xmission(dot)com
To: tgl(at)sss(dot)pgh(dot)pa(dot)us
Cc: pgsql-general(at)postgresql(dot)org
Subject: Re: PL/pgSQL trigger and sequence increment
Date: 2011-09-07 16:19:04
Message-ID: 20110907101904.6rkh02il0ckcog8c@webmail.xmission.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-general

> Seems like you would be a lot better off enforcing this with a unique
> index on (submitter_id, date_trunc('month',entry_timestamp)). The above
> not only doesn't provide any feedback, it's got serious race-condition
> problems.

I'll take a look at using an index to do this. The trigger is an ugly
solution.

> > Each row in the table also has a SERIAL identifier with a sequence
> > providing values. I'd like to provide information to the user
> > regarding why the INSERT or UPDATE failed, as the examples in the
> > documentation do via using a RAISE EXCEPTION instead of RETURN
> NULL > (see >
> http://www.postgresql.org/docs/8.3/interactive/plpgsql-trigger.html,
> > which appears to be unchanged in the documentation for 9.0). >
> However, if I do so, the sequence increments after the attempted >
> INSERT or UPDATE, which is not desired (and does not happen if >
> RETURN NULL is the result of the trigger function).

> Really? Frankly, I don't believe it. Any default value will get filled
> in long before triggers run. In any case, you'd still have issues from
> errors occurring later in the transaction. In general, you *can not*
> expect to not have "holes" in the serial number assignment when using a
> sequence object. You'll save yourself a lot of grief if you just accept
> that fact, rather than imagining (falsely) that you've found a
> workaround to avoid it.

I double-checked it and got the same behavior each time I did it.
Poking around in the documentation makes me think that the key is when
the trigger fires. The trigger in question is a BEFORE trigger, so
according to the docs if it returns NULL the INSERT never happens.
Thus, the sequence wouldn't increment - makes sense to me. It appears
that, if you get an exception instead, the sequence does increment,
which is the part that doesn't make sense.

> If you really must have gap-free serial numbers, it's possible, but it's
> slow, expensive, and doesn't rely on sequence objects. You can find the
> details in the list archives, but basically each insert has to lock the
> table against other inserts and then examine it to find the max current
> id.

Been there, done that, implemented a solution (which doesn't use
sequences). I'm not using that solution here - just don't see why a
BEFORE trigger should be incrementing a sequence.

Dominic Jones, Ph.D.

Browse pgsql-general by date

  From Date Subject
Next Message Radosław Smogura 2011-09-07 16:32:08 Re: SSL certificates issue
Previous Message Andrew Sullivan 2011-09-07 15:50:08 Re: conditional insert