elog/ereport syntax difficulties
От | Tom Lane |
---|---|
Тема | elog/ereport syntax difficulties |
Дата | |
Msg-id | 19836.1051042872@sss.pgh.pa.us обсуждение исходный текст |
Список | pgsql-hackers |
Awhile ago I proposed that we update elog() calls into a syntax like ereport(ERROR, errcode(ERRCODE_INVALID_CURSOR_NAME), errmsg("portal \"%s\" not found", stmt->portalname), ... other errxxx() fields as needed ...); implemented by a macro and some support routines, in the style #define ereport errstart(__FILE__, __LINE__, __func__), errfinish extern void errstart(const char *filename, int lineno, const char *funcname); extern void errfinish(int elevel, ...); While working on implementing this, I realized that it's not really going to fly, because the error level is only available to errfinish(), not to errstart(), errmsg(), etc. This has one little problem and one big problem. The little problem is that errmsg() can't skip formatting of messages that aren't going to get displayed, which will cost us some performance for elog(DEBUG) cases. The big problem is that there's a risk of losing a fatal error. Suppose we haveereport(PANIC, errmsg(....)) and during the processing of errmsg() some ERROR condition comes up (out of memory, say). The ERROR will get processed, then we'll longjmp out to the outer loop, and the PANIC condition never gets reported at all. Now we have a backend that thinks it's functional but has unknown corruption in internal state (whatever the PANIC wanted to whinge about). Very uncool. We can work around these problems if the elevel is known during errstart() --- for example, the error-level-degradation problem can be fixed by looking in the error stack to see if there's a pending FATAL or PANIC condition. But the nice clean macro syntax exhibited above doesn't lend itself to that. I am thinking that there's little choice but to put an extra set of parentheses into the ereport usage syntax. It would look something like ereport(ERROR, (errcode(ERRCODE_INVALID_CURSOR_NAME), errmsg("portal \"%s\" not found", stmt->portalname), ... other errxxx() fields as needed ...)); with an implementation along the lines of #define ereport(elevel,rest) \ (errstart(elevel, __FILE__, __LINE__, __func__) ? errfinish rest : 0) extern bool errstart(int elevel, const char *filename, int lineno, const char *funcname); extern void errfinish(); (The value of having errstart return a bool is that we can completely skip the rest of the work if errstart detects that no message need be displayed. This is actually better than the current elog implementation, wherein any functions used in the arguments to elog must be evaluated even if the message is then discarded.) The extra parens in the ereport call seem pretty ugly though. Can anyone think of a nicer way? regards, tom lane
В списке pgsql-hackers по дате отправления: