On Wed, Sep 25, 2019 at 05:47:39PM -0300, Alvaro Herrera wrote:
> This patch has been absolutely overlooked by reviewers.  Euler, you're
> registered as a reviewer for it.  Will you submit a review soon?  :-)
> 
> It does not currently apply, so if we get a rebase, that'd be good too.

Here you go.  There were four conflicts in total caused by the switch
to the central logging infra for vacuumlo/oid2name and the
introduction of recovery_gen.c.  No actual changes except the rebase.
--
Michael
diff --git a/contrib/oid2name/Makefile b/contrib/oid2name/Makefile
index 361a80a7a1..c6ba092f47 100644
--- a/contrib/oid2name/Makefile
+++ b/contrib/oid2name/Makefile
@@ -9,7 +9,7 @@ OBJS	= oid2name.o $(WIN32RES)
 TAP_TESTS = 1
 
 PG_CPPFLAGS = -I$(libpq_srcdir)
-PG_LIBS_INTERNAL = $(libpq_pgport)
+PG_LIBS_INTERNAL = $(libpq_pgport) -L$(top_builddir)/src/fe_utils -lpgfeutils
 
 ifdef USE_PGXS
 PG_CONFIG = pg_config
diff --git a/contrib/oid2name/oid2name.c b/contrib/oid2name/oid2name.c
index fa1e7959e7..362f95165d 100644
--- a/contrib/oid2name/oid2name.c
+++ b/contrib/oid2name/oid2name.c
@@ -47,6 +47,8 @@ struct options
 	const char *progname;
 };
 
+const char *progname;
+
 /* function prototypes */
 static void help(const char *progname);
 void		get_opts(int, char **, struct options *);
@@ -83,7 +85,6 @@ get_opts(int argc, char **argv, struct options *my_opts)
 	};
 
 	int			c;
-	const char *progname;
 	int			optindex;
 
 	pg_logging_init(argv[0]);
@@ -294,65 +295,20 @@ PGconn *
 sql_conn(struct options *my_opts)
 {
 	PGconn	   *conn;
-	bool		have_password = false;
-	char		password[100];
-	bool		new_pass;
 	PGresult   *res;
 
-	/*
-	 * Start the connection.  Loop until we have a password if requested by
-	 * backend.
-	 */
-	do
+	/* grab a connection, with password prompting */
+	conn = connect_with_password_prompt(my_opts->hostname,
+										my_opts->port,
+										my_opts->username,
+										my_opts->dbname,
+										my_opts->progname,
+										NULL,
+										true);
+	if (conn == NULL)
 	{
-#define PARAMS_ARRAY_SIZE	7
-
-		const char *keywords[PARAMS_ARRAY_SIZE];
-		const char *values[PARAMS_ARRAY_SIZE];
-
-		keywords[0] = "host";
-		values[0] = my_opts->hostname;
-		keywords[1] = "port";
-		values[1] = my_opts->port;
-		keywords[2] = "user";
-		values[2] = my_opts->username;
-		keywords[3] = "password";
-		values[3] = have_password ? password : NULL;
-		keywords[4] = "dbname";
-		values[4] = my_opts->dbname;
-		keywords[5] = "fallback_application_name";
-		values[5] = my_opts->progname;
-		keywords[6] = NULL;
-		values[6] = NULL;
-
-		new_pass = false;
-		conn = PQconnectdbParams(keywords, values, true);
-
-		if (!conn)
-		{
-			pg_log_error("could not connect to database %s",
-						 my_opts->dbname);
-			exit(1);
-		}
-
-		if (PQstatus(conn) == CONNECTION_BAD &&
-			PQconnectionNeedsPassword(conn) &&
-			!have_password)
-		{
-			PQfinish(conn);
-			simple_prompt("Password: ", password, sizeof(password), false);
-			have_password = true;
-			new_pass = true;
-		}
-	} while (new_pass);
-
-	/* check to see that the backend connection was successfully made */
-	if (PQstatus(conn) == CONNECTION_BAD)
-	{
-		pg_log_error("could not connect to database %s: %s",
-					 my_opts->dbname, PQerrorMessage(conn));
-		PQfinish(conn);
-		exit(1);
+		/* an error has been generated */
+		exit(-1);
 	}
 
 	res = PQexec(conn, ALWAYS_SECURE_SEARCH_PATH_SQL);
diff --git a/contrib/vacuumlo/Makefile b/contrib/vacuumlo/Makefile
index 3efcb46735..2515f61824 100644
--- a/contrib/vacuumlo/Makefile
+++ b/contrib/vacuumlo/Makefile
@@ -9,7 +9,7 @@ OBJS	= vacuumlo.o $(WIN32RES)
 TAP_TESTS = 1
 
 PG_CPPFLAGS = -I$(libpq_srcdir)
-PG_LIBS_INTERNAL = $(libpq_pgport)
+PG_LIBS_INTERNAL = $(libpq_pgport) -L$(top_builddir)/src/fe_utils -lpgfeutils
 
 ifdef USE_PGXS
 PG_CONFIG = pg_config
diff --git a/contrib/vacuumlo/vacuumlo.c b/contrib/vacuumlo/vacuumlo.c
index 533e2ce33c..900b58c5f4 100644
--- a/contrib/vacuumlo/vacuumlo.c
+++ b/contrib/vacuumlo/vacuumlo.c
@@ -50,6 +50,8 @@ struct _param
 	long		transaction_limit;
 };
 
