queriing the version of libpq

Started by Massa, Harald Arminover 15 years ago39 messageshackersgeneral
Jump to latest
hackersgeneral

With 9.0 there is the new hex encoding for BYTEA, which is activated by
default.

libpq BEFORE 9.0 are not able to decode that encoding.

I am programming with Python, using psycopg2. When psycopg2 is linked with
libpq 9.0, everything works fine with hex-encoding; if psycopg2 is linked
with libpq < 9.0, decoding hex-encoded bytea fails (it stays hexencoded).

This happens because in default configuration psycopg2 calls the
libpq-decode-encoded-bytea function (which is the way it should be done).

Now I would love to have an additional check "is the used psycopg2 linked to
an advanced-enough libpq", to be able to set bytea_output to 'escape' if the
libpq is not worthy.

My question: Which way is available to query the linked libpq version?

My other option is to select 'something_that_gets_casted_to_bytea'::bytea,
and check the return value. BUT that requires a round-trip to the server....

Harald
--
GHUM GmbH
Harald Armin Massa
Spielberger Straße 49
70435 Stuttgart
0173/9409607

Amtsgericht Stuttgart, HRB 734971
-
persuadere.
et programmare

#2Magnus Hagander
magnus@hagander.net
In reply to: Massa, Harald Armin (#1)
hackersgeneral
Re: queriing the version of libpq

On Tue, Oct 5, 2010 at 09:33, Massa, Harald Armin <chef@ghum.de> wrote:

With 9.0 there is the new hex encoding for BYTEA, which is activated by
default.
libpq BEFORE 9.0 are not able to decode that encoding.
I am programming with Python, using psycopg2. When psycopg2 is linked with
libpq 9.0, everything works fine with hex-encoding; if psycopg2 is linked
with libpq < 9.0, decoding hex-encoded bytea fails (it stays hexencoded).
This happens because in default configuration psycopg2 calls the
libpq-decode-encoded-bytea function (which is the way it should be done).
Now I would love to have an additional check "is the used psycopg2 linked to
an advanced-enough libpq", to be able to set bytea_output to 'escape' if the
libpq is not worthy.
My question: Which way is available to query the linked libpq version?
My other option is to select 'something_that_gets_casted_to_bytea'::bytea,
and check the return value. BUT that requires a round-trip to the server....

You can try calling PQconninfoParse() on a connectino string that has
applicationname= in it. That will fail on anything pre-9.0. Assuming
there's a way to access that function through psycopg2.

But it does outline that fact that it wouldn't suck to have a function
in libpq returning the version so that application can check this at
runtime - clearly it would also be useful when being linked "through"
something like psycopg2.

--
 Magnus Hagander
 Me: http://www.hagander.net/
 Work: http://www.redpill-linpro.com/

#3Greg Sabino Mullane
greg@turnstep.com
In reply to: Massa, Harald Armin (#1)
hackersgeneral
Re: queriing the version of libpq

-----BEGIN PGP SIGNED MESSAGE-----
Hash: RIPEMD160

My question: Which way is available to query the linked libpq version?

That's information your driver should be supplying. For example, in
Perl (DBD::Pg), you would say

if ($dbh->{pg_lib_version} >= 90000) {

I'd raise a bug with psycopg2 if it does not provide that information.

- --
Greg Sabino Mullane greg@turnstep.com
PGP Key: 0x14964AC8 201010051030
http://biglumber.com/x/web?pk=2529DF6AB8F79407E94445B4BC9B906714964AC8
-----BEGIN PGP SIGNATURE-----

iEYEAREDAAYFAkyrNskACgkQvJuQZxSWSsiW7wCfYge62y175Xtsk4drGbnt7UU5
0R4Ani1gxDhNA0xdHoq+xxxROjuC4wh+
=n33y
-----END PGP SIGNATURE-----

#4Magnus Hagander
magnus@hagander.net
In reply to: Greg Sabino Mullane (#3)
hackersgeneral
Re: queriing the version of libpq

On Tue, Oct 5, 2010 at 16:32, Greg Sabino Mullane <greg@turnstep.com> wrote:

My question: Which way is available to query the linked libpq version?

That's information your driver should be supplying. For example, in
Perl (DBD::Pg), you would say

if ($dbh->{pg_lib_version} >= 90000) {

I'd raise a bug with psycopg2 if it does not provide that information.

How does the driver figure it out?

--
 Magnus Hagander
 Me: http://www.hagander.net/
 Work: http://www.redpill-linpro.com/

#5Greg Sabino Mullane
greg@turnstep.com
In reply to: Magnus Hagander (#4)
hackersgeneral
Re: querying the version of libpq

-----BEGIN PGP SIGNED MESSAGE-----
Hash: RIPEMD160

if ($dbh->{pg_lib_version} >= 90000) {

I'd raise a bug with psycopg2 if it does not provide that information.

How does the driver figure it out?

DBD::Pg parses pg_config --version, then passes the information
to the C programs for directive fiddling. I certainly hope
other drivers are doing the same, as libpq varies across
major versions a good deal.

- --
Greg Sabino Mullane greg@turnstep.com
PGP Key: 0x14964AC8 201010051132
http://biglumber.com/x/web?pk=2529DF6AB8F79407E94445B4BC9B906714964AC8
-----BEGIN PGP SIGNATURE-----

iEYEAREDAAYFAkyrRR8ACgkQvJuQZxSWSsgHmwCfaAPXXA1YCZ6OgOjyis6uKVmz
HvoAnj42290eDAGO+HDsGVZvOAqwEXeR
=P8XV
-----END PGP SIGNATURE-----

In reply to: Greg Sabino Mullane (#5)
hackersgeneral
Re: querying the version of libpq

On 5 October 2010 16:33, Greg Sabino Mullane <greg@turnstep.com> wrote:

-----BEGIN PGP SIGNED MESSAGE-----
Hash: RIPEMD160

if ($dbh->{pg_lib_version} >= 90000) {

I'd raise a bug with psycopg2 if it does not provide that information.

How does the driver figure it out?

DBD::Pg parses pg_config --version, then passes the information
to the C programs for directive fiddling. I certainly hope
other drivers are doing the same, as libpq varies across
major versions a good deal.

I would imagine that most libpq wrapping drivers use libpq's
PQserverVersion(), which returns an integer that looks like 90000.

--
Regards,
Peter Geoghegan

#7Greg Sabino Mullane
greg@turnstep.com
In reply to: Peter Geoghegan (#6)
hackersgeneral
Re: querying the version of libpq

-----BEGIN PGP SIGNED MESSAGE-----
Hash: RIPEMD160

I would imagine that most libpq wrapping drivers use libpq's
PQserverVersion(), which returns an integer that looks like 90000.

Yeah, I'm familiar with that (I wrote it :) but it's not useful
here for two reasons:

1) It's not available on older versions

2) It returns the *target* version, not the *compiled* version.
In other words, it requires an existing PGconn object.

- --
Greg Sabino Mullane greg@turnstep.com
End Point Corporation http://www.endpoint.com/
PGP Key: 0x14964AC8 201010051212
http://biglumber.com/x/web?pk=2529DF6AB8F79407E94445B4BC9B906714964AC8
-----BEGIN PGP SIGNATURE-----

iEYEAREDAAYFAkyrTrsACgkQvJuQZxSWSsh+rACgkvzm7HFWO4X6jHy68M4lAr74
vSoAnRzG5F+pML4IQfQxCl64b3eiNbRm
=JL6x
-----END PGP SIGNATURE-----

In reply to: Peter Geoghegan (#6)
hackersgeneral
Re: querying the version of libpq

I would imagine that most libpq wrapping drivers use libpq's
PQserverVersion(), which returns an integer that looks like 90000.

exactly that is exposed as cn.server_version property of the psycopg2

connection object; but it does not help, as a 8.4libpq happily connects to a
9.0 server... for some values of happy :)

Harald

--
GHUM GmbH
Harald Armin Massa
Spielberger Straße 49
70435 Stuttgart
0173/9409607

Amtsgericht Stuttgart, HRB 734971
-
persuadere.
et programmare

#9Tom Lane
tgl@sss.pgh.pa.us
In reply to: Peter Geoghegan (#6)
hackersgeneral
Re: querying the version of libpq

Peter Geoghegan <peter.geoghegan86@gmail.com> writes:

On 5 October 2010 16:33, Greg Sabino Mullane <greg@turnstep.com> wrote:

How does the driver figure it out?

DBD::Pg parses pg_config --version, then passes the information
to the C programs for directive fiddling. I certainly hope
other drivers are doing the same, as libpq varies across
major versions a good deal.

I would imagine that most libpq wrapping drivers use libpq's
PQserverVersion(), which returns an integer that looks like 90000.

The real problem is that neither of these can be trusted to tell you the
*library* version. PQserverVersion() is something else altogether,
and I wouldn't want to assume that pg_config exactly matches the library
you're linked to --- if it's even present at all.

We could add a PQlibpqVersion(), maybe, but it would be many years
before client code could rely on that being present.

regards, tom lane

#10Magnus Hagander
magnus@hagander.net
In reply to: Tom Lane (#9)
hackersgeneral
Re: querying the version of libpq

On Tue, Oct 5, 2010 at 18:41, Tom Lane <tgl@sss.pgh.pa.us> wrote:

Peter Geoghegan <peter.geoghegan86@gmail.com> writes:

On 5 October 2010 16:33, Greg Sabino Mullane <greg@turnstep.com> wrote:

How does the driver figure it out?

DBD::Pg parses pg_config --version, then passes the information
to the C programs for directive fiddling. I certainly hope
other drivers are doing the same, as libpq varies across
major versions a good deal.

I would imagine that most libpq wrapping drivers use libpq's
PQserverVersion(), which returns an integer that looks like 90000.

The real problem is that neither of these can be trusted to tell you the
*library* version.  PQserverVersion() is something else altogether,
and I wouldn't want to assume that pg_config exactly matches the library
you're linked to --- if it's even present at all.

We could add a PQlibpqVersion(), maybe, but it would be many years
before client code could rely on that being present.

I think we should.

And in a small way they can already - if they check for it
dynamically, they'll know if it was 9.1 or newer at least :-) It'll be
a long time before it's *easy* to use though. But if we don't add it
now, it'll be even longer...

--
 Magnus Hagander
 Me: http://www.hagander.net/
 Work: http://www.redpill-linpro.com/

In reply to: Magnus Hagander (#10)
hackersgeneral
Re: querying the version of libpq

We could add a PQlibpqVersion(), maybe, but it would be many years
before client code could rely on that being present.

I think we should.

And in a small way they can already - if they check for it
dynamically, they'll know if it was 9.1 or newer at least :-) It'll be
a long time before it's *easy* to use though. But if we don't add it
now, it'll be even longer...

and an additional argument: Isn't it a wise decision for clients, to allways
use the newset libpq, independent of the server? As younger libpqs happily
connect to older servers AND are supposed to have less bugs.

As libpq is very small, can be statically linked into applications and there
are no license troubles, I can see no argument to use something that is not
brand new... (compared to other databases with 120megabyte clients with
longer licence restrictions than documentations...)

Or am I missing sth?

Harald

--
GHUM GmbH
Harald Armin Massa
Spielberger Straße 49
70435 Stuttgart
0173/9409607

Amtsgericht Stuttgart, HRB 734971
-
persuadere.
et programmare

#12Greg Sabino Mullane
greg@turnstep.com
In reply to: Tom Lane (#9)
hackersgeneral
Re: querying the version of libpq

-----BEGIN PGP SIGNED MESSAGE-----
Hash: RIPEMD160

The real problem is that neither of these can be trusted to tell you the
*library* version. PQserverVersion() is something else altogether,
and I wouldn't want to assume that pg_config exactly matches the library
you're linked to --- if it's even present at all.

Er...yes it will match exact...because we[1]DBD::Pg get the location of the
library files from pg_config as well. :) Handy little utility that.

[1]: DBD::Pg

- --
Greg Sabino Mullane greg@turnstep.com
End Point Corporation http://www.endpoint.com/
PGP Key: 0x14964AC8 201010051638
http://biglumber.com/x/web?pk=2529DF6AB8F79407E94445B4BC9B906714964AC8
-----BEGIN PGP SIGNATURE-----

iEYEAREDAAYFAkyrjPUACgkQvJuQZxSWSsiONwCfb8t30qkOBSKmMYDz2qL0mXIp
Xp4AoM2pQIQzUOSx4r8ZPdzNp/lA2Ar3
=1Ano
-----END PGP SIGNATURE-----

#13Dmitriy Igrishin
dmitigr@gmail.com
In reply to: Tom Lane (#9)
hackersgeneral
Re: querying the version of libpq

Hey all,

Could you call it as PQlibVersion() or even PQversion() instead of
PQlibpqVersion() ?

2010/10/5 Tom Lane <tgl@sss.pgh.pa.us>

Peter Geoghegan <peter.geoghegan86@gmail.com> writes:

On 5 October 2010 16:33, Greg Sabino Mullane <greg@turnstep.com> wrote:

How does the driver figure it out?

DBD::Pg parses pg_config --version, then passes the information
to the C programs for directive fiddling. I certainly hope
other drivers are doing the same, as libpq varies across
major versions a good deal.

I would imagine that most libpq wrapping drivers use libpq's
PQserverVersion(), which returns an integer that looks like 90000.

The real problem is that neither of these can be trusted to tell you the
*library* version. PQserverVersion() is something else altogether,
and I wouldn't want to assume that pg_config exactly matches the library
you're linked to --- if it's even present at all.

We could add a PQlibpqVersion(), maybe, but it would be many years
before client code could rely on that being present.

regards, tom lane

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

--
// Dmitriy.

#14Magnus Hagander
magnus@hagander.net
In reply to: Greg Sabino Mullane (#12)
hackersgeneral
Re: querying the version of libpq

On Tue, Oct 5, 2010 at 22:39, Greg Sabino Mullane <greg@turnstep.com> wrote:

The real problem is that neither of these can be trusted to tell you the
*library* version.  PQserverVersion() is something else altogether,
and I wouldn't want to assume that pg_config exactly matches the library
you're linked to --- if it's even present at all.

Er...yes it will match exact...because we[1] get the location of the
library files from pg_config as well. :) Handy little utility that.

How do you get pg_config to tell you which of the multiple versions of
libpq that may be installed on the machine you are actually linking
against?

--
 Magnus Hagander
 Me: http://www.hagander.net/
 Work: http://www.redpill-linpro.com/

#15Greg Sabino Mullane
greg@turnstep.com
In reply to: Magnus Hagander (#14)
hackersgeneral
Re: querying the version of libpq

-----BEGIN PGP SIGNED MESSAGE-----
Hash: RIPEMD160

Er...yes it will match exact...because we[1] get the location of the
library files from pg_config as well. :) Handy little utility that.

How do you get pg_config to tell you which of the multiple versions of
libpq that may be installed on the machine you are actually linking
against?

Not sure what you mean. pg_config *drives* the compilation and linking,
we don't blindly compile and simply take pg_config's word for it.
pg_config --libdir and pg_config --includedir.

- --
Greg Sabino Mullane greg@turnstep.com
End Point Corporation http://www.endpoint.com/
PGP Key: 0x14964AC8 201010051651
http://biglumber.com/x/web?pk=2529DF6AB8F79407E94445B4BC9B906714964AC8
-----BEGIN PGP SIGNATURE-----

iEYEAREDAAYFAkyrkB0ACgkQvJuQZxSWSsh4OACglNyrdKgf1jk5op7yzBw1Mh4M
sFUAnjiWVUDjNmJbNRnsuumZxzZvxQCT
=ig1E
-----END PGP SIGNATURE-----

#16Tom Lane
tgl@sss.pgh.pa.us
In reply to: Greg Sabino Mullane (#12)
hackersgeneral
Re: querying the version of libpq

"Greg Sabino Mullane" <greg@turnstep.com> writes:

The real problem is that neither of these can be trusted to tell you the
*library* version. PQserverVersion() is something else altogether,
and I wouldn't want to assume that pg_config exactly matches the library
you're linked to --- if it's even present at all.

Er...yes it will match exact...because we[1] get the location of the
library files from pg_config as well. :) Handy little utility that.

[ shrug... ] It's not at all hard to think of scenarios where that will
give you misleading results, even granted that you're willing to fall
over when pg_config isn't present. But regardless of that, the
technique simply isn't available to ordinary C code using the standard
dynamic linker.

regards, tom lane

#17Magnus Hagander
magnus@hagander.net
In reply to: Greg Sabino Mullane (#15)
hackersgeneral
Re: querying the version of libpq

On Tue, Oct 5, 2010 at 22:53, Greg Sabino Mullane <greg@turnstep.com> wrote:

Er...yes it will match exact...because we[1] get the location of the
library files from pg_config as well. :) Handy little utility that.

How do you get pg_config to tell you which of the multiple versions of
libpq that may be installed on the machine you are actually linking
against?

Not sure what you mean. pg_config *drives* the compilation and linking,
we don't blindly compile and simply take pg_config's word for it.
pg_config --libdir and pg_config --includedir.

But that's build-time, not run-time.

--
 Magnus Hagander
 Me: http://www.hagander.net/
 Work: http://www.redpill-linpro.com/

#18Greg Sabino Mullane
greg@turnstep.com
In reply to: Magnus Hagander (#17)
hackersgeneral
Re: querying the version of libpq

-----BEGIN PGP SIGNED MESSAGE-----
Hash: RIPEMD160

Not sure what you mean. pg_config *drives* the compilation and linking,
we don't blindly compile and simply take pg_config's word for it.
pg_config --libdir and pg_config --includedir.

But that's build-time, not run-time.

Correct, not sure of your point. Is this a problem? Build-time is
what we want here (determining the libpq we were built with)

- --
Greg Sabino Mullane greg@turnstep.com
End Point Corporation http://www.endpoint.com/
PGP Key: 0x14964AC8 201010060816
http://biglumber.com/x/web?pk=2529DF6AB8F79407E94445B4BC9B906714964AC8
-----BEGIN PGP SIGNATURE-----

iEYEAREDAAYFAkysaKQACgkQvJuQZxSWSsg0uACg78/o1brlOO4RtNi6U+O6noAG
PCYAn1dgpW8A/+BIOjNkhXygc16tyB3R
=YN9u
-----END PGP SIGNATURE-----

#19Magnus Hagander
magnus@hagander.net
In reply to: Greg Sabino Mullane (#18)
hackersgeneral
Re: querying the version of libpq

On Wed, Oct 6, 2010 at 14:17, Greg Sabino Mullane <greg@turnstep.com> wrote:

Not sure what you mean. pg_config *drives* the compilation and linking,
we don't blindly compile and simply take pg_config's word for it.
pg_config --libdir and pg_config --includedir.

But that's build-time, not run-time.

Correct, not sure of your point. Is this a problem? Build-time is
what we want here (determining the libpq we were built with)

The original question was how to find this out from python, which
means at runtime.

And the pg_lib_version of DBD::Pg clearly doesn't tell you what
version of libpq it's using, only what it was built against.

As long as you have libpq 9.0, you can decode the bytea hex thingy,
irregardless of what version of libpq your <whatever other
code/library> was linked against.

--
 Magnus Hagander
 Me: http://www.hagander.net/
 Work: http://www.redpill-linpro.com/

#20Tom Lane
tgl@sss.pgh.pa.us
In reply to: Magnus Hagander (#19)
hackersgeneral
Re: querying the version of libpq

Magnus Hagander <magnus@hagander.net> writes:

On Wed, Oct 6, 2010 at 14:17, Greg Sabino Mullane <greg@turnstep.com> wrote:

But that's build-time, not run-time.

Correct, not sure of your point. Is this a problem? Build-time is
what we want here (determining the libpq we were built with)

The original question was how to find this out from python, which
means at runtime.

And the pg_lib_version of DBD::Pg clearly doesn't tell you what
version of libpq it's using, only what it was built against.

As long as you have libpq 9.0, you can decode the bytea hex thingy,
irregardless of what version of libpq your <whatever other
code/library> was linked against.

The problem here is that you might actually be *running* with a
different version of libpq than you built against. This is actually
highly likely if you distribute an executable that dynamically links
to a shared library at runtime. And the dynamic linker will take any
version of libpq.so that has the same major number, meaning that you
cannot assume that it's not 8.4 just because you built against 9.0.

regards, tom lane

#21Magnus Hagander
magnus@hagander.net
In reply to: Tom Lane (#20)
hackersgeneral
#22Peter Eisentraut
peter_e@gmx.net
In reply to: Massa, Harald Armin (#1)
hackersgeneral
#23Devrim GÜNDÜZ
devrim@gunduz.org
In reply to: Peter Eisentraut (#22)
hackersgeneral
#24A.M.
agentm@themactionfaction.com
In reply to: Devrim GÜNDÜZ (#23)
hackersgeneral
In reply to: Magnus Hagander (#21)
hackersgeneral
#26Dmitriy Igrishin
dmitigr@gmail.com
In reply to: Massa, Harald Armin (#25)
hackersgeneral
In reply to: Dmitriy Igrishin (#26)
hackersgeneral
#28Dmitriy Igrishin
dmitigr@gmail.com
In reply to: Massa, Harald Armin (#27)
hackersgeneral
#29Bruce Momjian
bruce@momjian.us
In reply to: A.M. (#24)
hackersgeneral
In reply to: Magnus Hagander (#2)
hackersgeneral
#31Magnus Hagander
magnus@hagander.net
In reply to: Massa, Harald Armin (#30)
hackersgeneral
#32Dmitriy Igrishin
dmitigr@gmail.com
In reply to: Magnus Hagander (#31)
hackersgeneral
#33Tom Lane
tgl@sss.pgh.pa.us
In reply to: Magnus Hagander (#31)
hackersgeneral
#34Magnus Hagander
magnus@hagander.net
In reply to: Tom Lane (#33)
hackersgeneral
#35Tom Lane
tgl@sss.pgh.pa.us
In reply to: Magnus Hagander (#34)
hackersgeneral
#36Andrew Chernow
ac@esilo.com
In reply to: Magnus Hagander (#34)
hackersgeneral
#37Magnus Hagander
magnus@hagander.net
In reply to: Tom Lane (#35)
hackersgeneral
#38Magnus Hagander
magnus@hagander.net
In reply to: Magnus Hagander (#37)
hackersgeneral
#39crbenesch
chris@beneschtech.com
In reply to: Massa, Harald Armin (#30)
hackersgeneral