From 6eb9c5a5657d1fe77b55cc261450f3538d35a94d Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 4 May 2024 14:19:15 +0200 Subject: Adding upstream version 13.4. Signed-off-by: Daniel Baumann --- doc/src/sgml/html/libpq-async.html | 331 +++++++++++++++++++++++++++++++++++++ 1 file changed, 331 insertions(+) create mode 100644 doc/src/sgml/html/libpq-async.html (limited to 'doc/src/sgml/html/libpq-async.html') diff --git a/doc/src/sgml/html/libpq-async.html b/doc/src/sgml/html/libpq-async.html new file mode 100644 index 0000000..b3c6544 --- /dev/null +++ b/doc/src/sgml/html/libpq-async.html @@ -0,0 +1,331 @@ + +33.4. Asynchronous Command Processing

33.4. Asynchronous Command Processing

+ The PQexec function is adequate for submitting + commands in normal, synchronous applications. It has a few + deficiencies, however, that can be of importance to some users: + +

  • + PQexec 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. +

  • + 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.) +

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

  • + PQexec always collects the command's entire result, + buffering it in a single PGresult. While + this simplifies error-handling logic for the application, it can be + impractical for results containing many rows. +

+

+ Applications that do not like these limitations can instead use the + underlying functions that PQexec is built from: + PQsendQuery and PQgetResult. + There are also + PQsendQueryParams, + PQsendPrepare, + PQsendQueryPrepared, + PQsendDescribePrepared, and + PQsendDescribePortal, + which can be used with PQgetResult to duplicate + the functionality of + PQexecParams, + PQprepare, + PQexecPrepared, + PQdescribePrepared, and + PQdescribePortal + respectively. + +

PQsendQuery

+ 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 PQerrorMessage to get more + information about the failure). +

+int PQsendQuery(PGconn *conn, const char *command);
+

+ + After successfully calling PQsendQuery, call + PQgetResult one or more times to obtain the + results. PQsendQuery cannot be called again + (on the same connection) until PQgetResult + has returned a null pointer, indicating that the command is done. +

PQsendQueryParams

+ Submits a command and separate parameters to the server without + waiting for the result(s). +

+int PQsendQueryParams(PGconn *conn,
+                      const char *command,
+                      int nParams,
+                      const Oid *paramTypes,
+                      const char * const *paramValues,
+                      const int *paramLengths,
+                      const int *paramFormats,
+                      int resultFormat);
+

+ + This is equivalent to PQsendQuery except that + query parameters can be specified separately from the query string. + The function's parameters are handled identically to + PQexecParams. Like + PQexecParams, it will not work on 2.0-protocol + connections, and it allows only one command in the query string. +

PQsendPrepare

+ Sends a request to create a prepared statement with the given + parameters, without waiting for completion. +

+int PQsendPrepare(PGconn *conn,
+                  const char *stmtName,
+                  const char *query,
+                  int nParams,
+                  const Oid *paramTypes);
+

+ + This is an asynchronous version of PQprepare: it + returns 1 if it was able to dispatch the request, and 0 if not. + After a successful call, call PQgetResult to + determine whether the server successfully created the prepared + statement. The function's parameters are handled identically to + PQprepare. Like + PQprepare, it will not work on 2.0-protocol + connections. +

PQsendQueryPrepared

+ Sends a request to execute a prepared statement with given + parameters, without waiting for the result(s). +

+int PQsendQueryPrepared(PGconn *conn,
+                        const char *stmtName,
+                        int nParams,
+                        const char * const *paramValues,
+                        const int *paramLengths,
+                        const int *paramFormats,
+                        int resultFormat);
+

+ + This is similar to PQsendQueryParams, 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 + PQexecPrepared. Like + PQexecPrepared, it will not work on + 2.0-protocol connections. +

PQsendDescribePrepared

+ Submits a request to obtain information about the specified + prepared statement, without waiting for completion. +

+int PQsendDescribePrepared(PGconn *conn, const char *stmtName);
+

