Thread: psql commandline conninfo

psql commandline conninfo

From
Andrew Dunstan
Date:

I have been working on providing psql with the ability to accept a libpq 
conninfo string, so that the following now works for me:
 psql "conn:service=sname user=uname"

Instead of providing yet another switch, I overloaded the dbname 
parameter so that if it has the recognised prefix the remainder is 
treated as a conninfo string. I have 3 questions:

1. Is this a good way to go, or should we just provide yet another switch?
2. If this is ok, what should the prefix be? is "conn:" ok?
3. Should we append settings from other switches to the conninfo (e.g. 
-U or -h), or should we just ignore them? If we ignore them should we 
warn about that if they are present?

cheers

andrew


Re: psql commandline conninfo

From
Tom Lane
Date:
Andrew Dunstan <andrew@dunslane.net> writes:
> I have been working on providing psql with the ability to accept a libpq 
> conninfo string, so that the following now works for me:
>   psql "conn:service=sname user=uname"

Perhaps this should be implemented in libpq, not at the psql level?
Otherwise you're going to have to do it over for each client program.

> 2. If this is ok, what should the prefix be? is "conn:" ok?

I'd prefer to dispense with the conn:, so that this looks somehow
designed in rather than bolted on after the fact.

I'm tempted to suggest that if the "dbname" includes "=" it should be
considered a conninfo string; perhaps also after checking keyword
validity.

> 3. Should we append settings from other switches to the conninfo (e.g. 
> -U or -h), or should we just ignore them? If we ignore them should we 
> warn about that if they are present?

Do we complain about duplicate keywords in conninfo now?  I think not,
so appending the other switches would have the result of overriding what
is in conninfo, which is probably reasonable.  (Actually, if you
implement this in libpq, there's probably no need to form the appended
string explicitly --- just process the other options of PQsetdbLogin()
after the conninfo.)
        regards, tom lane


Re: psql commandline conninfo

From
Andrew Dunstan
Date:
Tom Lane wrote:
> Andrew Dunstan <andrew@dunslane.net> writes:
>   
>> I have been working on providing psql with the ability to accept a libpq 
>> conninfo string, so that the following now works for me:
>>   psql "conn:service=sname user=uname"
>>     
>
> Perhaps this should be implemented in libpq, not at the psql level?
> Otherwise you're going to have to do it over for each client program.
>
>   


Just as well I haven't spent much time on it, eh?
>> 2. If this is ok, what should the prefix be? is "conn:" ok?
>>     
>
> I'd prefer to dispense with the conn:, so that this looks somehow
> designed in rather than bolted on after the fact.
>   

well, I thought this made it look slightly URLish, a bit like a jbdc 
URL. But OK.  no big deal.

> I'm tempted to suggest that if the "dbname" includes "=" it should be
> considered a conninfo string; perhaps also after checking keyword
> validity.
>   

Now I look at fe-connect.c more closely, I'm tempted just to try parsing 
the dbname param as a conninfo string, and if it doesn't work fall back 
on a plain dbname. I could greatly reduce the chance of following the 
failure path by just looking for an = but I think anything more is 
likely to be redundant.

>   
>> 3. Should we append settings from other switches to the conninfo (e.g. 
>> -U or -h), or should we just ignore them? If we ignore them should we 
>> warn about that if they are present?
>>     
>
> Do we complain about duplicate keywords in conninfo now?  I think not,
> so appending the other switches would have the result of overriding what
> is in conninfo, which is probably reasonable.  (Actually, if you
> implement this in libpq, there's probably no need to form the appended
> string explicitly --- just process the other options of PQsetdbLogin()
> after the conninfo.)
>
>   

OK. I think this just falls out.

cheers

andrew





Re: psql commandline conninfo

From
Martijn van Oosterhout
Date:
On Tue, Dec 12, 2006 at 05:44:07PM -0500, Andrew Dunstan wrote:
> Now I look at fe-connect.c more closely, I'm tempted just to try parsing
> the dbname param as a conninfo string, and if it doesn't work fall back
> on a plain dbname. I could greatly reduce the chance of following the
> failure path by just looking for an = but I think anything more is
> likely to be redundant.

