agora inbox for [email protected]  
help / color / mirror / Atom feed
Another review of URI for libpq, v7 submission
22+ messages / 9 participants
[nested] [flat]

* Another review of URI for libpq, v7 submission
@ 2012-03-15 08:49 Daniel Farina <[email protected]>
  2012-03-15 14:34 ` Re: Another review of URI for libpq, v7 submission Alvaro Herrera <[email protected]>
  2012-03-15 14:36 ` Re: Another review of URI for libpq, v7 submission Alex Shulgin <[email protected]>
  0 siblings, 2 replies; 22+ messages in thread

From: Daniel Farina @ 2012-03-15 08:49 UTC (permalink / raw)
  To: Alexander Shulgin <[email protected]>; pgsql-hackers

I reviewed this and so far have not found any serious problems,
although as is par for the course it contains some of the fiddly bits
involved in any string manipulations in C.  I made a few edits -- none
strictly necessary for correctness -- that the original author is free
audit and/or include[0]. I did put in some defensive programming
choices (instead of if/else if/elseif/else raise an error, even if the
latter is allegedly impossible) that I think are a good idea.

Loops around pointer increments are very fastidiously checked for
NUL-byteness, and those that aren't are carefully guarded by
invariants that seem like they should prevent an overrun.  The nature
of the beast, I suppose, short of giving libpq a "StringData" like
struct and a small lexer to make it more clear that a subtle overrun
is not creeping in.

One thing I found puzzling was that in the latest revision the tests
appeared to be broken for me: all "@" signs were translated to "(at)".
 Is that mangling applied by the archives, or something?

The test suite neatly tries to copy pg_regress's general "make
installcheck" style, but it likes to use my username as the database
rather than the standard "regression" as seen by pg_regress.  It is
nice that a place to test connection strings and such is there, where
there was none before.

I am happy with the range and style of accepted URIs, and I think this
can stem the bleeding of the fragmentation already taking place at
large.

[0]: https://github.com/fdr/postgres/tree/uri, commit
e50ef375b7a731ca79bf5d3ca8b0bd69c97a9e71, aka the 'uri' branch

-- 
fdr



^ permalink  raw  reply  [nested|flat] 22+ messages in thread

* Re: Another review of URI for libpq, v7 submission
  2012-03-15 08:49 Another review of URI for libpq, v7 submission Daniel Farina <[email protected]>
@ 2012-03-15 14:34 ` Alvaro Herrera <[email protected]>
  1 sibling, 0 replies; 22+ messages in thread

From: Alvaro Herrera @ 2012-03-15 14:34 UTC (permalink / raw)
  To: Daniel Farina <[email protected]>; +Cc: Alexander Shulgin <[email protected]>; pgsql-hackers


Excerpts from Daniel Farina's message of jue mar 15 05:49:50 -0300 2012:

> One thing I found puzzling was that in the latest revision the tests
> appeared to be broken for me: all "@" signs were translated to "(at)".
>  Is that mangling applied by the archives, or something?

Ugh, ouch.  Yeah, that was done by the archives.  It seems that when
attachments are text/plain Mhonarc applies anti-spamming to them :-(
The original message doesn't have that problem.  Sorry about that.

-- 
Álvaro Herrera <[email protected]>
The PostgreSQL Company - Command Prompt, Inc.
PostgreSQL Replication, Consulting, Custom Development, 24x7 support



^ permalink  raw  reply  [nested|flat] 22+ messages in thread

* Re: Another review of URI for libpq, v7 submission
  2012-03-15 08:49 Another review of URI for libpq, v7 submission Daniel Farina <[email protected]>
@ 2012-03-15 14:36 ` Alex Shulgin <[email protected]>
  2012-03-15 21:09   ` Re: Another review of URI for libpq, v7 submission Daniel Farina <[email protected]>
  1 sibling, 1 reply; 22+ messages in thread

From: Alex Shulgin @ 2012-03-15 14:36 UTC (permalink / raw)
  To: Daniel Farina <[email protected]>; +Cc: pgsql-hackers

Daniel Farina <[email protected]> writes:

> I reviewed this and so far have not found any serious problems,
> although as is par for the course it contains some of the fiddly bits
> involved in any string manipulations in C.  I made a few edits -- none
> strictly necessary for correctness -- that the original author is free
> audit and/or include[0].

Thank you for the review, Daniel!

Apparently, I was on drugs when I've submitted v7, as it still contains
the bug for which to fix I was forced to move parts of the code back
into the main parser routine...

> I did put in some defensive programming choices (instead of if/else
> if/elseif/else raise an error, even if the latter is allegedly
> impossible) that I think are a good idea.

Yes, this is a good idea, I'll incorporate them in the patch.  However,
this one doesn't work:
https://github.com/fdr/postgres/commit/4fad90fb243d9266b1003cfbcf8397f67269fad3

Neither '@' or '/' are mandatory in the URI anywhere after "scheme://",
so we can't just say it "should never happen."  Running the regression
test with this commit applied highlights the problem.

> One thing I found puzzling was that in the latest revision the tests
> appeared to be broken for me: all "@" signs were translated to "(at)".
>  Is that mangling applied by the archives, or something?

This is definitely mangling by the lists.  I can see this has happened
to people before, e.g.:
http://archives.postgresql.org/pgsql-hackers/2010-01/msg00938.php

But that discussion didn't seem to lead to a solution for the problem.

I wonder if there's any evidence as to that mangling the email addresses
helps to reduce spam at all?  I mean replacing "(at)" back to "@" and
"(dot)" to "." is piece of cake for a spam crawler.

What I see though, is that most of the message-id URLs are broken by the
mangling.  Also I don't think everyone should just tolerate that it
messes with the attachments.  Should we all suddenly use
application/octet-stream or application/gzip instead of text/plain?

> The test suite neatly tries to copy pg_regress's general "make
> installcheck" style, but it likes to use my username as the database
> rather than the standard "regression" as seen by pg_regress.  It is
> nice that a place to test connection strings and such is there, where
> there was none before.

Oh, I don't see why we can't use "regression" too.

While testing this I've also noticed that there was some funny behavior
when you left out the final slash after hostname, e.g.:
"postgres://localhost/" vs. "postgres://localhost".  It turned out in
the former case we were setting dbname conninfo parameter to an empty
string and in the latter one we didn't set it at all.  The difference is
that when we do set it, the default dbname is derived from username, but
when we don't--$PGDATABASE is used.  I've fixed this, so now both URIs
work the same way (both do not set dbname.)

It also appeared to me that with the current code, a wide range of
funny-looking URIs are considered valid, e.g.:

postgres://user@
postgres://@host
postgres://host:/

and, taking approach to the extreme:

postgres://:@:

This specifies empty user, password, host and port, and looks really
funny.  I've added (actually revived) some checks to forbid setting
empty URI parts where it doesn't make much sense.

Finally, attached is v8.  Hopefully I didn't mess things up too much.

--
Regards,
Alex



^ permalink  raw  reply  [nested|flat] 22+ messages in thread

* Re: Another review of URI for libpq, v7 submission
  2012-03-15 08:49 Another review of URI for libpq, v7 submission Daniel Farina <[email protected]>
  2012-03-15 14:36 ` Re: Another review of URI for libpq, v7 submission Alex Shulgin <[email protected]>
@ 2012-03-15 21:09   ` Daniel Farina <[email protected]>
  2012-03-15 21:29     ` Re: Another review of URI for libpq, v7 submission Alex <[email protected]>
  0 siblings, 1 reply; 22+ messages in thread

From: Daniel Farina @ 2012-03-15 21:09 UTC (permalink / raw)
  To: Alex Shulgin <[email protected]>; +Cc: pgsql-hackers

On Thu, Mar 15, 2012 at 7:36 AM, Alex Shulgin <[email protected]> wrote:
> I wonder if there's any evidence as to that mangling the email addresses
> helps to reduce spam at all?  I mean replacing "(at)" back to "@" and
> "(dot)" to "." is piece of cake for a spam crawler.

I suspect we're long past the point in Internet history where such
simple obfuscation could possibly matter.

> Finally, attached is v8.  Hopefully I didn't mess things up too much.

I'll give it another look-over. Do you have these in git somewhere? It
will help me save time on some of the incremental changes.

-- 
fdr



^ permalink  raw  reply  [nested|flat] 22+ messages in thread

* Re: Another review of URI for libpq, v7 submission
  2012-03-15 08:49 Another review of URI for libpq, v7 submission Daniel Farina <[email protected]>
  2012-03-15 14:36 ` Re: Another review of URI for libpq, v7 submission Alex Shulgin <[email protected]>
  2012-03-15 21:09   ` Re: Another review of URI for libpq, v7 submission Daniel Farina <[email protected]>
@ 2012-03-15 21:29     ` Alex <[email protected]>
  2012-03-17 14:51       ` Re: Another review of URI for libpq, v7 submission Marko Kreen <[email protected]>
  0 siblings, 1 reply; 22+ messages in thread

From: Alex @ 2012-03-15 21:29 UTC (permalink / raw)
  To: Daniel Farina <[email protected]>; +Cc: pgsql-hackers


Daniel Farina <[email protected]> writes:
>
>> Finally, attached is v8.  Hopefully I didn't mess things up too much.
>
> I'll give it another look-over. Do you have these in git somewhere? It
> will help me save time on some of the incremental changes.

Yes, I've just pushed my dev branch to this fork of mine:
https://github.com/a1exsh/postgres/commits/uri



^ permalink  raw  reply  [nested|flat] 22+ messages in thread

* Re: Another review of URI for libpq, v7 submission
  2012-03-15 08:49 Another review of URI for libpq, v7 submission Daniel Farina <[email protected]>
  2012-03-15 14:36 ` Re: Another review of URI for libpq, v7 submission Alex Shulgin <[email protected]>
  2012-03-15 21:09   ` Re: Another review of URI for libpq, v7 submission Daniel Farina <[email protected]>
  2012-03-15 21:29     ` Re: Another review of URI for libpq, v7 submission Alex <[email protected]>
@ 2012-03-17 14:51       ` Marko Kreen <[email protected]>
  2012-03-20 22:18         ` Re: Another review of URI for libpq, v7 submission Alex <[email protected]>
  0 siblings, 1 reply; 22+ messages in thread

From: Marko Kreen @ 2012-03-17 14:51 UTC (permalink / raw)
  To: Alex <[email protected]>; +Cc: Daniel Farina <[email protected]>; pgsql-hackers

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");

?

-- 
marko




^ permalink  raw  reply  [nested|flat] 22+ messages in thread

* Re: Another review of URI for libpq, v7 submission
  2012-03-15 08:49 Another review of URI for libpq, v7 submission Daniel Farina <[email protected]>
  2012-03-15 14:36 ` Re: Another review of URI for libpq, v7 submission Alex Shulgin <[email protected]>
  2012-03-15 21:09   ` Re: Another review of URI for libpq, v7 submission Daniel Farina <[email protected]>
  2012-03-15 21:29     ` Re: Another review of URI for libpq, v7 submission Alex <[email protected]>
  2012-03-17 14:51       ` Re: Another review of URI for libpq, v7 submission Marko Kreen <[email protected]>
@ 2012-03-20 22:18         ` Alex <[email protected]>
  2012-03-21 16:42           ` Trivial libpq refactoring patch (was: Re: Another review of URI for libpq, v7 submission) Alex Shulgin <[email protected]>
  2012-03-22 21:42           ` Re: Another review of URI for libpq, v7 submission Alex <[email protected]>
  0 siblings, 2 replies; 22+ messages in thread

From: Alex @ 2012-03-20 22:18 UTC (permalink / raw)
  To: Marko Kreen <[email protected]>; +Cc: Daniel Farina <[email protected]>; pgsql-hackers


Marko Kreen <[email protected]> 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.

--
Alex



^ permalink  raw  reply  [nested|flat] 22+ messages in thread

* Trivial libpq refactoring patch (was: Re: Another review of URI for libpq, v7 submission)
  2012-03-15 08:49 Another review of URI for libpq, v7 submission Daniel Farina <[email protected]>
  2012-03-15 14:36 ` Re: Another review of URI for libpq, v7 submission Alex Shulgin <[email protected]>
  2012-03-15 21:09   ` Re: Another review of URI for libpq, v7 submission Daniel Farina <[email protected]>
  2012-03-15 21:29     ` Re: Another review of URI for libpq, v7 submission Alex <[email protected]>
  2012-03-17 14:51       ` Re: Another review of URI for libpq, v7 submission Marko Kreen <[email protected]>
  2012-03-20 22:18         ` Re: Another review of URI for libpq, v7 submission Alex <[email protected]>
@ 2012-03-21 16:42           ` Alex Shulgin <[email protected]>
  2012-03-22 16:10             ` Re: Trivial libpq refactoring patch (was: Re: Another review of URI for libpq, v7 submission) Tom Lane <[email protected]>
  1 sibling, 1 reply; 22+ messages in thread

From: Alex Shulgin @ 2012-03-21 16:42 UTC (permalink / raw)
  To: pgsql-hackers

Alex <[email protected]> writes:

> Marko Kreen <[email protected]> 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)
- 		{
- 			if ((tmp = getenv(option->envvar)) != NULL)
- 			{
- 				option->val = strdup(tmp);
- 				if (!option->val)
- 				{
- 					printfPQExpBuffer(errorMessage,
- 									  libpq_gettext("out of memory\n"));
- 					PQconninfoFree(options);
- 					return NULL;
- 				}
- 				continue;
- 			}
- 		}
- 
- 		/*
- 		 * No environment variable specified or this one isn't set - try
- 		 * compiled in
- 		 */
- 		if (option->compiled != NULL)
- 		{
- 			option->val = strdup(option->compiled);
- 			if (!option->val)
- 			{
- 				printfPQExpBuffer(errorMessage,
- 								  libpq_gettext("out of memory\n"));
- 				PQconninfoFree(options);
- 				return NULL;
- 			}
- 			continue;
- 		}
- 
- 		/*
- 		 * Special handling for user
- 		 */
- 		if (strcmp(option->keyword, "user") == 0)
- 		{
- 			option->val = pg_fe_getauthname(errorMessage);
- 			continue;
- 		}
- 	}
- 
  	return options;
  }
  
--- 4187,4200 ----
  	free(buf);
  
  	/*
! 	 * Fill in defaults if the caller wants that.
  	 */
! 	if (use_defaults && !conninfo_fill_defaults(options, errorMessage))
  	{
  		PQconninfoFree(options);
  		return NULL;
  	}
  
  	return options;
  }
  
***************
*** 4262,4268 **** conninfo_array_parse(const char *const * keywords, const char *const * values,
  					 PQExpBuffer errorMessage, bool use_defaults,
  					 int expand_dbname)
  {
- 	char	   *tmp;
  	PQconninfoOption *options;
  	PQconninfoOption *str_options = NULL;
  	PQconninfoOption *option;
--- 4217,4222 ----
***************
*** 4386,4405 **** conninfo_array_parse(const char *const * keywords, const char *const * values,
  	PQconninfoFree(str_options);
  
  	/*
! 	 * 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
--- 4340,4377 ----
  	PQconninfoFree(str_options);
  
  	/*
! 	 * Fill in defaults if the caller wants that.
  	 */
! 	if (use_defaults && !conninfo_fill_defaults(options, errorMessage))
! 	{
! 		PQconninfoFree(options);
! 		return NULL;
! 	}
! 
! 	return options;
! }
! 
! /*
!  * Fills the connection options array with the default values for unspecified
!  * options.
!  *
!  * Defaults are supplied from a service file, environment variables, etc.
!  *
!  * Returns TRUE if successful, FALSE otherwise, while filling in errorMessage.
!  */
! static bool
! conninfo_fill_defaults(PQconninfoOption *options,
! 					   PQExpBuffer errorMessage)
! {
! 	PQconninfoOption *option;
! 	char *tmp;
  
  	/*
  	 * If there's a service spec, use it to obtain any not-explicitly-given
  	 * parameters.
  	 */
  	if (parseServiceInfo(options, errorMessage))
! 		return false;
  
  	/*
  	 * Get the fallback resources for parameters not specified in the conninfo
***************
*** 4422,4429 **** conninfo_array_parse(const char *const * keywords, const char *const * values,
  				{
  					printfPQExpBuffer(errorMessage,
  									  libpq_gettext("out of memory\n"));
! 					PQconninfoFree(options);
! 					return NULL;
  				}
  				continue;
  			}
--- 4394,4400 ----
  				{
  					printfPQExpBuffer(errorMessage,
  									  libpq_gettext("out of memory\n"));
! 					return false;
  				}
  				continue;
  			}
***************
*** 4440,4447 **** conninfo_array_parse(const char *const * keywords, const char *const * values,
  			{
  				printfPQExpBuffer(errorMessage,
  								  libpq_gettext("out of memory\n"));
! 				PQconninfoFree(options);
! 				return NULL;
  			}
  			continue;
  		}
--- 4411,4417 ----
  			{
  				printfPQExpBuffer(errorMessage,
  								  libpq_gettext("out of memory\n"));
! 				return false;
  			}
  			continue;
  		}
***************
*** 4456,4462 **** conninfo_array_parse(const char *const * keywords, const char *const * values,
  		}
  	}
  
! 	return options;
  }
  
  static char *
--- 4426,4432 ----
  		}
  	}
  
! 	return true;
  }
  
  static char *

*** a/src/interfaces/libpq/fe-connect.c
--- b/src/interfaces/libpq/fe-connect.c
***************
*** 292,297 **** static PGconn *makeEmptyPGconn(void);
--- 292,298 ----
  static void fillPGconn(PGconn *conn, PQconninfoOption *connOptions);
  static void freePGconn(PGconn *conn);
  static void closePGconn(PGconn *conn);
+ static PQconninfoOption *conninfo_init(PQExpBuffer errorMessage);
  static PQconninfoOption *conninfo_parse(const char *conninfo,
  			   PQExpBuffer errorMessage, bool use_defaults);
  static PQconninfoOption *conninfo_array_parse(const char *const * keywords,
***************
*** 840,853 **** PQconndefaults(void)
  		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))
  	{
--- 841,849 ----
  		return NULL;			/* out of memory already :-( */
  
  	/* Make a working copy of PQconninfoOptions */
! 	connOptions = conninfo_init(&errorBuf);
  	if (connOptions == NULL)
  		return NULL;
  
  	if (!conninfo_fill_defaults(connOptions, &errorBuf))
  	{
***************
*** 4005,4010 **** PQconninfoParse(const char *conninfo, char **errmsg)
--- 4001,4025 ----
  }
  
  /*
+  * Makes a copy of PQconninfoOptions array.
+  */
+ static PQconninfoOption *
+ conninfo_init(PQExpBuffer errorMessage)
+ {
+ 	PQconninfoOption *options;
+ 
+ 	options = malloc(sizeof(PQconninfoOptions));
+ 	if (options == NULL)
+ 	{
+ 		printfPQExpBuffer(errorMessage,
+ 						  libpq_gettext("out of memory\n"));
+ 		return NULL;
+ 	}
+ 	memcpy(options, PQconninfoOptions, sizeof(PQconninfoOptions));
+ 	return options;
+ }
+ 
+ /*
   * Conninfo parser routine
   *
   * If successful, a malloc'd PQconninfoOption array is returned.
***************
*** 4026,4039 **** conninfo_parse(const char *conninfo, PQExpBuffer errorMessage,
  	PQconninfoOption *option;
  
  	/* Make a working copy of PQconninfoOptions */
! 	options = malloc(sizeof(PQconninfoOptions));
  	if (options == NULL)
- 	{
- 		printfPQExpBuffer(errorMessage,
- 						  libpq_gettext("out of memory\n"));
  		return NULL;
- 	}
- 	memcpy(options, PQconninfoOptions, sizeof(PQconninfoOptions));
  
  	/* Need a modifiable copy of the input string */
  	if ((buf = strdup(conninfo)) == NULL)
--- 4041,4049 ----
  	PQconninfoOption *option;
  
  	/* Make a working copy of PQconninfoOptions */
! 	options = conninfo_init(errorMessage);
  	if (options == NULL)
  		return NULL;
  
  	/* Need a modifiable copy of the input string */
  	if ((buf = strdup(conninfo)) == NULL)
***************
*** 4252,4266 **** conninfo_array_parse(const char *const * keywords, const char *const * values,
  	}
  
  	/* Make a working copy of PQconninfoOptions */
! 	options = malloc(sizeof(PQconninfoOptions));
  	if (options == NULL)
  	{
- 		printfPQExpBuffer(errorMessage,
- 						  libpq_gettext("out of memory\n"));
  		PQconninfoFree(str_options);
  		return NULL;
  	}
- 	memcpy(options, PQconninfoOptions, sizeof(PQconninfoOptions));
  
  	i = 0;
  	/* Parse the keywords/values arrays */
--- 4262,4273 ----
  	}
  
  	/* Make a working copy of PQconninfoOptions */
! 	options = conninfo_init(errorMessage);
  	if (options == NULL)
  	{
  		PQconninfoFree(str_options);
  		return NULL;
  	}
  
  	i = 0;
  	/* Parse the keywords/values arrays */


^ permalink  raw  reply  [nested|flat] 22+ messages in thread

* Re: Trivial libpq refactoring patch (was: Re: Another review of URI for libpq, v7 submission)
  2012-03-15 08:49 Another review of URI for libpq, v7 submission Daniel Farina <[email protected]>
  2012-03-15 14:36 ` Re: Another review of URI for libpq, v7 submission Alex Shulgin <[email protected]>
  2012-03-15 21:09   ` Re: Another review of URI for libpq, v7 submission Daniel Farina <[email protected]>
  2012-03-15 21:29     ` Re: Another review of URI for libpq, v7 submission Alex <[email protected]>
  2012-03-17 14:51       ` Re: Another review of URI for libpq, v7 submission Marko Kreen <[email protected]>
  2012-03-20 22:18         ` Re: Another review of URI for libpq, v7 submission Alex <[email protected]>
  2012-03-21 16:42           ` Trivial libpq refactoring patch (was: Re: Another review of URI for libpq, v7 submission) Alex Shulgin <[email protected]>
@ 2012-03-22 16:10             ` Tom Lane <[email protected]>
  0 siblings, 0 replies; 22+ messages in thread

