diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c index 0d92dcd036..7e82ea34f2 100644 --- a/src/backend/utils/error/elog.c +++ b/src/backend/utils/error/elog.c @@ -378,6 +378,8 @@ errstart(int elevel, const char *filename, int lineno, edata->funcname = funcname; /* the default text domain is the backend's */ edata->domain = domain ? domain : PG_TEXTDOMAIN("postgres"); + /* initialize context_domain the same way (see set_errcontext_domain()) */ + edata->context_domain = edata->domain; /* Select default errcode based on elevel */ if (elevel >= ERROR) edata->sqlerrcode = ERRCODE_INTERNAL_ERROR; @@ -728,7 +730,7 @@ errcode_for_socket_access(void) char *fmtbuf; \ StringInfoData buf; \ /* Internationalize the error format string */ \ - if (translateit && !in_error_recursion_trouble()) \ + if ((translateit) && !in_error_recursion_trouble()) \ fmt = dgettext((domain), fmt); \ /* Expand %m in format string */ \ fmtbuf = expand_fmt_string(fmt, edata); \ @@ -1048,6 +1050,16 @@ errcontext_msg(const char *fmt,...) * translate it. Instead, each errcontext_msg() call should be preceded by * a set_errcontext_domain() call to specify the domain. This is usually * done transparently by the errcontext() macro. + * + * Although errcontext is primarily meant for use at call sites distant from + * the original ereport call, there are a few places that invoke errcontext + * within ereport. The expansion of errcontext as a comma expression calling + * set_errcontext_domain then errcontext_msg is problematic in this case, + * because the intended comma expression becomes two arguments to errfinish, + * which the compiler is at liberty to evaluate in either order. But in + * such a case, the set_errcontext_domain calls must be selecting the same + * TEXTDOMAIN value that the errstart call did, so order does not matter + * so long as errstart initializes context_domain along with domain. */ int set_errcontext_domain(const char *domain) @@ -1057,7 +1069,8 @@ set_errcontext_domain(const char *domain) /* we don't bother incrementing recursion_depth */ CHECK_STACK_DEPTH(); - edata->context_domain = domain; + /* the default text domain is the backend's */ + edata->context_domain = domain ? domain : PG_TEXTDOMAIN("postgres"); return 0; /* return value does not matter */ }