Does that mean that:

psql -d "service=myservice"

should Just Work(tm)? That would be nice.

Have a nice day,
--
Martijn van Oosterhout   <kleptog@svana.org>   http://svana.org/kleptog/
> From each according to his ability. To each according to his ability to litigate.

Re: psql commandline conninfo

From
Tom Lane
Date:
Martijn van Oosterhout <kleptog@svana.org> writes:
> Does that mean that:
> psql -d "service=myservice"
> should Just Work(tm)? That would be nice.

Even more to the point,
psql "service=myservice"

which is why we want to overload dbname rather than any of the other
PQsetdbLogin parameters for this --- dbname has pride of place in the
command line syntax for several of the client programs.
        regards, tom lane


Re: psql commandline conninfo

From
Andrew Dunstan
Date:
Tom Lane wrote:
> Martijn van Oosterhout <kleptog@svana.org> writes:
>
>> Does that mean that:
>> psql -d "service=myservice"
>> should Just Work(tm)? That would be nice.
>>
>
> Even more to the point,
>
>     psql "service=myservice"
>
> which is why we want to overload dbname rather than any of the other
> PQsetdbLogin parameters for this --- dbname has pride of place in the
> command line syntax for several of the client programs.
>
>             regards, tom lane
>
>

Right. Here's the patch I just knocked up, which seems to Just Work (tm) ;-)

cheers

andrew