From: Tom Lane @ 2012-03-22 16:10 UTC (permalink / raw)
  To: Alex Shulgin <[email protected]>; +Cc: pgsql-hackers

Alex Shulgin <[email protected]> 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



^ permalink  raw  reply  [nested|flat] 22+ messages in thread

* Re: Another review of URI for libpq, v7 submission
  2012-03-15 08:49 Another review of URI for libpq, v7 submission Daniel Farina <[email protected]>
  2012-03-15 14:36 ` Re: Another review of URI for libpq, v7 submission Alex Shulgin <[email protected]>
  2012-03-15 21:09   ` Re: Another review of URI for libpq, v7 submission Daniel Farina <[email protected]>
  2012-03-15 21:29     ` Re: Another review of URI for libpq, v7 submission Alex <[email protected]>
  2012-03-17 14:51       ` Re: Another review of URI for libpq, v7 submission Marko Kreen <[email protected]>
  2012-03-20 22:18         ` Re: Another review of URI for libpq, v7 submission Alex <[email protected]>
@ 2012-03-22 21:42           ` Alex <[email protected]>
  2012-03-27 13:03             ` Re: Another review of URI for libpq, v7 submission Heikki Linnakangas <[email protected]>
  2012-03-27 17:22             ` Re: Another review of URI for libpq, v7 submission Peter Eisentraut <[email protected]>
  1 sibling, 2 replies; 22+ messages in thread

From: Alex @ 2012-03-22 21:42 UTC (permalink / raw)
  To: Marko Kreen <[email protected]>; +Cc: Daniel Farina <[email protected]>; pgsql-hackers

Alex <[email protected]> writes:

> Marko Kreen <[email protected]> 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.

Okay, at last here's v9, rebased against current master branch.

What's new in this version is parse_connection_string function to be
called instead of conninfo_parse.  It will check for possible URI in the
connection string and dispatch to conninfo_uri_parse if URI was found,
otherwise it will fall back to conninfo_parse.

In two places in code we don't want to parse the string unless it is
deemed a real connection string and not plain dbname.  The new function
recognized_connection_string is added to check this.

Thanks Marko for spotting the problem and thanks Tom for committing the
refactoring patch!

--
Alex



^ permalink  raw  reply  [nested|flat] 22+ messages in thread

* Re: Another review of URI for libpq, v7 submission
  2012-03-15 08:49 Another review of URI for libpq, v7 submission Daniel Farina <[email protected]>
  2012-03-15 14:36 ` Re: Another review of URI for libpq, v7 submission Alex Shulgin <[email protected]>
  2012-03-15 21:09   ` Re: Another review of URI for libpq, v7 submission Daniel Farina <[email protected]>
  2012-03-15 21:29     ` Re: Another review of URI for libpq, v7 submission Alex <[email protected]>
  2012-03-17 14:51       ` Re: Another review of URI for libpq, v7 submission Marko Kreen <[email protected]>
  2012-03-20 22:18         ` Re: Another review of URI for libpq, v7 submission Alex <[email protected]>
  2012-03-22 21:42           ` Re: Another review of URI for libpq, v7 submission Alex <[email protected]>
@ 2012-03-27 13:03             ` Heikki Linnakangas <[email protected]>
  2012-03-27 14:13               ` Re: Another review of URI for libpq, v7 submission Alex Shulgin <[email protected]>
  1 sibling, 1 reply; 22+ messages in thread

From: Heikki Linnakangas @ 2012-03-27 13:03 UTC (permalink / raw)
  To: Alex <[email protected]>; +Cc: Marko Kreen <[email protected]>; Daniel Farina <[email protected]>; pgsql-hackers

On 22.03.2012 23:42, Alex wrote:
> Okay, at last here's v9, rebased against current master branch.

Some quick comments on this patch:

I see a compiler warning:
fe-connect.c: In function ‘conninfo_parse’:
fe-connect.c:4113: warning: unused variable ‘option’

Docs are missing.

I wonder if you should get an error if you try specify the same option 
multiple times. At least the behavior needs to be documented.

Should %00 be forbidden?

The error message is a bit confusing for 
"postgres://localhost?dbname=%XXfoo":
WARNING: ignoring unrecognized URI query parameter: dbname
There is in fact nothing wrong with "dbname", it's the %XX in the value 
that's bogus.

Looking at conninfo_uri_decode(), I think it's missing a bounds check, 
and peeks at two bytes beyond the end of string if the input ends in a '%'.

-- 
   Heikki Linnakangas
   EnterpriseDB   http://www.enterprisedb.com



^ permalink  raw  reply  [nested|flat] 22+ messages in thread

* Re: Another review of URI for libpq, v7 submission
  2012-03-15 08:49 Another review of URI for libpq, v7 submission Daniel Farina <[email protected]>
  2012-03-15 14:36 ` Re: Another review of URI for libpq, v7 submission Alex Shulgin <[email protected]>
  2012-03-15 21:09   ` Re: Another review of URI for libpq, v7 submission Daniel Farina <[email protected]>
  2012-03-15 21:29     ` Re: Another review of URI for libpq, v7 submission Alex <[email protected]>
  2012-03-17 14:51       ` Re: Another review of URI for libpq, v7 submission Marko Kreen <[email protected]>
  2012-03-20 22:18         ` Re: Another review of URI for libpq, v7 submission Alex <[email protected]>
  2012-03-22 21:42           ` Re: Another review of URI for libpq, v7 submission Alex <[email protected]>
  2012-03-27 13:03             ` Re: Another review of URI for libpq, v7 submission Heikki Linnakangas <[email protected]>
@ 2012-03-27 14:13               ` Alex Shulgin <[email protected]>
  0 siblings, 0 replies; 22+ messages in thread

From: Alex Shulgin @ 2012-03-27 14:13 UTC (permalink / raw)
  To: Heikki Linnakangas <[email protected]>; +Cc: Marko Kreen <[email protected]>; Daniel Farina <[email protected]>; pgsql-hackers


Heikki Linnakangas <[email protected]> writes:

> On 22.03.2012 23:42, Alex wrote:
>> Okay, at last here's v9, rebased against current master branch.
>
> Some quick comments on this patch:

Heikki, thank you for taking a look at this!

> I see a compiler warning:
> fe-connect.c: In function ‘conninfo_parse’:
> fe-connect.c:4113: warning: unused variable ‘option’

The warning is due to the earlier commit e9ce658b.  I believe the above
line supposed to go away.

> Docs are missing.

Yes, my plan is to focus on the documentation and code comments while
sorting out any remaining issues with the code.

> I wonder if you should get an error if you try specify the same option
> multiple times. At least the behavior needs to be documented.

Since conninfo strings may contain duplicated keywords and the latter
just takes precedence, I think we should just do the same with URIs
(which we already do.)  I don't see the behavior of conninfo strings
documented anywhere, however.

> Should %00 be forbidden?

Probably yes, good spot.

> The error message is a bit confusing for
> "postgres://localhost?dbname=%XXfoo":
> WARNING: ignoring unrecognized URI query parameter: dbname
> There is in fact nothing wrong with "dbname", it's the %XX in the
> value that's bogus.

Hm, yes, that's a bug.

Looks like conninfo_uri_parse_params needs to be adjusted to properly
pass the error message generated by conninfo_store_uri_encoded_value.  I
wonder if examining the errorMessage buffer to tell if it's a hard error
(it's going to be empty in the case of ignoreMissing=true) is a good
practice.

> Looking at conninfo_uri_decode(), I think it's missing a bounds check,
> and peeks at two bytes beyond the end of string if the input ends in a
> %'.

No, in that case what happens on L4919 is this: we dereference q which
is pointing at NUL terminator and pass the value to the first
get_hexdigit in the "if" condition, the pointer itself is then
incremented and does point beyond the end of string, but since
get_hexdigit returns FALSE we don't call the second get_hexdigit, so we
don't dereference the invalid pointer.

There is a comment right before that "if" which says just that.

--
Alex



^ permalink  raw  reply  [nested|flat] 22+ messages in thread

* Re: Another review of URI for libpq, v7 submission
  2012-03-15 08:49 Another review of URI for libpq, v7 submission Daniel Farina <[email protected]>
  2012-03-15 14:36 ` Re: Another review of URI for libpq, v7 submission Alex Shulgin <[email protected]>
  2012-03-15 21:09   ` Re: Another review of URI for libpq, v7 submission Daniel Farina <[email protected]>
  2012-03-15 21:29     ` Re: Another review of URI for libpq, v7 submission Alex <[email protected]>
  2012-03-17 14:51       ` Re: Another review of URI for libpq, v7 submission Marko Kreen <[email protected]>
  2012-03-20 22:18         ` Re: Another review of URI for libpq, v7 submission Alex <[email protected]>
  2012-03-22 21:42           ` Re: Another review of URI for libpq, v7 submission Alex <[email protected]>
@ 2012-03-27 17:22             ` Peter Eisentraut <[email protected]>
  2012-03-27 19:21               ` Re: Another review of URI for libpq, v7 submission Alex <[email protected]>
  1 sibling, 1 reply; 22+ messages in thread

From: Peter Eisentraut @ 2012-03-27 17:22 UTC (permalink / raw)
  To: Alex <[email protected]>; +Cc: pgsql-hackers

On tor, 2012-03-22 at 23:42 +0200, Alex wrote:
> Okay, at last here's v9, rebased against current master branch.

Attached is a patch on top of your v9 with two small fixes:

- Don't provide a check target in libpq/Makefile if it's not
implemented.

- Use the configured port number for running the tests (otherwise it
runs against my system installation, for example).



Attachments:

  [text/x-patch] libpq-uri-v9+petere.patch (1009B, ../../[email protected]/2-libpq-uri-v9+petere.patch)
  download | inline diff:
diff --git i/src/interfaces/libpq/Makefile w/src/interfaces/libpq/Makefile
index f19f272..266e3db 100644
--- i/src/interfaces/libpq/Makefile
+++ w/src/interfaces/libpq/Makefile
@@ -121,7 +121,7 @@ install: all installdirs install-lib
 	$(INSTALL_DATA) $(srcdir)/pqexpbuffer.h '$(DESTDIR)$(includedir_internal)'
 	$(INSTALL_DATA) $(srcdir)/pg_service.conf.sample '$(DESTDIR)$(datadir)/pg_service.conf.sample'
 
-check installcheck:
+installcheck:
 	$(MAKE) -C test $@
 
 installdirs: installdirs-lib
diff --git i/src/interfaces/libpq/test/Makefile w/src/interfaces/libpq/test/Makefile
index 964bb20..869a2f0 100644
--- i/src/interfaces/libpq/test/Makefile
+++ w/src/interfaces/libpq/test/Makefile
@@ -5,7 +5,7 @@ include $(top_builddir)/src/Makefile.global
 all: installcheck
 
 installcheck:
-	BINDIR='$(bindir)' SUBDIR='$(subdir)' $(SHELL) ./regress.sh
+	BINDIR='$(bindir)' PGPORT='$(DEF_PGPORT)' SUBDIR='$(subdir)' $(SHELL) ./regress.sh
 
 clean distclean maintainer-clean:
 	rm -f regress.out regress.diff


^ permalink  raw  reply  [nested|flat] 22+ messages in thread

* Re: Another review of URI for libpq, v7 submission
  2012-03-15 08:49 Another review of URI for libpq, v7 submission Daniel Farina <[email protected]>
  2012-03-15 14:36 ` Re: Another review of URI for libpq, v7 submission Alex Shulgin <[email protected]>
  2012-03-15 21:09   ` Re: Another review of URI for libpq, v7 submission Daniel Farina <[email protected]>
  2012-03-15 21:29     ` Re: Another review of URI for libpq, v7 submission Alex <[email protected]>
  2012-03-17 14:51       ` Re: Another review of URI for libpq, v7 submission Marko Kreen <[email protected]>
  2012-03-20 22:18         ` Re: Another review of URI for libpq, v7 submission Alex <[email protected]>
  2012-03-22 21:42           ` Re: Another review of URI for libpq, v7 submission Alex <[email protected]>
  2012-03-27 17:22             ` Re: Another review of URI for libpq, v7 submission Peter Eisentraut <[email protected]>
@ 2012-03-27 19:21               ` Alex <[email protected]>
  2012-03-27 22:49                 ` Re: Another review of URI for libpq, v7 submission Alex <[email protected]>
  0 siblings, 1 reply; 22+ messages in thread

From: Alex @ 2012-03-27 19:21 UTC (permalink / raw)
  To: Peter Eisentraut <[email protected]>; +Cc: pgsql-hackers


Peter Eisentraut <[email protected]> writes:

> On tor, 2012-03-22 at 23:42 +0200, Alex wrote:
>> Okay, at last here's v9, rebased against current master branch.
>
> Attached is a patch on top of your v9 with two small fixes:
>
> - Don't provide a check target in libpq/Makefile if it's not
> implemented.
>
> - Use the configured port number for running the tests (otherwise it
> runs against my system installation, for example).

Neat, thank you.



^ permalink  raw  reply  [nested|flat] 22+ messages in thread

* Re: Another review of URI for libpq, v7 submission
  2012-03-15 08:49 Another review of URI for libpq, v7 submission Daniel Farina <[email protected]>
  2012-03-15 14:36 ` Re: Another review of URI for libpq, v7 submission Alex Shulgin <[email protected]>
  2012-03-15 21:09   ` Re: Another review of URI for libpq, v7 submission Daniel Farina <[email protected]>
  2012-03-15 21:29     ` Re: Another review of URI for libpq, v7 submission Alex <[email protected]>
  2012-03-17 14:51       ` Re: Another review of URI for libpq, v7 submission Marko Kreen <[email protected]>
  2012-03-20 22:18         ` Re: Another review of URI for libpq, v7 submission Alex <[email protected]>
  2012-03-22 21:42           ` Re: Another review of URI for libpq, v7 submission Alex <[email protected]>
  2012-03-27 17:22             ` Re: Another review of URI for libpq, v7 submission Peter Eisentraut <[email protected]>
  2012-03-27 19:21               ` Re: Another review of URI for libpq, v7 submission Alex <[email protected]>
@ 2012-03-27 22:49                 ` Alex <[email protected]>
  2012-04-05 16:52                   ` Re: Another review of URI for libpq, v7 submission Peter Eisentraut <[email protected]>
  0 siblings, 1 reply; 22+ messages in thread

From: Alex @ 2012-03-27 22:49 UTC (permalink / raw)
  To: Peter Eisentraut <[email protected]>; +Cc: Heikki Linnakangas <[email protected]>; pgsql-hackers

Alex <[email protected]> writes:

> Peter Eisentraut <[email protected]> writes:
>>
>> Attached is a patch on top of your v9 with two small fixes:
>>
>> - Don't provide a check target in libpq/Makefile if it's not
>> implemented.
>>
>> - Use the configured port number for running the tests (otherwise it
>> runs against my system installation, for example).
>
> Neat, thank you.

Attached is a gzipped v10, complete with the above fixes and fixes to
bugs found by Heikki.  Documentation and code comments are also finally
updated.

Of all the command-line utilities which can accept conninfo string, only
psql mentions that, so only its documentation was updated.  Other
utilities, like pg_dump and pg_restore can also work with either
conninfo or URI, however this remains undocumented.

--
Alex


Attachments:

  [application/octet-stream] libpq-uri-v10.patch.gz (10.1K, ../../[email protected]/2-libpq-uri-v10.patch.gz)
  download

^ permalink  raw  reply  [nested|flat] 22+ messages in thread

* Re: Another review of URI for libpq, v7 submission
  2012-03-15 08:49 Another review of URI for libpq, v7 submission Daniel Farina <[email protected]>
  2012-03-15 14:36 ` Re: Another review of URI for libpq, v7 submission Alex Shulgin <[email protected]>
  2012-03-15 21:09   ` Re: Another review of URI for libpq, v7 submission Daniel Farina <[email protected]>
  2012-03-15 21:29     ` Re: Another review of URI for libpq, v7 submission Alex <[email protected]>
  2012-03-17 14:51       ` Re: Another review of URI for libpq, v7 submission Marko Kreen <[email protected]>
  2012-03-20 22:18         ` Re: Another review of URI for libpq, v7 submission Alex <[email protected]>
  2012-03-22 21:42           ` Re: Another review of URI for libpq, v7 submission Alex <[email protected]>
  2012-03-27 17:22             ` Re: Another review of URI for libpq, v7 submission Peter Eisentraut <[email protected]>
  2012-03-27 19:21               ` Re: Another review of URI for libpq, v7 submission Alex <[email protected]>
  2012-03-27 22:49                 ` Re: Another review of URI for libpq, v7 submission Alex <[email protected]>
@ 2012-04-05 16:52                   ` Peter Eisentraut <[email protected]>
  2012-04-05 22:10                     ` Re: Another review of URI for libpq, v7 submission Alvaro Herrera <[email protected]>
  0 siblings, 1 reply; 22+ messages in thread

From: Peter Eisentraut @ 2012-04-05 16:52 UTC (permalink / raw)
  To: Alex <[email protected]>; +Cc: Heikki Linnakangas <[email protected]>; pgsql-hackers

On ons, 2012-03-28 at 01:49 +0300, Alex wrote:
> Attached is a gzipped v10, complete with the above fixes and fixes to
> bugs found by Heikki.  Documentation and code comments are also
> finally updated.

The compiler warning is still there:

fe-connect.c: In function ‘conninfo_parse’:
fe-connect.c:4122:20: error: unused variable ‘option’ [-Werror=unused-variable]





^ permalink  raw  reply  [nested|flat] 22+ messages in thread

* Re: Another review of URI for libpq, v7 submission
  2012-03-15 08:49 Another review of URI for libpq, v7 submission Daniel Farina <[email protected]>
  2012-03-15 14:36 ` Re: Another review of URI for libpq, v7 submission Alex Shulgin <[email protected]>
  2012-03-15 21:09   ` Re: Another review of URI for libpq, v7 submission Daniel Farina <[email protected]>
  2012-03-15 21:29     ` Re: Another review of URI for libpq, v7 submission Alex <[email protected]>
  2012-03-17 14:51       ` Re: Another review of URI for libpq, v7 submission Marko Kreen <[email protected]>
  2012-03-20 22:18         ` Re: Another review of URI for libpq, v7 submission Alex <[email protected]>
  2012-03-22 21:42           ` Re: Another review of URI for libpq, v7 submission Alex <[email protected]>
  2012-03-27 17:22             ` Re: Another review of URI for libpq, v7 submission Peter Eisentraut <[email protected]>
  2012-03-27 19:21               ` Re: Another review of URI for libpq, v7 submission Alex <[email protected]>
  2012-03-27 22:49                 ` Re: Another review of URI for libpq, v7 submission Alex <[email protected]>
  2012-04-05 16:52                   ` Re: Another review of URI for libpq, v7 submission Peter Eisentraut <[email protected]>
@ 2012-04-05 22:10                     ` Alvaro Herrera <[email protected]>
  2012-04-06 03:25                       ` Re: Another review of URI for libpq, v7 submission Alvaro Herrera <[email protected]>
  0 siblings, 1 reply; 22+ messages in thread

From: Alvaro Herrera @ 2012-04-05 22:10 UTC (permalink / raw)
  To: Peter Eisentraut <[email protected]>; +Cc: Alex <[email protected]>; Heikki Linnakangas <[email protected]>; pgsql-hackers

Excerpts from Peter Eisentraut's message of jue abr 05 13:52:13 -0300 2012:
> On ons, 2012-03-28 at 01:49 +0300, Alex wrote:
> > Attached is a gzipped v10, complete with the above fixes and fixes to
> > bugs found by Heikki.  Documentation and code comments are also
> > finally updated.
> 
> The compiler warning is still there:
> 
> fe-connect.c: In function ‘conninfo_parse’:
> fe-connect.c:4122:20: error: unused variable ‘option’ [-Werror=unused-variable]

Here's an updated patch, including this fix and others.  (Most notable
the fact that I got rid of conninfo_store_uri_encoded_value, instead
expanding conninfo_storeval a bit).  I also fixed the test script to run
in VPATH.  I intend to commit this shortly, barring objection from Peter
who is listed as "committer" in the CF app.

