On Tue, Mar 19, 2013 at 10:12:21AM -0400, Steve Singer wrote:
> >so it is clearly possible for PQconndefaults() to return NULL for
> >service file failures.  The questions are:
> >
> >*  Is this what we want?
> 
> What other choices do we have? I don't think PQconndefaults() should
> continue on as if PGSERVICE wasn't set in the environment after a
> failure from parseServiceInfo.

True.  Ignoring a service specification seems wrong, and issuing a
warning message weak.

> >*  Should we document this?
> 
> Yes the documentation should indicate that PQconndefaults() can
> return NULL for more than just memory failures.

The attached patch fixes this.  I am unclear about backpatching this as
it hits lot of code, is rare, and adds new translation strings.  On the
other hand, it does crash the applications.

-- 
  Bruce Momjian  <br...@momjian.us>        http://momjian.us
  EnterpriseDB                             http://enterprisedb.com

  + It's impossible for everything to be true. +
diff --git a/contrib/dblink/dblink.c b/contrib/dblink/dblink.c
new file mode 100644
index bba0d2a..eca061f
*** a/contrib/dblink/dblink.c
--- b/contrib/dblink/dblink.c
*************** dblink_fdw_validator(PG_FUNCTION_ARGS)
*** 1947,1953 ****
  		if (!options)			/* assume reason for failure is OOM */
  			ereport(ERROR,
  					(errcode(ERRCODE_FDW_OUT_OF_MEMORY),
! 					 errmsg("out of memory"),
  					 errdetail("could not get libpq's default connection options")));
  	}
  
--- 1947,1953 ----
  		if (!options)			/* assume reason for failure is OOM */
  			ereport(ERROR,
  					(errcode(ERRCODE_FDW_OUT_OF_MEMORY),
! 					 errmsg("out of memory or service name cannot be found"),
  					 errdetail("could not get libpq's default connection options")));
  	}
  
diff --git a/contrib/pg_upgrade/server.c b/contrib/pg_upgrade/server.c
new file mode 100644
index ed67759..cd246ce
*** a/contrib/pg_upgrade/server.c
--- b/contrib/pg_upgrade/server.c
*************** check_pghost_envvar(void)
*** 300,306 ****
  	/* Get valid libpq env vars from the PQconndefaults function */
  
  	start = PQconndefaults();
! 
  	for (option = start; option->keyword != NULL; option++)
  	{
  		if (option->envvar && (strcmp(option->envvar, "PGHOST") == 0 ||
--- 300,310 ----
  	/* Get valid libpq env vars from the PQconndefaults function */
  
  	start = PQconndefaults();
! 	if (!start)
! 		pg_log(PG_FATAL,
! 			   "out of memory or service name cannot be found\n"
! 			   "could not get libpq's default connection options\n");
! 	
  	for (option = start; option->keyword != NULL; option++)
  	{
  		if (option->envvar && (strcmp(option->envvar, "PGHOST") == 0 ||
diff --git a/contrib/postgres_fdw/option.c b/contrib/postgres_fdw/option.c
new file mode 100644
index 123cb4f..d4890be
*** a/contrib/postgres_fdw/option.c
--- b/contrib/postgres_fdw/option.c
*************** InitPgFdwOptions(void)
*** 169,175 ****
  	if (!libpq_options)			/* assume reason for failure is OOM */
  		ereport(ERROR,
  				(errcode(ERRCODE_FDW_OUT_OF_MEMORY),
! 				 errmsg("out of memory"),
  			 errdetail("could not get libpq's default connection options")));
  
  	/* Count how many libpq options are available. */
--- 169,175 ----
  	if (!libpq_options)			/* assume reason for failure is OOM */
  		ereport(ERROR,
  				(errcode(ERRCODE_FDW_OUT_OF_MEMORY),
! 				 errmsg("out of memory or service name cannot be found"),
  			 errdetail("could not get libpq's default connection options")));
  
  	/* Count how many libpq options are available. */
diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
new file mode 100644
index 775d250..ceb873e
*** a/doc/src/sgml/libpq.sgml
--- b/doc/src/sgml/libpq.sgml
*************** typedef struct
*** 481,487 ****
         current default values.  The return value points to an array of
         <structname>PQconninfoOption</structname> structures, which ends
         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.
--- 481,488 ----
         current default values.  The return value points to an array of
         <structname>PQconninfoOption</structname> structures, which ends
         with an entry having a null <structfield>keyword</> pointer.  The
!        null pointer is returned if memory could not be allocated or
!        the specified connection service name cannot be found. 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.
diff --git a/src/bin/scripts/pg_isready.c b/src/bin/scripts/pg_isready.c
new file mode 100644
index 4ba257d..f02f4f9
*** a/src/bin/scripts/pg_isready.c
--- b/src/bin/scripts/pg_isready.c
*************** main(int argc, char **argv)
*** 126,131 ****
--- 126,138 ----
  	 * Get the default host and port so we can display them in our output
  	 */
  	connect_options = PQconndefaults();
+ 	if (!connect_options)
+ 	{
+ 		fprintf(stderr, _("out of memory or service name cannot be found\n"
+ 						  "could not get libpq's default connection options\n"));
+ 		exit(PQPING_NO_ATTEMPT);
+ 	}
+ 
  	conn_opt_ptr = connect_options;
  	while (conn_opt_ptr->keyword)
  	{
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
new file mode 100644
index eea9c6b..60d0c8b
*** a/src/interfaces/libpq/fe-connect.c
--- b/src/interfaces/libpq/fe-connect.c
*************** connectOptions2(PGconn *conn)
*** 850,856 ****
   *
   * Construct a default connection options array, which identifies all the
   * available options and shows any default values that are available from the
!  * environment etc.  On error (eg out of memory), NULL is returned.
   *
   * Using this function, an application may determine all possible options
   * and their current default values.
--- 850,857 ----
   *
   * Construct a default connection options array, which identifies all the
   * available options and shows any default values that are available from the
!  * environment etc.  On error (out of memory or invalid service name),
!  * NULL is returned.
   *
   * Using this function, an application may determine all possible options
   * and their current default values.
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to