Skip site navigation (1) Skip section navigation (2)

[patch] libpq one-row-at-a-time API

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 (view raw or flat)
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: single-row.diff
Description: text/x-diff (11.2 KB)

Responses

pgsql-hackers by date

Next:From: Robert HaasDate: 2012-06-15 20:03:38
Subject: Re: [RFC][PATCH] Logical Replication/BDR prototype and architecture
Previous:From: Jeff JanesDate: 2012-06-15 17:58:44
Subject: Re: patch: avoid heavyweight locking on hash metapage

Privacy Policy | About PostgreSQL
Copyright © 1996-2014 The PostgreSQL Global Development Group