Re: PGparam proposal

From: Andrew Chernow <ac(at)esilo(dot)com>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: pgsql-hackers(at)postgresql(dot)org, Merlin Moncure <mmoncure(at)gmail(dot)com>
Subject: Re: PGparam proposal
Date: 2007-12-11 18:09:41
Message-ID: 475ED265.8070009@esilo.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

>library users would have no idea whether
> the values they provide are being sent as text or binary.

The putf interface currently abstracts how it actually sends it.
Although, you do put a C type rather than a string. There is a putstr
"%pqtypstr", which puts the string representation of a type.

> providing an easier-to-use
> API for PQexecParams and friends, and what parts are actually
> interested in binary data transmission (and why)

There are two things happening here and two things we are trying to solve:

1. putf and PGparam - simpler interface for executing queries using
parameterized functions.

2. getf - doesn't use PGparam at all. You pass it a PGresult. The goal
of this is to translate either text or binary results into a uniform C
type or structure. For instance, we expose the below structure for inet.

/* This struct works with CIDR as well. */
typedef struct
{
/* convenience, value the same as first 2 bytes of sa_buf */
unsigned short sa_family;

/* mask, ie. /24 */
int mask;
int is_cidr;

/* Cast to: sockaddr, sockaddr_in, sockaddr_in6, sockaddr_stroage */
int sa_len;
char sa_buf[128]; /* avoid referencing sockaddr structs */
} PGinet;

// "res" could be text or binary results, but PGinet remains the same.
PGinet inet;
PGgetf(res, tup_num, "%pginet", field_num &inet);
connect(sock,
(const struct sockaddr *)inet.sa_buf,
(socklen_t)inet.sa_len);

The above is simpler than examining "10.0.0.1/32" and converting it to a
struct sockaddr. The same struct is used when putting a type as a "C
type" rather than as a string. You can use getf without ever using
putf+PGparam, and vise-versa.

> your proposal completely glossed over the
> issue of exactly what data structure would be exposed to clients for
> anything more complex than an integer

Complex types require a receiving structure on the client side, thus the
types we added to libpq-fe.h: PGinet, PGpolygon, PGarray, PGtimestamp,
etc... But keep in mind that these structs are the result of libpq
extracting the data from text/binary formats and assigning data to
struct members. It does not expose raw format, the API user can already
get that via PQgetvalue().

> If we could have libpq insulate client apps from these kinds
> of changes, that would be one thing;

This is the goal of getf. The API user interfaces through PGinet, not
through the output of PQgetvalue(). We propose that its libpq's job
internally to handle changes to text or binary formats and expose
consistent types/structures.

> type NUMERIC (say, as a bignum integer plus
> exponent instead of the current BCD-ish format)

This is what we want to hide inside libpq's getf. Just expose a
PGnumeric that has been translated into c types. We never expose the
wire format, only the C translated version of it.

> without any reliance on binary data transmission whatsoever.

Yes this is possible, but at a performance & ease-of-use cost. Our
performance tests didn't show much gain with strings or ints, but
complex types were 10 times faster (putting/getting arrays, polygons,
paths, etc...). So, the trade-off is a little more maintainence
overhead on libpq.

BTW, previously we mentioned a 3rd party handler api concept. This is
not needed to get libpq up and going with built-in types (which is all
we feel it should be responsible for). the handler API can always be
added later w/o changing existing functions ... have to add a couple though.

andrew & merlin

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Guillaume Lelarge 2007-12-11 18:17:33 psql \dFp's behavior
Previous Message Peter Eisentraut 2007-12-11 18:03:03 Re: archive_command failures report confusing exit status