Re: Missing errcode() in ereport

Поиск
Список
Период
Сортировка
От Tom Lane
Тема Re: Missing errcode() in ereport
Дата
Msg-id 18567.1584666197@sss.pgh.pa.us
обсуждение исходный текст
Ответ на Re: Missing errcode() in ereport  (Tom Lane <tgl@sss.pgh.pa.us>)
Ответы Re: Missing errcode() in ereport  (Andres Freund <andres@anarazel.de>)
Список pgsql-hackers
I wrote:
> I think that at least some compilers will complain about side-effect-free
> subexpressions of a comma expression.  Could we restructure things so
> that the errcode/errmsg/etc calls form a standalone comma expression
> rather than appearing to be arguments of a varargs function?

Yeah, the attached quick-hack patch seems to work really well for this.
I find that this now works:

    ereport(ERROR,
            errcode(ERRCODE_DIVISION_BY_ZERO),
            errmsg("foo"));

where before it gave the weird error you quoted.  Also, these both
draw warnings about side-effect-free expressions:

    ereport(ERROR,
            ERRCODE_DIVISION_BY_ZERO,
            errmsg("foo"));

    ereport(ERROR,
            "%d", 42);

With gcc you just need -Wall to get such warnings, and clang
seems to give them by default.

As a nice side benefit, the backend gets a couple KB smaller from
removal of errfinish's useless dummy argument.

I think that we could now also change all the helper functions
(errmsg et al) to return void instead of a dummy value, but that
would make the patch a lot longer and probably not move the
goalposts much in terms of error detection.

It also looks like we could use the same trick to get plain elog()
to have the behavior of not evaluating its arguments when it's
not going to print anything.  I've not poked at that yet either.

            regards, tom lane

diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c
index 62eef7b..a29ccd9 100644
--- a/src/backend/utils/error/elog.c
+++ b/src/backend/utils/error/elog.c
@@ -438,7 +438,7 @@ matches_backtrace_functions(const char *funcname)
  * See elog.h for the error level definitions.
  */
 void
-errfinish(int dummy,...)
+errfinish(void)
 {
     ErrorData  *edata = &errordata[errordata_stack_depth];
     int            elevel;
@@ -1463,7 +1463,7 @@ elog_finish(int elevel, const char *fmt,...)
     /*
      * And let errfinish() finish up.
      */
-    errfinish(0);
+    errfinish();
 }
 
 
@@ -1749,7 +1749,7 @@ ThrowErrorData(ErrorData *edata)
     recursion_depth--;
 
     /* Process the error. */
-    errfinish(0);
+    errfinish();
 }
 
 /*
@@ -1863,7 +1863,7 @@ pg_re_throw(void)
          */
         error_context_stack = NULL;
 
-        errfinish(0);
+        errfinish();
     }
 
     /* Doesn't return ... */
diff --git a/src/include/utils/elog.h b/src/include/utils/elog.h
index 0a4ef02..e6fa85f 100644
--- a/src/include/utils/elog.h
+++ b/src/include/utils/elog.h
@@ -118,34 +118,34 @@
  *----------
  */
 #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(); \
         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(); \
         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
 
 extern bool errstart(int elevel, const char *filename, int lineno,
                      const char *funcname, const char *domain);
-extern void errfinish(int dummy,...);
+extern void errfinish(void);
 
 extern int    errcode(int sqlerrcode);


В списке pgsql-hackers по дате отправления:

Предыдущее
От: Peter Geoghegan
Дата:
Сообщение: Re: nbtree: assertion failure in _bt_killitems() for posting tuple
Следующее
От: Justin Pryzby
Дата:
Сообщение: Re: improve transparency of bitmap-only heap scans