Re: postgres fe/be protocol
От | Tom Lane |
---|---|
Тема | Re: postgres fe/be protocol |
Дата | |
Msg-id | 14747.963285108@sss.pgh.pa.us обсуждение исходный текст |
Ответ на | Re: postgres fe/be protocol (Chris Bitmead <chrisb@nimrod.itg.telstra.com.au>) |
Список | pgsql-hackers |
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
В списке pgsql-hackers по дате отправления: