The PQexec function is adequate for
submitting queries in simple synchronous applications. It has a
couple of major deficiencies however:

PQexec waits for the query to be
completed. The application may have other work to do (such as
maintaining a user interface), in which case it won't want to
block waiting for the response.

Since control is buried inside PQexec, it is hard for the frontend to decide
it would like to try to cancel the ongoing query. (It can be
done from a signal handler, but not otherwise.)

PQexec can return only one
PGresult structure. If the submitted query string contains
multiple SQL commands, all but
the last PGresult are discarded by PQexec.

Applications that do not like these limitations can instead
use the underlying functions that PQexec is built from: PQsendQuery and PQgetResult.

Older programs that used this functionality as well as
PQputline and PQputnbytes could block waiting to send data to
the backend, to address that issue, the function PQsetnonblocking was added.

Old applications can neglect to use PQsetnonblocking and get the older potentially
blocking behavior. Newer programs can use PQsetnonblocking to achieve a completely
non-blocking connection to the backend.

PQsetnonblocking Sets the
nonblocking status of the connection.

int PQsetnonblocking(PGconn *conn, int arg)

Sets the state of the connection to nonblocking if arg is
TRUE, blocking if arg is FALSE. Returns 0 if OK, -1 if error.

In the nonblocking state, calls to PQputline, PQputnbytes, PQsendQuery and PQendcopy will not block but instead return
an error if they need to be called again.

When a database connection has been set to non-blocking
mode and PQexec is called, it will
temporarily set the state of the connection to blocking until
the PQexec completes.

More of libpq is expected to be made safe for PQsetnonblocking functionality in the near
future.

PQisnonblocking Returns the
blocking status of the database connection.

int PQisnonblocking(const PGconn *conn)

Returns TRUE if the connection is set to non-blocking mode,
FALSE if blocking.

PQsendQuery Submit a query to
Postgres without waiting for
the result(s). TRUE is returned if the query was successfully
dispatched, FALSE if not (in which case, use PQerrorMessage
to get more information about the failure).

int PQsendQuery(PGconn *conn,
const char *query);

After successfully calling PQsendQuery, call PQgetResult one or more times to obtain the query
results. PQsendQuery may not be called
again (on the same connection) until PQgetResult has returned NULL, indicating that the
query is done.

PQgetResult Wait for the next
result from a prior PQsendQuery,
and return it. NULL is returned when the query is complete
and there will be no more results.

PGresult *PQgetResult(PGconn *conn);

PQgetResult must be called
repeatedly until it returns NULL, indicating that the query is
done. (If called when no query is active,
PQgetResult will just return NULL at once.) Each
non-null result from PQgetResult
should be processed using the same PGresult accessor
functions previously described. Don't forget to free each
result object with PQclear when
done with it. Note that PQgetResult
will block only if a query is active and the necessary
response data has not yet been read by PQconsumeInput.

Using PQsendQuery and PQgetResult solves one of PQexec's problems: If a query string contains
multiple SQL commands, the results
of those commands can be obtained individually. (This allows a
simple form of overlapped processing, by the way: the frontend
can be handling the results of one query while the backend is
still working on later queries in the same query string.)
However, calling PQgetResult will still
cause the frontend to block until the backend completes the next
SQL command. This can be avoided by
proper use of three more functions:

PQconsumeInput If input is
available from the backend, consume it.

int PQconsumeInput(PGconn *conn);

PQconsumeInput normally returns 1
indicating "no error", but returns 0 if there was some kind of
trouble (in which case PQerrorMessage is
set). Note that the result does not say whether any input data was
actually collected. After calling PQconsumeInput, the application may check
PQisBusy and/or PQnotifies to see if their state has changed.

PQconsumeInput may be called
even if the application is not prepared to deal with a result
or notification just yet. The routine will read available
data and save it in a buffer, thereby causing a select(2) read-ready indication to go away.
The application can thus use PQconsumeInput to clear the select condition immediately, and then
examine the results at leisure.

PQisBusy Returns 1 if a query is
busy, that is, PQgetResult would
block waiting for input. A 0 return indicates that PQgetResult can be called with assurance of
not blocking.

int PQisBusy(PGconn *conn);

PQisBusy will not itself attempt to
read data from the backend; therefore PQconsumeInput must be invoked first, or the busy
state will never end.

PQflush Attempt to flush any
data queued to the backend, returns 0 if successful (or if
the send queue is empty) or EOF if it failed for some
reason.

int PQflush(PGconn *conn);

PQflush needs to be called on a
non-blocking connection before calling select to determine if a response has arrived. If 0
is returned it ensures that there is no data queued to the backend
that has not actually been sent. Only applications that have used
PQsetnonblocking have a need for this.

PQsocket Obtain the file
descriptor number for the backend connection socket. A valid
descriptor will be >= 0; a result of -1 indicates that no
backend connection is currently open.

int PQsocket(const PGconn *conn);

PQsocket should be used to obtain
the backend socket descriptor in preparation for executing
select(2). This allows an application
using a blocking connection to wait for either backend responses or
other conditions. If the result of select(2) indicates that data can be read from the
backend socket, then PQconsumeInput
should be called to read the data; after which, PQisBusy, PQgetResult,
and/or PQnotifies can be used to process
the response.

Non-blocking connections (that have used PQsetnonblocking) should not use select until PQflush has returned 0 indicating that there
is no buffered data waiting to be sent to the backend.

A typical frontend using these functions will have a main loop
that uses select(2) to wait for all the
conditions that it must respond to. One of the conditions will be
input available from the backend, which in select's terms is readable data on the file
descriptor identified by PQsocket. When
the main loop detects input ready, it should call PQconsumeInput to read the input. It can then
call PQisBusy, followed by PQgetResult if PQisBusy
returns false (0). It can also call PQnotifies to detect NOTIFY messages (see
"Asynchronous Notification", below).

A frontend that uses PQsendQuery/PQgetResult
can also attempt to cancel a query that is still being processed
by the backend.

PQrequestCancel Request that
Postgres abandon processing
of the current query.

int PQrequestCancel(PGconn *conn);

The return value is 1 if the cancel request was successfully
dispatched, 0 if not. (If not, PQerrorMessage tells why not.) Successful dispatch
is no guarantee that the request will have any effect, however.
Regardless of the return value of PQrequestCancel, the application must continue with
the normal result-reading sequence using
PQgetResult. If the cancellation is effective, the
current query will terminate early and return an error
result. If the cancellation fails (say, because the backend
was already done processing the query), then there will be no
visible result at all.

Note that if the current query is part of a transaction,
cancellation will abort the whole transaction.

PQrequestCancel can safely be
invoked from a signal handler. So, it is also possible to use it
in conjunction with plain PQexec, if
the decision to cancel can be made in a signal handler. For
example, psql invokes PQrequestCancel from a SIGINT signal handler,
thus allowing interactive cancellation of queries that it issues
through PQexec. Note that PQrequestCancel will have no effect if the
connection is not currently open or the backend is not currently
processing a query.