From: | Marko Kreen <markokr(at)gmail(dot)com> |
---|---|
To: | Postgres Hackers <pgsql-hackers(at)postgresql(dot)org> |
Subject: | [patch] libpq one-row-at-a-time API |
Date: | 2012-06-15 18:21:51 |
Message-ID: | 20120615182151.GA8723@gmail.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-hackers |
The row-processor API is now in 9.2, but it solves only the
"different-row-storage" problem, but not the "one-row-at-a-time"
problem, as libpq is still in control until all rows are received.
This means libpq cannet still be used to implement iterative
result processing that almost all high-level languages are using.
We discussed potential API for fetching on single row at a time,
but did not reach conclusion. Basic arguments were:
1) Tom: PQisBusy must keep current behaviour. Thus also PQgetResult()
must keep current behaviour:
* PQisBusy() -> 0: need to call PQgetResult(), which returns PGresult
* PQisBusy() -> 1: need to call PQconsumeInput()
* PQisBusy() must be callable several times in a row, thus be
stateless from clients POV.
2) Me: behaviour must not be controlled by callback, but client code
that uses PQgetResult() + PQisBusy().
Now, looking at the problem with some perspective, the solution
is obvious: when in single-row mode, the PQgetResult() must return
proper PGresult for that single row. And everything else follows that.
Such API is implemented in attached patch:
* PQsetSingleRowMode(conn): set's single-row mode.
* PQisBusy(): stops after each row in single-row mode, sets PGASYNC_ROW_READY.
Thus keeping the property of being repeatedly callable.
* PQgetResult(): returns copy of the row if PGASYNC_ROW_READY. Sets row
resultStatus to PGRES_SINGLE_TUPLE. This needs to be different from
PGRES_TUPLES_OK to detect resultset end.
* PQgetRowData(): can be called instead PQgetResult() to get raw row data
in buffer, for more efficient processing. This is optional feature
that provides the original row-callback promise of avoiding unnecessary
row data copy.
* Although PQgetRowData() makes callback API unnecessary, it is still
fully compatible with it - the callback should not see any difference
whether the resultset is processed in single-row mode or
old single-PGresult mode. Unless it wants to - it can check
PGRES_TUPLES_OK vs. PGRES_SINGLE_TUPLE.
There is some duplicate code here that can be refactored (callback exec),
but I did not do it yet to avoid affecting existing code too much.
--
marko
PS. If a squint it seems like fix of exising API instead of new feature,
so perhaps it can still fit into 9.2?
Attachment | Content-Type | Size |
---|---|---|
single-row.diff | text/x-diff | 11.2 KB |
From | Date | Subject | |
---|---|---|---|
Next Message | Robert Haas | 2012-06-15 20:03:38 | Re: [RFC][PATCH] Logical Replication/BDR prototype and architecture |
Previous Message | Jeff Janes | 2012-06-15 17:58:44 | Re: patch: avoid heavyweight locking on hash metapage |