+const char *progname;
+
 static int	vacuumlo(const char *database, const struct _param *param);
 static void usage(const char *progname);
 
@@ -68,7 +70,6 @@ vacuumlo(const char *database, const struct _param *param)
 	long		matched;
 	long		deleted;
 	int			i;
-	bool		new_pass;
 	bool		success = true;
 	static bool have_password = false;
 	static char password[100];
@@ -80,58 +81,17 @@ vacuumlo(const char *database, const struct _param *param)
 		have_password = true;
 	}
 
-	/*
-	 * Start the connection.  Loop until we have a password if requested by
-	 * backend.
-	 */
-	do
+	/* grab a connection, depending on password prompting */
+	conn = connect_with_password_prompt(param->pg_host,
+										param->pg_port,
+										param->pg_user,
+										database,
+										progname,
+										password,
+										param->pg_prompt != TRI_NO);
+	if (conn == NULL)
 	{
-#define PARAMS_ARRAY_SIZE	   7
-
-		const char *keywords[PARAMS_ARRAY_SIZE];
-		const char *values[PARAMS_ARRAY_SIZE];
-
-		keywords[0] = "host";
-		values[0] = param->pg_host;
-		keywords[1] = "port";
-		values[1] = param->pg_port;
-		keywords[2] = "user";
-		values[2] = param->pg_user;
-		keywords[3] = "password";
-		values[3] = have_password ? password : NULL;
-		keywords[4] = "dbname";
-		values[4] = database;
-		keywords[5] = "fallback_application_name";
-		values[5] = param->progname;
-		keywords[6] = NULL;
-		values[6] = NULL;
-
-		new_pass = false;
-		conn = PQconnectdbParams(keywords, values, true);
-		if (!conn)
-		{
-			pg_log_error("connection to database \"%s\" failed", database);
-			return -1;
-		}
-
-		if (PQstatus(conn) == CONNECTION_BAD &&
-			PQconnectionNeedsPassword(conn) &&
-			!have_password &&
-			param->pg_prompt != TRI_NO)
-		{
-			PQfinish(conn);
-			simple_prompt("Password: ", password, sizeof(password), false);
-			have_password = true;
-			new_pass = true;
-		}
-	} while (new_pass);
-
-	/* check to see that the backend connection was successfully made */
-	if (PQstatus(conn) == CONNECTION_BAD)
-	{
-		pg_log_error("connection to database \"%s\" failed: %s",
-					 database, PQerrorMessage(conn));
-		PQfinish(conn);
+		/* an error has been generated */
 		return -1;
 	}
 