+ + This is an asynchronous version of PQdescribePrepared: + it returns 1 if it was able to dispatch the request, and 0 if not. + After a successful call, call PQgetResult to + obtain the results. The function's parameters are handled + identically to PQdescribePrepared. Like + PQdescribePrepared, it will not work on + 2.0-protocol connections. +

PQsendDescribePortal

+ Submits a request to obtain information about the specified + portal, without waiting for completion. +

+int PQsendDescribePortal(PGconn *conn, const char *portalName);
+

+ + This is an asynchronous version of PQdescribePortal: + it returns 1 if it was able to dispatch the request, and 0 if not. + After a successful call, call PQgetResult to + obtain the results. The function's parameters are handled + identically to PQdescribePortal. Like + PQdescribePortal, it will not work on + 2.0-protocol connections. +

PQgetResult

+ Waits for the next result from a prior + PQsendQuery, + PQsendQueryParams, + PQsendPrepare, + PQsendQueryPrepared, + PQsendDescribePrepared, or + PQsendDescribePortal + call, and returns it. + A null pointer is returned when the command is complete and there + will be no more results. +

+PGresult *PQgetResult(PGconn *conn);
+

+

+ PQgetResult must be called repeatedly until + it returns a null pointer, indicating that the command is done. + (If called when no command is active, + PQgetResult will just return a null pointer + 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 command is + active and the necessary response data has not yet been read by + PQconsumeInput + . +

Note

+ Even when PQresultStatus indicates a fatal + error, PQgetResult should be called until it + returns a null pointer, to allow libpq to + process the error information completely. +

+

+ Using PQsendQuery and + PQgetResult solves one of + PQexec's problems: If a command 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 client can be handling the results of one + command while the server is still working on later queries in the same + command string.) +

+ Another frequently-desired feature that can be obtained with + PQsendQuery and PQgetResult + is retrieving large query results a row at a time. This is discussed + in Section 33.5. +

+ By itself, calling PQgetResult + will still cause the client to block until the server completes the + next SQL command. This can be avoided by proper + use of two more functions: + +

PQconsumeInput +

+ If input is available from the server, 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 can be + consulted). Note that the result does not say whether any input + data was actually collected. After calling + PQconsumeInput + , the application can check + PQisBusy and/or + PQnotifies to see if their state has changed. +

+ PQconsumeInput + 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 select() + 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 command 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 server; therefore PQconsumeInput + + must be invoked first, or the busy state will never end. +

+

+ A typical application using these functions will have a main loop that + uses select() or poll() 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 + select() means 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 Section 33.8). +

+ A client that uses + PQsendQuery/PQgetResult + can also attempt to cancel a command that is still being processed + by the server; see Section 33.6. But regardless of + the return value of PQcancel, the application + must continue with the normal result-reading sequence using + PQgetResult. A successful cancellation will + simply cause the command to terminate sooner than it would have + otherwise. +

+ 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 COPY IN, + however.) To prevent this possibility and achieve completely + nonblocking database operation, the following additional functions + can be used. + +

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 1, or blocking if + arg is 0. Returns 0 if OK, -1 if error. +

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

+ Note that PQexec does not honor nonblocking + mode; if it is called, it will act in blocking fashion anyway. +

PQisnonblocking

+ Returns the blocking status of the database connection. +

+int PQisnonblocking(const PGconn *conn);
+

+

+ Returns 1 if the connection is set to nonblocking mode and 0 if + blocking. +

PQflush

+ 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). +

+int PQflush(PGconn *conn);
+

+

+

+ After sending any command or data on a nonblocking connection, call + PQflush. If it returns 1, wait for the socket + to become read- or write-ready. If it becomes write-ready, call + PQflush again. If it becomes read-ready, call + PQconsumeInput + , then call + PQflush again. Repeat until + PQflush returns 0. (It is necessary to check for + read-ready and drain the input with PQconsumeInput + , + 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 + PQflush returns 0, wait for the socket to be + read-ready and then read the response as described above. +

\ No newline at end of file -- cgit v1.2.3