Re: PGparam proposal - Mailing list pgsql-hackers

From Andrew Chernow
Subject Re: PGparam proposal
Date
Msg-id 475EAD62.305@esilo.com
Whole thread Raw
In response to PGparam proposal  (Andrew Chernow <ac@esilo.com>)
Responses Re: PGparam proposal
List pgsql-hackers
For starters, if binary results is a feature you wish you could uninvent 
then we are probably dead in the water for that reason.  This goes to 
the core of our concept.  If there is no desire to synch client & server 
in regards to type handling, than this a waste of time.  I think all of 
this would make libpq more powerful.  With that said, my follow up:
> I think a printf-style API is fundamentally a bad idea in this> context. printf only works well when the set of
concepts(datatypes,> format specifiers, etc) is small and fixed;
 

As of now, including numbers and alpha chars, there are 62 classes of 
which we used 11 (a class is the first char).  That leaves 51 classes 
with 62 types per class.  Where I would agree with you, is that over 
time things can become cryptic.

There are only several ways to do this.

1. Use Oids - doesn't work because they are not publically exposed by libpq.

2. Create a function for each type.  This idea was rejected because it 
bloated the API (I'll buy this).

3. Type aliasing schema - naturally, printf-style comes to mind but may 
become cryptic.

I should mention that we were only trying to support built-in pgtypes in 
libpq.  If you are looking to support all external types, then we 
propose the below:

For #3, maybe it would be better to abandon %c or %cc type encoding and 
move into something more verbose.  We could just spell out the type: 
%int4, %point, etc...  Maybe for built-in types you could prepend 'pg': 
%pgint4, %pgpoint. This opens up the namespace and removes scalability 
and cryptic issues.

Expanding on %pgint4 idea, 3rd party types can supply their own %typname 
handlers (a more moduler approach).  You can install them at runtime, 
PQinstallTypeHandler(typname, etc..), or something like that.  When a 
3rd party %typname is encountered, the appropriate handler would be 
used.  Standard pgtypes would be installed by default.

PQinstallTypeHandler(... "gisbox2d" ...);
PQputf(... "%gisbox2d %pgpolygon %pgint4" ...);
//PQgetf would use the same %typname

The only thing libpq should support by default, is the built-in pgtypes.  A handler can expand on this.
> I find the idea of embedding state like that into the PGconn to be> pretty horrid, as well.  It makes the design
non-reentrant>>You can't just randomly change the behavior of existing API functions.
 

Okay.  We initially had the PGparam as a public opaque, but changed it.  We will stop piggy backing off the existing
parameterizedfunctions. 
 
Instead, we will supply a PGparam exec/send functions.

typedef struct pg_param PGparam;//opaque

param = PQparamCreate(conn);
PQputf(param, "%pgint4 %pgtimestamptz", 62, &tstz);
res = PQparamExec(conn, param, "command", resfmt);
//PQparamExec will always PQparamClear(param), whether it failed or not
//That means after an exec/send, the param object is ready for puts
PQparamFinish(param); // free it

// This causes the below sequence of function calls:
// PQparamCreate, PQputf, PQexecParams("... VALUES ($1)"), PQparamFinish
res = PQparamExecf(conn, resfmt, "INSERT INTO t VALUES (%pgint)", 62);
> * the 8.2-to-8.3 change in the width of type money

We have code comments throughout the patches, as well as documented in 
the release notes.  At this point, we solved getf by checking 
PGgetlength.  If its 4, read4 otherwise read8.  For putf, we would have 
to check the server version.
> * the likely future change to type timestamptz to store original>   timezone explicitly

We would have to change how timestamptz handles the binary format from 
that version forward, looks like a switch on sversion for back+forwards 
compatibility.
> * the likely future change to type text to store encoding/collation>   info explicitly

Would the server do text conversion and then pass the converted text 
back to the client?  Or, would it choose a common encoding like UTF-8 
and return the text with encoding and let the client convert.  How does 
this affect text format?

In the end, some of these changes would change the text format right? 
That would push these changes into the API users lap, to parse and fuss 
with.  I just think it is cleaner to synch the binary and/or text 
formats with the server.  If you are looking for ways to change the 
binary/text format of types w/o having to make the most recent clients 
aware of this, then I think we have lost this battle.

Another solution is revamping utils/adt so that it is a shared API for 
client & server.  If you upgrade a client, you would automatically get 
the latest formatting functions.  Just like libpq checks protocol 
version in several places, conn->sversion would have to be checked, or 
maybe have a typefmt_api_version.

andrew & merlin



pgsql-hackers by date:

Previous
From: Alvaro Herrera
Date:
Subject: Re: [BUGS] BUG #3799: csvlog skips some logs
Next
From: Simon Riggs
Date:
Subject: Re: WORM and Read Only Tables (v0.1)