I think the only thing I'm not really sure about is the usage of the
<synopsis> tag to mark example URIs in the docs.  It looks to me that
they should mostly be <literal> instead, but I'm not really sure about
that either -- I'm suspecting the PDF output would look rather horrible.

-- 
Álvaro Herrera <[email protected]>
The PostgreSQL Company - Command Prompt, Inc.
PostgreSQL Replication, Consulting, Custom Development, 24x7 support


Attachments:

  [application/x-gzip] libpq-uri-v11.patch.gz (10.6K, ../../[email protected]/2-libpq-uri-v11.patch.gz)
  download

^ permalink  raw  reply  [nested|flat] 22+ messages in thread

* Re: Another review of URI for libpq, v7 submission
  2012-03-15 08:49 Another review of URI for libpq, v7 submission Daniel Farina <[email protected]>
  2012-03-15 14:36 ` Re: Another review of URI for libpq, v7 submission Alex Shulgin <[email protected]>
  2012-03-15 21:09   ` Re: Another review of URI for libpq, v7 submission Daniel Farina <[email protected]>
  2012-03-15 21:29     ` Re: Another review of URI for libpq, v7 submission Alex <[email protected]>
  2012-03-17 14:51       ` Re: Another review of URI for libpq, v7 submission Marko Kreen <[email protected]>
  2012-03-20 22:18         ` Re: Another review of URI for libpq, v7 submission Alex <[email protected]>
  2012-03-22 21:42           ` Re: Another review of URI for libpq, v7 submission Alex <[email protected]>
  2012-03-27 17:22             ` Re: Another review of URI for libpq, v7 submission Peter Eisentraut <[email protected]>
  2012-03-27 19:21               ` Re: Another review of URI for libpq, v7 submission Alex <[email protected]>
  2012-03-27 22:49                 ` Re: Another review of URI for libpq, v7 submission Alex <[email protected]>
  2012-04-05 16:52                   ` Re: Another review of URI for libpq, v7 submission Peter Eisentraut <[email protected]>
  2012-04-05 22:10                     ` Re: Another review of URI for libpq, v7 submission Alvaro Herrera <[email protected]>
@ 2012-04-06 03:25                       ` Alvaro Herrera <[email protected]>
  2012-04-06 06:09                         ` Re: Another review of URI for libpq, v7 submission Peter Eisentraut <[email protected]>
  0 siblings, 1 reply; 22+ messages in thread

From: Alvaro Herrera @ 2012-04-06 03:25 UTC (permalink / raw)
  To: Peter Eisentraut <[email protected]>; +Cc: Alex <[email protected]>; Heikki Linnakangas <[email protected]>; pgsql-hackers

Excerpts from Alvaro Herrera's message of jue abr 05 19:10:25 -0300 2012:

> I think the only thing I'm not really sure about is the usage of the
> <synopsis> tag to mark example URIs in the docs.  It looks to me that
> they should mostly be <literal> instead, but I'm not really sure about
> that either -- I'm suspecting the PDF output would look rather horrible.

Some moments of radical thinking later, I became unhappy with the fact
that the conninfo stuff and parameter keywords are all crammed in the
PQconnectdbParams description.  This feels wrong to me, even more so
after we expand it even more to add URIs to the mix.  I think it's
better to create a separate sect1 (which I've entitled "Connection
Strings") which explains the conninfo and URI formats as well as
accepted keywords.  The new section is referenced from the multiple
places that need it, without having to point to PQconnectdbParams.

Thoughts?

Wording suggestions are welcome.

dblink_connect docs should also have a mention of URIs now:

alvherre=# select dblink_connect('postgresql://localhost:55432');
 dblink_connect 
----------------
 OK
(1 fila)


-- 
Álvaro Herrera <[email protected]>
The PostgreSQL Company - Command Prompt, Inc.
PostgreSQL Replication, Consulting, Custom Development, 24x7 support


Attachments:

  [application/octet-stream] libpq-docs.patch (49.1K, ../../[email protected]/2-libpq-docs.patch)
  download | inline diff:
diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index 0ec501e..568e456 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -119,7 +119,9 @@ PGconn *PQconnectdbParams(const char * const *keywords,
       <para>
        When <literal>expand_dbname</literal> is non-zero, the
        <parameter>dbname</parameter> key word value is allowed to be recognized
-       as a <parameter>conninfo</parameter> string. See below for details.
+       as a connection string. More details on that, as well as a list of
+       currently recognized parameter key words, appears in
+       <xref linkend="libpq-connstring">.
       </para>
 
       <para>
@@ -130,507 +132,6 @@ PGconn *PQconnectdbParams(const char * const *keywords,
       </para>
 
       <para>
-       The currently recognized parameter key words are:
-
-       <variablelist>
-        <varlistentry id="libpq-connect-host" xreflabel="host">
-         <term><literal>host</literal></term>
-         <listitem>
-          <para>
-           Name of host to connect to.<indexterm><primary>host name</></>
-           If this begins with a slash, it specifies Unix-domain
-           communication rather than TCP/IP communication; the value is the
-           name of the directory in which the socket file is stored.  The
-           default behavior when <literal>host</literal> is not specified
-           is to connect to a Unix-domain
-           socket<indexterm><primary>Unix domain socket</></> in
-           <filename>/tmp</filename> (or whatever socket directory was specified
-           when <productname>PostgreSQL</> was built). On machines without
-           Unix-domain sockets, the default is to connect to <literal>localhost</>.
-          </para>
-         </listitem>
-        </varlistentry>
-
-        <varlistentry id="libpq-connect-hostaddr" xreflabel="hostaddr">
-         <term><literal>hostaddr</literal></term>
-         <listitem>
-          <para>
-           Numeric IP address of host to connect to.  This should be in the
-           standard IPv4 address format, e.g., <literal>172.28.40.9</>.  If
-           your machine supports IPv6, you can also use those addresses.
-           TCP/IP communication is
-           always used when a nonempty string is specified for this parameter.
-          </para>
-
-          <para>
-           Using <literal>hostaddr</> instead of <literal>host</> allows the
-           application to avoid a host name look-up, which might be important
-           in applications with time constraints. However, a host name is
-           required for Kerberos, GSSAPI, or SSPI authentication
-           methods, as well as for <literal>verify-full</> SSL
-           certificate verification.  The following rules are used:
-           <itemizedlist>
-            <listitem>
-             <para>
-              If <literal>host</> is specified without <literal>hostaddr</>,
-              a host name lookup occurs.
-             </para>
-            </listitem>
-            <listitem>
-             <para>
-              If <literal>hostaddr</> is specified without <literal>host</>,
-              the value for <literal>hostaddr</> gives the server network address.
-              The connection attempt will fail if the authentication
-              method requires a host name.
-             </para>
-            </listitem>
-            <listitem>
-             <para>
-              If both <literal>host</> and <literal>hostaddr</> are specified,
-              the value for <literal>hostaddr</> gives the server network address.
-              The value for <literal>host</> is ignored unless the
-              authentication method requires it, in which case it will be
-              used as the host name.
-             </para>
-            </listitem>
-           </itemizedlist>
-           Note that authentication is likely to fail if <literal>host</>
-           is not the name of the server at network address <literal>hostaddr</>.
-           Also, note that <literal>host</> rather than <literal>hostaddr</>
-           is used to identify the connection in <filename>~/.pgpass</> (see
-           <xref linkend="libpq-pgpass">).
-          </para>
-
-          <para>
-           Without either a host name or host address,
-           <application>libpq</application> will connect using a
-           local Unix-domain socket; or on machines without Unix-domain
-           sockets, it will attempt to connect to <literal>localhost</>.
-          </para>
-          </listitem>
-         </varlistentry>
-
-         <varlistentry id="libpq-connect-port" xreflabel="port">
-          <term><literal>port</literal></term>
-          <listitem>
-          <para>
-           Port number to connect to at the server host, or socket file
-           name extension for Unix-domain
-           connections.<indexterm><primary>port</></>
-          </para>
-         </listitem>
-        </varlistentry>
-
-        <varlistentry id="libpq-connect-dbname" xreflabel="dbname">
-         <term><literal>dbname</literal></term>
-         <listitem>
-         <para>
-          The database name.  Defaults to be the same as the user name.
-         </para>
-         </listitem>
-        </varlistentry>
-
-        <varlistentry id="libpq-connect-user" xreflabel="user">
-         <term><literal>user</literal></term>
-         <listitem>
-         <para>
-          <productname>PostgreSQL</productname> user name to connect as.
-          Defaults to be the same as the operating system name of the user
-          running the application.
-         </para>
-         </listitem>
-        </varlistentry>
-
-        <varlistentry id="libpq-connect-password" xreflabel="password">
-         <term><literal>password</literal></term>
-         <listitem>
-         <para>
-          Password to be used if the server demands password authentication.
-         </para>
-         </listitem>
-        </varlistentry>
-
-        <varlistentry id="libpq-connect-connect-timeout" xreflabel="connect_timeout">
-         <term><literal>connect_timeout</literal></term>
-         <listitem>
-         <para>
-          Maximum wait for connection, in seconds (write as a decimal integer
-          string). Zero or not specified means wait indefinitely.  It is not
-          recommended to use a timeout of less than 2 seconds.
-         </para>
-         </listitem>
-        </varlistentry>
-
-        <varlistentry id="libpq-connect-client-encoding" xreflabel="client_encoding">
-         <term><literal>client_encoding</literal></term>
-         <listitem>
-         <para>
-          This sets the <varname>client_encoding</varname>
-          configuration parameter for this connection.  In addition to
-          the values accepted by the corresponding server option, you
-          can use <literal>auto</literal> to determine the right
-          encoding from the current locale in the client
-          (<envar>LC_CTYPE</envar> environment variable on Unix
-          systems).
-         </para>
-         </listitem>
-        </varlistentry>
-
-        <varlistentry id="libpq-connect-options" xreflabel="options">
-         <term><literal>options</literal></term>
-         <listitem>
-          <para>
-           Adds command-line options to send to the server at run-time.
-           For example, setting this to <literal>-c geqo=off</> sets the
-           session's value of the <varname>geqo</> parameter to
-           <literal>off</>.  For a detailed discussion of the available
-           options, consult <xref linkend="runtime-config">.
-          </para>
-         </listitem>
-        </varlistentry>
-
-        <varlistentry id="libpq-connect-application-name" xreflabel="application_name">
-         <term><literal>application_name</literal></term>
-         <listitem>
-          <para>
-           Specifies a value for the <xref linkend="guc-application-name">
-           configuration parameter.
-          </para>
-         </listitem>
-        </varlistentry>
-
-        <varlistentry id="libpq-connect-fallback-application-name" xreflabel="fallback_application_name">
-         <term><literal>fallback_application_name</literal></term>
-         <listitem>
-          <para>
-           Specifies a fallback value for the <xref
-           linkend="guc-application-name"> configuration parameter.
-           This value will be used if no value has been given for
-           <literal>application_name</> via a connection parameter or the
-           <envar>PGAPPNAME</envar> environment variable.  Specifying
-           a fallback name is useful in generic utility programs that
-           wish to set a default application name but allow it to be
-           overridden by the user.
-          </para>
-         </listitem>
-        </varlistentry>
-
-        <varlistentry id="libpq-keepalives" xreflabel="keepalives">
-         <term><literal>keepalives</literal></term>
-         <listitem>
-          <para>
-           Controls whether client-side TCP keepalives are used. The default
-           value is 1, meaning on, but you can change this to 0, meaning off,
-           if keepalives are not wanted.  This parameter is ignored for
-           connections made via a Unix-domain socket.
-          </para>
-         </listitem>
-        </varlistentry>
-
-        <varlistentry id="libpq-keepalives-idle" xreflabel="keepalives_idle">
-         <term><literal>keepalives_idle</literal></term>
-         <listitem>
-          <para>
-           Controls the number of seconds of inactivity after which TCP should
-           send a keepalive message to the server.  A value of zero uses the
-           system default. This parameter is ignored for connections made via a
-           Unix-domain socket, or if keepalives are disabled. It is only supported
-           on systems where the <symbol>TCP_KEEPIDLE</> or <symbol>TCP_KEEPALIVE</>
-           socket option is available, and on Windows; on other systems, it has no
-           effect.
-          </para>
-         </listitem>
-        </varlistentry>
-
-        <varlistentry id="libpq-keepalives-interval" xreflabel="keepalives_interval">
-         <term><literal>keepalives_interval</literal></term>
-         <listitem>
-          <para>
-           Controls the number of seconds after which a TCP keepalive message
-           that is not acknowledged by the server should be retransmitted.  A
-           value of zero uses the system default. This parameter is ignored for
-           connections made via a Unix-domain socket, or if keepalives are disabled.
-           It is only supported on systems where the <symbol>TCP_KEEPINTVL</>
-           socket option is available, and on Windows; on other systems, it has no
-           effect.
-          </para>
-         </listitem>
-        </varlistentry>
-
-        <varlistentry id="libpq-keepalives-count" xreflabel="keepalives_count">
-         <term><literal>keepalives_count</literal></term>
-         <listitem>
-          <para>
-           Controls the number of TCP keepalives that can be lost before the
-           client's connection to the server is considered dead.  A value of
-           zero uses the system default. This parameter is ignored for
-           connections made via a Unix-domain socket, or if keepalives are disabled.
-           It is only supported on systems where the <symbol>TCP_KEEPCNT</>
-           socket option is available; on other systems, it has no effect.
-          </para>
-         </listitem>
-        </varlistentry>
-
-        <varlistentry id="libpq-connect-tty" xreflabel="tty">
-         <term><literal>tty</literal></term>
-         <listitem>
-         <para>
-          Ignored (formerly, this specified where to send server debug output).
-         </para>
-         </listitem>
-        </varlistentry>
-
-        <varlistentry id="libpq-connect-sslmode" xreflabel="sslmode">
-         <term><literal>sslmode</literal></term>
-         <listitem>
-          <para>
-           This option determines whether or with what priority a secure
-           <acronym>SSL</> TCP/IP connection will be negotiated with the
-           server. There are six modes:
-
-           <variablelist>
-            <varlistentry>
-             <term><literal>disable</literal></term>
-             <listitem>
-              <para>
-               only try a non-<acronym>SSL</> connection
-              </para>
-             </listitem>
-            </varlistentry>
-
-            <varlistentry>
-             <term><literal>allow</literal></term>
-             <listitem>
-              <para>
-               first try a non-<acronym>SSL</> connection; if that
-               fails, try an <acronym>SSL</> connection
-              </para>
-             </listitem>
-            </varlistentry>
-
-            <varlistentry>
-             <term><literal>prefer</literal> (default)</term>
-             <listitem>
-              <para>
-               first try an <acronym>SSL</> connection; if that fails,
-               try a non-<acronym>SSL</> connection
-              </para>
-             </listitem>
-            </varlistentry>
-
-            <varlistentry>
-             <term><literal>require</literal></term>
-             <listitem>
-              <para>
-               only try an <acronym>SSL</> connection. If a root CA
-               file is present, verify the certificate in the same way as
-               if <literal>verify-ca</literal> was specified
-              </para>
-             </listitem>
-            </varlistentry>
-
-            <varlistentry>
-             <term><literal>verify-ca</literal></term>
-             <listitem>
-              <para>
-               only try an <acronym>SSL</> connection, and verify that
-               the server certificate is issued by a trusted
-               certificate authority (<acronym>CA</>)
-              </para>
-             </listitem>
-            </varlistentry>
-
-            <varlistentry>
-             <term><literal>verify-full</literal></term>
-             <listitem>
-              <para>
-               only try an <acronym>SSL</> connection, verify that the
-               server certificate is issued by a
-               trusted <acronym>CA</> and that the server host name
-               matches that in the certificate
-              </para>
-             </listitem>
-            </varlistentry>
-           </variablelist>
-
-           See <xref linkend="libpq-ssl"> for a detailed description of how
-           these options work.
-          </para>
-
-          <para>
-           <literal>sslmode</> is ignored for Unix domain socket
-           communication.
-           If <productname>PostgreSQL</> is compiled without SSL support,
-           using options <literal>require</>, <literal>verify-ca</>, or
-           <literal>verify-full</> will cause an error, while
-           options <literal>allow</> and <literal>prefer</> will be
-           accepted but <application>libpq</> will not actually attempt
-           an <acronym>SSL</>
-           connection.<indexterm><primary>SSL</><secondary
-           sortas="libpq">with libpq</></indexterm>
-          </para>
-         </listitem>
-        </varlistentry>
-
-        <varlistentry id="libpq-connect-requiressl" xreflabel="requiressl">
-         <term><literal>requiressl</literal></term>
-         <listitem>
-          <para>
-           This option is deprecated in favor of the <literal>sslmode</>
-           setting.
-          </para>
-
-          <para>
-           If set to 1, an <acronym>SSL</acronym> connection to the server
-           is required (this is equivalent to <literal>sslmode</>
-           <literal>require</>).  <application>libpq</> will then refuse
-           to connect if the server does not accept an
-           <acronym>SSL</acronym> connection.  If set to 0 (default),
-           <application>libpq</> will negotiate the connection type with
-           the server (equivalent to <literal>sslmode</>
-           <literal>prefer</>).  This option is only available if
-           <productname>PostgreSQL</> is compiled with SSL support.
-          </para>
-         </listitem>
-        </varlistentry>
-
-        <varlistentry id="libpq-connect-sslcompression" xreflabel="sslcompression">
-         <term><literal>sslcompression</literal></term>
-         <listitem>
-          <para>
-           If set to 1 (default), data sent over SSL connections will be
-           compressed (this requires <productname>OpenSSL</> version
-           0.9.8 or later).
-           If set to 0, compression will be disabled (this requires
-           <productname>OpenSSL</> 1.0.0 or later).
-           This parameter is ignored if a connection without SSL is made,
-           or if the version of <productname>OpenSSL</> used does not support
-           it.
-          </para>
-          <para>
-           Compression uses CPU time, but can improve throughput if
-           the network is the bottleneck.
-           Disabling compression can improve response time and throughput
-           if CPU performance is the limiting factor.
-          </para>
-         </listitem>
-        </varlistentry>
-
-        <varlistentry id="libpq-connect-sslcert" xreflabel="sslcert">
-         <term><literal>sslcert</literal></term>
-         <listitem>
-          <para>
-           This parameter specifies the file name of the client SSL
-           certificate, replacing the default
-           <filename>~/.postgresql/postgresql.crt</>.
-           This parameter is ignored if an SSL connection is not made.
-          </para>
-         </listitem>
-        </varlistentry>
-
-        <varlistentry id="libpq-connect-sslkey" xreflabel="sslkey">
-         <term><literal>sslkey</literal></term>
-         <listitem>
-          <para>
-           This parameter specifies the location for the secret key used for
-           the client certificate. It can either specify a file name that will
-           be used instead of the default
-           <filename>~/.postgresql/postgresql.key</>, or it can specify a key
-           obtained from an external <quote>engine</> (engines are
-           <productname>OpenSSL</> loadable modules).  An external engine
-           specification should consist of a colon-separated engine name and
-           an engine-specific key identifier.  This parameter is ignored if an
-           SSL connection is not made.
-          </para>
-         </listitem>
-        </varlistentry>
-
-        <varlistentry id="libpq-connect-sslrootcert" xreflabel="sslrootcert">
-         <term><literal>sslrootcert</literal></term>
-         <listitem>
-          <para>
-           This parameter specifies the name of a file containing SSL
-           certificate authority (<acronym>CA</>) certificate(s).
-           If the file exists, the server's certificate will be verified
-           to be signed by one of these authorities.  The default is
-           <filename>~/.postgresql/root.crt</>.
-          </para>
-         </listitem>
-        </varlistentry>
-
-        <varlistentry id="libpq-connect-sslcrl" xreflabel="sslcrl">
-         <term><literal>sslcrl</literal></term>
-         <listitem>
-          <para>
-           This parameter specifies the file name of the SSL certificate
-           revocation list (CRL).  Certificates listed in this file, if it
-           exists, will be rejected while attempting to authenticate the
-           server's certificate.  The default is
-           <filename>~/.postgresql/root.crl</>.
-          </para>
-         </listitem>
-        </varlistentry>
-
-        <varlistentry id="libpq-connect-requirepeer" xreflabel="requirepeer">
-         <term><literal>requirepeer</literal></term>
-         <listitem>
-          <para>
-           This parameter specifies the operating-system user name of the
-           server, for example <literal>requirepeer=postgres</literal>.
-           When making a Unix-domain socket connection, if this
-           parameter is set, the client checks at the beginning of the
-           connection that the server process is running under the specified
-           user name; if it is not, the connection is aborted with an error.
-           This parameter can be used to provide server authentication similar
-           to that available with SSL certificates on TCP/IP connections.
-           (Note that if the Unix-domain socket is in
-           <filename>/tmp</filename> or another publicly writable location,
-           any user could start a server listening there.  Use this parameter
-           to ensure that you are connected to a server run by a trusted user.)
-           This option is only supported on platforms for which the
-           <literal>peer</> authentication method is implemented; see
-           <xref linkend="auth-peer">.
-          </para>
-         </listitem>
-        </varlistentry>
-
-        <varlistentry id="libpq-connect-krbsrvname" xreflabel="krbsrvname">
-         <term><literal>krbsrvname</literal></term>
-         <listitem>
-          <para>
-           Kerberos service name to use when authenticating with Kerberos 5
-           or GSSAPI.
-           This must match the service name specified in the server
-           configuration for Kerberos authentication to succeed. (See also
-           <xref linkend="kerberos-auth"> and <xref linkend="gssapi-auth">.)
-          </para>
-         </listitem>
-        </varlistentry>
-
-        <varlistentry id="libpq-connect-gsslib" xreflabel="gsslib">
-         <term><literal>gsslib</literal></term>
-         <listitem>
-          <para>
-           GSS library to use for GSSAPI authentication. Only used on Windows.
-           Set to <literal>gssapi</literal> to force libpq to use the GSSAPI
-           library for authentication instead of the default SSPI.
-          </para>
-         </listitem>
-        </varlistentry>
-
-        <varlistentry id="libpq-connect-service" xreflabel="service">
-         <term><literal>service</literal></term>
-         <listitem>
-          <para>
-           Service name to use for additional parameters.  It specifies a service
-           name in <filename>pg_service.conf</filename> that holds additional connection parameters.
-           This allows applications to specify only a service name so connection parameters
-           can be centrally maintained. See <xref linkend="libpq-pgservice">.
-          </para>
-         </listitem>
-        </varlistentry>
-       </variablelist>
-
        If  any  parameter is unspecified, then the corresponding
        environment variable (see <xref linkend="libpq-envars">)
        is checked. If the  environment  variable is not set either,
@@ -638,20 +139,11 @@ PGconn *PQconnectdbParams(const char * const *keywords,
       </para>
 
       <para>
-        If <literal>expand_dbname</literal> is non-zero and
-        <parameter>dbname</parameter> contains an <symbol>=</symbol> sign, it
-        is taken as a <parameter>conninfo</parameter> string in exactly the same way as
-        if it had been passed to <function>PQconnectdb</function>(see below). Previously
-        processed key words will be overridden by key words in the
-        <parameter>conninfo</parameter> string.
-      </para>
-
-      <para>
-        In general key words are processed from the beginning of these arrays in index
-        order. The effect of this is that when key words are repeated, the last processed
-        value is retained. Therefore, through careful placement of the
-        <parameter>dbname</parameter> key word, it is possible to determine what may
-        be overridden by a <parameter>conninfo</parameter> string, and what may not.
+       In general key words are processed from the beginning of these arrays in index
+       order. The effect of this is that when key words are repeated, the last processed
+       value is retained. Therefore, through careful placement of the
+       <parameter>dbname</parameter> key word, it is possible to determine what may
+       be overridden by a <parameter>conninfo</parameter> string, and what may not.
       </para>
 
      </listitem>
@@ -675,19 +167,13 @@ PGconn *PQconnectdb(const char *conninfo);
 
       <para>
        The passed string can be empty to use all default parameters, or it can
-       contain one or more parameter settings separated by whitespace.
-       Each parameter setting is in the form <literal>keyword = value</literal>.
-       Spaces around the equal sign are optional. To write an empty value,
-       or a value containing spaces, surround it with single quotes, e.g.,
-       <literal>keyword = 'a value'</literal>. Single quotes and backslashes
-       within the value must be escaped with a backslash, i.e.,
-       <literal>\'</literal> and <literal>\\</literal>.
-      </para>
+       contain one or more parameter settings separated by whitespace,
+       or it can contain a <acronym>URI</acronym>.
+       See <xref linkend="libpq-connstring"> for details.
+     </para>
 
-      <para>
-       The currently recognized parameter key words are the same as above.
-      </para>
-     </listitem>
+
+    </listitem>
     </varlistentry>
 
     <varlistentry id="libpq-pqsetdblogin">
@@ -714,10 +200,11 @@ PGconn *PQsetdbLogin(const char *pghost,
       </para>
 
       <para>
-        If the <parameter>dbName</parameter> contains an <symbol>=</symbol> sign, it
+        If the <parameter>dbName</parameter> contains
+        an <symbol>=</symbol> sign or has a valid connection <acronym>URI</acronym> prefix, it
         is taken as a <parameter>conninfo</parameter> string in exactly the same way as
         if it had been passed to <function>PQconnectdb</function>, and the remaining
-        parameters are then applied as above.
+        parameters are then applied as specified in <xref linkend="libpq-connstring">.
       </para>
      </listitem>
     </varlistentry>
@@ -795,7 +282,7 @@ PostgresPollingStatusType PQconnectPoll(PGconn *conn);
          <para>
           The <literal>hostaddr</> and <literal>host</> parameters are used appropriately to ensure that
           name and reverse name queries are not made. See the documentation of
-          these parameters under <function>PQconnectdbParams</function> above for details.
+          these parameters in <xref linkend="libpq-connstring"> for details.
          </para>
         </listitem>
 
@@ -6428,6 +5915,607 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough)
   </sect2>
  </sect1>
 
+ <sect1 id="libpq-connstring">
+  <title>Connection Strings</title>
+
+  <indexterm zone="libpq-connstring">
+   <primary><literal>conninfo</literal></primary>
+  </indexterm>
+
+  <indexterm zone="libpq-connstring">
+   <primary><literal>URI</literal></primary>
+  </indexterm>
+
+  <para>
+   Several <application>libpq</> functions parse a user-specified string to obtain
+   connection parameters.  There are two accepted formats for these strings:
+   plain <literal>keyword = value</literal> strings, and URIs.
+  </para>
+
+  <para>
+   In the first format, each parameter setting is in the form
+   <literal>keyword = value</literal>.  Spaces around the equal sign are
+   optional. To write an empty value, or a value containing spaces, surround it
+   with single quotes, e.g., <literal>keyword = 'a value'</literal>. Single
+   quotes and backslashes within
+   the value must be escaped with a backslash, i.e., <literal>\'</literal> and
+   <literal>\\</literal>.
+  </para>
+
+  <para>
+   The currently recognized parameter key words are the same as listed below.
+  </para>
+
+  <para>
+  The general form for connection <acronym>URI</acronym> is the
+  following:
+<synopsis>
+postgresql://username:password@hostname:port/database?param1=value1&amp;param2=value2&amp;...
+</synopsis>
+  </para>
+
+  <para>
+   The <acronym>URI</acronym> designator can be
+   either <literal>postgresql://</literal> or
+   <literal>postgres://</literal> and each of the <acronym>URI</acronym> parts is
+   optional.  The following examples illustrate valid <acronym>URI</acronym> syntax
+   uses:
+<synopsis>
+postgresql://
+postgresql://localhost
+postgresql://localhost:5433
+postgresql://localhost/mydb
+postgresql://user@localhost
+postgresql://user:secret@localhost
+postgresql://other@localhost/otherdb
+</synopsis>
+  </para>
+
+  <para>
+   Additional connection parameters may optionally follow the base <acronym>URI</acronym>.
+   Any connection parameters not corresponding to key words listed
+   below are ignored and a warning message about them is sent to
+   <filename>stderr</filename>.
+  </para>
+
+  <para>
+   For improved compatibility with JDBC connection <acronym>URI</acronym>
+   syntax, instances of parameter <literal>ssl=true</literal> are translated
+   into <literal>sslmode=require</literal> (see above.)
+  </para>
+
+  <para>
+   Percent-encoding may be used to include a symbol with special
+   meaning in any of the <acronym>URI</acronym> parts.
+  </para>
+
+  <para>
+   The host part may be either hostname or an IP address.  To specify an
+   IPv6 host address, enclose it in square brackets:
+<synopsis>
+postgresql://[::1]/database
+</synopsis>
+   As a special case, a host part which starts with <symbol>/</symbol> is
+   treated as a local Unix socket directory to look for the connection
+   socket special file:
+<synopsis>
+postgresql:///path/to/pgsql/socket/dir
+</synopsis>
+   The whole connection string up to the extra parameters designator
+   (<symbol>?</symbol>) is treated as the absolute path to the socket
+   directory (<literal>/path/to/pgsql/socket/dir</literal> in this
+   example.)  To specify a non-default database name in this case use the
+   following syntax:
+<synopsis>
+postgresql:///path/to/pgsql/socket/dir?dbname=other
+</synopsis>
+  </para>
+
+  <para>
+   The currently recognized parameter key words are:
+
+   <variablelist>
+	<varlistentry id="libpq-connect-host" xreflabel="host">
+	 <term><literal>host</literal></term>
+	 <listitem>
+	  <para>
+	   Name of host to connect to.<indexterm><primary>host name</></>
+	   If this begins with a slash, it specifies Unix-domain
+	   communication rather than TCP/IP communication; the value is the
+	   name of the directory in which the socket file is stored.  The
+	   default behavior when <literal>host</literal> is not specified
+	   is to connect to a Unix-domain
+	   socket<indexterm><primary>Unix domain socket</></> in
+	   <filename>/tmp</filename> (or whatever socket directory was specified
+	   when <productname>PostgreSQL</> was built). On machines without
+	   Unix-domain sockets, the default is to connect to <literal>localhost</>.
+	  </para>
+	 </listitem>
+	</varlistentry>
+
+	<varlistentry id="libpq-connect-hostaddr" xreflabel="hostaddr">
+	 <term><literal>hostaddr</literal></term>
+	 <listitem>
+	  <para>
+	   Numeric IP address of host to connect to.  This should be in the
+	   standard IPv4 address format, e.g., <literal>172.28.40.9</>.  If
+	   your machine supports IPv6, you can also use those addresses.
+	   TCP/IP communication is
+	   always used when a nonempty string is specified for this parameter.
+	  </para>
+
+	  <para>
+	   Using <literal>hostaddr</> instead of <literal>host</> allows the
+	   application to avoid a host name look-up, which might be important
+	   in applications with time constraints. However, a host name is
+	   required for Kerberos, GSSAPI, or SSPI authentication
+	   methods, as well as for <literal>verify-full</> SSL
+	   certificate verification.  The following rules are used:
+	   <itemizedlist>
+		<listitem>
+		 <para>
+		  If <literal>host</> is specified without <literal>hostaddr</>,
+		  a host name lookup occurs.
+		 </para>
+		</listitem>
+		<listitem>
+		 <para>
+		  If <literal>hostaddr</> is specified without <literal>host</>,
+		  the value for <literal>hostaddr</> gives the server network address.
+		  The connection attempt will fail if the authentication
+		  method requires a host name.
+		 </para>
+		</listitem>
+		<listitem>
+		 <para>
+		  If both <literal>host</> and <literal>hostaddr</> are specified,
+		  the value for <literal>hostaddr</> gives the server network address.
+		  The value for <literal>host</> is ignored unless the
+		  authentication method requires it, in which case it will be
+		  used as the host name.
+		 </para>
+		</listitem>
+	   </itemizedlist>
+	   Note that authentication is likely to fail if <literal>host</>
+	   is not the name of the server at network address <literal>hostaddr</>.
+	   Also, note that <literal>host</> rather than <literal>hostaddr</>
+	   is used to identify the connection in <filename>~/.pgpass</> (see
+	   <xref linkend="libpq-pgpass">).
+	  </para>
+
+	  <para>
+	   Without either a host name or host address,
+	   <application>libpq</application> will connect using a
+	   local Unix-domain socket; or on machines without Unix-domain
+	   sockets, it will attempt to connect to <literal>localhost</>.
+	  </para>
+	  </listitem>
+	 </varlistentry>
+
+	 <varlistentry id="libpq-connect-port" xreflabel="port">
+	  <term><literal>port</literal></term>
+	  <listitem>
+	  <para>
+	   Port number to connect to at the server host, or socket file
+	   name extension for Unix-domain
+	   connections.<indexterm><primary>port</></>
+	  </para>
+	 </listitem>
+	</varlistentry>
+
+	<varlistentry id="libpq-connect-dbname" xreflabel="dbname">
+	 <term><literal>dbname</literal></term>
+	 <listitem>
+	 <para>
+	  The database name.  Defaults to be the same as the user name.
+	  See <xref linkend="libpq-connstring"> for more details.
+	 </para>
+	 </listitem>
+	</varlistentry>
+
+	<varlistentry id="libpq-connect-user" xreflabel="user">
+	 <term><literal>user</literal></term>
+	 <listitem>
+	 <para>
+	  <productname>PostgreSQL</productname> user name to connect as.
+	  Defaults to be the same as the operating system name of the user
+	  running the application.
+	 </para>
+	 </listitem>
+	</varlistentry>
+
+	<varlistentry id="libpq-connect-password" xreflabel="password">
+	 <term><literal>password</literal></term>
+	 <listitem>
+	 <para>
+	  Password to be used if the server demands password authentication.
+	 </para>
+	 </listitem>
+	</varlistentry>
+
+	<varlistentry id="libpq-connect-connect-timeout" xreflabel="connect_timeout">
+	 <term><literal>connect_timeout</literal></term>
+	 <listitem>
+	 <para>
+	  Maximum wait for connection, in seconds (write as a decimal integer
+	  string). Zero or not specified means wait indefinitely.  It is not
+	  recommended to use a timeout of less than 2 seconds.
+	 </para>
+	 </listitem>
+	</varlistentry>
+
+	<varlistentry id="libpq-connect-client-encoding" xreflabel="client_encoding">
+	 <term><literal>client_encoding</literal></term>
+	 <listitem>
+	 <para>
+	  This sets the <varname>client_encoding</varname>
+	  configuration parameter for this connection.  In addition to
+	  the values accepted by the corresponding server option, you
+	  can use <literal>auto</literal> to determine the right
+	  encoding from the current locale in the client
+	  (<envar>LC_CTYPE</envar> environment variable on Unix
+	  systems).
+	 </para>
+	 </listitem>
+	</varlistentry>
+
+	<varlistentry id="libpq-connect-options" xreflabel="options">
+	 <term><literal>options</literal></term>
+	 <listitem>
+	  <para>
+	   Adds command-line options to send to the server at run-time.
+	   For example, setting this to <literal>-c geqo=off</> sets the
+	   session's value of the <varname>geqo</> parameter to
+	   <literal>off</>.  For a detailed discussion of the available
+	   options, consult <xref linkend="runtime-config">.
+	  </para>
+	 </listitem>
+	</varlistentry>
+
+	<varlistentry id="libpq-connect-application-name" xreflabel="application_name">
+	 <term><literal>application_name</literal></term>
+	 <listitem>
+	  <para>
+	   Specifies a value for the <xref linkend="guc-application-name">
+	   configuration parameter.
+	  </para>
+	 </listitem>
+	</varlistentry>
+
+	<varlistentry id="libpq-connect-fallback-application-name" xreflabel="fallback_application_name">
+	 <term><literal>fallback_application_name</literal></term>
+	 <listitem>
+	  <para>
+	   Specifies a fallback value for the <xref
+	   linkend="guc-application-name"> configuration parameter.
+	   This value will be used if no value has been given for
+	   <literal>application_name</> via a connection parameter or the
+	   <envar>PGAPPNAME</envar> environment variable.  Specifying
+	   a fallback name is useful in generic utility programs that
+	   wish to set a default application name but allow it to be
+	   overridden by the user.
+	  </para>
+	 </listitem>
+	</varlistentry>
+
+	<varlistentry id="libpq-keepalives" xreflabel="keepalives">
+	 <term><literal>keepalives</literal></term>
+	 <listitem>
+	  <para>
+	   Controls whether client-side TCP keepalives are used. The default
+	   value is 1, meaning on, but you can change this to 0, meaning off,
+	   if keepalives are not wanted.  This parameter is ignored for
+	   connections made via a Unix-domain socket.
+	  </para>
+	 </listitem>
+	</varlistentry>
+
+	<varlistentry id="libpq-keepalives-idle" xreflabel="keepalives_idle">
+	 <term><literal>keepalives_idle</literal></term>
+	 <listitem>
+	  <para>
+	   Controls the number of seconds of inactivity after which TCP should
+	   send a keepalive message to the server.  A value of zero uses the
+	   system default. This parameter is ignored for connections made via a
+	   Unix-domain socket, or if keepalives are disabled. It is only supported
+	   on systems where the <symbol>TCP_KEEPIDLE</> or <symbol>TCP_KEEPALIVE</>
+	   socket option is available, and on Windows; on other systems, it has no
+	   effect.
+	  </para>
+	 </listitem>
+	</varlistentry>
+
+	<varlistentry id="libpq-keepalives-interval" xreflabel="keepalives_interval">
+	 <term><literal>keepalives_interval</literal></term>
+	 <listitem>
+	  <para>
+	   Controls the number of seconds after which a TCP keepalive message
+	   that is not acknowledged by the server should be retransmitted.  A
+	   value of zero uses the system default. This parameter is ignored for
+	   connections made via a Unix-domain socket, or if keepalives are disabled.
+	   It is only supported on systems where the <symbol>TCP_KEEPINTVL</>
+	   socket option is available, and on Windows; on other systems, it has no
+	   effect.
+	  </para>
+	 </listitem>
+	</varlistentry>
+
+	<varlistentry id="libpq-keepalives-count" xreflabel="keepalives_count">
+	 <term><literal>keepalives_count</literal></term>
+	 <listitem>
+	  <para>
+	   Controls the number of TCP keepalives that can be lost before the
+	   client's connection to the server is considered dead.  A value of
+	   zero uses the system default. This parameter is ignored for
+	   connections made via a Unix-domain socket, or if keepalives are disabled.
+	   It is only supported on systems where the <symbol>TCP_KEEPCNT</>
+	   socket option is available; on other systems, it has no effect.
+	  </para>
+	 </listitem>
+	</varlistentry>
+
+	<varlistentry id="libpq-connect-tty" xreflabel="tty">
+	 <term><literal>tty</literal></term>
+	 <listitem>
+	 <para>
+	  Ignored (formerly, this specified where to send server debug output).
+	 </para>
+	 </listitem>
+	</varlistentry>
+
+	<varlistentry id="libpq-connect-sslmode" xreflabel="sslmode">
+	 <term><literal>sslmode</literal></term>
+	 <listitem>
+	  <para>
+	   This option determines whether or with what priority a secure
+	   <acronym>SSL</> TCP/IP connection will be negotiated with the
+	   server. There are six modes:
+
+	   <variablelist>
+		<varlistentry>
+		 <term><literal>disable</literal></term>
+		 <listitem>
+		  <para>
+		   only try a non-<acronym>SSL</> connection
+		  </para>
+		 </listitem>
+		</varlistentry>
+
+		<varlistentry>
+		 <term><literal>allow</literal></term>
+		 <listitem>
+		  <para>
+		   first try a non-<acronym>SSL</> connection; if that
+		   fails, try an <acronym>SSL</> connection
+		  </para>
+		 </listitem>
+		</varlistentry>
+
+		<varlistentry>
+		 <term><literal>prefer</literal> (default)</term>
+		 <listitem>
+		  <para>
+		   first try an <acronym>SSL</> connection; if that fails,
+		   try a non-<acronym>SSL</> connection
+		  </para>
+		 </listitem>
+		</varlistentry>
+
+		<varlistentry>
+		 <term><literal>require</literal></term>
+		 <listitem>
+		  <para>
+		   only try an <acronym>SSL</> connection. If a root CA
+		   file is present, verify the certificate in the same way as
+		   if <literal>verify-ca</literal> was specified
+		  </para>
+		 </listitem>
+		</varlistentry>
+
+		<varlistentry>
+		 <term><literal>verify-ca</literal></term>
+		 <listitem>
+		  <para>
+		   only try an <acronym>SSL</> connection, and verify that
+		   the server certificate is issued by a trusted
+		   certificate authority (<acronym>CA</>)
+		  </para>
+		 </listitem>
+		</varlistentry>
+
+		<varlistentry>
+		 <term><literal>verify-full</literal></term>
+		 <listitem>
+		  <para>
+		   only try an <acronym>SSL</> connection, verify that the
+		   server certificate is issued by a
+		   trusted <acronym>CA</> and that the server host name
+		   matches that in the certificate
+		  </para>
+		 </listitem>
+		</varlistentry>
+	   </variablelist>
+
+	   See <xref linkend="libpq-ssl"> for a detailed description of how
+	   these options work.
+	  </para>
+
+	  <para>
+	   <literal>sslmode</> is ignored for Unix domain socket
+	   communication.
+	   If <productname>PostgreSQL</> is compiled without SSL support,
+	   using options <literal>require</>, <literal>verify-ca</>, or
+	   <literal>verify-full</> will cause an error, while
+	   options <literal>allow</> and <literal>prefer</> will be
+	   accepted but <application>libpq</> will not actually attempt
+	   an <acronym>SSL</>
+	   connection.<indexterm><primary>SSL</><secondary
+	   sortas="libpq">with libpq</></indexterm>
+	  </para>
+	 </listitem>
+	</varlistentry>
+
+	<varlistentry id="libpq-connect-requiressl" xreflabel="requiressl">
+	 <term><literal>requiressl</literal></term>
+	 <listitem>
+	  <para>
+	   This option is deprecated in favor of the <literal>sslmode</>
+	   setting.
+	  </para>
+
+	  <para>
+	   If set to 1, an <acronym>SSL</acronym> connection to the server
+	   is required (this is equivalent to <literal>sslmode</>
+	   <literal>require</>).  <application>libpq</> will then refuse
+	   to connect if the server does not accept an
+	   <acronym>SSL</acronym> connection.  If set to 0 (default),
+	   <application>libpq</> will negotiate the connection type with
+	   the server (equivalent to <literal>sslmode</>
+	   <literal>prefer</>).  This option is only available if
+	   <productname>PostgreSQL</> is compiled with SSL support.
+	  </para>
+	 </listitem>
+	</varlistentry>
+
+	<varlistentry id="libpq-connect-sslcompression" xreflabel="sslcompression">
+	 <term><literal>sslcompression</literal></term>
+	 <listitem>
+	  <para>
+	   If set to 1 (default), data sent over SSL connections will be
+	   compressed (this requires <productname>OpenSSL</> version
+	   0.9.8 or later).
+	   If set to 0, compression will be disabled (this requires
+	   <productname>OpenSSL</> 1.0.0 or later).
+	   This parameter is ignored if a connection without SSL is made,
+	   or if the version of <productname>OpenSSL</> used does not support
+	   it.
+	  </para>
+	  <para>
+	   Compression uses CPU time, but can improve throughput if
+	   the network is the bottleneck.
+	   Disabling compression can improve response time and throughput
+	   if CPU performance is the limiting factor.
+	  </para>
+	 </listitem>
+	</varlistentry>
+
+	<varlistentry id="libpq-connect-sslcert" xreflabel="sslcert">
+	 <term><literal>sslcert</literal></term>
+	 <listitem>
+	  <para>
+	   This parameter specifies the file name of the client SSL
+	   certificate, replacing the default
+	   <filename>~/.postgresql/postgresql.crt</>.
+	   This parameter is ignored if an SSL connection is not made.
+	  </para>
+	 </listitem>
+	</varlistentry>
+
+	<varlistentry id="libpq-connect-sslkey" xreflabel="sslkey">
+	 <term><literal>sslkey</literal></term>
+	 <listitem>
+	  <para>
+	   This parameter specifies the location for the secret key used for
+	   the client certificate. It can either specify a file name that will
+	   be used instead of the default
+	   <filename>~/.postgresql/postgresql.key</>, or it can specify a key
+	   obtained from an external <quote>engine</> (engines are
+	   <productname>OpenSSL</> loadable modules).  An external engine
+	   specification should consist of a colon-separated engine name and
+	   an engine-specific key identifier.  This parameter is ignored if an
+	   SSL connection is not made.
+	  </para>
+	 </listitem>
+	</varlistentry>
+
+	<varlistentry id="libpq-connect-sslrootcert" xreflabel="sslrootcert">
+	 <term><literal>sslrootcert</literal></term>
+	 <listitem>
+	  <para>
+	   This parameter specifies the name of a file containing SSL
+	   certificate authority (<acronym>CA</>) certificate(s).
+	   If the file exists, the server's certificate will be verified
+	   to be signed by one of these authorities.  The default is
+	   <filename>~/.postgresql/root.crt</>.
+	  </para>
+	 </listitem>
+	</varlistentry>
+
+	<varlistentry id="libpq-connect-sslcrl" xreflabel="sslcrl">
+	 <term><literal>sslcrl</literal></term>
+	 <listitem>
+	  <para>
+	   This parameter specifies the file name of the SSL certificate
+	   revocation list (CRL).  Certificates listed in this file, if it
+	   exists, will be rejected while attempting to authenticate the
+	   server's certificate.  The default is
+	   <filename>~/.postgresql/root.crl</>.
+	  </para>
+	 </listitem>
+	</varlistentry>
+
+	<varlistentry id="libpq-connect-requirepeer" xreflabel="requirepeer">
+	 <term><literal>requirepeer</literal></term>
+	 <listitem>
+	  <para>
+	   This parameter specifies the operating-system user name of the
+	   server, for example <literal>requirepeer=postgres</literal>.
+	   When making a Unix-domain socket connection, if this
+	   parameter is set, the client checks at the beginning of the
+	   connection that the server process is running under the specified
+	   user name; if it is not, the connection is aborted with an error.
+	   This parameter can be used to provide server authentication similar
+	   to that available with SSL certificates on TCP/IP connections.
+	   (Note that if the Unix-domain socket is in
+	   <filename>/tmp</filename> or another publicly writable location,
+	   any user could start a server listening there.  Use this parameter
+	   to ensure that you are connected to a server run by a trusted user.)
+	   This option is only supported on platforms for which the
+	   <literal>peer</> authentication method is implemented; see
+	   <xref linkend="auth-peer">.
+	  </para>
+	 </listitem>
+	</varlistentry>
+
+	<varlistentry id="libpq-connect-krbsrvname" xreflabel="krbsrvname">
+	 <term><literal>krbsrvname</literal></term>
+	 <listitem>
+	  <para>
+	   Kerberos service name to use when authenticating with Kerberos 5
+	   or GSSAPI.
+	   This must match the service name specified in the server
+	   configuration for Kerberos authentication to succeed. (See also
+	   <xref linkend="kerberos-auth"> and <xref linkend="gssapi-auth">.)
+	  </para>
+	 </listitem>
+	</varlistentry>
+
+	<varlistentry id="libpq-connect-gsslib" xreflabel="gsslib">
+	 <term><literal>gsslib</literal></term>
+	 <listitem>
+	  <para>
+	   GSS library to use for GSSAPI authentication. Only used on Windows.
+	   Set to <literal>gssapi</literal> to force libpq to use the GSSAPI
+	   library for authentication instead of the default SSPI.
+	  </para>
+	 </listitem>
+	</varlistentry>
+
+	<varlistentry id="libpq-connect-service" xreflabel="service">
+	 <term><literal>service</literal></term>
+	 <listitem>
+	  <para>
+	   Service name to use for additional parameters.  It specifies a service
+	   name in <filename>pg_service.conf</filename> that holds additional connection parameters.
+	   This allows applications to specify only a service name so connection parameters
+	   can be centrally maintained. See <xref linkend="libpq-pgservice">.
+	  </para>
+	 </listitem>
+	</varlistentry>
+   </variablelist>
+  </para>
+ </sect1> 
+
  <sect1 id="libpq-envars">
   <title>Environment Variables</title>
 
@@ -6832,6 +6920,7 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough)
  </sect1>
 
 
+
  <sect1 id="libpq-pgservice">
   <title>The Connection Service File</title>
 
diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml
index b849101..bdcadf3 100644
--- a/doc/src/sgml/ref/psql-ref.sgml
+++ b/doc/src/sgml/ref/psql-ref.sgml
@@ -115,7 +115,10 @@ PostgreSQL documentation
        argument on the command line.
       </para>
       <para>
-       If this parameter contains an <symbol>=</symbol> sign, it is treated as a
+       If this parameter contains an <symbol>=</symbol> sign or starts
+       with a valid <acronym>URI</acronym> prefix
+       (<literal>postgresql://</literal>
+       or <literal>postgres://</literal>), it is treated as a
        <parameter>conninfo</parameter> string. See <xref linkend="libpq-connect"> for more information.
       </para>
       </listitem>
@@ -596,11 +599,13 @@ PostgreSQL documentation
 
     <para>
      An alternative way to specify connection parameters is in a
-     <parameter>conninfo</parameter> string, which is used instead of a
-     database name. This mechanism give you very wide control over the
+     <parameter>conninfo</parameter> string or
+     a <acronym>URI</acronym>, which is used instead of a database
+     name. This mechanism give you very wide control over the
      connection. For example:
 <programlisting>
 $ <userinput>psql "service=myservice sslmode=require"</userinput>
+$ <userinput>psql postgresql://dbmaster:5433/mydb?sslmode=require</userinput>
 </programlisting>
      This way you can also use LDAP for connection parameter lookup as
      described in <xref linkend="libpq-ldap">.


^ permalink  raw  reply  [nested|flat] 22+ messages in thread

* Re: Another review of URI for libpq, v7 submission
  2012-03-15 08:49 Another review of URI for libpq, v7 submission Daniel Farina <[email protected]>
  2012-03-15 14:36 ` Re: Another review of URI for libpq, v7 submission Alex Shulgin <[email protected]>
  2012-03-15 21:09   ` Re: Another review of URI for libpq, v7 submission Daniel Farina <[email protected]>
  2012-03-15 21:29     ` Re: Another review of URI for libpq, v7 submission Alex <[email protected]>
  2012-03-17 14:51       ` Re: Another review of URI for libpq, v7 submission Marko Kreen <[email protected]>
  2012-03-20 22:18         ` Re: Another review of URI for libpq, v7 submission Alex <[email protected]>
  2012-03-22 21:42           ` Re: Another review of URI for libpq, v7 submission Alex <[email protected]>
  2012-03-27 17:22             ` Re: Another review of URI for libpq, v7 submission Peter Eisentraut <[email protected]>
  2012-03-27 19:21               ` Re: Another review of URI for libpq, v7 submission Alex <[email protected]>
  2012-03-27 22:49                 ` Re: Another review of URI for libpq, v7 submission Alex <[email protected]>
  2012-04-05 16:52                   ` Re: Another review of URI for libpq, v7 submission Peter Eisentraut <[email protected]>
  2012-04-05 22:10                     ` Re: Another review of URI for libpq, v7 submission Alvaro Herrera <[email protected]>
  2012-04-06 03:25                       ` Re: Another review of URI for libpq, v7 submission Alvaro Herrera <[email protected]>
@ 2012-04-06 06:09                         ` Peter Eisentraut <[email protected]>
  2012-04-09 19:41                           ` Re: Another review of URI for libpq, v7 submission Alvaro Herrera <[email protected]>
  0 siblings, 1 reply; 22+ messages in thread

From: Peter Eisentraut @ 2012-04-06 06:09 UTC (permalink / raw)
  To: Alvaro Herrera <[email protected]>; +Cc: Alex <[email protected]>; Heikki Linnakangas <[email protected]>; pgsql-hackers

On fre, 2012-04-06 at 00:25 -0300, Alvaro Herrera wrote:
> Some moments of radical thinking later, I became unhappy with the fact
> that the conninfo stuff and parameter keywords are all crammed in the
> PQconnectdbParams description.  This feels wrong to me, even more so
> after we expand it even more to add URIs to the mix.  I think it's
> better to create a separate sect1 (which I've entitled "Connection
> Strings") which explains the conninfo and URI formats as well as
> accepted keywords.  The new section is referenced from the multiple
> places that need it, without having to point to PQconnectdbParams.

Yes, it should be split out.  But the libpq chapter already has too many
tiny sect1s.  I think it should be a sect2 under "Database Connection
Control".





^ permalink  raw  reply  [nested|flat] 22+ messages in thread

* Re: Another review of URI for libpq, v7 submission
  2012-03-15 08:49 Another review of URI for libpq, v7 submission Daniel Farina <[email protected]>
  2012-03-15 14:36 ` Re: Another review of URI for libpq, v7 submission Alex Shulgin <[email protected]>
  2012-03-15 21:09   ` Re: Another review of URI for libpq, v7 submission Daniel Farina <[email protected]>
  2012-03-15 21:29     ` Re: Another review of URI for libpq, v7 submission Alex <[email protected]>
  2012-03-17 14:51       ` Re: Another review of URI for libpq, v7 submission Marko Kreen <[email protected]>
  2012-03-20 22:18         ` Re: Another review of URI for libpq, v7 submission Alex <[email protected]>
  2012-03-22 21:42           ` Re: Another review of URI for libpq, v7 submission Alex <[email protected]>
  2012-03-27 17:22             ` Re: Another review of URI for libpq, v7 submission Peter Eisentraut <[email protected]>
  2012-03-27 19:21               ` Re: Another review of URI for libpq, v7 submission Alex <[email protected]>
  2012-03-27 22:49                 ` Re: Another review of URI for libpq, v7 submission Alex <[email protected]>
  2012-04-05 16:52                   ` Re: Another review of URI for libpq, v7 submission Peter Eisentraut <[email protected]>
  2012-04-05 22:10                     ` Re: Another review of URI for libpq, v7 submission Alvaro Herrera <[email protected]>
  2012-04-06 03:25                       ` Re: Another review of URI for libpq, v7 submission Alvaro Herrera <[email protected]>
  2012-04-06 06:09                         ` Re: Another review of URI for libpq, v7 submission Peter Eisentraut <[email protected]>