@@ -462,7 +422,6 @@ main(int argc, char **argv)
 	struct _param param;
 	int			c;
 	int			port;
-	const char *progname;
 	int			optindex;
 
 	pg_logging_init(argv[0]);
diff --git a/src/bin/pg_dump/pg_backup_db.c b/src/bin/pg_dump/pg_backup_db.c
index ee822c5249..20a849a8d2 100644
--- a/src/bin/pg_dump/pg_backup_db.c
+++ b/src/bin/pg_dump/pg_backup_db.c
@@ -245,7 +245,6 @@ ConnectDatabase(Archive *AHX,
 	ArchiveHandle *AH = (ArchiveHandle *) AHX;
 	char	   *password;
 	char		passbuf[100];
-	bool		new_pass;
 
 	if (AH->connection)
 		fatal("already connected to a database");
@@ -259,53 +258,18 @@ ConnectDatabase(Archive *AHX,
 	}
 	AH->promptPassword = prompt_password;
 
-	/*
-	 * Start the connection.  Loop until we have a password if requested by
-	 * backend.
-	 */
-	do
+	AH->connection = connect_with_password_prompt(pghost,
+												  pgport,
+												  username,
+												  dbname,
+												  progname,
+												  password,
+												  prompt_password != TRI_NO);
+	if (AH->connection == NULL)
 	{
-		const char *keywords[7];
-		const char *values[7];
-
-		keywords[0] = "host";
-		values[0] = pghost;
-		keywords[1] = "port";
-		values[1] = pgport;
-		keywords[2] = "user";
-		values[2] = username;
-		keywords[3] = "password";
-		values[3] = password;
-		keywords[4] = "dbname";
-		values[4] = dbname;
-		keywords[5] = "fallback_application_name";
-		values[5] = progname;
-		keywords[6] = NULL;
-		values[6] = NULL;
-
-		new_pass = false;
-		AH->connection = PQconnectdbParams(keywords, values, true);
-
-		if (!AH->connection)
-			fatal("could not connect to database");
-
-		if (PQstatus(AH->connection) == CONNECTION_BAD &&
-			PQconnectionNeedsPassword(AH->connection) &&
-			password == NULL &&
-			prompt_password != TRI_NO)
-		{
-			PQfinish(AH->connection);
-			simple_prompt("Password: ", passbuf, sizeof(passbuf), false);
-			password = passbuf;
-			new_pass = true;
-		}
-	} while (new_pass);
-
-	/* check to see that the backend connection was successfully made */
-	if (PQstatus(AH->connection) == CONNECTION_BAD)
-		fatal("connection to database \"%s\" failed: %s",
-			  PQdb(AH->connection) ? PQdb(AH->connection) : "",
-			  PQerrorMessage(AH->connection));
+		/* an error has been generated */
+		exit_nicely(1);
+	}
 
 	/* Start strict; later phases may override this. */
 	PQclear(ExecuteSqlQueryForSingleRow((Archive *) AH,
diff --git a/src/bin/pg_dump/t/002_pg_dump.pl b/src/bin/pg_dump/t/002_pg_dump.pl
index 4712e3a958..c932219a56 100644
--- a/src/bin/pg_dump/t/002_pg_dump.pl
+++ b/src/bin/pg_dump/t/002_pg_dump.pl
@@ -3422,7 +3422,7 @@ foreach my $db (sort keys %create_sql)
 
 command_fails_like(
 	[ 'pg_dump', '-p', "$port", 'qqq' ],
-	qr/\Qpg_dump: error: connection to database "qqq" failed: FATAL:  database "qqq" does not exist\E/,
+	qr/\Qpg_dump: error: could not connect to database "qqq": FATAL:  database "qqq" does not exist\E/,
 	'connecting to a non-existent database');
 
 #########################################
diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c
index ed7652bfbf..0c5512b240 100644
--- a/src/bin/pgbench/pgbench.c
+++ b/src/bin/pgbench/pgbench.c
@@ -35,6 +35,7 @@
 #include "common/int.h"
 #include "common/logging.h"
 #include "fe_utils/conditional.h"
+#include "fe_utils/connect.h"
 #include "getopt_long.h"
 #include "libpq-fe.h"
 #include "portability/instr_time.h"
@@ -1151,67 +1152,15 @@ static PGconn *
 doConnect(void)
 {
 	PGconn	   *conn;
-	bool		new_pass;
-	static bool have_password = false;
-	static char password[100];
-
-	/*
-	 * Start the connection.  Loop until we have a password if requested by
-	 * backend.
-	 */
-	do
-	{
-#define PARAMS_ARRAY_SIZE	7
-
-		const char *keywords[PARAMS_ARRAY_SIZE];
-		const char *values[PARAMS_ARRAY_SIZE];
-
-		keywords[0] = "host";
-		values[0] = pghost;
-		keywords[1] = "port";
-		values[1] = pgport;
-		keywords[2] = "user";
-		values[2] = login;
-		keywords[3] = "password";
-		values[3] = have_password ? password : NULL;
-		keywords[4] = "dbname";
-		values[4] = dbName;
-		keywords[5] = "fallback_application_name";
-		values[5] = progname;
-		keywords[6] = NULL;
-		values[6] = NULL;
-
-		new_pass = false;
-
-		conn = PQconnectdbParams(keywords, values, true);
-
-		if (!conn)
-		{
-			fprintf(stderr, "connection to database \"%s\" failed\n",
-					dbName);
-			return NULL;
-		}
-
-		if (PQstatus(conn) == CONNECTION_BAD &&
-			PQconnectionNeedsPassword(conn) &&
-			!have_password)
-		{
-			PQfinish(conn);
-			simple_prompt("Password: ", password, sizeof(password), false);
-			have_password = true;
-			new_pass = true;
-		}
-	} while (new_pass);
-
-	/* check to see that the backend connection was successfully made */
-	if (PQstatus(conn) == CONNECTION_BAD)
-	{
-		fprintf(stderr, "connection to database \"%s\" failed:\n%s",
-				dbName, PQerrorMessage(conn));
-		PQfinish(conn);
-		return NULL;
-	}
 
+	/* Connect to database, with optional password prompting */
+	conn = connect_with_password_prompt(pghost,
+										pgport,
+										login,
+										dbName,
+										progname,
+										NULL,
+										true);
 	return conn;
 }
 
diff --git a/src/bin/pgbench/t/001_pgbench_with_server.pl b/src/bin/pgbench/t/001_pgbench_with_server.pl
index b82d3f65c4..8357903aa3 100644
--- a/src/bin/pgbench/t/001_pgbench_with_server.pl
+++ b/src/bin/pgbench/t/001_pgbench_with_server.pl
@@ -78,7 +78,7 @@ pgbench(
 	1,
 	[qr{^$}],
 	[
-		qr{connection to database "no-such-database" failed},
+		qr{could not connect to database "no-such-database"},
 		qr{FATAL:  database "no-such-database" does not exist}
 	],
 	'no such database');
diff --git a/src/bin/scripts/common.c b/src/bin/scripts/common.c
index 1b38a1da49..aed0af740d 100644
--- a/src/bin/scripts/common.c
+++ b/src/bin/scripts/common.c
@@ -74,7 +74,6 @@ connectDatabase(const char *dbname, const char *pghost,
 				bool echo, bool fail_ok, bool allow_password_reuse)
 {
 	PGconn	   *conn;
-	bool		new_pass;
 	static bool have_password = false;
 	static char password[100];
 
@@ -87,64 +86,19 @@ connectDatabase(const char *dbname, const char *pghost,
 		have_password = true;
 	}
 
-	/*
-	 * Start the connection.  Loop until we have a password if requested by
-	 * backend.
-	 */
-	do
-	{
-		const char *keywords[7];
-		const char *values[7];
-
-		keywords[0] = "host";
-		values[0] = pghost;
-		keywords[1] = "port";
-		values[1] = pgport;
-		keywords[2] = "user";
-		values[2] = pguser;
-		keywords[3] = "password";
-		values[3] = have_password ? password : NULL;
-		keywords[4] = "dbname";
-		values[4] = dbname;
-		keywords[5] = "fallback_application_name";
-		values[5] = progname;
-		keywords[6] = NULL;
-		values[6] = NULL;
-
-		new_pass = false;
-		conn = PQconnectdbParams(keywords, values, true);
-
-		if (!conn)
-		{
-			pg_log_error("could not connect to database %s: out of memory",
-						 dbname);
-			exit(1);
-		}
-
-		/*
-		 * No luck?  Trying asking (again) for a password.
-		 */
-		if (PQstatus(conn) == CONNECTION_BAD &&
-			PQconnectionNeedsPassword(conn) &&
-			prompt_password != TRI_NO)
-		{
-			PQfinish(conn);
-			simple_prompt("Password: ", password, sizeof(password), false);
-			have_password = true;
-			new_pass = true;
-		}
-	} while (new_pass);
-
-	/* check to see that the backend connection was successfully made */
-	if (PQstatus(conn) == CONNECTION_BAD)
+	/* grab a connection, with password prompting */
+	conn = connect_with_password_prompt(pghost,
+										pgport,
+										pguser,
+										dbname,
+										progname,
+										password,
+										prompt_password != TRI_NO);
+	if (conn == NULL)
 	{
+		/* an error has been generated */
 		if (fail_ok)
-		{
-			PQfinish(conn);
 			return NULL;
-		}
-		pg_log_error("could not connect to database %s: %s",
-					 dbname, PQerrorMessage(conn));
 		exit(1);
 	}
 
diff --git a/src/fe_utils/Makefile b/src/fe_utils/Makefile
index f2e516a2aa..59c028b400 100644
--- a/src/fe_utils/Makefile
+++ b/src/fe_utils/Makefile
@@ -19,7 +19,7 @@ include $(top_builddir)/src/Makefile.global
 
 override CPPFLAGS := -DFRONTEND -I$(libpq_srcdir) $(CPPFLAGS)
 
-OBJS = conditional.o mbprint.o print.o psqlscan.o recovery_gen.o \
+OBJS = conditional.o connect.o mbprint.o print.o psqlscan.o recovery_gen.o \
        simple_list.o string_utils.o
 
 all: libpgfeutils.a
diff --git a/src/fe_utils/connect.c b/src/fe_utils/connect.c
new file mode 100644
index 0000000000..cae69f1f9a
--- /dev/null
+++ b/src/fe_utils/connect.c
@@ -0,0 +1,112 @@
+/*-------------------------------------------------------------------------
+ *
+ * Utility functions to connect to a backend.
+ *
+ *
+ * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/fe_utils/connect.c
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#include "postgres_fe.h"
+
+#include "common/logging.h"
+#include "fe_utils/connect.h"
+
+#include "libpq-fe.h"
+
+/*
+ * connect_with_password_prompt
+ *
+ * Connect to a PostgreSQL backend with the given set of connection
+ * parameters, optionally asking for password prompting.
+ *
+ * The caller can optionally pass a password with "saved_password"
+ * which will be used at the first connection attempt.
+ *
+ * The result is the connection to the backend.  On error, the result
+ * is NULL and an error is logged.
+ */
+PGconn *
+connect_with_password_prompt(const char *hostname,
+							 const char *port,
+							 const char *username,
+							 const char *dbname,
+							 const char *progname,
+							 char *saved_password,
+							 bool enable_prompt)
+{
+	PGconn     *conn;
+	bool        new_pass;
+	static bool have_password = false;
+	static char password[100];
+
+	if (saved_password != NULL)
+	{
+		/* XXX: need to be more careful with overflows here */
+		memcpy(password, saved_password, strlen(saved_password) + 1);
+		have_password = true;
+	}
+
+	/*
+	 * Start the connection.  Loop until we have a password if requested by
+	 * backend.
+	 */
+	do
+	{
+#define PARAMS_ARRAY_SIZE	7
+
+		const char *keywords[PARAMS_ARRAY_SIZE];
+		const char *values[PARAMS_ARRAY_SIZE];
+
+		keywords[0] = "host";
+		values[0] = hostname;
+		keywords[1] = "port";
+		values[1] = port;
+		keywords[2] = "user";
+		values[2] = username;
+		keywords[3] = "password";
+		values[3] = have_password ? password : NULL;
+		keywords[4] = "dbname";
+		values[4] = dbname;
+		keywords[5] = "fallback_application_name";
+		values[5] = progname;
+		keywords[6] = NULL;
+		values[6] = NULL;
+
+		new_pass = false;
+		conn = PQconnectdbParams(keywords, values, true);
+
+		if (!conn)
+		{
+			pg_log_error("could not connect to database \"%s\"",
+						 dbname);
+			return NULL;
+		}
+
+		if (PQstatus(conn) == CONNECTION_BAD &&
+			PQconnectionNeedsPassword(conn) &&
+			!have_password &&
+			enable_prompt)
+		{
+			PQfinish(conn);
+			simple_prompt("Password: ", password, sizeof(password), false);
+			have_password = true;
+			new_pass = true;
+		}
+	} while (new_pass);
+
+	/* check to see that the backend connection was successfully made */
+	if (PQstatus(conn) == CONNECTION_BAD)
+	{
+		pg_log_error("could not connect to database \"%s\": %s",
+					 dbname, PQerrorMessage(conn));
+		PQfinish(conn);
+		return NULL;
+	}
+
+	return conn;
+}
diff --git a/src/include/fe_utils/connect.h b/src/include/fe_utils/connect.h
index c1c8c04ab0..fef5d1a1b6 100644
--- a/src/include/fe_utils/connect.h
+++ b/src/include/fe_utils/connect.h
@@ -13,6 +13,8 @@
 #ifndef CONNECT_H
 #define CONNECT_H
 
+#include "libpq-fe.h"
+
 /*
  * This SQL statement installs an always-secure search path, so malicious
  * users can't take control.  CREATE of an unqualified name will fail, because
@@ -25,4 +27,12 @@
 #define ALWAYS_SECURE_SEARCH_PATH_SQL \
 	"SELECT pg_catalog.set_config('search_path', '', false);"
 
+extern PGconn * connect_with_password_prompt(const char *hostname,
+							 const char *port,
+							 const char *username,
+							 const char *dbname,
+							 const char *progname,
+							 char *saved_password,
+							 bool enable_prompt);
+
 #endif							/* CONNECT_H */
diff --git a/src/tools/msvc/Mkvcbuild.pm b/src/tools/msvc/Mkvcbuild.pm
index 7a103e6140..367bdeeb26 100644
--- a/src/tools/msvc/Mkvcbuild.pm
+++ b/src/tools/msvc/Mkvcbuild.pm
@@ -142,7 +142,7 @@ sub mkvcbuild
 	our @pgcommonbkndfiles = @pgcommonallfiles;
 
 	our @pgfeutilsfiles = qw(
-	  conditional.c mbprint.c print.c psqlscan.l psqlscan.c
+	  conditional.c connect.c mbprint.c print.c psqlscan.l psqlscan.c
 	  simple_list.c string_utils.c recovery_gen.c);
 
 	$libpgport = $solution->AddProject('libpgport', 'lib', 'misc');

Attachment: signature.asc
Description: PGP signature

Reply via email to