From: | Robert Haas <robertmhaas(at)gmail(dot)com> |
---|---|
To: | "pgsql-hackers(at)postgresql(dot)org" <pgsql-hackers(at)postgresql(dot)org> |
Subject: | pg_croak, or something like it? |
Date: | 2020-01-27 14:29:01 |
Message-ID: | CA+TgmoYt6xNLmxDsing7Fa4DaUyUD0O3+ZorC-hYVrtBcA=GVA@mail.gmail.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-hackers |
Hi,
Recent developments on the "backup manifest" thread and others have
caused me to take an interest in making more code that has
historically been backend-only accessible in frontend environments
also. I'm pretty sure I'm not alone in having often wished for more
backend-only facilities to be available in front-end code, because
many of them are very convenient, but up until now I haven't been
motivated enough to do much about it.
Probably the thorniest problem is the backend's widespread dependence
on ereport() and elog(). Now, it would not be enormously difficult to
code up something that will sigsetjmp() and siglongjmp() in front-end
code just as we do in backend code, but I think it would be largely
missing the point. Just jumping out of a function some place and back
to the top level is not very safe, because you will tend to leak
resources and leave data structures in broken states. In the backend,
we've made this safe via transaction cleanup, which arranges to
release resources, including memory, at the proper times. Getting this
to work everywhere and for all the kinds of resources that matter has
been a pretty significant undertaking; while frontend environments
tend to be simpler, I think it's likely to take a good deal of work
and thought to figure it all out. There's another problem, too: when
ereport() is used in the backend, it reports not only an error message
but a bunch of other things like an error code, an optional error
detail, and an error context. It might be good to introduce some of
these concepts on the frontend side, but it will be confusing if
frontend errors start getting reported just like backend errors, so
here again I feel we need to think carefully.
That being said, not all uses of ereport() and elog() are created
equal. Sometimes, they are just used to report warnings, which
typically don't contain much more than a primary message, and
sometimes they are used to report can't-happen conditions, which ERROR
in backend code and could probably just print a message and exit() in
frontend code. Providing a general way to do this kind of thing seems
a lot easier than solving the whole problem, and it would allow us to
avoid continuing to copy stuff like this:
#ifndef FRONTEND
#define pg_log_warning(...) elog(WARNING, __VA_ARGS__)
#else
#include "common/logging.h"
#endif
We have two copies of that already, and I don't think we should
continue to add more. So, what I'd like to propose is a pair of
macros, one of which arranges for a warning of an appropriate sort for
either a backend or frontend environment, and the other of which is
used for a can't happen condition that should either ERROR or just
exit. Taking a page from my Perl programming background, I propose to
call these pg_carp() and pg_croak(), although I'm not in love with
those names so let the bikeshedding commence. Something like:
#ifdef FRONTEND
#define pg_croak(...) do { pg_log_fatal(__VA_ARGS__); exit(1) } while (0)
#define pg_carp(...) pg_log_warning(__VA_ARGS__);
#else
#define pg_croak(...) elog(ERROR, __VA_ARGS__)
#define pg_carp(...) elog(WARNING, __VA_ARGS__)
#endif
It is of course somewhat questionable to consider a "croak" as
effectively *fatal* on the frontend side but only ERROR rather than
FATAL on the backend side, but for the kinds of things I'm looking at
it seems like the most useful definition. If the JSON parser goes
horribly wrong to due to some logic bug, it is neither useful nor
friendly to terminate the session, but a frontend tool is probably
fine for it to just exit. The user perception will be, in each case,
that the last command they attempted (either from the command-line or
from psql, as the case may be) failed but that they are free to enter
more commands without needing to start a new session (either of psql
or bash or whatever).
Thoughts?
--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company
From | Date | Subject | |
---|---|---|---|
Next Message | Tom Lane | 2020-01-27 15:08:37 | Re: pg_croak, or something like it? |
Previous Message | Kohei KaiGai | 2020-01-27 14:08:36 | Re: TRUNCATE on foreign tables |