Thread: postgres fe/be protocol
I inserted some debug into libpq, then I ran psql, and I noticed that there are two 'Z' "Ready for query" messages sent after each query. Is there a reason for that? Is it a bug?
Chris Bitmead <chris@bitmead.com> writes: > I inserted some debug into libpq, then I ran psql, and I noticed that > there are two 'Z' "Ready for query" messages sent after each query. Is > there a reason for that? Is it a bug? I'm pretty sure the backend sends only one 'Z' per query cycle. Are you watching the outgoing requests too? Maybe psql is sending an extra empty query. (It didn't use to do that, but maybe it does after Peter's recent work on it...) regards, tom lane
----- Original Message ----- From: Tom Lane <tgl@sss.pgh.pa.us> To: Chris Bitmead <chris@bitmead.com> Cc: Postgres Hackers List <hackers@postgresql.org> Sent: Monday, July 10, 2000 4:44 PM Subject: Re: [HACKERS] postgres fe/be protocol > Chris Bitmead <chris@bitmead.com> writes: > > I inserted some debug into libpq, then I ran psql, and I noticed that > > there are two 'Z' "Ready for query" messages sent after each query. Is > > there a reason for that? Is it a bug? > > I'm pretty sure the backend sends only one 'Z' per query cycle. Are you > watching the outgoing requests too? Maybe psql is sending an extra > empty query. (It didn't use to do that, but maybe it does after Peter's > recent work on it...) Actually it used to when it first made a connection to test that it was alive, but not afterwards. JDBC was originally based on libpq, but I replaced the empty query with a couple of useful ones. > > regards, tom lane
Tom Lane wrote: > > Chris Bitmead <chris@bitmead.com> writes: > > I inserted some debug into libpq, then I ran psql, and I noticed that > > there are two 'Z' "Ready for query" messages sent after each query. Is > > there a reason for that? Is it a bug? > > I'm pretty sure the backend sends only one 'Z' per query cycle. Are you > watching the outgoing requests too? Maybe psql is sending an extra > empty query. (It didn't use to do that, but maybe it does after Peter's > recent work on it...) I put in a printf in parseInput in fe-exec.c in libpq, straight after it reads the id. This is only going to see messages incoming to the front end. I also had a break-point on PQexec and it was only called once per query. For each query that I input to psql, everything looked normal except for the two 'Z's. Ok, I've just done it again on another platform with the same result. This is what I see... chrisb=# select * from a; P T D C Z Zaa | bb | cc -----+-----+-----aaa | bbb | ccc (1 row) We've got the P - select results, T - describe output D - one output tuple, C - complete Z - ready for input. It all seems sensible except for the two Z's.
Chris Bitmead <chrisb@nimrod.itg.telstra.com.au> writes: > Tom Lane wrote: >> I'm pretty sure the backend sends only one 'Z' per query cycle. > I put in a printf in parseInput in fe-exec.c in libpq, straight after > it reads the id. Oh. What you're missing is that the input message isn't necessarily *consumed* when first seen. The sequence of events is * absorb bufferload of data into libpq input buffer; * parse messages in parseInput until 'C' is seen; * when 'C' message is completely read, set asyncStatus = PGASYNC_READY (fe-exec.c line 756 in current sources), then absorb that message by advancing inCursor (line 878) and loop back around. Now it sees the final 'Z' message, but decides at line 713 not to process it just yet. So it returns to PQgetResult, which finishes off and stashes away the PGresult object, and then sets asyncStatus = PGASYNC_BUSY again. * PQexec will now loop around and call PQgetResult and thence parseInput again, which will now absorb the 'Z' and set asyncStatus = PGASYNC_IDLE, which finally allows the PQexec loop to return. In the meantime your printf printed the 'Z' a second time. This is kind of baroque, I agree, but it seemed to be necessary to support asynchronous data reading without doing too much damage to backward compatibility of PQexec() semantics. In particular, the critical thing here is that we need to be able to deliver a sequence of PGresult objects when the query string contains multiple commands and the application is using PQgetResult --- but the old behavior of PQexec was that you only got back the *last* PGresult if the query string produced more than one, so I had to preserve that... regards, tom lane