Index: src/interfaces/libpq/fe-connect.c
===================================================================
RCS file: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v
retrieving revision 1.339
diff -c -r1.339 fe-connect.c
*** src/interfaces/libpq/fe-connect.c    21 Nov 2006 16:28:00 -0000    1.339
--- src/interfaces/libpq/fe-connect.c    12 Dec 2006 22:49:28 -0000
***************
*** 567,572 ****
--- 567,573 ----
               const char *pwd)
  {
      PGconn       *conn;
+     bool       have_conninfo = false;

      /*
       * Allocate memory for the conn structure
***************
*** 575,585 ****
      if (conn == NULL)
          return NULL;

      /*
       * Parse an empty conninfo string in order to set up the same defaults
!      * that PQconnectdb() would use.
       */
!     if (!connectOptions1(conn, ""))
          return conn;

      /*
--- 576,609 ----
      if (conn == NULL)
          return NULL;

+     /*
+      * Have we got something that might be a conninfo string?
+      * If so, try that first.
+      */
+     if (dbName && strchr(dbName,'='))
+     {
+         if(connectOptions1(conn,dbName))
+         {
+             /* it was a conninfo string */
+             have_conninfo = true;
+         }
+         else
+         {
+             /* put things back the way they were so we can try again */
+             freePGconn(conn);
+             conn = makeEmptyPGconn();
+             if (conn == NULL)
+                 return NULL;
+
+         }
+     }
+
      /*
       * Parse an empty conninfo string in order to set up the same defaults
!      * that PQconnectdb() would use. Skip this if we already found a
!      * conninfo string.
       */
!     if (!have_conninfo && !connectOptions1(conn, ""))
          return conn;

      /*
***************
*** 613,619 ****
          conn->pgtty = strdup(pgtty);
      }

!     if (dbName && dbName[0] != '\0')
      {
          if (conn->dbName)
              free(conn->dbName);
--- 637,643 ----
          conn->pgtty = strdup(pgtty);
      }

!     if (!have_conninfo && dbName && dbName[0] != '\0')
      {
          if (conn->dbName)
              free(conn->dbName);

Re: psql commandline conninfo

From
Tom Lane
Date:
Andrew Dunstan <andrew@dunslane.net> writes:
> Right. Here's the patch I just knocked up, which seems to Just Work (tm) ;-)

The main objection I can see to this is that you'd get a fairly
unhelpful message if you intended a conninfo string and there was
anything wrong with your syntax (eg, misspelled keyword).  Maybe we
should go with the conn: bit, although really that doesn't seem any
less likely to collide with actual dbnames than the "does it contain
"="" idea.  Anyone have other ideas how to disambiguate?

            regards, tom lane

Re: psql commandline conninfo

From
Casey Duncan
Date:
On Dec 12, 2006, at 3:37 PM, Tom Lane wrote:

> Andrew Dunstan <andrew@dunslane.net> writes:
>> Right. Here's the patch I just knocked up, which seems to Just
>> Work (tm) ;-)
>
> The main objection I can see to this is that you'd get a fairly
> unhelpful message if you intended a conninfo string and there was
> anything wrong with your syntax (eg, misspelled keyword).  Maybe we
> should go with the conn: bit, although really that doesn't seem any
> less likely to collide with actual dbnames than the "does it contain
> "="" idea.  Anyone have other ideas how to disambiguate?

I would personally prefer a real option over a prefix, i.e. --
dbconn="service=foo" though the inline conninfo string in place of
the dbname would be ideal.

Perhaps like Tom suggests, if the value matches a conninfo regex
(slightly more rigid than just containing an equals character) then
we assume it is a conninfo string, but never try it as a dbname. If
someone has a database named like a conninfo string (c'mon folks ;^)
then they would need to pass it as explicitly an argument to '-d' or
'--dbname', not as a bare argument.

This is not completely b/w compatible of course, but IMO the added
convenience outweighs the incompatibility.

-Casey

Re: psql commandline conninfo

From
"Andrew Dunstan"
Date:
Casey Duncan wrote:
> On Dec 12, 2006, at 3:37 PM, Tom Lane wrote:
>
>> Andrew Dunstan <andrew@dunslane.net> writes:
>>> Right. Here's the patch I just knocked up, which seems to Just
>>> Work (tm) ;-)
>>
>> The main objection I can see to this is that you'd get a fairly
>> unhelpful message if you intended a conninfo string and there was
>> anything wrong with your syntax (eg, misspelled keyword).  Maybe we
>> should go with the conn: bit, although really that doesn't seem any
>> less likely to collide with actual dbnames than the "does it contain
>> "="" idea.  Anyone have other ideas how to disambiguate?
>
> I would personally prefer a real option over a prefix, i.e. --
> dbconn="service=foo" though the inline conninfo string in place of
> the dbname would be ideal.
>
> Perhaps like Tom suggests, if the value matches a conninfo regex
> (slightly more rigid than just containing an equals character) then
> we assume it is a conninfo string, but never try it as a dbname. If
> someone has a database named like a conninfo string (c'mon folks ;^)
> then they would need to pass it as explicitly an argument to '-d' or
> '--dbname', not as a bare argument.
>

You are confusing two things here. The way the patch is written it simply
interprets the parameter passed to libpq - it has no idea what was used
(if anything) on the commandline. The alternative, as Tom pointed out, is
to patch every client.

I'm inclined to say we should go back almost to my original suggestion: a
param that starts with conn: and contains an = is conclusively presumed to
be a conninfo string.

The workaround for a db name like that (say conn:foo=bar) is to use
"conn:dbname='conn:foo=bar'". You'll soon get tired of that and rename the
db to something sane :-)


cheers

andrew



Re: psql commandline conninfo

From
Casey Duncan
Date:
On Dec 12, 2006, at 5:16 PM, Andrew Dunstan wrote:

> Casey Duncan wrote:
>> On Dec 12, 2006, at 3:37 PM, Tom Lane wrote:
>>
>>> Andrew Dunstan <andrew@dunslane.net> writes:
>>>> Right. Here's the patch I just knocked up, which seems to Just
>>>> Work (tm) ;-)
>>>
>>> The main objection I can see to this is that you'd get a fairly
>>> unhelpful message if you intended a conninfo string and there was
>>> anything wrong with your syntax (eg, misspelled keyword).  Maybe we
>>> should go with the conn: bit, although really that doesn't seem any
>>> less likely to collide with actual dbnames than the "does it contain
>>> "="" idea.  Anyone have other ideas how to disambiguate?
>>
>> I would personally prefer a real option over a prefix, i.e. --
>> dbconn="service=foo" though the inline conninfo string in place of
>> the dbname would be ideal.
>>
>> Perhaps like Tom suggests, if the value matches a conninfo regex
>> (slightly more rigid than just containing an equals character) then
>> we assume it is a conninfo string, but never try it as a dbname. If
>> someone has a database named like a conninfo string (c'mon folks ;^)
>> then they would need to pass it as explicitly an argument to '-d' or
>> '--dbname', not as a bare argument.
>>
>
> You are confusing two things here. The way the patch is written it  
> simply
> interprets the parameter passed to libpq - it has no idea what was  
> used
> (if anything) on the commandline. The alternative, as Tom pointed  
> out, is
> to patch every client.

I was speaking from and end-user point of view, but I see your point.  
It's certainly attractive to just patch libpq and be done. However,  
that does have the side-effect of implicitly propagating the behavior  
to all libpg client software. That may be more unpleasantly  
surprising to more people then just changing the built-in postgresql  
client utilities. But then again it could also be considered a  
feature 8^)

-Casey



Re: psql commandline conninfo

From
"Andrew Dunstan"
Date:
Casey Duncan wrote:

>
> I was speaking from and end-user point of view, but I see your point.
> It's certainly attractive to just patch libpq and be done. However,
> that does have the side-effect of implicitly propagating the behavior
> to all libpg client software. That may be more unpleasantly
> surprising to more people then just changing the built-in postgresql
> client utilities. But then again it could also be considered a
> feature 8^)


We change libpq from time to time. Besides, how many DBs are there that
match the name pattern /^conn:.*=/ ? My guess is mighty few. So I don't
expect lots of surprise.

cheers

andrew



Re: psql commandline conninfo

From
Tom Lane
Date:
"Andrew Dunstan" <andrew@dunslane.net> writes:
> We change libpq from time to time. Besides, how many DBs are there that
> match the name pattern /^conn:.*=/ ? My guess is mighty few. So I don't
> expect lots of surprise.

Um, but how many DB names have an "=" in them at all?

Basically what this proposal is about is migrating from separated
dbname/user/host/port/etc parameters to a unified conninfo parameter.
That seems to me like a good long-term objective, and so I'm willing
to break a few eggs on the way to the omelet, as long as we're not
breaking any very likely usages.

So: who here has a database with "=" in the name?  And hands up if
you've got a database whose name begins with "conn:"?

I'm betting zero response rate on both of those, so see no reason to
contort the long-term definition for a very marginal difference in
the extent of backwards compatibility ...
        regards, tom lane


Re: psql commandline conninfo

From
"Albe Laurenz"
Date:
Tom Lane wrote:
>> We change libpq from time to time. Besides, how many DBs are there
that
>> match the name pattern /^conn:.*=/ ? My guess is mighty few. So I
don't
>> expect lots of surprise.
>
> Um, but how many DB names have an "=" in them at all?
>
> Basically what this proposal is about is migrating from separated
> dbname/user/host/port/etc parameters to a unified conninfo parameter.
> That seems to me like a good long-term objective, and so I'm willing
> to break a few eggs on the way to the omelet, as long as we're not
> breaking any very likely usages.
>
> So: who here has a database with "=" in the name?  And hands up if
> you've got a database whose name begins with "conn:"?
>
> I'm betting zero response rate on both of those, so see no reason to
> contort the long-term definition for a very marginal difference in
> the extent of backwards compatibility ...

I second the idea to have libpq interpret a database name with "=" in
it as a connection parameter string.

The "conn:" seems artificial and difficult to remember to me.

As to the problem of cryptic error messages from psql, can't we improve
libpq's error response if it gets a database name that causes problems
when parsed as a connection parameter string? That would take care of
that.

Yours,
Laurenz Albe


Re: psql commandline conninfo

From
Andrew Dunstan
Date:
Tom Lane wrote:
> "Andrew Dunstan" <andrew@dunslane.net> writes:
>   
>> We change libpq from time to time. Besides, how many DBs are there that
>> match the name pattern /^conn:.*=/ ? My guess is mighty few. So I don't
>> expect lots of surprise.
>>     
>
> Um, but how many DB names have an "=" in them at all?
>
> Basically what this proposal is about is migrating from separated
> dbname/user/host/port/etc parameters to a unified conninfo parameter.
> That seems to me like a good long-term objective, and so I'm willing
> to break a few eggs on the way to the omelet, as long as we're not
> breaking any very likely usages.
>
> So: who here has a database with "=" in the name?  And hands up if
> you've got a database whose name begins with "conn:"?
>
> I'm betting zero response rate on both of those, so see no reason to
> contort the long-term definition for a very marginal difference in
> the extent of backwards compatibility ...
>
>     
>   

I'm not sure -hackers is the most representative group to poll regarding 
dbnames in use ...

Anyway, if I understand your current position, the only change needed to 
my current patch would be that if we fail to parse a dbname parameter 
that contains an = we simply fail at that point, rather than retrying it 
as a straight database name.

I'm OK with that.

cheers

andrew



Re: psql commandline conninfo

From
"Andrew Dunstan"
Date:
Andrew Dunstan wrote:
> Tom Lane wrote:
>> "Andrew Dunstan" <andrew@dunslane.net> writes:
>>
>>> We change libpq from time to time. Besides, how many DBs are there that
>>> match the name pattern /^conn:.*=/ ? My guess is mighty few. So I don't
>>> expect lots of surprise.
>>>
>>
>> Um, but how many DB names have an "=" in them at all?
>>
>> Basically what this proposal is about is migrating from separated
>> dbname/user/host/port/etc parameters to a unified conninfo parameter.
>> That seems to me like a good long-term objective, and so I'm willing
>> to break a few eggs on the way to the omelet, as long as we're not
>> breaking any very likely usages.
>>
>> So: who here has a database with "=" in the name?  And hands up if
>> you've got a database whose name begins with "conn:"?
>>
>> I'm betting zero response rate on both of those, so see no reason to
>> contort the long-term definition for a very marginal difference in
>> the extent of backwards compatibility ...
>>
>>
>>
>
> I'm not sure -hackers is the most representative group to poll regarding
> dbnames in use ...
>
> Anyway, if I understand your current position, the only change needed to
> my current patch would be that if we fail to parse a dbname parameter
> that contains an = we simply fail at that point, rather than retrying it
> as a straight database name.
>
> I'm OK with that.
>


Here's the patch for what I think is the consensus position. If there's no
objection I will apply this and document it.

cheers

andrew

Attachment

Re: [PATCHES] psql commandline conninfo

From
Tom Lane
Date:
"Andrew Dunstan" <andrew@dunslane.net> writes:
> BTW, what is the approved way to handle warnings about const? Copy the
> object?

Well, in the revised code there shouldn't be any warning at all, but
I think the mistake in your original was to declare the local variable
as "char *" instead of "const char *".

If "const" is being used as intended then a const-violation warning
would indeed suggest that you needed to make a writable copy.
Sometimes the problem is that you're working in a chunk of inadequately
const-ified code, ie, you're passing a const argument to some other
functions that do indeed treat their inputs as read-only but don't
declare them const.  In such cases you can either run around and try to
inject const everywhere it should be, or hold your nose and use a cast,
or give up on marking your own argument const :-(.  But you weren't
presented with that problem here, because connectOptions1() is already
const-ified.

            regards, tom lane

Re: [PATCHES] psql commandline conninfo

From
Bruce Momjian
Date:
I assume this patch will still allow a database name with an equals
sign, right?


    psql "dbname='a=b'"


The libpq documentation isn't clear that single-quotes also escape
equals, but I assume that is true looking at the code:

    http://www.postgresql.org/docs/8.2/static/libpq-connect.html

    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 keyword = value. Spaces around the
    equal sign are optional. To write an empty value or a value containing
    spaces, surround it with single quotes, e.g., keyword = 'a value'.
    Single quotes and backslashes within the value must be escaped with a
    backslash, i.e., \' and \\.


---------------------------------------------------------------------------

Andrew Dunstan wrote:
> Andrew Dunstan wrote:
> > Tom Lane wrote:
> >> "Andrew Dunstan" <andrew@dunslane.net> writes:
> >>
> >>> We change libpq from time to time. Besides, how many DBs are there that
> >>> match the name pattern /^conn:.*=/ ? My guess is mighty few. So I don't
> >>> expect lots of surprise.
> >>>
> >>
> >> Um, but how many DB names have an "=" in them at all?
> >>
> >> Basically what this proposal is about is migrating from separated
> >> dbname/user/host/port/etc parameters to a unified conninfo parameter.
> >> That seems to me like a good long-term objective, and so I'm willing
> >> to break a few eggs on the way to the omelet, as long as we're not
> >> breaking any very likely usages.
> >>
> >> So: who here has a database with "=" in the name?  And hands up if
> >> you've got a database whose name begins with "conn:"?
> >>
> >> I'm betting zero response rate on both of those, so see no reason to
> >> contort the long-term definition for a very marginal difference in
> >> the extent of backwards compatibility ...
> >>
> >>
> >>
> >
> > I'm not sure -hackers is the most representative group to poll regarding
> > dbnames in use ...
> >
> > Anyway, if I understand your current position, the only change needed to
> > my current patch would be that if we fail to parse a dbname parameter
> > that contains an = we simply fail at that point, rather than retrying it
> > as a straight database name.
> >
> > I'm OK with that.
> >
>
>
> Here's the patch for what I think is the consensus position. If there's no
> objection I will apply this and document it.
>
> cheers
>
> andrew

[ Attachment, skipping... ]

>
> ---------------------------(end of broadcast)---------------------------
> TIP 9: In versions below 8.0, the planner will ignore your desire to
>        choose an index scan if your joining column's datatypes do not
>        match

--
  Bruce Momjian   bruce@momjian.us
  EnterpriseDB    http://www.enterprisedb.com

  + If your life is a hard drive, Christ can be your backup. +

Re: [PATCHES] psql commandline conninfo

From
"Andrew Dunstan"
Date:
Bruce Momjian wrote:
>
> I assume this patch will still allow a database name with an equals
> sign, right?
>
>
>     psql "dbname='a=b'"


Yes. In fact, reading the code it looks like the quotes are not necessary
in this case.

cheers

andrew



Re: [PATCHES] psql commandline conninfo

From
Bruce Momjian
Date:
Andrew Dunstan wrote:
> Bruce Momjian wrote:
> >
> > I assume this patch will still allow a database name with an equals
> > sign, right?
> >
> >
> >     psql "dbname='a=b'"
> 
> 
> Yes. In fact, reading the code it looks like the quotes are not necessary
> in this case.

OK, good to know.  Does the patch need documentation too?  Are we
deprecating the psql options now duplicated by the new functionality,
like host/port/username/password?

--  Bruce Momjian   bruce@momjian.us EnterpriseDB    http://www.enterprisedb.com
 + If your life is a hard drive, Christ can be your backup. +


Re: [PATCHES] psql commandline conninfo

From
Tom Lane
Date:
Bruce Momjian <bruce@momjian.us> writes:
> OK, good to know.  Does the patch need documentation too?

Certainly.

> Are we
> deprecating the psql options now duplicated by the new functionality,
> like host/port/username/password?

I'd vote not.  This is just another way to do it.
        regards, tom lane


Re: [PATCHES] psql commandline conninfo

From
Andrew Dunstan
Date:

Tom Lane wrote:
> Bruce Momjian <bruce@momjian.us> writes:
>   
>> OK, good to know.  Does the patch need documentation too?
>>     
>
> Certainly.
>   


That's why I haven't committed it yet. I intend to put info in the psql 
manual as well as in the libpq reference.
>   
>> Are we
>> deprecating the psql options now duplicated by the new functionality,
>> like host/port/username/password?
>>     
>
> I'd vote not.  This is just another way to do it.
>
>             
>   

I entirely agree. It lets you do some nice things that aren't obvious 
now, like:
 psql 'service=foo sslmode=require'

cheers

andrew