diff options
Diffstat (limited to 'doc/src/sgml/libpq.sgml')
-rw-r--r-- | doc/src/sgml/libpq.sgml | 507 |
1 files changed, 467 insertions, 40 deletions
diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml index a2bbf33d029..d3e87056f2c 100644 --- a/doc/src/sgml/libpq.sgml +++ b/doc/src/sgml/libpq.sgml @@ -265,7 +265,7 @@ PGconn *PQsetdb(char *pghost, <varlistentry id="libpq-PQconnectStartParams"> <term><function>PQconnectStartParams</function><indexterm><primary>PQconnectStartParams</primary></indexterm></term> <term><function>PQconnectStart</function><indexterm><primary>PQconnectStart</primary></indexterm></term> - <term><function>PQconnectPoll</function><indexterm><primary>PQconnectPoll</primary></indexterm></term> + <term id="libpq-PQconnectPoll"><function>PQconnectPoll</function><indexterm><primary>PQconnectPoll</primary></indexterm></term> <listitem> <para> <indexterm><primary>nonblocking connection</primary></indexterm> @@ -2622,17 +2622,19 @@ int PQserverVersion(const PGconn *conn); </varlistentry> <varlistentry id="libpq-PQerrorMessage"> - <term><function>PQerrorMessage</function><indexterm><primary>PQerrorMessage</primary></indexterm></term> + <term> + <function>PQerrorMessage</function><indexterm><primary>PQerrorMessage</primary></indexterm> + <indexterm><primary>error message</primary><secondary>in <structname>PGconn</structname></secondary></indexterm> + </term> <listitem> <para> - <indexterm><primary>error message</primary></indexterm> Returns the error message - most recently generated by an operation on the connection. + Returns the error message most recently generated by + an operation on the connection. <synopsis> char *PQerrorMessage(const PGconn *conn); </synopsis> - </para> <para> @@ -5287,7 +5289,7 @@ int PQisBusy(PGconn *conn); <xref linkend="libpq-PQsendQuery"/>/<xref linkend="libpq-PQgetResult"/> can also attempt to cancel a command that is still being processed by the server; see <xref linkend="libpq-cancel"/>. But regardless of - the return value of <xref linkend="libpq-PQcancel"/>, the application + the return value of <xref linkend="libpq-PQcancelBlocking"/>, the application must continue with the normal result-reading sequence using <xref linkend="libpq-PQgetResult"/>. A successful cancellation will simply cause the command to terminate sooner than it would have @@ -6030,14 +6032,429 @@ int PQsetSingleRowMode(PGconn *conn); <title>Canceling Queries in Progress</title> <indexterm zone="libpq-cancel"> - <primary>canceling</primary> - <secondary>SQL command</secondary> + <primary>canceling SQL queries</primary> + </indexterm> + <indexterm zone="libpq-cancel"> + <primary>query cancellation</primary> </indexterm> - <para> - A client application can request cancellation of a command that is - still being processed by the server, using the functions described in - this section. + <sect2 id="libpq-cancel-functions"> + <title>Functions for Sending Cancel Requests</title> + <variablelist> + <varlistentry id="libpq-PQcancelCreate"> + <term><function>PQcancelCreate</function><indexterm><primary>PQcancelCreate</primary></indexterm></term> + + <listitem> + <para> + Prepares a connection over which a cancel request can be sent. +<synopsis> +PGcancelConn *PQcancelCreate(PGconn *conn); +</synopsis> + </para> + + <para> + <xref linkend="libpq-PQcancelCreate"/> creates a + <structname>PGcancelConn</structname><indexterm><primary>PGcancelConn</primary></indexterm> + object, but it won't instantly start sending a cancel request over this + connection. A cancel request can be sent over this connection in a + blocking manner using <xref linkend="libpq-PQcancelBlocking"/> and in a + non-blocking manner using <xref linkend="libpq-PQcancelStart"/>. + The return value can be passed to <xref linkend="libpq-PQcancelStatus"/> + to check if the <structname>PGcancelConn</structname> object was + created successfully. The <structname>PGcancelConn</structname> object + is an opaque structure that is not meant to be accessed directly by the + application. This <structname>PGcancelConn</structname> object can be + used to cancel the query that's running on the original connection in a + thread-safe way. + </para> + + <para> + Many connection parameters of the original client will be reused when + setting up the connection for the cancel request. Importantly, if the + original connection requires encryption of the connection and/or + verification of the target host (using <literal>sslmode</literal> or + <literal>gssencmode</literal>), then the connection for the cancel + request is made with these same requirements. Any connection options + that are only used during authentication or after authentication of the + client are ignored though, because cancellation requests do not require + authentication and the connection is closed right after the cancellation + request is submitted. + </para> + + <para> + Note that when <function>PQcancelCreate</function> returns a non-null + pointer, you must call <xref linkend="libpq-PQcancelFinish"/> when you + are finished with it, in order to dispose of the structure and any + associated memory blocks. This must be done even if the cancel request + failed or was abandoned. + </para> + </listitem> + </varlistentry> + + <varlistentry id="libpq-PQcancelBlocking"> + <term><function>PQcancelBlocking</function><indexterm><primary>PQcancelBlocking</primary></indexterm></term> + + <listitem> + <para> + Requests that the server abandons processing of the current command + in a blocking manner. +<synopsis> +int PQcancelBlocking(PGcancelConn *cancelConn); +</synopsis> + </para> + + <para> + The request is made over the given <structname>PGcancelConn</structname>, + which needs to be created with <xref linkend="libpq-PQcancelCreate"/>. + The return value of <xref linkend="libpq-PQcancelBlocking"/> + is 1 if the cancel request was successfully + dispatched and 0 if not. If it was unsuccessful, the error message can be + retrieved using <xref linkend="libpq-PQcancelErrorMessage"/>. + </para> + + <para> + Successful dispatch of the cancellation is no guarantee that the request + will have any effect, however. If the cancellation is effective, the + command being canceled will terminate early and return an error result. + If the cancellation fails (say, because the server was already done + processing the command), then there will be no visible result at all. + </para> + + </listitem> + </varlistentry> + + <varlistentry id="libpq-PQcancelStart"> + <term><function>PQcancelStart</function><indexterm><primary>PQcancelStart</primary></indexterm></term> + <term><function>PQcancelPoll</function><indexterm><primary>PQcancelPoll</primary></indexterm></term> + + <listitem> + <para> + Requests that the server abandons processing of the current command + in a non-blocking manner. +<synopsis> +int PQcancelStart(PGcancelConn *cancelConn); + +PostgresPollingStatusType PQcancelPoll(PGcancelConn *cancelConn); +</synopsis> + </para> + + <para> + The request is made over the given <structname>PGcancelConn</structname>, + which needs to be created with <xref linkend="libpq-PQcancelCreate"/>. + The return value of <xref linkend="libpq-PQcancelStart"/> + is 1 if the cancellation request could be started and 0 if not. + If it was unsuccessful, the error message can be + retrieved using <xref linkend="libpq-PQcancelErrorMessage"/>. + </para> + + <para> + If <function>PQcancelStart</function> succeeds, the next stage + is to poll <application>libpq</application> so that it can proceed with + the cancel connection sequence. + Use <xref linkend="libpq-PQcancelSocket"/> to obtain the descriptor of the + socket underlying the database connection. + (Caution: do not assume that the socket remains the same + across <function>PQcancelPoll</function> calls.) + Loop thus: If <function>PQcancelPoll(cancelConn)</function> last returned + <symbol>PGRES_POLLING_READING</symbol>, wait until the socket is ready to + read (as indicated by <function>select()</function>, + <function>poll()</function>, or similar system function). + Then call <function>PQcancelPoll(cancelConn)</function> again. + Conversely, if <function>PQcancelPoll(cancelConn)</function> last returned + <symbol>PGRES_POLLING_WRITING</symbol>, wait until the socket is ready + to write, then call <function>PQcancelPoll(cancelConn)</function> again. + On the first iteration, i.e., if you have yet to call + <function>PQcancelPoll(cancelConn)</function>, behave as if it last returned + <symbol>PGRES_POLLING_WRITING</symbol>. Continue this loop until + <function>PQcancelPoll(cancelConn)</function> returns + <symbol>PGRES_POLLING_FAILED</symbol>, indicating the connection procedure + has failed, or <symbol>PGRES_POLLING_OK</symbol>, indicating cancel + request was successfully dispatched. + </para> + + <para> + Successful dispatch of the cancellation is no guarantee that the request + will have any effect, however. If the cancellation is effective, the + command being canceled will terminate early and return an error result. + If the cancellation fails (say, because the server was already done + processing the command), then there will be no visible result at all. + </para> + + <para> + At any time during connection, the status of the connection can be + checked by calling <xref linkend="libpq-PQcancelStatus"/>. + If this call returns <symbol>CONNECTION_BAD</symbol>, then + the cancel procedure has failed; if the call returns + <function>CONNECTION_OK</function>, then cancel request was + successfully dispatched. + Both of these states are equally detectable from the return value of + <function>PQcancelPoll</function>, described above. + Other states might also occur during (and only during) an asynchronous + connection procedure. + These indicate the current stage of the connection procedure and might + be useful to provide feedback to the user for example. + These statuses are: + + <variablelist> + <varlistentry id="libpq-cancel-connection-allocated"> + <term><symbol>CONNECTION_ALLOCATED</symbol></term> + <listitem> + <para> + Waiting for a call to <xref linkend="libpq-PQcancelStart"/> or + <xref linkend="libpq-PQcancelBlocking"/>, to actually open the + socket. This is the connection state right after + calling <xref linkend="libpq-PQcancelCreate"/> + or <xref linkend="libpq-PQcancelReset"/>. No connection to the + server has been initiated yet at this point. To actually start + sending the cancel request use <xref linkend="libpq-PQcancelStart"/> or + <xref linkend="libpq-PQcancelBlocking"/>. + </para> + </listitem> + </varlistentry> + + <varlistentry id="libpq-cancel-connection-started"> + <term><symbol>CONNECTION_STARTED</symbol></term> + <listitem> + <para> + Waiting for connection to be made. + </para> + </listitem> + </varlistentry> + + <varlistentry id="libpq-cancel-connection-made"> + <term><symbol>CONNECTION_MADE</symbol></term> + <listitem> + <para> + Connection OK; waiting to send. + </para> + </listitem> + </varlistentry> + + <varlistentry id="libpq-cancel-connection-awaiting-response"> + <term><symbol>CONNECTION_AWAITING_RESPONSE</symbol></term> + <listitem> + <para> + Waiting for a response from the server. + </para> + </listitem> + </varlistentry> + + <varlistentry id="libpq-cancel-connection-ssl-startup"> + <term><symbol>CONNECTION_SSL_STARTUP</symbol></term> + <listitem> + <para> + Negotiating SSL encryption. + </para> + </listitem> + </varlistentry> + + <varlistentry id="libpq-cancel-connection-gss-startup"> + <term><symbol>CONNECTION_GSS_STARTUP</symbol></term> + <listitem> + <para> + Negotiating GSS encryption. + </para> + </listitem> + </varlistentry> + </variablelist> + + Note that, although these constants will remain (in order to maintain + compatibility), an application should never rely upon these occurring in a + particular order, or at all, or on the status always being one of these + documented values. An application might do something like this: +<programlisting> +switch(PQcancelStatus(conn)) +{ + case CONNECTION_STARTED: + feedback = "Connecting..."; + break; + + case CONNECTION_MADE: + feedback = "Connected to server..."; + break; +. +. +. + default: + feedback = "Connecting..."; +} +</programlisting> + </para> + + <para> + The <literal>connect_timeout</literal> connection parameter is ignored + when using <function>PQcancelPoll</function>; it is the application's + responsibility to decide whether an excessive amount of time has elapsed. + Otherwise, <function>PQcancelStart</function> followed by a + <function>PQcancelPoll</function> loop is equivalent to + <xref linkend="libpq-PQcancelBlocking"/>. + </para> + + </listitem> + </varlistentry> + + <varlistentry id="libpq-PQcancelStatus"> + <term><function>PQcancelStatus</function><indexterm><primary>PQcancelStatus</primary></indexterm></term> + + <listitem> + <para> + Returns the status of the cancel connection. +<synopsis> +ConnStatusType PQcancelStatus(const PGcancelConn *cancelConn); +</synopsis> + </para> + + <para> + The status can be one of a number of values. However, only three of + these are seen outside of an asynchronous cancel procedure: + <literal>CONNECTION_ALLOCATED</literal>, + <literal>CONNECTION_OK</literal> and + <literal>CONNECTION_BAD</literal>. The initial state of a + <function>PGcancelConn</function> that's successfully created using + <xref linkend="libpq-PQcancelCreate"/> is <literal>CONNECTION_ALLOCATED</literal>. + A cancel request that was successfully dispatched + has the status <literal>CONNECTION_OK</literal>. A failed + cancel attempt is signaled by status + <literal>CONNECTION_BAD</literal>. An OK status will + remain so until <xref linkend="libpq-PQcancelFinish"/> or + <xref linkend="libpq-PQcancelReset"/> is called. + </para> + + <para> + See the entry for <xref linkend="libpq-PQcancelStart"/> with regards + to other status codes that might be returned. + </para> + + <para> + Successful dispatch of the cancellation is no guarantee that the request + will have any effect, however. If the cancellation is effective, the + command being canceled will terminate early and return an error result. + If the cancellation fails (say, because the server was already done + processing the command), then there will be no visible result at all. + </para> + + </listitem> + </varlistentry> + + <varlistentry id="libpq-PQcancelSocket"> + <term><function>PQcancelSocket</function><indexterm><primary>PQcancelSocket</primary></indexterm></term> + + <listitem> + <para> + Obtains the file descriptor number of the cancel connection socket to + the server. +<synopsis> +int PQcancelSocket(const PGcancelConn *cancelConn); +</synopsis> + </para> + + <para> + A valid descriptor will be greater than or equal to 0; + a result of -1 indicates that no server connection is currently open. + This might change as a result of calling any of the functions + in this section on the <structname>PQcancelConn</structname> + (except for <xref linkend="libpq-PQcancelErrorMessage"/> and + <function>PQcancelSocket</function> itself). + </para> + </listitem> + </varlistentry> + + <varlistentry id="libpq-PQcancelErrorMessage"> + <term> + <function>PQcancelErrorMessage</function><indexterm><primary>PQcancelErrorMessage</primary></indexterm> + <indexterm><primary>error message</primary><secondary>in <structname>PGcancelConn</structname></secondary></indexterm> + </term> + + <listitem> + <para> + Returns the error message most recently generated by an + operation on the cancel connection. +<synopsis> +char *PQcancelErrorMessage(const PGcancelConn *cancelconn); +</synopsis> + </para> + + <para> + Nearly all <application>libpq</application> functions that take a + <structname>PGcancelConn</structname> will set a message for + <xref linkend="libpq-PQcancelErrorMessage"/> if they fail. + Note that by <application>libpq</application> convention, + a nonempty <xref linkend="libpq-PQcancelErrorMessage"/> result + can consist of multiple lines, and will include a trailing newline. + The caller should not free the result directly. + It will be freed when the associated + <structname>PGcancelConn</structname> handle is passed to + <xref linkend="libpq-PQcancelFinish"/>. The result string should not be + expected to remain the same across operations on the + <literal>PGcancelConn</literal> structure. + </para> + </listitem> + </varlistentry> + + <varlistentry id="libpq-PQcancelFinish"> + <term><function>PQcancelFinish</function><indexterm><primary>PQcancelFinish</primary></indexterm></term> + <listitem> + <para> + Closes the cancel connection (if it did not finish sending the + cancel request yet). Also frees memory used by the + <structname>PGcancelConn</structname> object. +<synopsis> +void PQcancelFinish(PGcancelConn *cancelConn); +</synopsis> + </para> + + <para> + Note that even if the cancel attempt fails (as + indicated by <xref linkend="libpq-PQcancelStatus"/>), the + application should call <xref linkend="libpq-PQcancelFinish"/> + to free the memory used by the <structname>PGcancelConn</structname> + object. + The <structname>PGcancelConn</structname> pointer must not be used + again after <xref linkend="libpq-PQcancelFinish"/> has been called. + </para> + </listitem> + </varlistentry> + + <varlistentry id="libpq-PQcancelReset"> + <term><function>PQcancelReset</function><indexterm><primary>PQcancelReset</primary></indexterm></term> + <listitem> + <para> + Resets the <symbol>PGcancelConn</symbol> so it can be reused for a new + cancel connection. +<synopsis> +void PQcancelReset(PGcancelConn *cancelConn); +</synopsis> + </para> + + <para> + If the <symbol>PGcancelConn</symbol> is currently used to send a cancel + request, then this connection is closed. It will then prepare the + <symbol>PGcancelConn</symbol> object such that it can be used to send a + new cancel request. + </para> + + <para> + This can be used to create one <structname>PGcancelConn</structname> + for a <structname>PGconn</structname> and reuse it multiple times + throughout the lifetime of the original <structname>PGconn</structname>. + </para> + </listitem> + </varlistentry> + </variablelist> + </sect2> + + <sect2 id="libpq-cancel-deprecated"> + <title>Obsolete Functions for Sending Cancel Requests</title> + + <para> + These functions represent older methods of sending cancel requests. + Although they still work, they are deprecated due to not sending the cancel + requests in an encrypted manner, even when the original connection + specified <literal>sslmode</literal> or <literal>gssencmode</literal> to + require encryption. Thus these older methods are heavily discouraged from + being used in new code, and it is recommended to change existing code to + use the new functions instead. + </para> <variablelist> <varlistentry id="libpq-PQgetCancel"> @@ -6046,7 +6463,7 @@ int PQsetSingleRowMode(PGconn *conn); <listitem> <para> Creates a data structure containing the information needed to cancel - a command issued through a particular database connection. + a command using <xref linkend="libpq-PQcancel"/>. <synopsis> PGcancel *PQgetCancel(PGconn *conn); </synopsis> @@ -6054,10 +6471,11 @@ PGcancel *PQgetCancel(PGconn *conn); <para> <xref linkend="libpq-PQgetCancel"/> creates a - <structname>PGcancel</structname><indexterm><primary>PGcancel</primary></indexterm> object - given a <structname>PGconn</structname> connection object. It will return - <symbol>NULL</symbol> if the given <parameter>conn</parameter> is <symbol>NULL</symbol> or an invalid - connection. The <structname>PGcancel</structname> object is an opaque + <structname>PGcancel</structname><indexterm><primary>PGcancel</primary></indexterm> + object given a <structname>PGconn</structname> connection object. + It will return <symbol>NULL</symbol> if the given <parameter>conn</parameter> + is <symbol>NULL</symbol> or an invalid connection. + The <structname>PGcancel</structname> object is an opaque structure that is not meant to be accessed directly by the application; it can only be passed to <xref linkend="libpq-PQcancel"/> or <xref linkend="libpq-PQfreeCancel"/>. @@ -6088,36 +6506,38 @@ void PQfreeCancel(PGcancel *cancel); <listitem> <para> - Requests that the server abandon processing of the current command. + <xref linkend="libpq-PQcancel"/> is a deprecated and insecure + variant of <xref linkend="libpq-PQcancelBlocking"/>, but one that can be + used safely from within a signal handler. <synopsis> int PQcancel(PGcancel *cancel, char *errbuf, int errbufsize); </synopsis> </para> <para> - The return value is 1 if the cancel request was successfully - dispatched and 0 if not. If not, <parameter>errbuf</parameter> is filled - with an explanatory error message. <parameter>errbuf</parameter> - must be a char array of size <parameter>errbufsize</parameter> (the - recommended size is 256 bytes). + <xref linkend="libpq-PQcancel"/> only exists because of backwards + compatibility reasons. <xref linkend="libpq-PQcancelBlocking"/> should be + used instead. The only benefit that <xref linkend="libpq-PQcancel"/> has + is that it can be safely invoked from a signal handler, if the + <parameter>errbuf</parameter> is a local variable in the signal handler. + However, this is generally not considered a big enough benefit to be + worth the security issues that this function has. </para> <para> - Successful dispatch is no guarantee that the request will have - any effect, however. If the cancellation is effective, the current - command will terminate early and return an error result. If the - cancellation fails (say, because the server was already done - processing the command), then there will be no visible result at - all. + The <structname>PGcancel</structname> object is read-only as far as + <xref linkend="libpq-PQcancel"/> is concerned, so it can also be invoked + from a thread that is separate from the one manipulating the + <structname>PGconn</structname> object. </para> <para> - <xref linkend="libpq-PQcancel"/> can safely be invoked from a signal - handler, if the <parameter>errbuf</parameter> is a local variable in the - signal handler. The <structname>PGcancel</structname> object is read-only - as far as <xref linkend="libpq-PQcancel"/> is concerned, so it can - also be invoked from a thread that is separate from the one - manipulating the <structname>PGconn</structname> object. + The return value of <xref linkend="libpq-PQcancel"/> is 1 if the + cancel request was successfully dispatched and 0 if not. + If not, <parameter>errbuf</parameter> is filled with an explanatory + error message. + <parameter>errbuf</parameter> must be a char array of size + <parameter>errbufsize</parameter> (the recommended size is 256 bytes). </para> </listitem> </varlistentry> @@ -6129,14 +6549,22 @@ int PQcancel(PGcancel *cancel, char *errbuf, int errbufsize); <listitem> <para> - <xref linkend="libpq-PQrequestCancel"/> is a deprecated variant of - <xref linkend="libpq-PQcancel"/>. + <xref linkend="libpq-PQrequestCancel"/> is a deprecated and insecure + variant of <xref linkend="libpq-PQcancelBlocking"/>. <synopsis> int PQrequestCancel(PGconn *conn); </synopsis> </para> <para> + <xref linkend="libpq-PQrequestCancel"/> only exists because of backwards + compatibility reasons. <xref linkend="libpq-PQcancelBlocking"/> should be + used instead. There is no benefit to using + <xref linkend="libpq-PQrequestCancel"/> over + <xref linkend="libpq-PQcancelBlocking"/>. + </para> + + <para> Requests that the server abandon processing of the current command. It operates directly on the <structname>PGconn</structname> object, and in case of failure stores the @@ -6150,8 +6578,7 @@ int PQrequestCancel(PGconn *conn); </listitem> </varlistentry> </variablelist> - </para> - + </sect2> </sect1> <sect1 id="libpq-fastpath"> @@ -9362,7 +9789,7 @@ int PQisthreadsafe(); The deprecated functions <xref linkend="libpq-PQrequestCancel"/> and <xref linkend="libpq-PQoidStatus"/> are not thread-safe and should not be used in multithread programs. <xref linkend="libpq-PQrequestCancel"/> - can be replaced by <xref linkend="libpq-PQcancel"/>. + can be replaced by <xref linkend="libpq-PQcancelBlocking"/>. <xref linkend="libpq-PQoidStatus"/> can be replaced by <xref linkend="libpq-PQoidValue"/>. </para> |