On 02/02/2010 10:23 PM, Tom Lane wrote: > Joe Conway <[email protected]> writes: >> Should I also be looking to replace all (or most) other instances of >> PQsetdbLogin()? > > I think we at least wanted to fix pg_dump(all)/pg_restore. Not sure if > the others are worth troubling over.
OK, this one includes pg_dump(all)/pg_restore and common.c from bin/scripts (createdb, vacuumdb, etc). I still need to adjust the docs, but other than that any remaining complaints? Joe
Index: src/bin/pg_dump/pg_backup_db.c
===================================================================
RCS file: /opt/src/cvs/pgsql/src/bin/pg_dump/pg_backup_db.c,v
retrieving revision 1.85
diff -c -r1.85 pg_backup_db.c
*** src/bin/pg_dump/pg_backup_db.c 14 Dec 2009 00:39:11 -0000 1.85
--- src/bin/pg_dump/pg_backup_db.c 4 Feb 2010 03:57:42 -0000
***************
*** 154,163 ****
do
{
new_pass = false;
! newConn = PQsetdbLogin(PQhost(AH->connection), PQport(AH->connection),
! NULL, NULL, newdb,
! newuser, password);
if (!newConn)
die_horribly(AH, modulename, "failed to reconnect to database\n");
--- 154,187 ----
do
{
+ #define PARAMS_ARRAY_SIZE 7
+ const char **keywords = malloc(PARAMS_ARRAY_SIZE * sizeof(*keywords));
+ const char **values = malloc(PARAMS_ARRAY_SIZE * sizeof(*values));
+
+ if (!keywords || !values)
+ die_horribly(AH, modulename, "out of memory\n");
+
+ keywords[0] = "host";
+ values[0] = PQhost(AH->connection);
+ keywords[1] = "port";
+ values[1] = PQport(AH->connection);
+ keywords[2] = "user";
+ values[2] = newuser;
+ keywords[3] = "password";
+ values[3] = password;
+ keywords[4] = "dbname";
+ values[4] = newdb;
+ keywords[5] = "fallback_application_name";
+ values[5] = progname;
+ keywords[6] = NULL;
+ values[6] = NULL;
+
new_pass = false;
! newConn = PQconnectdbParams(keywords, values, true);
!
! free(keywords);
! free(values);
!
if (!newConn)
die_horribly(AH, modulename, "failed to reconnect to database\n");
***************
*** 237,245 ****
*/
do
{
new_pass = false;
! AH->connection = PQsetdbLogin(pghost, pgport, NULL, NULL,
! dbname, username, password);
if (!AH->connection)
die_horribly(AH, modulename, "failed to connect to database\n");
--- 261,293 ----
*/
do
{
+ #define PARAMS_ARRAY_SIZE 7
+ const char **keywords = malloc(PARAMS_ARRAY_SIZE * sizeof(*keywords));
+ const char **values = malloc(PARAMS_ARRAY_SIZE * sizeof(*values));
+
+ if (!keywords || !values)
+ die_horribly(AH, modulename, "out of memory\n");
+
+ 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);
!
! free(keywords);
! free(values);
if (!AH->connection)
die_horribly(AH, modulename, "failed to connect to database\n");
***************
*** 697,699 ****
--- 745,748 ----
else
return false;
}
+
Index: src/bin/pg_dump/pg_dumpall.c
===================================================================
RCS file: /opt/src/cvs/pgsql/src/bin/pg_dump/pg_dumpall.c,v
retrieving revision 1.131
diff -c -r1.131 pg_dumpall.c
*** src/bin/pg_dump/pg_dumpall.c 6 Jan 2010 03:34:41 -0000 1.131
--- src/bin/pg_dump/pg_dumpall.c 4 Feb 2010 03:55:45 -0000
***************
*** 1618,1625 ****
*/
do
{
new_pass = false;
! conn = PQsetdbLogin(pghost, pgport, NULL, NULL, dbname, pguser, password);
if (!conn)
{
--- 1618,1653 ----
*/
do
{
+ #define PARAMS_ARRAY_SIZE 7
+ const char **keywords = malloc(PARAMS_ARRAY_SIZE * sizeof(*keywords));
+ const char **values = malloc(PARAMS_ARRAY_SIZE * sizeof(*values));
+
+ if (!keywords || !values)
+ {
+ fprintf(stderr, _("%s: out of memory\n"), progname);
+ exit(1);
+ }
+
+ keywords[0] = "host";
+ values[0] = pghost;
+ keywords[1] = "port";
+ values[1] = pgport;
+ keywords[2] = "user";
+ values[2] = pguser;
+ 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;
! conn = PQconnectdbParams(keywords, values, true);
!
! free(keywords);
! free(values);
if (!conn)
{
Index: src/bin/psql/command.c
===================================================================
RCS file: /opt/src/cvs/pgsql/src/bin/psql/command.c,v
retrieving revision 1.213
diff -c -r1.213 command.c
*** src/bin/psql/command.c 2 Jan 2010 16:57:59 -0000 1.213
--- src/bin/psql/command.c 4 Feb 2010 01:18:34 -0000
***************
*** 1213,1219 ****
* Connects to a database with given parameters. If there exists an
* established connection, NULL values will be replaced with the ones
* in the current connection. Otherwise NULL will be passed for that
! * parameter to PQsetdbLogin(), so the libpq defaults will be used.
*
* In interactive mode, if connection fails with the given parameters,
* the old connection will be kept.
--- 1213,1219 ----
* Connects to a database with given parameters. If there exists an
* established connection, NULL values will be replaced with the ones
* in the current connection. Otherwise NULL will be passed for that
! * parameter to PQconnectdbParams(), so the libpq defaults will be used.
*
* In interactive mode, if connection fails with the given parameters,
* the old connection will be kept.
***************
*** 1255,1262 ****
while (true)
{
! n_conn = PQsetdbLogin(host, port, NULL, NULL,
! dbname, user, password);
/* We can immediately discard the password -- no longer needed */
if (password)
--- 1255,1283 ----
while (true)
{
! #define PARAMS_ARRAY_SIZE 7
! const char **keywords = pg_malloc(PARAMS_ARRAY_SIZE * sizeof(*keywords));
! const char **values = pg_malloc(PARAMS_ARRAY_SIZE * sizeof(*values));
!
! keywords[0] = "host";
! values[0] = host;
! keywords[1] = "port";
! values[1] = port;
! keywords[2] = "user";
! values[2] = user;
! keywords[3] = "password";
! values[3] = password;
! keywords[4] = "dbname";
! values[4] = dbname;
! keywords[5] = "fallback_application_name";
! values[5] = pset.progname;
! keywords[6] = NULL;
! values[6] = NULL;
!
! n_conn = PQconnectdbParams(keywords, values, true);
!
! free(keywords);
! free(values);
/* We can immediately discard the password -- no longer needed */
if (password)
Index: src/bin/psql/startup.c
===================================================================
RCS file: /opt/src/cvs/pgsql/src/bin/psql/startup.c,v
retrieving revision 1.159
diff -c -r1.159 startup.c
*** src/bin/psql/startup.c 28 Jan 2010 06:28:26 -0000 1.159
--- src/bin/psql/startup.c 4 Feb 2010 02:31:32 -0000
***************
*** 90,97 ****
char *password = NULL;
char *password_prompt = NULL;
bool new_pass;
- const char *keywords[] = {"host","port","dbname","user",
- "password","application_name",NULL};
set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("psql"));
--- 90,95 ----
***************
*** 173,192 ****
/* loop until we have a password if requested by backend */
do
{
! const char *values[] = {
! options.host,
! options.port,
! (options.action == ACT_LIST_DB &&
! options.dbname == NULL) ? "postgres" : options.dbname,
! options.username,
! password,
! pset.progname,
! NULL
! };
!
! new_pass = false;
!
! pset.db = PQconnectdbParams(keywords, values);
if (PQstatus(pset.db) == CONNECTION_BAD &&
PQconnectionNeedsPassword(pset.db) &&
--- 171,201 ----
/* loop until we have a password if requested by backend */
do
{
! #define PARAMS_ARRAY_SIZE 7
! const char **keywords = pg_malloc(PARAMS_ARRAY_SIZE * sizeof(*keywords));
! const char **values = pg_malloc(PARAMS_ARRAY_SIZE * sizeof(*values));
!
! keywords[0] = "host";
! values[0] = options.host;
! keywords[1] = "port";
! values[1] = options.port;
! keywords[2] = "user";
! values[2] = options.username;
! keywords[3] = "password";
! values[3] = password;
! keywords[4] = "dbname";
! values[4] = (options.action == ACT_LIST_DB &&
! options.dbname == NULL) ?
! "postgres" : options.dbname;
! keywords[5] = "fallback_application_name";
! values[5] = pset.progname;
! keywords[6] = NULL;
! values[6] = NULL;
!
! new_pass = false;
! pset.db = PQconnectdbParams(keywords, values, true);
! free(keywords);
! free(values);
if (PQstatus(pset.db) == CONNECTION_BAD &&
PQconnectionNeedsPassword(pset.db) &&
Index: src/bin/scripts/common.c
===================================================================
RCS file: /opt/src/cvs/pgsql/src/bin/scripts/common.c,v
retrieving revision 1.38
diff -c -r1.38 common.c
*** src/bin/scripts/common.c 2 Jan 2010 16:58:00 -0000 1.38
--- src/bin/scripts/common.c 4 Feb 2010 03:54:14 -0000
***************
*** 108,115 ****
*/
do
{
new_pass = false;
! conn = PQsetdbLogin(pghost, pgport, NULL, NULL, dbname, pguser, password);
if (!conn)
{
--- 108,143 ----
*/
do
{
+ #define PARAMS_ARRAY_SIZE 7
+ const char **keywords = malloc(PARAMS_ARRAY_SIZE * sizeof(*keywords));
+ const char **values = malloc(PARAMS_ARRAY_SIZE * sizeof(*values));
+
+ if (!keywords || !values)
+ {
+ fprintf(stderr, _("%s: out of memory\n"), progname);
+ exit(1);
+ }
+
+ keywords[0] = "host";
+ values[0] = pghost;
+ keywords[1] = "port";
+ values[1] = pgport;
+ keywords[2] = "user";
+ values[2] = pguser;
+ 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;
! conn = PQconnectdbParams(keywords, values, true);
!
! free(keywords);
! free(values);
if (!conn)
{
Index: src/interfaces/libpq/fe-connect.c
===================================================================
RCS file: /opt/src/cvs/pgsql/src/interfaces/libpq/fe-connect.c,v
retrieving revision 1.385
diff -c -r1.385 fe-connect.c
*** src/interfaces/libpq/fe-connect.c 28 Jan 2010 06:28:26 -0000 1.385
--- src/interfaces/libpq/fe-connect.c 3 Feb 2010 16:56:45 -0000
***************
*** 269,275 ****
PQExpBuffer errorMessage, bool use_defaults);
static PQconninfoOption *conninfo_array_parse(const char **keywords,
const char **values, PQExpBuffer errorMessage,
! bool use_defaults);
static char *conninfo_getval(PQconninfoOption *connOptions,
const char *keyword);
static void defaultNoticeReceiver(void *arg, const PGresult *res);
--- 269,275 ----
PQExpBuffer errorMessage, bool use_defaults);
static PQconninfoOption *conninfo_array_parse(const char **keywords,
const char **values, PQExpBuffer errorMessage,
! bool use_defaults, bool expand_dbname);
static char *conninfo_getval(PQconninfoOption *connOptions,
const char *keyword);
static void defaultNoticeReceiver(void *arg, const PGresult *res);
***************
*** 336,344 ****
* call succeeded.
*/
PGconn *
! PQconnectdbParams(const char **keywords, const char **values)
{
! PGconn *conn = PQconnectStartParams(keywords, values);
if (conn && conn->status != CONNECTION_BAD)
(void) connectDBComplete(conn);
--- 336,346 ----
* call succeeded.
*/
PGconn *
! PQconnectdbParams(const char **keywords,
! const char **values,
! bool expand_dbname)
{
! PGconn *conn = PQconnectStartParams(keywords, values, expand_dbname);
if (conn && conn->status != CONNECTION_BAD)
(void) connectDBComplete(conn);
***************
*** 400,406 ****
* See PQconnectPoll for more info.
*/
PGconn *
! PQconnectStartParams(const char **keywords, const char **values)
{
PGconn *conn;
PQconninfoOption *connOptions;
--- 402,410 ----
* See PQconnectPoll for more info.
*/
PGconn *
! PQconnectStartParams(const char **keywords,
! const char **values,
! bool expand_dbname)
{
PGconn *conn;
PQconninfoOption *connOptions;
***************
*** 416,422 ****
* Parse the conninfo arrays
*/
connOptions = conninfo_array_parse(keywords, values,
! &conn->errorMessage, true);
if (connOptions == NULL)
{
conn->status = CONNECTION_BAD;
--- 420,427 ----
* Parse the conninfo arrays
*/
connOptions = conninfo_array_parse(keywords, values,
! &conn->errorMessage,
! true, expand_dbname);
if (connOptions == NULL)
{
conn->status = CONNECTION_BAD;
***************
*** 3729,3744 ****
* left in errorMessage.
* Defaults are supplied (from a service file, environment variables, etc)
* for unspecified options, but only if use_defaults is TRUE.
*/
static PQconninfoOption *
conninfo_array_parse(const char **keywords, const char **values,
! PQExpBuffer errorMessage, bool use_defaults)
{
char *tmp;
PQconninfoOption *options;
PQconninfoOption *option;
int i = 0;
/* Make a working copy of PQconninfoOptions */
options = malloc(sizeof(PQconninfoOptions));
if (options == NULL)
--- 3734,3786 ----
* left in errorMessage.
* Defaults are supplied (from a service file, environment variables, etc)
* for unspecified options, but only if use_defaults is TRUE.
+ *
+ * If expand_dbname is TRUE, and the value passed for keyword "dbname"
+ * contains an "=", assume it is a conninfo string and process it,
+ * overriding any previously processed conflicting keywords. Subsequent
+ * keywords will take precedence, however.
*/
static PQconninfoOption *
conninfo_array_parse(const char **keywords, const char **values,
! PQExpBuffer errorMessage, bool use_defaults,
! bool expand_dbname)
{
char *tmp;
PQconninfoOption *options;
+ PQconninfoOption *str_options = NULL;
PQconninfoOption *option;
int i = 0;
+ /*
+ * If expand_dbname is true, check keyword "dbname"
+ * to see if val is actually a conninfo string
+ */
+ while(expand_dbname && keywords[i])
+ {
+ const char *pname = keywords[i];
+ const char *pvalue = values[i];
+
+ /* first find "dbname" if any */
+ if (strcmp(pname, "dbname") == 0)
+ {
+ /* next look for "=" in the value */
+ if (pvalue && strchr(pvalue, '='))
+ {
+ /*
+ * Must be a conninfo string, so parse it, but do not
+ * use defaults here -- those get picked up later.
+ * We only want to override for those parameters actually
+ * passed.
+ */
+ str_options = conninfo_parse(pvalue, errorMessage, false);
+ if (str_options == NULL)
+ return NULL;
+ }
+ break;
+ }
+ ++i;
+ }
+
/* Make a working copy of PQconninfoOptions */
options = malloc(sizeof(PQconninfoOptions));
if (options == NULL)
***************
*** 3749,3754 ****
--- 3791,3797 ----
}
memcpy(options, PQconninfoOptions, sizeof(PQconninfoOptions));
+ i = 0;
/* Parse the keywords/values arrays */
while(keywords[i])
{
***************
*** 3774,3792 ****
return NULL;
}
! /*
! * Store the value
! */
! if (option->val)
! free(option->val);
! option->val = strdup(pvalue);
! if (!option->val)
! {
! printfPQExpBuffer(errorMessage,
! libpq_gettext("out of memory\n"));
! PQconninfoFree(options);
! return NULL;
! }
}
++i;
}
--- 3817,3867 ----
return NULL;
}
! /*
! * If we are on the dbname parameter, and we have a parsed
! * conninfo string, copy those parameters across, overriding
! * any existing previous settings
! */
! if (strcmp(pname, "dbname") == 0 && str_options)
! {
! PQconninfoOption *str_option;
!
! for (str_option = str_options; str_option->keyword != NULL; str_option++)
! {
! if (str_option->val != NULL)
! {
! int k;
!
! for (k = 0; options[k].keyword; k++)
! {
! if (strcmp(options[k].keyword, str_option->keyword) == 0)
! {
! if (options[k].val)
! free(options[k].val);
! options[k].val = strdup(str_option->val);
! break;
! }
! }
! }
! }
! PQconninfoFree(str_options);
! }
! else
! {
! /*
! * Store the value, overriding previous settings
! */
! if (option->val)
! free(option->val);
! option->val = strdup(pvalue);
! if (!option->val)
! {
! printfPQExpBuffer(errorMessage,
! libpq_gettext("out of memory\n"));
! PQconninfoFree(options);
! return NULL;
! }
! }
}
++i;
}
Index: src/interfaces/libpq/libpq-fe.h
===================================================================
RCS file: /opt/src/cvs/pgsql/src/interfaces/libpq/libpq-fe.h,v
retrieving revision 1.150
diff -c -r1.150 libpq-fe.h
*** src/interfaces/libpq/libpq-fe.h 28 Jan 2010 06:28:26 -0000 1.150
--- src/interfaces/libpq/libpq-fe.h 4 Feb 2010 01:20:00 -0000
***************
*** 226,237 ****
/* make a new client connection to the backend */
/* Asynchronous (non-blocking) */
extern PGconn *PQconnectStart(const char *conninfo);
! extern PGconn *PQconnectStartParams(const char **keywords, const char **values);
extern PostgresPollingStatusType PQconnectPoll(PGconn *conn);
/* Synchronous (blocking) */
extern PGconn *PQconnectdb(const char *conninfo);
! extern PGconn *PQconnectdbParams(const char **keywords, const char **values);
extern PGconn *PQsetdbLogin(const char *pghost, const char *pgport,
const char *pgoptions, const char *pgtty,
const char *dbName,
--- 226,239 ----
/* make a new client connection to the backend */
/* Asynchronous (non-blocking) */
extern PGconn *PQconnectStart(const char *conninfo);
! extern PGconn *PQconnectStartParams(const char **keywords,
! const char **values, bool expand_dbname);
extern PostgresPollingStatusType PQconnectPoll(PGconn *conn);
/* Synchronous (blocking) */
extern PGconn *PQconnectdb(const char *conninfo);
! extern PGconn *PQconnectdbParams(const char **keywords,
! const char **values, bool expand_dbname);
extern PGconn *PQsetdbLogin(const char *pghost, const char *pgport,
const char *pgoptions, const char *pgtty,
const char *dbName,
signature.asc
Description: OpenPGP digital signature
