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');
signature.asc
Description: PGP signature
