The experiences with elog() and ereport() have shown that having one
function that can return or not depending on some log level parameter
isn't a good idea when you want to communicate well with the compiler.
In pg_upgrade, there is a similar case with the pg_log() function.
Since that isn't a public API, I'm proposing to change it and introduce
a separate function pg_fatal() for those cases where the calls don't
return.

>From 12ae7ed2b4174f694f67f31ac18eb1fe22d30ef9 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pete...@gmx.net>
Date: Wed, 11 Sep 2013 22:43:03 -0400
Subject: [PATCH] pg_upgrade: Split off pg_fatal() from pg_log()

This allows decorating pg_fatal() with noreturn compiler hints, leading
to better diagnostics.
---
 contrib/pg_upgrade/check.c           | 68 ++++++++++++--------------
 contrib/pg_upgrade/controldata.c     | 92 ++++++++++++++++--------------------
 contrib/pg_upgrade/exec.c            | 21 ++++----
 contrib/pg_upgrade/file.c            |  3 +-
 contrib/pg_upgrade/function.c        | 11 ++---
 contrib/pg_upgrade/info.c            |  6 +--
 contrib/pg_upgrade/option.c          | 23 +++++----
 contrib/pg_upgrade/page.c            |  6 +--
 contrib/pg_upgrade/parallel.c        | 12 ++---
 contrib/pg_upgrade/pg_upgrade.c      |  8 ++--
 contrib/pg_upgrade/pg_upgrade.h      |  3 ++
 contrib/pg_upgrade/relfilenode.c     | 11 ++---
 contrib/pg_upgrade/server.c          | 11 ++---
 contrib/pg_upgrade/tablespace.c      |  3 +-
 contrib/pg_upgrade/util.c            | 35 +++++++++++---
 contrib/pg_upgrade/version.c         |  2 +-
 contrib/pg_upgrade/version_old_8_3.c | 23 ++++-----
 17 files changed, 165 insertions(+), 173 deletions(-)

diff --git a/contrib/pg_upgrade/check.c b/contrib/pg_upgrade/check.c
index 0376fcb..1a37b79 100644
--- a/contrib/pg_upgrade/check.c
+++ b/contrib/pg_upgrade/check.c
@@ -158,8 +158,7 @@ static void check_locale_and_encoding(ControlData *oldctrl,
 	 * matching install-user oids.
 	 */
 	if (old_cluster.install_role_oid != new_cluster.install_role_oid)
-		pg_log(PG_FATAL,
-			   "Old and new cluster install users have different values for pg_authid.oid.\n");
+		pg_fatal("Old and new cluster install users have different values for pg_authid.oid.\n");
 
 	/*
 	 * We only allow the install user in the new cluster because other defined
@@ -167,7 +166,7 @@ static void check_locale_and_encoding(ControlData *oldctrl,
 	 * error during pg_dump restore.
 	 */
 	if (new_cluster.role_count != 1)
-		pg_log(PG_FATAL, "Only the install user can be defined in the new cluster.\n");
+		pg_fatal("Only the install user can be defined in the new cluster.\n");
 
 	check_for_prepared_transactions(&new_cluster);
 }
