📄 protocol.sgml
字号:
</para> </listitem> </varlistentry> <varlistentry> <term>ErrorResponse</term> <listitem> <para> Start-up failed. The connection is closed after sending this message. </para> </listitem> </varlistentry> <varlistentry> <term>NoticeResponse</term> <listitem> <para> A warning message has been issued. The frontend should display the message but continue listening for ReadyForQuery or ErrorResponse. </para> </listitem> </varlistentry> </variablelist> </para> <para> The ReadyForQuery message is the same one that the backend will issue after each command cycle. Depending on the coding needs of the frontend, it is reasonable to consider ReadyForQuery as starting a command cycle, or to consider ReadyForQuery as ending the start-up phase and each subsequent command cycle. </para> </sect2> <sect2> <title>Simple Query</title> <para> A simple query cycle is initiated by the frontend sending a Query message to the backend. The message includes an SQL command (or commands) expressed as a text string. The backend then sends one or more response messages depending on the contents of the query command string, and finally a ReadyForQuery response message. ReadyForQuery informs the frontend that it may safely send a new command. (It is not actually necessary for the frontend to wait for ReadyForQuery before issuing another command, but the frontend must then take responsibility for figuring out what happens if the earlier command fails and already-issued later commands succeed.) </para> <para> The possible response messages from the backend are: <variablelist> <varlistentry> <term>CommandComplete</term> <listitem> <para> An SQL command completed normally. </para> </listitem> </varlistentry> <varlistentry> <term>CopyInResponse</term> <listitem> <para> The backend is ready to copy data from the frontend to a table; see <xref linkend="protocol-copy">. </para> </listitem> </varlistentry> <varlistentry> <term>CopyOutResponse</term> <listitem> <para> The backend is ready to copy data from a table to the frontend; see <xref linkend="protocol-copy">. </para> </listitem> </varlistentry> <varlistentry> <term>RowDescription</term> <listitem> <para> Indicates that rows are about to be returned in response to a <command>SELECT</command>, <command>FETCH</command>, etc query. The contents of this message describe the column layout of the rows. This will be followed by a DataRow message for each row being returned to the frontend. </para> </listitem> </varlistentry> <varlistentry> <term>DataRow</term> <listitem> <para> One of the set of rows returned by a <command>SELECT</command>, <command>FETCH</command>, etc query. </para> </listitem> </varlistentry> <varlistentry> <term>EmptyQueryResponse</term> <listitem> <para> An empty query string was recognized. </para> </listitem> </varlistentry> <varlistentry> <term>ErrorResponse</term> <listitem> <para> An error has occurred. </para> </listitem> </varlistentry> <varlistentry> <term>ReadyForQuery</term> <listitem> <para> Processing of the query string is complete. A separate message is sent to indicate this because the query string may contain multiple SQL commands. (CommandComplete marks the end of processing one SQL command, not the whole string.) 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 query. Notices are in addition to other responses, i.e., the backend will continue processing the command. </para> </listitem> </varlistentry> </variablelist> </para> <para> The response to a <command>SELECT</> query (or other queries that return row sets, such as <command>EXPLAIN</> or <command>SHOW</>) normally consists of RowDescription, zero or more DataRow messages, and then CommandComplete. <command>COPY</> to or from the frontend invokes special protocol as described in <xref linkend="protocol-copy">. All other query types normally produce only a CommandComplete message. </para> <para> Since a query string could contain several queries (separated by semicolons), there might be several such response sequences before the backend finishes processing the query string. ReadyForQuery is issued when the entire string has been processed and the backend is ready to accept a new query string. </para> <para> If a completely empty (no contents other than whitespace) query string is received, the response is EmptyQueryResponse followed by ReadyForQuery. </para> <para> In the event of an error, ErrorResponse is issued followed by ReadyForQuery. All further processing of the query string is aborted by ErrorResponse (even if more queries remained in it). Note that this may occur partway through the sequence of messages generated by an individual query. </para> <para> In simple Query mode, the format of retrieved values is always text, except when the given command is a <command>FETCH</> from a cursor declared with the <literal>BINARY</> option. In that case, the retrieved values are in binary format. The format codes given in the RowDescription message tell which format is being used. </para> <para> A frontend must be prepared to accept ErrorResponse and NoticeResponse messages whenever it is expecting any other type of message. See also <xref linkend="protocol-async"> concerning messages that the backend may generate due to outside events. </para> <para> Recommended practice is to code frontends in a state-machine style that will accept any message type at any time that it could make sense, rather than wiring in assumptions about the exact sequence of messages. </para> </sect2> <sect2> <title>Extended Query</title> <para> The extended query protocol breaks down the above-described simple query protocol into multiple steps. The results of preparatory steps can be re-used multiple times for improved efficiency. Furthermore, additional features are available, such as the possibility of supplying data values as separate parameters instead of having to insert them directly into a query string. </para> <para> In the extended protocol, the frontend first sends a Parse message, which contains a textual query string, optionally some information about data types of parameter placeholders, and the name of a destination prepared-statement object (an empty string selects the unnamed prepared statement). The response is either ParseComplete or ErrorResponse. Parameter data types may be specified by OID; if not given, the parser attempts to infer the data types in the same way as it would do for untyped literal string constants. </para> <note> <para> A parameter data type can be left unspecified by setting it to zero, or by making the array of parameter type OIDs shorter than the number of parameter symbols (<literal>$</><replaceable>n</>) used in the query string. Another special case is that a parameter's type can be specified as <type>void</> (that is, the OID of the <type>void</> pseudotype). This is meant to allow parameter symbols to be used for function parameters that are actually OUT parameters. Ordinarily there is no context in which a <type>void</> parameter could be used, but if such a parameter symbol appears in a function's parameter list, it is effectively ignored. For example, a function call such as <literal>foo($1,$2,$3,$4)</> could match a function with two IN and two OUT arguments, if <literal>$3</> and <literal>$4</> are specified as having type <type>void</>. </para> </note> <note> <para> The query string contained in a Parse message cannot include more than one SQL statement; else a syntax error is reported. This restriction does not exist in the simple-query protocol, but it does exist in the extended protocol, because allowing prepared statements or portals to contain multiple commands would complicate the protocol unduly. </para> </note> <para> If successfully created, a named prepared-statement object lasts till the end of the current session, unless explicitly destroyed. An unnamed prepared statement lasts only until the next Parse statement specifying the unnamed statement as destination is issued. (Note that a simple Query message also destroys the unnamed statement.) Named prepared statements must be explicitly closed before they can be redefined by a Parse message, but this is not required for the unnamed statement. Named prepared statements can also be created and accessed at the SQL command level, using <command>PREPARE</> and <command>EXECUTE</>. </para> <para> Once a prepared statement exists, it can be readied for execution using a Bind message. The Bind message gives the name of the source prepared statement (empty string denotes the unnamed prepared statement), the name of the destination portal (empty string denotes the unnamed portal), and the values to use for any parameter placeholders present in the prepared statement. The supplied parameter set must match those needed by the prepared statement. (If you declared any <type>void</> parameters in the Parse message, pass NULL values for them in the Bind message.) Bind also specifies the format to use for any data returned by the query; the format can be specified overall, or per-column. The response is either BindComplete or ErrorResponse. </para> <note> <para> The choice between text and binary output is determined by the format codes given in Bind, regardless of the SQL command involved. The <literal>BINARY</> attribute in cursor declarations is irrelevant when using extended query protocol. </para> </note> <para> Query planning for named prepared-statement objects occurs when the Parse message is received. If a query will be repeatedly executed with different parameters, it may be beneficial to send a single Parse message containing a parameterized query, followed by multiple Bind and Execute messages. This will avoid replanning the query on each execution. </para> <para> The unnamed prepared statement is likewise planned during Parse processing if the Parse message defines no parameters. But if there are parameters, query planning is delayed until the first Bind message for the statement is received. The planner will consider the actual values of the parameters provided in the Bind message when planning the query. </para> <note> <para> Query plans generated from a parameterized query may be less efficient than query plans generated from an equivalent query with actual parameter values substituted. The query planner cannot make decisions based on actual parameter values (for example, index selectivity) when planning a parameterized query assigned to a named prepared-statement object. This possible penalty is avoided when using the unnamed statement, since it is not planned until actual parameter values are available. </para> <para> If a second or subsequent Bind referencing the unnamed prepared-statement object is received without an intervening Parse, the query is not replanned. The parameter values used in the first Bind message may produce a query plan that is only efficient for a subset of possible parameter values. To force replanning of the query for a fresh set of parameters, send another Parse message to replace the unnamed prepared-statement object. </para> </note> <para> If successfully created, a named portal object lasts till the end of the current transaction, unless explicitly destroyed. An unnamed portal is destroyed at the end of the transaction, or as soon as the next Bind statement specifying the unnamed portal as destination is issued. (Note that a simple Query message also destroys the unnamed portal.) Named portals must be explicitly closed before they can be redefined by a Bind message, but this is not required for the unnamed portal. Named portals can also be created and accessed at the SQL command level, using <command>DECLARE CURSOR</> and <command>FETCH</>. </para> <para> Once a portal exists, it can be executed using an Execute message. The Execute message specifies the portal name (empty string denotes the unnamed portal) and a maximum result-row count (zero meaning <quote>fetch all rows</>). The result-row count is only meaningful for portals containing commands that return row sets; in other cases the command is always executed to completion, and the row count is ignored. The possible responses to Execute are the same as those described above for queries issued via simple query protocol, except that Execute doesn't cause ReadyForQuery or RowDescription to be issued. </para> <para> If Execute terminates before completing the execution of a portal (due to reaching a nonzero result-row count), it will send a PortalSuspended message; the appearance of this message tells the frontend that another Execute should be issued against the same portal to complete the operation. The CommandComplete message indicating completion of the source SQL command is not sent until the portal's execution is completed. Therefore, an Execute phase is always terminated by the appearance of exactly one of these messages: CommandComplete, EmptyQueryResponse (if the portal was created from an empty query string), ErrorResponse, or PortalSuspended. </para> <para> At completion of each series of extended-query messages, the frontend should issue a Sync message. This parameterless message causes the backend to close the current transaction if it's not inside a <command>BEGIN</>/<command>COMMIT</> transaction block (<quote>close</> meaning to commit if no error, or roll back if error). Then a ReadyForQuery response is issued. The purpose of Sync is to provide a resynchronization point for error recovery. When an error is detected while processing any extended-query message, the backend issues ErrorResponse, then reads and discards messages until a Sync is reached, then issues ReadyForQuery and returns to normal message processing. (But note that no skipping occurs if an error is detected <emphasis>while</> processing Sync — this ensures that there is one and only one ReadyForQuery sent for each Sync.) </para> <note> <para>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -