aboutsummaryrefslogtreecommitdiff
path: root/src/interfaces/libpq/fe-connect.c
diff options
context:
space:
mode:
authorJoe Conway <mail@joeconway.com>2010-02-05 03:09:05 +0000
committerJoe Conway <mail@joeconway.com>2010-02-05 03:09:05 +0000
commitf419a82c704ec33fe5b861f914935b233a54bcee (patch)
tree4c32bd4b142b4c76d6fa17e403eaa189df835e7b /src/interfaces/libpq/fe-connect.c
parenta141ec13de1b2ee4ff7ec1e6b0da03ce7eb7dbbb (diff)
downloadpostgresql-f419a82c704ec33fe5b861f914935b233a54bcee.tar.gz
postgresql-f419a82c704ec33fe5b861f914935b233a54bcee.zip
Modify recently added PQconnectdbParams() with new argument, expand_dbname.
If expand_dbname is non-zero and dbname contains an = sign, it is taken as a conninfo string in exactly the same way as if it had been passed to PQconnectdb. This is equivalent to the way PQsetdbLogin() works, allowing PQconnectdbParams() to be a complete alternative. Also improve the way the new function is called from psql and replace a previously missed call to PQsetdbLogin() in psql. Additionally use PQconnectdbParams() for pg_dump and friends, and the bin/scripts command line utilities such as vacuumdb, createdb, etc. Finally, update the documentation for the new parameter, as well as the nuances of precedence in cases where key words are repeated or duplicated in the conninfo string.
Diffstat (limited to 'src/interfaces/libpq/fe-connect.c')
-rw-r--r--src/interfaces/libpq/fe-connect.c115
1 files changed, 95 insertions, 20 deletions
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index 048c438527b..994b70b1904 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/interfaces/libpq/fe-connect.c,v 1.385 2010/01/28 06:28:26 joe Exp $
+ * $PostgreSQL: pgsql/src/interfaces/libpq/fe-connect.c,v 1.386 2010/02/05 03:09:05 joe Exp $
*
*-------------------------------------------------------------------------
*/
@@ -269,7 +269,7 @@ static PQconninfoOption *conninfo_parse(const char *conninfo,
PQExpBuffer errorMessage, bool use_defaults);
static PQconninfoOption *conninfo_array_parse(const char **keywords,
const char **values, PQExpBuffer errorMessage,
- bool use_defaults);
+ bool use_defaults, int expand_dbname);
static char *conninfo_getval(PQconninfoOption *connOptions,
const char *keyword);
static void defaultNoticeReceiver(void *arg, const PGresult *res);
@@ -336,9 +336,11 @@ pgthreadlock_t pg_g_threadlock = default_threadlock;
* call succeeded.
*/
PGconn *
-PQconnectdbParams(const char **keywords, const char **values)
+PQconnectdbParams(const char **keywords,
+ const char **values,
+ int expand_dbname)
{
- PGconn *conn = PQconnectStartParams(keywords, values);
+ PGconn *conn = PQconnectStartParams(keywords, values, expand_dbname);
if (conn && conn->status != CONNECTION_BAD)
(void) connectDBComplete(conn);
@@ -400,7 +402,9 @@ PQconnectdb(const char *conninfo)
* See PQconnectPoll for more info.
*/
PGconn *
-PQconnectStartParams(const char **keywords, const char **values)
+PQconnectStartParams(const char **keywords,
+ const char **values,
+ int expand_dbname)
{
PGconn *conn;
PQconninfoOption *connOptions;
@@ -416,7 +420,8 @@ PQconnectStartParams(const char **keywords, const char **values)
* Parse the conninfo arrays
*/
connOptions = conninfo_array_parse(keywords, values,
- &conn->errorMessage, true);
+ &conn->errorMessage,
+ true, expand_dbname);
if (connOptions == NULL)
{
conn->status = CONNECTION_BAD;
@@ -3729,16 +3734,53 @@ conninfo_parse(const char *conninfo, PQExpBuffer errorMessage,
* 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 non-zero, 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)
+ PQExpBuffer errorMessage, bool use_defaults,
+ int expand_dbname)
{
char *tmp;
PQconninfoOption *options;
+ PQconninfoOption *str_options = NULL;
PQconninfoOption *option;
int i = 0;
+ /*
+ * If expand_dbname is non-zero, 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,6 +3791,7 @@ conninfo_array_parse(const char **keywords, const char **values,
}
memcpy(options, PQconninfoOptions, sizeof(PQconninfoOptions));
+ i = 0;
/* Parse the keywords/values arrays */
while(keywords[i])
{
@@ -3774,22 +3817,54 @@ conninfo_array_parse(const char **keywords, const char **values,
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;
- }
+ /*
+ * 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;
+ }
+ }
+ }
+ }
+ }
+ 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;
}
+ PQconninfoFree(str_options);
/*
* Stop here if caller doesn't want defaults filled in.