@@ -271,11 +270,11 @@ static void check_locale_and_encoding(ControlData *oldctrl,
 	 */
 
 	if (GET_MAJOR_VERSION(old_cluster.major_version) < 803)
-		pg_log(PG_FATAL, "This utility can only upgrade from PostgreSQL version 8.3 and later.\n");
+		pg_fatal("This utility can only upgrade from PostgreSQL version 8.3 and later.\n");
 
 	/* Only current PG version is supported as a target */
 	if (GET_MAJOR_VERSION(new_cluster.major_version) != GET_MAJOR_VERSION(PG_VERSION_NUM))
-		pg_log(PG_FATAL, "This utility can only upgrade to PostgreSQL version %s.\n",
+		pg_fatal("This utility can only upgrade to PostgreSQL version %s.\n",
 			   PG_MAJORVERSION);
 
 	/*
@@ -284,7 +283,7 @@ static void check_locale_and_encoding(ControlData *oldctrl,
 	 * versions.
 	 */
 	if (old_cluster.major_version > new_cluster.major_version)
-		pg_log(PG_FATAL, "This utility cannot be used to downgrade to older major PostgreSQL versions.\n");
+		pg_fatal("This utility cannot be used to downgrade to older major PostgreSQL versions.\n");
 
 	/* get old and new binary versions */
 	get_bin_version(&old_cluster);
@@ -293,12 +292,10 @@ static void check_locale_and_encoding(ControlData *oldctrl,
 	/* Ensure binaries match the designated data directories */
 	if (GET_MAJOR_VERSION(old_cluster.major_version) !=
 		GET_MAJOR_VERSION(old_cluster.bin_version))
-		pg_log(PG_FATAL,
-			   "Old cluster data and binary directories are from different major versions.\n");
+		pg_fatal("Old cluster data and binary directories are from different major versions.\n");
 	if (GET_MAJOR_VERSION(new_cluster.major_version) !=
 		GET_MAJOR_VERSION(new_cluster.bin_version))
-		pg_log(PG_FATAL,
-			   "New cluster data and binary directories are from different major versions.\n");
+		pg_fatal("New cluster data and binary directories are from different major versions.\n");
 
 	check_ok();
 }
@@ -315,17 +312,17 @@ static void check_locale_and_encoding(ControlData *oldctrl,
 	/* Is it 9.0 but without tablespace directories? */
 	if (GET_MAJOR_VERSION(new_cluster.major_version) == 900 &&
 		new_cluster.controldata.cat_ver < TABLE_SPACE_SUBDIRS_CAT_VER)
-		pg_log(PG_FATAL, "This utility can only upgrade to PostgreSQL version 9.0 after 2010-01-11\n"
+		pg_fatal("This utility can only upgrade to PostgreSQL version 9.0 after 2010-01-11\n"
 			   "because of backend API changes made during development.\n");
 
 	/* We read the real port number for PG >= 9.1 */
 	if (live_check && GET_MAJOR_VERSION(old_cluster.major_version) < 901 &&
 		old_cluster.port == DEF_PGUPORT)
-		pg_log(PG_FATAL, "When checking a pre-PG 9.1 live old server, "
+		pg_fatal("When checking a pre-PG 9.1 live old server, "
 			   "you must specify the old server's port number.\n");
 
 	if (live_check && old_cluster.port == new_cluster.port)
-		pg_log(PG_FATAL, "When checking a live server, "
+		pg_fatal("When checking a live server, "
 			   "the old and new port numbers must be different.\n");
 }
 
@@ -413,16 +410,13 @@ static void check_locale_and_encoding(ControlData *oldctrl,
 	 * UTF-8 vs. UTF8, so at least we display the mismatching values.
 	 */
 	if (pg_strcasecmp(oldctrl->lc_collate, newctrl->lc_collate) != 0)
-		pg_log(PG_FATAL,
-		 "lc_collate cluster values do not match:  old \"%s\", new \"%s\"\n",
+		pg_fatal("lc_collate cluster values do not match:  old \"%s\", new \"%s\"\n",
 			   oldctrl->lc_collate, newctrl->lc_collate);
 	if (pg_strcasecmp(oldctrl->lc_ctype, newctrl->lc_ctype) != 0)
-		pg_log(PG_FATAL,
-		   "lc_ctype cluster values do not match:  old \"%s\", new \"%s\"\n",
+		pg_fatal("lc_ctype cluster values do not match:  old \"%s\", new \"%s\"\n",
 			   oldctrl->lc_ctype, newctrl->lc_ctype);
 	if (pg_strcasecmp(oldctrl->encoding, newctrl->encoding) != 0)
-		pg_log(PG_FATAL,
-		   "encoding cluster values do not match:  old \"%s\", new \"%s\"\n",
+		pg_fatal("encoding cluster values do not match:  old \"%s\", new \"%s\"\n",
 			   oldctrl->encoding, newctrl->encoding);
 }
 
@@ -442,7 +436,7 @@ static void check_locale_and_encoding(ControlData *oldctrl,
 		{
 			/* pg_largeobject and its index should be skipped */
 			if (strcmp(rel_arr->rels[relnum].nspname, "pg_catalog") != 0)
-				pg_log(PG_FATAL, "New cluster database \"%s\" is not empty\n",
+				pg_fatal("New cluster database \"%s\" is not empty\n",
 					   new_cluster.dbarr.dbs[dbnum].db_name);
 		}
 	}
@@ -475,7 +469,7 @@ static void check_locale_and_encoding(ControlData *oldctrl,
 			 SCRIPT_EXT);
 
 	if ((script = fopen_priv(*analyze_script_file_name, "w")) == NULL)
-		pg_log(PG_FATAL, "Could not open file \"%s\": %s\n",
+		pg_fatal("Could not open file \"%s\": %s\n",
 			   *analyze_script_file_name, getErrorText(errno));
 
 #ifndef WIN32
@@ -580,7 +574,7 @@ static void check_locale_and_encoding(ControlData *oldctrl,
 
 #ifndef WIN32
 	if (chmod(*analyze_script_file_name, S_IRWXU) != 0)
-		pg_log(PG_FATAL, "Could not add execute permission to file \"%s\": %s\n",
+		pg_fatal("Could not add execute permission to file \"%s\": %s\n",
 			   *analyze_script_file_name, getErrorText(errno));
 #endif
 
@@ -634,7 +628,7 @@ static void check_locale_and_encoding(ControlData *oldctrl,
 	prep_status("Creating script to delete old cluster");
 
 	if ((script = fopen_priv(*deletion_script_file_name, "w")) == NULL)
-		pg_log(PG_FATAL, "Could not open file \"%s\": %s\n",
+		pg_fatal("Could not open file \"%s\": %s\n",
 			   *deletion_script_file_name, getErrorText(errno));
 
 #ifndef WIN32
@@ -688,7 +682,7 @@ static void check_locale_and_encoding(ControlData *oldctrl,
 
 #ifndef WIN32
 	if (chmod(*deletion_script_file_name, S_IRWXU) != 0)
-		pg_log(PG_FATAL, "Could not add execute permission to file \"%s\": %s\n",
+		pg_fatal("Could not add execute permission to file \"%s\": %s\n",
 			   *deletion_script_file_name, getErrorText(errno));
 #endif
 
@@ -716,7 +710,7 @@ static void check_locale_and_encoding(ControlData *oldctrl,
 							"WHERE rolname = current_user");
 
 	if (PQntuples(res) != 1 || strcmp(PQgetvalue(res, 0, 0), "t") != 0)
-		pg_log(PG_FATAL, "database user \"%s\" is not a superuser\n",
+		pg_fatal("database user \"%s\" is not a superuser\n",
 			   os_info.user);
 
 	cluster->install_role_oid = atooid(PQgetvalue(res, 0, 1));
@@ -728,7 +722,7 @@ static void check_locale_and_encoding(ControlData *oldctrl,
 							"FROM pg_catalog.pg_roles ");
 
 	if (PQntuples(res) != 1)
-		pg_log(PG_FATAL, "could not determine the number of users\n");
+		pg_fatal("could not determine the number of users\n");
 
 	cluster->role_count = atoi(PQgetvalue(res, 0, 0));
 
@@ -759,7 +753,7 @@ static void check_locale_and_encoding(ControlData *oldctrl,
 							"FROM pg_catalog.pg_prepared_xacts");
 
 	if (PQntuples(res) != 0)
-		pg_log(PG_FATAL, "The %s cluster contains prepared transactions\n",
+		pg_fatal("The %s cluster contains prepared transactions\n",
 			   CLUSTER_NAME(cluster));
 
 	PQclear(res);
@@ -824,7 +818,7 @@ static void check_locale_and_encoding(ControlData *oldctrl,
 		{
 			found = true;
 			if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
-				pg_log(PG_FATAL, "Could not open file \"%s\": %s\n",
+				pg_fatal("Could not open file \"%s\": %s\n",
 					   output_path, getErrorText(errno));
 			if (!db_used)
 			{
@@ -847,8 +841,7 @@ static void check_locale_and_encoding(ControlData *oldctrl,
 	if (found)
 	{
 		pg_log(PG_REPORT, "fatal\n");
-		pg_log(PG_FATAL,
-			   "Your installation contains \"contrib/isn\" functions which rely on the\n"
+		pg_fatal("Your installation contains \"contrib/isn\" functions which rely on the\n"
 		  "bigint data type.  Your old and new clusters pass bigint values\n"
 		"differently so this cluster cannot currently be upgraded.  You can\n"
 			   "manually upgrade databases that use \"contrib/isn\" facilities and remove\n"
@@ -929,7 +922,7 @@ static void check_locale_and_encoding(ControlData *oldctrl,
 		{
 			found = true;
 			if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
-				pg_log(PG_FATAL, "Could not open file \"%s\": %s\n",
+				pg_fatal("Could not open file \"%s\": %s\n",
 					   output_path, getErrorText(errno));
 			if (!db_used)
 			{
@@ -953,8 +946,7 @@ static void check_locale_and_encoding(ControlData *oldctrl,
 	if (found)
 	{
 		pg_log(PG_REPORT, "fatal\n");
-		pg_log(PG_FATAL,
-			   "Your installation contains one of the reg* data types in user tables.\n"
+		pg_fatal("Your installation contains one of the reg* data types in user tables.\n"
 		 "These data types reference system OIDs that are not preserved by\n"
 		"pg_upgrade, so this cluster cannot currently be upgraded.  You can\n"
 			   "remove the problem tables and restart the upgrade.  A list of the problem\n"
@@ -979,7 +971,7 @@ static void check_locale_and_encoding(ControlData *oldctrl,
 
 	if ((output = popen(cmd, "r")) == NULL ||
 		fgets(cmd_output, sizeof(cmd_output), output) == NULL)
-		pg_log(PG_FATAL, "Could not get pg_ctl version data using %s: %s\n",
+		pg_fatal("Could not get pg_ctl version data using %s: %s\n",
 			   cmd, getErrorText(errno));
 
 	pclose(output);
@@ -989,7 +981,7 @@ static void check_locale_and_encoding(ControlData *oldctrl,
 		*strchr(cmd_output, '\n') = '\0';
 
 	if (sscanf(cmd_output, "%*s %*s %d.%d", &pre_dot, &post_dot) != 2)
-		pg_log(PG_FATAL, "could not get version from %s\n", cmd);
+		pg_fatal("could not get version from %s\n", cmd);
 
 	cluster->bin_version = (pre_dot * 100 + post_dot) * 100;
 }
@@ -1009,7 +1001,7 @@ static void check_locale_and_encoding(ControlData *oldctrl,
 
 	save = setlocale(category, NULL);
 	if (!save)
-		pg_log(PG_FATAL, "failed to get the current locale\n");
+		pg_fatal("failed to get the current locale\n");
 
 	/* 'save' may be pointing at a modifiable scratch variable, so copy it. */
 	save = pg_strdup(save);
@@ -1018,13 +1010,13 @@ static void check_locale_and_encoding(ControlData *oldctrl,
 	res = setlocale(category, locale);
 
 	if (!res)
-		pg_log(PG_FATAL, "failed to get system local name for \"%s\"\n", res);
+		pg_fatal("failed to get system local name for \"%s\"\n", res);
 
 	res = pg_strdup(res);
 
 	/* restore old value. */
 	if (!setlocale(category, save))
-		pg_log(PG_FATAL, "failed to restore old locale \"%s\"\n", save);
+		pg_fatal("failed to restore old locale \"%s\"\n", save);
 
 	pg_free(save);
 
diff --git a/contrib/pg_upgrade/controldata.c b/contrib/pg_upgrade/controldata.c
index d2d8785..08e95e8 100644
--- a/contrib/pg_upgrade/controldata.c
+++ b/contrib/pg_upgrade/controldata.c
@@ -118,7 +118,7 @@
 	fflush(stderr);
 
 	if ((output = popen(cmd, "r")) == NULL)
-		pg_log(PG_FATAL, "Could not get control data using %s: %s\n",
+		pg_fatal("Could not get control data using %s: %s\n",
 			   cmd, getErrorText(errno));
 
 	/* Only pre-8.4 has these so if they are not set below we will check later */
@@ -155,8 +155,7 @@
 		{
 			for (p = bufin; *p; p++)
 				if (!isascii(*p))
-					pg_log(PG_FATAL,
-						   "The 8.3 cluster's pg_controldata is incapable of outputting ASCII, even\n"
+					pg_fatal("The 8.3 cluster's pg_controldata is incapable of outputting ASCII, even\n"
 						   "with LANG=C.  You must upgrade this cluster to a newer version of PostgreSQL\n"
 						   "8.3 to fix this bug.  PostgreSQL 8.3.7 and later are known to work properly.\n");
 		}
@@ -167,7 +166,7 @@
 			p = strchr(p, ':');
 
 			if (p == NULL || strlen(p) <= 1)
-				pg_log(PG_FATAL, "%d: pg_resetxlog problem\n", __LINE__);
+				pg_fatal("%d: pg_resetxlog problem\n", __LINE__);
 
 			p++;				/* removing ':' char */
 			cluster->controldata.ctrl_ver = str2uint(p);
@@ -177,7 +176,7 @@
 			p = strchr(p, ':');
 
 			if (p == NULL || strlen(p) <= 1)
-				pg_log(PG_FATAL, "%d: controldata retrieval problem\n", __LINE__);
+				pg_fatal("%d: controldata retrieval problem\n", __LINE__);
 
 			p++;				/* removing ':' char */
 			cluster->controldata.cat_ver = str2uint(p);
@@ -187,14 +186,14 @@
 			/* Skip the colon and any whitespace after it */
 			p = strchr(p, ':');
 			if (p == NULL || strlen(p) <= 1)
-				pg_log(PG_FATAL, "%d: controldata retrieval problem\n", __LINE__);
+				pg_fatal("%d: controldata retrieval problem\n", __LINE__);
 			p = strpbrk(p, "01234567890ABCDEF");
 			if (p == NULL || strlen(p) <= 1)
-				pg_log(PG_FATAL, "%d: controldata retrieval problem\n", __LINE__);
+				pg_fatal("%d: controldata retrieval problem\n", __LINE__);
 
 			/* Make sure it looks like a valid WAL file name */
 			if (strspn(p, "0123456789ABCDEF") != 24)
-				pg_log(PG_FATAL, "%d: controldata retrieval problem\n", __LINE__);
+				pg_fatal("%d: controldata retrieval problem\n", __LINE__);
 
 			strlcpy(cluster->controldata.nextxlogfile, p, 25);
 			got_nextxlogfile = true;
@@ -204,7 +203,7 @@
 			p = strchr(p, ':');
 
 			if (p == NULL || strlen(p) <= 1)
-				pg_log(PG_FATAL, "%d: controldata retrieval problem\n", __LINE__);
+				pg_fatal("%d: controldata retrieval problem\n", __LINE__);
 
 			p++;				/* removing ':' char */
 			logid = str2uint(p);
@@ -215,7 +214,7 @@
 			p = strchr(p, ':');
 
 			if (p == NULL || strlen(p) <= 1)
-				pg_log(PG_FATAL, "%d: controldata retrieval problem\n", __LINE__);
+				pg_fatal("%d: controldata retrieval problem\n", __LINE__);
 
 			p++;				/* removing ':' char */
 			segno = str2uint(p);
@@ -226,7 +225,7 @@
 			p = strchr(p, ':');
 
 			if (p == NULL || strlen(p) <= 1)
-				pg_log(PG_FATAL, "%d: controldata retrieval problem\n", __LINE__);
+				pg_fatal("%d: controldata retrieval problem\n", __LINE__);
 
 			p++;				/* removing ':' char */
 			cluster->controldata.chkpnt_tli = str2uint(p);
@@ -240,7 +239,7 @@
 				op = strchr(p, ':');
 
 			if (op == NULL || strlen(op) <= 1)
-				pg_log(PG_FATAL, "%d: controldata retrieval problem\n", __LINE__);
+				pg_fatal("%d: controldata retrieval problem\n", __LINE__);
 
 			op++;				/* removing ':' char */
 			cluster->controldata.chkpnt_nxtxid = str2uint(op);
@@ -251,7 +250,7 @@
 			p = strchr(p, ':');
 
 			if (p == NULL || strlen(p) <= 1)
-				pg_log(PG_FATAL, "%d: controldata retrieval problem\n", __LINE__);
+				pg_fatal("%d: controldata retrieval problem\n", __LINE__);
 
 			p++;				/* removing ':' char */
 			cluster->controldata.chkpnt_nxtoid = str2uint(p);
@@ -262,7 +261,7 @@
 			p = strchr(p, ':');
 
 			if (p == NULL || strlen(p) <= 1)
-				pg_log(PG_FATAL, "%d: controldata retrieval problem\n", __LINE__);
+				pg_fatal("%d: controldata retrieval problem\n", __LINE__);
 
 			p++;				/* removing ':' char */
 			cluster->controldata.chkpnt_nxtmulti = str2uint(p);
@@ -273,7 +272,7 @@
 			p = strchr(p, ':');
 
 			if (p == NULL || strlen(p) <= 1)
-				pg_log(PG_FATAL, "%d: controldata retrieval problem\n", __LINE__);
+				pg_fatal("%d: controldata retrieval problem\n", __LINE__);
 
 			p++;				/* removing ':' char */
 			cluster->controldata.chkpnt_oldstMulti = str2uint(p);
@@ -284,7 +283,7 @@
 			p = strchr(p, ':');
 
 			if (p == NULL || strlen(p) <= 1)
-				pg_log(PG_FATAL, "%d: controldata retrieval problem\n", __LINE__);
+				pg_fatal("%d: controldata retrieval problem\n", __LINE__);
 
 			p++;				/* removing ':' char */
 			cluster->controldata.chkpnt_nxtmxoff = str2uint(p);
@@ -295,7 +294,7 @@
 			p = strchr(p, ':');
 
 			if (p == NULL || strlen(p) <= 1)
-				pg_log(PG_FATAL, "%d: controldata retrieval problem\n", __LINE__);
+				pg_fatal("%d: controldata retrieval problem\n", __LINE__);
 
 			p++;				/* removing ':' char */
 			cluster->controldata.align = str2uint(p);
@@ -306,7 +305,7 @@
 			p = strchr(p, ':');
 
 			if (p == NULL || strlen(p) <= 1)
-				pg_log(PG_FATAL, "%d: controldata retrieval problem\n", __LINE__);
+				pg_fatal("%d: controldata retrieval problem\n", __LINE__);
 
 			p++;				/* removing ':' char */
 			cluster->controldata.blocksz = str2uint(p);
@@ -317,7 +316,7 @@
 			p = strchr(p, ':');
 
 			if (p == NULL || strlen(p) <= 1)
-				pg_log(PG_FATAL, "%d: controldata retrieval problem\n", __LINE__);
+				pg_fatal("%d: controldata retrieval problem\n", __LINE__);
 
 			p++;				/* removing ':' char */
 			cluster->controldata.largesz = str2uint(p);
@@ -328,7 +327,7 @@
 			p = strchr(p, ':');
 
 			if (p == NULL || strlen(p) <= 1)
-				pg_log(PG_FATAL, "%d: controldata retrieval problem\n", __LINE__);
+				pg_fatal("%d: controldata retrieval problem\n", __LINE__);
 
 			p++;				/* removing ':' char */
 			cluster->controldata.walsz = str2uint(p);
@@ -339,7 +338,7 @@
 			p = strchr(p, ':');
 
 			if (p == NULL || strlen(p) <= 1)
-				pg_log(PG_FATAL, "%d: controldata retrieval problem\n", __LINE__);
+				pg_fatal("%d: controldata retrieval problem\n", __LINE__);
 
 			p++;				/* removing ':' char */
 			cluster->controldata.walseg = str2uint(p);
@@ -350,7 +349,7 @@
 			p = strchr(p, ':');
 
 			if (p == NULL || strlen(p) <= 1)
-				pg_log(PG_FATAL, "%d: controldata retrieval problem\n", __LINE__);
+				pg_fatal("%d: controldata retrieval problem\n", __LINE__);
 
 			p++;				/* removing ':' char */
 			cluster->controldata.ident = str2uint(p);
@@ -361,7 +360,7 @@
 			p = strchr(p, ':');
 
 			if (p == NULL || strlen(p) <= 1)
-				pg_log(PG_FATAL, "%d: controldata retrieval problem\n", __LINE__);
+				pg_fatal("%d: controldata retrieval problem\n", __LINE__);
 
 			p++;				/* removing ':' char */
 			cluster->controldata.index = str2uint(p);
@@ -372,7 +371,7 @@
 			p = strchr(p, ':');
 
 			if (p == NULL || strlen(p) <= 1)
-				pg_log(PG_FATAL, "%d: controldata retrieval problem\n", __LINE__);
+				pg_fatal("%d: controldata retrieval problem\n", __LINE__);
 
 			p++;				/* removing ':' char */
 			cluster->controldata.toast = str2uint(p);
@@ -383,7 +382,7 @@
 			p = strchr(p, ':');
 
 			if (p == NULL || strlen(p) <= 1)
-				pg_log(PG_FATAL, "%d: controldata retrieval problem\n", __LINE__);
+				pg_fatal("%d: controldata retrieval problem\n", __LINE__);
 
 			p++;				/* removing ':' char */
 			cluster->controldata.date_is_int = strstr(p, "64-bit integers") != NULL;
@@ -394,7 +393,7 @@
 			p = strchr(p, ':');
 
 			if (p == NULL || strlen(p) <= 1)
-				pg_log(PG_FATAL, "%d: controldata retrieval problem\n", __LINE__);
+				pg_fatal("%d: controldata retrieval problem\n", __LINE__);
 
 			p++;				/* removing ':' char */
 			/* used later for contrib check */
@@ -406,7 +405,7 @@
 			p = strchr(p, ':');
 
 			if (p == NULL || strlen(p) <= 1)
-				pg_log(PG_FATAL, "%d: controldata retrieval problem\n", __LINE__);
+				pg_fatal("%d: controldata retrieval problem\n", __LINE__);
 
 			p++;				/* removing ':' char */
 			/* used later for contrib check */
@@ -419,7 +418,7 @@
 			p = strchr(p, ':');
 
 			if (p == NULL || strlen(p) <= 1)
-				pg_log(PG_FATAL, "%d: controldata retrieval problem\n", __LINE__);
+				pg_fatal("%d: controldata retrieval problem\n", __LINE__);
 
 			p++;				/* removing ':' char */
 			/* skip leading spaces and remove trailing newline */
@@ -434,7 +433,7 @@
 			p = strchr(p, ':');
 
 			if (p == NULL || strlen(p) <= 1)
-				pg_log(PG_FATAL, "%d: controldata retrieval problem\n", __LINE__);
+				pg_fatal("%d: controldata retrieval problem\n", __LINE__);
 
 			p++;				/* removing ':' char */
 			/* skip leading spaces and remove trailing newline */
@@ -559,8 +558,7 @@
 		if (!got_data_checksum_version)
 			pg_log(PG_REPORT, "  data checksum version\n");
 
-		pg_log(PG_FATAL,
-			   "Cannot continue without required control information, terminating\n");
+		pg_fatal("Cannot continue without required control information, terminating\n");
 	}
 }
 
@@ -575,37 +573,29 @@
 				   ControlData *newctrl)
 {
 	if (oldctrl->align == 0 || oldctrl->align != newctrl->align)
-		pg_log(PG_FATAL,
-		"old and new pg_controldata alignments are invalid or do not match\n"
+		pg_fatal("old and new pg_controldata alignments are invalid or do not match\n"
 			   "Likely one cluster is a 32-bit install, the other 64-bit\n");
 
 	if (oldctrl->blocksz == 0 || oldctrl->blocksz != newctrl->blocksz)
-		pg_log(PG_FATAL,
-			   "old and new pg_controldata block sizes are invalid or do not match\n");
+		pg_fatal("old and new pg_controldata block sizes are invalid or do not match\n");
 
 	if (oldctrl->largesz == 0 || oldctrl->largesz != newctrl->largesz)
-		pg_log(PG_FATAL,
-			   "old and new pg_controldata maximum relation segement sizes are invalid or do not match\n");
+		pg_fatal("old and new pg_controldata maximum relation segement sizes are invalid or do not match\n");
 
 	if (oldctrl->walsz == 0 || oldctrl->walsz != newctrl->walsz)
-		pg_log(PG_FATAL,
-			   "old and new pg_controldata WAL block sizes are invalid or do not match\n");
+		pg_fatal("old and new pg_controldata WAL block sizes are invalid or do not match\n");
 
 	if (oldctrl->walseg == 0 || oldctrl->walseg != newctrl->walseg)
-		pg_log(PG_FATAL,
-			   "old and new pg_controldata WAL segment sizes are invalid or do not match\n");
+		pg_fatal("old and new pg_controldata WAL segment sizes are invalid or do not match\n");
 
 	if (oldctrl->ident == 0 || oldctrl->ident != newctrl->ident)
-		pg_log(PG_FATAL,
-			   "old and new pg_controldata maximum identifier lengths are invalid or do not match\n");
+		pg_fatal("old and new pg_controldata maximum identifier lengths are invalid or do not match\n");
 
 	if (oldctrl->index == 0 || oldctrl->index != newctrl->index)
-		pg_log(PG_FATAL,
-			   "old and new pg_controldata maximum indexed columns are invalid or do not match\n");
+		pg_fatal("old and new pg_controldata maximum indexed columns are invalid or do not match\n");
 
 	if (oldctrl->toast == 0 || oldctrl->toast != newctrl->toast)
-		pg_log(PG_FATAL,
-			   "old and new pg_controldata maximum TOAST chunk sizes are invalid or do not match\n");
+		pg_fatal("old and new pg_controldata maximum TOAST chunk sizes are invalid or do not match\n");
 
 	if (oldctrl->date_is_int != newctrl->date_is_int)
 	{
@@ -615,8 +605,7 @@
 		/*
 		 * This is a common 8.3 -> 8.4 upgrade problem, so we are more verbose
 		 */
-		pg_log(PG_FATAL,
-			"You will need to rebuild the new server with configure option\n"
+		pg_fatal("You will need to rebuild the new server with configure option\n"
 			   "--disable-integer-datetimes or get server binaries built with those\n"
 			   "options.\n");
 	}
@@ -627,8 +616,7 @@
 	 */
 	if (oldctrl->data_checksum_version != newctrl->data_checksum_version)
 	{
-		pg_log(PG_FATAL,
-			   "old and new pg_controldata checksum versions are invalid or do not match\n");
+		pg_fatal("old and new pg_controldata checksum versions are invalid or do not match\n");
 	}
 }
 
@@ -645,7 +633,7 @@
 	snprintf(old_path, sizeof(old_path), "%s/global/pg_control", old_cluster.pgdata);
 	snprintf(new_path, sizeof(new_path), "%s/global/pg_control.old", old_cluster.pgdata);
 	if (pg_mv_file(old_path, new_path) != 0)
-		pg_log(PG_FATAL, "Unable to rename %s to %s.\n", old_path, new_path);
+		pg_fatal("Unable to rename %s to %s.\n", old_path, new_path);
 	check_ok();
 
 	pg_log(PG_REPORT, "\n"
diff --git a/contrib/pg_upgrade/exec.c b/contrib/pg_upgrade/exec.c
index 44f6a75..309585c 100644
--- a/contrib/pg_upgrade/exec.c
+++ b/contrib/pg_upgrade/exec.c
@@ -65,11 +65,11 @@
 	written += vsnprintf(cmd + written, MAXCMDLEN - written, fmt, ap);
 	va_end(ap);
 	if (written >= MAXCMDLEN)
-		pg_log(PG_FATAL, "command too long\n");
+		pg_fatal("command too long\n");
 	written += snprintf(cmd + written, MAXCMDLEN - written,
 						" >> \"%s\" 2>&1" SYSTEMQUOTE, log_file);
 	if (written >= MAXCMDLEN)
-		pg_log(PG_FATAL, "command too long\n");
+		pg_fatal("command too long\n");
 
 	pg_log(PG_VERBOSE, "%s\n", cmd);
 
@@ -109,7 +109,7 @@
 #endif
 
 	if (log == NULL)
-		pg_log(PG_FATAL, "cannot write to log file %s\n", log_file);
+		pg_fatal("cannot write to log file %s\n", log_file);
 
 #ifdef WIN32
 	/* Are we printing "command:" before its output? */
@@ -163,7 +163,7 @@
 	 * log these commands to a third file, but that just adds complexity.
 	 */
 	if ((log = fopen(log_file, "a")) == NULL)
-		pg_log(PG_FATAL, "cannot write to log file %s\n", log_file);
+		pg_fatal("cannot write to log file %s\n", log_file);
 	fprintf(log, "\n\n");
 	fclose(log);
 #endif
@@ -189,7 +189,7 @@
 	{
 		/* ENOTDIR means we will throw a more useful error later */
 		if (errno != ENOENT && errno != ENOTDIR)
-			pg_log(PG_FATAL, "could not open file \"%s\" for reading: %s\n",
+			pg_fatal("could not open file \"%s\" for reading: %s\n",
 				   path, getErrorText(errno));
 
 		return false;
@@ -216,8 +216,7 @@
 #else
 	if (win32_check_directory_write_permissions() != 0)
 #endif
-		pg_log(PG_FATAL,
-		  "You must have read and write access in the current directory.\n");
+		pg_fatal("You must have read and write access in the current directory.\n");
 
 	check_bin_dir(&old_cluster);
 	check_data_dir(old_cluster.pgdata);
@@ -350,10 +349,10 @@
 	 * Ensure that the file exists and is a regular file.
 	 */
 	if (stat(path, &buf) < 0)
-		pg_log(PG_FATAL, "check for \"%s\" failed: %s\n",
+		pg_fatal("check for \"%s\" failed: %s\n",
 			   path, getErrorText(errno));
 	else if (!S_ISREG(buf.st_mode))
-		pg_log(PG_FATAL, "check for \"%s\" failed: not an executable file\n",
+		pg_fatal("check for \"%s\" failed: not an executable file\n",
 			   path);
 
 	/*
@@ -365,7 +364,7 @@
 #else
 	if ((buf.st_mode & S_IRUSR) == 0)
 #endif
-		pg_log(PG_FATAL, "check for \"%s\" failed: cannot read file (permission denied)\n",
+		pg_fatal("check for \"%s\" failed: cannot read file (permission denied)\n",
 			   path);
 
 #ifndef WIN32
@@ -373,6 +372,6 @@
 #else
 	if ((buf.st_mode & S_IXUSR) == 0)
 #endif
-		pg_log(PG_FATAL, "check for \"%s\" failed: cannot execute (permission denied)\n",
+		pg_fatal("check for \"%s\" failed: cannot execute (permission denied)\n",
 			   path);
 }
diff --git a/contrib/pg_upgrade/file.c b/contrib/pg_upgrade/file.c
index dfeb79f..bf1f8a0 100644
--- a/contrib/pg_upgrade/file.c
+++ b/contrib/pg_upgrade/file.c
@@ -204,8 +204,7 @@
 
 	if (pg_link_file(existing_file, new_link_file) == -1)
 	{
-		pg_log(PG_FATAL,
-			   "Could not create hard link between old and new data directories: %s\n"
+		pg_fatal("Could not create hard link between old and new data directories: %s\n"
 			   "In link mode the old and new data directories must be on the same file system volume.\n",
 			   getErrorText(errno));
 	}
diff --git a/contrib/pg_upgrade/function.c b/contrib/pg_upgrade/function.c
index 6e8ef7c..78e75bf 100644
--- a/contrib/pg_upgrade/function.c
+++ b/contrib/pg_upgrade/function.c
@@ -216,8 +216,7 @@
 	}
 
 	if (found_public_plpython_handler)
-		pg_log(PG_FATAL,
-		 "Remove the problem functions from the old cluster to continue.\n");
+		pg_fatal("Remove the problem functions from the old cluster to continue.\n");
 
 	totaltups++;				/* reserve for pg_upgrade_support */
 
@@ -324,11 +323,10 @@
 
 			/* exit and report missing support library with special message */
 			if (strcmp(lib, PG_UPGRADE_SUPPORT) == 0)
-				pg_log(PG_FATAL,
-					   "The pg_upgrade_support module must be created and installed in the new cluster.\n");
+				pg_fatal("The pg_upgrade_support module must be created and installed in the new cluster.\n");
 
 			if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
-				pg_log(PG_FATAL, "Could not open file \"%s\": %s\n",
+				pg_fatal("Could not open file \"%s\": %s\n",
 					   output_path, getErrorText(errno));
 			fprintf(script, "Could not load library \"%s\"\n%s\n",
 					lib,
@@ -344,8 +342,7 @@
 	{
 		fclose(script);
 		pg_log(PG_REPORT, "fatal\n");
-		pg_log(PG_FATAL,
-			   "Your installation references loadable libraries that are missing from the\n"
+		pg_fatal("Your installation references loadable libraries that are missing from the\n"
 			   "new installation.  You can add these libraries to the new installation,\n"
 			   "or remove the functions using them from the old installation.  A list of\n"
 			   "problem libraries is in the file:\n"
diff --git a/contrib/pg_upgrade/info.c b/contrib/pg_upgrade/info.c
index 18daf1c..46054b3 100644
--- a/contrib/pg_upgrade/info.c
+++ b/contrib/pg_upgrade/info.c
@@ -51,7 +51,7 @@ static void create_rel_filename_map(const char *old_data, const char *new_data,
 		RelInfo    *new_rel = &new_db->rel_arr.rels[relnum];
 
 		if (old_rel->reloid != new_rel->reloid)
-			pg_log(PG_FATAL, "Mismatch of relation OID in database \"%s\": old OID %d, new OID %d\n",
+			pg_fatal("Mismatch of relation OID in database \"%s\": old OID %d, new OID %d\n",
 				   old_db->db_name, old_rel->reloid, new_rel->reloid);
 
 		/*
@@ -68,7 +68,7 @@ static void create_rel_filename_map(const char *old_data, const char *new_data,
 			((GET_MAJOR_VERSION(old_cluster.major_version) >= 900 ||
 			  strcmp(old_rel->nspname, "pg_toast") != 0) &&
 			 strcmp(old_rel->relname, new_rel->relname) != 0))
-			pg_log(PG_FATAL, "Mismatch of relation names in database \"%s\": "
+			pg_fatal("Mismatch of relation names in database \"%s\": "
 				   "old name \"%s.%s\", new name \"%s.%s\"\n",
 				   old_db->db_name, old_rel->nspname, old_rel->relname,
 				   new_rel->nspname, new_rel->relname);
@@ -83,7 +83,7 @@ static void create_rel_filename_map(const char *old_data, const char *new_data,
 	 * error above
 	 */
 	if (old_db->rel_arr.nrels != new_db->rel_arr.nrels)
-		pg_log(PG_FATAL, "old and new databases \"%s\" have a different number of relations\n",
+		pg_fatal("old and new databases \"%s\" have a different number of relations\n",
 			   old_db->db_name);
 
 	*nmaps = num_maps;
diff --git a/contrib/pg_upgrade/option.c b/contrib/pg_upgrade/option.c
index 2774b1e..250aeb8 100644
--- a/contrib/pg_upgrade/option.c
+++ b/contrib/pg_upgrade/option.c
@@ -96,10 +96,10 @@ static void check_required_directory(char **dirpath, char **configpath,
 
 	/* Allow help and version to be run as root, so do the test here. */
 	if (os_user_effective_id == 0)
-		pg_log(PG_FATAL, "%s: cannot be run as root\n", os_info.progname);
+		pg_fatal("%s: cannot be run as root\n", os_info.progname);
 
 	if ((log_opts.internal = fopen_priv(INTERNAL_LOG_FILE, "a")) == NULL)
-		pg_log(PG_FATAL, "cannot write to log file %s\n", INTERNAL_LOG_FILE);
+		pg_fatal("cannot write to log file %s\n", INTERNAL_LOG_FILE);
 
 	while ((option = getopt_long(argc, argv, "d:D:b:B:cj:ko:O:p:P:rU:v",
 								 long_options, &optindex)) != -1)
@@ -152,7 +152,7 @@ static void check_required_directory(char **dirpath, char **configpath,
 			case 'p':
 				if ((old_cluster.port = atoi(optarg)) <= 0)
 				{
-					pg_log(PG_FATAL, "invalid old port number\n");
+					pg_fatal("invalid old port number\n");
 					exit(1);
 				}
 				break;
@@ -160,7 +160,7 @@ static void check_required_directory(char **dirpath, char **configpath,
 			case 'P':
 				if ((new_cluster.port = atoi(optarg)) <= 0)
 				{
-					pg_log(PG_FATAL, "invalid new port number\n");
+					pg_fatal("invalid new port number\n");
 					exit(1);
 				}
 				break;
@@ -187,8 +187,7 @@ static void check_required_directory(char **dirpath, char **configpath,
 				break;
 
 			default:
-				pg_log(PG_FATAL,
-					   "Try \"%s --help\" for more information.\n",
+				pg_fatal("Try \"%s --help\" for more information.\n",
 					   os_info.progname);
 				break;
 		}
@@ -198,7 +197,7 @@ static void check_required_directory(char **dirpath, char **configpath,
 	for (filename = output_files; *filename != NULL; filename++)
 	{
 		if ((fp = fopen_priv(*filename, "a")) == NULL)
-			pg_log(PG_FATAL, "cannot write to log file %s\n", *filename);
+			pg_fatal("cannot write to log file %s\n", *filename);
 
 		/* Start with newline because we might be appending to a file. */
 		fprintf(fp, "\n"
@@ -308,7 +307,7 @@ static void check_required_directory(char **dirpath, char **configpath,
 				*configpath = pg_strdup(envVar);
 		}
 		else
-			pg_log(PG_FATAL, "You must identify the directory where the %s.\n"
+			pg_fatal("You must identify the directory where the %s.\n"
 				   "Please use the %s command-line option or the %s environment variable.\n",
 				   description, cmdLineOption, envVarName);
 	}
@@ -371,7 +370,7 @@ static void check_required_directory(char **dirpath, char **configpath,
 
 	if ((output = popen(cmd, "r")) == NULL ||
 		fgets(cmd_output, sizeof(cmd_output), output) == NULL)
-		pg_log(PG_FATAL, "Could not get data directory using %s: %s\n",
+		pg_fatal("Could not get data directory using %s: %s\n",
 			   cmd, getErrorText(errno));
 
 	pclose(output);
@@ -410,7 +409,7 @@ static void check_required_directory(char **dirpath, char **configpath,
 			/* Use the current directory for the socket */
 			cluster->sockdir = pg_malloc(MAXPGPATH);
 			if (!getcwd(cluster->sockdir, MAXPGPATH))
-				pg_log(PG_FATAL, "cannot find current directory\n");
+				pg_fatal("cannot find current directory\n");
 		}
 		else
 		{
@@ -428,14 +427,14 @@ static void check_required_directory(char **dirpath, char **configpath,
 			snprintf(filename, sizeof(filename), "%s/postmaster.pid",
 					 cluster->pgdata);
 			if ((fp = fopen(filename, "r")) == NULL)
-				pg_log(PG_FATAL, "Cannot open file %s: %m\n", filename);
+				pg_fatal("Cannot open file %s: %m\n", filename);
 
 			for (lineno = 1;
 			   lineno <= Max(LOCK_FILE_LINE_PORT, LOCK_FILE_LINE_SOCKET_DIR);
 				 lineno++)
 			{
 				if (fgets(line, sizeof(line), fp) == NULL)
-					pg_log(PG_FATAL, "Cannot read line %d from %s: %m\n", lineno, filename);
+					pg_fatal("Cannot read line %d from %s: %m\n", lineno, filename);
 
 				/* potentially overwrite user-supplied value */
 				if (lineno == LOCK_FILE_LINE_PORT)
diff --git a/contrib/pg_upgrade/page.c b/contrib/pg_upgrade/page.c
index 8f8527d..3b3e1d9 100644
--- a/contrib/pg_upgrade/page.c
+++ b/contrib/pg_upgrade/page.c
@@ -65,7 +65,7 @@ static pageCnvCtx *loadConverterPlugin(
 		 */
 
 		if ((converter = loadConverterPlugin(newPageVersion, oldPageVersion)) == NULL)
-			pg_log(PG_FATAL, "could not find plugin to convert from old page layout to new page layout\n");
+			pg_fatal("could not find plugin to convert from old page layout to new page layout\n");
 
 		return converter;
 	}
@@ -91,10 +91,10 @@ static pageCnvCtx *loadConverterPlugin(
 	ssize_t		bytesRead;
 
 	if ((relfd = open(pathName, O_RDONLY, 0)) < 0)
-		pg_log(PG_FATAL, "could not open relation %s\n", pathName);
+		pg_fatal("could not open relation %s\n", pathName);
 
 	if ((bytesRead = read(relfd, &page, sizeof(page))) != sizeof(page))
-		pg_log(PG_FATAL, "could not read page header of %s\n", pathName);
+		pg_fatal("could not read page header of %s\n", pathName);
 
 	*version = PageGetPageLayoutVersion(&page);
 
diff --git a/contrib/pg_upgrade/parallel.c b/contrib/pg_upgrade/parallel.c
index f00bb71..dcd21dc 100644
--- a/contrib/pg_upgrade/parallel.c
+++ b/contrib/pg_upgrade/parallel.c
@@ -128,7 +128,7 @@
 			_exit(!exec_prog(log_file, opt_log_file, true, "%s", cmd));
 		else if (child < 0)
 			/* fork failed */
-			pg_log(PG_FATAL, "could not create worker process: %s\n", strerror(errno));
+			pg_fatal("could not create worker process: %s\n", strerror(errno));
 #else
 		/* empty array element are always at the end */
 		new_arg = exec_thread_args[parallel_jobs - 1];
@@ -147,7 +147,7 @@
 		child = (HANDLE) _beginthreadex(NULL, 0, (void *) win32_exec_prog,
 										new_arg, 0, NULL);
 		if (child == 0)
-			pg_log(PG_FATAL, "could not create worker thread: %s\n", strerror(errno));
+			pg_fatal("could not create worker thread: %s\n", strerror(errno));
 
 		thread_handles[parallel_jobs - 1] = child;
 #endif
@@ -242,7 +242,7 @@
 		}
 		else if (child < 0)
 			/* fork failed */
-			pg_log(PG_FATAL, "could not create worker process: %s\n", strerror(errno));
+			pg_fatal("could not create worker process: %s\n", strerror(errno));
 #else
 		/* empty array element are always at the end */
 		new_arg = transfer_thread_args[parallel_jobs - 1];
@@ -263,7 +263,7 @@
 		child = (HANDLE) _beginthreadex(NULL, 0, (void *) win32_transfer_all_new_dbs,
 										new_arg, 0, NULL);
 		if (child == 0)
-			pg_log(PG_FATAL, "could not create worker thread: %s\n", strerror(errno));
+			pg_fatal("could not create worker thread: %s\n", strerror(errno));
 
 		thread_handles[parallel_jobs - 1] = child;
 #endif
@@ -311,7 +311,7 @@
 		return false;
 
 	if (WEXITSTATUS(work_status) != 0)
-		pg_log(PG_FATAL, "child worker exited abnormally: %s\n", strerror(errno));
+		pg_fatal("child worker exited abnormally: %s\n", strerror(errno));
 #else
 	/* wait for one to finish */
 	thread_num = WaitForMultipleObjects(parallel_jobs, thread_handles,
@@ -326,7 +326,7 @@
 	/* get the result */
 	GetExitCodeThread(thread_handles[thread_num], &res);
 	if (res != 0)
-		pg_log(PG_FATAL, "child worker exited abnormally: %s\n", strerror(errno));
+		pg_fatal("child worker exited abnormally: %s\n", strerror(errno));
 
 	/* dispose of handle to stop leaks */
 	CloseHandle(thread_handles[thread_num]);
diff --git a/contrib/pg_upgrade/pg_upgrade.c b/contrib/pg_upgrade/pg_upgrade.c
index 85b1181..a4d544c 100644
--- a/contrib/pg_upgrade/pg_upgrade.c
+++ b/contrib/pg_upgrade/pg_upgrade.c
@@ -205,7 +205,7 @@
 		else
 		{
 			if (!user_opts.check)
-				pg_log(PG_FATAL, "There seems to be a postmaster servicing the old cluster.\n"
+				pg_fatal("There seems to be a postmaster servicing the old cluster.\n"
 					   "Please shutdown that postmaster and try again.\n");
 			else
 				*live_check = true;
@@ -218,13 +218,13 @@
 		if (start_postmaster(&new_cluster, false))
 			stop_postmaster(false);
 		else
-			pg_log(PG_FATAL, "There seems to be a postmaster servicing the new cluster.\n"
+			pg_fatal("There seems to be a postmaster servicing the new cluster.\n"
 				   "Please shutdown that postmaster and try again.\n");
 	}
 
 	/* get path to pg_upgrade executable */
 	if (find_my_exec(argv0, exec_path) < 0)
-		pg_log(PG_FATAL, "Could not get path name to pg_upgrade: %s\n", getErrorText(errno));
+		pg_fatal("Could not get path name to pg_upgrade: %s\n", getErrorText(errno));
 
 	/* Trim off program name and keep just path */
 	*last_dir_separator(exec_path) = '\0';
@@ -378,7 +378,7 @@
 	snprintf(old_path, sizeof(old_path), "%s/%s", old_cluster.pgdata, subdir);
 	snprintf(new_path, sizeof(new_path), "%s/%s", new_cluster.pgdata, subdir);
 	if (!rmtree(new_path, true))
-		pg_log(PG_FATAL, "could not delete directory \"%s\"\n", new_path);
+		pg_fatal("could not delete directory \"%s\"\n", new_path);
 	check_ok();
 
 	prep_status("Copying old %s to new server", subdir);
diff --git a/contrib/pg_upgrade/pg_upgrade.h b/contrib/pg_upgrade/pg_upgrade.h
index 0b3ad20..48554a6 100644
--- a/contrib/pg_upgrade/pg_upgrade.h
+++ b/contrib/pg_upgrade/pg_upgrade.h
@@ -451,6 +451,9 @@ __attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
 void
 pg_log(eLogType type, char *fmt,...)
 __attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
+void
+pg_fatal(char *fmt,...)
+__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2),noreturn));
 void		end_progress_output(void);
 void
 prep_status(const char *fmt,...)
diff --git a/contrib/pg_upgrade/relfilenode.c b/contrib/pg_upgrade/relfilenode.c
index a951fc9..08c1db3 100644
--- a/contrib/pg_upgrade/relfilenode.c
+++ b/contrib/pg_upgrade/relfilenode.c
@@ -107,7 +107,7 @@ static void transfer_relfile(pageCnvCtx *pageConverter, FileNameMap *map,
 		}
 
 		if (new_dbnum >= new_db_arr->ndbs)
-			pg_log(PG_FATAL, "old database \"%s\" not found in the new cluster\n",
+			pg_fatal("old database \"%s\" not found in the new cluster\n",
 				   old_db->db_name);
 
 		n_maps = 0;
@@ -258,7 +258,7 @@ static void transfer_relfile(pageCnvCtx *pageConverter, FileNameMap *map,
 				if (errno == ENOENT)
 					return;
 				else
-					pg_log(PG_FATAL, "error while checking for file existence \"%s.%s\" (\"%s\" to \"%s\"): %s\n",
+					pg_fatal("error while checking for file existence \"%s.%s\" (\"%s\" to \"%s\"): %s\n",
 						   map->nspname, map->relname, old_file, new_file,
 						   getErrorText(errno));
 			}
@@ -271,7 +271,7 @@ static void transfer_relfile(pageCnvCtx *pageConverter, FileNameMap *map,
 		pg_log(PG_STATUS, "%s", old_file);
 
 		if ((user_opts.transfer_mode == TRANSFER_MODE_LINK) && (pageConverter != NULL))
-			pg_log(PG_FATAL, "This upgrade requires page-by-page conversion, "
+			pg_fatal("This upgrade requires page-by-page conversion, "
 				   "you must use copy mode instead of link mode.\n");
 
 		if (user_opts.transfer_mode == TRANSFER_MODE_COPY)
@@ -279,7 +279,7 @@ static void transfer_relfile(pageCnvCtx *pageConverter, FileNameMap *map,
 			pg_log(PG_VERBOSE, "copying \"%s\" to \"%s\"\n", old_file, new_file);
 
 			if ((msg = copyAndUpdateFile(pageConverter, old_file, new_file, true)) != NULL)
-				pg_log(PG_FATAL, "error while copying relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n",
+				pg_fatal("error while copying relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n",
 					   map->nspname, map->relname, old_file, new_file, msg);
 		}
 		else
@@ -287,8 +287,7 @@ static void transfer_relfile(pageCnvCtx *pageConverter, FileNameMap *map,
 			pg_log(PG_VERBOSE, "linking \"%s\" to \"%s\"\n", old_file, new_file);
 
 			if ((msg = linkAndUpdateFile(pageConverter, old_file, new_file)) != NULL)
-				pg_log(PG_FATAL,
-					   "error while creating link for relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n",
+				pg_fatal("error while creating link for relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n",
 					   map->nspname, map->relname, old_file, new_file, msg);
 		}
 	}
diff --git a/contrib/pg_upgrade/server.c b/contrib/pg_upgrade/server.c
index 1ad85cf..b75f553 100644
--- a/contrib/pg_upgrade/server.c
+++ b/contrib/pg_upgrade/server.c
@@ -149,12 +149,12 @@
 	snprintf(ver_filename, sizeof(ver_filename), "%s/PG_VERSION",
 			 cluster->pgdata);
 	if ((version_fd = fopen(ver_filename, "r")) == NULL)
-		pg_log(PG_FATAL, "could not open version file: %s\n", ver_filename);
+		pg_fatal("could not open version file: %s\n", ver_filename);
 
 	if (fscanf(version_fd, "%63s", cluster->major_version_str) == 0 ||
 		sscanf(cluster->major_version_str, "%d.%d", &integer_version,
 			   &fractional_version) != 2)
-		pg_log(PG_FATAL, "could not get version from %s\n", cluster->pgdata);
+		pg_fatal("could not get version from %s\n", cluster->pgdata);
 
 	fclose(version_fd);
 
@@ -270,7 +270,7 @@
 			   PQerrorMessage(conn));
 		if (conn)
 			PQfinish(conn);
-		pg_log(PG_FATAL, "could not connect to %s postmaster started with the command:\n"
+		pg_fatal("could not connect to %s postmaster started with the command:\n"
 			   "%s\n",
 			   CLUSTER_NAME(cluster), cmd);
 	}
@@ -281,7 +281,7 @@
 	 * enabled, fail now.  This could happen if the server was already running.
 	 */
 	if (!pg_ctl_return)
-		pg_log(PG_FATAL, "pg_ctl failed to start the %s server, or connection failed\n",
+		pg_fatal("pg_ctl failed to start the %s server, or connection failed\n",
 			   CLUSTER_NAME(cluster));
 
 	return true;
@@ -336,8 +336,7 @@
 			/* check for 'local' host values */
 				(strcmp(value, "localhost") != 0 && strcmp(value, "127.0.0.1") != 0 &&
 				 strcmp(value, "::1") != 0 && value[0] != '/'))
-				pg_log(PG_FATAL,
-					   "libpq environment variable %s has a non-local server value: %s\n",
+				pg_fatal("libpq environment variable %s has a non-local server value: %s\n",
 					   option->envvar, value);
 		}
 	}
diff --git a/contrib/pg_upgrade/tablespace.c b/contrib/pg_upgrade/tablespace.c
index 4747e79..229f4a8 100644
--- a/contrib/pg_upgrade/tablespace.c
+++ b/contrib/pg_upgrade/tablespace.c
@@ -25,8 +25,7 @@
 
 	if (os_info.num_old_tablespaces > 0 &&
 	strcmp(old_cluster.tablespace_suffix, new_cluster.tablespace_suffix) == 0)
-		pg_log(PG_FATAL,
-			   "Cannot upgrade to/from the same system catalog version when\n"
+		pg_fatal("Cannot upgrade to/from the same system catalog version when\n"
 			   "using tablespaces.\n");
 }
 
diff --git a/contrib/pg_upgrade/util.c b/contrib/pg_upgrade/util.c
index 4da7658..0ddda46 100644
--- a/contrib/pg_upgrade/util.c
+++ b/contrib/pg_upgrade/util.c
@@ -80,15 +80,14 @@
 }
 
 
+static
+ __attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 0)))
 void
-pg_log(eLogType type, char *fmt,...)
+pg_log_v(eLogType type, const char *fmt, va_list ap)
 {
-	va_list		args;
 	char		message[MAX_STRING];
 
-	va_start(args, fmt);
-	vsnprintf(message, sizeof(message), fmt, args);
-	va_end(args);
+	vsnprintf(message, sizeof(message), fmt, ap);
 
 	/* PG_VERBOSE and PG_STATUS are only output in verbose mode */
 	/* fopen() on log_opts.internal might have failed, so check it */
@@ -132,8 +131,6 @@
 
 		case PG_FATAL:
 			printf("\n%s", _(message));
-			printf("Failure, exiting\n");
-			exit(1);
 			break;
 
 		default:
@@ -144,6 +141,30 @@
 
 
 void
+pg_log(eLogType type, char *fmt,...)
+{
+	va_list		args;
+
+	va_start(args, fmt);
+	pg_log_v(type, fmt, args);
+	va_end(args);
+}
+
+
+void
+pg_fatal(char *fmt,...)
+{
+	va_list		args;
+
+	va_start(args, fmt);
+	pg_log_v(PG_FATAL, fmt, args);
+	va_end(args);
+	printf("Failure, exiting\n");
+	exit(1);
+}
+
+
+void
 check_ok(void)
 {
 	/* all seems well */
diff --git a/contrib/pg_upgrade/version.c b/contrib/pg_upgrade/version.c
index 5fe7ec4..54f7ed8 100644
--- a/contrib/pg_upgrade/version.c
+++ b/contrib/pg_upgrade/version.c
@@ -49,7 +49,7 @@
 			if (!check_mode)
 			{
 				if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
-					pg_log(PG_FATAL, "could not open file \"%s\": %s\n", output_path, getErrorText(errno));
+					pg_fatal("could not open file \"%s\": %s\n", output_path, getErrorText(errno));
 				fprintf(script, "\\connect %s\n",
 						quote_identifier(active_db->db_name));
 				fprintf(script,
diff --git a/contrib/pg_upgrade/version_old_8_3.c b/contrib/pg_upgrade/version_old_8_3.c
index e244dcf..4f450d5 100644
--- a/contrib/pg_upgrade/version_old_8_3.c
+++ b/contrib/pg_upgrade/version_old_8_3.c
@@ -73,7 +73,7 @@
 		{
 			found = true;
 			if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
-				pg_log(PG_FATAL, "could not open file \"%s\": %s\n", output_path, getErrorText(errno));
+				pg_fatal("could not open file \"%s\": %s\n", output_path, getErrorText(errno));
 			if (!db_used)
 			{
 				fprintf(script, "Database: %s\n", active_db->db_name);
@@ -96,8 +96,7 @@
 	if (found)
 	{
 		pg_log(PG_REPORT, "fatal\n");
-		pg_log(PG_FATAL,
-			   "Your installation contains the \"name\" data type in user tables.  This\n"
+		pg_fatal("Your installation contains the \"name\" data type in user tables.  This\n"
 		"data type changed its internal alignment between your old and new\n"
 			   "clusters so this cluster cannot currently be upgraded.  You can remove\n"
 		"the problem tables and restart the upgrade.  A list of the problem\n"
@@ -164,7 +163,7 @@
 		{
 			found = true;
 			if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
-				pg_log(PG_FATAL, "could not open file \"%s\": %s\n", output_path, getErrorText(errno));
+				pg_fatal("could not open file \"%s\": %s\n", output_path, getErrorText(errno));
 			if (!db_used)
 			{
 				fprintf(script, "Database: %s\n", active_db->db_name);
@@ -187,8 +186,7 @@
 	if (found)
 	{
 		pg_log(PG_REPORT, "fatal\n");
-		pg_log(PG_FATAL,
-			   "Your installation contains the \"tsquery\" data type.    This data type\n"
+		pg_fatal("Your installation contains the \"tsquery\" data type.    This data type\n"
 			   "added a new internal field between your old and new clusters so this\n"
 		"cluster cannot currently be upgraded.  You can remove the problem\n"
 			   "columns and restart the upgrade.  A list of the problem columns is in the\n"
@@ -243,7 +241,7 @@
 		{
 			found = true;
 			if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
-				pg_log(PG_FATAL, "Could not open file \"%s\": %s\n",
+				pg_fatal("Could not open file \"%s\": %s\n",
 					   output_path, getErrorText(errno));
 			if (!db_used)
 			{
@@ -266,8 +264,7 @@
 	if (found)
 	{
 		pg_log(PG_REPORT, "fatal\n");
-		pg_log(PG_FATAL,
-			   "Your installation contains the \"ltree\" data type.  This data type\n"
+		pg_fatal("Your installation contains the \"ltree\" data type.  This data type\n"
 			   "changed its internal storage format between your old and new clusters so this\n"
 			   "cluster cannot currently be upgraded.  You can manually upgrade databases\n"
 			   "that use \"contrib/ltree\" facilities and remove \"contrib/ltree\" from the old\n"
@@ -364,7 +361,7 @@
 			if (!check_mode)
 			{
 				if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
-					pg_log(PG_FATAL, "could not open file \"%s\": %s\n", output_path, getErrorText(errno));
+					pg_fatal("could not open file \"%s\": %s\n", output_path, getErrorText(errno));
 				if (!db_used)
 				{
 					fprintf(script, "\\connect %s\n\n",
@@ -480,7 +477,7 @@
 			if (!check_mode)
 			{
 				if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
-					pg_log(PG_FATAL, "could not open file \"%s\": %s\n", output_path, getErrorText(errno));
+					pg_fatal("could not open file \"%s\": %s\n", output_path, getErrorText(errno));
 				if (!db_used)
 				{
 					fprintf(script, "\\connect %s\n",
@@ -599,7 +596,7 @@
 			if (!check_mode)
 			{
 				if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
-					pg_log(PG_FATAL, "could not open file \"%s\": %s\n", output_path, getErrorText(errno));
+					pg_fatal("could not open file \"%s\": %s\n", output_path, getErrorText(errno));
 				if (!db_used)
 				{
 					fprintf(script, "\\connect %s\n",
@@ -721,7 +718,7 @@
 			found = true;
 
 			if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
-				pg_log(PG_FATAL, "could not open file \"%s\": %s\n", output_path, getErrorText(errno));
+				pg_fatal("could not open file \"%s\": %s\n", output_path, getErrorText(errno));
 			if (!db_used)
 			{
 				fprintf(script, "\\connect %s\n\n",
-- 
1.8.4.rc3

-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to