On Thu, Mar 28, 2013 at 03:06:30PM -0400, Steve Singer wrote:
> So to summarise:
>
> Plan A: The first patch I attached for pg_upgrade + documentation
> changes, and changing the other places that call PQconndefaults() to
> accept failures on either out of memory, or an invalid PGSERVICE
>
> Plan B: Create a new function PQconndefaults2(char * errorBuffer) or
> something similar that returned error information to the caller.
>
> Plan C: PQconndefaults() just ignores an invalid service but
> connection attempts fail because other callers of
> conninfo_add_defaults still pay attention to connection failures.
> This is the second patch I sent.
>
> Plan D: Service lookup failures are always ignored by
> conninfo_add_defaults. If you attempt to connect with a bad
> PGSERVICE set it will behave as if no PGSERVICE value was set. I
> don't think anyone explicitly proposed this yet.
>
> Plan 'D' is the only option that I'm opposed to, it will effect a
> lot more applications then ones that call PQconndefaults() and I
> feel it will confuse users.
>
> I'm not convinced plan B is worth the effort of having to maintain
> two versions of PQconndefaults() for a while to fix a corner case.
OK, I am back to looking at this issue from March. I went with option
C, patch attached, which seems to be the most popular. It is similar to
Steve's patch, but structured differently and includes a doc patch.
--
Bruce Momjian <[email protected]> http://momjian.us
EnterpriseDB http://enterprisedb.com
+ Everyone has their own god. +
diff --git a/contrib/pg_upgrade/server.c b/contrib/pg_upgrade/server.c
new file mode 100644
index b75f553..7d2aa35
*** a/contrib/pg_upgrade/server.c
--- b/contrib/pg_upgrade/server.c
*************** check_pghost_envvar(void)
*** 325,330 ****
--- 325,333 ----
start = PQconndefaults();
+ if (!start)
+ pg_fatal("out of memory\n");
+
for (option = start; option->keyword != NULL; option++)
{
if (option->envvar && (strcmp(option->envvar, "PGHOST") == 0 ||
diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
new file mode 100644
index 955f248..503a63a
*** a/doc/src/sgml/libpq.sgml
--- b/doc/src/sgml/libpq.sgml
*************** typedef struct
*** 483,489 ****
with an entry having a null <structfield>keyword</> pointer. The
null pointer is returned if memory could not be allocated. Note that
the current default values (<structfield>val</structfield> fields)
! will depend on environment variables and other context. Callers
must treat the connection options data as read-only.
</para>
--- 483,490 ----
with an entry having a null <structfield>keyword</> pointer. The
null pointer is returned if memory could not be allocated. Note that
the current default values (<structfield>val</structfield> fields)
! will depend on environment variables and other context. A
! missing or invalid service file will be silently ignored. Callers
must treat the connection options data as read-only.
</para>
diff --git a/src/interfaces/libpq/fe-auth.c b/src/interfaces/libpq/fe-auth.c
new file mode 100644
index 975f795..9797140
*** a/src/interfaces/libpq/fe-auth.c
--- b/src/interfaces/libpq/fe-auth.c
*************** pg_fe_sendauth(AuthRequest areq, PGconn
*** 982,988 ****
* if there is an error, return NULL with an error message in errorMessage
*/
char *
! pg_fe_getauthname(PQExpBuffer errorMessage)
{
const char *name = NULL;
char *authn;
--- 982,988 ----
* if there is an error, return NULL with an error message in errorMessage
*/
char *
! pg_fe_getauthname(void)
{
const char *name = NULL;
char *authn;
diff --git a/src/interfaces/libpq/fe-auth.h b/src/interfaces/libpq/fe-auth.h
new file mode 100644
index bfddc68..25440b0
*** a/src/interfaces/libpq/fe-auth.h
--- b/src/interfaces/libpq/fe-auth.h
***************
*** 19,24 ****
extern int pg_fe_sendauth(AuthRequest areq, PGconn *conn);
! extern char *pg_fe_getauthname(PQExpBuffer errorMessage);
#endif /* FE_AUTH_H */
--- 19,24 ----
extern int pg_fe_sendauth(AuthRequest areq, PGconn *conn);
! extern char *pg_fe_getauthname(void);
#endif /* FE_AUTH_H */
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
new file mode 100644
index 8dd1a59..7ab4a9a
*** a/src/interfaces/libpq/fe-connect.c
--- b/src/interfaces/libpq/fe-connect.c
*************** PQconndefaults(void)
*** 875,881 ****
connOptions = conninfo_init(&errorBuf);
if (connOptions != NULL)
{
! if (!conninfo_add_defaults(connOptions, &errorBuf))
{
PQconninfoFree(connOptions);
connOptions = NULL;
--- 875,882 ----
connOptions = conninfo_init(&errorBuf);
if (connOptions != NULL)
{
! /* pass NULL errorBuf to ignore errors */
! if (!conninfo_add_defaults(connOptions, NULL))
{
PQconninfoFree(connOptions);
connOptions = NULL;
*************** conninfo_array_parse(const char *const *
*** 4412,4420 ****
*
* Defaults are obtained from a service file, environment variables, etc.
*
! * Returns TRUE if successful, otherwise FALSE; errorMessage is filled in
! * upon failure. Note that failure to locate a default value is not an
! * error condition here --- we just leave the option's value as NULL.
*/
static bool
conninfo_add_defaults(PQconninfoOption *options, PQExpBuffer errorMessage)
--- 4413,4422 ----
*
* Defaults are obtained from a service file, environment variables, etc.
*
! * Returns TRUE if successful, otherwise FALSE; errorMessage, if supplied,
! * is filled in upon failure. Note that failure to locate a default value
! * is not an error condition here --- we just leave the option's value as
! * NULL.
*/
static bool
conninfo_add_defaults(PQconninfoOption *options, PQExpBuffer errorMessage)
*************** conninfo_add_defaults(PQconninfoOption *
*** 4424,4432 ****
/*
* If there's a service spec, use it to obtain any not-explicitly-given
! * parameters.
*/
! if (parseServiceInfo(options, errorMessage) != 0)
return false;
/*
--- 4426,4435 ----
/*
* If there's a service spec, use it to obtain any not-explicitly-given
! * parameters. Ignore error if no error message buffer is passed
! * because there is no way to pass back the failure message.
*/
! if (parseServiceInfo(options, errorMessage) != 0 && errorMessage)
return false;
/*
*************** conninfo_add_defaults(PQconninfoOption *
*** 4448,4455 ****
option->val = strdup(tmp);
if (!option->val)
{
! printfPQExpBuffer(errorMessage,
! libpq_gettext("out of memory\n"));
return false;
}
continue;
--- 4451,4459 ----
option->val = strdup(tmp);
if (!option->val)
{
! if (errorMessage)
! printfPQExpBuffer(errorMessage,
! libpq_gettext("out of memory\n"));
return false;
}
continue;
*************** conninfo_add_defaults(PQconninfoOption *
*** 4465,4472 ****
option->val = strdup(option->compiled);
if (!option->val)
{
! printfPQExpBuffer(errorMessage,
! libpq_gettext("out of memory\n"));
return false;
}
continue;
--- 4469,4477 ----
option->val = strdup(option->compiled);
if (!option->val)
{
! if (errorMessage)
! printfPQExpBuffer(errorMessage,
! libpq_gettext("out of memory\n"));
return false;
}
continue;
*************** conninfo_add_defaults(PQconninfoOption *
*** 4477,4483 ****
*/
if (strcmp(option->keyword, "user") == 0)
{
! option->val = pg_fe_getauthname(errorMessage);
continue;
}
}
--- 4482,4488 ----
*/
if (strcmp(option->keyword, "user") == 0)
{
! option->val = pg_fe_getauthname();
continue;
}
}
--
Sent via pgsql-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers