Re: Error-safe user functions

From: Corey Huinker <corey(dot)huinker(at)gmail(dot)com>
To: Nikita Glukhov <n(dot)gluhov(at)postgrespro(dot)ru>
Cc: PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org>
Subject: Re: Error-safe user functions
Date: 2022-10-10 16:54:28
Message-ID: CADkLM=d+HS6brXHwXDb6SUfdU1oJw28dSzj074QsF2gHr+z5Ww@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

>
>
> The idea is simple -- introduce new "error-safe" calling mode of user
> functions by passing special node through FunctCallInfo.context, in
> which function should write error info and return instead of throwing
> it. Also such functions should manually free resources before
> returning an error. This gives ability to avoid PG_TRY/PG_CATCH and
> subtransactions.
>
> I tried something similar when trying to implement TRY_CAST (
https://learn.microsoft.com/en-us/sql/t-sql/functions/try-cast-transact-sql?view=sql-server-ver16)
late last year. I also considered having a default datum rather than just
returning NULL.

I had not considered a new node type. I had considered having every
function have a "safe" version, which would be a big duplication of logic
requiring a lot of regression tests and possibly fuzzing tests.

Instead, I extended every core input function to have an extra boolean
parameter to indicate if failures were allowed, and then an extra Datum
parameter for the default value. The Input function wouldn't need to check
the value of the new parameters until it was already in a situation where
it found invalid data, but the extra overhead still remained, and it meant
that basically every third party type extension would need to be changed.

Then I considered whether the cast failure should be completely silent, or
if the previous error message should instead be omitted as a LOG/INFO/WARN,
and if we'd want that to be configurable, so then the boolean parameter
became an integer enum:

* regular fail (0)
* use default silently (1)
* use default emit LOG/NOTICE/WARNING (2,3,4)

At the time, all of this seemed like too big of a change for a function
that isn't even in the SQL Standard, but maybe SQL/JSON changes that.

If so, it would allow for a can-cast-to test that users would find very
useful. Something like:

SELECT CASE WHEN 'abc' CAN BE integer THEN 'Integer' ELSE 'Nope' END

There's obviously no standard syntax to support that, but the data
cleansing possibilities would be great.

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Tom Lane 2022-10-10 17:00:08 Re: src/test/perl/PostgreSQL/Test/*.pm not installed
Previous Message Alvaro Herrera 2022-10-10 16:53:58 Re: shadow variables - pg15 edition