Re: Trivial libpq refactoring patch (was: Re: [HACKERS] Another review of URI for libpq, v7 submission)

2012-03-22 Thread Tom Lane
Alex Shulgin a...@commandprompt.com writes:
 While working on this fix I've figured out that I need my
 conninfo_uri_parse to support use_defaults parameter, like
 conninfo(_array)_parse functions do.

 The problem is that the block of code which does the defaults handling
 is duplicated in both of the above functions.  What I'd like to do is
 extract it into a separate function to call.  What I wouldn't like is
 bloating the original URI patch with this unrelated change.

Applied with minor adjustments --- notably, I thought
conninfo_add_defaults was a better name for the function.

regards, tom lane

-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Trivial libpq refactoring patch (was: Re: [HACKERS] Another review of URI for libpq, v7 submission)

2012-03-21 Thread Alex Shulgin
Alex a...@commandprompt.com writes:

 Marko Kreen mark...@gmail.com writes:

 On Thu, Mar 15, 2012 at 11:29:31PM +0200, Alex wrote:
 https://github.com/a1exsh/postgres/commits/uri

 The point of the patch is to have one string with all connection options,
 in standard format, yes?  So why does not this work:

   db = PQconnectdb(postgres://localhost);

 ?

 Good catch.

 I've figured out that we'll need a bit more intrusive change than simply
 overriding the expand_dbname check in conninfo_array_parse (like the
 current version does) to support URIs in all PQconnect* variants.

 I still need to figure out some details, but this is to give people a
 status update.

While working on this fix I've figured out that I need my
conninfo_uri_parse to support use_defaults parameter, like
conninfo(_array)_parse functions do.

The problem is that the block of code which does the defaults handling
is duplicated in both of the above functions.  What I'd like to do is
extract it into a separate function to call.  What I wouldn't like is
bloating the original URI patch with this unrelated change.

So here's a trivial patch to do the refactoring.  Also, it uses the
newly added conninfo_fill_defaults directly in PQconndefaults, instead
of doing the parse empty conninfo string trick.  If this could be
applied, I'd rebase my patch against the updated master branch and
submit the new version.

As it goes, the patch adds a little duplication when it comes to
creating a working copy of PQconninfoOptions array.  Attached is the
second patch on top of the first one to extract this bit of code into
conninfo_init.  Not sure if we should go all the way through this, so
it's not critical if this one is not applied.

--
Regards,
Alex
*** a/src/interfaces/libpq/fe-connect.c
--- b/src/interfaces/libpq/fe-connect.c
***
*** 297,302  static PQconninfoOption *conninfo_parse(const char *conninfo,
--- 297,304 
  static PQconninfoOption *conninfo_array_parse(const char *const * keywords,
 const char *const * values, 
PQExpBuffer errorMessage,
 bool use_defaults, int expand_dbname);
+ static bool conninfo_fill_defaults(PQconninfoOption *options,
+  PQExpBuffer errorMessage);
  static char *conninfo_getval(PQconninfoOption *connOptions,
const char *keyword);
  static void defaultNoticeReceiver(void *arg, const PGresult *res);
***
*** 836,842  PQconndefaults(void)
initPQExpBuffer(errorBuf);
if (PQExpBufferDataBroken(errorBuf))
return NULL;/* out of memory already :-( */
!   connOptions = conninfo_parse(, errorBuf, true);
termPQExpBuffer(errorBuf);
return connOptions;
  }
--- 838,860 
initPQExpBuffer(errorBuf);
if (PQExpBufferDataBroken(errorBuf))
return NULL;/* out of memory already :-( */
! 
!   /* Make a working copy of PQconninfoOptions */
!   connOptions = malloc(sizeof(PQconninfoOptions));
!   if (connOptions == NULL)
!   {
!   printfPQExpBuffer(errorBuf,
! libpq_gettext(out of 
memory\n));
!   return NULL;
!   }
!   memcpy(connOptions, PQconninfoOptions, sizeof(PQconninfoOptions));
! 
!   if (!conninfo_fill_defaults(connOptions, errorBuf))
!   {
!   PQconninfoFree(connOptions);
!   connOptions = NULL;
!   }
! 
termPQExpBuffer(errorBuf);
return connOptions;
  }
***
*** 4002,4008  conninfo_parse(const char *conninfo, PQExpBuffer 
errorMessage,
char   *pname;
char   *pval;
char   *buf;
-   char   *tmp;
char   *cp;
char   *cp2;
PQconninfoOption *options;
--- 4020,4025 
***
*** 4170,4245  conninfo_parse(const char *conninfo, PQExpBuffer 
errorMessage,
free(buf);
  
/*
!* Stop here if caller doesn't want defaults filled in.
!*/
!   if (!use_defaults)
!   return options;
! 
!   /*
!* If there's a service spec, use it to obtain any not-explicitly-given
!* parameters.
 */
!   if (parseServiceInfo(options, errorMessage))
{
PQconninfoFree(options);
return NULL;
}
  
-   /*
-* Get the fallback resources for parameters not specified in the 
conninfo
-* string nor the service.
-*/
-   for (option = options; option-keyword != NULL; option++)
-   {
-   if (option-val != NULL)
-   continue;   /* Value was in 
conninfo or service */
- 
-   /*
-* Try to get the environment variable fallback
-*/
-   if (option-envvar != NULL)
-   {