mirror of
https://github.com/postgres/postgres.git
synced 2025-07-26 01:22:12 +03:00
Re-implement the ereport() macro using __VA_ARGS__.
Now that we require C99, we can depend on __VA_ARGS__ to work, and revising ereport() to use it has several significant benefits: * The extra parentheses around the auxiliary function calls are now optional. Aside from being a bit less ugly, this removes a common gotcha for new contributors, because in some cases the compiler errors you got from forgetting them were unintelligible. * The auxiliary function calls are now evaluated as a comma expression list rather than as extra arguments to errfinish(). This means that compilers can be expected to warn about no-op expressions in the list, allowing detection of several other common mistakes such as forgetting to add errmsg(...) when converting an elog() call to ereport(). * Unlike the situation with extra function arguments, comma expressions are guaranteed to be evaluated left-to-right, so this removes platform dependency in the order of the auxiliary function calls. While that dependency hasn't caused us big problems in the past, this change does allow dropping some rather shaky assumptions around errcontext() domain handling. There's no intention to make wholesale changes of existing ereport calls, but as proof-of-concept this patch removes the extra parens from a couple of calls in postgres.c. While new code can be written either way, code intended to be back-patched will need to use extra parens for awhile yet. It seems worth back-patching this change into v12, so as to reduce the window where we have to be careful about that by one year. Hence, this patch is careful to preserve ABI compatibility; a followup HEAD-only patch will make some additional simplifications. Andres Freund and Tom Lane Discussion: https://postgr.es/m/CA+fd4k6N8EjNvZpM8nme+y+05mz-SM8Z_BgkixzkA34R+ej0Kw@mail.gmail.com
This commit is contained in:
@ -91,9 +91,9 @@
|
||||
/*----------
|
||||
* New-style error reporting API: to be used in this way:
|
||||
* ereport(ERROR,
|
||||
* (errcode(ERRCODE_UNDEFINED_CURSOR),
|
||||
* errmsg("portal \"%s\" not found", stmt->portalname),
|
||||
* ... other errxxx() fields as needed ...));
|
||||
* errcode(ERRCODE_UNDEFINED_CURSOR),
|
||||
* errmsg("portal \"%s\" not found", stmt->portalname),
|
||||
* ... other errxxx() fields as needed ...);
|
||||
*
|
||||
* The error level is required, and so is a primary error message (errmsg
|
||||
* or errmsg_internal). All else is optional. errcode() defaults to
|
||||
@ -101,6 +101,9 @@
|
||||
* if elevel is WARNING, or ERRCODE_SUCCESSFUL_COMPLETION if elevel is
|
||||
* NOTICE or below.
|
||||
*
|
||||
* Before Postgres v12, extra parentheses were required around the
|
||||
* list of auxiliary function calls; that's now optional.
|
||||
*
|
||||
* ereport_domain() allows a message domain to be specified, for modules that
|
||||
* wish to use a different message catalog from the backend's. To avoid having
|
||||
* one copy of the default text domain per .o file, we define it as NULL here
|
||||
@ -118,28 +121,28 @@
|
||||
*----------
|
||||
*/
|
||||
#ifdef HAVE__BUILTIN_CONSTANT_P
|
||||
#define ereport_domain(elevel, domain, rest) \
|
||||
#define ereport_domain(elevel, domain, ...) \
|
||||
do { \
|
||||
pg_prevent_errno_in_scope(); \
|
||||
if (errstart(elevel, __FILE__, __LINE__, PG_FUNCNAME_MACRO, domain)) \
|
||||
errfinish rest; \
|
||||
__VA_ARGS__, errfinish(0); \
|
||||
if (__builtin_constant_p(elevel) && (elevel) >= ERROR) \
|
||||
pg_unreachable(); \
|
||||
} while(0)
|
||||
#else /* !HAVE__BUILTIN_CONSTANT_P */
|
||||
#define ereport_domain(elevel, domain, rest) \
|
||||
#define ereport_domain(elevel, domain, ...) \
|
||||
do { \
|
||||
const int elevel_ = (elevel); \
|
||||
pg_prevent_errno_in_scope(); \
|
||||
if (errstart(elevel_, __FILE__, __LINE__, PG_FUNCNAME_MACRO, domain)) \
|
||||
errfinish rest; \
|
||||
__VA_ARGS__, errfinish(0); \
|
||||
if (elevel_ >= ERROR) \
|
||||
pg_unreachable(); \
|
||||
} while(0)
|
||||
#endif /* HAVE__BUILTIN_CONSTANT_P */
|
||||
|
||||
#define ereport(elevel, rest) \
|
||||
ereport_domain(elevel, TEXTDOMAIN, rest)
|
||||
#define ereport(elevel, ...) \
|
||||
ereport_domain(elevel, TEXTDOMAIN, __VA_ARGS__)
|
||||
|
||||
#define TEXTDOMAIN NULL
|
||||
|
||||
|
Reference in New Issue
Block a user