Thread: First draft of new FE/BE protocol spec posted for comments
I have committed a first-draft revision of the FE/BE protocol document; you can read it at http://candle.pha.pa.us/main/writings/pgsql/sgml/protocol.html or in a few hours at http://developer.postgresql.org/docs/postgres/protocol.html I'd appreciate it if people would look it over for both presentation and content. There are a couple of loose ends that are still bothering me --- please comment: The new Execute command (part of the extended query protocol) has a field saying whether to return data in text or binary format. When retrieving from a cursor, it is not clear whether this should override the declaration of the cursor (BINARY or not). I am inclined to think that it should, but a possible compromise is to add a third value of the field meaning "don't care", in which case you'd get back text in all cases except when reading a cursor declared BINARY. This would be strictly for backwards compatibility though, and so maybe it doesn't matter. Old apps will probably be going through the simple-Query interface, which will give them the old behavior. I have dropped the CursorResponse message from the protocol, as it didn't seem to be doing anything useful; does anyone care about it? The document as it stands is a little bit schizoid about binary data formats. The new message types I've added are currently specified to use a representation that matches the COPY BINARY file format: an int16 typlen (replaced with 0 if NULL), followed by a field value, where if typlen = -1 the first four bytes of the field value are self-inclusive length. The existing message types that handle binary data (BinaryRow, FunctionCall, FunctionResult) do it differently: a physical length (not counting self) followed by data. This is a bit of a mess, and I think it would make sense to standardize the representation one way or the other. The reason I'm inclined to move away from the old representation is that it's effectively broken on machines where MAXALIGN is greater than four: because it strips the length word out of the "contents" of varlena datatypes, the remainder of the varlena is not correctly aligned when stored in libpq memory. (The mail list archives seem to be down at the moment, so I can't give a URL, but there was a discussion of this point in pgsql-hackers on 2-Aug-99.) This will clearly be a user-visible change for people using binary cursors, but I think we *must* change it now or be stuck with the old mistake forever. An alternative approach, assuming we get as far as implementing architecture-independent binary representations, is to change the COPY BINARY file format to use them, and then the issue largely goes away --- we can stick with the existing layout for BinaryRow and make the other FE/BE messages use a similar format. But in either case, something breaks --- either binary cursors or COPY BINARY files. Any preference which to break? regards, tom lane
On Tue, Apr 15, 2003 at 07:08:30PM -0400, Tom Lane wrote: > I have committed a first-draft revision of the FE/BE protocol document; > you can read it at > http://candle.pha.pa.us/main/writings/pgsql/sgml/protocol.html > or in a few hours at > http://developer.postgresql.org/docs/postgres/protocol.html > I'd appreciate it if people would look it over for both presentation > and content. Just showing my ignorance: I read 46.2.3 Extended Query, and wondered "What is a portal?" (portal == cursor?) also noted that SQL EXECUTE (prepared statement) != Execute (portal) and in 46.3. Message Data Types, reading "There is no predefined limit on the length of a string that can be returned by the backend." one might say Oh no! but of course you know what it's maximum size is by then, as you know the length of the response which contains the string.. Cheers, Patrick
Patrick Welche <prlw1@newn.cam.ac.uk> writes: > Just showing my ignorance: I read 46.2.3 Extended Query, and wondered "What > is a portal?" (portal == cursor?) It's the thing that holds the state of an executable command. I was going to call 'em cursors, but a cursor only works for a SELECT command, so it didn't seem like the right word. I seized on "portal" which is the term already used internally in the backend. If you've got a better idea, let's hear it ... regards, tom lane
Re: [HACKERS] First draft of new FE/BE protocol spec posted for comments
From
"Sander Steffann"
Date:
Hi, > My final question is more of an implementation question than comments on > the protocol itself. Since the jdbc driver needs to be backwardly > compatible with 7.3 and earlier servers that will speak the 2.0 > protocol, what is the recomended way to write the client so that it can > 'detect' which protocol to use. The only thing I can think of is to > start by sending a version 2 protocol message (which will work across > all the database versions that jdbc will be supporting) then if it finds > it it talking to a 7.4 server, close the connection and reconnect using > the version 3 protocol. This will double connection time when > connecting to a 7.4 server but is the only way I can think of to do > this. Is there a better way that I am missing? Since I guess there will be a lot more 7.4+ servers than older servers I think you should at least try protocol v3 first, and if that fails try v2. Try to keep it as fast as possible for the most used version. Could be that that this isn't possible though. I don't know the protocol well enough to be sure. Maybe its an idea to introduce a new messagetype at protocol level with which the client can ask the server which protocol versions it supports. That would make protocol changes a lot easier in the future. And if the server doesn't understand that new messagetype you know you are talking to a v2-only server :) Bye Sander
Barry Lind <blind@xythos.com> writes: > The Bind message contains a field for the typlen of the parameter value. > This field as documented signifies null with the special value of 0. > This implies that there cannot be any datatype that allows an empty > value to mean something other than null, as there would be no way to > distinguish null from a value that was 0 bytes long. No, typlen is the value from pg_type.typlen; there is no meaning to the value zero in that column. A variable-length datum that happened to be zero bytes long would still be associated with a negative typlen. A fixed-length datum of zero bytes isn't real likely ... > Why does the message EmptyQueryResponse still exist? It is documented > as existing for "historical reasons". Can't it be removed in a major > overhaul of the protocol like this? I was ready to get rid of it and then realized that it has a use now. With it, it's guaranteed that the response to Execute will end with exactly one of these messages: CommandComplete, EmptyQueryResponse (if the portal was created from an empty query string), ErrorResponse, or PortalSuspended. Without it, we'd need to invent some other message to signify the end of an Execute cycle. > My final question is more of an implementation question than comments on > the protocol itself. Since the jdbc driver needs to be backwardly > compatible with 7.3 and earlier servers that will speak the 2.0 > protocol, what is the recomended way to write the client so that it can > 'detect' which protocol to use. I'd do it the other way: send a 3.0 connection request and then, if you get a "bad protocol" error response, send a 2.0 connection request. You do have to be a little careful about parsing the connection response since if it's 'E' it might be either 2.0 or 3.0 layout, but that can be handled without too much difficulty I think. (Look at the already-committed code in libpq's fe-connect.c.) regards, tom lane
Tom Lane wrote: > Barry Lind <blind@xythos.com> writes: >>My final question is more of an implementation question than comments on >>the protocol itself. Since the jdbc driver needs to be backwardly >>compatible with 7.3 and earlier servers that will speak the 2.0 >>protocol, what is the recomended way to write the client so that it can >>'detect' which protocol to use. > > I'd do it the other way: send a 3.0 connection request and then, if you > get a "bad protocol" error response, send a 2.0 connection request. > You do have to be a little careful about parsing the connection response > since if it's 'E' it might be either 2.0 or 3.0 layout, but that can be > handled without too much difficulty I think. (Look at the > already-committed code in libpq's fe-connect.c.) > OK. So this is what I plan to do: First try a 3.0 connection. If an error response is received from the connection attempt then check if the error is in a 3.0 format, if yes then report the error, else if not 3.0 format then try a 2.0 connection, if that returns an error then report it. thanks, --Barry