Current File : //usr/share/doc/postgresql-9.2.24/html/libpq-async.html |
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>Asynchronous Command Processing</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REV="MADE"
HREF="mailto:pgsql-docs@postgresql.org"><LINK
REL="HOME"
TITLE="PostgreSQL 9.2.24 Documentation"
HREF="index.html"><LINK
REL="UP"
TITLE="libpq - C Library"
HREF="libpq.html"><LINK
REL="PREVIOUS"
TITLE="Command Execution Functions"
HREF="libpq-exec.html"><LINK
REL="NEXT"
TITLE="Retrieving Query Results Row-By-Row"
HREF="libpq-single-row-mode.html"><LINK
REL="STYLESHEET"
TYPE="text/css"
HREF="stylesheet.css"><META
HTTP-EQUIV="Content-Type"
CONTENT="text/html; charset=ISO-8859-1"><META
NAME="creation"
CONTENT="2017-11-06T22:43:11"></HEAD
><BODY
CLASS="SECT1"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="5"
ALIGN="center"
VALIGN="bottom"
><A
HREF="index.html"
>PostgreSQL 9.2.24 Documentation</A
></TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="top"
><A
TITLE="Command Execution Functions"
HREF="libpq-exec.html"
ACCESSKEY="P"
>Prev</A
></TD
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="top"
><A
HREF="libpq.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="60%"
ALIGN="center"
VALIGN="bottom"
>Chapter 31. <SPAN
CLASS="APPLICATION"
>libpq</SPAN
> - C Library</TD
><TD
WIDTH="20%"
ALIGN="right"
VALIGN="top"
><A
TITLE="Retrieving Query Results Row-By-Row"
HREF="libpq-single-row-mode.html"
ACCESSKEY="N"
>Next</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECT1"
><H1
CLASS="SECT1"
><A
NAME="LIBPQ-ASYNC"
>31.4. Asynchronous Command Processing</A
></H1
><P
> The <CODE
CLASS="FUNCTION"
>PQexec</CODE
> function is adequate for submitting
commands in normal, synchronous applications. It has a few
deficiencies, however, that can be of importance to some users:
<P
></P
></P><UL
><LI
><P
> <CODE
CLASS="FUNCTION"
>PQexec</CODE
> waits for the command to be completed.
The application might have other work to do (such as maintaining a
user interface), in which case it won't want to block waiting for
the response.
</P
></LI
><LI
><P
> Since the execution of the client application is suspended while it
waits for the result, it is hard for the application to decide that
it would like to try to cancel the ongoing command. (It can be done
from a signal handler, but not otherwise.)
</P
></LI
><LI
><P
> <CODE
CLASS="FUNCTION"
>PQexec</CODE
> can return only one
<TT
CLASS="STRUCTNAME"
>PGresult</TT
> structure. If the submitted command
string contains multiple <ACRONYM
CLASS="ACRONYM"
>SQL</ACRONYM
> commands, all but
the last <TT
CLASS="STRUCTNAME"
>PGresult</TT
> are discarded by
<CODE
CLASS="FUNCTION"
>PQexec</CODE
>.
</P
></LI
><LI
><P
> <CODE
CLASS="FUNCTION"
>PQexec</CODE
> always collects the command's entire result,
buffering it in a single <TT
CLASS="STRUCTNAME"
>PGresult</TT
>. While
this simplifies error-handling logic for the application, it can be
impractical for results containing many rows.
</P
></LI
></UL
><P>
</P
><P
> Applications that do not like these limitations can instead use the
underlying functions that <CODE
CLASS="FUNCTION"
>PQexec</CODE
> is built from:
<CODE
CLASS="FUNCTION"
>PQsendQuery</CODE
> and <CODE
CLASS="FUNCTION"
>PQgetResult</CODE
>.
There are also
<CODE
CLASS="FUNCTION"
>PQsendQueryParams</CODE
>,
<CODE
CLASS="FUNCTION"
>PQsendPrepare</CODE
>,
<CODE
CLASS="FUNCTION"
>PQsendQueryPrepared</CODE
>,
<CODE
CLASS="FUNCTION"
>PQsendDescribePrepared</CODE
>, and
<CODE
CLASS="FUNCTION"
>PQsendDescribePortal</CODE
>,
which can be used with <CODE
CLASS="FUNCTION"
>PQgetResult</CODE
> to duplicate
the functionality of
<CODE
CLASS="FUNCTION"
>PQexecParams</CODE
>,
<CODE
CLASS="FUNCTION"
>PQprepare</CODE
>,
<CODE
CLASS="FUNCTION"
>PQexecPrepared</CODE
>,
<CODE
CLASS="FUNCTION"
>PQdescribePrepared</CODE
>, and
<CODE
CLASS="FUNCTION"
>PQdescribePortal</CODE
>
respectively.
<P
></P
></P><DIV
CLASS="VARIABLELIST"
><DL
><DT
><A
NAME="LIBPQ-PQSENDQUERY"
></A
><CODE
CLASS="FUNCTION"
>PQsendQuery</CODE
>
</DT
><DD
><P
> Submits a command to the server without waiting for the result(s).
1 is returned if the command was successfully dispatched and 0 if
not (in which case, use <CODE
CLASS="FUNCTION"
>PQerrorMessage</CODE
> to get more
information about the failure).
</P><PRE
CLASS="SYNOPSIS"
>int PQsendQuery(PGconn *conn, const char *command);</PRE
><P>
After successfully calling <CODE
CLASS="FUNCTION"
>PQsendQuery</CODE
>, call
<CODE
CLASS="FUNCTION"
>PQgetResult</CODE
> one or more times to obtain the
results. <CODE
CLASS="FUNCTION"
>PQsendQuery</CODE
> cannot be called again
(on the same connection) until <CODE
CLASS="FUNCTION"
>PQgetResult</CODE
>
has returned a null pointer, indicating that the command is done.
</P
></DD
><DT
><A
NAME="LIBPQ-PQSENDQUERYPARAMS"
></A
><CODE
CLASS="FUNCTION"
>PQsendQueryParams</CODE
>
</DT
><DD
><P
> Submits a command and separate parameters to the server without
waiting for the result(s).
</P><PRE
CLASS="SYNOPSIS"
>int PQsendQueryParams(PGconn *conn,
const char *command,
int nParams,
const Oid *paramTypes,
const char * const *paramValues,
const int *paramLengths,
const int *paramFormats,
int resultFormat);</PRE
><P>
This is equivalent to <CODE
CLASS="FUNCTION"
>PQsendQuery</CODE
> except that
query parameters can be specified separately from the query string.
The function's parameters are handled identically to
<CODE
CLASS="FUNCTION"
>PQexecParams</CODE
>. Like
<CODE
CLASS="FUNCTION"
>PQexecParams</CODE
>, it will not work on 2.0-protocol
connections, and it allows only one command in the query string.
</P
></DD
><DT
><A
NAME="LIBPQ-PQSENDPREPARE"
></A
><CODE
CLASS="FUNCTION"
>PQsendPrepare</CODE
>
</DT
><DD
><P
> Sends a request to create a prepared statement with the given
parameters, without waiting for completion.
</P><PRE
CLASS="SYNOPSIS"
>int PQsendPrepare(PGconn *conn,
const char *stmtName,
const char *query,
int nParams,
const Oid *paramTypes);</PRE
><P>
This is an asynchronous version of <CODE
CLASS="FUNCTION"
>PQprepare</CODE
>: it
returns 1 if it was able to dispatch the request, and 0 if not.
After a successful call, call <CODE
CLASS="FUNCTION"
>PQgetResult</CODE
> to
determine whether the server successfully created the prepared
statement. The function's parameters are handled identically to
<CODE
CLASS="FUNCTION"
>PQprepare</CODE
>. Like
<CODE
CLASS="FUNCTION"
>PQprepare</CODE
>, it will not work on 2.0-protocol
connections.
</P
></DD
><DT
><A
NAME="LIBPQ-PQSENDQUERYPREPARED"
></A
><CODE
CLASS="FUNCTION"
>PQsendQueryPrepared</CODE
>
</DT
><DD
><P
> Sends a request to execute a prepared statement with given
parameters, without waiting for the result(s).
</P><PRE
CLASS="SYNOPSIS"
>int PQsendQueryPrepared(PGconn *conn,
const char *stmtName,
int nParams,
const char * const *paramValues,
const int *paramLengths,
const int *paramFormats,
int resultFormat);</PRE
><P>
This is similar to <CODE
CLASS="FUNCTION"
>PQsendQueryParams</CODE
>, but
the command to be executed is specified by naming a
previously-prepared statement, instead of giving a query string.
The function's parameters are handled identically to
<CODE
CLASS="FUNCTION"
>PQexecPrepared</CODE
>. Like
<CODE
CLASS="FUNCTION"
>PQexecPrepared</CODE
>, it will not work on
2.0-protocol connections.
</P
></DD
><DT
><A
NAME="LIBPQ-PQSENDDESCRIBEPREPARED"
></A
><CODE
CLASS="FUNCTION"
>PQsendDescribePrepared</CODE
>
</DT
><DD
><P
> Submits a request to obtain information about the specified
prepared statement, without waiting for completion.
</P><PRE
CLASS="SYNOPSIS"
>int PQsendDescribePrepared(PGconn *conn, const char *stmtName);</PRE
><P>
This is an asynchronous version of <CODE
CLASS="FUNCTION"
>PQdescribePrepared</CODE
>:
it returns 1 if it was able to dispatch the request, and 0 if not.
After a successful call, call <CODE
CLASS="FUNCTION"
>PQgetResult</CODE
> to
obtain the results. The function's parameters are handled
identically to <CODE
CLASS="FUNCTION"
>PQdescribePrepared</CODE
>. Like
<CODE
CLASS="FUNCTION"
>PQdescribePrepared</CODE
>, it will not work on
2.0-protocol connections.
</P
></DD
><DT
><A
NAME="LIBPQ-PQSENDDESCRIBEPORTAL"
></A
><CODE
CLASS="FUNCTION"
>PQsendDescribePortal</CODE
>
</DT
><DD
><P
> Submits a request to obtain information about the specified
portal, without waiting for completion.
</P><PRE
CLASS="SYNOPSIS"
>int PQsendDescribePortal(PGconn *conn, const char *portalName);</PRE
><P>
This is an asynchronous version of <CODE
CLASS="FUNCTION"
>PQdescribePortal</CODE
>:
it returns 1 if it was able to dispatch the request, and 0 if not.
After a successful call, call <CODE
CLASS="FUNCTION"
>PQgetResult</CODE
> to
obtain the results. The function's parameters are handled
identically to <CODE
CLASS="FUNCTION"
>PQdescribePortal</CODE
>. Like
<CODE
CLASS="FUNCTION"
>PQdescribePortal</CODE
>, it will not work on
2.0-protocol connections.
</P
></DD
><DT
><A
NAME="LIBPQ-PQGETRESULT"
></A
><CODE
CLASS="FUNCTION"
>PQgetResult</CODE
>
</DT
><DD
><P
> Waits for the next result from a prior
<CODE
CLASS="FUNCTION"
>PQsendQuery</CODE
>,
<CODE
CLASS="FUNCTION"
>PQsendQueryParams</CODE
>,
<CODE
CLASS="FUNCTION"
>PQsendPrepare</CODE
>,
<CODE
CLASS="FUNCTION"
>PQsendQueryPrepared</CODE
>,
<CODE
CLASS="FUNCTION"
>PQsendDescribePrepared</CODE
>, or
<CODE
CLASS="FUNCTION"
>PQsendDescribePortal</CODE
>
call, and returns it.
A null pointer is returned when the command is complete and there
will be no more results.
</P><PRE
CLASS="SYNOPSIS"
>PGresult *PQgetResult(PGconn *conn);</PRE
><P>
</P
><P
> <CODE
CLASS="FUNCTION"
>PQgetResult</CODE
> must be called repeatedly until
it returns a null pointer, indicating that the command is done.
(If called when no command is active,
<CODE
CLASS="FUNCTION"
>PQgetResult</CODE
> will just return a null pointer
at once.) Each non-null result from
<CODE
CLASS="FUNCTION"
>PQgetResult</CODE
> should be processed using the
same <TT
CLASS="STRUCTNAME"
>PGresult</TT
> accessor functions previously
described. Don't forget to free each result object with
<CODE
CLASS="FUNCTION"
>PQclear</CODE
> when done with it. Note that
<CODE
CLASS="FUNCTION"
>PQgetResult</CODE
> will block only if a command is
active and the necessary response data has not yet been read by
<CODE
CLASS="FUNCTION"
>PQconsumeInput</CODE
>.
</P
><DIV
CLASS="NOTE"
><BLOCKQUOTE
CLASS="NOTE"
><P
><B
>Note: </B
> Even when <CODE
CLASS="FUNCTION"
>PQresultStatus</CODE
> indicates a fatal
error, <CODE
CLASS="FUNCTION"
>PQgetResult</CODE
> should be called until it
returns a null pointer, to allow <SPAN
CLASS="APPLICATION"
>libpq</SPAN
> to
process the error information completely.
</P
></BLOCKQUOTE
></DIV
></DD
></DL
></DIV
><P>
</P
><P
> Using <CODE
CLASS="FUNCTION"
>PQsendQuery</CODE
> and
<CODE
CLASS="FUNCTION"
>PQgetResult</CODE
> solves one of
<CODE
CLASS="FUNCTION"
>PQexec</CODE
>'s problems: If a command string contains
multiple <ACRONYM
CLASS="ACRONYM"
>SQL</ACRONYM
> commands, the results of those commands
can be obtained individually. (This allows a simple form of overlapped
processing, by the way: the client can be handling the results of one
command while the server is still working on later queries in the same
command string.)
</P
><P
> Another frequently-desired feature that can be obtained with
<CODE
CLASS="FUNCTION"
>PQsendQuery</CODE
> and <CODE
CLASS="FUNCTION"
>PQgetResult</CODE
>
is retrieving large query results a row at a time. This is discussed
in <A
HREF="libpq-single-row-mode.html"
>Section 31.5</A
>.
</P
><P
> By itself, calling <CODE
CLASS="FUNCTION"
>PQgetResult</CODE
>
will still cause the client to block until the server completes the
next <ACRONYM
CLASS="ACRONYM"
>SQL</ACRONYM
> command. This can be avoided by proper
use of two more functions:
<P
></P
></P><DIV
CLASS="VARIABLELIST"
><DL
><DT
><A
NAME="LIBPQ-PQCONSUMEINPUT"
></A
><CODE
CLASS="FUNCTION"
>PQconsumeInput</CODE
>
</DT
><DD
><P
> If input is available from the server, consume it.
</P><PRE
CLASS="SYNOPSIS"
>int PQconsumeInput(PGconn *conn);</PRE
><P>
</P
><P
> <CODE
CLASS="FUNCTION"
>PQconsumeInput</CODE
> normally returns 1 indicating
<SPAN
CLASS="QUOTE"
>"no error"</SPAN
>, but returns 0 if there was some kind of
trouble (in which case <CODE
CLASS="FUNCTION"
>PQerrorMessage</CODE
> can be
consulted). Note that the result does not say whether any input
data was actually collected. After calling
<CODE
CLASS="FUNCTION"
>PQconsumeInput</CODE
>, the application can check
<CODE
CLASS="FUNCTION"
>PQisBusy</CODE
> and/or
<CODE
CLASS="FUNCTION"
>PQnotifies</CODE
> to see if their state has changed.
</P
><P
> <CODE
CLASS="FUNCTION"
>PQconsumeInput</CODE
> can be called even if the
application is not prepared to deal with a result or notification
just yet. The function will read available data and save it in
a buffer, thereby causing a <CODE
CLASS="FUNCTION"
>select()</CODE
>
read-ready indication to go away. The application can thus use
<CODE
CLASS="FUNCTION"
>PQconsumeInput</CODE
> to clear the
<CODE
CLASS="FUNCTION"
>select()</CODE
> condition immediately, and then
examine the results at leisure.
</P
></DD
><DT
><A
NAME="LIBPQ-PQISBUSY"
></A
><CODE
CLASS="FUNCTION"
>PQisBusy</CODE
>
</DT
><DD
><P
> Returns 1 if a command is busy, that is,
<CODE
CLASS="FUNCTION"
>PQgetResult</CODE
> would block waiting for input.
A 0 return indicates that <CODE
CLASS="FUNCTION"
>PQgetResult</CODE
> can be
called with assurance of not blocking.
</P><PRE
CLASS="SYNOPSIS"
>int PQisBusy(PGconn *conn);</PRE
><P>
</P
><P
> <CODE
CLASS="FUNCTION"
>PQisBusy</CODE
> will not itself attempt to read data
from the server; therefore <CODE
CLASS="FUNCTION"
>PQconsumeInput</CODE
>
must be invoked first, or the busy state will never end.
</P
></DD
></DL
></DIV
><P>
</P
><P
> A typical application using these functions will have a main loop that
uses <CODE
CLASS="FUNCTION"
>select()</CODE
> or <CODE
CLASS="FUNCTION"
>poll()</CODE
> to wait for
all the conditions that it must respond to. One of the conditions
will be input available from the server, which in terms of
<CODE
CLASS="FUNCTION"
>select()</CODE
> means readable data on the file
descriptor identified by <CODE
CLASS="FUNCTION"
>PQsocket</CODE
>. When the main
loop detects input ready, it should call
<CODE
CLASS="FUNCTION"
>PQconsumeInput</CODE
> to read the input. It can then
call <CODE
CLASS="FUNCTION"
>PQisBusy</CODE
>, followed by
<CODE
CLASS="FUNCTION"
>PQgetResult</CODE
> if <CODE
CLASS="FUNCTION"
>PQisBusy</CODE
>
returns false (0). It can also call <CODE
CLASS="FUNCTION"
>PQnotifies</CODE
>
to detect <TT
CLASS="COMMAND"
>NOTIFY</TT
> messages (see <A
HREF="libpq-notify.html"
>Section 31.8</A
>).
</P
><P
> A client that uses
<CODE
CLASS="FUNCTION"
>PQsendQuery</CODE
>/<CODE
CLASS="FUNCTION"
>PQgetResult</CODE
>
can also attempt to cancel a command that is still being processed
by the server; see <A
HREF="libpq-cancel.html"
>Section 31.6</A
>. But regardless of
the return value of <CODE
CLASS="FUNCTION"
>PQcancel</CODE
>, the application
must continue with the normal result-reading sequence using
<CODE
CLASS="FUNCTION"
>PQgetResult</CODE
>. A successful cancellation will
simply cause the command to terminate sooner than it would have
otherwise.
</P
><P
> By using the functions described above, it is possible to avoid
blocking while waiting for input from the database server. However,
it is still possible that the application will block waiting to send
output to the server. This is relatively uncommon but can happen if
very long SQL commands or data values are sent. (It is much more
probable if the application sends data via <TT
CLASS="COMMAND"
>COPY IN</TT
>,
however.) To prevent this possibility and achieve completely
nonblocking database operation, the following additional functions
can be used.
<P
></P
></P><DIV
CLASS="VARIABLELIST"
><DL
><DT
><A
NAME="LIBPQ-PQSETNONBLOCKING"
></A
><CODE
CLASS="FUNCTION"
>PQsetnonblocking</CODE
>
</DT
><DD
><P
> Sets the nonblocking status of the connection.
</P><PRE
CLASS="SYNOPSIS"
>int PQsetnonblocking(PGconn *conn, int arg);</PRE
><P>
</P
><P
> Sets the state of the connection to nonblocking if
<TT
CLASS="PARAMETER"
>arg</TT
> is 1, or blocking if
<TT
CLASS="PARAMETER"
>arg</TT
> is 0. Returns 0 if OK, -1 if error.
</P
><P
> In the nonblocking state, calls to
<CODE
CLASS="FUNCTION"
>PQsendQuery</CODE
>, <CODE
CLASS="FUNCTION"
>PQputline</CODE
>,
<CODE
CLASS="FUNCTION"
>PQputnbytes</CODE
>, and
<CODE
CLASS="FUNCTION"
>PQendcopy</CODE
> will not block but instead return
an error if they need to be called again.
</P
><P
> Note that <CODE
CLASS="FUNCTION"
>PQexec</CODE
> does not honor nonblocking
mode; if it is called, it will act in blocking fashion anyway.
</P
></DD
><DT
><A
NAME="LIBPQ-PQISNONBLOCKING"
></A
><CODE
CLASS="FUNCTION"
>PQisnonblocking</CODE
>
</DT
><DD
><P
> Returns the blocking status of the database connection.
</P><PRE
CLASS="SYNOPSIS"
>int PQisnonblocking(const PGconn *conn);</PRE
><P>
</P
><P
> Returns 1 if the connection is set to nonblocking mode and 0 if
blocking.
</P
></DD
><DT
><A
NAME="LIBPQ-PQFLUSH"
></A
><CODE
CLASS="FUNCTION"
>PQflush</CODE
>
</DT
><DD
><P
> Attempts to flush any queued output data to the server. Returns
0 if successful (or if the send queue is empty), -1 if it failed
for some reason, or 1 if it was unable to send all the data in
the send queue yet (this case can only occur if the connection
is nonblocking).
</P><PRE
CLASS="SYNOPSIS"
>int PQflush(PGconn *conn);</PRE
><P>
</P
></DD
></DL
></DIV
><P>
</P
><P
> After sending any command or data on a nonblocking connection, call
<CODE
CLASS="FUNCTION"
>PQflush</CODE
>. If it returns 1, wait for the socket
to become read- or write-ready. If it becomes write-ready, call
<CODE
CLASS="FUNCTION"
>PQflush</CODE
> again. If it becomes read-ready, call
<CODE
CLASS="FUNCTION"
>PQconsumeInput</CODE
>, then call
<CODE
CLASS="FUNCTION"
>PQflush</CODE
> again. Repeat until
<CODE
CLASS="FUNCTION"
>PQflush</CODE
> returns 0. (It is necessary to check for
read-ready and drain the input with <CODE
CLASS="FUNCTION"
>PQconsumeInput</CODE
>,
because the server can block trying to send us data, e.g. NOTICE
messages, and won't read our data until we read its.) Once
<CODE
CLASS="FUNCTION"
>PQflush</CODE
> returns 0, wait for the socket to be
read-ready and then read the response as described above.
</P
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="libpq-exec.html"
ACCESSKEY="P"
>Prev</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="index.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="libpq-single-row-mode.html"
ACCESSKEY="N"
>Next</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Command Execution Functions</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="libpq.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Retrieving Query Results Row-By-Row</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>