Re: Unexpected behaviour of a RAISE statement in an IMMUTABLE function

From: Joel Mukuthu <jom(at)upright(dot)co>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: pgsql-bugs(at)lists(dot)postgresql(dot)org
Subject: Re: Unexpected behaviour of a RAISE statement in an IMMUTABLE function
Date: 2022-11-25 09:56:20
Message-ID: CAAT35tEOAiNtvhoXwM-rp=AMi11vkL11uWKMA-VvDx4MYahorg@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

Thank you for the responses.

This explains the issue quite clearly to me, but I'm still a bit in the
dark as to what scenarios I should have in mind when I think of statement
side-effects in postgres. Does "side-effects" mean that a statement writes
to tables or files? Or what other scenarios should I have in mind? I'm wary
of making a similar mistake in future.

In this regard, would it make sense to try and warn users of some possible
mistakes in function definitions? I'm aware of discussions such as
https://postgrespro.com/list/thread-id/1752462 and I'm not proposing that,
but perhaps issuing a warning at compile time if there's an INSERT or RAISE
in a non-volatile function. Or would adding some more examples to the docs (
https://www.postgresql.org/docs/current/xfunc-volatility.html) suffice?

Best regards,
Joel Mukuthu

On Wed, Nov 23, 2022 at 5:20 PM Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> wrote:

> Joel Mukuthu <jom(at)upright(dot)co> writes:
> > CREATE FUNCTION raise_exception_immutable(IN err_message text)
> > RETURNS void
> > LANGUAGE 'plpgsql'
> > IMMUTABLE
> > AS $BODY$
> > BEGIN
> > RAISE EXCEPTION
> > USING MESSAGE = err_message;
> > END;
> > $BODY$;
>
> A function with side-effects (like raising an error) isn't
> really immutable [1]. We do fudge that a bit, since hardly
> anything could be marked immutable if there were a strict
> rule about it --- but when the primary point of the function
> is to cause that side-effect, you can't fudge it.
>
> > 4. This raises an exception that was surprising to me:
>
> > SELECT raise_exception_immutable('foo') WHERE false;
> > -- ERROR: foo
> > -- CONTEXT: PL/pgSQL function raise_exception_immutable(text) line 3 at
> > RAISE
>
> The allegedly-immutable function is evaluated during constant folding.
>
> > 5. This does not raises an exception, that was also surprising to me:
>
> > SELECT raise_exception_immutable(format('foo')) WHERE false;
>
> format() isn't immutable, only stable; so constant-folding can't
> reach the error.
>
> regards, tom lane
>
> [1] https://www.postgresql.org/docs/current/xfunc-volatility.html
>

--
Joel Mukuthu
Upright Solutions
jom(at)upright(dot)co

In response to

Browse pgsql-bugs by date

  From Date Subject
Next Message bowenshi 2022-11-25 09:56:37 Re: BUG #17695: Failed Assert in logical replication snapbuild.
Previous Message Hayato Kuroda (Fujitsu) 2022-11-25 09:07:56 RE: BUG #17695: Failed Assert in logical replication snapbuild.