@ 2012-04-09 19:41                           ` Alvaro Herrera <[email protected]>
  2012-04-11 07:46                             ` Re: Another review of URI for libpq, v7 submission Alvaro Herrera <[email protected]>
  0 siblings, 1 reply; 22+ messages in thread

From: Alvaro Herrera @ 2012-04-09 19:41 UTC (permalink / raw)
  To: Peter Eisentraut <[email protected]>; +Cc: Alex <[email protected]>; Heikki Linnakangas <[email protected]>; pgsql-hackers

Excerpts from Peter Eisentraut's message of vie abr 06 03:09:10 -0300 2012:
> On fre, 2012-04-06 at 00:25 -0300, Alvaro Herrera wrote:
> > Some moments of radical thinking later, I became unhappy with the fact
> > that the conninfo stuff and parameter keywords are all crammed in the
> > PQconnectdbParams description.  This feels wrong to me, even more so
> > after we expand it even more to add URIs to the mix.  I think it's
> > better to create a separate sect1 (which I've entitled "Connection
> > Strings") which explains the conninfo and URI formats as well as
> > accepted keywords.  The new section is referenced from the multiple
> > places that need it, without having to point to PQconnectdbParams.
> 
> Yes, it should be split out.  But the libpq chapter already has too many
> tiny sect1s.  I think it should be a sect2 under "Database Connection
> Control".

Thanks, that seems a good idea.  I have tweaked things slightly and it
looks pretty decent to me.  Wording improvements are welcome.  The file
in its entirety can be seen here:
https://github.com/alvherre/postgres/blob/uri/doc/src/sgml/libpq.sgml
The new bits start at line 1224.  I also attach the HTML output for easy
reading.  (I wonder if it's going to be visible in the archives).

There are three minor things that need to be changed for this to be
committable:

1. it depends on strtok_r which is likely to be a problem in MSVC++ and
perhaps older Unix platforms as well.

2. The ssl=true trick being converted into sslmode=require doesn't work
if the URI specifies them uri-encoded, which seems bogus.

3. if an unknown keyword is uri-encoded, the error message displays it
still uri-encoded.  Seems to me it'd be better to uri-decode it before
throwing error.

Alexander says he's going to work on these and then I'll finally commit it.

-- 
Álvaro Herrera <[email protected]>
The PostgreSQL Company - Command Prompt, Inc.
PostgreSQL Replication, Consulting, Custom Development, 24x7 support


Attachments:

  [text/html] libpq-connect.html (49.3K, ../../[email protected]/2-libpq-connect.html)
  download | inline:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>Database Connection Control Functions</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REV="MADE"
HREF="mailto:[email protected]"><LINK
REL="HOME"
TITLE="PostgreSQL 9.2devel Documentation"
HREF="index.html"><LINK
REL="UP"
TITLE="libpq - C Library"
HREF="libpq.html"><LINK
REL="PREVIOUS"
TITLE="libpq - C Library"
HREF="libpq.html"><LINK
REL="NEXT"
TITLE="Connection Status Functions"
HREF="libpq-status.html"><LINK
REL="STYLESHEET"
TYPE="text/css"
HREF="stylesheet.css"><META
HTTP-EQUIV="Content-Type"
CONTENT="text/html; charset=ISO-8859-1"><META
NAME="creation"
CONTENT="2012-04-09T19:26:53"></HEAD
><BODY
CLASS="SECT1"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="5"
ALIGN="center"
VALIGN="bottom"
><A
HREF="index.html"
>PostgreSQL 9.2devel Documentation</A
></TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="top"
><A
TITLE="libpq - C Library"
HREF="libpq.html"
ACCESSKEY="P"
>Prev</A
></TD
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="top"
><A
HREF="libpq.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="60%"
ALIGN="center"
VALIGN="bottom"
>Chapter 31. <SPAN
CLASS="APPLICATION"
>libpq</SPAN
> - C Library</TD
><TD
WIDTH="20%"
ALIGN="right"
VALIGN="top"
><A
TITLE="Connection Status Functions"
HREF="libpq-status.html"
ACCESSKEY="N"
>Next</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECT1"
><H1
CLASS="SECT1"
><A
NAME="LIBPQ-CONNECT"
>31.1. Database Connection Control Functions</A
></H1
><P
>   The following functions deal with making a connection to a
   <SPAN
CLASS="PRODUCTNAME"
>PostgreSQL</SPAN
> backend server.  An
   application program can have several backend connections open at
   one time.  (One reason to do that is to access more than one
   database.)  Each connection is represented by a
   <TT
CLASS="STRUCTNAME"
>PGconn</TT
> object, which
   is obtained from the function <CODE
CLASS="FUNCTION"
>PQconnectdb</CODE
>,
   <CODE
CLASS="FUNCTION"
>PQconnectdbParams</CODE
>, or
   <CODE
CLASS="FUNCTION"
>PQsetdbLogin</CODE
>.  Note that these functions will always
   return a non-null object pointer, unless perhaps there is too
   little memory even to allocate the <TT
CLASS="STRUCTNAME"
>PGconn</TT
> object.
   The <CODE
CLASS="FUNCTION"
>PQstatus</CODE
> function should be called to check
   the return value for a successful connection before queries are sent
   via the connection object.

   <DIV
CLASS="WARNING"
><P
></P
><TABLE
CLASS="WARNING"
BORDER="1"
WIDTH="100%"
><TR
><TD
ALIGN="CENTER"
><B
>Warning</B
></TD
></TR
><TR
><TD
ALIGN="LEFT"
><P
>     On Unix, forking a process with open libpq connections can lead to
     unpredictable results because the parent and child processes share
     the same sockets and operating system resources.  For this reason,
     such usage is not recommended, though doing an <CODE
CLASS="FUNCTION"
>exec</CODE
> from
     the child process to load a new executable is safe.
    </P
></TD
></TR
></TABLE
></DIV
>

   </P><DIV
CLASS="NOTE"
><BLOCKQUOTE
CLASS="NOTE"
><P
><B
>Note: </B
>     On Windows, there is a way to improve performance if a single
     database connection is repeatedly started and shutdown.  Internally,
     libpq calls <CODE
CLASS="FUNCTION"
>WSAStartup()</CODE
> and <CODE
CLASS="FUNCTION"
>WSACleanup()</CODE
> for connection startup
     and shutdown, respectively.  <CODE
CLASS="FUNCTION"
>WSAStartup()</CODE
> increments an internal
     Windows library reference count which is decremented by <CODE
CLASS="FUNCTION"
>WSACleanup()</CODE
>.
     When the reference count is just one, calling <CODE
CLASS="FUNCTION"
>WSACleanup()</CODE
> frees
     all resources and all DLLs are unloaded.  This is an expensive
     operation.  To avoid this, an application can manually call
     <CODE
CLASS="FUNCTION"
>WSAStartup()</CODE
> so resources will not be freed when the last database
     connection is closed.
    </P
></BLOCKQUOTE
></DIV
><P>

   <P
></P
></P><DIV
CLASS="VARIABLELIST"
><DL
><DT
><A
NAME="LIBPQ-PQCONNECTDBPARAMS"
></A
><CODE
CLASS="FUNCTION"
>PQconnectdbParams</CODE
></DT
><DD
><P
>       Makes a new connection to the database server.

</P><PRE
CLASS="SYNOPSIS"
>PGconn *PQconnectdbParams(const char * const *keywords,
                          const char * const *values,
                          int expand_dbname);</PRE
><P>
      </P
><P
>       This function opens a new database connection using the parameters taken
       from two <TT
CLASS="SYMBOL"
>NULL</TT
>-terminated arrays. The first,
       <TT
CLASS="LITERAL"
>keywords</TT
>, is defined as an array of strings, each one
       being a key word. The second, <TT
CLASS="LITERAL"
>values</TT
>, gives the value
       for each key word. Unlike <CODE
CLASS="FUNCTION"
>PQsetdbLogin</CODE
> below, the parameter
       set can be extended without changing the function signature, so use of
       this function (or its nonblocking analogs <CODE
CLASS="FUNCTION"
>PQconnectStartParams</CODE
>
       and <CODE
CLASS="FUNCTION"
>PQconnectPoll</CODE
>) is preferred for new application
       programming.
      </P
><P
>       The currently recognized parameter key words are listed in
       <A
HREF="libpq-connect.html#LIBPQ-PARAMKEYWORDS"
>Section 31.1.1</A
>.
      </P
><P
>       When <TT
CLASS="LITERAL"
>expand_dbname</TT
> is non-zero, the
       <TT
CLASS="PARAMETER"
>dbname</TT
> key word value is allowed to be recognized
       as a connection string. More details on the possible formats appear in 
       <A
HREF="libpq-connect.html#LIBPQ-CONNSTRING"
>Section 31.1.2</A
>.
      </P
><P
>       The passed arrays can be empty to use all default parameters, or can
       contain one or more parameter settings. They should be matched in length.
       Processing will stop with the last non-<TT
CLASS="SYMBOL"
>NULL</TT
> element
       of the <TT
CLASS="LITERAL"
>keywords</TT
> array.
      </P
><P
>       If  any  parameter is unspecified, then the corresponding
       environment variable (see <A
HREF="libpq-envars.html"
>Section 31.14</A
>)
       is checked. If the  environment  variable is not set either,
       then the indicated built-in defaults are used.
      </P
><P
>       In general key words are processed from the beginning of these arrays in index
       order. The effect of this is that when key words are repeated, the last processed
       value is retained. Therefore, through careful placement of the
       <TT
CLASS="PARAMETER"
>dbname</TT
> key word, it is possible to determine what may
       be overridden by a <TT
CLASS="PARAMETER"
>conninfo</TT
> string, and what may not.
      </P
></DD
><DT
><A
NAME="LIBPQ-PQCONNECTDB"
></A
><CODE
CLASS="FUNCTION"
>PQconnectdb</CODE
></DT
><DD
><P
>       Makes a new connection to the database server.

</P><PRE
CLASS="SYNOPSIS"
>PGconn *PQconnectdb(const char *conninfo);</PRE
><P>
      </P
><P
>       This function opens a new database connection using the parameters taken
       from the string <TT
CLASS="LITERAL"
>conninfo</TT
>.
      </P
><P
>       The passed string can be empty to use all default parameters, or it can
       contain one or more parameter settings separated by whitespace,
       or it can contain a <ACRONYM
CLASS="ACRONYM"
>URI</ACRONYM
>.
       See <A
HREF="libpq-connect.html#LIBPQ-CONNSTRING"
>Section 31.1.2</A
> for details.
     </P
></DD
><DT
><A
NAME="LIBPQ-PQSETDBLOGIN"
></A
><CODE
CLASS="FUNCTION"
>PQsetdbLogin</CODE
></DT
><DD
><P
>       Makes a new connection to the database server.
</P><PRE
CLASS="SYNOPSIS"
>PGconn *PQsetdbLogin(const char *pghost,
                     const char *pgport,
                     const char *pgoptions,
                     const char *pgtty,
                     const char *dbName,
                     const char *login,
                     const char *pwd);</PRE
><P>
       </P
><P
>        This is the predecessor of <CODE
CLASS="FUNCTION"
>PQconnectdb</CODE
> with a fixed
        set of parameters.  It has the same functionality except that the
        missing parameters will always take on default values.  Write <TT
CLASS="SYMBOL"
>NULL</TT
> or an
        empty string for any one of the fixed parameters that is to be defaulted.
      </P
><P
>        If the <TT
CLASS="PARAMETER"
>dbName</TT
> contains
        an <TT
CLASS="SYMBOL"
>=</TT
> sign or has a valid connection <ACRONYM
CLASS="ACRONYM"
>URI</ACRONYM
> prefix, it
        is taken as a <TT
CLASS="PARAMETER"
>conninfo</TT
> string in exactly the same way as
        if it had been passed to <CODE
CLASS="FUNCTION"
>PQconnectdb</CODE
>, and the remaining
        parameters are then applied as specified in <A
HREF="libpq-connect.html#LIBPQ-CONNSTRING"
>Section 31.1.2</A
>.
      </P
></DD
><DT
><A
NAME="LIBPQ-PQSETDB"
></A
><CODE
CLASS="FUNCTION"
>PQsetdb</CODE
></DT
><DD
><P
>   Makes a new connection to the database server.
</P><PRE
CLASS="SYNOPSIS"
>PGconn *PQsetdb(char *pghost,
                char *pgport,
                char *pgoptions,
                char *pgtty,
                char *dbName);</PRE
><P>
     </P
><P
>      This is a macro that calls <CODE
CLASS="FUNCTION"
>PQsetdbLogin</CODE
> with null pointers
      for the <TT
CLASS="PARAMETER"
>login</TT
> and <TT
CLASS="PARAMETER"
>pwd</TT
> parameters.  It is provided
      for backward compatibility with very old programs.
     </P
></DD
><DT
><A
NAME="LIBPQ-PQCONNECTSTARTPARAMS"
></A
><CODE
CLASS="FUNCTION"
>PQconnectStartParams</CODE
><BR><CODE
CLASS="FUNCTION"
>PQconnectStart</CODE
><BR><CODE
CLASS="FUNCTION"
>PQconnectPoll</CODE
></DT
><DD
><P
>       
       Make a connection to the database server in a nonblocking manner.

</P><PRE
CLASS="SYNOPSIS"
>PGconn *PQconnectStartParams(const char * const *keywords,
                             const char * const *values,
                             int expand_dbname);

PGconn *PQconnectStart(const char *conninfo);

PostgresPollingStatusType PQconnectPoll(PGconn *conn);</PRE
><P>
      </P
><P
>       These three functions are used to open a connection to a database server such
       that your application's thread of execution is not blocked on remote I/O
       whilst doing so. The point of this approach is that the waits for I/O to
       complete can occur in the application's main loop, rather than down inside
       <CODE
CLASS="FUNCTION"
>PQconnectdbParams</CODE
> or <CODE
CLASS="FUNCTION"
>PQconnectdb</CODE
>, and so the
       application can manage this operation in parallel with other activities.
      </P
><P
>       With <CODE
CLASS="FUNCTION"
>PQconnectStartParams</CODE
>, the database connection is made
       using the parameters taken from the <TT
CLASS="LITERAL"
>keywords</TT
> and
       <TT
CLASS="LITERAL"
>values</TT
> arrays, and controlled by <TT
CLASS="LITERAL"
>expand_dbname</TT
>,
       as described above for <CODE
CLASS="FUNCTION"
>PQconnectdbParams</CODE
>.
      </P
><P
>       With <CODE
CLASS="FUNCTION"
>PQconnectStart</CODE
>, the database connection is made
       using the parameters taken from the string <TT
CLASS="LITERAL"
>conninfo</TT
> as
       described above for <CODE
CLASS="FUNCTION"
>PQconnectdb</CODE
>.
      </P
><P
>       Neither <CODE
CLASS="FUNCTION"
>PQconnectStartParams</CODE
> nor <CODE
CLASS="FUNCTION"
>PQconnectStart</CODE
>
       nor <CODE
CLASS="FUNCTION"
>PQconnectPoll</CODE
> will block, so long as a number of
       restrictions are met:
       <P
></P
></P><UL
><LI
><P
>          The <TT
CLASS="LITERAL"
>hostaddr</TT
> and <TT
CLASS="LITERAL"
>host</TT
> parameters are used appropriately to ensure that
          name and reverse name queries are not made. See the documentation of
          these parameters in <A
HREF="libpq-connect.html#LIBPQ-PARAMKEYWORDS"
>Section 31.1.1</A
> for details.
         </P
></LI
><LI
><P
>          If you call <CODE
CLASS="FUNCTION"
>PQtrace</CODE
>, ensure that the stream object
          into which you trace will not block.
         </P
></LI
><LI
><P
>          You ensure that the socket is in the appropriate state
          before calling <CODE
CLASS="FUNCTION"
>PQconnectPoll</CODE
>, as described below.
         </P
></LI
></UL
><P>
      </P
><P
>       Note: use of <CODE
CLASS="FUNCTION"
>PQconnectStartParams</CODE
> is analogous to
       <CODE
CLASS="FUNCTION"
>PQconnectStart</CODE
> shown below.
      </P
><P
>       To begin a nonblocking connection request, call <TT
CLASS="LITERAL"
>conn = PQconnectStart("<TT
CLASS="REPLACEABLE"
><I
>connection_info_string</I
></TT
>")</TT
>.
       If <TT
CLASS="VARNAME"
>conn</TT
> is null, then <SPAN
CLASS="APPLICATION"
>libpq</SPAN
> has been unable to allocate a new <TT
CLASS="STRUCTNAME"
>PGconn</TT
>
       structure. Otherwise, a valid <TT
CLASS="STRUCTNAME"
>PGconn</TT
> pointer is returned (though not yet
       representing a valid connection to the database). On return from
       <CODE
CLASS="FUNCTION"
>PQconnectStart</CODE
>, call <TT
CLASS="LITERAL"
>status = PQstatus(conn)</TT
>. If <TT
CLASS="VARNAME"
>status</TT
> equals
       <TT
CLASS="SYMBOL"
>CONNECTION_BAD</TT
>, <CODE
CLASS="FUNCTION"
>PQconnectStart</CODE
> has failed.
      </P
><P
>       If <CODE
CLASS="FUNCTION"
>PQconnectStart</CODE
> succeeds, the next stage is to poll
       <SPAN
CLASS="APPLICATION"
>libpq</SPAN
> so that it can proceed with the connection sequence.
       Use <CODE
CLASS="FUNCTION"
>PQsocket(conn)</CODE
> to obtain the descriptor of the
       socket underlying the database connection.
       Loop thus: If <CODE
CLASS="FUNCTION"
>PQconnectPoll(conn)</CODE
> last returned
       <TT
CLASS="SYMBOL"
>PGRES_POLLING_READING</TT
>, wait until the socket is ready to
       read (as indicated by <CODE
CLASS="FUNCTION"
>select()</CODE
>, <CODE
CLASS="FUNCTION"
>poll()</CODE
>, or
       similar system function).
       Then call <CODE
CLASS="FUNCTION"
>PQconnectPoll(conn)</CODE
> again.
       Conversely, if <CODE
CLASS="FUNCTION"
>PQconnectPoll(conn)</CODE
> last returned
       <TT
CLASS="SYMBOL"
>PGRES_POLLING_WRITING</TT
>, wait until the socket is ready
       to write, then call <CODE
CLASS="FUNCTION"
>PQconnectPoll(conn)</CODE
> again.
       If you have yet to call
       <CODE
CLASS="FUNCTION"
>PQconnectPoll</CODE
>, i.e., just after the call to
       <CODE
CLASS="FUNCTION"
>PQconnectStart</CODE
>, behave as if it last returned
       <TT
CLASS="SYMBOL"
>PGRES_POLLING_WRITING</TT
>.  Continue this loop until
       <CODE
CLASS="FUNCTION"
>PQconnectPoll(conn)</CODE
> returns
       <TT
CLASS="SYMBOL"
>PGRES_POLLING_FAILED</TT
>, indicating the connection procedure
       has failed, or <TT
CLASS="SYMBOL"
>PGRES_POLLING_OK</TT
>, indicating the connection
       has been successfully made.
      </P
><P
>       At any time during connection, the status of the connection can be
       checked by calling <CODE
CLASS="FUNCTION"
>PQstatus</CODE
>. If this call returns <TT
CLASS="SYMBOL"
>CONNECTION_BAD</TT
>, then the
       connection procedure has failed; if the call returns <CODE
CLASS="FUNCTION"
>CONNECTION_OK</CODE
>, then the
       connection is ready.  Both of these states are equally detectable
       from the return value of <CODE
CLASS="FUNCTION"
>PQconnectPoll</CODE
>, described above. Other states might also occur
       during (and only during) an asynchronous connection procedure. These
       indicate the current stage of the connection procedure and might be useful
       to provide feedback to the user for example. These statuses are:

       <P
></P
></P><DIV
CLASS="VARIABLELIST"
><DL
><DT
><A
NAME="LIBPQ-CONNECTION-STARTED"
></A
><TT
CLASS="SYMBOL"
>CONNECTION_STARTED</TT
></DT
><DD
><P
>           Waiting for connection to be made.
          </P
></DD
><DT
><A
NAME="LIBPQ-CONNECTION-MADE"
></A
><TT
CLASS="SYMBOL"
>CONNECTION_MADE</TT
></DT
><DD
><P
>           Connection OK; waiting to send.
          </P
></DD
><DT
><A
NAME="LIBPQ-CONNECTION-AWAITING-RESPONSE"
></A
><TT
CLASS="SYMBOL"
>CONNECTION_AWAITING_RESPONSE</TT
></DT
><DD
><P
>           Waiting for a response from the server.
          </P
></DD
><DT
><A
NAME="LIBPQ-CONNECTION-AUTH-OK"
></A
><TT
CLASS="SYMBOL"
>CONNECTION_AUTH_OK</TT
></DT
><DD
><P
>           Received authentication; waiting for backend start-up to finish.
          </P
></DD
><DT
><A
NAME="LIBPQ-CONNECTION-SSL-STARTUP"
></A
><TT
CLASS="SYMBOL"
>CONNECTION_SSL_STARTUP</TT
></DT
><DD
><P
>           Negotiating SSL encryption.
          </P
></DD
><DT
><A
NAME="LIBPQ-CONNECTION-SETENV"
></A
><TT
CLASS="SYMBOL"
>CONNECTION_SETENV</TT
></DT
><DD
><P
>           Negotiating environment-driven parameter settings.
          </P
></DD
></DL
></DIV
><P>

       Note that, although these constants will remain (in order to maintain
       compatibility), an application should never rely upon these occurring in a
       particular order, or at all, or on the status always being one of these
       documented values. An application might do something like this:
</P><PRE
CLASS="PROGRAMLISTING"
>switch(PQstatus(conn))
{
        case CONNECTION_STARTED:
            feedback = "Connecting...";
            break;

        case CONNECTION_MADE:
            feedback = "Connected to server...";
            break;
.
.
.
        default:
            feedback = "Connecting...";
}</PRE
><P>
      </P
><P
>       The <TT
CLASS="LITERAL"
>connect_timeout</TT
> connection parameter is ignored
       when using <CODE
CLASS="FUNCTION"
>PQconnectPoll</CODE
>; it is the application's
       responsibility to decide whether an excessive amount of time has elapsed.
       Otherwise, <CODE
CLASS="FUNCTION"
>PQconnectStart</CODE
> followed by a
       <CODE
CLASS="FUNCTION"
>PQconnectPoll</CODE
> loop is equivalent to
       <CODE
CLASS="FUNCTION"
>PQconnectdb</CODE
>.
      </P
><P
>       Note that if <CODE
CLASS="FUNCTION"
>PQconnectStart</CODE
> returns a non-null pointer, you must call
       <CODE
CLASS="FUNCTION"
>PQfinish</CODE
> when you are finished with it, in order to dispose of
       the structure and any associated memory blocks. This must be done even if
       the connection attempt fails or is abandoned.
      </P
></DD
><DT
><A
NAME="LIBPQ-PQCONNDEFAULTS"
></A
><CODE
CLASS="FUNCTION"
>PQconndefaults</CODE
></DT
><DD
><P
>       Returns the default connection options.
</P><PRE
CLASS="SYNOPSIS"
>PQconninfoOption *PQconndefaults(void);

typedef struct
{
    char   *keyword;   /* The keyword of the option */
    char   *envvar;    /* Fallback environment variable name */
    char   *compiled;  /* Fallback compiled in default value */
    char   *val;       /* Option's current value, or NULL */
    char   *label;     /* Label for field in connect dialog */
    char   *dispchar;  /* Indicates how to display this field
                          in a connect dialog. Values are:
                          ""        Display entered value as is
                          "*"       Password field - hide value
                          "D"       Debug option - don't show by default */
    int     dispsize;  /* Field size in characters for dialog */
} PQconninfoOption;</PRE
><P>
      </P
><P
>       Returns a connection options array.  This can be used to determine
       all possible <CODE
CLASS="FUNCTION"
>PQconnectdb</CODE
> options and their
       current default values.  The return value points to an array of
       <TT
CLASS="STRUCTNAME"
>PQconninfoOption</TT
> structures, which ends
       with an entry having a null <TT
CLASS="STRUCTFIELD"
>keyword</TT
> pointer.  The
       null pointer is returned if memory could not be allocated. Note that
       the current default values (<TT
CLASS="STRUCTFIELD"
>val</TT
> fields)
       will depend on environment variables and other context.  Callers
       must treat the connection options data as read-only.
      </P
><P
>       After processing the options array, free it by passing it to
       <CODE
CLASS="FUNCTION"
>PQconninfoFree</CODE
>.  If this is not done, a small amount of memory
       is leaked for each call to <CODE
CLASS="FUNCTION"
>PQconndefaults</CODE
>.
      </P
></DD
><DT
><A
NAME="LIBPQ-PQCONNINFOPARSE"
></A
><CODE
CLASS="FUNCTION"
>PQconninfoParse</CODE
></DT
><DD
><P
>       Returns parsed connection options from the provided connection string.

</P><PRE
CLASS="SYNOPSIS"
>PQconninfoOption *PQconninfoParse(const char *conninfo, char **errmsg);</PRE
><P>
      </P
><P
>       Parses a connection string and returns the resulting options as an
       array; or returns <TT
CLASS="SYMBOL"
>NULL</TT
> if there is a problem with the connection
       string.  This function can be used to extract
       the <CODE
CLASS="FUNCTION"
>PQconnectdb</CODE
> options in the provided
       connection string.  The return value points to an array of
       <TT
CLASS="STRUCTNAME"
>PQconninfoOption</TT
> structures, which ends
       with an entry having a null <TT
CLASS="STRUCTFIELD"
>keyword</TT
> pointer.
      </P
><P
>       All legal options will be present in the result array, but the
       <TT
CLASS="LITERAL"
>PQconninfoOption</TT
> for any option not present
       in the connection string will have <TT
CLASS="LITERAL"
>val</TT
> set to
       <TT
CLASS="LITERAL"
>NULL</TT
>; default values are not inserted.
      </P
><P
>       If <TT
CLASS="LITERAL"
>errmsg</TT
> is not <TT
CLASS="SYMBOL"
>NULL</TT
>, then <TT
CLASS="LITERAL"
>*errmsg</TT
> is set
       to <TT
CLASS="SYMBOL"
>NULL</TT
> on success, else to a <CODE
CLASS="FUNCTION"
>malloc</CODE
>'d error string explaining
       the problem.  (It is also possible for <TT
CLASS="LITERAL"
>*errmsg</TT
> to be
       set to <TT
CLASS="SYMBOL"
>NULL</TT
> and the function to return <TT
CLASS="SYMBOL"
>NULL</TT
>;
       this indicates an out-of-memory condition.)
      </P
><P
>       After processing the options array, free it by passing it to
       <CODE
CLASS="FUNCTION"
>PQconninfoFree</CODE
>.  If this is not done, some memory
       is leaked for each call to <CODE
CLASS="FUNCTION"
>PQconninfoParse</CODE
>.
       Conversely, if an error occurs and <TT
CLASS="LITERAL"
>errmsg</TT
> is not <TT
CLASS="SYMBOL"
>NULL</TT
>,
       be sure to free the error string using <CODE
CLASS="FUNCTION"
>PQfreemem</CODE
>.
      </P
></DD
><DT
><A
NAME="LIBPQ-PQFINISH"
></A
><CODE
CLASS="FUNCTION"
>PQfinish</CODE
></DT
><DD
><P
>       Closes  the  connection to the server.  Also frees
       memory used by the <TT
CLASS="STRUCTNAME"
>PGconn</TT
> object.
</P><PRE
CLASS="SYNOPSIS"
>void PQfinish(PGconn *conn);</PRE
><P>
      </P
><P
>       Note that even if the server connection attempt fails (as
       indicated by <CODE
CLASS="FUNCTION"
>PQstatus</CODE
>), the application should call <CODE
CLASS="FUNCTION"
>PQfinish</CODE
>
       to free the memory used by the <TT
CLASS="STRUCTNAME"
>PGconn</TT
> object.
       The <TT
CLASS="STRUCTNAME"
>PGconn</TT
> pointer must not be used again after
       <CODE
CLASS="FUNCTION"
>PQfinish</CODE
> has been called.
      </P
></DD
><DT
><A
NAME="LIBPQ-PQRESET"
></A
><CODE
CLASS="FUNCTION"
>PQreset</CODE
></DT
><DD
><P
>       Resets the communication channel to the server.
</P><PRE
CLASS="SYNOPSIS"
>void PQreset(PGconn *conn);</PRE
><P>
      </P
><P
>       This function will close the connection
       to the server and attempt to  reestablish  a  new
       connection to the same server, using all the same
       parameters previously used.  This might be useful for
       error recovery if a working connection is lost.
      </P
></DD
><DT
><A
NAME="LIBPQ-PQRESETSTART"
></A
><CODE
CLASS="FUNCTION"
>PQresetStart</CODE
><BR><CODE
CLASS="FUNCTION"
>PQresetPoll</CODE
></DT
><DD
><P
>       Reset the communication channel to the server, in a nonblocking manner.

</P><PRE
CLASS="SYNOPSIS"
>int PQresetStart(PGconn *conn);

PostgresPollingStatusType PQresetPoll(PGconn *conn);</PRE
><P>
      </P
><P
>       These functions will close the connection to the server and attempt to
       reestablish a new connection to the same server, using all the same
       parameters previously used. This can be useful for error recovery if a
       working connection is lost. They differ from <CODE
CLASS="FUNCTION"
>PQreset</CODE
> (above) in that they
       act in a nonblocking manner. These functions suffer from the same
       restrictions as <CODE
CLASS="FUNCTION"
>PQconnectStartParams</CODE
>, <CODE
CLASS="FUNCTION"
>PQconnectStart</CODE
>
       and <CODE
CLASS="FUNCTION"
>PQconnectPoll</CODE
>.
      </P
><P
>       To initiate a connection reset, call
       <CODE
CLASS="FUNCTION"
>PQresetStart</CODE
>. If it returns 0, the reset has
       failed. If it returns 1, poll the reset using
       <CODE
CLASS="FUNCTION"
>PQresetPoll</CODE
> in exactly the same way as you
       would create the connection using <CODE
CLASS="FUNCTION"
>PQconnectPoll</CODE
>.
      </P
></DD
><DT
><A
NAME="LIBPQ-PQPINGPARAMS"
></A
><CODE
CLASS="FUNCTION"
>PQpingParams</CODE
></DT
><DD
><P
>       <CODE
CLASS="FUNCTION"
>PQpingParams</CODE
> reports the status of the
       server.  It accepts connection parameters identical to those of
       <CODE
CLASS="FUNCTION"
>PQconnectdbParams</CODE
>, described above.  It is not, however,
       necessary to supply correct user name, password, or database name
       values to obtain the server status.

</P><PRE
CLASS="SYNOPSIS"
>PGPing PQpingParams(const char * const *keywords,
                    const char * const *values,
                    int expand_dbname);</PRE
><P>

       The function returns one of the following values:

       <P
></P
></P><DIV
CLASS="VARIABLELIST"
><DL
><DT
><A
NAME="LIBPQ-PQPINGPARAMS-PQPING-OK"
></A
><TT
CLASS="LITERAL"
>PQPING_OK</TT
></DT
><DD
><P
>           The server is running and appears to be accepting connections.
          </P
></DD
><DT
><A
NAME="LIBPQ-PQPINGPARAMS-PQPING-REJECT"
></A
><TT
CLASS="LITERAL"
>PQPING_REJECT</TT
></DT
><DD
><P
>           The server is running but is in a state that disallows connections
           (startup, shutdown, or crash recovery).
          </P
></DD
><DT
><A
NAME="LIBPQ-PQPINGPARAMS-PQPING-NO-RESPONSE"
></A
><TT
CLASS="LITERAL"
>PQPING_NO_RESPONSE</TT
></DT
><DD
><P
>           The server could not be contacted.  This might indicate that the
           server is not running, or that there is something wrong with the
           given connection parameters (for example, wrong port number), or
           that there is a network connectivity problem (for example, a
           firewall blocking the connection request).
          </P
></DD
><DT
><A
NAME="LIBPQ-PQPINGPARAMS-PQPING-NO-ATTEMPT"
></A
><TT
CLASS="LITERAL"
>PQPING_NO_ATTEMPT</TT
></DT
><DD
><P
>           No attempt was made to contact the server, because the supplied
           parameters were obviously incorrect or there was some client-side
           problem (for example, out of memory).
          </P
></DD
></DL
></DIV
><P>

      </P
></DD
><DT
><A
NAME="LIBPQ-PQPING"
></A
><CODE
CLASS="FUNCTION"
>PQping</CODE
></DT
><DD
><P
>       <CODE
CLASS="FUNCTION"
>PQping</CODE
> reports the status of the
       server.  It accepts connection parameters identical to those of
       <CODE
CLASS="FUNCTION"
>PQconnectdb</CODE
>, described above.  It is not, however,
       necessary to supply correct user name, password, or database name
       values to obtain the server status.

</P><PRE
CLASS="SYNOPSIS"
>PGPing PQping(const char *conninfo);</PRE
><P>
      </P
><P
>       The return values are the same as for <CODE
CLASS="FUNCTION"
>PQpingParams</CODE
>.
      </P
></DD
></DL
></DIV
><P>
  </P
><DIV
CLASS="SECT2"
><H2
CLASS="SECT2"
><A
NAME="LIBPQ-PARAMKEYWORDS"
>31.1.1. Parameter Key Words</A
></H2
><P
>    The currently recognized parameter key words are:

    <P
></P
></P><DIV
CLASS="VARIABLELIST"
><DL
><DT
><A
NAME="LIBPQ-CONNECT-HOST"
></A
><TT
CLASS="LITERAL"
>host</TT
></DT
><DD
><P
>        Name of host to connect to.
        If this begins with a slash, it specifies Unix-domain
        communication rather than TCP/IP communication; the value is the
        name of the directory in which the socket file is stored.  The
        default behavior when <TT
CLASS="LITERAL"
>host</TT
> is not specified
        is to connect to a Unix-domain
        socket in
        <TT
CLASS="FILENAME"
>/tmp</TT
> (or whatever socket directory was specified
        when <SPAN
CLASS="PRODUCTNAME"
>PostgreSQL</SPAN
> was built). On machines without
        Unix-domain sockets, the default is to connect to <TT
CLASS="LITERAL"
>localhost</TT
>.
       </P
></DD
><DT
><A
NAME="LIBPQ-CONNECT-HOSTADDR"
></A
><TT
CLASS="LITERAL"
>hostaddr</TT
></DT
><DD
><P
>        Numeric IP address of host to connect to.  This should be in the
        standard IPv4 address format, e.g., <TT
CLASS="LITERAL"
>172.28.40.9</TT
>.  If
        your machine supports IPv6, you can also use those addresses.
        TCP/IP communication is
        always used when a nonempty string is specified for this parameter.
       </P
><P
>        Using <TT
CLASS="LITERAL"
>hostaddr</TT
> instead of <TT
CLASS="LITERAL"
>host</TT
> allows the
        application to avoid a host name look-up, which might be important
        in applications with time constraints. However, a host name is
        required for Kerberos, GSSAPI, or SSPI authentication
        methods, as well as for <TT
CLASS="LITERAL"
>verify-full</TT
> SSL
        certificate verification.  The following rules are used:
        <P
></P
></P><UL
><LI
><P
>           If <TT
CLASS="LITERAL"
>host</TT
> is specified without <TT
CLASS="LITERAL"
>hostaddr</TT
>,
           a host name lookup occurs.
          </P
></LI
><LI
><P
>           If <TT
CLASS="LITERAL"
>hostaddr</TT
> is specified without <TT
CLASS="LITERAL"
>host</TT
>,
           the value for <TT
CLASS="LITERAL"
>hostaddr</TT
> gives the server network address.
           The connection attempt will fail if the authentication
           method requires a host name.
          </P
></LI
><LI
><P
>           If both <TT
CLASS="LITERAL"
>host</TT
> and <TT
CLASS="LITERAL"
>hostaddr</TT
> are specified,
           the value for <TT
CLASS="LITERAL"
>hostaddr</TT
> gives the server network address.
           The value for <TT
CLASS="LITERAL"
>host</TT
> is ignored unless the
           authentication method requires it, in which case it will be
           used as the host name.
          </P
></LI
></UL
><P>
        Note that authentication is likely to fail if <TT
CLASS="LITERAL"
>host</TT
>
        is not the name of the server at network address <TT
CLASS="LITERAL"
>hostaddr</TT
>.
        Also, note that <TT
CLASS="LITERAL"
>host</TT
> rather than <TT
CLASS="LITERAL"
>hostaddr</TT
>
        is used to identify the connection in <TT
CLASS="FILENAME"
>~/.pgpass</TT
> (see
        <A
HREF="libpq-pgpass.html"
>Section 31.15</A
>).
       </P
><P
>        Without either a host name or host address,
        <SPAN
CLASS="APPLICATION"
>libpq</SPAN
> will connect using a
        local Unix-domain socket; or on machines without Unix-domain
        sockets, it will attempt to connect to <TT
CLASS="LITERAL"
>localhost</TT
>.
       </P
></DD
><DT
><A
NAME="LIBPQ-CONNECT-PORT"
></A
><TT
CLASS="LITERAL"
>port</TT
></DT
><DD
><P
>        Port number to connect to at the server host, or socket file
        name extension for Unix-domain
        connections.
       </P
></DD
><DT
><A
NAME="LIBPQ-CONNECT-DBNAME"
></A
><TT
CLASS="LITERAL"
>dbname</TT
></DT
><DD
><P
>       The database name.  Defaults to be the same as the user name.
       In certain, very specific contexts, the value is checked for extended
       formats; see <A
HREF="libpq-connect.html#LIBPQ-CONNSTRING"
>Section 31.1.2</A
> for more details on
       those.
      </P
></DD
><DT
><A
NAME="LIBPQ-CONNECT-USER"
></A
><TT
CLASS="LITERAL"
>user</TT
></DT
><DD
><P
>       <SPAN
CLASS="PRODUCTNAME"
>PostgreSQL</SPAN
> user name to connect as.
       Defaults to be the same as the operating system name of the user
       running the application.
      </P
></DD
><DT
><A
NAME="LIBPQ-CONNECT-PASSWORD"
></A
><TT
CLASS="LITERAL"
>password</TT
></DT
><DD
><P
>       Password to be used if the server demands password authentication.
      </P
></DD
><DT
><A
NAME="LIBPQ-CONNECT-CONNECT-TIMEOUT"
></A
><TT
CLASS="LITERAL"
>connect_timeout</TT
></DT
><DD
><P
>       Maximum wait for connection, in seconds (write as a decimal integer
       string). Zero or not specified means wait indefinitely.  It is not
       recommended to use a timeout of less than 2 seconds.
      </P
></DD
><DT
><A
NAME="LIBPQ-CONNECT-CLIENT-ENCODING"
></A
><TT
CLASS="LITERAL"
>client_encoding</TT
></DT
><DD
><P
>       This sets the <TT
CLASS="VARNAME"
>client_encoding</TT
>
       configuration parameter for this connection.  In addition to
       the values accepted by the corresponding server option, you
       can use <TT
CLASS="LITERAL"
>auto</TT
> to determine the right
       encoding from the current locale in the client
       (<TT
CLASS="ENVAR"
>LC_CTYPE</TT
> environment variable on Unix
       systems).
      </P
></DD
><DT
><A
NAME="LIBPQ-CONNECT-OPTIONS"
></A
><TT
CLASS="LITERAL"
>options</TT
></DT
><DD
><P
>        Adds command-line options to send to the server at run-time.
        For example, setting this to <TT
CLASS="LITERAL"
>-c geqo=off</TT
> sets the
        session's value of the <TT
CLASS="VARNAME"
>geqo</TT
> parameter to
        <TT
CLASS="LITERAL"
>off</TT
>.  For a detailed discussion of the available
        options, consult <A
HREF="runtime-config.html"
>Chapter 18</A
>.
       </P
></DD
><DT
><A
NAME="LIBPQ-CONNECT-APPLICATION-NAME"
></A
><TT
CLASS="LITERAL"
>application_name</TT
></DT
><DD
><P
>        Specifies a value for the <A
HREF="runtime-config-logging.html#GUC-APPLICATION-NAME"
>application_name</A
>
        configuration parameter.
       </P
></DD
><DT
><A
NAME="LIBPQ-CONNECT-FALLBACK-APPLICATION-NAME"
></A
><TT
CLASS="LITERAL"
>fallback_application_name</TT
></DT
><DD
><P
>        Specifies a fallback value for the <A
HREF="runtime-config-logging.html#GUC-APPLICATION-NAME"
>application_name</A
> configuration parameter.
        This value will be used if no value has been given for
        <TT
CLASS="LITERAL"
>application_name</TT
> via a connection parameter or the
        <TT
CLASS="ENVAR"
>PGAPPNAME</TT
> environment variable.  Specifying
        a fallback name is useful in generic utility programs that
        wish to set a default application name but allow it to be
        overridden by the user.
       </P
></DD
><DT
><A
NAME="LIBPQ-KEEPALIVES"
></A
><TT
CLASS="LITERAL"
>keepalives</TT
></DT
><DD
><P
>        Controls whether client-side TCP keepalives are used. The default
        value is 1, meaning on, but you can change this to 0, meaning off,
        if keepalives are not wanted.  This parameter is ignored for
        connections made via a Unix-domain socket.
       </P
></DD
><DT
><A
NAME="LIBPQ-KEEPALIVES-IDLE"
></A
><TT
CLASS="LITERAL"
>keepalives_idle</TT
></DT
><DD
><P
>        Controls the number of seconds of inactivity after which TCP should
        send a keepalive message to the server.  A value of zero uses the
        system default. This parameter is ignored for connections made via a
        Unix-domain socket, or if keepalives are disabled. It is only supported
        on systems where the <TT
CLASS="SYMBOL"
>TCP_KEEPIDLE</TT
> or <TT
CLASS="SYMBOL"
>TCP_KEEPALIVE</TT
>
        socket option is available, and on Windows; on other systems, it has no
        effect.
       </P
></DD
><DT
><A
NAME="LIBPQ-KEEPALIVES-INTERVAL"
></A
><TT
CLASS="LITERAL"
>keepalives_interval</TT
></DT
><DD
><P
>        Controls the number of seconds after which a TCP keepalive message
        that is not acknowledged by the server should be retransmitted.  A
        value of zero uses the system default. This parameter is ignored for
        connections made via a Unix-domain socket, or if keepalives are disabled.
        It is only supported on systems where the <TT
CLASS="SYMBOL"
>TCP_KEEPINTVL</TT
>
        socket option is available, and on Windows; on other systems, it has no
        effect.
       </P
></DD
><DT
><A
NAME="LIBPQ-KEEPALIVES-COUNT"
></A
><TT
CLASS="LITERAL"
>keepalives_count</TT
></DT
><DD
><P
>        Controls the number of TCP keepalives that can be lost before the
        client's connection to the server is considered dead.  A value of
        zero uses the system default. This parameter is ignored for
        connections made via a Unix-domain socket, or if keepalives are disabled.
        It is only supported on systems where the <TT
CLASS="SYMBOL"
>TCP_KEEPCNT</TT
>
        socket option is available; on other systems, it has no effect.
       </P
></DD
><DT
><A
NAME="LIBPQ-CONNECT-TTY"
></A
><TT
CLASS="LITERAL"
>tty</TT
></DT
><DD
><P
>       Ignored (formerly, this specified where to send server debug output).
      </P
></DD
><DT
><A
NAME="LIBPQ-CONNECT-SSLMODE"
></A
><TT
CLASS="LITERAL"
>sslmode</TT
></DT
><DD
><P
>        This option determines whether or with what priority a secure
        <ACRONYM
CLASS="ACRONYM"
>SSL</ACRONYM
> TCP/IP connection will be negotiated with the
        server. There are six modes:

        <P
></P
></P><DIV
CLASS="VARIABLELIST"
><DL
><DT
><TT
CLASS="LITERAL"
>disable</TT
></DT
><DD
><P
>            only try a non-<ACRONYM
CLASS="ACRONYM"
>SSL</ACRONYM
> connection
           </P
></DD
><DT
><TT
CLASS="LITERAL"
>allow</TT
></DT
><DD
><P
>            first try a non-<ACRONYM
CLASS="ACRONYM"
>SSL</ACRONYM
> connection; if that
            fails, try an <ACRONYM
CLASS="ACRONYM"
>SSL</ACRONYM
> connection
           </P
></DD
><DT
><TT
CLASS="LITERAL"
>prefer</TT
> (default)</DT
><DD
><P
>            first try an <ACRONYM
CLASS="ACRONYM"
>SSL</ACRONYM
> connection; if that fails,
            try a non-<ACRONYM
CLASS="ACRONYM"
>SSL</ACRONYM
> connection
           </P
></DD
><DT
><TT
CLASS="LITERAL"
>require</TT
></DT
><DD
><P
>            only try an <ACRONYM
CLASS="ACRONYM"
>SSL</ACRONYM
> connection. If a root CA
            file is present, verify the certificate in the same way as
            if <TT
CLASS="LITERAL"
>verify-ca</TT
> was specified
           </P
></DD
><DT
><TT
CLASS="LITERAL"
>verify-ca</TT
></DT
><DD
><P
>            only try an <ACRONYM
CLASS="ACRONYM"
>SSL</ACRONYM
> connection, and verify that
            the server certificate is issued by a trusted
            certificate authority (<ACRONYM
CLASS="ACRONYM"
>CA</ACRONYM
>)
           </P
></DD
><DT
><TT
CLASS="LITERAL"
>verify-full</TT
></DT
><DD
><P
>            only try an <ACRONYM
CLASS="ACRONYM"
>SSL</ACRONYM
> connection, verify that the
            server certificate is issued by a
            trusted <ACRONYM
CLASS="ACRONYM"
>CA</ACRONYM
> and that the server host name
            matches that in the certificate
           </P
></DD
></DL
></DIV
><P>

        See <A
HREF="libpq-ssl.html"
>Section 31.18</A
> for a detailed description of how
        these options work.
       </P
><P
>        <TT
CLASS="LITERAL"
>sslmode</TT
> is ignored for Unix domain socket
        communication.
        If <SPAN
CLASS="PRODUCTNAME"
>PostgreSQL</SPAN
> is compiled without SSL support,
        using options <TT
CLASS="LITERAL"
>require</TT
>, <TT
CLASS="LITERAL"
>verify-ca</TT
>, or
        <TT
CLASS="LITERAL"
>verify-full</TT
> will cause an error, while
        options <TT
CLASS="LITERAL"
>allow</TT
> and <TT
CLASS="LITERAL"
>prefer</TT
> will be
        accepted but <SPAN
CLASS="APPLICATION"
>libpq</SPAN
> will not actually attempt
        an <ACRONYM
CLASS="ACRONYM"
>SSL</ACRONYM
>
        connection.
       </P
></DD
><DT
><A
NAME="LIBPQ-CONNECT-REQUIRESSL"
></A
><TT
CLASS="LITERAL"
>requiressl</TT
></DT
><DD
><P
>        This option is deprecated in favor of the <TT
CLASS="LITERAL"
>sslmode</TT
>
        setting.
       </P
><P
>        If set to 1, an <ACRONYM
CLASS="ACRONYM"
>SSL</ACRONYM
> connection to the server
        is required (this is equivalent to <TT
CLASS="LITERAL"
>sslmode</TT
>
        <TT
CLASS="LITERAL"
>require</TT
>).  <SPAN
CLASS="APPLICATION"
>libpq</SPAN
> will then refuse
        to connect if the server does not accept an
        <ACRONYM
CLASS="ACRONYM"
>SSL</ACRONYM
> connection.  If set to 0 (default),
        <SPAN
CLASS="APPLICATION"
>libpq</SPAN
> will negotiate the connection type with
        the server (equivalent to <TT
CLASS="LITERAL"
>sslmode</TT
>
        <TT
CLASS="LITERAL"
>prefer</TT
>).  This option is only available if
        <SPAN
CLASS="PRODUCTNAME"
>PostgreSQL</SPAN
> is compiled with SSL support.
       </P
></DD
><DT
><A
NAME="LIBPQ-CONNECT-SSLCOMPRESSION"
></A
><TT
CLASS="LITERAL"
>sslcompression</TT
></DT
><DD
><P
>        If set to 1 (default), data sent over SSL connections will be
        compressed (this requires <SPAN
CLASS="PRODUCTNAME"
>OpenSSL</SPAN
> version
        0.9.8 or later).
        If set to 0, compression will be disabled (this requires
        <SPAN
CLASS="PRODUCTNAME"
>OpenSSL</SPAN
> 1.0.0 or later).
        This parameter is ignored if a connection without SSL is made,
        or if the version of <SPAN
CLASS="PRODUCTNAME"
>OpenSSL</SPAN
> used does not support
        it.
       </P
><P
>        Compression uses CPU time, but can improve throughput if
        the network is the bottleneck.
        Disabling compression can improve response time and throughput
        if CPU performance is the limiting factor.
       </P
></DD
><DT
><A
NAME="LIBPQ-CONNECT-SSLCERT"
></A
><TT
CLASS="LITERAL"
>sslcert</TT
></DT
><DD
><P
>        This parameter specifies the file name of the client SSL
        certificate, replacing the default
        <TT
CLASS="FILENAME"
>~/.postgresql/postgresql.crt</TT
>.
        This parameter is ignored if an SSL connection is not made.
       </P
></DD
><DT
><A
NAME="LIBPQ-CONNECT-SSLKEY"
></A
><TT
CLASS="LITERAL"
>sslkey</TT
></DT
><DD
><P
>        This parameter specifies the location for the secret key used for
        the client certificate. It can either specify a file name that will
        be used instead of the default
        <TT
CLASS="FILENAME"
>~/.postgresql/postgresql.key</TT
>, or it can specify a key
        obtained from an external <SPAN
CLASS="QUOTE"
>"engine"</SPAN
> (engines are
        <SPAN
CLASS="PRODUCTNAME"
>OpenSSL</SPAN
> loadable modules).  An external engine
        specification should consist of a colon-separated engine name and
        an engine-specific key identifier.  This parameter is ignored if an
        SSL connection is not made.
       </P
></DD
><DT
><A
NAME="LIBPQ-CONNECT-SSLROOTCERT"
></A
><TT
CLASS="LITERAL"
>sslrootcert</TT
></DT
><DD
><P
>        This parameter specifies the name of a file containing SSL
        certificate authority (<ACRONYM
CLASS="ACRONYM"
>CA</ACRONYM
>) certificate(s).
        If the file exists, the server's certificate will be verified
        to be signed by one of these authorities.  The default is
        <TT
CLASS="FILENAME"
>~/.postgresql/root.crt</TT
>.
       </P
></DD
><DT
><A
NAME="LIBPQ-CONNECT-SSLCRL"
></A
><TT
CLASS="LITERAL"
>sslcrl</TT
></DT
><DD
><P
>        This parameter specifies the file name of the SSL certificate
        revocation list (CRL).  Certificates listed in this file, if it
        exists, will be rejected while attempting to authenticate the
        server's certificate.  The default is
        <TT
CLASS="FILENAME"
>~/.postgresql/root.crl</TT
>.
       </P
></DD
><DT
><A
NAME="LIBPQ-CONNECT-REQUIREPEER"
></A
><TT
CLASS="LITERAL"
>requirepeer</TT
></DT
><DD
><P
>        This parameter specifies the operating-system user name of the
        server, for example <TT
CLASS="LITERAL"
>requirepeer=postgres</TT
>.
        When making a Unix-domain socket connection, if this
        parameter is set, the client checks at the beginning of the
        connection that the server process is running under the specified
        user name; if it is not, the connection is aborted with an error.
        This parameter can be used to provide server authentication similar
        to that available with SSL certificates on TCP/IP connections.
        (Note that if the Unix-domain socket is in
        <TT
CLASS="FILENAME"
>/tmp</TT
> or another publicly writable location,
        any user could start a server listening there.  Use this parameter
        to ensure that you are connected to a server run by a trusted user.)
        This option is only supported on platforms for which the
        <TT
CLASS="LITERAL"
>peer</TT
> authentication method is implemented; see
        <A
HREF="auth-methods.html#AUTH-PEER"
>Section 19.3.7</A
>.
       </P
></DD
><DT
><A
NAME="LIBPQ-CONNECT-KRBSRVNAME"
></A
><TT
CLASS="LITERAL"
>krbsrvname</TT
></DT
><DD
><P
>        Kerberos service name to use when authenticating with Kerberos 5
        or GSSAPI.
        This must match the service name specified in the server
        configuration for Kerberos authentication to succeed. (See also
        <A
HREF="auth-methods.html#KERBEROS-AUTH"
>Section 19.3.5</A
> and <A
HREF="auth-methods.html#GSSAPI-AUTH"
>Section 19.3.3</A
>.)
       </P
></DD
><DT
><A
NAME="LIBPQ-CONNECT-GSSLIB"
></A
><TT
CLASS="LITERAL"
>gsslib</TT
></DT
><DD
><P
>        GSS library to use for GSSAPI authentication. Only used on Windows.
        Set to <TT
CLASS="LITERAL"
>gssapi</TT
> to force libpq to use the GSSAPI
        library for authentication instead of the default SSPI.
       </P
></DD
><DT
><A
NAME="LIBPQ-CONNECT-SERVICE"
></A
><TT
CLASS="LITERAL"
>service</TT
></DT
><DD
><P
>        Service name to use for additional parameters.  It specifies a service
        name in <TT
CLASS="FILENAME"
>pg_service.conf</TT
> that holds additional connection parameters.
        This allows applications to specify only a service name so connection parameters
        can be centrally maintained. See <A
HREF="libpq-pgservice.html"
>Section 31.16</A
>.
       </P
></DD
></DL
></DIV
><P>
   </P
></DIV
><DIV
CLASS="SECT2"
><H2
CLASS="SECT2"
><A
NAME="LIBPQ-CONNSTRING"
>31.1.2. Connection Strings</A
></H2
><P
>    Several <SPAN
CLASS="APPLICATION"
>libpq</SPAN
> functions parse a user-specified string to obtain
    connection parameters.  There are two accepted formats for these strings:
    plain <TT
CLASS="LITERAL"
>keyword = value</TT
> strings, and URIs.
   </P
><P
>    In the first format, each parameter setting is in the form
    <TT
CLASS="LITERAL"
>keyword = value</TT
>.  Spaces around the equal sign are
    optional. To write an empty value, or a value containing spaces, surround it
    with single quotes, e.g., <TT
CLASS="LITERAL"
>keyword = 'a value'</TT
>. Single
    quotes and backslashes within
    the value must be escaped with a backslash, i.e., <TT
CLASS="LITERAL"
>\'</TT
> and
    <TT
CLASS="LITERAL"
>\\</TT
>.
   </P
><P
>    The currently recognized parameter key words are listed in
    <A
HREF="libpq-connect.html#LIBPQ-PARAMKEYWORDS"
>Section 31.1.1</A
>.
   </P
><P
>   The general form for connection <ACRONYM
CLASS="ACRONYM"
>URI</ACRONYM
> is the
   following:
 </P><PRE
CLASS="SYNOPSIS"
>postgresql://username:password@hostname:port/database?param1=value1&amp;param2=value2&amp;...
postgresql:///path/to/pgsql/socket/dir?param1=value1
 </PRE
><P>
   </P
><P
>    The <ACRONYM
CLASS="ACRONYM"
>URI</ACRONYM
> designator can be either
    <TT
CLASS="LITERAL"
>postgresql://</TT
> or <TT
CLASS="LITERAL"
>postgres://</TT
> and
    each of the <ACRONYM
CLASS="ACRONYM"
>URI</ACRONYM
> parts is optional.  The following
    examples illustrate valid <ACRONYM
CLASS="ACRONYM"
>URI</ACRONYM
> syntax uses:
 </P><PRE
CLASS="SYNOPSIS"
> postgresql://
 postgresql://localhost
 postgresql://localhost:5433
 postgresql://localhost/mydb
 postgresql://user@localhost
 postgresql://user:secret@localhost
 postgresql://other@localhost/otherdb
 </PRE
><P>
   </P
><P
>    Additional connection parameters may optionally follow the base <ACRONYM
CLASS="ACRONYM"
>URI</ACRONYM
>.
    Any connection parameters not corresponding to key words listed
    below are ignored and a warning message about them is sent to
    <TT
CLASS="FILENAME"
>stderr</TT
>.
   </P
><P
>    For improved compatibility with JDBC connection <ACRONYM
CLASS="ACRONYM"
>URI</ACRONYM
>
    syntax, instances of parameter <TT
CLASS="LITERAL"
>ssl=true</TT
> are translated
    into <TT
CLASS="LITERAL"
>sslmode=require</TT
> (see above.)
   </P
><P
>    Percent-encoding may be used to include a symbol with special
    meaning in any of the <ACRONYM
CLASS="ACRONYM"
>URI</ACRONYM
> parts.
   </P
><P
>    The host part may be either hostname or an IP address.  To specify an
    IPv6 host address, enclose it in square brackets:
 </P><PRE
CLASS="SYNOPSIS"
> postgresql://[::1]/database
 </PRE
><P>
    As a special case, a host part which starts with <TT
CLASS="SYMBOL"
>/</TT
> is
    treated as a local Unix socket directory to look for the connection
    socket special file:
 </P><PRE
CLASS="SYNOPSIS"
> postgresql:///path/to/pgsql/socket/dir
 </PRE
><P>
    The whole connection string up to the extra parameters designator
    (<TT
CLASS="SYMBOL"
>?</TT
>) is treated as the absolute path to the socket
    directory (<TT
CLASS="LITERAL"
>/path/to/pgsql/socket/dir</TT
> in this
    example.)  To specify a non-default database name in this case use the
    following syntax:
 </P><PRE
CLASS="SYNOPSIS"
> postgresql:///path/to/pgsql/socket/dir?dbname=other
 </PRE
><P>
   </P
></DIV
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="libpq.html"
ACCESSKEY="P"
>Prev</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="index.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="libpq-status.html"
ACCESSKEY="N"
>Next</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><SPAN
CLASS="APPLICATION"
>libpq</SPAN
> - C Library</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="libpq.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Connection Status Functions</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

^ permalink  raw  reply  [nested|flat] 22+ messages in thread

* Re: Another review of URI for libpq, v7 submission
  2012-03-15 08:49 Another review of URI for libpq, v7 submission Daniel Farina <[email protected]>
  2012-03-15 14:36 ` Re: Another review of URI for libpq, v7 submission Alex Shulgin <[email protected]>
  2012-03-15 21:09   ` Re: Another review of URI for libpq, v7 submission Daniel Farina <[email protected]>
  2012-03-15 21:29     ` Re: Another review of URI for libpq, v7 submission Alex <[email protected]>
  2012-03-17 14:51       ` Re: Another review of URI for libpq, v7 submission Marko Kreen <[email protected]>
  2012-03-20 22:18         ` Re: Another review of URI for libpq, v7 submission Alex <[email protected]>
  2012-03-22 21:42           ` Re: Another review of URI for libpq, v7 submission Alex <[email protected]>
  2012-03-27 17:22             ` Re: Another review of URI for libpq, v7 submission Peter Eisentraut <[email protected]>
  2012-03-27 19:21               ` Re: Another review of URI for libpq, v7 submission Alex <[email protected]>
  2012-03-27 22:49                 ` Re: Another review of URI for libpq, v7 submission Alex <[email protected]>
  2012-04-05 16:52                   ` Re: Another review of URI for libpq, v7 submission Peter Eisentraut <[email protected]>
  2012-04-05 22:10                     ` Re: Another review of URI for libpq, v7 submission Alvaro Herrera <[email protected]>
  2012-04-06 03:25                       ` Re: Another review of URI for libpq, v7 submission Alvaro Herrera <[email protected]>
  2012-04-06 06:09                         ` Re: Another review of URI for libpq, v7 submission Peter Eisentraut <[email protected]>
  2012-04-09 19:41                           ` Re: Another review of URI for libpq, v7 submission Alvaro Herrera <[email protected]>
@ 2012-04-11 07:46                             ` Alvaro Herrera <[email protected]>
  0 siblings, 0 replies; 22+ messages in thread

From: Alvaro Herrera @ 2012-04-11 07:46 UTC (permalink / raw)
  To: Peter Eisentraut <[email protected]>; +Cc: Alex <[email protected]>; Heikki Linnakangas <[email protected]>; pgsql-hackers


Excerpts from Alvaro Herrera's message of lun abr 09 16:41:50 -0300 2012:

> There are three minor things that need to be changed for this to be
> committable:

Committed this patch after some more editorialization; in particular the
test was rewritten so that instead of trying to connect, it uses
PQconninfoParse to figure out how the URI is parsed, which makes a
lot more sense.  Also some other changes to the accepted URI, in
particular so that username, pwd, and port are possible to be specified
when using unix-domain sockets.

Now that it is a done deal I'm sure people will start complaining how
bad the documentation change was; please keep the flames up.

-- 
Álvaro Herrera <[email protected]>
The PostgreSQL Company - Command Prompt, Inc.
PostgreSQL Replication, Consulting, Custom Development, 24x7 support



^ permalink  raw  reply  [nested|flat] 22+ messages in thread

* [PATCH 5/9] document store_change somewhat more
@ 2026-03-12 15:10 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 22+ messages in thread

From: Álvaro Herrera @ 2026-03-12 15:10 UTC (permalink / raw)

---
 .../replication/pgoutput_repack/pgoutput_repack.c        | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/src/backend/replication/pgoutput_repack/pgoutput_repack.c b/src/backend/replication/pgoutput_repack/pgoutput_repack.c
index 90f3a8975b9..79fc611b9ff 100644
--- a/src/backend/replication/pgoutput_repack/pgoutput_repack.c
+++ b/src/backend/replication/pgoutput_repack/pgoutput_repack.c
@@ -158,7 +158,14 @@ plugin_change(LogicalDecodingContext *ctx, ReorderBufferTXN *txn,
 	}
 }
 
-/* Store concurrent data change. */
+/*
+ * For each change affecting the table being repacked, we store enough
+ * information about each tuple in it, so that it can be replayed in the
+ * new copy of the table.
+ *
+ * XXX for DELETE and the UPDATE OLD tuples, we could store just the
+ * replication identity instead of the full tuple.
+ */
 static void
 store_change(LogicalDecodingContext *ctx, Relation relation,
 			 ConcurrentChangeKind kind, HeapTuple tuple)
-- 
2.47.3


--pnppmxqkefjd4hu2
Content-Type: text/plain; charset=utf-8
Content-Disposition: attachment;
	filename*0="0006-use-int-instead-of-uint32-for-the-result-of-list_len.noc";
	filename*1="fbot.txt"



^ permalink  raw  reply  [nested|flat] 22+ messages in thread


end of thread, other threads:[~2026-03-12 15:10 UTC | newest]

Thread overview: 22+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2012-03-15 08:49 Another review of URI for libpq, v7 submission Daniel Farina <[email protected]>
2012-03-15 14:34 ` Alvaro Herrera <[email protected]>
2012-03-15 14:36 ` Alex Shulgin <[email protected]>
2012-03-15 21:09   ` Daniel Farina <[email protected]>
2012-03-15 21:29     ` Alex <[email protected]>
2012-03-17 14:51       ` Marko Kreen <[email protected]>
2012-03-20 22:18         ` Alex <[email protected]>
2012-03-21 16:42           ` Trivial libpq refactoring patch (was: Re: Another review of URI for libpq, v7 submission) Alex Shulgin <[email protected]>
2012-03-22 16:10             ` Re: Trivial libpq refactoring patch (was: Re: Another review of URI for libpq, v7 submission) Tom Lane <[email protected]>
2012-03-22 21:42           ` Alex <[email protected]>
2012-03-27 13:03             ` Heikki Linnakangas <[email protected]>
2012-03-27 14:13               ` Alex Shulgin <[email protected]>
2012-03-27 17:22             ` Peter Eisentraut <[email protected]>
2012-03-27 19:21               ` Alex <[email protected]>
2012-03-27 22:49                 ` Alex <[email protected]>
2012-04-05 16:52                   ` Peter Eisentraut <[email protected]>
2012-04-05 22:10                     ` Alvaro Herrera <[email protected]>
2012-04-06 03:25                       ` Alvaro Herrera <[email protected]>
2012-04-06 06:09                         ` Peter Eisentraut <[email protected]>
2012-04-09 19:41                           ` Alvaro Herrera <[email protected]>
2012-04-11 07:46                             ` Alvaro Herrera <[email protected]>
2026-03-12 15:10 [PATCH 5/9] document store_change somewhat more Álvaro Herrera <[email protected]>

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox