From 5231e698e4674085667fa1e729d75580c54d1595 Mon Sep 17 00:00:00 2001
From: Andres Freund <andres@anarazel.de>
Date: Thu, 19 Mar 2020 18:57:23 -0700
Subject: [PATCH v2 3/3] WIP: elog: Move file / line / function domain setup to
 errfinish().

TODO: Need to verify domain handling is equivalent to
before (especially vs set_errcontext_domain() etc).

Author: Andres Freund
Discussion: https://postgr.es/m/5995.1584660775@sss.pgh.pa.us
---
 src/include/utils/elog.h       | 14 ++++----
 src/backend/utils/error/elog.c | 59 ++++++++++++++++++----------------
 2 files changed, 39 insertions(+), 34 deletions(-)

diff --git a/src/include/utils/elog.h b/src/include/utils/elog.h
index 8404760ae39..7d728043747 100644
--- a/src/include/utils/elog.h
+++ b/src/include/utils/elog.h
@@ -121,10 +121,10 @@
 #define ereport_domain(elevel, domain, ...)	\
 	do { \
 		pg_prevent_errno_in_scope(); \
-		if (errstart(elevel, __FILE__, __LINE__, PG_FUNCNAME_MACRO, domain)) \
+		if (errstart(elevel)) \
 		{ \
 			__VA_ARGS__; \
-			errfinish(); \
+			errfinish(__FILE__, __LINE__, PG_FUNCNAME_MACRO, domain); \
 		} \
 		if (__builtin_constant_p(elevel) && (elevel) >= ERROR) \
 			pg_unreachable(); \
@@ -134,10 +134,10 @@
 	do { \
 		const int elevel_ = (elevel); \
 		pg_prevent_errno_in_scope(); \
-		if (errstart(elevel_, __FILE__, __LINE__, PG_FUNCNAME_MACRO, domain)) \
+		if (errstart(elevel_) \
 		{ \
 			__VA_ARGS__; \
-			errfinish(); \
+			errfinish(__FILE__, __LINE__, PG_FUNCNAME_MACRO, domain)); \
 		} \
 		if (elevel_ >= ERROR) \
 			pg_unreachable(); \
@@ -149,9 +149,9 @@
 
 #define TEXTDOMAIN NULL
 
-extern bool errstart(int elevel, const char *filename, int lineno,
-					 const char *funcname, const char *domain);
-extern void errfinish(void);
+extern bool errstart(int elevel);
+extern void errfinish(const char *filename, int lineno,
+					  const char *funcname, const char *domain);
 
 extern void errcode(int sqlerrcode);
 
diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c
index 141eddeeeba..c5392b41726 100644
--- a/src/backend/utils/error/elog.c
+++ b/src/backend/utils/error/elog.c
@@ -223,17 +223,15 @@ err_gettext(const char *str)
 /*
  * errstart --- begin an error-reporting cycle
  *
- * Create a stack entry and store the given parameters in it.  Subsequently,
- * errmsg() and perhaps other routines will be called to further populate
- * the stack entry.  Finally, errfinish() will be called to actually process
- * the error report.
+ * Create and initialize error stack entry.  Subsequently, errmsg() and
+ * perhaps other routines will be called to further populate the stack entry.
+ * Finally, errfinish() will be called to actually process the error report.
  *
  * Returns true in normal case.  Returns false to short-circuit the error
  * report (if it's a warning or lower and not to be reported anywhere).
  */
 bool
-errstart(int elevel, const char *filename, int lineno,
-		 const char *funcname, const char *domain)
+errstart(int elevel)
 {
 	ErrorData  *edata;
 	bool		output_to_server;
@@ -321,8 +319,7 @@ errstart(int elevel, const char *filename, int lineno,
 	if (ErrorContext == NULL)
 	{
 		/* Oops, hard crash time; very little we can do safely here */
-		write_stderr("error occurred at %s:%d before error message processing is available\n",
-					 filename ? filename : "(unknown file)", lineno);
+		write_stderr("error occurred before error message processing is available\n");
 		exit(2);
 	}
 
@@ -368,20 +365,9 @@ errstart(int elevel, const char *filename, int lineno,
 	edata->elevel = elevel;
 	edata->output_to_server = output_to_server;
 	edata->output_to_client = output_to_client;
-	if (filename)
-	{
-		const char *slash;
 
-		/* keep only base name, useful especially for vpath builds */
-		slash = strrchr(filename, '/');
-		if (slash)
-			filename = slash + 1;
-	}
-	edata->filename = filename;
-	edata->lineno = lineno;
-	edata->funcname = funcname;
 	/* the default text domain is the backend's */
-	edata->domain = domain ? domain : PG_TEXTDOMAIN("postgres");
+	edata->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 */
@@ -434,11 +420,12 @@ matches_backtrace_functions(const char *funcname)
  *
  * Produce the appropriate error report(s) and pop the error stack.
  *
- * If elevel is ERROR or worse, control does not return to the caller.
- * See elog.h for the error level definitions.
+ * If elevel, as passed to errstart(), is ERROR or worse, control does not
+ * return to the caller.  See elog.h for the error level definitions.
  */
 void
-errfinish(void)
+errfinish(const char *filename, int lineno, const char *funcname,
+		  const char *domain)
 {
 	ErrorData  *edata = &errordata[errordata_stack_depth];
 	int			elevel;
@@ -449,6 +436,23 @@ errfinish(void)
 	CHECK_STACK_DEPTH();
 	elevel = edata->elevel;
 
+	if (filename)
+	{
+		const char *slash;
+
+		/* keep only base name, useful especially for vpath builds */
+		slash = strrchr(filename, '/');
+		if (slash)
+			filename = slash + 1;
+	}
+
+	edata->filename = filename;
+	edata->lineno = lineno;
+	edata->funcname = funcname;
+
+	if (domain)
+		edata->domain = domain;
+
 	/*
 	 * Do processing in ErrorContext, which we hope has enough reserved space
 	 * to report an error.
@@ -1569,8 +1573,7 @@ ThrowErrorData(ErrorData *edata)
 	ErrorData  *newedata;
 	MemoryContext oldcontext;
 
-	if (!errstart(edata->elevel, edata->filename, edata->lineno,
-				  edata->funcname, NULL))
+	if (!errstart(edata->elevel))
 		return;					/* error is not to be reported at all */
 
 	newedata = &errordata[errordata_stack_depth];
@@ -1612,7 +1615,8 @@ ThrowErrorData(ErrorData *edata)
 	recursion_depth--;
 
 	/* Process the error. */
-	errfinish();
+	errfinish(edata->filename, edata->lineno,
+			  edata->funcname, edata->domain);
 }
 
 /*
@@ -1726,7 +1730,8 @@ pg_re_throw(void)
 		 */
 		error_context_stack = NULL;
 
-		errfinish();
+		errfinish(edata->filename, edata->lineno,
+				  edata->funcname, edata->domain);
 	}
 
 	/* Doesn't return ... */
-- 
2.25.0.114.g5b0ca878e0

