Thread: PQParam version 0.5

PQParam version 0.5

From
Andrew Chernow
Date:
Here is the lastest pgparam patch.  It is patched against a fresh
checkout on 2007-12-05.

This release adds support for printf-style param puts/execs.  Instead of
having to do a PQputX for each param, you can use a format string and
put multiple params.  PQputf(), PQparamExecf() and PQparamSendf()
support this.  See release notes and conversion specifiers for details.

Also changed PQputint8's prototype.  Previously, it was using a void* as
the value argument, due to a lack of a portable 64-bit type in libpq.
We found an intersting way around this by using macro and variable
argument tricks.

Andrew & Merlin

Attachment

Re: PQParam version 0.5

From
Alvaro Herrera
Date:
Andrew Chernow escribió:

> Also changed PQputint8's prototype.  Previously, it was using a void* as
> the value argument, due to a lack of a portable 64-bit type in libpq. We
> found an intersting way around this by using macro and variable argument
> tricks.

I didn't read the patch, but variadic macros are not portable.  FWIW
uint64 should "portable" to all platforms that have it (and it should be
32 bits on platforms that don't), but you have to watch for
INT64_IS_BUSTED.

--
Alvaro Herrera                 http://www.amazon.com/gp/registry/DXLWNGRJD34J
"I suspect most samba developers are already technically insane...
Of course, since many of them are Australians, you can't tell." (L. Torvalds)

Re: PQParam version 0.5

From
"Merlin Moncure"
Date:
On Dec 5, 2007 2:44 PM, Alvaro Herrera <alvherre@alvh.no-ip.org> wrote:
> Andrew Chernow escribió:
>
> > Also changed PQputint8's prototype.  Previously, it was using a void* as
> > the value argument, due to a lack of a portable 64-bit type in libpq. We
> > found an intersting way around this by using macro and variable argument
> > tricks.
>
> I didn't read the patch, but variadic macros are not portable.  FWIW
> uint64 should "portable" to all platforms that have it (and it should be
> 32 bits on platforms that don't), but you have to watch for
> INT64_IS_BUSTED.

we don't use variadic macros...just a macro wrapper to a variadic function.

merlin

Re: PQParam version 0.5

From
Andrew Chernow
Date:
Merlin Moncure wrote:
> On Dec 5, 2007 2:44 PM, Alvaro Herrera <alvherre@alvh.no-ip.org> wrote:
>> Andrew Chernow escribió:
>>
>>> Also changed PQputint8's prototype.  Previously, it was using a void* as
>>> the value argument, due to a lack of a portable 64-bit type in libpq. We
>>> found an intersting way around this by using macro and variable argument
>>> tricks.
>> I didn't read the patch, but variadic macros are not portable.  FWIW
>> uint64 should "portable" to all platforms that have it (and it should be
>> 32 bits on platforms that don't), but you have to watch for
>> INT64_IS_BUSTED.
>
> we don't use variadic macros...just a macro wrapper to a variadic function.
>
> merlin
>
> ---------------------------(end of broadcast)---------------------------
> TIP 3: Have you checked our extensive FAQ?
>
>                http://www.postgresql.org/docs/faq
>
>

Taken from libpq-fe.h

#define PQputint8(conn, i8) PQputint8v(conn, sizeof(i8), i8)
/* Function subject to change. Do not use directly, see PQputint8. */
extern int PQputint8v(PGconn *conn, size_t valsize, ...);

// goal was pass by value, not by ptr, which was our first solution
PQputint8(conn, 12345678912345LL);

The problem is libpq has no public 64-bit data type to use with the
PQputint8 prototype.  But! if we make PQputint8 a macro that wraps a
variadic function, we get around the data type issue.

Since libpq doesn't have a public 64-bit portable data type, we felt
this was done for a good reason.  We didn't want to break that convention.

andrew

Re: PQParam version 0.5

From
Tom Lane
Date:
Andrew Chernow <ac@esilo.com> writes:
> Here is the lastest pgparam patch.  It is patched against a fresh
> checkout on 2007-12-05.

What is this for?  Why is it a good idea?  It appears to be a fairly
enormous increase in the size of libpq's API, and I really don't think
I want to buy into the idea that libpq should know explicitly about each
and every backend datatype.  The 100% lack of any documentation in the
patch isn't helping you sell it, BTW.

            regards, tom lane

Re: PQParam version 0.5

From
Andrew Chernow
Date:
Tom Lane wrote:
> Andrew Chernow <ac@esilo.com> writes:
>> Here is the lastest pgparam patch.  It is patched against a fresh
>> checkout on 2007-12-05.
>
> What is this for?  Why is it a good idea?  It appears to be a fairly
> enormous increase in the size of libpq's API, and I really don't think
> I want to buy into the idea that libpq should know explicitly about each
> and every backend datatype.  The 100% lack of any documentation in the
> patch isn't helping you sell it, BTW.
>
>             regards, tom lane
>
>

 >>enormous increase in the size of libpq's API
We can dramatically reduce the exports by using macros, if preferred.

 >>The 100% lack of any documentation
Okay, we will do this.  For starters, take a look at test.c.  Below is a
brief description:

1. Managed params, rather than manually building PQexecParam arrays;
which is a little error prone and tedious.

   PQputint4(conn, 5);
   PQputtextptr(conn, "abc");
   PQparamExec(conn, "INSERT INTO t VALUES ($1, $2)", 1, NULL);
   // the NULL arg is a PGresult**, which is auto-cleared
   // when NULL.  Otherwise *result is assigned.

   // or use the print-style: we changed the argument order since
   // our last release, it felt off.
   PGresult *r;
   PQparamExecf(conn, "SELECT * FROM foo(%d, %t)", 1, &r, 5, "abc");

2. In binary result mode, the user has no idea how the data is formatted
and there are no demarshaling functions, thus making the binary
parameterized API impractical.  So, we made PQget functions that support
text or binary results.  The benefit of supporting both is that the new
PQget functions can be used regardless of how the query was executed.

   long long i8;
   PGinet inet;
   PQgetint8(res, 0, 0, &i8);
   PQgetinet(res, 0, 1, &inet);

   // coming soon. Currently, no way of doing this now.
   PGarr arr;
   int item, itemlen;
   PQgetarr(res, 0, 0, &arr);
   // access 2 dim "2d" array - arr[2][7]
   itemlen = PQgetarr2d(&arr, &item, 2, 7);

3. Client & server should both understand how data is formatted over the
wire, otherwise the data received by the client is not useful.  Things
like int4 or even a BOX are not that tricky, but other types are or may
change between versions.

4. Why do atoi(PQgetvalue(...)) everywhere?

Andrew


Re: PQParam version 0.5

From
"Merlin Moncure"
Date:
On Dec 6, 2007 11:58 AM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
> I want to buy into the idea that libpq should know explicitly about each
> and every backend datatype.

I don' t necessarily agree with this.  First of all, the server gives
you an oid for the column which introduces the dependency...this has
been the case for a while now.  Secondly, why shouldn't the client
library understand the data the server hands out, at least for
built-in types.

Usings arrays in client side apps is a huge pain...and not efficient
for large arrays.  Same for the variable length geometry types.

merlin