>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



---------------------------(end of broadcast)---------------------------
TIP 6: explain analyze is your friend

Reply via email to