📄 protocol.sgml
字号:
Sync does not cause a transaction block opened with <command>BEGIN</> to be closed. It is possible to detect this situation since the ReadyForQuery message includes transaction status information. </para> </note> <para> In addition to these fundamental, required operations, there are several optional operations that can be used with extended-query protocol. </para> <para> The Describe message (portal variant) specifies the name of an existing portal (or an empty string for the unnamed portal). The response is a RowDescription message describing the rows that will be returned by executing the portal; or a NoData message if the portal does not contain a query that will return rows; or ErrorResponse if there is no such portal. </para> <para> The Describe message (statement variant) specifies the name of an existing prepared statement (or an empty string for the unnamed prepared statement). The response is a ParameterDescription message describing the parameters needed by the statement, followed by a RowDescription message describing the rows that will be returned when the statement is eventually executed (or a NoData message if the statement will not return rows). ErrorResponse is issued if there is no such prepared statement. Note that since Bind has not yet been issued, the formats to be used for returned columns are not yet known to the backend; the format code fields in the RowDescription message will be zeroes in this case. </para> <tip> <para> In most scenarios the frontend should issue one or the other variant of Describe before issuing Execute, to ensure that it knows how to interpret the results it will get back. </para> </tip> <para> The Close message closes an existing prepared statement or portal and releases resources. It is not an error to issue Close against a nonexistent statement or portal name. The response is normally CloseComplete, but could be ErrorResponse if some difficulty is encountered while releasing resources. Note that closing a prepared statement implicitly closes any open portals that were constructed from that statement. </para> <para> The Flush message does not cause any specific output to be generated, but forces the backend to deliver any data pending in its output buffers. A Flush must be sent after any extended-query command except Sync, if the frontend wishes to examine the results of that command before issuing more commands. Without Flush, messages returned by the backend will be combined into the minimum possible number of packets to minimize network overhead. </para> <note> <para> The simple Query message is approximately equivalent to the series Parse, Bind, portal Describe, Execute, Close, Sync, using the unnamed prepared statement and portal objects and no parameters. One difference is that it will accept multiple SQL statements in the query string, automatically performing the bind/describe/execute sequence for each one in succession. Another difference is that it will not return ParseComplete, BindComplete, CloseComplete, or NoData messages. </para> </note> </sect2> <sect2> <title>Function Call</title> <para> The Function Call sub-protocol allows the client to request a direct call of any function that exists in the database's <structname>pg_proc</structname> system catalog. The client must have execute permission for the function. </para> <note> <para> The Function Call sub-protocol is a legacy feature that is probably best avoided in new code. Similar results can be accomplished by setting up a prepared statement that does <literal>SELECT function($1, ...)</>. The Function Call cycle can then be replaced with Bind/Execute. </para> </note> <para> A Function Call cycle is initiated by the frontend sending a FunctionCall message to the backend. The backend then sends one or more response messages depending on the results of the function call, and finally a ReadyForQuery response message. ReadyForQuery informs the frontend that it may safely send a new query or function call. </para> <para> The possible response messages from the backend are: <variablelist> <varlistentry> <term>ErrorResponse</term> <listitem> <para> An error has occurred. </para> </listitem> </varlistentry> <varlistentry> <term>FunctionCallResponse</term> <listitem> <para> The function call was completed and returned the result given in the message. (Note that the Function Call protocol can only handle a single scalar result, not a row type or set of results.) </para> </listitem> </varlistentry> <varlistentry> <term>ReadyForQuery</term> <listitem> <para> Processing of the function call is complete. ReadyForQuery will always be sent, whether processing terminates successfully or with an error. </para> </listitem> </varlistentry> <varlistentry> <term>NoticeResponse</term> <listitem> <para> A warning message has been issued in relation to the function call. Notices are in addition to other responses, i.e., the backend will continue processing the command. </para> </listitem> </varlistentry> </variablelist> </para> </sect2> <sect2 id="protocol-copy"> <title>COPY Operations</title> <para> The <command>COPY</> command allows high-speed bulk data transfer to or from the server. Copy-in and copy-out operations each switch the connection into a distinct sub-protocol, which lasts until the operation is completed. </para> <para> Copy-in mode (data transfer to the server) is initiated when the backend executes a <command>COPY FROM STDIN</> SQL statement. The backend sends a CopyInResponse message to the frontend. The frontend should then send zero or more CopyData messages, forming a stream of input data. (The message boundaries are not required to have anything to do with row boundaries, although that is often a reasonable choice.) The frontend can terminate the copy-in mode by sending either a CopyDone message (allowing successful termination) or a CopyFail message (which will cause the <command>COPY</> SQL statement to fail with an error). The backend then reverts to the command-processing mode it was in before the <command>COPY</> started, which will be either simple or extended query protocol. It will next send either CommandComplete (if successful) or ErrorResponse (if not). </para> <para> In the event of a backend-detected error during copy-in mode (including receipt of a CopyFail message), the backend will issue an ErrorResponse message. If the <command>COPY</> command was issued via an extended-query message, the backend will now discard frontend messages until a Sync message is received, then it will issue ReadyForQuery and return to normal processing. If the <command>COPY</> command was issued in a simple Query message, the rest of that message is discarded and ReadyForQuery is issued. In either case, any subsequent CopyData, CopyDone, or CopyFail messages issued by the frontend will simply be dropped. </para> <para> The backend will ignore Flush and Sync messages received during copy-in mode. Receipt of any other non-copy message type constitutes an error that will abort the copy-in state as described above. (The exception for Flush and Sync is for the convenience of client libraries that always send Flush or Sync after an Execute message, without checking whether the command to be executed is a <command>COPY FROM STDIN</>.) </para> <para> Copy-out mode (data transfer from the server) is initiated when the backend executes a <command>COPY TO STDOUT</> SQL statement. The backend sends a CopyOutResponse message to the frontend, followed by zero or more CopyData messages (always one per row), followed by CopyDone. The backend then reverts to the command-processing mode it was in before the <command>COPY</> started, and sends CommandComplete. The frontend cannot abort the transfer (except by closing the connection or issuing a Cancel request), but it can discard unwanted CopyData and CopyDone messages. </para> <para> In the event of a backend-detected error during copy-out mode, the backend will issue an ErrorResponse message and revert to normal processing. The frontend should treat receipt of ErrorResponse (or indeed any message type other than CopyData or CopyDone) as terminating the copy-out mode. </para> <para> The CopyInResponse and CopyOutResponse messages include fields that inform the frontend of the number of columns per row and the format codes being used for each column. (As of the present implementation, all columns in a given <command>COPY</> operation will use the same format, but the message design does not assume this.) </para> </sect2> <sect2 id="protocol-async"> <title>Asynchronous Operations</title> <para> There are several cases in which the backend will send messages that are not specifically prompted by the frontend's command stream. Frontends must be prepared to deal with these messages at any time, even when not engaged in a query. At minimum, one should check for these cases before beginning to read a query response. </para> <para> It is possible for NoticeResponse messages to be generated due to outside activity; for example, if the database administrator commands a <quote>fast</> database shutdown, the backend will send a NoticeResponse indicating this fact before closing the connection. Accordingly, frontends should always be prepared to accept and display NoticeResponse messages, even when the connection is nominally idle. </para> <para> ParameterStatus messages will be generated whenever the active value changes for any of the parameters the backend believes the frontend should know about. Most commonly this occurs in response to a <command>SET</> SQL command executed by the frontend, and this case is effectively synchronous — but it is also possible for parameter status changes to occur because the administrator changed a configuration file and then sent the <systemitem>SIGHUP</systemitem> signal to the postmaster. Also, if a <command>SET</command> command is rolled back, an appropriate ParameterStatus message will be generated to report the current effective value. </para> <para> At present there is a hard-wired set of parameters for which ParameterStatus will be generated: they are <literal>server_version</>, <literal>server_encoding</>, <literal>client_encoding</>, <literal>is_superuser</>, <literal>session_authorization</>, <literal>DateStyle</>, <literal>TimeZone</>, <literal>integer_datetimes</>, and <literal>standard_conforming_strings</>. (<literal>server_encoding</>, <literal>TimeZone</>, and <literal>integer_datetimes</> were not reported by releases before 8.0; <literal>standard_conforming_strings</> was not reported by releases before 8.1.) Note that <literal>server_version</>, <literal>server_encoding</> and <literal>integer_datetimes</> are pseudo-parameters that cannot change after startup. This set might change in the future, or even become configurable. Accordingly, a frontend should simply ignore ParameterStatus for parameters that it does not understand or care about. </para> <para> If a frontend issues a <command>LISTEN</command> command, then the backend will send a NotificationResponse message (not to be confused with NoticeResponse!) whenever a <command>NOTIFY</command> command is executed for the same notification name. </para> <note> <para> At present, NotificationResponse can only be sent outside a transaction, and thus it will not occur in the middle of a command-response series, though it may occur just before ReadyForQuery. It is unwise to design frontend logic that assumes that, however. Good practice is to be able to accept NotificationResponse at any point in the protocol. </para> </note> </sect2> <sect2> <title>Cancelling Requests in Progress</title> <para> During the processing of a query, the frontend may request cancellation of the query. The cancel request is not sent directly on the open connection to the backend for reasons of implementation efficiency: we don't want to have the backend constantly checking for new input from the frontend during query processing. Cancel requests should be relatively infrequent, so we make them slightly cumbersome in order to avoid a penalty in the normal case. </para> <para> To issue a cancel request, the frontend opens a new connection to the server and sends a CancelRequest message, rather than the StartupMessage message that would ordinarily be sent across a new connection. The server will process this request and then close the connection. For security reasons, no direct reply is made to the cancel request message. </para> <para> A CancelRequest message will be ignored unless it contains the same key data (PID and secret key) passed to the frontend during connection start-up. If the request matches the PID and secret key for a currently executing backend, the processing of the current query is aborted. (In the existing implementation, this is done by sending a special signal to the backend process that is processing the query.) </para> <para> The cancellation signal may or may not have any effect — for example, if it arrives after the backend has finished processing the query, then it will have no effect. If the cancellation is effective, it results in the current command being terminated early with an error message. </para> <para> The upshot of all this is that for reasons of both security and efficiency, the frontend has no direct way to tell whether a cancel request has succeeded. It must continue to wait for the backend to respond to the query. Issuing a cancel simply improves the odds that the current query will finish soon, and improves the odds that it will fail with an error message instead of succeeding. </para> <para> Since the cancel request is sent across a new connection to the server and not across the regular frontend/backend communication link, it is possible for the cancel request to be issued by any process, not just the frontend whose query is to be canceled. This may have some benefits of flexibility in building multiple-process applications. It also introduces a security risk, in that unauthorized persons might try to cancel queries. The security risk is addressed by requiring a dynamically generated secret key to be supplied in cancel requests. </para> </sect2> <sect2> <title>Termination</title> <para> The normal, graceful termination procedure is that the frontend sends a Terminate message and immediately closes the connection. On receipt of this message, the backend closes the connection and terminates. </para> <para> In rare cases (such as an administrator-commanded database shutdown) the backend may disconnect without any frontend request to do so. In such cases the backend will attempt to send an error or notice message giving the reason for the disconnection before it closes the connection. </para> <para> Other termination scenarios arise from various failure cases, such as core dump at one end or the other, loss of the communications link, loss of message-boundary synchronization, etc. If either frontend or backend sees an unexpected closure of the connection, it should clean up and terminate. The frontend has the option of launching a new backend
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -